diff --git a/tools/rpi/ahoy.yml.example b/tools/rpi/ahoy.yml.example index 9426d1a4..8438b9f7 100644 --- a/tools/rpi/ahoy.yml.example +++ b/tools/rpi/ahoy.yml.example @@ -8,7 +8,7 @@ ahoy: nrf: - ce_pin: 22 cs_pin: 0 - txpower: 'low' # default txpower (low,max) + txpower: 'low' # default txpower (min,low,high,max) mqtt: disabled: false @@ -32,7 +32,7 @@ ahoy: inverters: - name: 'balkon' serial: 114172220003 - txpower: 'low' # txpower per inverter (low,max) + txpower: 'low' # txpower per inverter (min,low,high,max) mqtt: send_raw_enabled: false # allow inject debug data via mqtt topic: 'hoymiles/114172221234' # defaults to 'hoymiles/{serial}' diff --git a/tools/rpi/hoymiles/__init__.py b/tools/rpi/hoymiles/__init__.py index c3010522..ada9a6ef 100644 --- a/tools/rpi/hoymiles/__init__.py +++ b/tools/rpi/hoymiles/__init__.py @@ -11,7 +11,7 @@ import re from datetime import datetime import json import crcmod -from RF24 import RF24, RF24_PA_LOW, RF24_PA_MAX, RF24_250KBPS, RF24_CRC_DISABLED, RF24_CRC_8, RF24_CRC_16 +from RF24 import RF24, RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX, RF24_250KBPS, RF24_CRC_DISABLED, RF24_CRC_8, RF24_CRC_16 from .decoders import * f_crc_m = crcmod.predefined.mkPredefinedCrcFun('modbus') @@ -319,8 +319,12 @@ class HoymilesNRF: self.radio.setCRCLength(RF24_CRC_16) self.radio.enableDynamicPayloads() - if txpower == 'low': + if txpower == 'min': + self.radio.setPALevel(RF24_PA_MIN) + elif txpower == 'low': self.radio.setPALevel(RF24_PA_LOW) + elif txpower == 'high': + self.radio.setPALevel(RF24_PA_HIGH) else: self.radio.setPALevel(RF24_PA_MAX) @@ -675,6 +679,10 @@ class InverterTransaction: :return: if successful scheduled :rtype: bool """ + + if not self.radio: + return + packet = compose_esb_fragment(b'', seq=int(0x80 + frame_id).to_bytes(1, 'big'), src=self.dtu_ser, diff --git a/tools/rpi/hoymiles/__main__.py b/tools/rpi/hoymiles/__main__.py index c9c2ba01..a9f8e9ed 100644 --- a/tools/rpi/hoymiles/__main__.py +++ b/tools/rpi/hoymiles/__main__.py @@ -81,7 +81,9 @@ def poll_inverter(inverter, retries=4): if isinstance(result, hoymiles.decoders.StatusResponse): data = result.__dict__() if hoymiles.HOYMILES_DEBUG_LOGGING: - print(f'{c_datetime} Decoded: {data["temperature"]}', end='') + print(f'{c_datetime} Decoded: temp={data["temperature"]}', end='') + if data['powerfactor'] is not None: + print(f', pf={data["powerfactor"]}', end='') phase_id = 0 for phase in data['phases']: print(f' phase{phase_id}=voltage:{phase["voltage"]}, current:{phase["current"]}, power:{phase["power"]}, frequency:{data["frequency"]}', end='') @@ -129,6 +131,8 @@ def mqtt_send_status(broker, inverter_ser, data, topic=None): broker.publish(f'{topic}/emeter-dc/{string_id}/current', string['current']) string_id = string_id + 1 # Global + if data['powerfactor'] is not None: + broker.publish(f'{topic}/pf', data['powerfactor']) broker.publish(f'{topic}/frequency', data['frequency']) broker.publish(f'{topic}/temperature', data['temperature']) diff --git a/tools/rpi/hoymiles/decoders/__init__.py b/tools/rpi/hoymiles/decoders/__init__.py index 60a72504..8aaf2d36 100644 --- a/tools/rpi/hoymiles/decoders/__init__.py +++ b/tools/rpi/hoymiles/decoders/__init__.py @@ -45,6 +45,7 @@ class StatusResponse(Response): e_keys = ['voltage','current','power','energy_total','energy_daily','powerfactor'] temperature = None frequency = None + powerfactor = None def unpack(self, fmt, base): """ @@ -118,6 +119,7 @@ class StatusResponse(Response): data['strings'] = self.strings data['temperature'] = self.temperature data['frequency'] = self.frequency + data['powerfactor'] = self.powerfactor data['time'] = self.time_rx return data @@ -534,6 +536,10 @@ class Hm600Decode0B(StatusResponse): """ Grid frequency in Hertz """ return self.unpack('>H', 28)[0]/100 @property + def powerfactor(self): + """ Powerfactor """ + return self.unpack('>H', 36)[0]/1000 + @property def temperature(self): """ Inverter temperature in °C """ return self.unpack('>H', 38)[0]/10 @@ -654,6 +660,10 @@ class Hm1200Decode0B(StatusResponse): """ Grid frequency in Hertz """ return self.unpack('>H', 48)[0]/100 @property + def powerfactor(self): + """ Powerfactor """ + return self.unpack('>H', 56)[0]/1000 + @property def temperature(self): """ Inverter temperature in °C """ return self.unpack('>H', 58)[0]/10 diff --git a/tools/rpi/hoymiles/outputs.py b/tools/rpi/hoymiles/outputs.py index 7b942846..84d057e3 100644 --- a/tools/rpi/hoymiles/outputs.py +++ b/tools/rpi/hoymiles/outputs.py @@ -114,6 +114,8 @@ class InfluxOutputPlugin(OutputPluginFactory): data_stack.append(f'{measurement},string={string_id},type=current value={string["current"]:3f} {ctime}') string_id = string_id + 1 # Global + if data['powerfactor'] is not None: + data_stack.append(f'{measurement},type=pf value={data["powerfactor"]:f} {ctime}') data_stack.append(f'{measurement},type=frequency value={data["frequency"]:.3f} {ctime}') data_stack.append(f'{measurement},type=temperature value={data["temperature"]:.2f} {ctime}') @@ -193,5 +195,7 @@ class MqttOutputPlugin(OutputPluginFactory): self.client.publish(f'{topic}/emeter-dc/{string_id}/current', string['current']) string_id = string_id + 1 # Global + if data['powerfactor'] is not None: + self.client.publish(f'{topic}/pf', data['powerfactor']) self.client.publish(f'{topic}/frequency', data['frequency']) self.client.publish(f'{topic}/temperature', data['temperature'])