DCU: Possibility for setting the out power

Fixes #415
This commit is contained in:
Stefan Allius
2025-05-18 15:11:35 +02:00
parent c1bdec0844
commit cf1a87ed6f
2 changed files with 37 additions and 0 deletions

View File

@@ -247,6 +247,7 @@ class SolarmanBase(Message):
class SolarmanV5(SolarmanBase): class SolarmanV5(SolarmanBase):
AT_CMD = 1 AT_CMD = 1
MB_RTU_CMD = 2 MB_RTU_CMD = 2
DCU_CMD = 5
AT_CMD_RSP = 8 AT_CMD_RSP = 8
MB_CLIENT_DATA_UP = 30 MB_CLIENT_DATA_UP = 30
'''Data up time in client mode''' '''Data up time in client mode'''
@@ -532,6 +533,24 @@ class SolarmanV5(SolarmanBase):
except Exception: except Exception:
self.ifc.tx_clear() self.ifc.tx_clear()
def send_dcu_cmd(self, pdu: bytearray):
if self.sensor_list != 0x3026:
logger.debug(f'[{self.node_id}] DCU CMD not allowed,'
f' for sensor: {self.sensor_list:#04x}')
return
if self.state != State.up:
logger.warning(f'[{self.node_id}] ignore DCU CMD,'
' cause the state is not UP anymore')
return
self._build_header(0x4510)
self.ifc.tx_add(struct.pack('<BHLLL', self.DCU_CMD,
self.sensor_list, 0, 0, 0))
self.ifc.tx_add(pdu)
self._finish_send_msg()
self.ifc.tx_log(logging.INFO, f'Send DCU CMD :{self.addr}:')
self.ifc.tx_flush()
def __forward_msg(self): def __forward_msg(self):
self.forward(self.ifc.rx_peek(), self.header_len+self.data_len+2) self.forward(self.ifc.rx_peek(), self.header_len+self.data_len+2)

View File

@@ -2,6 +2,7 @@ import asyncio
import logging import logging
import aiomqtt import aiomqtt
import traceback import traceback
import struct
from modbus import Modbus from modbus import Modbus
from messages import Message from messages import Message
@@ -32,6 +33,7 @@ class Mqtt(metaclass=Singleton):
self.ha_status_topic = f"{ha['auto_conf_prefix']}/status" self.ha_status_topic = f"{ha['auto_conf_prefix']}/status"
self.mb_rated_topic = f"{ha['entity_prefix']}/+/rated_load" self.mb_rated_topic = f"{ha['entity_prefix']}/+/rated_load"
self.mb_out_coeff_topic = f"{ha['entity_prefix']}/+/out_coeff" self.mb_out_coeff_topic = f"{ha['entity_prefix']}/+/out_coeff"
self.dcu_power_topic = f"{ha['entity_prefix']}/+/dcu_power"
self.mb_reads_topic = f"{ha['entity_prefix']}/+/modbus_read_regs" self.mb_reads_topic = f"{ha['entity_prefix']}/+/modbus_read_regs"
self.mb_inputs_topic = f"{ha['entity_prefix']}/+/modbus_read_inputs" self.mb_inputs_topic = f"{ha['entity_prefix']}/+/modbus_read_inputs"
self.mb_at_cmd_topic = f"{ha['entity_prefix']}/+/at_cmd" self.mb_at_cmd_topic = f"{ha['entity_prefix']}/+/at_cmd"
@@ -85,6 +87,7 @@ class Mqtt(metaclass=Singleton):
await self.__client.subscribe(self.ha_status_topic) await self.__client.subscribe(self.ha_status_topic)
await self.__client.subscribe(self.mb_rated_topic) await self.__client.subscribe(self.mb_rated_topic)
await self.__client.subscribe(self.mb_out_coeff_topic) await self.__client.subscribe(self.mb_out_coeff_topic)
await self.__client.subscribe(self.dcu_power_topic)
await self.__client.subscribe(self.mb_reads_topic) await self.__client.subscribe(self.mb_reads_topic)
await self.__client.subscribe(self.mb_inputs_topic) await self.__client.subscribe(self.mb_inputs_topic)
await self.__client.subscribe(self.mb_at_cmd_topic) await self.__client.subscribe(self.mb_at_cmd_topic)
@@ -148,6 +151,21 @@ class Mqtt(metaclass=Singleton):
except Exception: except Exception:
pass pass
if message.topic.matches(self.dcu_power_topic):
payload = message.payload.decode("UTF-8")
try:
val = round(float(payload) * 10)
if val < 1000 or val > 8000:
logger_mqtt.error('dcu_power: value must be in'
'the range 100..800,'
f' got: {payload}')
else:
pdu = struct.pack('>BBBBBBH', 1, 1, 6, 1, 0, 1, val)
for fnc in self.each_inverter(message, "send_dcu_cmd"):
fnc(pdu)
except Exception:
pass
if message.topic.matches(self.mb_reads_topic): if message.topic.matches(self.mb_reads_topic):
await self.modbus_cmd(message, await self.modbus_cmd(message,
Modbus.READ_REGS, 2) Modbus.READ_REGS, 2)