diff --git a/custom_components/haier/core/attribute.py b/custom_components/haier/core/attribute.py index 6ba2955..f88717d 100644 --- a/custom_components/haier/core/attribute.py +++ b/custom_components/haier/core/attribute.py @@ -85,8 +85,15 @@ def parse_global(self, attributes: List[dict]): break # 燃气热水器 - if 'outWaterTemp' in all_attribute_keys and 'targetTemp' in all_attribute_keys and 'totalUseGasL' in all_attribute_keys: - yield self._parse_as_gas_water_heater(attributes) + if 'targetTemp' in all_attribute_keys and 'totalUseGasL' in all_attribute_keys: + yield self._parse_as_water_heater(attributes,True,False) + elif 'targetTemperature' in all_attribute_keys and 'currentTemperature' in all_attribute_keys: + # 空气能 + if 'dualHeaterMode' in all_attribute_keys: + yield self._parse_as_water_heater(attributes,False,True) + # 电热水器 + else: + yield self._parse_as_water_heater(attributes,False,False) @staticmethod def _parse_as_sensor(attribute): @@ -178,11 +185,16 @@ def _parse_as_climate(attributes: List[dict], feature_fields: List[str]): return HaierAttribute('climate', 'Climate', Platform.CLIMATE, options, ext) @staticmethod - def _parse_as_gas_water_heater(attributes: List[dict]): + def _parse_as_water_heater(attributes: List[dict], is_gas, is_heat_pump): for attr in attributes: - if attr['name'] == 'targetTemp': - target_temperature_attr = attr - break + if is_gas: + if attr['name'] == 'targetTemp': + target_temperature_attr = attr + break + else: + if attr['name'] == 'targetTemperature': + target_temperature_attr = attr + break else: raise RuntimeError('targetTemp attr not found') @@ -194,9 +206,17 @@ def _parse_as_gas_water_heater(attributes: List[dict]): ext = { 'customize': True, + 'is_gas': is_gas, + 'is_heat_pump': is_heat_pump, } - return HaierAttribute('gas_water_heater', 'GasWaterHeater', Platform.WATER_HEATER, options, ext) + return HaierAttribute( + 'gas_water_heater' if is_gas else 'water_heater', + 'GasWaterHeater' if is_gas else 'WaterHeater', + Platform.WATER_HEATER, + options, + ext + ) @staticmethod def _is_binary_attribute(attribute): diff --git a/custom_components/haier/water_heater.py b/custom_components/haier/water_heater.py index 7e5400f..cb0dc90 100644 --- a/custom_components/haier/water_heater.py +++ b/custom_components/haier/water_heater.py @@ -5,6 +5,9 @@ WaterHeaterEntity, STATE_GAS, SUPPORT_AWAY_MODE, + STATE_PERFORMANCE, + STATE_ELECTRIC, + STATE_HEAT_PUMP, SUPPORT_TARGET_TEMPERATURE, SUPPORT_OPERATION_MODE, ) @@ -31,11 +34,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_e entry, async_add_entities, Platform.WATER_HEATER, - lambda device, attribute: HaierWaterHeater(device, attribute) + lambda device, attribute: HaierGasWaterHeater(device, attribute) if attribute.ext['is_gas'] else HaierWaterHeater(device, attribute) ) -class HaierWaterHeater(HaierAbstractEntity, WaterHeaterEntity): +class HaierGasWaterHeater(HaierAbstractEntity, WaterHeaterEntity): def __init__(self, device: HaierDevice, attribute: HaierAttribute): super().__init__(device, attribute) @@ -58,6 +61,8 @@ def set_temperature(self, **kwargs) -> None: def _update_value(self): if 'outWaterTemp' in self._attributes_data: self._attr_current_temperature = float(self._attributes_data['outWaterTemp']) + else: + self._attr_current_temperature = float(self._attributes_data['targetTemp']) self._attr_target_temperature = float(self._attributes_data['targetTemp']) @@ -91,3 +96,93 @@ def set_operation_mode(self, operation_mode): self._send_command({ 'onOffStatus': power_state }) + +class HaierWaterHeater(HaierAbstractEntity, WaterHeaterEntity): + + def __init__(self, device: HaierDevice, attribute: HaierAttribute): + super().__init__(device, attribute) + self._attr_temperature_unit = TEMP_CELSIUS + self._attr_supported_features = SUPPORT_FLAGS + self._attr_is_heat_pump = self._attribute.ext['is_heat_pump'] + # 默认的0-70温度范围太宽,homekit不支持 + self._attr_min_temp = 35 + self._attr_max_temp = 65 + + @property + def operation_list(self): + """List of available operation modes.""" + if self._attr_is_heat_pump: + return [STATE_OFF, STATE_HEAT_PUMP, STATE_PERFORMANCE] + else: + return [STATE_OFF, STATE_ELECTRIC] + + def set_temperature(self, **kwargs) -> None: + self._send_command({ + 'targetTemperature': kwargs['temperature'] + }) + + def _update_value(self): + if 'currentTemperature' in self._attributes_data: + self._attr_current_temperature = float(self._attributes_data['currentTemperature']) + + self._attr_target_temperature = float(self._attributes_data['targetTemperature']) + + if not try_read_as_bool(self._attributes_data['onOffStatus']): + # 关机状态 + self._attr_current_operation = STATE_OFF + self._attr_is_away_mode_on = True + elif self._attr_is_heat_pump and try_read_as_bool(self._attributes_data['dualHeaterMode']): + # 空气能双源速热 + self._attr_current_operation = STATE_PERFORMANCE + self._attr_is_away_mode_on = False + elif self._attr_is_heat_pump and not try_read_as_bool(self._attributes_data['dualHeaterMode']): + # 空气能节能模式 + self._attr_current_operation = STATE_HEAT_PUMP + self._attr_is_away_mode_on = False + else: + # 电热水器开机状态 + self._attr_current_operation = STATE_ELECTRIC + self._attr_is_away_mode_on = False + + def turn_away_mode_on(self): + """Turn away mode on.""" + self._send_command({ + 'onOffStatus': False + }) + + def turn_away_mode_off(self): + """Turn away mode off.""" + self._send_command({ + 'onOffStatus': True + }) + + def set_operation_mode(self, operation_mode): + """Set operation mode""" + if self._attr_is_heat_pump: + if operation_mode == STATE_HEAT_PUMP: + self._send_command({ + 'onOffStatus': True + }) + self._send_command({ + 'dualHeaterMode': False + }) + elif operation_mode == STATE_PERFORMANCE: + self._send_command({ + 'onOffStatus': True + }) + self._send_command({ + 'dualHeaterMode': True + }) + else: + self._send_command({ + 'onOffStatus': False + }) + + else: + if operation_mode == STATE_ELECTRIC: + power_state = True + else: + power_state = False + self._send_command({ + 'onOffStatus': power_state + }) \ No newline at end of file