diff --git a/README.md b/README.md
index 87d96d7..4c4cb3e 100644
--- a/README.md
+++ b/README.md
@@ -29,11 +29,15 @@ This is a custom component for [Home Assistant](http://home-assistant.io) that a
- [On Mode](#on-mode)
- [Off Mode](#off-mode)
- [Auto Mode](#auto-mode)
+ - [Auto Settings Mode](#auto-setting-mode)
+ - [Target Settings Mode](#target-settings-mode)
- [Timer to On Mode](#timer-to-on-mode)
- [Timer to Off Mode](#timer-to-off-mode)
- [Cycle Mode](#cycle-mode)
- [Schedule Mode](#schedule-mode)
- [VPD Mode](#vpd-mode)
+ - [Auto Settings Mode](#auto-setting-mode-1)
+ - [Target Settings Mode](#target-settings-mode-1)
- [Device Settings](#device-settings)
- [Dynamic Response](#dynamic-response)
- [Transition Mode](#transition-mode)
@@ -183,7 +187,12 @@ Device is always set to the on speed . This mode has no unique controls.
Device is always set to the off speed . This mode has no unique controls.
### Auto Mode
-Device toggled based on temperature and/or humidity triggers
+Device toggled based on temperature and/or humidity triggers. This mode is split into two sub modes: Auto and Target.
+
+- `Auto Settings Mode`: Swap between `Auto` and `Target` setting mode types. `Target` mode is not valid for some device types.
+
+#### Auto Setting Mode
+
- `High Temp Enabled`: Enable or disable high temp trigger while in Auto mode
- `High Temp Trigger`: If trigger is enabled, device will be turned on if temp exceeds configured value.
- `Low Temp Enabled`: Enable or disable low temp trigger while in Auto mode
@@ -193,6 +202,16 @@ Device toggled based on temperature and/or humidity triggers
- `Low Humidity Enabled`: Enable or disable low humidity trigger while in Auto mode
- `Low Humidity Trigger`: If trigger is enabled, device will be turned on if humidity drops below configured value.
+#### Target Settings Mode
+
+- `Target Temp Enabled`: Enabled or disable the target temperature target. *
+- `Target Temp`: If enabled, target temperature to maintain. *
+- `Target Humidity Enabled`: Enable or disable the target humidity target. **
+- `Target Humidity`: If enabled, the target humidity to maintain. **
+
+* Only valid for AC or Heater devices
+** Only valid for Humidifier devices
+
### Timer to On Mode
Device is turned on after a set duration
- `Minutes to On`: Device will be turned on after the configured number of minutes
@@ -213,7 +232,19 @@ Device is toggled based on a schedule
### VPD Mode
Device is toggled based on VPD triggers
+
+- `VPD Settings Mode`: Swap between `Auto` and `Target` setting mode types. `Target` mode is not valid for some device types.
+
+#### Auto Setting Mode
+
- `VPD High Enabled`: Enable or disable high VPD trigger while in VPD mode
- `VPD High Trigger`: If trigger is enabled, device will be turned on if VPD exceeds configured value.
- `VPD Low Enabled`: Enable or disable low VPD trigger while in VPD mode
- `VPD Low Trigger`: If trigger is enabled, device will be turned on if VPD drops below configured value.
+
+#### Target Settings Mode
+
+- `Target VPD Enabled`: Enable or disable the target VPD target *
+- `Target VPD`: If enabled, the target VPD to maintain *
+
+* Only valid for AC, Heater, and Humidifier devices
diff --git a/custom_components/ac_infinity/const.py b/custom_components/ac_infinity/const.py
index d0e250e..d9f9ec0 100644
--- a/custom_components/ac_infinity/const.py
+++ b/custom_components/ac_infinity/const.py
@@ -118,10 +118,14 @@ class PortControlKey:
TIMER_DURATION_TO_OFF = "acitveTimerOff"
CYCLE_DURATION_ON = "activeCycleOn"
CYCLE_DURATION_OFF = "activeCycleOff"
+ VPD_SETTINGS_MODE = "vpdSettingMode"
VPD_HIGH_ENABLED = "activeHtVpd"
VPD_HIGH_TRIGGER = "activeHtVpdNums"
VPD_LOW_ENABLED = "activeLtVpd"
VPD_LOW_TRIGGER = "activeLtVpdNums"
+ VPD_TARGET_ENABLED = "targetVpdSwitch"
+ VPD_TARGET = "targetVpd"
+ AUTO_SETTINGS_MODE = "settingMode"
AUTO_TEMP_HIGH_TRIGGER = "devHt"
AUTO_TEMP_HIGH_TRIGGER_F = "devHtf"
AUTO_TEMP_HIGH_ENABLED = "activeHt"
@@ -132,9 +136,11 @@ class PortControlKey:
AUTO_TEMP_LOW_ENABLED = "activeLt"
AUTO_HUMIDITY_LOW_TRIGGER = "devLh"
AUTO_HUMIDITY_LOW_ENABLED = "activeLh"
- TARGET_HUMIDITY_SWITCH = "targetHumiSwitch"
- TARGET_TEMPERATURE_SWITCH = "targetTSwitch"
- TARGET_VPD_SWITCH = "targetVpdSwitch"
+ AUTO_TARGET_TEMP_ENABLED = "targetTSwitch"
+ AUTO_TARGET_TEMP = "targetTemp"
+ AUTO_TARGET_TEMP_F = "targetTempF"
+ AUTO_TARGET_HUMIDITY_ENABLED = "targetHumiSwitch"
+ AUTO_TARGET_HUMIDITY = "targetHumi"
EC_OR_TDS = "ecOrTds"
VPD_STATUS = "vpdstatus"
VPD_NUMS = "vpdnums"
diff --git a/custom_components/ac_infinity/manifest.json b/custom_components/ac_infinity/manifest.json
index dcf8c59..9ccf02e 100644
--- a/custom_components/ac_infinity/manifest.json
+++ b/custom_components/ac_infinity/manifest.json
@@ -10,5 +10,5 @@
"iot_class": "cloud_polling",
"issue_tracker": "https://github.com/dalinicus/homeassistant-acinfinity",
"requirements": [],
- "version": "1.6.0"
+ "version": "1.7.0"
}
diff --git a/custom_components/ac_infinity/number.py b/custom_components/ac_infinity/number.py
index 28d7d01..7d7b8a8 100644
--- a/custom_components/ac_infinity/number.py
+++ b/custom_components/ac_infinity/number.py
@@ -246,6 +246,21 @@ def __set_value_fn_temp_auto_high(
)
+def __set_value_fn_target_temp(
+ entity: ACInfinityEntity, port: ACInfinityPort, value: int
+):
+ return entity.ac_infinity.update_port_controls(
+ port.controller.device_id,
+ port.port_index,
+ [
+ # value is received from HA as C
+ (PortControlKey.AUTO_TARGET_TEMP, value),
+ # degrees F must be calculated and set in addition to C
+ (PortControlKey.AUTO_TARGET_TEMP_F, int(round((value * 1.8) + 32, 0))),
+ ],
+ )
+
+
def __get_value_fn_dynamic_transition_temp(
entity: ACInfinityEntity, port: ACInfinityPort
):
@@ -488,6 +503,20 @@ def __set_value_fn_dynamic_buffer_temp(
get_value_fn=__get_value_fn_vpd_control,
set_value_fn=__set_value_fn_vpd_control,
),
+ ACInfinityPortNumberEntityDescription(
+ key=PortControlKey.VPD_TARGET,
+ device_class=NumberDeviceClass.PRESSURE,
+ mode=NumberMode.BOX,
+ native_min_value=0,
+ native_max_value=9.9,
+ native_step=0.1,
+ icon="mdi:water-thermometer-outline",
+ translation_key="target_vpd",
+ native_unit_of_measurement=None,
+ suitable_fn=suitable_fn_port_control_default,
+ get_value_fn=__get_value_fn_vpd_control,
+ set_value_fn=__set_value_fn_vpd_control,
+ ),
ACInfinityPortNumberEntityDescription(
key=PortControlKey.AUTO_HUMIDITY_LOW_TRIGGER,
device_class=NumberDeviceClass.HUMIDITY,
@@ -516,6 +545,20 @@ def __set_value_fn_dynamic_buffer_temp(
get_value_fn=get_value_fn_port_control_default,
set_value_fn=set_value_fn_port_control_default,
),
+ ACInfinityPortNumberEntityDescription(
+ key=PortControlKey.AUTO_TARGET_HUMIDITY,
+ device_class=NumberDeviceClass.HUMIDITY,
+ mode=NumberMode.AUTO,
+ native_min_value=0,
+ native_max_value=100,
+ native_step=1,
+ icon="mdi:water-percent",
+ translation_key="target_humidity",
+ native_unit_of_measurement=None,
+ suitable_fn=suitable_fn_port_control_default,
+ get_value_fn=get_value_fn_port_control_default,
+ set_value_fn=set_value_fn_port_control_default,
+ ),
ACInfinityPortNumberEntityDescription(
key=PortControlKey.AUTO_TEMP_LOW_TRIGGER,
device_class=NumberDeviceClass.TEMPERATURE,
@@ -544,6 +587,20 @@ def __set_value_fn_dynamic_buffer_temp(
get_value_fn=get_value_fn_port_control_default,
set_value_fn=__set_value_fn_temp_auto_high,
),
+ ACInfinityPortNumberEntityDescription(
+ key=PortControlKey.AUTO_TARGET_TEMP,
+ device_class=NumberDeviceClass.TEMPERATURE,
+ native_unit_of_measurement=UnitOfTemperature.CELSIUS,
+ mode=NumberMode.AUTO,
+ native_min_value=0,
+ native_max_value=90,
+ native_step=1,
+ icon=None,
+ translation_key="target_temp",
+ suitable_fn=suitable_fn_port_control_default,
+ get_value_fn=get_value_fn_port_control_default,
+ set_value_fn=__set_value_fn_target_temp,
+ ),
ACInfinityPortNumberEntityDescription(
key=AdvancedSettingsKey.DYNAMIC_TRANSITION_TEMP,
device_class=None,
diff --git a/custom_components/ac_infinity/select.py b/custom_components/ac_infinity/select.py
index b423cd3..44dd92b 100644
--- a/custom_components/ac_infinity/select.py
+++ b/custom_components/ac_infinity/select.py
@@ -75,6 +75,11 @@ class ACInfinityPortSelectEntityDescription(
6: "Fan",
}
+SETTINGS_MODE_OPTIONS = [
+ "Auto",
+ "Target",
+]
+
def __get_value_fn_outside_climate(
entity: ACInfinityEntity, controller: ACInfinityController
@@ -97,6 +102,25 @@ def __set_value_fn_outside_climate(
)
+def __get_value_fn_setting_mode(entity: ACInfinityEntity, port: ACInfinityPort):
+ return SETTINGS_MODE_OPTIONS[
+ entity.ac_infinity.get_port_control(
+ port.controller.device_id, port.port_index, entity.entity_description.key
+ )
+ ]
+
+
+def __set_value_fn_setting_mode(
+ entity: ACInfinityEntity, port: ACInfinityPort, value: str
+):
+ return entity.ac_infinity.update_port_control(
+ port.controller.device_id,
+ port.port_index,
+ entity.entity_description.key,
+ SETTINGS_MODE_OPTIONS.index(value),
+ )
+
+
def __get_value_fn_active_mode(entity: ACInfinityEntity, port: ACInfinityPort):
return MODE_OPTIONS[
# data is 1 based. Adjust to 0 based enum by subtracting 1
@@ -193,6 +217,22 @@ def __set_value_fn_device_load_type(
get_value_fn=__get_value_fn_active_mode,
set_value_fn=__set_value_fn_active_mode,
),
+ ACInfinityPortSelectEntityDescription(
+ key=PortControlKey.AUTO_SETTINGS_MODE,
+ translation_key="auto_settings_mode",
+ options=SETTINGS_MODE_OPTIONS,
+ suitable_fn=suitable_fn_port_control_default,
+ get_value_fn=__get_value_fn_setting_mode,
+ set_value_fn=__set_value_fn_setting_mode,
+ ),
+ ACInfinityPortSelectEntityDescription(
+ key=PortControlKey.VPD_SETTINGS_MODE,
+ translation_key="vpd_settings_mode",
+ options=SETTINGS_MODE_OPTIONS,
+ suitable_fn=suitable_fn_port_control_default,
+ get_value_fn=__get_value_fn_setting_mode,
+ set_value_fn=__set_value_fn_setting_mode,
+ ),
ACInfinityPortSelectEntityDescription(
key=AdvancedSettingsKey.DEVICE_LOAD_TYPE,
translation_key="device_load_type",
diff --git a/custom_components/ac_infinity/strings.json b/custom_components/ac_infinity/strings.json
index b5fa67b..ca33658 100644
--- a/custom_components/ac_infinity/strings.json
+++ b/custom_components/ac_infinity/strings.json
@@ -82,18 +82,27 @@
"vpd_mode_high_trigger": {
"name": "VPD High Trigger"
},
+ "target_vpd": {
+ "name": "Target VPD"
+ },
"auto_mode_humidity_low_trigger": {
"name": "Humidity Low Trigger"
},
"auto_mode_humidity_high_trigger": {
"name": "Humidity High Trigger"
},
+ "target_humidity": {
+ "name": "Target Humidity"
+ },
"auto_mode_temp_low_trigger": {
"name": "Temperature Low Trigger"
},
"auto_mode_temp_high_trigger": {
"name": "Temperature High Trigger"
},
+ "target_temp": {
+ "name": "Target Temperature"
+ },
"temperature_calibration": {
"name": "Temperature Calibration"
},
@@ -140,6 +149,12 @@
},
"outside_climate_humidity": {
"name": "Outside Humidity"
+ },
+ "auto_settings_mode": {
+ "name": "Auto Settings Mode"
+ },
+ "vpd_settings_mode": {
+ "name": "VPD Settings Mode"
}
},
"sensor": {
@@ -166,6 +181,9 @@
"vpd_mode_high_enabled": {
"name": "VPD High Trigger Enabled"
},
+ "target_vpd_enabled": {
+ "name": "Target VPD Enabled"
+ },
"auto_mode_humidity_low_enabled": {
"name": "Humidity Low Trigger Enabled"
},
@@ -178,6 +196,12 @@
"auto_mode_temp_high_enabled": {
"name": "Temperature High Trigger Enabled"
},
+ "target_temp_enabled": {
+ "name": "Target Temperature Enabled"
+ },
+ "target_humidity_enabled": {
+ "name": "Target Humidity Enabled"
+ },
"schedule_mode_on_time_enabled": {
"name": "Scheduled On-Time Enabled"
},
diff --git a/custom_components/ac_infinity/switch.py b/custom_components/ac_infinity/switch.py
index 40c86e3..9405f1d 100644
--- a/custom_components/ac_infinity/switch.py
+++ b/custom_components/ac_infinity/switch.py
@@ -97,6 +97,17 @@ def __get_value_fn_schedule_enabled(entity: ACInfinityEntity, port: ACInfinityPo
get_value_fn=get_value_fn_port_control_default,
set_value_fn=set_value_fn_port_control_default,
),
+ ACInfinityPortSwitchEntityDescription(
+ key=PortControlKey.VPD_TARGET_ENABLED,
+ device_class=SwitchDeviceClass.SWITCH,
+ on_value=1,
+ off_value=0,
+ icon=None, # default
+ translation_key="target_vpd_enabled",
+ suitable_fn=suitable_fn_port_control_default,
+ get_value_fn=get_value_fn_port_control_default,
+ set_value_fn=set_value_fn_port_control_default,
+ ),
ACInfinityPortSwitchEntityDescription(
key=PortControlKey.AUTO_TEMP_HIGH_ENABLED,
device_class=SwitchDeviceClass.SWITCH,
@@ -141,6 +152,28 @@ def __get_value_fn_schedule_enabled(entity: ACInfinityEntity, port: ACInfinityPo
get_value_fn=get_value_fn_port_control_default,
set_value_fn=set_value_fn_port_control_default,
),
+ ACInfinityPortSwitchEntityDescription(
+ key=PortControlKey.AUTO_TARGET_TEMP_ENABLED,
+ device_class=SwitchDeviceClass.SWITCH,
+ on_value=1,
+ off_value=0,
+ icon=None, # default
+ translation_key="target_temp_enabled",
+ suitable_fn=suitable_fn_port_control_default,
+ get_value_fn=get_value_fn_port_control_default,
+ set_value_fn=set_value_fn_port_control_default,
+ ),
+ ACInfinityPortSwitchEntityDescription(
+ key=PortControlKey.AUTO_TARGET_HUMIDITY_ENABLED,
+ device_class=SwitchDeviceClass.SWITCH,
+ on_value=1,
+ off_value=0,
+ icon=None, # default
+ translation_key="target_humidity_enabled",
+ suitable_fn=suitable_fn_port_control_default,
+ get_value_fn=get_value_fn_port_control_default,
+ set_value_fn=set_value_fn_port_control_default,
+ ),
ACInfinityPortSwitchEntityDescription(
key=PortControlKey.SCHEDULED_START_TIME,
device_class=SwitchDeviceClass.SWITCH,
diff --git a/custom_components/ac_infinity/translations/en.json b/custom_components/ac_infinity/translations/en.json
index 8991236..4db2fc0 100644
--- a/custom_components/ac_infinity/translations/en.json
+++ b/custom_components/ac_infinity/translations/en.json
@@ -83,18 +83,27 @@
"vpd_mode_high_trigger": {
"name": "VPD High Trigger"
},
+ "target_vpd": {
+ "name": "Target VPD"
+ },
"auto_mode_humidity_low_trigger": {
"name": "Humidity Low Trigger"
},
"auto_mode_humidity_high_trigger": {
"name": "Humidity High Trigger"
},
+ "target_humidity": {
+ "name": "Target Humidity"
+ },
"auto_mode_temp_low_trigger": {
"name": "Temperature Low Trigger"
},
"auto_mode_temp_high_trigger": {
"name": "Temperature High Trigger"
},
+ "target_temp": {
+ "name": "Target Temperature"
+ },
"temperature_calibration": {
"name": "Temperature Calibration"
},
@@ -141,6 +150,12 @@
},
"outside_climate_humidity": {
"name": "Outside Humidity"
+ },
+ "auto_settings_mode": {
+ "name": "Auto Settings Mode"
+ },
+ "vpd_settings_mode": {
+ "name": "VPD Settings Mode"
}
},
"sensor": {
@@ -167,6 +182,9 @@
"vpd_mode_high_enabled": {
"name": "VPD High Trigger Enabled"
},
+ "target_vpd_enabled": {
+ "name": "Target VPD Enabled"
+ },
"auto_mode_humidity_low_enabled": {
"name": "Humidity Low Trigger Enabled"
},
@@ -179,6 +197,12 @@
"auto_mode_temp_high_enabled": {
"name": "Temperature High Trigger Enabled"
},
+ "target_temp_enabled": {
+ "name": "Target Temperature Enabled"
+ },
+ "target_humidity_enabled": {
+ "name": "Target Humidity Enabled"
+ },
"schedule_mode_on_time_enabled": {
"name": "Scheduled On-Time Enabled"
},
diff --git a/tests/test_client.py b/tests/test_client.py
index 4114705..c46696c 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -245,9 +245,10 @@ async def test_set_device_port_setting_zero_even_when_null(self, set_value):
assert isinstance(dev_mode_settings["data"], dict)
dev_mode_settings["data"][PortControlKey.SURPLUS] = set_value
- dev_mode_settings["data"][PortControlKey.TARGET_TEMPERATURE_SWITCH] = set_value
- dev_mode_settings["data"][PortControlKey.TARGET_HUMIDITY_SWITCH] = set_value
- dev_mode_settings["data"][PortControlKey.TARGET_VPD_SWITCH] = set_value
+ dev_mode_settings["data"][
+ PortControlKey.AUTO_TARGET_HUMIDITY_ENABLED
+ ] = set_value
+ dev_mode_settings["data"][PortControlKey.VPD_TARGET_ENABLED] = set_value
dev_mode_settings["data"][PortControlKey.EC_OR_TDS] = set_value
dev_mode_settings["data"][PortControlKey.MASTER_PORT] = set_value
@@ -257,9 +258,8 @@ async def test_set_device_port_setting_zero_even_when_null(self, set_value):
expected = set_value if set_value else 0
assert payload[PortControlKey.SURPLUS] == expected
- assert payload[PortControlKey.TARGET_HUMIDITY_SWITCH] == expected
- assert payload[PortControlKey.TARGET_TEMPERATURE_SWITCH] == expected
- assert payload[PortControlKey.TARGET_VPD_SWITCH] == expected
+ assert payload[PortControlKey.AUTO_TARGET_HUMIDITY_ENABLED] == expected
+ assert payload[PortControlKey.VPD_TARGET_ENABLED] == expected
assert payload[PortControlKey.EC_OR_TDS] == expected
assert payload[PortControlKey.MASTER_PORT] == expected
diff --git a/tests/test_number.py b/tests/test_number.py
index fe7b5b1..d561783 100644
--- a/tests/test_number.py
+++ b/tests/test_number.py
@@ -43,7 +43,7 @@ async def test_async_setup_all_sensors_created(self, setup):
test_objects.entities.add_entities_callback,
)
- assert len(test_objects.entities._added_entities) == 79
+ assert len(test_objects.entities._added_entities) == 91
@pytest.mark.parametrize(
"setting", [PortControlKey.OFF_SPEED, PortControlKey.ON_SPEED]
@@ -180,15 +180,16 @@ async def test_async_set_native_value_timer(
test_objects.refresh_mock.assert_called()
@pytest.mark.parametrize(
- "key,label",
+ "key",
[
- (PortControlKey.VPD_HIGH_TRIGGER, "High"),
- (PortControlKey.VPD_LOW_TRIGGER, "Low"),
+ PortControlKey.AUTO_HUMIDITY_LOW_TRIGGER,
+ PortControlKey.AUTO_HUMIDITY_HIGH_TRIGGER,
+ PortControlKey.AUTO_TARGET_HUMIDITY,
],
)
@pytest.mark.parametrize("port", [1, 2, 3, 4])
- async def test_async_setup_vpd_trigger_setup_for_each_port(
- self, setup, key, port, label
+ async def test_async_setup_humidity_trigger_setup_for_each_port(
+ self, setup, key, port
):
"""Setting for vpd trigger setup for each port"""
@@ -198,19 +199,37 @@ async def test_async_setup_vpd_trigger_setup_for_each_port(
assert entity.device_info is not None
@pytest.mark.parametrize(
- "setting,enabled_setting",
+ "key",
+ [
+ PortControlKey.VPD_HIGH_TRIGGER,
+ PortControlKey.VPD_LOW_TRIGGER,
+ PortControlKey.VPD_TARGET,
+ ],
+ )
+ @pytest.mark.parametrize("port", [1, 2, 3, 4])
+ async def test_async_setup_vpd_trigger_setup_for_each_port(self, setup, key, port):
+ """Setting for vpd trigger setup for each port"""
+
+ entity = await execute_and_get_port_entity(setup, async_setup_entry, port, key)
+
+ assert entity.unique_id == f"{DOMAIN}_{MAC_ADDR}_port_{port}_{key}"
+ assert entity.device_info is not None
+
+ @pytest.mark.parametrize(
+ "setting",
[
- (PortControlKey.VPD_LOW_TRIGGER, PortControlKey.VPD_LOW_ENABLED),
- (PortControlKey.VPD_HIGH_TRIGGER, PortControlKey.VPD_HIGH_ENABLED),
+ PortControlKey.AUTO_HUMIDITY_LOW_TRIGGER,
+ PortControlKey.AUTO_HUMIDITY_HIGH_TRIGGER,
+ PortControlKey.AUTO_TARGET_HUMIDITY,
],
)
@pytest.mark.parametrize(
"value,expected",
- [(55, 5.5), (0, 0)], # minutes to seconds
+ [(55, 55), (0, 0)], # minutes to seconds
)
@pytest.mark.parametrize("port", [1, 2, 3, 4])
- async def test_async_update_value_vpd(
- self, setup, setting, value, expected, port, enabled_setting
+ async def test_async_update_value_humidity(
+ self, setup, setting, value, expected, port
):
"""Reported sensor value matches the value in the json payload"""
@@ -231,6 +250,72 @@ async def test_async_update_value_vpd(
[
PortControlKey.VPD_LOW_TRIGGER,
PortControlKey.VPD_HIGH_TRIGGER,
+ PortControlKey.VPD_TARGET,
+ ],
+ )
+ @pytest.mark.parametrize(
+ "value,expected",
+ [(55, 5.5), (0, 0)], # minutes to seconds
+ )
+ @pytest.mark.parametrize("port", [1, 2, 3, 4])
+ async def test_async_update_value_vpd(self, setup, setting, value, expected, port):
+ """Reported sensor value matches the value in the json payload"""
+
+ test_objects: ACTestObjects = setup
+ entity = await execute_and_get_port_entity(
+ setup, async_setup_entry, port, setting
+ )
+
+ test_objects.ac_infinity._port_controls[(str(DEVICE_ID), port)][setting] = value
+ entity._handle_coordinator_update()
+
+ assert isinstance(entity, ACInfinityPortNumberEntity)
+ assert entity.native_value == expected
+ test_objects.write_ha_mock.assert_called()
+
+ @pytest.mark.parametrize(
+ "setting",
+ [
+ PortControlKey.AUTO_HUMIDITY_LOW_TRIGGER,
+ PortControlKey.AUTO_HUMIDITY_HIGH_TRIGGER,
+ PortControlKey.AUTO_TARGET_HUMIDITY,
+ ],
+ )
+ @pytest.mark.parametrize(
+ "expected,value,prev_value",
+ [(55, 55, 45), (0, 0, 45)], # minutes to seconds
+ )
+ @pytest.mark.parametrize("port", [1, 2, 3, 4])
+ async def test_async_set_native_value_humidity(
+ self, setup, setting, value, expected, port, prev_value
+ ):
+ """Reported entity value matches the value in the json payload"""
+ future: Future = asyncio.Future()
+ future.set_result(None)
+
+ test_objects: ACTestObjects = setup
+
+ test_objects.ac_infinity._port_controls[(str(DEVICE_ID), port)][
+ setting
+ ] = prev_value
+ entity = await execute_and_get_port_entity(
+ setup, async_setup_entry, port, setting
+ )
+
+ assert isinstance(entity, ACInfinityPortNumberEntity)
+ await entity.async_set_native_value(value)
+
+ test_objects.port_control_set_mock.assert_called_with(
+ str(DEVICE_ID), port, setting, expected
+ )
+ test_objects.refresh_mock.assert_called()
+
+ @pytest.mark.parametrize(
+ "setting",
+ [
+ PortControlKey.VPD_LOW_TRIGGER,
+ PortControlKey.VPD_HIGH_TRIGGER,
+ PortControlKey.VPD_TARGET,
],
)
@pytest.mark.parametrize(
@@ -346,6 +431,7 @@ async def test_async_set_native_value_cycle_timer(
PortControlKey.AUTO_TEMP_LOW_TRIGGER,
PortControlKey.AUTO_TEMP_LOW_TRIGGER_F,
),
+ (PortControlKey.AUTO_TARGET_TEMP, PortControlKey.AUTO_TARGET_TEMP_F),
],
)
@pytest.mark.parametrize(
@@ -392,6 +478,7 @@ async def test_async_update_temp_trigger_correct(
PortControlKey.AUTO_TEMP_LOW_TRIGGER,
PortControlKey.AUTO_TEMP_LOW_TRIGGER_F,
),
+ (PortControlKey.AUTO_TARGET_TEMP, PortControlKey.AUTO_TARGET_TEMP_F),
],
)
@pytest.mark.parametrize("port", [1, 2, 3, 4])
diff --git a/tests/test_select.py b/tests/test_select.py
index cc5a86c..5d49b7b 100644
--- a/tests/test_select.py
+++ b/tests/test_select.py
@@ -42,7 +42,7 @@ async def test_async_setup_all_sensors_created(self, setup):
test_objects.entities.add_entities_callback,
)
- assert len(test_objects.entities._added_entities) == 14
+ assert len(test_objects.entities._added_entities) == 22
@pytest.mark.parametrize(
"setting",
@@ -374,3 +374,70 @@ async def test_async_set_native_value_load_type_unknown_device_type(
assert isinstance(entity, ACInfinityPortSelectEntity)
with pytest.raises(ValueError):
await entity.async_select_option("Pizza")
+
+ @pytest.mark.parametrize(
+ "setting", [PortControlKey.AUTO_SETTINGS_MODE, PortControlKey.VPD_SETTINGS_MODE]
+ )
+ @pytest.mark.parametrize(
+ "setting_mode,expected",
+ [
+ (0, "Auto"),
+ (1, "Target"),
+ ],
+ )
+ @pytest.mark.parametrize("port", [1, 2, 3, 4])
+ async def test_async_update_settings_mode_value_correct(
+ self, setup, setting_mode, expected, port, setting
+ ):
+ """Reported sensor value matches the value in the json payload"""
+
+ test_objects: ACTestObjects = setup
+ entity = await execute_and_get_port_entity(
+ setup,
+ async_setup_entry,
+ port,
+ setting,
+ )
+
+ test_objects.ac_infinity._port_controls[(str(DEVICE_ID), port)][
+ setting
+ ] = setting_mode
+ entity._handle_coordinator_update()
+
+ assert isinstance(entity, ACInfinityPortSelectEntity)
+ assert entity.current_option == expected
+ test_objects.write_ha_mock.assert_called()
+
+ @pytest.mark.parametrize(
+ "setting", [PortControlKey.AUTO_SETTINGS_MODE, PortControlKey.VPD_SETTINGS_MODE]
+ )
+ @pytest.mark.parametrize(
+ "expected,setting_mode_string",
+ [
+ (0, "Auto"),
+ (1, "Target"),
+ ],
+ )
+ @pytest.mark.parametrize("port", [1, 2, 3, 4])
+ async def test_async_set_native_value_setting_mode(
+ self, setup, setting_mode_string, expected, port, setting
+ ):
+ """Reported sensor value matches the value in the json payload"""
+ future: Future = asyncio.Future()
+ future.set_result(None)
+
+ test_objects: ACTestObjects = setup
+ entity = await execute_and_get_port_entity(
+ setup,
+ async_setup_entry,
+ port,
+ setting,
+ )
+
+ assert isinstance(entity, ACInfinityPortSelectEntity)
+ await entity.async_select_option(setting_mode_string)
+
+ test_objects.port_control_set_mock.assert_called_with(
+ str(DEVICE_ID), port, setting, expected
+ )
+ test_objects.refresh_mock.assert_called()
diff --git a/tests/test_switch.py b/tests/test_switch.py
index cfe9e28..1374284 100644
--- a/tests/test_switch.py
+++ b/tests/test_switch.py
@@ -41,7 +41,7 @@ async def test_async_setup_all_sensors_created(self, setup):
test_objects.entities.add_entities_callback,
)
- assert len(test_objects.entities._added_entities) == 36
+ assert len(test_objects.entities._added_entities) == 48
@pytest.mark.parametrize(
"setting",
@@ -50,8 +50,11 @@ async def test_async_setup_all_sensors_created(self, setup):
PortControlKey.AUTO_HUMIDITY_LOW_ENABLED,
PortControlKey.AUTO_TEMP_HIGH_ENABLED,
PortControlKey.AUTO_TEMP_LOW_ENABLED,
+ PortControlKey.AUTO_TARGET_TEMP_ENABLED,
+ PortControlKey.AUTO_TARGET_HUMIDITY_ENABLED,
PortControlKey.VPD_HIGH_ENABLED,
PortControlKey.VPD_LOW_ENABLED,
+ PortControlKey.VPD_TARGET_ENABLED,
PortControlKey.SCHEDULED_START_TIME,
PortControlKey.SCHEDULED_END_TIME,
AdvancedSettingsKey.SUNRISE_TIMER_ENABLED,
@@ -79,8 +82,11 @@ async def test_async_setup_mode_created_for_each_port(self, setup, port, setting
(PortControlKey.AUTO_HUMIDITY_LOW_ENABLED, 1, True),
(PortControlKey.AUTO_TEMP_HIGH_ENABLED, 1, True),
(PortControlKey.AUTO_TEMP_LOW_ENABLED, 1, True),
+ (PortControlKey.AUTO_TARGET_TEMP_ENABLED, 1, True),
+ (PortControlKey.AUTO_TARGET_HUMIDITY_ENABLED, 1, True),
(PortControlKey.VPD_HIGH_ENABLED, 1, True),
(PortControlKey.VPD_LOW_ENABLED, 1, True),
+ (PortControlKey.VPD_TARGET_ENABLED, 1, True),
(PortControlKey.SCHEDULED_START_TIME, SCHEDULE_MIDNIGHT_VALUE, True),
(PortControlKey.SCHEDULED_END_TIME, SCHEDULE_MIDNIGHT_VALUE, True),
# disabled
@@ -88,8 +94,11 @@ async def test_async_setup_mode_created_for_each_port(self, setup, port, setting
(PortControlKey.AUTO_HUMIDITY_LOW_ENABLED, 0, False),
(PortControlKey.AUTO_TEMP_HIGH_ENABLED, 0, False),
(PortControlKey.AUTO_TEMP_LOW_ENABLED, 0, False),
+ (PortControlKey.AUTO_TARGET_TEMP_ENABLED, 0, False),
+ (PortControlKey.AUTO_TARGET_HUMIDITY_ENABLED, 0, False),
(PortControlKey.VPD_HIGH_ENABLED, 0, False),
(PortControlKey.VPD_LOW_ENABLED, 0, False),
+ (PortControlKey.VPD_TARGET_ENABLED, 0, False),
(PortControlKey.SCHEDULED_START_TIME, SCHEDULE_DISABLED_VALUE, False),
(PortControlKey.SCHEDULED_END_TIME, SCHEDULE_DISABLED_VALUE, False),
],
@@ -157,8 +166,11 @@ async def test_async_update_port_setting_value_correct(
(PortControlKey.AUTO_HUMIDITY_LOW_ENABLED, 1),
(PortControlKey.AUTO_TEMP_HIGH_ENABLED, 1),
(PortControlKey.AUTO_TEMP_LOW_ENABLED, 1),
+ (PortControlKey.AUTO_TARGET_TEMP_ENABLED, 1),
+ (PortControlKey.AUTO_TARGET_HUMIDITY_ENABLED, 1),
(PortControlKey.VPD_HIGH_ENABLED, 1),
(PortControlKey.VPD_LOW_ENABLED, 1),
+ (PortControlKey.VPD_TARGET_ENABLED, 1),
(PortControlKey.SCHEDULED_START_TIME, SCHEDULE_MIDNIGHT_VALUE),
(PortControlKey.SCHEDULED_END_TIME, SCHEDULE_EOD_VALUE),
],
@@ -225,8 +237,11 @@ async def test_async_turn_on_port_setting(
(PortControlKey.AUTO_HUMIDITY_LOW_ENABLED, 0),
(PortControlKey.AUTO_TEMP_HIGH_ENABLED, 0),
(PortControlKey.AUTO_TEMP_LOW_ENABLED, 0),
+ (PortControlKey.AUTO_TARGET_TEMP_ENABLED, 0),
+ (PortControlKey.AUTO_TARGET_HUMIDITY_ENABLED, 0),
(PortControlKey.VPD_HIGH_ENABLED, 0),
(PortControlKey.VPD_LOW_ENABLED, 0),
+ (PortControlKey.VPD_TARGET_ENABLED, 0),
(PortControlKey.SCHEDULED_START_TIME, SCHEDULE_DISABLED_VALUE),
(PortControlKey.SCHEDULED_END_TIME, SCHEDULE_DISABLED_VALUE),
],