PVOutput - remove 0 values, MQTT - improve session handling

This commit is contained in:
bohdan-s
2022-01-17 14:45:08 +11:00
parent f3957ee074
commit 1d02bac750
5 changed files with 75 additions and 43 deletions
+25 -16
View File
@@ -25,7 +25,7 @@ class export_mqtt(object):
self.mqtt_client.tls_set()
try:
self.mqtt_client.connect(config.get('host'), port=config.get('port', 1883))
self.mqtt_client.connect(config.get('host'), port=config.get('port', 1883), keepalive=60)
self._isConfigured = True
except Exception as err:
logging.error(f"MQTT: Connection {config.get('host')}:{config.get('port', 1883)}")
@@ -52,9 +52,6 @@ class export_mqtt(object):
logging.info("MQTT: Skipped, Initial Configuration Failed")
return False
# After a while you'll need to reconnect, so just reconnect before each publish
self.mqtt_client.reconnect()
if not self.model:
self.model = inverter.get('device_type_code', 'unknown')
self.model_clean = self.model.replace('.','').replace('-','')
@@ -63,8 +60,18 @@ class export_mqtt(object):
logging.debug(f'MQTT: Sensor Topic = {self.sensor_topic}')
logging.debug(f"MQTT: Publishing: {self.sensor_topic} : {json.dumps(inverter)}")
result = self.mqtt_client.publish(self.sensor_topic, json.dumps(inverter).replace('"', '\"'))
result.wait_for_publish()
try:
result = self.mqtt_client.publish(self.sensor_topic, json.dumps(inverter).replace('"', '\"'))
result.wait_for_publish()
if result.rc == mqtt.MQTT_ERR_SUCCESS:
logging.info("MQTT: Published")
else:
logging.error(f"MQTT: Failed to publish with error code: {result.rc}")
if result.rc == mqtt.MQTT_ERR_NO_CONN:
logging.warning(f"MQTT: Attempting to reconnect to MQTT")
self.mqtt_client.reconnect()
except Exception as err:
logging.error(f"MQTT: Failed to publish with error: {err}")
if self.homeassistant:
if self.ha_discovery:
@@ -89,15 +96,17 @@ class export_mqtt(object):
config_msg['ic'] = "mdi:solar-power"
config_msg['device'] = { "name":"Solar Inverter", "mf":"Sungrow", "mdl":self.model, "connections":[["address", self.inverter_ip ]]}
result = self.mqtt_client.publish(ha_topic, json.dumps(config_msg), retain=True)
result.wait_for_publish()
logging.info("MQTT: Published Home Assistant Discovery messages")
try:
result = self.mqtt_client.publish(ha_topic, json.dumps(config_msg), retain=True)
result.wait_for_publish()
if result.rc != mqtt.MQTT_ERR_SUCCESS:
logging.error(f"MQTT: Failed to publish with error code: {result.rc}")
if result.rc == mqtt.MQTT_ERR_NO_CONN:
logging.warning(f"MQTT: Attempting to reconnect to MQTT")
self.mqtt_client.reconnect()
except Exception as err:
logging.error(f"MQTT: Failed to publish with error: {err}")
self.ha_discovery = False
logging.info("MQTT: Published Home Assistant Discovery messages")
if result.rc != mqtt.MQTT_ERR_SUCCESS:
# See https://github.com/eclipse/paho.mqtt.python/blob/master/src/paho/mqtt/client.py#L149 for error code mapping
logging.error(f"MQTT: Failed to publish with error code: {result.rc}")
else:
logging.info("MQTT: Published")
return result
return True
+47 -24
View File
@@ -27,11 +27,9 @@ class export_pvoutput(object):
self.rate_limit = config.get('rate_limit', 60)
self.status_interval = config.get('status_interval',5)
self.batch_points = config.get('batch_points',1)
self.inverter_data = { "v1": 0, "v2": 0, "v3": 0, "v4": 0, "v5": 0, "v6": 0, "v7": 0, "v8": 0, "v9": 0, "v10": 0, "v11": 0, "v12": 0 }
self.inverter_data_count = 0
self.collected_data = {}
self.payload_data = None
self.batch_count = 0
self.payload_format = "{date},{time},{v1},{v2},{v3},{v4},{v5},{v6},{v7},{v8},{v9},{v10},{v11},{v12}"
for parameter in config.get('parameters'):
self.parameters.append(parameter)
@@ -78,46 +76,71 @@ class export_pvoutput(object):
# Add new data to old data and increase count of data points
for parameter in self.parameters:
if parameter.get('name')[0] == 'v':
if inverter.get(parameter.get('register')):
if parameter.get('multiple'):
self.inverter_data[parameter.get('name')] = round(self.inverter_data[parameter.get('name')] + (inverter.get(parameter.get('register')) * parameter.get('multiple')),3)
if not self.collected_data.get(parameter.get('name'),False):
if inverter.get(parameter.get('register')):
self.collected_data[parameter.get('name')] = 0
else:
self.inverter_data[parameter.get('name')] = round(self.inverter_data[parameter.get('name')] + inverter.get(parameter.get('register')),3)
logging.warning(f"PVOutput: {parameter.get('name')} configured to use {parameter.get('register')} but inverter is not returning this register")
if parameter.get('multiple'):
self.collected_data[parameter.get('name')] = round(self.collected_data[parameter.get('name')] + (inverter.get(parameter.get('register')) * parameter.get('multiple')),3)
else:
logging.warning(f"PVOutput: {parameter.get('name')} configured to use {parameter.get('register')} but inverter is not returning this register")
elif parameter.get('name') == 'c1':
c1 = parameter.get('value')
self.inverter_data_count +=1
self.collected_data[parameter.get('name')] = round(self.collected_data[parameter.get('name')] + inverter.get(parameter.get('register')),3)
if parameter.get('name') == 'c1':
cumulative_energy = parameter.get('value')
if self.collected_data.get('count',False):
self.collected_data['count'] +=1
else:
self.collected_data['count'] = 1
logging.info('PVOutput: Data logged')
logging.debug(f'PVOutput: Points: {self.batch_count} Data: {self.inverter_data}, c1={str(c1)}')
logging.debug(f'PVOutput: Data: {self.collected_data}')
# Process data points every status_interval
if int(now.strftime("%M")) % self.status_interval == 0 and not now.strftime("%H:%M") == self.latest_run.strftime("%H:%M"):
for v in self.inverter_data:
if not self.inverter_data[v] == 0:
self.inverter_data[v] = round(self.inverter_data[v] / self.inverter_data_count, 2)
self.inverter_data_count = 0
for v in self.collected_data:
if v[0] == 'v' and not self.collected_data[v] == 0:
self.collected_data[v] = round(self.collected_data[v] / self.collected_data['count'], 2)
payload = self.payload_format
payload = payload.replace('{date}',now.strftime("%Y%m%d"))
payload = payload.replace('{time}',now.strftime("%H:%M"))
data_point = str(now.strftime("%Y%m%d")) + "," + str(now.strftime("%H:%M"))
for data in self.inverter_data:
payload = payload.replace('{' + data + '}',str(self.inverter_data.get(data)))
for x in range(1, 13):
v = 'v' + str(x)
if self.collected_data.get(v):
data_point = data_point + "," + str(self.collected_data[v])
else:
data_point = data_point + ","
self.inverter_data = { "v1": 0, "v2": 0, "v3": 0, "v4": 0, "v5": 0, "v6": 0, "v7": 0, "v8": 0, "v9": 0, "v10": 0, "v11": 0, "v12": 0 }
if self.collected_data.get('v2', False) and self.collected_data.get('v4', False):
net_data = 1
else:
net_data = 0
self.collected_data = {}
print(data_point)
if self.payload_data:
self.payload_data = self.payload_data + ";"
else:
self.payload_data = ""
self.payload_data = self.payload_data + payload
self.payload_data = self.payload_data + data_point
self.batch_count +=1
if self.batch_count == self.batch_points:
payload = {'data': self.payload_data, 'c1': str(c1)}
payload = {}
payload['data'] = self.payload_data
if net_data > 0:
payload['n'] = net_data
if 'cumulative_energy' in locals():
payload['c1'] = cumulative_energy
logging.debug("PVOutput: Request; " + self.statusbatch_url + ", " + str(self.headers) + " : " + str(payload))
response = requests.post(url=self.statusbatch_url, headers=self.headers, params=payload)
self.batch_count = 0
+1 -1
View File
@@ -254,7 +254,7 @@ registers:
address: 5017
datatype: "S32" # Documentation says Unsigned, but seems to be returning Signed 32bit
- name: "phase_a_voltage"
level: 1
level: 1
address: 5019
datatype: "U16"
multiple: 0.1
+1 -1
View File
@@ -136,7 +136,7 @@ def scrape_inverter():
pass
scrape_end = datetime.now()
logging.info(f'Inventer: Successfully scrapped in {(scrape_end - scrape_start).seconds}.{(scrape_end - scrape_start).microseconds} secs')
logging.info(f'Inverter: Successfully scraped in {(scrape_end - scrape_start).seconds}.{(scrape_end - scrape_start).microseconds} secs')
return True
+1 -1
View File
@@ -1 +1 @@
__version__ = '0.2.3'
__version__ = '0.2.4'