Browse Source

Merge branch 'nrf_container' of https://github.com/vendetta1987/ahoy into vendetta1987-nrf_container

pull/1219/head
lumapu 1 year ago
parent
commit
24b9be867c
  1. 2
      .gitignore
  2. 13
      tools/rpi/hoymiles/__init__.py
  3. 13
      tools/rpi/hoymiles/__main__.py
  4. 73
      tools/rpi/hoymiles/outputs.py

2
.gitignore

@ -13,3 +13,5 @@ src/web/html/tmp/*
*.suo
*.ipch
src/output.map
/.venv

13
tools/rpi/hoymiles/__init__.py

@ -344,6 +344,9 @@ class HoymilesNRF:
if not radio.begin():
raise RuntimeError('Can\'t open radio')
if not radio.isChipConnected():
logging.warning("could not connect to NRF24 radio")
self.txpower = radio_config.get('txpower', 'max')
@ -411,7 +414,7 @@ class HoymilesNRF:
self.radio.startListening()
fragments = []
received_sth=False
# Receive: Loop
t_end = time.monotonic_ns()+timeout
while time.monotonic_ns() < t_end:
@ -431,7 +434,7 @@ class HoymilesNRF:
ch_rx=self.rx_channel, ch_tx=self.tx_channel,
time_rx=datetime.now()
)
received_sth=True
yield fragment
else:
@ -447,7 +450,11 @@ class HoymilesNRF:
self.radio.setChannel(self.rx_channel)
self.radio.startListening()
time.sleep(0.004)
time.sleep(0.005)
if not received_sth:
raise TimeoutError
def next_rx_channel(self):
"""

13
tools/rpi/hoymiles/__main__.py

@ -103,10 +103,11 @@ class SunsetHandler:
def sun_status2mqtt(self, dtu_ser, dtu_name):
if not mqtt_client or not self.suntimes:
return
local_sunrise = self.suntimes.riselocal(datetime.now()).strftime("%d.%m.%YT%H:%M")
local_sunset = self.suntimes.setlocal(datetime.now()).strftime("%d.%m.%YT%H:%M")
local_zone = self.suntimes.setlocal(datetime.now()).tzinfo._key
if self.suntimes:
local_sunrise = self.suntimes.riselocal(datetime.now()).strftime("%d.%m.%YT%H:%M")
local_sunset = self.suntimes.setlocal(datetime.now()).strftime("%d.%m.%YT%H:%M")
local_zone = self.suntimes.setlocal(datetime.now()).tzinfo.key
mqtt_client.info2mqtt({'topic' : f'{dtu_name}/{dtu_ser}'}, \
{'dis_night_comm' : 'True', \
'local_sunrise' : local_sunrise, \
@ -235,14 +236,14 @@ def poll_inverter(inverter, dtu_ser, do_init, retries):
if isinstance(result, hoymiles.decoders.StatusResponse):
data = result.__dict__()
if 'event_count' in data:
if data is not None and 'event_count' in data:
if event_message_index[inv_str] < data['event_count']:
event_message_index[inv_str] = data['event_count']
command_queue[inv_str].append(hoymiles.compose_send_time_payload(InfoCommands.AlarmData, alarm_id=event_message_index[inv_str]))
if mqtt_client:
mqtt_client.store_status(result, topic=inverter.get('mqtt', {}).get('topic', None))
if influx_client:
influx_client.store_status(result)
@ -409,7 +410,7 @@ if __name__ == '__main__':
str(g_inverter_ser),
g_inverter.get('mqtt', {}).get('topic', f'hoymiles/{g_inverter_ser}') + '/command'
)
mqtt_client.subscribe(topic_item[1])
mqtt_client.client.subscribe(topic_item[1])
mqtt_command_topic_subs.append(topic_item)
# start main-loop

73
tools/rpi/hoymiles/outputs.py

@ -227,6 +227,11 @@ class MqttOutputPlugin(OutputPluginFactory):
"""
data = response.__dict__()
if data is None:
logging.warn("received data object is empty")
return
topic = params.get('topic', None)
if not topic:
topic = f'{data.get("inverter_name", "hoymiles")}/{data.get("inverter_ser", None)}'
@ -243,31 +248,33 @@ class MqttOutputPlugin(OutputPluginFactory):
# AC Data
phase_id = 0
phase_sum_power = 0
for phase in data['phases']:
self.client.publish(f'{topic}/emeter/{phase_id}/voltage', phase['voltage'], self.qos, self.ret)
self.client.publish(f'{topic}/emeter/{phase_id}/current', phase['current'], self.qos, self.ret)
self.client.publish(f'{topic}/emeter/{phase_id}/power', phase['power'], self.qos, self.ret)
self.client.publish(f'{topic}/emeter/{phase_id}/Q_AC', phase['reactive_power'], self.qos, self.ret)
self.client.publish(f'{topic}/emeter/{phase_id}/frequency', phase['frequency'], self.qos, self.ret)
phase_id = phase_id + 1
phase_sum_power += phase['power']
if data['phases'] is not None:
for phase in data['phases']:
self.client.publish(f'{topic}/emeter/{phase_id}/voltage', phase['voltage'], self.qos, self.ret)
self.client.publish(f'{topic}/emeter/{phase_id}/current', phase['current'], self.qos, self.ret)
self.client.publish(f'{topic}/emeter/{phase_id}/power', phase['power'], self.qos, self.ret)
self.client.publish(f'{topic}/emeter/{phase_id}/Q_AC', phase['reactive_power'], self.qos, self.ret)
self.client.publish(f'{topic}/emeter/{phase_id}/frequency', phase['frequency'], self.qos, self.ret)
phase_id = phase_id + 1
phase_sum_power += phase['power']
# DC Data
string_id = 0
string_sum_power = 0
for string in data['strings']:
if 'name' in string:
string_name = string['name'].replace(" ","_")
else:
string_name = string_id
self.client.publish(f'{topic}/emeter-dc/{string_name}/voltage', string['voltage'], self.qos, self.ret)
self.client.publish(f'{topic}/emeter-dc/{string_name}/current', string['current'], self.qos, self.ret)
self.client.publish(f'{topic}/emeter-dc/{string_name}/power', string['power'], self.qos, self.ret)
self.client.publish(f'{topic}/emeter-dc/{string_name}/YieldDay', string['energy_daily'], self.qos, self.ret)
self.client.publish(f'{topic}/emeter-dc/{string_name}/YieldTotal', string['energy_total']/1000, self.qos, self.ret)
self.client.publish(f'{topic}/emeter-dc/{string_name}/Irradiation', string['irradiation'], self.qos, self.ret)
string_id = string_id + 1
string_sum_power += string['power']
if data['strings'] is not None:
for string in data['strings']:
if 'name' in string:
string_name = string['name'].replace(" ","_")
else:
string_name = string_id
self.client.publish(f'{topic}/emeter-dc/{string_name}/voltage', string['voltage'], self.qos, self.ret)
self.client.publish(f'{topic}/emeter-dc/{string_name}/current', string['current'], self.qos, self.ret)
self.client.publish(f'{topic}/emeter-dc/{string_name}/power', string['power'], self.qos, self.ret)
self.client.publish(f'{topic}/emeter-dc/{string_name}/YieldDay', string['energy_daily'], self.qos, self.ret)
self.client.publish(f'{topic}/emeter-dc/{string_name}/YieldTotal', string['energy_total']/1000, self.qos, self.ret)
self.client.publish(f'{topic}/emeter-dc/{string_name}/Irradiation', string['irradiation'], self.qos, self.ret)
string_id = string_id + 1
string_sum_power += string['power']
# Global
if data['event_count'] is not None:
@ -279,19 +286,23 @@ class MqttOutputPlugin(OutputPluginFactory):
self.client.publish(f'{topic}/YieldTotal', data['yield_total']/1000, self.qos, self.ret)
if data['yield_today'] is not None:
self.client.publish(f'{topic}/YieldToday', data['yield_today']/1000, self.qos, self.ret)
self.client.publish(f'{topic}/Efficiency', data['efficiency'], self.qos, self.ret)
if data['efficiency'] is not None:
self.client.publish(f'{topic}/Efficiency', data['efficiency'], self.qos, self.ret)
elif isinstance(response, HardwareInfoResponse):
self.client.publish(f'{topic}/Firmware/Version',\
f'{data["FW_ver_maj"]}.{data["FW_ver_min"]}.{data["FW_ver_pat"]}', self.qos, self.ret)
self.client.publish(f'{topic}/Firmware/Build_at',\
f'{data["FW_build_dd"]}/{data["FW_build_mm"]}/{data["FW_build_yy"]}T{data["FW_build_HH"]}:{data["FW_build_MM"]}',\
self.qos, self.ret)
self.client.publish(f'{topic}/Firmware/HWPartId',\
f'{data["FW_HW_ID"]}', self.qos, self.ret)
if data["FW_ver_maj"] is not None and data["FW_ver_min"] is not None and data["FW_ver_pat"] is not None:
self.client.publish(f'{topic}/Firmware/Version',\
f'{data["FW_ver_maj"]}.{data["FW_ver_min"]}.{data["FW_ver_pat"]}', self.qos, self.ret)
if data["FW_build_dd"] is not None and data["FW_build_mm"] is not None and data["FW_build_yy"] is not None and data["FW_build_HH"] is not None and data["FW_build_MM"] is not None:
self.client.publish(f'{topic}/Firmware/Build_at',\
f'{data["FW_build_dd"]}/{data["FW_build_mm"]}/{data["FW_build_yy"]}T{data["FW_build_HH"]}:{data["FW_build_MM"]}',\
self.qos, self.ret)
if data["FW_HW_ID"] is not None:
self.client.publish(f'{topic}/Firmware/HWPartId',\
f'{data["FW_HW_ID"]}', self.qos, self.ret)
else:
raise ValueError('Data needs to be instance of StatusResponse or a instance of HardwareInfoResponse')

Loading…
Cancel
Save