mirror of
https://github.com/lumapu/ahoy.git
synced 2025-08-06 09:58:23 +02:00
Merge branch 'main' of https://github.com/grindylow/ahoy
This commit is contained in:
commit
f41e76df1b
3 changed files with 36 additions and 15 deletions
|
@ -8,6 +8,7 @@ ahoy:
|
||||||
nrf:
|
nrf:
|
||||||
- ce_pin: 22
|
- ce_pin: 22
|
||||||
cs_pin: 0
|
cs_pin: 0
|
||||||
|
txpower: 'low' # default txpower (low,max)
|
||||||
|
|
||||||
mqtt:
|
mqtt:
|
||||||
disabled: false
|
disabled: false
|
||||||
|
@ -31,6 +32,7 @@ ahoy:
|
||||||
inverters:
|
inverters:
|
||||||
- name: 'balkon'
|
- name: 'balkon'
|
||||||
serial: 114172220003
|
serial: 114172220003
|
||||||
|
txpower: 'low' # txpower per inverter (low,max)
|
||||||
mqtt:
|
mqtt:
|
||||||
send_raw_enabled: false # allow inject debug data via mqtt
|
send_raw_enabled: false # allow inject debug data via mqtt
|
||||||
topic: 'hoymiles/114172221234' # defaults to 'hoymiles/{serial}'
|
topic: 'hoymiles/114172221234' # defaults to 'hoymiles/{serial}'
|
||||||
|
|
|
@ -274,16 +274,27 @@ class HoymilesNRF:
|
||||||
rx_channel_list = [3,23,40,61,75]
|
rx_channel_list = [3,23,40,61,75]
|
||||||
rx_channel_ack = False
|
rx_channel_ack = False
|
||||||
rx_error = 0
|
rx_error = 0
|
||||||
|
txpower = 'max'
|
||||||
|
|
||||||
def __init__(self, device):
|
def __init__(self, **radio_config):
|
||||||
"""
|
"""
|
||||||
Claim radio device
|
Claim radio device
|
||||||
|
|
||||||
:param NRF24 device: instance of NRF24
|
:param NRF24 device: instance of NRF24
|
||||||
"""
|
"""
|
||||||
self.radio = device
|
radio = RF24(
|
||||||
|
radio_config.get('ce_pin', 22),
|
||||||
|
radio_config.get('cs_pin', 0),
|
||||||
|
radio_config.get('spispeed', 1000000))
|
||||||
|
|
||||||
def transmit(self, packet):
|
if not radio.begin():
|
||||||
|
raise RuntimeError('Can\'t open radio')
|
||||||
|
|
||||||
|
self.txpower = radio_config.get('txpower', 'max')
|
||||||
|
|
||||||
|
self.radio = radio
|
||||||
|
|
||||||
|
def transmit(self, packet, txpower=None):
|
||||||
"""
|
"""
|
||||||
Transmit Packet
|
Transmit Packet
|
||||||
|
|
||||||
|
@ -292,12 +303,14 @@ class HoymilesNRF:
|
||||||
:rtype: bool
|
:rtype: bool
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if not txpower:
|
||||||
|
txpower = self.txpower
|
||||||
|
|
||||||
inv_esb_addr = b'\01' + packet[1:5]
|
inv_esb_addr = b'\01' + packet[1:5]
|
||||||
dtu_esb_addr = b'\01' + packet[5:9]
|
dtu_esb_addr = b'\01' + packet[5:9]
|
||||||
|
|
||||||
self.radio.stopListening() # put radio in TX mode
|
self.radio.stopListening() # put radio in TX mode
|
||||||
self.radio.setDataRate(RF24_250KBPS)
|
self.radio.setDataRate(RF24_250KBPS)
|
||||||
#self.radio.setPALevel(RF24_PA_LOW)
|
|
||||||
self.radio.openReadingPipe(1,dtu_esb_addr)
|
self.radio.openReadingPipe(1,dtu_esb_addr)
|
||||||
self.radio.openWritingPipe(inv_esb_addr)
|
self.radio.openWritingPipe(inv_esb_addr)
|
||||||
self.radio.setChannel(self.tx_channel)
|
self.radio.setChannel(self.tx_channel)
|
||||||
|
@ -306,6 +319,11 @@ class HoymilesNRF:
|
||||||
self.radio.setCRCLength(RF24_CRC_16)
|
self.radio.setCRCLength(RF24_CRC_16)
|
||||||
self.radio.enableDynamicPayloads()
|
self.radio.enableDynamicPayloads()
|
||||||
|
|
||||||
|
if txpower == 'low':
|
||||||
|
self.radio.setPALevel(RF24_PA_LOW)
|
||||||
|
else:
|
||||||
|
self.radio.setPALevel(RF24_PA_MAX)
|
||||||
|
|
||||||
return self.radio.write(packet)
|
return self.radio.write(packet)
|
||||||
|
|
||||||
def receive(self, timeout=None):
|
def receive(self, timeout=None):
|
||||||
|
@ -402,6 +420,9 @@ class HoymilesNRF:
|
||||||
"""
|
"""
|
||||||
return self.rx_channel_list[self.rx_channel_id]
|
return self.rx_channel_list[self.rx_channel_id]
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self.radio.powerDown()
|
||||||
|
|
||||||
def frame_payload(payload):
|
def frame_payload(payload):
|
||||||
"""
|
"""
|
||||||
Prepare payload for transmission, append Modbus CRC16
|
Prepare payload for transmission, append Modbus CRC16
|
||||||
|
@ -490,6 +511,7 @@ class InverterTransaction:
|
||||||
time_rx = None
|
time_rx = None
|
||||||
|
|
||||||
radio = None
|
radio = None
|
||||||
|
txpower = None
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
request_time=None,
|
request_time=None,
|
||||||
|
@ -513,6 +535,9 @@ class InverterTransaction:
|
||||||
if radio:
|
if radio:
|
||||||
self.radio = radio
|
self.radio = radio
|
||||||
|
|
||||||
|
if 'txpower' in params:
|
||||||
|
self.txpower = params['txpower']
|
||||||
|
|
||||||
if not request_time:
|
if not request_time:
|
||||||
request_time=datetime.now()
|
request_time=datetime.now()
|
||||||
|
|
||||||
|
@ -555,7 +580,7 @@ class InverterTransaction:
|
||||||
c_datetime = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
|
c_datetime = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
|
||||||
print(f'{c_datetime} Transmit {len(packet)} | {hexify_payload(packet)}')
|
print(f'{c_datetime} Transmit {len(packet)} | {hexify_payload(packet)}')
|
||||||
|
|
||||||
self.radio.transmit(packet)
|
self.radio.transmit(packet, txpower=self.txpower)
|
||||||
|
|
||||||
wait = False
|
wait = False
|
||||||
try:
|
try:
|
||||||
|
@ -619,6 +644,8 @@ class InverterTransaction:
|
||||||
self.time_rx = end_frame.time_rx
|
self.time_rx = end_frame.time_rx
|
||||||
tr_len = end_frame.seq - 0x80
|
tr_len = end_frame.seq - 0x80
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
|
seq_last = max(frames, key=lambda frame:frame.seq).seq
|
||||||
|
self.__retransmit_frame(seq_last + 1)
|
||||||
raise BufferError(f'Missing packet: Last packet {len(self.scratch)}')
|
raise BufferError(f'Missing packet: Last packet {len(self.scratch)}')
|
||||||
|
|
||||||
# Rebuild payload from unordered frames
|
# Rebuild payload from unordered frames
|
||||||
|
|
|
@ -14,7 +14,6 @@ import argparse
|
||||||
import yaml
|
import yaml
|
||||||
from yaml.loader import SafeLoader
|
from yaml.loader import SafeLoader
|
||||||
import paho.mqtt.client
|
import paho.mqtt.client
|
||||||
from RF24 import RF24, RF24_PA_LOW, RF24_PA_MAX, RF24_250KBPS, RF24_CRC_DISABLED, RF24_CRC_8, RF24_CRC_16
|
|
||||||
import hoymiles
|
import hoymiles
|
||||||
|
|
||||||
def main_loop():
|
def main_loop():
|
||||||
|
@ -52,6 +51,7 @@ def poll_inverter(inverter, retries=4):
|
||||||
payload_ttl = payload_ttl - 1
|
payload_ttl = payload_ttl - 1
|
||||||
com = hoymiles.InverterTransaction(
|
com = hoymiles.InverterTransaction(
|
||||||
radio=hmradio,
|
radio=hmradio,
|
||||||
|
txpower=inverter.get('txpower', None),
|
||||||
dtu_ser=dtu_ser,
|
dtu_ser=dtu_ser,
|
||||||
inverter_ser=inverter_ser,
|
inverter_ser=inverter_ser,
|
||||||
request=next(hoymiles.compose_esb_packet(
|
request=next(hoymiles.compose_esb_packet(
|
||||||
|
@ -207,11 +207,7 @@ if __name__ == '__main__':
|
||||||
# Prepare for multiple transceivers, makes them configurable (currently
|
# Prepare for multiple transceivers, makes them configurable (currently
|
||||||
# only one supported)
|
# only one supported)
|
||||||
for radio_config in ahoy_config.get('nrf', [{}]):
|
for radio_config in ahoy_config.get('nrf', [{}]):
|
||||||
radio = RF24(
|
hmradio = hoymiles.HoymilesNRF(**radio_config)
|
||||||
radio_config.get('ce_pin', 22),
|
|
||||||
radio_config.get('cs_pin', 0),
|
|
||||||
radio_config.get('spispeed', 1000000))
|
|
||||||
hmradio = hoymiles.HoymilesNRF(device=radio)
|
|
||||||
|
|
||||||
mqtt_client = None
|
mqtt_client = None
|
||||||
|
|
||||||
|
@ -242,9 +238,6 @@ 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'))
|
||||||
|
|
||||||
if not radio.begin():
|
|
||||||
raise RuntimeError('Can\'t open radio')
|
|
||||||
|
|
||||||
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')
|
||||||
|
@ -274,5 +267,4 @@ if __name__ == '__main__':
|
||||||
time.sleep(time.time() % loop_interval)
|
time.sleep(time.time() % loop_interval)
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
radio.powerDown()
|
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue