mirror of
https://github.com/lumapu/ahoy.git
synced 2025-07-30 22:48:27 +02:00
Improve python code quality
Mostly fix naming convetion, add descriptions. Cleanup code, left behind from tinkering.
This commit is contained in:
parent
2934c23688
commit
e4eebb67e4
4 changed files with 279 additions and 163 deletions
|
@ -1,4 +1,9 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Hoymiles output plugin library
|
||||
"""
|
||||
|
||||
import socket
|
||||
from datetime import datetime, timezone
|
||||
|
@ -11,15 +16,46 @@ except ModuleNotFoundError:
|
|||
|
||||
class OutputPluginFactory:
|
||||
def __init__(self, **params):
|
||||
"""Initialize output plugin"""
|
||||
"""
|
||||
Initialize output plugin
|
||||
|
||||
self.inverter_ser = params.get('inverter_ser', 0)
|
||||
:param inverter_ser: The inverter serial
|
||||
:type inverter_ser: str
|
||||
:param inverter_name: The configured name for the inverter
|
||||
:type inverter_name: str
|
||||
"""
|
||||
|
||||
def store_status(self, data):
|
||||
self.inverter_ser = params.get('inverter_ser', '')
|
||||
self.inverter_name = params.get('inverter_name', None)
|
||||
|
||||
def store_status(self, response, **params):
|
||||
"""
|
||||
Default function
|
||||
|
||||
:raises NotImplementedError: when the plugin does not implement store status data
|
||||
"""
|
||||
raise NotImplementedError('The current output plugin does not implement store_status')
|
||||
|
||||
class InfluxOutputPlugin(OutputPluginFactory):
|
||||
""" Influx2 output plugin """
|
||||
api = None
|
||||
|
||||
def __init__(self, url, token, **params):
|
||||
"""
|
||||
Initialize InfluxOutputPlugin
|
||||
|
||||
The following targets must be present in your InfluxDB. This does not
|
||||
automatically create anything for You.
|
||||
|
||||
:param str url: The url to connect this client to. Like http://localhost:8086
|
||||
:param str token: Influx2 access token which is allowed to write to bucket
|
||||
:param org: Influx2 org, the token belongs to
|
||||
:type org: str
|
||||
:param bucket: Influx2 bucket to store data in (also known as retention policy)
|
||||
:type bucket: str
|
||||
:param measurement: Default measurement-prefix to use
|
||||
:type measurement: str
|
||||
"""
|
||||
super().__init__(**params)
|
||||
|
||||
self._bucket = params.get('bucket', 'hoymiles/autogen')
|
||||
|
@ -30,20 +66,20 @@ class InfluxOutputPlugin(OutputPluginFactory):
|
|||
client = InfluxDBClient(url, token, bucket=self._bucket)
|
||||
self.api = client.write_api()
|
||||
|
||||
def store_status(self, response):
|
||||
def store_status(self, response, **params):
|
||||
"""
|
||||
Publish StatusResponse object
|
||||
|
||||
:param influxdb.InfluxDBClient influx_client: A connected instance to Influx database
|
||||
:param str inverter_ser: inverter serial
|
||||
:param hoymiles.StatusResponse data: decoded inverter StatusResponse
|
||||
:type response: hoymiles.StatusResponse
|
||||
:param measurement: Influx measurement name
|
||||
:type measurement: str
|
||||
:param hoymiles.decoders.StatusResponse response: StatusResponse object
|
||||
:type response: hoymiles.decoders.StatusResponse
|
||||
:param measurement: Custom influx measurement name
|
||||
:type measurement: str or None
|
||||
|
||||
:raises ValueError: when response is not instance of StatusResponse
|
||||
"""
|
||||
|
||||
if not isinstance(response, StatusResponse):
|
||||
raise RuntimeError('Data needs to be instance of StatusResponse')
|
||||
raise ValueError('Data needs to be instance of StatusResponse')
|
||||
|
||||
data = response.__dict__()
|
||||
|
||||
|
@ -89,7 +125,30 @@ except ModuleNotFoundError:
|
|||
pass
|
||||
|
||||
class MqttOutputPlugin(OutputPluginFactory):
|
||||
""" Mqtt output plugin """
|
||||
client = None
|
||||
|
||||
def __init__(self, *args, **params):
|
||||
"""
|
||||
Initialize MqttOutputPlugin
|
||||
|
||||
:param host: Broker ip or hostname (defaults to: 127.0.0.1)
|
||||
:type host: str
|
||||
:param port: Broker port
|
||||
:type port: int (defaults to: 1883)
|
||||
:param user: Optional username to login to the broker
|
||||
:type user: str or None
|
||||
:param password: Optional passwort to login to the broker
|
||||
:type password: str or None
|
||||
:param topic: Topic prefix to use (defaults to: hoymiles/{inverter_ser})
|
||||
:type topic: str
|
||||
|
||||
:param paho.mqtt.client.Client broker: mqtt-client instance
|
||||
:param str inverter_ser: inverter serial
|
||||
:param hoymiles.StatusResponse data: decoded inverter StatusResponse
|
||||
:param topic: custom mqtt topic prefix (default: hoymiles/{inverter_ser})
|
||||
:type topic: str
|
||||
"""
|
||||
super().__init__(*args, **params)
|
||||
|
||||
mqtt_client = paho.mqtt.client.Client()
|
||||
|
@ -103,36 +162,36 @@ class MqttOutputPlugin(OutputPluginFactory):
|
|||
"""
|
||||
Publish StatusResponse object
|
||||
|
||||
:param paho.mqtt.client.Client broker: mqtt-client instance
|
||||
:param str inverter_ser: inverter serial
|
||||
:param hoymiles.StatusResponse data: decoded inverter StatusResponse
|
||||
:param hoymiles.decoders.StatusResponse response: StatusResponse object
|
||||
:param topic: custom mqtt topic prefix (default: hoymiles/{inverter_ser})
|
||||
:type topic: str
|
||||
|
||||
:raises ValueError: when response is not instance of StatusResponse
|
||||
"""
|
||||
|
||||
if not isinstance(response, StatusResponse):
|
||||
raise RuntimeError('Data needs to be instance of StatusResponse')
|
||||
raise ValueError('Data needs to be instance of StatusResponse')
|
||||
|
||||
data = response.__dict__()
|
||||
|
||||
topic = params.get('topic', f'hoymiles/{inverter_ser}')
|
||||
topic = params.get('topic', f'hoymiles/{data["inverter_ser"]}')
|
||||
|
||||
# AC Data
|
||||
phase_id = 0
|
||||
for phase in data['phases']:
|
||||
self.mqtt_client.publish(f'{topic}/emeter/{phase_id}/power', phase['power'])
|
||||
self.mqtt_client.publish(f'{topic}/emeter/{phase_id}/voltage', phase['voltage'])
|
||||
self.mqtt_client.publish(f'{topic}/emeter/{phase_id}/current', phase['current'])
|
||||
self.client.publish(f'{topic}/emeter/{phase_id}/power', phase['power'])
|
||||
self.client.publish(f'{topic}/emeter/{phase_id}/voltage', phase['voltage'])
|
||||
self.client.publish(f'{topic}/emeter/{phase_id}/current', phase['current'])
|
||||
phase_id = phase_id + 1
|
||||
|
||||
# DC Data
|
||||
string_id = 0
|
||||
for string in data['strings']:
|
||||
self.mqtt_client.publish(f'{topic}/emeter-dc/{string_id}/total', string['energy_total']/1000)
|
||||
self.mqtt_client.publish(f'{topic}/emeter-dc/{string_id}/power', string['power'])
|
||||
self.mqtt_client.publish(f'{topic}/emeter-dc/{string_id}/voltage', string['voltage'])
|
||||
self.mqtt_client.publish(f'{topic}/emeter-dc/{string_id}/current', string['current'])
|
||||
self.client.publish(f'{topic}/emeter-dc/{string_id}/total', string['energy_total']/1000)
|
||||
self.client.publish(f'{topic}/emeter-dc/{string_id}/power', string['power'])
|
||||
self.client.publish(f'{topic}/emeter-dc/{string_id}/voltage', string['voltage'])
|
||||
self.client.publish(f'{topic}/emeter-dc/{string_id}/current', string['current'])
|
||||
string_id = string_id + 1
|
||||
# Global
|
||||
self.mqtt_client.publish(f'{topic}/frequency', data['frequency'])
|
||||
self.mqtt_client.publish(f'{topic}/temperature', data['temperature'])
|
||||
self.client.publish(f'{topic}/frequency', data['frequency'])
|
||||
self.client.publish(f'{topic}/temperature', data['temperature'])
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue