| 
						
						
							
								
							
						
						
					 | 
					@ -9,6 +9,7 @@ import socket | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import logging | 
					 | 
					 | 
					import logging | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					from datetime import datetime, timezone | 
					 | 
					 | 
					from datetime import datetime, timezone | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					from hoymiles.decoders import StatusResponse, HardwareInfoResponse | 
					 | 
					 | 
					from hoymiles.decoders import StatusResponse, HardwareInfoResponse | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					from hoymiles import HOYMILES_TRANSACTION_LOGGING, HOYMILES_DEBUG_LOGGING | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					class OutputPluginFactory: | 
					 | 
					 | 
					class OutputPluginFactory: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    def __init__(self, **params): | 
					 | 
					 | 
					    def __init__(self, **params): | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -39,6 +40,7 @@ class InfluxOutputPlugin(OutputPluginFactory): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    def __init__(self, url, token, **params): | 
					 | 
					 | 
					    def __init__(self, url, token, **params): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        """ | 
					 | 
					 | 
					        """ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        Initialize InfluxOutputPlugin | 
					 | 
					 | 
					        Initialize InfluxOutputPlugin | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        https://influxdb-client.readthedocs.io/en/stable/api.html#influxdbclient | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        The following targets must be present in your InfluxDB. This does not | 
					 | 
					 | 
					        The following targets must be present in your InfluxDB. This does not | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        automatically create anything for You. | 
					 | 
					 | 
					        automatically create anything for You. | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -68,8 +70,12 @@ class InfluxOutputPlugin(OutputPluginFactory): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        self._org = params.get('org', '') | 
					 | 
					 | 
					        self._org = params.get('org', '') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        self._measurement = params.get('measurement', f'inverter,host={socket.gethostname()}') | 
					 | 
					 | 
					        self._measurement = params.get('measurement', f'inverter,host={socket.gethostname()}') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        client = InfluxDBClient(url, token, bucket=self._bucket) | 
					 | 
					 | 
					        with InfluxDBClient(url, token, bucket=self._bucket) as self.client: | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        self.api = client.write_api() | 
					 | 
					 | 
					             self.api = self.client.write_api() | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    def disco(self, **params): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        self.client.close()          # Shutdown the client | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        return | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    def store_status(self, response, **params): | 
					 | 
					 | 
					    def store_status(self, response, **params): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        """ | 
					 | 
					 | 
					        """ | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -102,6 +108,9 @@ class InfluxOutputPlugin(OutputPluginFactory): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        # InfluxDB requires nanoseconds | 
					 | 
					 | 
					        # InfluxDB requires nanoseconds | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        ctime = int(utctime.timestamp() * 1e9) | 
					 | 
					 | 
					        ctime = int(utctime.timestamp() * 1e9) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        if HOYMILES_DEBUG_LOGGING: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            logging.info(f'InfluxDB: utctime: {utctime}') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        # AC Data | 
					 | 
					 | 
					        # AC Data | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        phase_id = 0 | 
					 | 
					 | 
					        phase_id = 0 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        for phase in data['phases']: | 
					 | 
					 | 
					        for phase in data['phases']: | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -135,6 +144,9 @@ class InfluxOutputPlugin(OutputPluginFactory): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            data_stack.append(f'{measurement},type=YieldToday value={data["yield_today"]/1000:.3f} {ctime}') | 
					 | 
					 | 
					            data_stack.append(f'{measurement},type=YieldToday value={data["yield_today"]/1000:.3f} {ctime}') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        data_stack.append(f'{measurement},type=Efficiency value={data["efficiency"]:.2f} {ctime}') | 
					 | 
					 | 
					        data_stack.append(f'{measurement},type=Efficiency value={data["efficiency"]:.2f} {ctime}') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        if HOYMILES_DEBUG_LOGGING: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            #logging.debug(f'INFLUX data to DB: {data_stack}') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            pass | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        self.api.write(self._bucket, self._org, data_stack) | 
					 | 
					 | 
					        self.api.write(self._bucket, self._org, data_stack) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					class MqttOutputPlugin(OutputPluginFactory): | 
					 | 
					 | 
					class MqttOutputPlugin(OutputPluginFactory): | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -196,6 +208,12 @@ class MqttOutputPlugin(OutputPluginFactory): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    def disco(self, **params): | 
					 | 
					 | 
					    def disco(self, **params): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        self.client.loop_stop()    # Stop loop  | 
					 | 
					 | 
					        self.client.loop_stop()    # Stop loop  | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        self.client.disconnect()   # disconnect | 
					 | 
					 | 
					        self.client.disconnect()   # disconnect | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        return | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    def info2mqtt(self, mqtt_topic, mqtt_data): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        for mqtt_key in mqtt_data: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            self.client.publish(f'{mqtt_topic["topic"]}/{mqtt_key}', mqtt_data[mqtt_key], self.qos, self.ret) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        return | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    def store_status(self, response, **params): | 
					 | 
					 | 
					    def store_status(self, response, **params): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        """ | 
					 | 
					 | 
					        """ | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -209,13 +227,18 @@ class MqttOutputPlugin(OutputPluginFactory): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        """ | 
					 | 
					 | 
					        """ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        data = response.__dict__() | 
					 | 
					 | 
					        data = response.__dict__() | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        topic = params.get('topic', None) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        if not topic: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            topic = f'{data.get("inverter_name", "hoymiles")}/{data.get("inverter_ser", None)}' | 
					 | 
					 | 
					            topic = f'{data.get("inverter_name", "hoymiles")}/{data.get("inverter_ser", None)}' | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        if HOYMILES_DEBUG_LOGGING: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            logging.info(f'MQTT-topic: {topic} data-type: {type(response)}') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        if isinstance(response, StatusResponse): | 
					 | 
					 | 
					        if isinstance(response, StatusResponse): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            # Global Head | 
					 | 
					 | 
					            # Global Head | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            if data['time'] is not None: | 
					 | 
					 | 
					            if data['time'] is not None: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					               self.client.publish(f'{topic}/time', data['time'].strftime("%d.%m.%y - %H:%M:%S"), self.qos, self.ret) | 
					 | 
					 | 
					               self.client.publish(f'{topic}/time', data['time'].strftime("%d.%m.%YT%H:%M:%S"), self.qos, self.ret) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            # AC Data | 
					 | 
					 | 
					            # AC Data | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            phase_id = 0 | 
					 | 
					 | 
					            phase_id = 0 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -233,12 +256,16 @@ class MqttOutputPlugin(OutputPluginFactory): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            string_id = 0 | 
					 | 
					 | 
					            string_id = 0 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            string_sum_power = 0 | 
					 | 
					 | 
					            string_sum_power = 0 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            for string in data['strings']: | 
					 | 
					 | 
					            for string in data['strings']: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					                self.client.publish(f'{topic}/emeter-dc/{string_id}/voltage', string['voltage'], self.qos, self.ret) | 
					 | 
					 | 
					                if 'name' in string: | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                self.client.publish(f'{topic}/emeter-dc/{string_id}/current', string['current'], self.qos, self.ret) | 
					 | 
					 | 
					                    string_name = string['name'].replace(" ","_") | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                self.client.publish(f'{topic}/emeter-dc/{string_id}/power', string['power'], self.qos, self.ret) | 
					 | 
					 | 
					                else: | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                self.client.publish(f'{topic}/emeter-dc/{string_id}/YieldDay', string['energy_daily'], self.qos, self.ret) | 
					 | 
					 | 
					                    string_name = string_id | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                self.client.publish(f'{topic}/emeter-dc/{string_id}/YieldTotal', string['energy_total']/1000, self.qos, self.ret) | 
					 | 
					 | 
					                self.client.publish(f'{topic}/emeter-dc/{string_name}/voltage', string['voltage'], self.qos, self.ret) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                self.client.publish(f'{topic}/emeter-dc/{string_id}/Irradiation', string['irradiation'], self.qos, self.ret) | 
					 | 
					 | 
					                self.client.publish(f'{topic}/emeter-dc/{string_name}/current', string['current'], self.qos, self.ret) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                self.client.publish(f'{topic}/emeter-dc/{string_name}/power', string['power'], self.qos, self.ret) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                self.client.publish(f'{topic}/emeter-dc/{string_name}/YieldDay', string['energy_daily'], self.qos, self.ret) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                self.client.publish(f'{topic}/emeter-dc/{string_name}/YieldTotal', string['energy_total']/1000, self.qos, self.ret) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                self.client.publish(f'{topic}/emeter-dc/{string_name}/Irradiation', string['irradiation'], self.qos, self.ret) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                string_id = string_id + 1 | 
					 | 
					 | 
					                string_id = string_id + 1 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                string_sum_power += string['power'] | 
					 | 
					 | 
					                string_sum_power += string['power'] | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -277,9 +304,10 @@ class VzInverterOutput: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        self.channels = dict() | 
					 | 
					 | 
					        self.channels = dict() | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        for channel in config.get('channels', []): | 
					 | 
					 | 
					        for channel in config.get('channels', []): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            uid = channel.get('uid') | 
					 | 
					 | 
					            uid = channel.get('uid', None) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					            ctype = channel.get('type') | 
					 | 
					 | 
					            ctype = channel.get('type') | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					            if uid and ctype: | 
					 | 
					 | 
					            # if uid and ctype: | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            if ctype: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                self.channels[ctype] = uid | 
					 | 
					 | 
					                self.channels[ctype] = uid | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    def store_status(self, data, session): | 
					 | 
					 | 
					    def store_status(self, data, session): | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -295,6 +323,9 @@ class VzInverterOutput: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        ts = int(round(data['time'].timestamp() * 1000)) | 
					 | 
					 | 
					        ts = int(round(data['time'].timestamp() * 1000)) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        if HOYMILES_DEBUG_LOGGING: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            logging.info(f'Volkszaehler-Timestamp: {ts}') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        # AC Data | 
					 | 
					 | 
					        # AC Data | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        phase_id = 0 | 
					 | 
					 | 
					        phase_id = 0 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        for phase in data['phases']: | 
					 | 
					 | 
					        for phase in data['phases']: | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -327,13 +358,24 @@ class VzInverterOutput: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        if data['yield_today'] is not None: | 
					 | 
					 | 
					        if data['yield_today'] is not None: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            self.try_publish(ts, f'yield_today', data['yield_today']) | 
					 | 
					 | 
					            self.try_publish(ts, f'yield_today', data['yield_today']) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        self.try_publish(ts, f'efficiency', data['efficiency']) | 
					 | 
					 | 
					        self.try_publish(ts, f'efficiency', data['efficiency']) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        return | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    def try_publish(self, ts, ctype, value): | 
					 | 
					 | 
					    def try_publish(self, ts, ctype, value): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        if not ctype in self.channels: | 
					 | 
					 | 
					        if not ctype in self.channels: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            if HOYMILES_DEBUG_LOGGING: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                logging.warning(f'ctype \"{ctype}\" not found in ahoy.yml') | 
					 | 
					 | 
					                logging.warning(f'ctype \"{ctype}\" not found in ahoy.yml') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            return | 
					 | 
					 | 
					            return | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        uid = self.channels[ctype] | 
					 | 
					 | 
					        uid = self.channels[ctype] | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        url = f'{self.baseurl}/data/{uid}.json?operation=add&ts={ts}&value={value}' | 
					 | 
					 | 
					        url = f'{self.baseurl}/data/{uid}.json?operation=add&ts={ts}&value={value}' | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        if uid == None: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            if HOYMILES_DEBUG_LOGGING: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                logging.debug(f'ctype \"{ctype}\" has no configured uid-value in ahoy.yml') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            return | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        if HOYMILES_DEBUG_LOGGING: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            logging.debug(f'VZ-url: {url}') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        try: | 
					 | 
					 | 
					        try: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            r = self.session.get(url) | 
					 | 
					 | 
					            r = self.session.get(url) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            if r.status_code == 404: | 
					 | 
					 | 
					            if r.status_code == 404: | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -344,6 +386,7 @@ class VzInverterOutput: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					               raise ValueError(f'Transmit result {url}') | 
					 | 
					 | 
					               raise ValueError(f'Transmit result {url}') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        except ConnectionError as e: | 
					 | 
					 | 
					        except ConnectionError as e: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            raise ValueError(f'Could not connect VZ-DB {type(e)} {e.keys()}') | 
					 | 
					 | 
					            raise ValueError(f'Could not connect VZ-DB {type(e)} {e.keys()}') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        return | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					class VolkszaehlerOutputPlugin(OutputPluginFactory): | 
					 | 
					 | 
					class VolkszaehlerOutputPlugin(OutputPluginFactory): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    def __init__(self, config, **params): | 
					 | 
					 | 
					    def __init__(self, config, **params): | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -364,13 +407,17 @@ class VolkszaehlerOutputPlugin(OutputPluginFactory): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            exit(1) | 
					 | 
					 | 
					            exit(1) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        self.session = requests.Session() | 
					 | 
					 | 
					        self.session = requests.Session() | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        self.inverters = dict() | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        self.inverters = dict() | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        for inverterconfig in config.get('inverters', []): | 
					 | 
					 | 
					        for inverterconfig in config.get('inverters', []): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            serial = inverterconfig.get('serial') | 
					 | 
					 | 
					            serial = inverterconfig.get('serial') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            output = VzInverterOutput(inverterconfig, self.session) | 
					 | 
					 | 
					            output = VzInverterOutput(inverterconfig, self.session) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            self.inverters[serial] = output | 
					 | 
					 | 
					            self.inverters[serial] = output | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    def disco(self, **params): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        self.session.close()            # closing the connection | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        return | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    def store_status(self, response, **params): | 
					 | 
					 | 
					    def store_status(self, response, **params): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        """ | 
					 | 
					 | 
					        """ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        Publish StatusResponse object | 
					 | 
					 | 
					        Publish StatusResponse object | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -395,3 +442,4 @@ class VolkszaehlerOutputPlugin(OutputPluginFactory): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                output.store_status(data, self.session) | 
					 | 
					 | 
					                output.store_status(data, self.session) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            except ValueError as e: | 
					 | 
					 | 
					            except ValueError as e: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                logging.warning('Could not send data to volkszaehler instance: %s' % e) | 
					 | 
					 | 
					                logging.warning('Could not send data to volkszaehler instance: %s' % e) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        return | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
					 | 
					
  |