Skip to content

Commit

Permalink
Dev -> Main v0.6.9 (#226)
Browse files Browse the repository at this point in the history
* - updated water heater naming

* - initial support for built-in AC units

* Add support for Built-In AC Unit

Built-In AC unit operation and function is similar to a WAC.
`gehomesdk` version bumped from 0.4.25 to 0.4.27 to include latest
ErdApplianceType enum.

* Update README.md

Update README.md to include Built-In AC as supported device

* - updated zero serial number detection (resolves #89)

* - updated version
- updated changelog

* - hopefully fixed recursion bug with numbers

* - added cooktop support

* - fixed circular reference

* Add support for fridges with reduced support for ERD codes (no turbo mode, no current temperature reporting, no temperature setpoint limit reporting, no door status reporting). This change has been tested on a Fisher & Paykel RF610AA.

* - added dual dishwasher support
- updated documentation
- version bumps

* - added water heater support

* - added basic espresso maker device

* - bugfixes

* - rewrote initialization (resolves #99)

* - added logic to prevent double registration of entities

* - added correct min/max temps for water heaters

* Fix CoffeeMaker after the NumberEntity refactoring

* - added fix for CGY366P2TS1 (#116) to try to get the cooktop status, but fail more gracefully if it isn't supported

* - fixed region setting in update coordinator

* - version bump
- doc update
- string fixes

* - updated the temperature conversion to use non-deprecated HASS methods

* - updated documentation (@gleepwurp)

* - more documentation updates

* - updated dishwasher for new functionality
- updated documentation

* updated uom for liquid volume per HA specifications

* - fixed typo in oven (#149)

* - updated change log
- fixed oven light control (#144)

* - fixed issues with dishwasher (#155)
- added oim descaling sensor (#154)
- version bump

* - updated change log

* updated dual dishwasher for changes to gehomesdk (#161)

Co-authored-by: na4ma4 <[email protected]>

* await disconnect when unloading (#169)

Fixes #164.

* Check for upper oven light when there is a lower oven (#174)

Resolves issue #121

* - added oven warming drawers
- simplified oven entity logic

* - fixed issues with the new oven initialization logic

* - fixed bad type import for warming drawer

* -added iot class (#181)

* - updated the gehomesdk version requirement

* - gehomesdk version bump

* - added dehumidifier (#114)

* - dehumidifier appliance type fix

* - added oven state sensors (#175)

* - updated change logs
- updated sdk version requirement

* - removed target select
- added dehumidifier entity
- sdk version bump

* - updated dehumidifier icon

* - added humidifier platform

* - fixed typos in humidifier class

* - fixed copy/paste error

* - sdk version requirement bump

* - sdk version bump

* - updated dehumidifier to handle target precision
- updated dehumidifier sensor value conversion

* - missed a commit

* - SDK version bump

* Set device class on day flow for water softeners (#207)

This should allow sensor to be added to the energy dashboard.

* - removed references to _hass in update coordinator
- removed hass attribute in ge_entity
- version bump

* bumped gehomesdk version requirement

* - added fridge/freezer controls

* - documentation updates

* - fixed error when reloading integration

* - added additional update error handling

* - fixed coordinator bug

* - added additional logic to handle non-standard ready conditions

* Set device class on day flow for water filters (#209)

* - bumped sdk version requirement

* added new style cooktop status support (#159)

* Update deprecated constants or remove unused ones (#219)

* - updated documentation

---------

Co-authored-by: Rob Schmidt <[email protected]>
Co-authored-by: Federico Sevilla <[email protected]>
Co-authored-by: alexanv1 <[email protected]>
Co-authored-by: na4ma4 <[email protected]>
Co-authored-by: na4ma4 <[email protected]>
Co-authored-by: Alex Peters <[email protected]>
Co-authored-by: Chris Petersen <[email protected]>
Co-authored-by: Nathan Fiscus <[email protected]>
Co-authored-by: Jason Foley <[email protected]>
Co-authored-by: myztillx <[email protected]>
  • Loading branch information
11 people authored Jan 28, 2024
1 parent 3b6e657 commit efe500f
Show file tree
Hide file tree
Showing 42 changed files with 356 additions and 217 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@

# GE Home Appliances (SmartHQ) Changelog

## 0.6.9

- Added additional fridge controls [#200]
- Bugfix: Additional auth stability improvements [#215, #211]
- Bugfix: Removed deprecated constants [#218]

## 0.6.8

- Added Dehumidifier [#114]
Expand Down
12 changes: 10 additions & 2 deletions custom_components/ge_home/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,13 @@ def async_devices_discovered(apis: list[ApplianceApi]):
]
_LOGGER.debug(f'Found {len(entities):d} unregistered binary sensors')
async_add_entities(entities)

async_dispatcher_connect(hass, coordinator.signal_ready, async_devices_discovered)

#if we're already initialized at this point, call device
#discovery directly, otherwise add a callback based on the
#ready signal
if coordinator.initialized:
async_devices_discovered(coordinator.appliance_apis.values())
else:
# add the ready signal and register the remove callback
coordinator.add_signal_remove_callback(
async_dispatcher_connect(hass, coordinator.signal_ready, async_devices_discovered))
10 changes: 9 additions & 1 deletion custom_components/ge_home/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,12 @@ def async_devices_discovered(apis: list[ApplianceApi]):
_LOGGER.debug(f'Found {len(entities):d} unregistered buttons ')
async_add_entities(entities)

async_dispatcher_connect(hass, coordinator.signal_ready, async_devices_discovered)
#if we're already initialized at this point, call device
#discovery directly, otherwise add a callback based on the
#ready signal
if coordinator.initialized:
async_devices_discovered(coordinator.appliance_apis.values())
else:
# add the ready signal and register the remove callback
coordinator.add_signal_remove_callback(
async_dispatcher_connect(hass, coordinator.signal_ready, async_devices_discovered))
10 changes: 9 additions & 1 deletion custom_components/ge_home/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,12 @@ def async_devices_discovered(apis: list[ApplianceApi]):
_LOGGER.debug(f'Found {len(entities):d} unregistered climate entities')
async_add_entities(entities)

async_dispatcher_connect(hass, coordinator.signal_ready, async_devices_discovered)
#if we're already initialized at this point, call device
#discovery directly, otherwise add a callback based on the
#ready signal
if coordinator.initialized:
async_devices_discovered(coordinator.appliance_apis.values())
else:
# add the ready signal and register the remove callback
coordinator.add_signal_remove_callback(
async_dispatcher_connect(hass, coordinator.signal_ready, async_devices_discovered))
4 changes: 2 additions & 2 deletions custom_components/ge_home/devices/cooktop.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from typing import List
from gehomesdk.erd.erd_data_type import ErdDataType

from homeassistant.const import DEVICE_CLASS_POWER_FACTOR
from homeassistant.components.sensor import SensorDeviceClass
from homeassistant.helpers.entity import Entity
from gehomesdk import (
ErdCode,
Expand Down Expand Up @@ -44,7 +44,7 @@ def get_all_entities(self) -> List[Entity]:
cooktop_entities.append(GeErdPropertyBinarySensor(self, ErdCode.COOKTOP_STATUS, prop+".on"))
cooktop_entities.append(GeErdPropertyBinarySensor(self, ErdCode.COOKTOP_STATUS, prop+".synchronized"))
if not v.on_off_only:
cooktop_entities.append(GeErdPropertySensor(self, ErdCode.COOKTOP_STATUS, prop+".power_pct", icon_override="mdi:fire", device_class_override=DEVICE_CLASS_POWER_FACTOR, data_type_override=ErdDataType.INT))
cooktop_entities.append(GeErdPropertySensor(self, ErdCode.COOKTOP_STATUS, prop+".power_pct", icon_override="mdi:fire", device_class_override=SensorDeviceClass.POWER_FACTOR, data_type_override=ErdDataType.INT))

return base_entities + cooktop_entities

Expand Down
20 changes: 16 additions & 4 deletions custom_components/ge_home/devices/fridge.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from homeassistant.components.binary_sensor import DEVICE_CLASS_PROBLEM
from homeassistant.const import DEVICE_CLASS_TEMPERATURE
from homeassistant.components.sensor import SensorDeviceClass
import logging
from typing import List

Expand Down Expand Up @@ -31,7 +31,8 @@
GeDispenser,
GeErdPropertySensor,
GeErdPropertyBinarySensor,
ConvertableDrawerModeOptionsConverter
ConvertableDrawerModeOptionsConverter,
GeFridgeIceControlSwitch
)

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -61,7 +62,10 @@ def get_all_entities(self) -> List[Entity]:
proximity_light: ErdOnOff = self.try_get_erd_value(ErdCode.PROXIMITY_LIGHT)
display_mode: ErdOnOff = self.try_get_erd_value(ErdCode.DISPLAY_MODE)
lockout_mode: ErdOnOff = self.try_get_erd_value(ErdCode.LOCKOUT_MODE)

turbo_cool: ErdOnOff = self.try_get_erd_value(ErdCode.TURBO_COOL_STATUS)
turbo_freeze: ErdOnOff = self.try_get_erd_value(ErdCode.TURBO_FREEZE_STATUS)
ice_boost: ErdOnOff = self.try_get_erd_value(ErdCode.FRIDGE_ICE_BOOST)

units = self.hass.config.units

# Common entities
Expand All @@ -80,8 +84,11 @@ def get_all_entities(self) -> List[Entity]:
GeErdPropertySensor(self, ErdCode.CURRENT_TEMPERATURE, "fridge"),
GeFridge(self),
])
if turbo_cool is not None:
fridge_entities.append(GeErdSwitch(self, ErdCode.FRIDGE_ICE_BOOST))
if(ice_maker_control and ice_maker_control.status_fridge != ErdOnOff.NA):
fridge_entities.append(GeErdPropertyBinarySensor(self, ErdCode.ICE_MAKER_CONTROL, "status_fridge"))
fridge_entities.append(GeFridgeIceControlSwitch(self, "fridge"))
if(water_filter and water_filter != ErdFilterStatus.NA):
fridge_entities.append(GeErdSensor(self, ErdCode.WATER_FILTER_STATUS))
if(air_filter and air_filter != ErdFilterStatus.NA):
Expand All @@ -105,8 +112,13 @@ def get_all_entities(self) -> List[Entity]:
GeErdPropertySensor(self, ErdCode.CURRENT_TEMPERATURE, "freezer"),
GeFreezer(self),
])
if turbo_freeze is not None:
freezer_entities.append(GeErdSwitch(self, ErdCode.TURBO_FREEZE_STATUS))
if ice_boost is not None:
freezer_entities.append(GeErdSwitch(self, ErdCode.FRIDGE_ICE_BOOST))
if(ice_maker_control and ice_maker_control.status_freezer != ErdOnOff.NA):
freezer_entities.append(GeErdPropertyBinarySensor(self, ErdCode.ICE_MAKER_CONTROL, "status_freezer"))
freezer_entities.append(GeFridgeIceControlSwitch(self, "freezer"))
if(ice_bucket_status and ice_bucket_status.is_present_freezer):
freezer_entities.append(GeErdPropertySensor(self, ErdCode.ICE_MAKER_BUCKET_STATUS, "state_full_freezer"))

Expand All @@ -117,7 +129,7 @@ def get_all_entities(self) -> List[Entity]:
GeErdSensor(self, ErdCode.HOT_WATER_SET_TEMP),
GeErdPropertySensor(self, ErdCode.HOT_WATER_STATUS, "status", icon_override="mdi:information-outline"),
GeErdPropertySensor(self, ErdCode.HOT_WATER_STATUS, "time_until_ready", icon_override="mdi:timer-outline"),
GeErdPropertySensor(self, ErdCode.HOT_WATER_STATUS, "current_temp", device_class_override=DEVICE_CLASS_TEMPERATURE, data_type_override=ErdDataType.INT),
GeErdPropertySensor(self, ErdCode.HOT_WATER_STATUS, "current_temp", device_class_override=SensorDeviceClass.TEMPERATURE, data_type_override=ErdDataType.INT),
GeErdPropertyBinarySensor(self, ErdCode.HOT_WATER_STATUS, "faulted", device_class_override=DEVICE_CLASS_PROBLEM),
GeDispenser(self)
])
Expand Down
21 changes: 15 additions & 6 deletions custom_components/ge_home/devices/oven.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from typing import List
from gehomesdk.erd.erd_data_type import ErdDataType

from homeassistant.const import DEVICE_CLASS_POWER_FACTOR
from homeassistant.components.sensor import SensorDeviceClass
from homeassistant.helpers.entity import Entity
from gehomesdk import (
ErdCode,
Expand Down Expand Up @@ -100,18 +100,27 @@ def get_all_entities(self) -> List[Entity]:
if oven_config.has_warming_drawer and warm_drawer is not None:
oven_entities.append(GeErdSensor(self, ErdCode.WARMING_DRAWER_STATE))

if cooktop_config == ErdCooktopConfig.PRESENT:
if cooktop_config == ErdCooktopConfig.PRESENT:
# attempt to get the cooktop status using legacy status
cooktop_status_erd = ErdCode.COOKTOP_STATUS
cooktop_status: CooktopStatus = self.try_get_erd_value(ErdCode.COOKTOP_STATUS)

# if we didn't get it, try using the new version
if cooktop_status is None:
cooktop_status_erd = ErdCode.COOKTOP_STATUS_EXT
cooktop_status: CooktopStatus = self.try_get_erd_value(ErdCode.COOKTOP_STATUS_EXT)

# if we got a status through either mechanism, we can add the entities
if cooktop_status is not None:
cooktop_entities.append(GeErdBinarySensor(self, ErdCode.COOKTOP_STATUS))
cooktop_entities.append(GeErdBinarySensor(self, cooktop_status_erd))

for (k, v) in cooktop_status.burners.items():
if v.exists:
prop = self._camel_to_snake(k)
cooktop_entities.append(GeErdPropertyBinarySensor(self, ErdCode.COOKTOP_STATUS, prop+".on"))
cooktop_entities.append(GeErdPropertyBinarySensor(self, ErdCode.COOKTOP_STATUS, prop+".synchronized"))
cooktop_entities.append(GeErdPropertyBinarySensor(self, cooktop_status_erd, prop+".on"))
cooktop_entities.append(GeErdPropertyBinarySensor(self, cooktop_status_erd, prop+".synchronized"))
if not v.on_off_only:
cooktop_entities.append(GeErdPropertySensor(self, ErdCode.COOKTOP_STATUS, prop+".power_pct", icon_override="mdi:fire", device_class_override=DEVICE_CLASS_POWER_FACTOR, data_type_override=ErdDataType.INT))
cooktop_entities.append(GeErdPropertySensor(self, cooktop_status_erd, prop+".power_pct", icon_override="mdi:fire", device_class_override=SensorDeviceClass.POWER_FACTOR, data_type_override=ErdDataType.INT))

return base_entities + oven_entities + cooktop_entities

Expand Down
2 changes: 1 addition & 1 deletion custom_components/ge_home/devices/water_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def get_all_entities(self) -> List[Entity]:
GeErdBinarySensor(self, ErdCode.WH_FILTER_MANUAL_MODE, icon_on_override="mdi:human", icon_off_override="mdi:robot"),
GeErdBinarySensor(self, ErdCode.WH_FILTER_LEAK_VALIDITY, device_class_override="moisture"),
GeErdPropertySensor(self, ErdCode.WH_FILTER_FLOW_RATE, "flow_rate"),
GeErdSensor(self, ErdCode.WH_FILTER_DAY_USAGE),
GeErdSensor(self, ErdCode.WH_FILTER_DAY_USAGE, device_class_override="water"),
GeErdPropertySensor(self, ErdCode.WH_FILTER_LIFE_REMAINING, "life_remaining"),
GeErdBinarySensor(self, ErdCode.WH_FILTER_FLOW_ALERT, device_class_override="moisture"),
]
Expand Down
2 changes: 1 addition & 1 deletion custom_components/ge_home/devices/water_softener.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def get_all_entities(self) -> List[Entity]:
GeErdBinarySensor(self, ErdCode.WH_FILTER_MANUAL_MODE, icon_on_override="mdi:human", icon_off_override="mdi:robot"),
GeErdPropertySensor(self, ErdCode.WH_FILTER_FLOW_RATE, "flow_rate"),
GeErdBinarySensor(self, ErdCode.WH_FILTER_FLOW_ALERT, device_class_override="moisture"),
GeErdSensor(self, ErdCode.WH_FILTER_DAY_USAGE),
GeErdSensor(self, ErdCode.WH_FILTER_DAY_USAGE, device_class_override="water"),
GeErdSensor(self, ErdCode.WH_SOFTENER_ERROR_CODE, icon_override="mdi:alert-circle"),
GeErdBinarySensor(self, ErdCode.WH_SOFTENER_LOW_SALT, icon_on_override="mdi:alert", icon_off_override="mdi:grain"),
GeErdSensor(self, ErdCode.WH_SOFTENER_SHUTOFF_VALVE_STATE, icon_override="mdi:state-machine"),
Expand Down
5 changes: 0 additions & 5 deletions custom_components/ge_home/entities/ac/fan_mode_options.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import logging
from typing import Any, List, Optional

from homeassistant.components.climate.const import (
HVAC_MODE_AUTO,
HVAC_MODE_COOL,
HVAC_MODE_FAN_ONLY,
)
from gehomesdk import ErdAcFanSetting
from ..common import OptionsConverter

Expand Down
24 changes: 10 additions & 14 deletions custom_components/ge_home/entities/ac/ge_biac_climate.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import logging
from typing import Any, List, Optional

from homeassistant.components.climate.const import (
HVAC_MODE_AUTO,
HVAC_MODE_COOL,
HVAC_MODE_FAN_ONLY,
)
from homeassistant.components.climate import HVACMode
from gehomesdk import ErdAcOperationMode
from ...devices import ApplianceApi
from ..common import GeClimate, OptionsConverter
Expand All @@ -16,28 +12,28 @@
class BiacHvacModeOptionsConverter(OptionsConverter):
@property
def options(self) -> List[str]:
return [HVAC_MODE_AUTO, HVAC_MODE_COOL, HVAC_MODE_FAN_ONLY]
return [HVACMode.AUTO, HVACMode.COOL, HVACMode.FAN_ONLY]
def from_option_string(self, value: str) -> Any:
try:
return {
HVAC_MODE_AUTO: ErdAcOperationMode.ENERGY_SAVER,
HVAC_MODE_COOL: ErdAcOperationMode.COOL,
HVAC_MODE_FAN_ONLY: ErdAcOperationMode.FAN_ONLY
HVACMode.AUTO: ErdAcOperationMode.ENERGY_SAVER,
HVACMode.COOL: ErdAcOperationMode.COOL,
HVACMode.FAN_ONLY: ErdAcOperationMode.FAN_ONLY
}.get(value)
except:
_LOGGER.warn(f"Could not set HVAC mode to {value.upper()}")
return ErdAcOperationMode.COOL
def to_option_string(self, value: Any) -> Optional[str]:
try:
return {
ErdAcOperationMode.ENERGY_SAVER: HVAC_MODE_AUTO,
ErdAcOperationMode.AUTO: HVAC_MODE_AUTO,
ErdAcOperationMode.COOL: HVAC_MODE_COOL,
ErdAcOperationMode.FAN_ONLY: HVAC_MODE_FAN_ONLY
ErdAcOperationMode.ENERGY_SAVER: HVACMode.AUTO,
ErdAcOperationMode.AUTO: HVACMode.AUTO,
ErdAcOperationMode.COOL: HVACMode.COOL,
ErdAcOperationMode.FAN_ONLY: HVACMode.FAN_ONLY
}.get(value)
except:
_LOGGER.warn(f"Could not determine operation mode mapping for {value}")
return HVAC_MODE_COOL
return HVACMode.COOL

class GeBiacClimate(GeClimate):
"""Class for Built-In AC units"""
Expand Down
36 changes: 13 additions & 23 deletions custom_components/ge_home/entities/ac/ge_pac_climate.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
import logging
from typing import Any, List, Optional


from homeassistant.const import (
TEMP_FAHRENHEIT
)
from homeassistant.components.climate.const import (
HVAC_MODE_AUTO,
HVAC_MODE_COOL,
HVAC_MODE_DRY,
HVAC_MODE_FAN_ONLY,
HVAC_MODE_HEAT,
)
from homeassistant.components.climate import HVACMode
from gehomesdk import ErdCode, ErdAcOperationMode, ErdSacAvailableModes, ErdSacTargetTemperatureRange
from ...devices import ApplianceApi
from ..common import GeClimate, OptionsConverter
Expand All @@ -25,34 +15,34 @@ def __init__(self, available_modes: ErdSacAvailableModes):

@property
def options(self) -> List[str]:
modes = [HVAC_MODE_COOL, HVAC_MODE_FAN_ONLY]
modes = [HVACMode.COOL, HVACMode.FAN_ONLY]
if self._available_modes and self._available_modes.has_heat:
modes.append(HVAC_MODE_HEAT)
modes.append(HVACMode.HEAT)
if self._available_modes and self._available_modes.has_dry:
modes.append(HVAC_MODE_DRY)
modes.append(HVACMode.DRY)
return modes
def from_option_string(self, value: str) -> Any:
try:
return {
HVAC_MODE_COOL: ErdAcOperationMode.COOL,
HVAC_MODE_HEAT: ErdAcOperationMode.HEAT,
HVAC_MODE_FAN_ONLY: ErdAcOperationMode.FAN_ONLY,
HVAC_MODE_DRY: ErdAcOperationMode.DRY
HVACMode.COOL: ErdAcOperationMode.COOL,
HVACMode.HEAT: ErdAcOperationMode.HEAT,
HVACMode.FAN_ONLY: ErdAcOperationMode.FAN_ONLY,
HVACMode.DRY: ErdAcOperationMode.DRY
}.get(value)
except:
_LOGGER.warn(f"Could not set HVAC mode to {value.upper()}")
return ErdAcOperationMode.COOL
def to_option_string(self, value: Any) -> Optional[str]:
try:
return {
ErdAcOperationMode.COOL: HVAC_MODE_COOL,
ErdAcOperationMode.HEAT: HVAC_MODE_HEAT,
ErdAcOperationMode.DRY: HVAC_MODE_DRY,
ErdAcOperationMode.FAN_ONLY: HVAC_MODE_FAN_ONLY
ErdAcOperationMode.COOL: HVACMode.COOL,
ErdAcOperationMode.HEAT: HVACMode.HEAT,
ErdAcOperationMode.DRY: HVACMode.DRY,
ErdAcOperationMode.FAN_ONLY: HVACMode.FAN_ONLY
}.get(value)
except:
_LOGGER.warn(f"Could not determine operation mode mapping for {value}")
return HVAC_MODE_COOL
return HVACMode.COOL

class GePacClimate(GeClimate):
"""Class for Portable AC units"""
Expand Down
Loading

0 comments on commit efe500f

Please sign in to comment.