mirror of
https://github.com/lumapu/ahoy.git
synced 2025-08-06 09:58:23 +02:00
Merge pull request #173 from chehrlic/chris_vz
Initial plugin to directly send the values from the inverter to the v…
This commit is contained in:
commit
b8ed52b4a2
3 changed files with 112 additions and 0 deletions
|
@ -28,6 +28,33 @@ ahoy:
|
||||||
bucket: 'telegraf/autogen'
|
bucket: 'telegraf/autogen'
|
||||||
measurement: 'hoymiles'
|
measurement: 'hoymiles'
|
||||||
|
|
||||||
|
volkszaehler:
|
||||||
|
disabled: true
|
||||||
|
url: 'http://localhost/middleware/'
|
||||||
|
channels:
|
||||||
|
- type: 'temperature'
|
||||||
|
uid: 'ad578a40-1d97-11ed-8e8b-fda01a416575'
|
||||||
|
- type: 'frequency'
|
||||||
|
uid: ''
|
||||||
|
- type: 'ac_power0'
|
||||||
|
uid: '7ca5ac50-1e41-11ed-927f-610c4cb2c69e'
|
||||||
|
- type: 'ac_voltage0'
|
||||||
|
uid: '9a38e2e0-1d94-11ed-b539-25f8607ac030'
|
||||||
|
- type: 'ac_current0'
|
||||||
|
uid: 'a9a4daf0-1e41-11ed-b68c-eb73eef3d21d'
|
||||||
|
- type: 'dc_power0'
|
||||||
|
uid: '38eb3ca0-1e53-11ed-b830-792e70a592fa'
|
||||||
|
- type: 'dc_voltage0'
|
||||||
|
uid: ''
|
||||||
|
- type: 'dc_current0'
|
||||||
|
uid: ''
|
||||||
|
- type: 'dc_power1'
|
||||||
|
uid: '51c0e9d0-1e53-11ed-b574-8bc81547eb8f'
|
||||||
|
- type: 'dc_voltage1'
|
||||||
|
uid: ''
|
||||||
|
- type: 'dc_current1'
|
||||||
|
uid: ''
|
||||||
|
|
||||||
dtu:
|
dtu:
|
||||||
serial: 99978563001
|
serial: 99978563001
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,9 @@ def poll_inverter(inverter, retries=4):
|
||||||
if influx_client:
|
if influx_client:
|
||||||
influx_client.store_status(result)
|
influx_client.store_status(result)
|
||||||
|
|
||||||
|
if volkszaehler_client:
|
||||||
|
volkszaehler_client.store_status(result)
|
||||||
|
|
||||||
def mqtt_send_status(broker, inverter_ser, data, topic=None):
|
def mqtt_send_status(broker, inverter_ser, data, topic=None):
|
||||||
"""
|
"""
|
||||||
Publish StatusResponse object
|
Publish StatusResponse object
|
||||||
|
@ -247,6 +250,13 @@ if __name__ == '__main__':
|
||||||
bucket=influx_config.get('bucket', None),
|
bucket=influx_config.get('bucket', None),
|
||||||
measurement=influx_config.get('measurement', 'hoymiles'))
|
measurement=influx_config.get('measurement', 'hoymiles'))
|
||||||
|
|
||||||
|
volkszaehler_client = None
|
||||||
|
volkszaehler_config = ahoy_config.get('volkszaehler', {})
|
||||||
|
if volkszaehler_config and not volkszaehler_config.get('disabled', False):
|
||||||
|
from .outputs import VolkszaehlerOutputPlugin
|
||||||
|
volkszaehler_client = VolkszaehlerOutputPlugin(
|
||||||
|
volkszaehler_config)
|
||||||
|
|
||||||
g_inverters = [g_inverter.get('serial') for g_inverter in ahoy_config.get('inverters', [])]
|
g_inverters = [g_inverter.get('serial') for g_inverter in ahoy_config.get('inverters', [])]
|
||||||
for g_inverter in ahoy_config.get('inverters', []):
|
for g_inverter in ahoy_config.get('inverters', []):
|
||||||
g_inverter_ser = g_inverter.get('serial')
|
g_inverter_ser = g_inverter.get('serial')
|
||||||
|
|
|
@ -201,3 +201,78 @@ class MqttOutputPlugin(OutputPluginFactory):
|
||||||
self.client.publish(f'{topic}/pf', data['powerfactor'])
|
self.client.publish(f'{topic}/pf', data['powerfactor'])
|
||||||
self.client.publish(f'{topic}/frequency', data['frequency'])
|
self.client.publish(f'{topic}/frequency', data['frequency'])
|
||||||
self.client.publish(f'{topic}/temperature', data['temperature'])
|
self.client.publish(f'{topic}/temperature', data['temperature'])
|
||||||
|
|
||||||
|
try:
|
||||||
|
import requests
|
||||||
|
import time
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class VolkszaehlerOutputPlugin(OutputPluginFactory):
|
||||||
|
def __init__(self, config, **params):
|
||||||
|
"""
|
||||||
|
Initialize VolkszaehlerOutputPlugin
|
||||||
|
"""
|
||||||
|
super().__init__(**params)
|
||||||
|
|
||||||
|
self.baseurl = config.get('url', 'http://localhost/middleware/')
|
||||||
|
self.channels = dict()
|
||||||
|
for channel in config.get('channels', []):
|
||||||
|
uid = channel.get('uid')
|
||||||
|
ctype = channel.get('type')
|
||||||
|
if uid and ctype:
|
||||||
|
self.channels[ctype] = uid
|
||||||
|
|
||||||
|
def store_status(self, response, **params):
|
||||||
|
"""
|
||||||
|
Publish StatusResponse object
|
||||||
|
|
||||||
|
:param hoymiles.decoders.StatusResponse response: StatusResponse object
|
||||||
|
|
||||||
|
:raises ValueError: when response is not instance of StatusResponse
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not isinstance(response, StatusResponse):
|
||||||
|
raise ValueError('Data needs to be instance of StatusResponse')
|
||||||
|
|
||||||
|
if len(self.channels) == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
data = response.__dict__()
|
||||||
|
|
||||||
|
ts = int(round(data['time'].timestamp() * 1000))
|
||||||
|
|
||||||
|
# AC Data
|
||||||
|
phase_id = 0
|
||||||
|
for phase in data['phases']:
|
||||||
|
self.try_publish(ts, f'ac_power{phase_id}', phase['power'])
|
||||||
|
self.try_publish(ts, f'ac_voltage{phase_id}', phase['voltage'])
|
||||||
|
self.try_publish(ts, f'ac_current{phase_id}', phase['current'])
|
||||||
|
phase_id = phase_id + 1
|
||||||
|
|
||||||
|
# DC Data
|
||||||
|
string_id = 0
|
||||||
|
for string in data['strings']:
|
||||||
|
self.try_publish(ts, f'dc_power{string_id}', string['power'])
|
||||||
|
self.try_publish(ts, f'dc_voltage{string_id}', string['voltage'])
|
||||||
|
self.try_publish(ts, f'dc_current{string_id}', string['current'])
|
||||||
|
self.try_publish(ts, f'dc_total{string_id}', string['energy_total'])
|
||||||
|
self.try_publish(ts, f'dc_daily{string_id}', string['energy_daily'])
|
||||||
|
string_id = string_id + 1
|
||||||
|
# Global
|
||||||
|
if data['powerfactor'] is not None:
|
||||||
|
self.try_publish(ts, f'powerfactor', data['powerfactor'])
|
||||||
|
self.try_publish(ts, f'frequency', data['frequency'])
|
||||||
|
self.try_publish(ts, f'temperature', data['temperature'])
|
||||||
|
|
||||||
|
def try_publish(self, ts, ctype, value):
|
||||||
|
if not ctype in self.channels:
|
||||||
|
return
|
||||||
|
uid = self.channels[ctype]
|
||||||
|
url = f'{self.baseurl}/data/{uid}.json?operation=add&ts={ts}&value={value}'
|
||||||
|
try:
|
||||||
|
r = requests.get(url)
|
||||||
|
if r.status_code != 200:
|
||||||
|
raise ValueError('Could not send request (%s)' % url)
|
||||||
|
except ConnectionError as e:
|
||||||
|
raise ValueError('Could not send request (%s)' % e)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue