@ -735,7 +735,7 @@ class Web { 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					# ifdef ENABLE_PROMETHEUS_EP # ifdef ENABLE_PROMETHEUS_EP  
			
		
	
		
		
			
				
					        enum  {         enum  {  
			
		
	
		
		
			
				
					
					            metricsStateStart ,  metricsStateInverter ,  metricStateChannel  , metricsStateEnd             metricsStateStart ,  metricsStateInverter ,  metricStateRealtimeData , metricsStateAlarmData  , metricsStateEnd  
			
				
				
			
		
	
		
		
	
		
		
			
				
					        }  metricsStep ;         }  metricsStep ;  
			
		
	
		
		
			
				
					        int  metricsInverterId , metricsChannelId ;         int  metricsInverterId , metricsChannelId ;  
			
		
	
		
		
			
				
					
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -749,15 +749,22 @@ class Web { 
			
		
	
		
		
			
				
					                Inverter < >  * iv ;                 Inverter < >  * iv ;  
			
		
	
		
		
			
				
					                record_t < >  * rec ;                 record_t < >  * rec ;  
			
		
	
		
		
			
				
					                statistics_t  * stat ;                 statistics_t  * stat ;  
			
		
	
		
		
			
				
					                String  promUnit ,  promType ;  
			
		
	
		
		
			
				
					                String  metrics ;                 String  metrics ;  
			
		
	
		
		
			
				
					                char  type [ 60 ] ,  topic [ 100 ] ,  val [ 25 ] ;                 char  type [ 60 ] ,  topic [ 100 ] ,  val [ 25 ] ;  
			
		
	
		
		
			
				
					                size_t  len  =  0 ;                 size_t  len  =  0 ;  
			
		
	
		
		
			
				
					                int  alarmChannelId ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                switch  ( metricsStep )  {                 switch  ( metricsStep )  {  
			
		
	
		
		
			
				
					                    case  metricsStateStart :  // System Info & NRF Statistics : fit to one packet
                     case  metricsStateStart :  // System Info & NRF Statistics : fit to one packet
  
			
		
	
		
		
			
				
					
					                        snprintf ( topic , sizeof ( topic ) , " # TYPE ahoy_solar_info gauge \n ahoy_solar_info{version= \" %s \" ,image= \" \" ,devicename= \" %s \" } 1 \n " ,                         snprintf ( type , sizeof ( type ) , " # TYPE ahoy_solar_info gauge \n " ) ;  
			
				
				
			
		
	
		
		
	
		
		
			
				
					                        snprintf ( topic , sizeof ( topic ) , " ahoy_solar_info{version= \" %s \" ,image= \" \" ,devicename= \" %s \" } 1 \n " ,  
			
		
	
		
		
			
				
					                            mApp - > getVersion ( ) ,  mConfig - > sys . deviceName ) ;                             mApp - > getVersion ( ) ,  mConfig - > sys . deviceName ) ;  
			
		
	
		
		
			
				
					
					                        metrics  =  topic ;                         metrics  =  String ( type )  +  String ( topic ) ;  
			
				
				
			
		
	
		
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                        snprintf ( topic , sizeof ( topic ) , " # TYPE ahoy_solar_freeheap gauge \n ahoy_solar_freeheap{devicename= \" %s \" } %u \n " , mConfig - > sys . deviceName , ESP . getFreeHeap ( ) ) ;  
			
		
	
		
		
			
				
					                        metrics  + =  String ( topic ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                        // NRF Statistics
                         // NRF Statistics
  
			
		
	
		
		
			
				
					                        stat  =  mApp - > getStatistics ( ) ;                         stat  =  mApp - > getStatistics ( ) ;  
			
		
	
		
		
			
				
					                        metrics  + =  radioStatistic ( F ( " rx_success " ) ,      stat - > rxSuccess ) ;                         metrics  + =  radioStatistic ( F ( " rx_success " ) ,      stat - > rxSuccess ) ;  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -776,24 +783,40 @@ class Web { 
			
		
	
		
		
			
				
					                        if  ( metricsInverterId  <  mSys - > getNumInverters ( ) )  {                         if  ( metricsInverterId  <  mSys - > getNumInverters ( ) )  {  
			
		
	
		
		
			
				
					                            iv  =  mSys - > getInverterByPos ( metricsInverterId ) ;                             iv  =  mSys - > getInverterByPos ( metricsInverterId ) ;  
			
		
	
		
		
			
				
					                            if ( NULL  ! =  iv )  {                             if ( NULL  ! =  iv )  {  
			
		
	
		
		
			
				
					
					                                // Inverter info
                                 // Inverter info : fit to one packet
  
			
				
				
			
		
	
		
		
			
				
					
					                                len  =  snprintf ( ( char  * ) buffer ,  maxLen ,  " ahoy_solar_inverter_info{name= \" %s \" ,serial= \" %12llx \" ,enabled= \" %d \" } 1 \n " ,                                 snprintf ( type , sizeof ( type ) , " # TYPE ahoy_solar_inverter_info gauge \n " ) ;  
			
				
				
			
		
	
		
		
			
				
					
					                                    iv - > config - > name ,  iv - > config - > serial . u64 , iv - > config - > enabled ) ;                                 snprintf ( topic , sizeof ( topic ) , " ahoy_solar_inverter_info{name= \" %s \" ,serial= \" %12llx \" } 1 \n " ,  
			
				
				
			
		
	
		
		
			
				
					
					                                // Start Channel loop for this inverter
                                     iv - > config - > name ,  iv - > config - > serial . u64 ) ;  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					                                metrics  =  String ( type )  +  String ( topic ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                                snprintf ( type , sizeof ( type ) , " # TYPE ahoy_solar_inverter_is_enabled gauge \n " ) ;  
			
		
	
		
		
			
				
					                                snprintf ( topic , sizeof ( topic ) , " ahoy_solar_inverter_is_enabled {inverter= \" %s \" } %d \n " , iv - > config - > name , iv - > config - > enabled ) ;  
			
		
	
		
		
			
				
					                                metrics  + =  String ( type )  +  String ( topic ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                                snprintf ( type , sizeof ( type ) , " # TYPE ahoy_solar_inverter_is_available gauge \n " ) ;  
			
		
	
		
		
			
				
					                                snprintf ( topic , sizeof ( topic ) , " ahoy_solar_inverter_is_available {inverter= \" %s \" } %d \n " , iv - > config - > name , iv - > isAvailable ( mApp - > getTimestamp ( ) ) ) ;  
			
		
	
		
		
			
				
					                                metrics  + =  String ( type )  +  String ( topic ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                                snprintf ( type , sizeof ( type ) , " # TYPE ahoy_solar_inverter_is_producing gauge \n " ) ;  
			
		
	
		
		
			
				
					                                snprintf ( topic , sizeof ( topic ) , " ahoy_solar_inverter_is_producing {inverter= \" %s \" } %d \n " , iv - > config - > name , iv - > isProducing ( mApp - > getTimestamp ( ) ) ) ;  
			
		
	
		
		
			
				
					                                metrics  + =  String ( type )  +  String ( topic ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                                len  =  snprintf ( ( char  * ) buffer , maxLen , " %s " , metrics . c_str ( ) ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                                // Start Realtime Data Channel loop for this inverter
  
			
		
	
		
		
			
				
					                                metricsChannelId  =  0 ;                                 metricsChannelId  =  0 ;  
			
		
	
		
		
			
				
					
					                                metricsStep  =  metricStateChannel ;                                 metricsStep  =  metricStateRealtimeData  ;  
			
				
				
			
		
	
		
		
	
		
		
			
				
					                            }                             }  
			
		
	
		
		
			
				
					                        }  else  {                         }  else  {  
			
		
	
		
		
			
				
					                            metricsStep  =  metricsStateEnd ;                             metricsStep  =  metricsStateEnd ;  
			
		
	
		
		
			
				
					                        }                         }  
			
		
	
		
		
			
				
					                        break ;                         break ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					
					                    case  metricStateChannel :  // Channel loop
                     case  metricStateRealtimeData  :  // Realtime Data  Channel loop
  
			
				
				
			
		
	
		
		
	
		
		
			
				
					                        iv  =  mSys - > getInverterByPos ( metricsInverterId ) ;                         iv  =  mSys - > getInverterByPos ( metricsInverterId ) ;  
			
		
	
		
		
			
				
					                        rec  =  iv - > getRecordStruct ( RealTimeRunData_Debug ) ;                         rec  =  iv - > getRecordStruct ( RealTimeRunData_Debug ) ;  
			
		
	
		
		
			
				
					                        if  ( metricsChannelId  <  rec - > length )  {                         if  ( metricsChannelId  <  rec - > length )  {  
			
		
	
		
		
			
				
					                            uint8_t  channel  =  rec - > assign [ metricsChannelId ] . ch ;                             uint8_t  channel  =  rec - > assign [ metricsChannelId ] . ch ;  
			
		
	
		
		
			
				
					                            String  promUnit ,  promType ;  
			
		
	
		
		
			
				
					                            std : : tie ( promUnit ,  promType )  =  convertToPromUnits ( iv - > getUnit ( metricsChannelId ,  rec ) ) ;                             std : : tie ( promUnit ,  promType )  =  convertToPromUnits ( iv - > getUnit ( metricsChannelId ,  rec ) ) ;  
			
		
	
		
		
			
				
					                            snprintf ( type ,  sizeof ( type ) ,  " # TYPE ahoy_solar_%s%s %s " ,  iv - > getFieldName ( metricsChannelId ,  rec ) ,  promUnit . c_str ( ) ,  promType . c_str ( ) ) ;                             snprintf ( type ,  sizeof ( type ) ,  " # TYPE ahoy_solar_%s%s %s " ,  iv - > getFieldName ( metricsChannelId ,  rec ) ,  promUnit . c_str ( ) ,  promType . c_str ( ) ) ;  
			
		
	
		
		
			
				
					                            if  ( 0  = =  channel )  {                             if  ( 0  = =  channel )  {  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -808,12 +831,34 @@ class Web { 
			
		
	
		
		
			
				
					                        }  else  {                         }  else  {  
			
		
	
		
		
			
				
					                            len  =  snprintf ( ( char * ) buffer , maxLen , " # \n " ) ;  // At least one char to send otherwise the transmission ends.
                             len  =  snprintf ( ( char * ) buffer , maxLen , " # \n " ) ;  // At least one char to send otherwise the transmission ends.
  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					
					                            // All channels processed --> try next inverter
                             // All realtime data channels processed --> try alarm data
  
			
				
				
			
		
	
		
		
			
				
					
					                            metricsInverterId + + ;                             metricsStep  =  metricsStateAlarmData ;  
			
				
				
			
		
	
		
		
			
				
					                            metricsStep  =  metricsStateInverter ;  
			
		
	
		
		
	
		
		
	
		
		
			
				
					                        }                         }  
			
		
	
		
		
			
				
					                        break ;                         break ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                    case  metricsStateAlarmData :  // Alarm Info loop
  
			
		
	
		
		
			
				
					                        iv  =  mSys - > getInverterByPos ( metricsInverterId ) ;  
			
		
	
		
		
			
				
					                        rec  =  iv - > getRecordStruct ( AlarmData ) ;  
			
		
	
		
		
			
				
					                        // simple hack : there is only one channel with alarm data
  
			
		
	
		
		
			
				
					                        // TODO: find the right one channel with the alarm id
  
			
		
	
		
		
			
				
					                        alarmChannelId  =  0 ;  
			
		
	
		
		
			
				
					                        // printf("AlarmData Length %d\n",rec->length);
  
			
		
	
		
		
			
				
					                        if  ( alarmChannelId  <  rec - > length )  
			
		
	
		
		
			
				
					                        {  
			
		
	
		
		
			
				
					                            //uint8_t channel = rec->assign[alarmChannelId].ch;
  
			
		
	
		
		
			
				
					                            std : : tie ( promUnit ,  promType )  =  convertToPromUnits ( iv - > getUnit ( alarmChannelId ,  rec ) ) ;  
			
		
	
		
		
			
				
					                            snprintf ( type ,  sizeof ( type ) ,  " # TYPE ahoy_solar_%s%s %s " ,  iv - > getFieldName ( alarmChannelId ,  rec ) ,  promUnit . c_str ( ) ,  promType . c_str ( ) ) ;  
			
		
	
		
		
			
				
					                            snprintf ( topic ,  sizeof ( topic ) ,  " ahoy_solar_%s%s{inverter= \" %s \" } " ,  iv - > getFieldName ( alarmChannelId ,  rec ) ,  promUnit . c_str ( ) ,  iv - > config - > name ) ;  
			
		
	
		
		
			
				
					                            snprintf ( val ,  sizeof ( val ) ,  " %.3f " ,  iv - > getValue ( alarmChannelId ,  rec ) ) ;  
			
		
	
		
		
			
				
					                            len  =  snprintf ( ( char * ) buffer , maxLen , " %s \n %s %s \n " , type , topic , val ) ;  
			
		
	
		
		
			
				
					                        }  else  {  
			
		
	
		
		
			
				
					                            len  =  snprintf ( ( char * ) buffer , maxLen , " # \n " ) ;  // At least one char to send otherwise the transmission ends.
  
			
		
	
		
		
			
				
					                        }  
			
		
	
		
		
			
				
					                        // alarm channel processed --> try next inverter
  
			
		
	
		
		
			
				
					                        metricsInverterId + + ;  
			
		
	
		
		
			
				
					                        metricsStep  =  metricsStateInverter ;  
			
		
	
		
		
			
				
					                        break ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                    case  metricsStateEnd :                     case  metricsStateEnd :  
			
		
	
		
		
			
				
					                    default :  // end of transmission
                     default :  // end of transmission
  
			
		
	
		
		
			
				
					                        len  =  0 ;                         len  =  0 ;