Skip to content

Commit

Permalink
Optimize read input registers requests
Browse files Browse the repository at this point in the history
  • Loading branch information
vortizhe committed Feb 22, 2023
1 parent 29af696 commit e75eaf4
Showing 1 changed file with 56 additions and 68 deletions.
124 changes: 56 additions & 68 deletions custom_components/ingeteam_modbus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
BATTERY_STATUS,
BATTERY_BMS_ALARMS,
BATTERY_LIMITATION_REASONS,
AP_REDUCTION_REASONS
AP_REDUCTION_REASONS,
)

_LOGGER = logging.getLogger(__name__)
Expand All @@ -41,7 +41,9 @@
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_PORT): cv.string,
vol.Optional(CONF_MODBUS_ADDRESS, default=DEFAULT_MODBUS_ADDRESS): cv.positive_int,
vol.Optional(
CONF_MODBUS_ADDRESS, default=DEFAULT_MODBUS_ADDRESS
): cv.positive_int,
vol.Optional(CONF_READ_METER, default=DEFAULT_READ_METER): cv.boolean,
vol.Optional(CONF_READ_BATTERY, default=DEFAULT_READ_BATTERY): cv.boolean,
vol.Optional(
Expand Down Expand Up @@ -200,25 +202,22 @@ def read_input_registers(self, unit, address, count):
kwargs = {"unit": unit} if unit else {}
return self._client.read_input_registers(address, count, **kwargs, slave=1)


def read_modbus_data(self):
return (
self.read_modbus_data_status()
and self.read_modbus_data_inverter()
and self.read_modbus_data_meter()
and self.read_modbus_data_pv_field()
and self.read_modbus_data_battery()
)

def read_modbus_data_status(self):
status_data = self.read_input_registers(unit=self._address, address=9, count=8)
status_data = self.read_input_registers(unit=self._address, address=0, count=80)
if status_data.isError():
return False

decoder = BinaryPayloadDecoder.fromRegisters(
status_data.registers, byteorder=Endian.Big
return (
self.read_modbus_data_status(status_data.registers[9:17])
and self.read_modbus_data_battery(status_data.registers[17:31])
and self.read_modbus_data_pv_field(status_data.registers[31:37])
and self.read_modbus_data_inverter(status_data.registers[37:67])
and self.read_modbus_data_meter(status_data.registers[69:73])
)

def read_modbus_data_status(self, registers):
decoder = BinaryPayloadDecoder.fromRegisters(registers, byteorder=Endian.Big)

stop_code = decoder.decode_16bit_uint()
alarm_code = decoder.decode_32bit_uint()
decoder.skip_bytes(6)
Expand All @@ -236,20 +235,15 @@ def read_modbus_data_status(self):
self.data["waiting_time"] = waiting_time

if status in INVERTER_STATUS:
self.data['status'] = INVERTER_STATUS[status]
self.data["status"] = INVERTER_STATUS[status]
else:
self.data['status'] = status
self.data["status"] = status

return True

def read_modbus_data_inverter(self):
status_data = self.read_input_registers(unit=self._address, address=37, count=30)
if status_data.isError():
return False

decoder = BinaryPayloadDecoder.fromRegisters(
status_data.registers, byteorder=Endian.Big
)
def read_modbus_data_inverter(self, registers):

decoder = BinaryPayloadDecoder.fromRegisters(registers, byteorder=Endian.Big)

active_power = decoder.decode_16bit_int()
reactive_power = decoder.decode_16bit_int()
Expand Down Expand Up @@ -285,9 +279,9 @@ def read_modbus_data_inverter(self):
self.data["ap_reduction_ratio"] = ap_reduction_ratio / 10
self.data["ap_reduction_reason"] = ap_reduction_reason
if ap_reduction_reason in AP_REDUCTION_REASONS:
self.data['ap_reduction_reason'] = AP_REDUCTION_REASONS[ap_reduction_reason]
self.data["ap_reduction_reason"] = AP_REDUCTION_REASONS[ap_reduction_reason]
else:
self.data['ap_reduction_reason'] = ap_reduction_reason
self.data["ap_reduction_reason"] = ap_reduction_reason
self.data["reactive_setpoint_type"] = reactive_setpoint_type
self.data["cl_voltage"] = cl_voltage
self.data["cl_current"] = cl_current / 100
Expand All @@ -303,24 +297,17 @@ def read_modbus_data_inverter(self):
self.data["dc_bus_voltage"] = dc_bus_voltage
self.data["internal_temp"] = internal_temp / 10
self.data["rms_diff_current"] = rms_diff_current
self.data["do_1_status"] = BOOLEAN_STATUS[do_1_status]
self.data["do_1_status"] = BOOLEAN_STATUS[do_1_status]
self.data["do_2_status"] = BOOLEAN_STATUS[do_2_status]
self.data["di_drm_status"] = BOOLEAN_STATUS[di_drm_status]
self.data["di_2_status"] = BOOLEAN_STATUS[di_2_status]
self.data["di_3_status"] = BOOLEAN_STATUS[di_3_status]

return True

def read_modbus_data_meter(self):
"""start reading meter data """
meter_data = self.read_input_registers(unit=self._address, address=69, count=4)
if meter_data.isError():
return False
def read_modbus_data_meter(self, registers):
decoder = BinaryPayloadDecoder.fromRegisters(registers, byteorder=Endian.Big)

decoder = BinaryPayloadDecoder.fromRegisters(
meter_data.registers, byteorder=Endian.Big
)

em_voltage = decoder.decode_16bit_uint()
em_freq = decoder.decode_16bit_uint()
em_active_power_data = decoder.decode_16bit_int()
Expand All @@ -330,20 +317,17 @@ def read_modbus_data_meter(self):
self.data["em_voltage"] = round(em_voltage, abs(em_voltage))
self.data["em_freq"] = round(em_freq / 10)
self.data["em_active_power"] = em_active_power if em_active_power >= 0 else 0
self.data["em_active_power_returned"] = em_active_power * -1 if em_active_power < 0 else 0
self.data["em_reactive_power"] = round(em_reactive_power, abs(em_reactive_power))
self.data["em_active_power_returned"] = (
em_active_power * -1 if em_active_power < 0 else 0
)
self.data["em_reactive_power"] = round(
em_reactive_power, abs(em_reactive_power)
)

return True


def read_modbus_data_pv_field(self):
inverter_data = self.read_input_registers(unit=self._address, address=31, count=6)
if inverter_data.isError():
return False

decoder = BinaryPayloadDecoder.fromRegisters(
inverter_data.registers, byteorder=Endian.Big
)
def read_modbus_data_pv_field(self, registers):
decoder = BinaryPayloadDecoder.fromRegisters(registers, byteorder=Endian.Big)

pv1_voltage = decoder.decode_16bit_uint()
pv1_current = decoder.decode_16bit_uint()
Expand All @@ -352,7 +336,7 @@ def read_modbus_data_pv_field(self):
pv2_current = decoder.decode_16bit_uint()
pv2_power = decoder.decode_16bit_uint()

self.data["pv1_voltage"] = pv1_voltage
self.data["pv1_voltage"] = pv1_voltage
self.data["pv1_current"] = pv1_current / 100
self.data["pv1_power"] = pv1_power
self.data["pv2_voltage"] = pv2_voltage
Expand All @@ -363,13 +347,9 @@ def read_modbus_data_pv_field(self):

return True

def read_modbus_data_battery(self):
battery_data = self.read_input_registers(unit=self._address, address=17, count=14)
if battery_data.isError():
return False

def read_modbus_data_battery(self, registers):
decoder = BinaryPayloadDecoder.fromRegisters(
battery_data.registers, byteorder=Endian.Big,wordorder=Endian.Little
registers, byteorder=Endian.Big, wordorder=Endian.Little
)

battery_voltage = decoder.decode_16bit_uint()
Expand All @@ -387,30 +367,38 @@ def read_modbus_data_battery(self):
battery_discharge_limitation_reason = decoder.decode_16bit_uint()
battery_voltage_internal = decoder.decode_16bit_uint()


self.data["battery_voltage"] = battery_voltage / 10
self.data["battery_current"] = battery_current / 100
self.data["battery_discharging_power"] = battery_power if battery_power > 0 else 0
self.data["battery_charging_power"] = battery_power * -1 if battery_power < 0 else 0
self.data["battery_discharging_power"] = (
battery_power if battery_power > 0 else 0
)
self.data["battery_charging_power"] = (
battery_power * -1 if battery_power < 0 else 0
)
self.data["battery_state_of_charge"] = battery_state_of_charge
self.data["battery_state_of_health"] = battery_state_of_health
self.data["battery_charging_voltage"] = battery_charging_voltage / 10
self.data["battery_discharging_voltage"] = battery_discharging_voltage / 10
self.data["battery_charging_current_max"] = battery_charging_current_max / 100
self.data["battery_discharging_current_max"] = battery_discharging_current_max / 100
self.data["battery_discharging_current_max"] = (
battery_discharging_current_max / 100
)
self.data["battery_temp"] = battery_temp / 10
self.data["battery_voltage_internal"] = battery_voltage_internal / 10
self.data['battery_status'] = BATTERY_STATUS[battery_status]
self.data['battery_bms_alarm'] = BATTERY_BMS_ALARMS[battery_bms_alarm]
self.data['battery_discharge_limitation_reason'] = BATTERY_LIMITATION_REASONS[battery_discharge_limitation_reason]
self.data["battery_status"] = BATTERY_STATUS[battery_status]
self.data["battery_bms_alarm"] = BATTERY_BMS_ALARMS[battery_bms_alarm]
self.data["battery_discharge_limitation_reason"] = BATTERY_LIMITATION_REASONS[
battery_discharge_limitation_reason
]

# Some attr are bugged in certain statuses
if battery_status == 7:
self.data['battery_voltage'] = 0
self.data['battery_current'] = 0
self.data['battery_power'] = 0
self.data['battery_charging_current_max'] = 0
self.data['battery_discharging_current_max'] = 0
self.data['battery_bms_alarm'] = "None"
self.data["battery_voltage"] = 0
self.data["battery_current"] = 0
self.data["battery_power"] = 0
self.data["battery_charging_current_max"] = 0
self.data["battery_discharging_current_max"] = 0
self.data["battery_bms_alarm"] = "None"

return True

0 comments on commit e75eaf4

Please sign in to comment.