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 scale and offset to temperature values to Modbus Climate #27045

Merged
merged 4 commits into from Nov 26, 2019
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Expand Up @@ -178,6 +178,7 @@ homeassistant/components/mill/* @danielhiversen
homeassistant/components/min_max/* @fabaff
homeassistant/components/minio/* @tkislan
homeassistant/components/mobile_app/* @robbiet480
homeassistant/components/modbus/* @adamchengtkc
homeassistant/components/monoprice/* @etsinko
homeassistant/components/moon/* @fabaff
homeassistant/components/mpd/* @fabaff
Expand Down
80 changes: 73 additions & 7 deletions homeassistant/components/modbus/climate.py
Expand Up @@ -7,9 +7,15 @@
from homeassistant.components.climate import PLATFORM_SCHEMA, ClimateDevice
from homeassistant.components.climate.const import (
SUPPORT_TARGET_TEMPERATURE,
HVAC_MODE_HEAT,
HVAC_MODE_AUTO,
)
from homeassistant.const import (
ATTR_TEMPERATURE,
CONF_NAME,
CONF_SLAVE,
TEMP_CELSIUS,
TEMP_FAHRENHEIT,
)
from homeassistant.const import ATTR_TEMPERATURE, CONF_NAME, CONF_SLAVE
import homeassistant.helpers.config_validation as cv

from . import CONF_HUB, DEFAULT_HUB, DOMAIN as MODBUS_DOMAIN
Expand All @@ -21,12 +27,17 @@
CONF_DATA_TYPE = "data_type"
CONF_COUNT = "data_count"
CONF_PRECISION = "precision"

CONF_SCALE = "scale"
CONF_OFFSET = "offset"
CONF_UNIT = "temperature_unit"
DATA_TYPE_INT = "int"
DATA_TYPE_UINT = "uint"
DATA_TYPE_FLOAT = "float"
CONF_MAX_TEMP = "max_temp"
CONF_MIN_TEMP = "min_temp"
CONF_STEP = "temp_step"
SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE
HVAC_MODES = [HVAC_MODE_HEAT]
HVAC_MODES = [HVAC_MODE_AUTO]

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{
Expand All @@ -40,6 +51,12 @@
),
vol.Optional(CONF_HUB, default=DEFAULT_HUB): cv.string,
vol.Optional(CONF_PRECISION, default=1): cv.positive_int,
vol.Optional(CONF_SCALE, default=1): vol.Coerce(float),
vol.Optional(CONF_OFFSET, default=0): vol.Coerce(float),
vol.Optional(CONF_MAX_TEMP, default=5): cv.positive_int,
vol.Optional(CONF_MIN_TEMP, default=35): cv.positive_int,
vol.Optional(CONF_STEP, default=0.5): vol.Coerce(float),
vol.Optional(CONF_UNIT, default="C"): cv.string,
}
)

Expand All @@ -53,6 +70,12 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
data_type = config.get(CONF_DATA_TYPE)
count = config.get(CONF_COUNT)
precision = config.get(CONF_PRECISION)
scale = config.get(CONF_SCALE)
offset = config.get(CONF_OFFSET)
unit = config.get(CONF_UNIT)
max_temp = config.get(CONF_MAX_TEMP)
min_temp = config.get(CONF_MIN_TEMP)
temp_step = config.get(CONF_STEP)
hub_name = config.get(CONF_HUB)
hub = hass.data[MODBUS_DOMAIN][hub_name]

Expand All @@ -67,6 +90,12 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
data_type,
count,
precision,
scale,
offset,
unit,
max_temp,
min_temp,
temp_step,
)
],
True,
Expand All @@ -86,6 +115,12 @@ def __init__(
data_type,
count,
precision,
scale,
offset,
unit,
max_temp,
min_temp,
temp_step,
):
"""Initialize the unit."""
self._hub = hub
Expand All @@ -98,6 +133,12 @@ def __init__(
self._data_type = data_type
self._count = int(count)
self._precision = precision
self._scale = scale
self._offset = offset
self._unit = unit
self._max_temp = max_temp
self._min_temp = min_temp
self._temp_step = temp_step
self._structure = ">f"

data_types = {
Expand All @@ -123,7 +164,7 @@ def update(self):
@property
def hvac_mode(self):
"""Return the current HVAC mode."""
return HVAC_MODE_HEAT
return HVAC_MODE_AUTO

@property
def hvac_modes(self):
Expand All @@ -145,9 +186,31 @@ def target_temperature(self):
"""Return the target temperature."""
return self._target_temperature

@property
def temperature_unit(self):
"""Return the unit of measurement."""
return TEMP_FAHRENHEIT if self._unit == "F" else TEMP_CELSIUS

@property
def min_temp(self):
"""Return the minimum temperature."""
return self._min_temp

@property
def max_temp(self):
"""Return the maximum temperature."""
return self._max_temp

@property
def target_temperature_step(self):
"""Return the supported step of target temperature."""
return self._temp_step

def set_temperature(self, **kwargs):
"""Set new target temperature."""
target_temperature = kwargs.get(ATTR_TEMPERATURE)
target_temperature = int(
(kwargs.get(ATTR_TEMPERATURE) - self._offset) / self._scale
)
if target_temperature is None:
return
byte_string = struct.pack(self._structure, target_temperature)
Expand All @@ -170,7 +233,10 @@ def read_register(self, register):
[x.to_bytes(2, byteorder="big") for x in result.registers]
)
val = struct.unpack(self._structure, byte_string)[0]
register_value = format(val, f".{self._precision}f")
register_value = format(
(self._scale * val) + self._offset, f".{self._precision}f"
)
register_value = float(register_value)
return register_value

def write_register(self, register, value):
Expand Down
4 changes: 3 additions & 1 deletion homeassistant/components/modbus/manifest.json
Expand Up @@ -6,5 +6,7 @@
"pymodbus==1.5.2"
],
"dependencies": [],
"codeowners": []
"codeowners": [
"@adamchengtkc"
]
}