diff --git a/diematic_server/boiler.py b/diematic_server/boiler.py index bbe6062..4912a5a 100644 --- a/diematic_server/boiler.py +++ b/diematic_server/boiler.py @@ -24,8 +24,9 @@ def __init__(self, uuid, index): if 'type' in register and register['type'] == 'bits': for varname in register['bits']: - self._init_register_value(varname, register['id'], influx) - self.attribute_list.append(varname) + realvarname = varname if type(varname) is str else varname['name'] + self._init_register_value(realvarname, register['id'], influx) + self.attribute_list.append(realvarname) elif 'name' in register and 'id' in register: is_bits = 'type' in register and register['type'] == 'bits' @@ -37,7 +38,6 @@ def __init__(self, uuid, index): def _init_register_value(self, varname, id, influx): # this method is protected by self.lock setattr(self, varname, {'name': varname, 'status': 'init', 'value': None, 'id': id, 'influx': influx}) - # { # 'name': varname, # 'value': registervalue, @@ -50,7 +50,8 @@ def _init_register_value(self, varname, id, influx): def _set_register_value(self, varname, registervalue): # this method is protected by self.lock - previous_value = getattr(self, varname, {'name': varname, 'status': 'init', 'value': registervalue}) + realvarname = varname if type(varname) is str else varname['name'] + previous_value = getattr(self, realvarname, {'name': realvarname, 'status': 'init', 'value': registervalue}) varvalue = previous_value.copy() prestatus = previous_value.get('status') if prestatus == 'init': @@ -61,7 +62,7 @@ def _set_register_value(self, varname, registervalue): varvalue['value'] = registervalue varvalue['read'] = datetime.now().isoformat() varvalue['status'] = status - setattr(self, varname, varvalue) + setattr(self, realvarname, varvalue) def _add_register_field(self, varname, field, value): previous_value = getattr(self, varname) @@ -307,7 +308,8 @@ def _register(self, varname): if register['type'] == 'bits': for i in range(len(register['bits'])): bit_varname = register['bits'][i] - if bit_varname == varname: + checkname = bit_varname if type(bit_varname) is str else bit_varname['name'] + if checkname == varname: return register else: if register.get('name') == varname: @@ -329,10 +331,13 @@ def _update_register(self, register): self._set_register_value(varname, register_value) for i in range(len(register['bits'])): bit_varname = register['bits'][i] - if bit_varname == 'io_unused': + realvarname = bit_varname if type(bit_varname) is str else bit_varname['name'] + if realvarname == 'io_unused': continue bit_value = register_value >> i & 1 - self._set_register_value(bit_varname, bit_value) + self._set_register_value(realvarname, bit_value) + if 'desc' in bit_varname: + self._add_register_field(bit_varname['name'], 'desc', bit_varname['desc']) else: if 'name' in register: varname = register.get('name') @@ -431,10 +436,11 @@ def prepare_write(self, write): overallvalue = 0 for i in range(len(register['bits'])): bit_varname = register['bits'][i] - if bit_varname == 'io_unused': + checkvarname = bit_varname if type(bit_varname) is str else bit_varname['name'] + if checkvarname == 'io_unused': continue - if bit_varname != write['name']: - bit_value = getattr(self, bit_varname)['value'] << i + if checkvarname != write['name']: + bit_value = getattr(self, checkvarname)['value'] << i overallvalue = overallvalue | bit_value else: bit_value = write['newvalue'] << i diff --git a/diematic_server/diematicd.py b/diematic_server/diematicd.py index af8eff0..3c14f91 100644 --- a/diematic_server/diematicd.py +++ b/diematic_server/diematicd.py @@ -418,17 +418,39 @@ def home_assistant_discovery(self, data: dict[str, Any]) -> None: suggested_display_precision = register.get('suggested_display_precision', None) self.ha_discover( prefix, uuid, model, sw_version, retain, subtopic, device_name, - component=component, object_id=object_id, device_class=device_class, - entity_category=entity_category, icon=icon, state_class=state_class, + component=component, object_id=object_id, entity_category=entity_category, + icon=icon, + device_class=device_class, state_class=state_class, unit=unit, min=min, max=max, step=step, value_template=value_template, command_template=command_template, options=options, suggested_display_precision=suggested_display_precision ) - - def ha_discover(self, prefix:str, uuid:str, model: str, sw_version: str, retain: bool, subtopic: str, device_name: str, - component: str, object_id: str, device_class: str, entity_category: str, icon: str, state_class: str, unit: str, - min: float = None, max: float = None, step: float = None, value_template: str = None, command_template: str = None, - options: list[str] = None, suggested_display_precision: int = None + + bitstypes = [b for x in self.MyBoiler.index if x.get('type', None) == 'bits' and x.get('bits', None) is not None for b in x['bits'] ] + for bit in bitstypes: + if type(bit) is dict: + self.ha_discover( + prefix, uuid, model, sw_version, retain, subtopic, device_name, + component='binary_sensor', object_id=bit['name'], + entity_category='diagnostic', icon='mdi:pump', payload_on='1', payload_off='0' + ) + + # for circuit in ("a", "b", "c"): + # if f"monday_{circuit}_0000_0030" in bitstypes: + # self.ha_discover( + # prefix, uuid, model, sw_version, retain, subtopic, device_name, + # component='binary_sensor', object_id=f"io_circ_{circuit}_pump_on", + # entity_category='diagnostic', icon='mdi:pump', payload_on='1', payload_off='0' + # ) + + + def ha_discover(self, prefix:str, uuid:str, model: str, sw_version: str, retain: bool, subtopic: str, + device_name: str, component: str, object_id: str, entity_category: str, icon: str, + device_class: str = None, state_class: str = None, unit: str = None, + min: float = None, max: float = None, step: float = None, + value_template: str = None, command_template: str = None, + options: list[str] = None, suggested_display_precision: int = None, + payload_on: str = None, payload_off: str = None ): entity_name = self.MyBoiler.get_register_field(object_id, 'desc') topic_head = f'{prefix}/{component}/{uuid}/{object_id}' @@ -492,6 +514,12 @@ def ha_discover(self, prefix:str, uuid:str, model: str, sw_version: str, retain: self.command_topic(topic_head, object_id, config) if component == 'sensor': config['platform'] = 'sensor' + if component == 'binary_sensor': + config['platform'] = 'binary_sensor' + if payload_on is not None: + config['payload_on'] = payload_on + if payload_off is not None: + config['payload_off'] = payload_off config_str = json.dumps(config, indent=2) self.mqttc.publish(topic, config_str).wait_for_publish() diff --git a/diematic_server/webserver.py b/diematic_server/webserver.py index d88fda4..4bb5398 100644 --- a/diematic_server/webserver.py +++ b/diematic_server/webserver.py @@ -70,8 +70,11 @@ def __init__(self, boiler) -> None: for register in boiler.index: if 'type' in list(register) and register['type'] == 'bits': for bit in register['bits']: - if bit != "io_unused": - DiematicWebRequestHandler.parameter_names.append(bit) + if type(bit) is str: + if bit != "io_unused": + DiematicWebRequestHandler.parameter_names.append(bit) + elif type(bit) is dict: + DiematicWebRequestHandler.parameter_names.append(bit['name']) elif 'name' in list(register): DiematicWebRequestHandler.parameter_names.append(register['name']) DiematicWebRequestHandler.parameter_names.sort() diff --git a/etc/diematic.yaml b/etc/diematic.yaml index e114f9f..ce76a63 100644 --- a/etc/diematic.yaml +++ b/etc/diematic.yaml @@ -1232,12 +1232,18 @@ registers: - io_burder_1_2 - io_hydraulic_valve_open - io_hydraulic_valve_close - - io_boiler_pump + - bit: + name: io_boiler_pump + desc: Boiler pump - id: 475 type: bits bits: - - io_dhw_pump_on - - io_circ_a_pump_on + - bit: + name: io_dhw_pump_on + desc: Hot water pump + - bit: + name: io_circ_a_pump_on + desc: Circuit A pump - io_circ_a_3wv_open - io_circ_a_3wv_close - io_circ_b_pump_on @@ -1246,9 +1252,15 @@ registers: - io_circ_c_pump_on - io_circ_c_3wv_open - io_circ_c_3wv_close - - io_aux_pump_1_on - - io_aux_pump_2_on - - io_aux_pump_3_on + - bit: + name: io_aux_pump_1_on + desc: Aux pump 1 + - bit: + name: io_aux_pump_2_on + desc: Aux pump 2 + - bit: + name: io_aux_pump_3_on + desc: Aux pump 3 - io_phone_output - id: 503 name: power @@ -1592,7 +1604,9 @@ registers: - io_unused - io_direct_circuit_off - io_direct_circuit_3wv_off - - io_secondary_pump + - bit: + name: io_secondary_pump + desc: Secondary pump - io_unused - io_unused - io_unused