From 73a03971079425d5a0915a1fe1c27339ed2b78fc Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Tue, 6 Sep 2022 17:48:46 +0200 Subject: [PATCH] RPI: be able to handle more than one inverter with the volkszaehler plugin --- tools/rpi/ahoy.yml.example | 50 ++++++++++++++++---------------- tools/rpi/hoymiles/outputs.py | 54 +++++++++++++++++++++++++---------- 2 files changed, 65 insertions(+), 39 deletions(-) diff --git a/tools/rpi/ahoy.yml.example b/tools/rpi/ahoy.yml.example index a7afb01c..644508e5 100644 --- a/tools/rpi/ahoy.yml.example +++ b/tools/rpi/ahoy.yml.example @@ -30,30 +30,32 @@ ahoy: 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: '' + inverters: + - serial: 114172220003 + 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: serial: 99978563001 diff --git a/tools/rpi/hoymiles/outputs.py b/tools/rpi/hoymiles/outputs.py index a0bfdfef..a6f798ee 100644 --- a/tools/rpi/hoymiles/outputs.py +++ b/tools/rpi/hoymiles/outputs.py @@ -208,14 +208,10 @@ try: except ModuleNotFoundError: pass -class VolkszaehlerOutputPlugin(OutputPluginFactory): - def __init__(self, config, **params): - """ - Initialize VolkszaehlerOutputPlugin - """ - super().__init__(**params) - - self.session = requests.Session() +class VzInverterOutput: + def __init__(self, config, session): + self.session = session + self.serial = config.get('serial') self.baseurl = config.get('url', 'http://localhost/middleware/') self.channels = dict() for channel in config.get('channels', []): @@ -224,7 +220,7 @@ class VolkszaehlerOutputPlugin(OutputPluginFactory): if uid and ctype: self.channels[ctype] = uid - def store_status(self, response, **params): + def store_status(self, data, session): """ Publish StatusResponse object @@ -232,15 +228,9 @@ class VolkszaehlerOutputPlugin(OutputPluginFactory): :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 @@ -277,3 +267,37 @@ class VolkszaehlerOutputPlugin(OutputPluginFactory): raise ValueError('Could not send request (%s)' % url) except ConnectionError as e: raise ValueError('Could not send request (%s)' % e) + +class VolkszaehlerOutputPlugin(OutputPluginFactory): + def __init__(self, config, **params): + """ + Initialize VolkszaehlerOutputPlugin + """ + super().__init__(**params) + + self.session = requests.Session() + self.inverters = dict() + for inverterconfig in config.get('inverters', []): + serial = inverterconfig.get('serial') + output = VzInverterOutput(inverterconfig, self.session) + self.inverters[serial] = output + + 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.inverters) == 0: + return + + data = response.__dict__() + serial = data["inverter_ser"] + if serial in self.inverters: + output = self.inverters[serial] + output.store_status(data, self.session)