Skip to content

Commit

Permalink
Maintenance
Browse files Browse the repository at this point in the history
- Fixed "unsupported value type" error with "Standby" sensor (issue ollo69#174)
- Added oven "Current Temperature" sensors
- Enabled more sensors by default for wash devices
  • Loading branch information
ollo69 committed Jun 11, 2021
1 parent 920a198 commit 62f64bb
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 36 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![](https://img.shields.io/badge/COMMUNITY-FORUM-success?style=for-the-badge)](https://community.home-assistant.io)

# LG ThinQ Devices integration for HomeAssistant
A Homeassistant custom component to monitor LG Air Conditioner, Washer, Dryer, DishWasher, Refrigerator, Styler and Range
A Homeassistant custom component to monitor and control LG Air Conditioner, Washer, Dryer, DishWasher, Refrigerator, Styler and Range
using ThinQ API based on [WideQ project][wideq].<br/>

**Important Version note:**
Expand Down
2 changes: 1 addition & 1 deletion custom_components/smartthinq_sensors/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Support to interface with LGE ThinQ Devices.
"""

__version__ = "0.8.10"
__version__ = "0.8.11"
PROJECT_URL = "https://github.com/ollo69/ha-smartthinq-sensors/"
ISSUE_URL = "{}issues".format(PROJECT_URL)

Expand Down
2 changes: 1 addition & 1 deletion custom_components/smartthinq_sensors/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
"requirements": ["pycountry>=20.7.3"],
"config_flow": true,
"iot_class": "cloud_polling",
"version": "0.8.10"
"version": "0.8.11"
}
62 changes: 42 additions & 20 deletions custom_components/smartthinq_sensors/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
FEAT_COOKTOP_CENTER_STATE,
FEAT_COOKTOP_RIGHT_FRONT_STATE,
FEAT_COOKTOP_RIGHT_REAR_STATE,
FEAT_OVEN_LOWER_CURRENT_TEMP,
FEAT_OVEN_LOWER_STATE,
FEAT_OVEN_UPPER_CURRENT_TEMP,
FEAT_OVEN_UPPER_STATE,
)

Expand Down Expand Up @@ -147,6 +149,12 @@
ATTR_VALUE_FN: lambda x: x._power_state,
ATTR_ENABLED: True,
},
ATTR_CURRENT_COURSE: {
ATTR_MEASUREMENT_NAME: "Current Course",
ATTR_ICON: "mdi:pin-outline",
ATTR_VALUE_FN: lambda x: x._current_course,
ATTR_ENABLED: True,
},
FEAT_RUN_STATE: {
ATTR_MEASUREMENT_NAME: "Run State",
ATTR_ICON: DEFAULT_ICON,
Expand All @@ -159,51 +167,51 @@
ATTR_VALUE_FEAT: FEAT_PROCESS_STATE,
ATTR_ENABLED: True,
},
FEAT_PRE_STATE: {
ATTR_MEASUREMENT_NAME: "Pre State",
ATTR_ICON: DEFAULT_ICON,
ATTR_VALUE_FEAT: FEAT_PRE_STATE,
},
FEAT_ERROR_MSG: {
ATTR_MEASUREMENT_NAME: "Error Message",
ATTR_ICON: "mdi:alert-circle-outline",
ATTR_VALUE_FEAT: FEAT_ERROR_MSG,
},
FEAT_TUBCLEAN_COUNT: {
ATTR_MEASUREMENT_NAME: "Tube Clean Counter",
ATTR_ICON: DEFAULT_ICON,
ATTR_VALUE_FEAT: FEAT_TUBCLEAN_COUNT,
},
FEAT_SPINSPEED: {
ATTR_MEASUREMENT_NAME: "Spin Speed",
ATTR_ICON: "mdi:rotate-3d",
ATTR_VALUE_FEAT: FEAT_SPINSPEED,
ATTR_ENABLED: True,
},
FEAT_WATERTEMP: {
ATTR_MEASUREMENT_NAME: "Water Temp",
ATTR_ICON: "mdi:thermometer-lines",
ATTR_VALUE_FEAT: FEAT_WATERTEMP,
ATTR_ENABLED: True,
},
FEAT_TEMPCONTROL: {
ATTR_MEASUREMENT_NAME: "Temp Control",
ATTR_ICON: "mdi:thermometer-lines",
ATTR_VALUE_FEAT: FEAT_TEMPCONTROL,
ATTR_ENABLED: True,
},
FEAT_DRYLEVEL: {
ATTR_MEASUREMENT_NAME: "Dry Level",
ATTR_ICON: "mdi:tumble-dryer",
ATTR_VALUE_FEAT: FEAT_DRYLEVEL,
ATTR_ENABLED: True,
},
FEAT_ERROR_MSG: {
ATTR_MEASUREMENT_NAME: "Error Message",
ATTR_ICON: "mdi:alert-circle-outline",
ATTR_VALUE_FEAT: FEAT_ERROR_MSG,
ATTR_ENABLED: True,
},
FEAT_PRE_STATE: {
ATTR_MEASUREMENT_NAME: "Pre State",
ATTR_ICON: DEFAULT_ICON,
ATTR_VALUE_FEAT: FEAT_PRE_STATE,
},
FEAT_TUBCLEAN_COUNT: {
ATTR_MEASUREMENT_NAME: "Tube Clean Counter",
ATTR_ICON: DEFAULT_ICON,
ATTR_VALUE_FEAT: FEAT_TUBCLEAN_COUNT,
},
FEAT_HALFLOAD: {
ATTR_MEASUREMENT_NAME: "Half Load",
ATTR_ICON: "mdi:circle-half-full",
ATTR_VALUE_FEAT: FEAT_HALFLOAD,
},
ATTR_CURRENT_COURSE: {
ATTR_MEASUREMENT_NAME: "Current Course",
ATTR_ICON: "mdi:pin-outline",
ATTR_VALUE_FN: lambda x: x._current_course,
},
ATTR_INITIAL_TIME: {
ATTR_MEASUREMENT_NAME: "Initial Time",
ATTR_ICON: "mdi:clock-outline",
Expand Down Expand Up @@ -394,13 +402,27 @@
ATTR_VALUE_FN: lambda x: x._oven_lower_target_temp,
ATTR_ENABLED: True,
},
FEAT_OVEN_LOWER_CURRENT_TEMP: {
ATTR_MEASUREMENT_NAME: "Oven Lower Current Temperature",
ATTR_UNIT_FN: lambda x: x._oven_temp_unit,
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
ATTR_VALUE_FEAT: FEAT_OVEN_LOWER_CURRENT_TEMP,
ATTR_ENABLED: True,
},
ATTR_OVEN_UPPER_TARGET_TEMP: {
ATTR_MEASUREMENT_NAME: "Oven Upper Target Temperature",
ATTR_UNIT_FN: lambda x: x._oven_temp_unit,
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
ATTR_VALUE_FN: lambda x: x._oven_upper_target_temp,
ATTR_ENABLED: True,
},
FEAT_OVEN_UPPER_CURRENT_TEMP: {
ATTR_MEASUREMENT_NAME: "Oven Upper Current Temperature",
ATTR_UNIT_FN: lambda x: x._oven_temp_unit,
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
ATTR_VALUE_FEAT: FEAT_OVEN_UPPER_CURRENT_TEMP,
ATTR_ENABLED: True,
},
}

RANGE_BINARY_SENSORS = {
Expand Down
3 changes: 3 additions & 0 deletions custom_components/smartthinq_sensors/wideq/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,12 @@
FEAT_COOKTOP_CENTER_STATE = "cooktop_center_state"
FEAT_COOKTOP_RIGHT_FRONT_STATE = "cooktop_right_front_state"
FEAT_COOKTOP_RIGHT_REAR_STATE = "cooktop_right_rear_state"
FEAT_OVEN_LOWER_CURRENT_TEMP = "oven_lower_current_temp"
FEAT_OVEN_LOWER_STATE = "oven_lower_state"
FEAT_OVEN_UPPER_CURRENT_TEMP = "oven_upper_current_temp"
FEAT_OVEN_UPPER_STATE = "oven_upper_state"


# request ciphers settings
CIPHERS = ":HIGH:!DH:!aNULL"

Expand Down
55 changes: 43 additions & 12 deletions custom_components/smartthinq_sensors/wideq/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,12 @@ def value(self, name):
elif d["type"] == "String":
pass
else:
assert False, "unsupported value type {}".format(d["type"])
_LOGGER.error(
"ModelInfo: unsupported value type (%s) - value: %s",
d["type"],
d,
)
return None

def default(self, name):
"""Get the default value, if it exists, for a given value.
Expand Down Expand Up @@ -537,6 +542,23 @@ def decode_monitor(self, data):
else:
return self.decode_monitor_json(data)

@staticmethod
def _get_current_temp_key(key: str, data):
"""Special case for oven current temperature, that in protocol
is represented with a suffix "F" or "C" depending from the unit
"""
if key.count("CurrentTemperature") == 0:
return key
new_key = key[:-1]
if not new_key.endswith("CurrentTemperature"):
return key
unit_key = f"{new_key}Unit"
if unit_key not in data:
return key
if data[unit_key][0] == key[-1]:
return f"{new_key}Value"
return key

def decode_snapshot(self, data, key):
"""Decode status data."""
decoded = {}
Expand All @@ -545,25 +567,29 @@ def decode_snapshot(self, data, key):
info = data.get(key)
if not info:
return decoded

protocol = self._data["Monitoring"]["protocol"]
if isinstance(protocol, list):
for elem in protocol:
if "superSet" in elem:
key = elem["value"]
value = data
for ident in elem["superSet"].split("."):
if value is not None:
value = value.get(ident)
if value is None:
break
pr_key = self._get_current_temp_key(ident, value)
value = value.get(pr_key)
if value is not None:
if isinstance(value, Number):
value = int(value)
decoded[key] = str(value)
else:
for data_key, value_key in protocol.items():
value = info.get(data_key, "")
if value is not None and isinstance(value, Number):
value = int(value)
decoded[value_key] = str(value)
return decoded

for data_key, value_key in protocol.items():
value = info.get(data_key, "")
if value is not None and isinstance(value, Number):
value = int(value)
decoded[value_key] = str(value)
return decoded


Expand Down Expand Up @@ -628,12 +654,17 @@ def value(self, data):
# return ReferenceValue(
# self.data[ref]
# )
# elif d['dataType'] == 'Boolean':
# return EnumValue({'0': 'False', '1' : 'True'})
elif data_type in ("Boolean", "boolean"):
return {"0": {"label": LABEL_BIT_OFF}, "1": {"label": LABEL_BIT_ON}}
# elif d['dataType'] == 'String':
# pass
else:
assert False, "unsupported value type {}".format(data_type)
_LOGGER.error(
"ModelInfoV2: unsupported value type (%s) - value: %s",
data_type,
data,
)
return None

def default(self, name):
"""Get the default value, if it exists, for a given value.
Expand Down
32 changes: 32 additions & 0 deletions custom_components/smartthinq_sensors/wideq/range.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
FEAT_COOKTOP_CENTER_STATE,
FEAT_COOKTOP_RIGHT_FRONT_STATE,
FEAT_COOKTOP_RIGHT_REAR_STATE,
FEAT_OVEN_LOWER_CURRENT_TEMP,
FEAT_OVEN_LOWER_STATE,
FEAT_OVEN_UPPER_CURRENT_TEMP,
FEAT_OVEN_UPPER_STATE,
)

Expand Down Expand Up @@ -200,6 +202,34 @@ def oven_upper_target_temp(self):
return None
return self._data.get(key)

@property
def oven_lower_current_temp(self):
unit = self.oven_temp_unit
if unit == UNIT_TEMP_FAHRENHEIT:
key = "LowerCookTemp_F"
elif unit == UNIT_TEMP_CELSIUS:
key = "LowerCookTemp_C"
else:
return None
status = self._data.get(key)
return self._update_feature(
FEAT_OVEN_LOWER_CURRENT_TEMP, status, False
)

@property
def oven_upper_current_temp(self):
unit = self.oven_temp_unit
if unit == UNIT_TEMP_FAHRENHEIT:
key = "UpperCookTemp_F"
elif unit == UNIT_TEMP_CELSIUS:
key = "UpperCookTemp_C"
else:
return None
status = self._data.get(key)
return self._update_feature(
FEAT_OVEN_UPPER_CURRENT_TEMP, status, False
)

def _update_features(self):
result = [
self.cooktop_left_front_state,
Expand All @@ -208,6 +238,8 @@ def _update_features(self):
self.cooktop_right_front_state,
self.cooktop_right_rear_state,
self.oven_lower_state,
self.oven_lower_current_temp,
self.oven_upper_state,
self.oven_upper_current_temp,
]
return
2 changes: 1 addition & 1 deletion info.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# LG ThinQ Devices integration for HomeAssistant
A Homeassistant custom component to monitor LG Air Conditioner, Washer, Dryer, DishWasher, Refrigerator, Styler and Range
A Homeassistant custom component to monitor and control LG Air Conditioner, Washer, Dryer, DishWasher, Refrigerator, Styler and Range
using ThinQ API based on [WideQ project][wideq].<br/>

**Important Version note:**
Expand Down

0 comments on commit 62f64bb

Please sign in to comment.