From c1139976095296068dd49c1d75b87e36a7925815 Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Sun, 7 Feb 2016 19:28:23 +0000 Subject: [PATCH 1/4] Tweak mFi switch behavior to avoid false states When we update the mFi server for the state of a switch, the new state is not always reported immediately if we update right after the action (the server is not RESTful). This patch adds some internal target-state handling to report the desired state on the next poll, allowing any subsequent polls to override that state. Also, bump the version requirement for mficlient to 0.2.2 to absorb a bug fix. --- homeassistant/components/sensor/mfi.py | 2 +- homeassistant/components/switch/mfi.py | 10 +++++++--- requirements_all.txt | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/sensor/mfi.py b/homeassistant/components/sensor/mfi.py index 3e68f779dbb..d032279e6dd 100644 --- a/homeassistant/components/sensor/mfi.py +++ b/homeassistant/components/sensor/mfi.py @@ -14,7 +14,7 @@ from homeassistant.components.sensor import DOMAIN from homeassistant.helpers.entity import Entity from homeassistant.helpers import validate_config -REQUIREMENTS = ['mficlient==0.2'] +REQUIREMENTS = ['mficlient==0.2.2'] _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/switch/mfi.py b/homeassistant/components/switch/mfi.py index aebaa95c88b..ac03e976e21 100644 --- a/homeassistant/components/switch/mfi.py +++ b/homeassistant/components/switch/mfi.py @@ -12,7 +12,7 @@ from homeassistant.components.switch import DOMAIN, SwitchDevice from homeassistant.const import CONF_USERNAME, CONF_PASSWORD from homeassistant.helpers import validate_config -REQUIREMENTS = ['mficlient==0.2'] +REQUIREMENTS = ['mficlient==0.2.2'] _LOGGER = logging.getLogger(__name__) @@ -56,6 +56,7 @@ class MfiSwitch(SwitchDevice): """ An mFi switch-able device. """ def __init__(self, port): self._port = port + self._target_state = None @property def should_poll(self): @@ -75,14 +76,17 @@ class MfiSwitch(SwitchDevice): def update(self): self._port.refresh() + if self._target_state is not None: + self._port.data['output'] = float(self._target_state) + self._target_state = None def turn_on(self): self._port.control(True) - self._port.data['output'] = 1.0 + self._target_state = True def turn_off(self): self._port.control(False) - self._port.data['output'] = 0.0 + self._target_state = False @property def current_power_mwh(self): diff --git a/requirements_all.txt b/requirements_all.txt index 922bff9cba1..73a53ab7435 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -107,7 +107,7 @@ limitlessled==1.0.0 # homeassistant.components.sensor.mfi # homeassistant.components.switch.mfi -mficlient==0.2 +mficlient==0.2.2 # homeassistant.components.discovery netdisco==0.5.2 From 951fa603ff7a19c1a23569ad86f2a51df9304e15 Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Sun, 7 Feb 2016 20:24:19 +0000 Subject: [PATCH 2/4] Support mPort voltage output switch types An mPort device has a voltage output port that, if configured, we should support like a switch. --- homeassistant/components/switch/mfi.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/homeassistant/components/switch/mfi.py b/homeassistant/components/switch/mfi.py index ac03e976e21..1cee23e906b 100644 --- a/homeassistant/components/switch/mfi.py +++ b/homeassistant/components/switch/mfi.py @@ -18,6 +18,9 @@ _LOGGER = logging.getLogger(__name__) SWITCH_MODELS = [ 'Outlet', + 'Output 5v', + 'Output 12v', + 'Output 24v', ] From 8f690ff077444659015b25680086915af7868374 Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Sun, 7 Feb 2016 20:26:25 +0000 Subject: [PATCH 3/4] Add support for mPort input sensors The mPort device has input pins that can be configured as digital or analog inputs. We should support those as sensors. --- homeassistant/components/sensor/mfi.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/sensor/mfi.py b/homeassistant/components/sensor/mfi.py index d032279e6dd..3aeb6736819 100644 --- a/homeassistant/components/sensor/mfi.py +++ b/homeassistant/components/sensor/mfi.py @@ -18,10 +18,14 @@ REQUIREMENTS = ['mficlient==0.2.2'] _LOGGER = logging.getLogger(__name__) +STATE_ON = 'on' +STATE_OFF = 'off' SENSOR_MODELS = [ 'Ubiquiti mFi-THS', 'Ubiquiti mFi-CS', 'Outlet', + 'Input Analog', + 'Input Digital', ] @@ -69,7 +73,10 @@ class MfiSensor(Entity): @property def state(self): - return self._port.value + if self._port.model == 'Input Digital': + return self._port.value > 0 and STATE_ON or STATE_OFF + else: + return self._port.value @property def unit_of_measurement(self): @@ -77,6 +84,8 @@ class MfiSensor(Entity): return TEMP_CELCIUS elif self._port.tag == 'active_pwr': return 'Watts' + elif self._port.model == 'Input Digital': + return 'State' return self._port.tag def update(self): From 0a7db98b0e74a99663aab0b4e66591e9c9b2006e Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Sun, 7 Feb 2016 20:32:11 +0000 Subject: [PATCH 4/4] Round mFi sensor values to reasonable levels of precision Most of the mFi sensors are able to reasonably provide accurate readings to a tenth of a unit or so. This patch rounds them for better display in the UI. Normally, I would expect this to be a view action instead of altering the actual data emitted, but since these values are reasonable for sensor precision, we're not really losing anything. I followed the model from the openweathermap component, which rounds for readability in the backend. --- homeassistant/components/sensor/mfi.py | 9 ++++++++- homeassistant/components/switch/mfi.py | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/sensor/mfi.py b/homeassistant/components/sensor/mfi.py index 3aeb6736819..d361fa9f690 100644 --- a/homeassistant/components/sensor/mfi.py +++ b/homeassistant/components/sensor/mfi.py @@ -20,6 +20,12 @@ _LOGGER = logging.getLogger(__name__) STATE_ON = 'on' STATE_OFF = 'off' +DIGITS = { + 'volts': 1, + 'amps': 1, + 'active_power': 0, + 'temperature': 1, +} SENSOR_MODELS = [ 'Ubiquiti mFi-THS', 'Ubiquiti mFi-CS', @@ -76,7 +82,8 @@ class MfiSensor(Entity): if self._port.model == 'Input Digital': return self._port.value > 0 and STATE_ON or STATE_OFF else: - return self._port.value + digits = DIGITS.get(self._port.tag, 0) + return round(self._port.value, digits) @property def unit_of_measurement(self): diff --git a/homeassistant/components/switch/mfi.py b/homeassistant/components/switch/mfi.py index 1cee23e906b..46cfdb56213 100644 --- a/homeassistant/components/switch/mfi.py +++ b/homeassistant/components/switch/mfi.py @@ -98,6 +98,6 @@ class MfiSwitch(SwitchDevice): @property def device_state_attributes(self): attr = {} - attr['volts'] = self._port.data.get('v_rms', 0) - attr['amps'] = self._port.data.get('i_rms', 0) + attr['volts'] = round(self._port.data.get('v_rms', 0), 1) + attr['amps'] = round(self._port.data.get('i_rms', 0), 1) return attr