Browse Source

Merge branch 'main' of https://github.com/grindylow/ahoy

pull/59/head
lumapu 3 years ago
parent
commit
f3b0bc8bb8
  1. 4
      tools/rpi/ahoy.yml.example
  2. 12
      tools/rpi/hoymiles/__init__.py
  3. 6
      tools/rpi/hoymiles/__main__.py
  4. 10
      tools/rpi/hoymiles/decoders/__init__.py
  5. 4
      tools/rpi/hoymiles/outputs.py

4
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}'

12
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,

6
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'])

10
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

4
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'])

Loading…
Cancel
Save