Skip to content
This repository has been archived by the owner on Oct 7, 2021. It is now read-only.

Commit

Permalink
Added climate external temperature sensor
Browse files Browse the repository at this point in the history
  • Loading branch information
ollo69 committed Dec 8, 2020
1 parent 324713e commit bf20a0c
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 10 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ For the configuration use exactly the same options used to configure the standar

## Integration Options (From UI integration page)

It is possible to change various behaviors through the integration options, some common for integration and others specific to each `light` and `climate` devices. These can be changed at **Tuya** -> **Options** on the Integrations page.
It is possible to change various behaviors through the integration options, some common for integration and others specific to each `light` and `climate` devices. These can be changed at **Tuya Custom** -> **Options** on the Integrations page.

### Common Options

Expand Down Expand Up @@ -90,6 +90,9 @@ but all selected devices must be of the same type.

- **Max target temperature**: set the maximum allowed `target temperature` for the entity.

- **Sensor for current temperature**: any HA sensor entity that provide `current temperature`, used when not available from device.

## Device parameters (configuration.yaml)

Configuration of device parameter using `configuration.yaml` is not supported anymore. Use integration options for this.
Please note that option previously set in configuration file will not be loaded anymore and must be configured again from integration page.
5 changes: 4 additions & 1 deletion custom_components/tuya_custom/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,16 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
tuya.init, username, password, country_code, platform
)
except (
TuyaAPIRateLimitException,
TuyaNetException,
TuyaServerException,
TuyaFrequentlyInvokeException,
) as exc:
raise ConfigEntryNotReady() from exc

except TuyaAPIRateLimitException as exc:
_LOGGER.error("Tuya login rate limited")
raise ConfigEntryNotReady() from exc

except TuyaAPIException as exc:
_LOGGER.error(
"Connection error during integration setup. Error: %s", exc,
Expand Down
48 changes: 46 additions & 2 deletions custom_components/tuya_custom/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,19 @@
ATTR_TEMPERATURE,
CONF_PLATFORM,
CONF_UNIT_OF_MEASUREMENT,
ENTITY_MATCH_NONE,
PRECISION_TENTHS,
PRECISION_WHOLE,
TEMP_CELSIUS,
TEMP_FAHRENHEIT,
)
from homeassistant.core import callback
from homeassistant.core import callback, valid_entity_id
from homeassistant.helpers.dispatcher import async_dispatcher_connect

from . import TuyaDevice
from .const import (
CONF_CURR_TEMP_DIVIDER,
CONF_EXT_TEMP_SENSOR,
CONF_MAX_TEMP,
CONF_MIN_TEMP,
CONF_TEMP_DIVIDER,
Expand Down Expand Up @@ -110,6 +112,8 @@ def __init__(self, tuya, platform):
self._def_hvac_mode = HVAC_MODE_AUTO
self._min_temp = None
self._max_temp = None
self._temp_entity = None
self._temp_entity_error = False

@callback
def _process_config(self):
Expand All @@ -129,6 +133,7 @@ def _process_config(self):
else:
self._min_temp = min_temp
self._max_temp = max_temp
self._temp_entity = config.get(CONF_EXT_TEMP_SENSOR)

async def async_added_to_hass(self):
"""Create operation list when add to hass."""
Expand Down Expand Up @@ -191,7 +196,10 @@ def hvac_modes(self):
@property
def current_temperature(self):
"""Return the current temperature."""
return self._tuya.current_temperature()
curr_temp = self._tuya.current_temperature()
if curr_temp is None:
return self._get_ext_temperature()
return curr_temp

@property
def target_temperature(self):
Expand Down Expand Up @@ -263,3 +271,39 @@ def max_temp(self):
if max_temp is not None:
return max_temp
return super().max_temp

def _set_and_log_temp_error(self, error_msg):
if not self._temp_entity_error:
_LOGGER.warning(
"Error on Tuya external temperature sensor %s: %s",
self._temp_entity,
error_msg,
)
self._temp_entity_error = True

def _get_ext_temperature(self):
"""Get external temperature entity current state."""
if not self._temp_entity or self._temp_entity == ENTITY_MATCH_NONE:
return None

entity_name = self._temp_entity
if not valid_entity_id(entity_name):
self._set_and_log_temp_error("entity name is invalid")
return None

state_obj = self.hass.states.get(entity_name)
if state_obj:
temperature = state_obj.state
try:
float(temperature)
except (TypeError, ValueError):
self._set_and_log_temp_error(
"entity state is not available or is not a number"
)
return None

self._temp_entity_error = False
return temperature

self._set_and_log_temp_error("entity not found")
return None
23 changes: 19 additions & 4 deletions custom_components/tuya_custom/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
CONF_COUNTRYCODE,
CONF_CURR_TEMP_DIVIDER,
CONF_DISCOVERY_INTERVAL,
CONF_EXT_TEMP_SENSOR,
CONF_MAX_KELVIN,
CONF_MAX_TEMP,
CONF_MIN_KELVIN,
Expand Down Expand Up @@ -233,7 +234,7 @@ async def _async_device_form(self, devs_id):
device_id, self.config_entry.options.get(device_id, {})
)

config_schema = self._get_device_schema(device_type, curr_conf, device)
config_schema = await self._get_device_schema(device_type, curr_conf, device)
if not config_schema:
self._form_error = ERROR_DEV_NOT_CONFIG
return await self.async_step_init()
Expand Down Expand Up @@ -318,12 +319,13 @@ async def async_step_device(self, user_input=None, dev_ids=None):

return await self.async_step_init()

def _get_device_schema(self, device_type, curr_conf, device):
async def _get_device_schema(self, device_type, curr_conf, device):
"""Return option schema for device."""
if device_type == "light":
return self._get_light_schema(curr_conf, device)
if device_type == "climate":
return self._get_climate_schema(curr_conf, device)
entities_list = await _get_entities_matching_domains(self.hass, ["sensor"])
return self._get_climate_schema(curr_conf, device, entities_list)
return None

@staticmethod
Expand Down Expand Up @@ -365,10 +367,11 @@ def _get_light_schema(curr_conf, device):
return config_schema

@staticmethod
def _get_climate_schema(curr_conf, device):
def _get_climate_schema(curr_conf, device, entities_list):
"""Create option schema for climate device."""
unit = device.temperature_unit()
def_unit = TEMP_FAHRENHEIT if unit == "FAHRENHEIT" else TEMP_CELSIUS
entities_list.insert(0, ENTITY_MATCH_NONE)

config_schema = vol.Schema(
{
Expand All @@ -389,7 +392,19 @@ def _get_climate_schema(curr_conf, device):
vol.Optional(
CONF_MAX_TEMP, default=curr_conf.get(CONF_MAX_TEMP, 0),
): int,
vol.Optional(
CONF_EXT_TEMP_SENSOR,
default=curr_conf.get(CONF_EXT_TEMP_SENSOR, ENTITY_MATCH_NONE),
): vol.In(entities_list),
}
)

return config_schema


async def _get_entities_matching_domains(hass, domains):
"""List entities in the given domains."""
included_domains = set(domains)
entity_ids = hass.states.async_entity_ids(included_domains)
entity_ids.sort()
return entity_ids
1 change: 1 addition & 0 deletions custom_components/tuya_custom/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
CONF_COUNTRYCODE = "country_code"
CONF_CURR_TEMP_DIVIDER = "curr_temp_divider"
CONF_DISCOVERY_INTERVAL = "discovery_interval"
CONF_EXT_TEMP_SENSOR = "ext_temp_sensor"
CONF_MAX_KELVIN = "max_kelvin"
CONF_MAX_TEMP = "max_temp"
CONF_MIN_KELVIN = "min_kelvin"
Expand Down
3 changes: 2 additions & 1 deletion custom_components/tuya_custom/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@
"temp_divider": "Temperature values divider (0 = use default)",
"curr_temp_divider": "Current Temperature value divider (0 = use default)",
"min_temp": "Min target temperature (use min and max = 0 for default)",
"max_temp": "Max target temperature (use min and max = 0 for default)"
"max_temp": "Max target temperature (use min and max = 0 for default)",
"ext_temp_sensor": "Sensor for current temperature"
}
}
},
Expand Down
3 changes: 2 additions & 1 deletion custom_components/tuya_custom/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@
"support_color": "Force color support",
"temp_divider": "Temperature values divider (0 = use default)",
"tuya_max_coltemp": "Max color temperature reported by device",
"unit_of_measurement": "Temperature unit used by device"
"unit_of_measurement": "Temperature unit used by device",
"ext_temp_sensor": "Sensor for current temperature"
},
"description": "Configure options to adjust displayed information for {device_type} device `{device_name}`",
"title": "Configure Tuya Device"
Expand Down

0 comments on commit bf20a0c

Please sign in to comment.