From 1ddcab5e263fbe161fa3d26f4392cd0f49f27122 Mon Sep 17 00:00:00 2001 From: Phil Hawthorne Date: Wed, 14 Jun 2017 08:42:55 +1000 Subject: [PATCH] Make percentage string values as floats/ints in InfluxDB (#7879) * Make percentage string values as floats in InfluxDB Currently Z-wave and other compontents report an attributes battery level as an integer, for example ```yaml { "is_awake": false, "battery_level": 61, } ``` However, some other components like Vera add the battery level as a string ```yaml { "Vera Device Id": 25, "device_armed": "False", "battery_level": "63%", "device_tripped": "False", } ``` By removing any % signs in the field, this will send the value to InfluxDB as an int, which can then be used to plot the data in graphs correctly, like other percentage fields. * Add tests and remove all trailing non digits Adds tests and now removes all trailing non-numeric characters for better use * Update variable name for InfluxDB digit checks Updates the variable used for the regex to remove trailing non digits * Fix linting errors for InfluxDB component Fixes a small linting error on the InfluxDB component --- homeassistant/components/influxdb.py | 7 +++++++ tests/components/test_influxdb.py | 19 ++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/influxdb.py b/homeassistant/components/influxdb.py index 7ac3f4dcdce..37aeeee41b7 100644 --- a/homeassistant/components/influxdb.py +++ b/homeassistant/components/influxdb.py @@ -6,6 +6,8 @@ https://home-assistant.io/components/influxdb/ """ import logging +import re + import voluptuous as vol from homeassistant.const import ( @@ -147,6 +149,8 @@ def setup(hass, config): } ] + non_digit_tail = re.compile(r'[\d.]+') + non_decimal = re.compile(r'[^\d.]+') for key, value in state.attributes.items(): if key != 'unit_of_measurement': # If the key is already in fields @@ -161,6 +165,9 @@ def setup(hass, config): except (ValueError, TypeError): new_key = "{}_str".format(key) json_body[0]['fields'][new_key] = str(value) + if non_digit_tail.match(json_body[0]['fields'][new_key]): + json_body[0]['fields'][key] = float( + non_decimal.sub('', value)) json_body[0]['tags'].update(tags) diff --git a/tests/components/test_influxdb.py b/tests/components/test_influxdb.py index ab1f8916c37..301c4c7b9b1 100644 --- a/tests/components/test_influxdb.py +++ b/tests/components/test_influxdb.py @@ -120,7 +120,10 @@ class TestInfluxDB(unittest.TestCase): attrs = { 'unit_of_measurement': 'foobars', 'longitude': '1.1', - 'latitude': '2.2' + 'latitude': '2.2', + 'battery_level': '99%', + 'temperature': '20c', + 'last_seen': 'Last seen 23 minutes ago' } state = mock.MagicMock( state=in_, domain='fake', object_id='entity', attributes=attrs) @@ -136,7 +139,12 @@ class TestInfluxDB(unittest.TestCase): 'fields': { 'state': out, 'longitude': 1.1, - 'latitude': 2.2 + 'latitude': 2.2, + 'battery_level_str': '99%', + 'battery_level': 99.0, + 'temperature_str': '20c', + 'temperature': 20.0, + 'last_seen_str': 'Last seen 23 minutes ago' }, }] @@ -151,7 +159,12 @@ class TestInfluxDB(unittest.TestCase): 'fields': { 'value': out, 'longitude': 1.1, - 'latitude': 2.2 + 'latitude': 2.2, + 'battery_level_str': '99%', + 'battery_level': 99.0, + 'temperature_str': '20c', + 'temperature': 20.0, + 'last_seen_str': 'Last seen 23 minutes ago' }, }] self.handler_method(event)