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

Add PM10, PM2, PM1 sensors to AC-device #613

Merged
merged 10 commits into from
Oct 18, 2023
Merged
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
21 changes: 21 additions & 0 deletions custom_components/smartthinq_sensors/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,27 @@ class ThinQSensorEntityDescription(SensorEntityDescription):
device_class=SensorDeviceClass.HUMIDITY,
native_unit_of_measurement=PERCENTAGE,
),
ThinQSensorEntityDescription(
key=AirConditionerFeatures.PM1,
name="PM1",
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.PM1,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
),
ThinQSensorEntityDescription(
key=AirConditionerFeatures.PM10,
name="PM10",
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.PM10,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
),
ThinQSensorEntityDescription(
key=AirConditionerFeatures.PM25,
name="PM2.5",
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.PM25,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
),
ThinQSensorEntityDescription(
key=AirConditionerFeatures.FILTER_MAIN_LIFE,
name="Filter Remaining Life",
Expand Down
3 changes: 3 additions & 0 deletions custom_components/smartthinq_sensors/wideq/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class AirConditionerFeatures(StrEnum):
MODE_AIRCLEAN = "mode_airclean"
MODE_AWHP_SILENT = "mode_awhp_silent"
MODE_JET = "mode_jet"
PM1 = "pm1"
PM10 = "pm10"
PM25 = "pm25"
RESERVATION_SLEEP_TIME = "reservation_sleep_time"
ROOM_TEMP = "room_temperature"
WATER_IN_TEMP = "water_in_temperature"
Expand Down
72 changes: 71 additions & 1 deletion custom_components/smartthinq_sensors/wideq/devices/ac.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

AWHP_MODEL_TYPE = ["AWHP", "SAC_AWHP"]

SUPPORT_AIR_POLUTION = ["SupportAirPolution", "support.airPolution"]
SUPPORT_OPERATION_MODE = ["SupportOpMode", "support.airState.opMode"]
SUPPORT_WIND_STRENGTH = ["SupportWindStrength", "support.airState.windStrength"]
SUPPORT_DUCT_ZONE = ["SupportDuctZoneType", "support.airState.ductZone.type"]
Expand All @@ -32,6 +33,10 @@
SUPPORT_JET_HEAT = [SUPPORT_RAC_SUBMODE, "@AC_MAIN_WIND_MODE_HEAT_JET_W"]
SUPPORT_AIRCLEAN = [SUPPORT_RAC_MODE, "@AIRCLEAN"]
SUPPORT_HOT_WATER = [SUPPORT_PAC_MODE, "@HOTWATER"]
SUPPORT_PM = [
SUPPORT_AIR_POLUTION,
["@PM10_SUPPORT", "@PM1_0_SUPPORT", "@PM2_5_SUPPORT"],
]

CTRL_BASIC = ["Control", "basicCtrl"]
CTRL_WIND_DIRECTION = ["Control", "wDirCtrl"]
Expand Down Expand Up @@ -64,6 +69,9 @@
STATE_MODE_AIRCLEAN = ["AirClean", "airState.wMode.airClean"]
STATE_MODE_JET = ["Jet", "airState.wMode.jet"]
STATE_LIGHTING_DISPLAY = ["DisplayControl", "airState.lightingState.displayControl"]
STATE_PM1 = ["SensorPM1", "airState.quality.PM1"]
STATE_PM10 = ["SensorPM10", "airState.quality.PM10"]
STATE_PM25 = ["SensorPM2", "airState.quality.PM2"]
skinkie marked this conversation as resolved.
Show resolved Hide resolved
STATE_RESERVATION_SLEEP_TIME = ["SleepTime", "airState.reservation.sleepTime"]

FILTER_TYPES = [
Expand Down Expand Up @@ -278,6 +286,7 @@ def __init__(
self._is_air_to_water = None
self._is_water_heater_supported = None
self._is_mode_airclean_supported = None
self._is_pm_supported = None
self._is_duct_zones_supported = None
self._supported_operation = None
self._supported_op_modes = None
Expand Down Expand Up @@ -324,7 +333,11 @@ def _is_mode_supported(self, key):
if not isinstance(key, list):
return False
supp_key = self._get_state_key(key[0])
return self.model_info.enum_value(supp_key, key[1]) is not None

if isinstance(key[1], list):
return [self.model_info.enum_value(supp_key, k) is not None for k in key[1]]
else:
return self.model_info.enum_value(supp_key, key[1]) is not None

def _get_supported_operations(self):
"""Get a list of the ACOp Operations the device supports."""
Expand Down Expand Up @@ -684,6 +697,27 @@ def is_mode_jet_available(self):
return True
return False

@property
def is_pm10_supported(self):
"""Return if PM sensors are supported."""
if self._is_pm_supported is None:
self._is_pm_supported = self._is_mode_supported(SUPPORT_PM)
return self._is_pm_supported[0]

@property
def is_pm25_supported(self):
"""Return if PM sensors are supported."""
if self._is_pm_supported is None:
self._is_pm_supported = self._is_mode_supported(SUPPORT_PM)
return self._is_pm_supported[2]

@property
def is_pm1_supported(self):
"""Return if PM sensors are supported."""
if self._is_pm_supported is None:
self._is_pm_supported = self._is_mode_supported(SUPPORT_PM)
return self._is_pm_supported[1]

Comment on lines +700 to +720
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that I like to have 3 different properties, because I'm planning to replace cache attributes with cached_property and I couldn't use in this case.
Apart this I like this approach, I'll think about this later.
Maybe should be better to order the array in different way (PM1, PM25 and PM10)? Or you use this order for a specific reason (I'm not a PM expert)?

Copy link
Contributor Author

@skinkie skinkie Oct 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because from a human readability standpoint I liked:
1 = PM1
2 = PM2
0 = PM10 ;-)

I initially modelled this as a dictionary, with a key lookup, but for some reason, I could not get def is_pm_supported(self, key): working.

@property
def hot_water_target_temperature_step(self):
"""Return target temperature step used for hot water."""
Expand Down Expand Up @@ -1247,6 +1281,39 @@ def filters_life(self):

return result

@property
def pm1(self):
"""Return Air PM1 value."""
if not self._device.is_pm1_supported:
return None

key = self._get_state_key(STATE_PM1)
if (value := self.lookup_range(key)) is None:
return None
return self._update_feature(AirConditionerFeatures.PM1, value, False)

@property
def pm10(self):
"""Return Air PM10 value."""
if not self._device.is_pm10_supported:
return None

key = self._get_state_key(STATE_PM10)
if (value := self.lookup_range(key)) is None:
return None
return self._update_feature(AirConditionerFeatures.PM10, value, False)

@property
def pm25(self):
"""Return Air PM2.5 value."""
if not self._device.is_pm25_supported:
return None

key = self._get_state_key(STATE_PM25)
if (value := self.lookup_range(key)) is None:
return None
return self._update_feature(AirConditionerFeatures.PM25, value, False)

@property
def water_in_current_temp(self):
"""Return AWHP in water current temperature."""
Expand Down Expand Up @@ -1343,6 +1410,9 @@ def _update_features(self):
self.energy_current,
self.filters_life,
self.humidity,
self.pm10,
self.pm25,
self.pm1,
self.mode_airclean,
self.mode_jet,
self.lighting_display,
Expand Down
Loading