Skip to content

Commit

Permalink
Add unit system support
Browse files Browse the repository at this point in the history
Add unit symbol constants

Initial unit system object

Import more constants

Pydoc for unit system file

Import constants for configuration validation

Unit system validation method

Typing for constants

Inches are valid lengths too

Typings

Change base class to dict - needed for remote api call serialization

Validation

Use dictionary keys

Defined unit systems

Update location util to use metric instead of us fahrenheit

Update constant imports

Import defined unit systems

Update configuration to use unit system

Update schema to use unit system

Update constants

Add imports to core for unit system and distance

Type for config

Default unit system

Convert distance from HASS instance

Update temperature conversion to use unit system

Update temperature conversion

Set unit system based on configuration

Set info unit system

Return unit system dictionary with config dictionary

Auto discover unit system

Update location test for use metric

Update forecast unit system

Update mold indicator unit system

Update thermostat unit system

Update thermostat demo test

Unit tests around unit system

Update test common hass configuration

Update configuration unit tests

There should always be a unit system!

Update core unit tests

Constants typing

Linting issues

Remove unused import

Update fitbit sensor to use application unit system

Update google travel time to use application unit system

Update configuration example

Update dht sensor

Update DHT temperature conversion to use the utility function

Update swagger config

Update my sensors metric flag

Update hvac component temperature conversion

HVAC conversion for temperature

Pull unit from sensor type map

Pull unit from sensor type map

Update the temper sensor unit

Update yWeather sensor unit

Update hvac demo unit test

Set unit test config unit system to metric

Use hass unit system length for default in proximity

Use the name of the system instead of temperature

Use constants from const

Unused import

Forecasted temperature

Fix calculation in case furthest distance is greater than 1000000 units

Remove unneeded constants

Set default length to km or miles

Use constants

Linting doesn't like importing just for typing

Fix reference

Test is expecting meters - set config to meters

Use constant

Use constant

PyDoc for unit test

Should be not in

Rename to units

Change unit system to be an object - not a dictionary

Return tuple in conversion

Move convert to temperature util

Temperature conversion is now in unit system

Update imports

Rename to units

Units is now an object

Use temperature util conversion

Unit system is now an object

Validate and convert unit system config

Return the scalar value in template distance

Test is expecting meters

Update unit tests around unit system

Distance util returns tuple

Fix location info test

Set units

Update unit tests

Convert distance

DOH

Pull out the scalar from the vector

Linting

I really hate python linting

Linting again

BLARG

Unit test documentation

Unit test around is metric flag

Break ternary statement into if/else blocks

Don't use dictionary - use members

is metric flag

Rename constants

Use is metric flag

Move constants to CONST file

Move to const file

Raise error if unit is not expected

Typing

No need to return unit since only performing conversion if it can work

Use constants

Line wrapping

Raise error if invalid value

Remove subscripts from conversion as they are no longer returned as tuples

No longer tuples

No longer tuples

Check for numeric type

Fix string format to use correct variable

Typing

Assert errors raised

Remove subscript

Only convert temperature if we know the unit

If no unit of measurement set - default to HASS config

Convert only if we know the unit

Remove subscription

Fix not in clause

Linting fixes

Wants a boolean

Clearer if-block

Check if the key is in the config first

Missed a couple expecting tuples

Backwards compatibility

No like-y ternary!

Error handling around state setting

Pretty unit system configuration validation

More tuple crap

Use is metric flag

Error handling around min/max temp

Explode if no unit

Pull unit from config

Celsius has a decimal

Unused import

Check if it's a temperature before we try to convert it to a temperature

Linting says too many statements - combine lat/long in a fairly reasonable manner

Backwards compatibility unit test

Better doc
  • Loading branch information
Teagan42 authored and balloob committed Aug 5, 2016
1 parent 792154a commit 26526ca
Show file tree
Hide file tree
Showing 39 changed files with 595 additions and 261 deletions.
4 changes: 2 additions & 2 deletions config/configuration.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ homeassistant:
# Impacts weather/sunrise data
elevation: 665

# C for Celsius, F for Fahrenheit
temperature_unit: C
# 'metric' for Metric System, 'imperial' for imperial system
unit_system: metric

# Pick yours from here:
# http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
Expand Down
3 changes: 2 additions & 1 deletion docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -419,8 +419,9 @@ definitions:
description: Longitude of Home Assistant server
location_name:
type: string
temperature_unit:
unit_system:
type: string
description: The system for measurement units
time_zone:
type: string
version:
Expand Down
21 changes: 11 additions & 10 deletions homeassistant/components/hvac/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
"""
import logging
import os
from numbers import Number

from homeassistant.helpers.entity_component import EntityComponent

from homeassistant.config import load_yaml_config_file
import homeassistant.util as util
from homeassistant.util.temperature import convert as convert_temperature
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.temperature import convert
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa
from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_TEMPERATURE, STATE_ON, STATE_OFF, STATE_UNKNOWN,
Expand Down Expand Up @@ -204,8 +205,8 @@ def temperature_set_service(service):
return

for hvac in target_hvacs:
hvac.set_temperature(convert(
temperature, hass.config.temperature_unit,
hvac.set_temperature(convert_temperature(
temperature, hass.config.units.temperature_unit,
hvac.unit_of_measurement))

if hvac.should_poll:
Expand Down Expand Up @@ -462,12 +463,12 @@ def turn_aux_heat_off(self):
@property
def min_temp(self):
"""Return the minimum temperature."""
return convert(19, TEMP_CELSIUS, self.unit_of_measurement)
return convert_temperature(19, TEMP_CELSIUS, self.unit_of_measurement)

@property
def max_temp(self):
"""Return the maximum temperature."""
return convert(30, TEMP_CELSIUS, self.unit_of_measurement)
return convert_temperature(30, TEMP_CELSIUS, self.unit_of_measurement)

@property
def min_humidity(self):
Expand All @@ -481,13 +482,13 @@ def max_humidity(self):

def _convert_for_display(self, temp):
"""Convert temperature into preferred units for display purposes."""
if temp is None:
return None
if temp is None or not isinstance(temp, Number):
return temp

value = convert(temp, self.unit_of_measurement,
self.hass.config.temperature_unit)
value = convert_temperature(temp, self.unit_of_measurement,
self.hass.config.units.temperature_unit)

if self.hass.config.temperature_unit is TEMP_CELSIUS:
if self.hass.config.units.temperature_unit is TEMP_CELSIUS:
decimal_count = 1
else:
# Users of fahrenheit generally expect integer units.
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/mysensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from homeassistant.const import (ATTR_BATTERY_LEVEL, CONF_OPTIMISTIC,
EVENT_HOMEASSISTANT_START,
EVENT_HOMEASSISTANT_STOP,
STATE_OFF, STATE_ON, TEMP_CELSIUS)
STATE_OFF, STATE_ON)
from homeassistant.helpers import validate_config, discovery

CONF_GATEWAYS = 'gateways'
Expand Down Expand Up @@ -53,7 +53,7 @@ def setup(hass, config): # pylint: disable=too-many-locals
import mysensors.mysensors as mysensors

version = str(config[DOMAIN].get(CONF_VERSION, DEFAULT_VERSION))
is_metric = (hass.config.temperature_unit == TEMP_CELSIUS)
is_metric = hass.config.units.is_metric
persistence = config[DOMAIN].get(CONF_PERSISTENCE, True)

def setup_gateway(device, persistence_file, baud_rate, tcp_port):
Expand Down
11 changes: 4 additions & 7 deletions homeassistant/components/proximity.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@
# Default zone
DEFAULT_PROXIMITY_ZONE = 'home'

# Default unit of measure
DEFAULT_UNIT_OF_MEASUREMENT = 'km'

# Default distance to zone
DEFAULT_DIST_TO_ZONE = NOT_SET

Expand Down Expand Up @@ -71,7 +68,7 @@ def setup_proximity_component(hass, config):

# Get the unit of measurement from configuration.yaml.
unit_of_measure = config.get(ATTR_UNIT_OF_MEASUREMENT,
DEFAULT_UNIT_OF_MEASUREMENT)
hass.config.units.length_unit)

zone_id = 'zone.{}'.format(proximity_zone)
state = hass.states.get(zone_id)
Expand Down Expand Up @@ -216,11 +213,11 @@ def check_proximity_state_change(self, entity, old_state, new_state):

# Loop through each of the distances collected and work out the
# closest.
closest_device = ''
dist_to_zone = 1000000
closest_device = None # type: str
dist_to_zone = None # type: float

for device in distances_to_zone:
if distances_to_zone[device] < dist_to_zone:
if not dist_to_zone or distances_to_zone[device] < dist_to_zone:
closest_device = device
dist_to_zone = distances_to_zone[device]

Expand Down
10 changes: 6 additions & 4 deletions homeassistant/components/sensor/dht.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from homeassistant.const import TEMP_FAHRENHEIT
from homeassistant.helpers.entity import Entity
from homeassistant.util import Throttle
from homeassistant.util.temperature import celsius_to_fahrenheit

# Update this requirement to upstream as soon as it supports Python 3.
REQUIREMENTS = ['http://github.com/mala-zaba/Adafruit_Python_DHT/archive/'
Expand All @@ -32,8 +33,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
# pylint: disable=import-error
import Adafruit_DHT

SENSOR_TYPES['temperature'][1] = hass.config.temperature_unit
unit = hass.config.temperature_unit
SENSOR_TYPES['temperature'][1] = hass.config.units.temperature_unit
available_sensors = {
"DHT11": Adafruit_DHT.DHT11,
"DHT22": Adafruit_DHT.DHT22,
Expand All @@ -58,7 +58,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
if variable not in SENSOR_TYPES:
_LOGGER.error('Sensor type: "%s" does not exist', variable)
else:
dev.append(DHTSensor(data, variable, unit, name))
dev.append(
DHTSensor(data, variable, SENSOR_TYPES[variable][1], name))
except KeyError:
pass

Expand Down Expand Up @@ -103,7 +104,8 @@ def update(self):
if self.type == 'temperature':
self._state = round(data['temperature'], 1)
if self.temp_unit == TEMP_FAHRENHEIT:
self._state = round(data['temperature'] * 1.8 + 32, 1)
self._state = round(celsius_to_fahrenheit(data['temperature']),
1)
elif self.type == 'humidity':
self._state = round(data['humidity'], 1)

Expand Down
4 changes: 1 addition & 3 deletions homeassistant/components/sensor/fitbit.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import datetime
import time

from homeassistant.const import TEMP_CELSIUS
from homeassistant.util import Throttle
from homeassistant.helpers.entity import Entity
from homeassistant.loader import get_component
Expand Down Expand Up @@ -238,8 +237,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
for resource in config.get("monitored_resources",
FITBIT_DEFAULT_RESOURCE_LIST):
dev.append(FitbitSensor(authd_client, config_path, resource,
hass.config.temperature_unit ==
TEMP_CELSIUS))
hass.config.units.is_metric))
add_devices(dev)

else:
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/sensor/forecast.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
HTTPError, Timeout

from homeassistant.components.sensor import DOMAIN
from homeassistant.const import CONF_API_KEY, TEMP_CELSIUS
from homeassistant.const import CONF_API_KEY
from homeassistant.helpers import validate_config
from homeassistant.helpers.entity import Entity
from homeassistant.util import Throttle
Expand Down Expand Up @@ -62,7 +62,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):

if 'units' in config:
units = config['units']
elif hass.config.temperature_unit == TEMP_CELSIUS:
elif hass.config.units.is_metric:
units = 'si'
else:
units = 'us'
Expand Down
8 changes: 2 additions & 6 deletions homeassistant/components/sensor/google_travel_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@

from homeassistant.helpers.entity import Entity
from homeassistant.const import (
CONF_API_KEY, TEMP_CELSIUS, TEMP_FAHRENHEIT,
EVENT_HOMEASSISTANT_START, ATTR_LATITUDE, ATTR_LONGITUDE)
CONF_API_KEY, EVENT_HOMEASSISTANT_START, ATTR_LATITUDE, ATTR_LONGITUDE)

from homeassistant.util import Throttle
import homeassistant.helpers.config_validation as cv
Expand Down Expand Up @@ -92,10 +91,7 @@ def run_setup(event):
options = config.get(CONF_OPTIONS)

if options.get('units') is None:
if hass.config.temperature_unit is TEMP_CELSIUS:
options['units'] = 'metric'
elif hass.config.temperature_unit is TEMP_FAHRENHEIT:
options['units'] = 'imperial'
options['units'] = hass.config.units.name

travel_mode = config.get(CONF_TRAVEL_MODE)
mode = options.get(CONF_MODE)
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/sensor/mold_indicator.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def __init__(self, hass, name, indoor_temp_sensor, outdoor_temp_sensor,
self._indoor_humidity_sensor = indoor_humidity_sensor
self._outdoor_temp_sensor = outdoor_temp_sensor
self._calib_factor = calib_factor
self._is_metric = (hass.config.temperature_unit == TEMP_CELSIUS)
self._is_metric = hass.config.units.is_metric

self._dewpoint = None
self._indoor_temp = None
Expand Down
9 changes: 5 additions & 4 deletions homeassistant/components/sensor/openweathermap.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):

from pyowm import OWM

SENSOR_TYPES['temperature'][1] = hass.config.temperature_unit
unit = hass.config.temperature_unit
SENSOR_TYPES['temperature'][1] = hass.config.units.temperature_unit
forecast = config.get('forecast')
owm = OWM(config.get(CONF_API_KEY, None))

Expand All @@ -67,13 +66,15 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
if variable not in SENSOR_TYPES:
_LOGGER.error('Sensor type: "%s" does not exist', variable)
else:
dev.append(OpenWeatherMapSensor(data, variable, unit))
dev.append(OpenWeatherMapSensor(data, variable,
SENSOR_TYPES[variable][1]))
except KeyError:
pass

if forecast:
SENSOR_TYPES['forecast'] = ['Forecast', None]
dev.append(OpenWeatherMapSensor(data, 'forecast', unit))
dev.append(OpenWeatherMapSensor(data, 'forecast',
SENSOR_TYPES['temperature'][1]))

add_devices(dev)

Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/sensor/temper.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None):
"""Setup the Temper sensors."""
from temperusb.temper import TemperHandler

temp_unit = hass.config.temperature_unit
temp_unit = hass.config.units.temperature_unit
name = config.get(CONF_NAME, DEVICE_DEFAULT_NAME)
temper_devices = TemperHandler().get_devices()
add_devices_callback([TemperSensor(dev, temp_unit, name + '_' + str(idx))
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/sensor/vera.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ def update(self):
self._temperature_units = TEMP_CELSIUS

if self.hass:
temp = self.hass.config.temperature(
temp = self.hass.config.units.temperature(
current_temp,
self._temperature_units)

current_temp, self._temperature_units = temp
current_temp = temp

self.current_value = current_temp
elif self.vera_device.category == "Light Sensor":
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/sensor/yweather.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Yahoo! weather sensor."""
from yahooweather import get_woeid, UNIT_C, UNIT_F

unit = hass.config.temperature_unit
unit = hass.config.units.temperature_unit
woeid = config.get("woeid", None)
forecast = config.get("forecast", 0)

Expand Down
35 changes: 24 additions & 11 deletions homeassistant/components/thermostat/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@
"""
import logging
import os
from numbers import Number

import voluptuous as vol

from homeassistant.helpers.entity_component import EntityComponent

from homeassistant.config import load_yaml_config_file
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.temperature import convert
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa
import homeassistant.helpers.config_validation as cv
from homeassistant.util.temperature import convert
from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_TEMPERATURE, STATE_ON, STATE_OFF, STATE_UNKNOWN,
TEMP_CELSIUS)
Expand Down Expand Up @@ -146,9 +147,13 @@ def temperature_set_service(service):
temperature = service.data[ATTR_TEMPERATURE]

for thermostat in target_thermostats:
thermostat.set_temperature(convert(
temperature, hass.config.temperature_unit,
thermostat.unit_of_measurement))
if thermostat.unit_of_measurement is not None:
converted_temperature = convert(
temperature, hass.config.units.temperature_unit,
thermostat.unit_of_measurement)
else:
converted_temperature = temperature
thermostat.set_temperature(converted_temperature)

thermostat.update_ha_state(True)

Expand Down Expand Up @@ -301,22 +306,30 @@ def turn_fan_off(self):
@property
def min_temp(self):
"""Return the minimum temperature."""
return convert(7, TEMP_CELSIUS, self.unit_of_measurement)
try:
unit = self.unit_of_measurement
return convert(7, TEMP_CELSIUS, unit)
except ValueError:
return STATE_UNKNOWN

@property
def max_temp(self):
"""Return the maximum temperature."""
return convert(35, TEMP_CELSIUS, self.unit_of_measurement)
try:
unit = self.unit_of_measurement
return convert(35, TEMP_CELSIUS, unit)
except ValueError:
return STATE_UNKNOWN

def _convert_for_display(self, temp):
"""Convert temperature into preferred units for display purposes."""
if temp is None:
return None
if temp is None or not isinstance(temp, Number):
return temp

value = convert(temp, self.unit_of_measurement,
self.hass.config.temperature_unit)
value = self.hass.config.units.temperature(temp,
self.unit_of_measurement)

if self.hass.config.temperature_unit is TEMP_CELSIUS:
if self.hass.config.units.is_metric:
decimal_count = 1
else:
# Users of fahrenheit generally expect integer units.
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/thermostat/eq3btsmart.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from homeassistant.components.thermostat import ThermostatDevice
from homeassistant.const import TEMP_CELSIUS
from homeassistant.helpers.temperature import convert
from homeassistant.util.temperature import convert

REQUIREMENTS = ['bluepy_devices==0.2.0']

Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/thermostat/heat_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def __init__(self, hass, name, heater_entity_id, sensor_entity_id,
self._min_temp = min_temp
self._max_temp = max_temp
self._target_temp = target_temp
self._unit = None
self._unit = hass.config.units.temperature_unit

track_state_change(hass, sensor_entity_id, self._sensor_changed)

Expand Down
Loading

0 comments on commit 26526ca

Please sign in to comment.