Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

water_heater实体增加支持空气能和电热水器 #125

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 27 additions & 7 deletions custom_components/haier/core/attribute.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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')

Expand All @@ -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):
Expand Down
99 changes: 97 additions & 2 deletions custom_components/haier/water_heater.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
WaterHeaterEntity,
STATE_GAS,
SUPPORT_AWAY_MODE,
STATE_PERFORMANCE,
STATE_ELECTRIC,
STATE_HEAT_PUMP,
SUPPORT_TARGET_TEMPERATURE,
SUPPORT_OPERATION_MODE,
)
Expand All @@ -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)
Expand All @@ -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'])

Expand Down Expand Up @@ -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
})