core/tests/components/test_influxdb.py

652 lines
23 KiB
Python
Raw Normal View History

2016-03-09 09:25:50 +00:00
"""The tests for the InfluxDB component."""
import unittest
import datetime
from unittest import mock
import influxdb as influx_client
from homeassistant.setup import setup_component
import homeassistant.components.influxdb as influxdb
from homeassistant.const import EVENT_STATE_CHANGED, STATE_OFF, STATE_ON, \
STATE_STANDBY
from tests.common import get_test_home_assistant
@mock.patch('influxdb.InfluxDBClient')
class TestInfluxDB(unittest.TestCase):
2016-03-09 09:25:50 +00:00
"""Test the InfluxDB component."""
def setUp(self):
"""Setup things to be run when tests are started."""
self.hass = get_test_home_assistant()
self.handler_method = None
self.hass.bus.listen = mock.Mock()
def tearDown(self):
"""Clear data."""
self.hass.stop()
def test_setup_config_full(self, mock_client):
2016-03-09 09:25:50 +00:00
"""Test the setup with full configuration."""
config = {
'influxdb': {
'host': 'host',
'port': 123,
'database': 'db',
'username': 'user',
'password': 'password',
'ssl': 'False',
'verify_ssl': 'False',
}
}
assert setup_component(self.hass, influxdb.DOMAIN, config)
self.assertTrue(self.hass.bus.listen.called)
2016-10-20 17:10:12 +00:00
self.assertEqual(
EVENT_STATE_CHANGED, self.hass.bus.listen.call_args_list[0][0][0])
self.assertTrue(mock_client.return_value.query.called)
def test_setup_config_defaults(self, mock_client):
2016-03-09 09:25:50 +00:00
"""Test the setup with default configuration."""
config = {
'influxdb': {
'host': 'host',
'username': 'user',
'password': 'pass',
}
}
assert setup_component(self.hass, influxdb.DOMAIN, config)
self.assertTrue(self.hass.bus.listen.called)
2016-10-20 17:10:12 +00:00
self.assertEqual(
EVENT_STATE_CHANGED, self.hass.bus.listen.call_args_list[0][0][0])
def test_setup_minimal_config(self, mock_client):
2016-10-20 17:10:12 +00:00
"""Test the setup with minimal configuration."""
config = {
'influxdb': {}
}
assert setup_component(self.hass, influxdb.DOMAIN, config)
def test_setup_missing_password(self, mock_client):
"""Test the setup with existing username and missing password."""
config = {
'influxdb': {
'username': 'user'
}
}
assert not setup_component(self.hass, influxdb.DOMAIN, config)
def test_setup_query_fail(self, mock_client):
2016-03-09 09:25:50 +00:00
"""Test the setup for query failures."""
config = {
'influxdb': {
'host': 'host',
'username': 'user',
'password': 'pass',
}
}
mock_client.return_value.query.side_effect = \
influx_client.exceptions.InfluxDBClientError('fake')
assert not setup_component(self.hass, influxdb.DOMAIN, config)
def _setup(self):
2016-03-09 09:25:50 +00:00
"""Setup the client."""
config = {
'influxdb': {
'host': 'host',
'username': 'user',
'password': 'pass',
'exclude': {
'entities': ['fake.blacklisted'],
'domains': ['another_fake']
}
}
}
assert setup_component(self.hass, influxdb.DOMAIN, config)
self.handler_method = self.hass.bus.listen.call_args_list[0][0][1]
def test_event_listener(self, mock_client):
2016-03-09 09:25:50 +00:00
"""Test the event listener."""
self._setup()
# map of HA State to valid influxdb [state, value] fields
valid = {
'1': [None, 1],
'1.0': [None, 1.0],
STATE_ON: [STATE_ON, 1],
STATE_OFF: [STATE_OFF, 0],
STATE_STANDBY: [STATE_STANDBY, None],
'foo': ['foo', None]
}
for in_, out in valid.items():
attrs = {
'unit_of_measurement': 'foobars',
'longitude': '1.1',
'latitude': '2.2',
'battery_level': '99%',
'temperature': '20c',
'last_seen': 'Last seen 23 minutes ago',
'updated_at': datetime.datetime(2017, 1, 1, 0, 0),
'multi_periods': '0.120.240.2023873'
}
state = mock.MagicMock(
InfluxDB component improvements (#8633) * Allow reporting some state attributes as tags to InfluxDB Some state attributes should really be tags in InfluxDB. E.g. it is helpful to be able to group by friendly_name, or add a custom attribute like "location" and group by that. Graphs in Grafana are much easier to read when friendly names are used, and not node ids. This commit adds an optional setting to InfluxDB config: 'tags_attributes'. Any attribute on this list will be reported as tag and not as field to InfluxDB. * Allow overriding InfluxDB measurement for each reported item separately Bundling all items with the same "unit of measurement" together does not always makes sense. For example, both "relatively humidity" and "battery level" are reported as "%", but I'd rather see them as separate measurements in InfluxDB. This commit allows for 'influxdb_measurement' attribute. When set on node, it will take precedence over the global 'override_measurement' and component-specific 'unit_of_measurement'. * Minor updates to InfluxDB component improvements, as suggested by @MartinHjelmare. * Moved per-component config from 'customize' into 'influxdb' configuration section. The following three sub-sections were added: 'component_config', 'component_config_domain' and 'component_config_glob'. The sole supported per-component attribute at this point is 'override_measurement'. * Lint * Fixed mocked entity_ids in InfluxDB tests to be in domain.entity_id format, to satisfy EntityValues requirements. * Added tests for new InfluxDB configuration parameters * Fixes to some docstrings
2017-08-03 14:26:01 +00:00
state=in_, domain='fake', entity_id='fake.entity-id',
object_id='entity', attributes=attrs)
2016-10-20 17:10:12 +00:00
event = mock.MagicMock(data={'new_state': state}, time_fired=12345)
body = [{
'measurement': 'foobars',
'tags': {
'domain': 'fake',
'entity_id': 'entity',
},
'time': 12345,
'fields': {
'longitude': 1.1,
'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',
'last_seen': 23.0,
'updated_at_str': '2017-01-01 00:00:00',
'updated_at': 20170101000000,
'multi_periods_str': '0.120.240.2023873'
},
}]
if out[0] is not None:
body[0]['fields']['state'] = out[0]
if out[1] is not None:
body[0]['fields']['value'] = out[1]
self.handler_method(event)
self.assertEqual(
mock_client.return_value.write_points.call_count, 1
)
self.assertEqual(
mock_client.return_value.write_points.call_args,
mock.call(body)
)
mock_client.return_value.write_points.reset_mock()
def test_event_listener_no_units(self, mock_client):
"""Test the event listener for missing units."""
self._setup()
for unit in (None, ''):
if unit:
attrs = {'unit_of_measurement': unit}
else:
attrs = {}
state = mock.MagicMock(
InfluxDB component improvements (#8633) * Allow reporting some state attributes as tags to InfluxDB Some state attributes should really be tags in InfluxDB. E.g. it is helpful to be able to group by friendly_name, or add a custom attribute like "location" and group by that. Graphs in Grafana are much easier to read when friendly names are used, and not node ids. This commit adds an optional setting to InfluxDB config: 'tags_attributes'. Any attribute on this list will be reported as tag and not as field to InfluxDB. * Allow overriding InfluxDB measurement for each reported item separately Bundling all items with the same "unit of measurement" together does not always makes sense. For example, both "relatively humidity" and "battery level" are reported as "%", but I'd rather see them as separate measurements in InfluxDB. This commit allows for 'influxdb_measurement' attribute. When set on node, it will take precedence over the global 'override_measurement' and component-specific 'unit_of_measurement'. * Minor updates to InfluxDB component improvements, as suggested by @MartinHjelmare. * Moved per-component config from 'customize' into 'influxdb' configuration section. The following three sub-sections were added: 'component_config', 'component_config_domain' and 'component_config_glob'. The sole supported per-component attribute at this point is 'override_measurement'. * Lint * Fixed mocked entity_ids in InfluxDB tests to be in domain.entity_id format, to satisfy EntityValues requirements. * Added tests for new InfluxDB configuration parameters * Fixes to some docstrings
2017-08-03 14:26:01 +00:00
state=1, domain='fake', entity_id='fake.entity-id',
object_id='entity', attributes=attrs)
event = mock.MagicMock(data={'new_state': state}, time_fired=12345)
body = [{
InfluxDB component improvements (#8633) * Allow reporting some state attributes as tags to InfluxDB Some state attributes should really be tags in InfluxDB. E.g. it is helpful to be able to group by friendly_name, or add a custom attribute like "location" and group by that. Graphs in Grafana are much easier to read when friendly names are used, and not node ids. This commit adds an optional setting to InfluxDB config: 'tags_attributes'. Any attribute on this list will be reported as tag and not as field to InfluxDB. * Allow overriding InfluxDB measurement for each reported item separately Bundling all items with the same "unit of measurement" together does not always makes sense. For example, both "relatively humidity" and "battery level" are reported as "%", but I'd rather see them as separate measurements in InfluxDB. This commit allows for 'influxdb_measurement' attribute. When set on node, it will take precedence over the global 'override_measurement' and component-specific 'unit_of_measurement'. * Minor updates to InfluxDB component improvements, as suggested by @MartinHjelmare. * Moved per-component config from 'customize' into 'influxdb' configuration section. The following three sub-sections were added: 'component_config', 'component_config_domain' and 'component_config_glob'. The sole supported per-component attribute at this point is 'override_measurement'. * Lint * Fixed mocked entity_ids in InfluxDB tests to be in domain.entity_id format, to satisfy EntityValues requirements. * Added tests for new InfluxDB configuration parameters * Fixes to some docstrings
2017-08-03 14:26:01 +00:00
'measurement': 'fake.entity-id',
'tags': {
'domain': 'fake',
'entity_id': 'entity',
},
'time': 12345,
'fields': {
'value': 1,
},
}]
self.handler_method(event)
self.assertEqual(
mock_client.return_value.write_points.call_count, 1
)
self.assertEqual(
mock_client.return_value.write_points.call_args,
mock.call(body)
)
mock_client.return_value.write_points.reset_mock()
def test_event_listener_fail_write(self, mock_client):
2016-03-09 09:25:50 +00:00
"""Test the event listener for write failures."""
self._setup()
2016-10-20 17:10:12 +00:00
state = mock.MagicMock(
InfluxDB component improvements (#8633) * Allow reporting some state attributes as tags to InfluxDB Some state attributes should really be tags in InfluxDB. E.g. it is helpful to be able to group by friendly_name, or add a custom attribute like "location" and group by that. Graphs in Grafana are much easier to read when friendly names are used, and not node ids. This commit adds an optional setting to InfluxDB config: 'tags_attributes'. Any attribute on this list will be reported as tag and not as field to InfluxDB. * Allow overriding InfluxDB measurement for each reported item separately Bundling all items with the same "unit of measurement" together does not always makes sense. For example, both "relatively humidity" and "battery level" are reported as "%", but I'd rather see them as separate measurements in InfluxDB. This commit allows for 'influxdb_measurement' attribute. When set on node, it will take precedence over the global 'override_measurement' and component-specific 'unit_of_measurement'. * Minor updates to InfluxDB component improvements, as suggested by @MartinHjelmare. * Moved per-component config from 'customize' into 'influxdb' configuration section. The following three sub-sections were added: 'component_config', 'component_config_domain' and 'component_config_glob'. The sole supported per-component attribute at this point is 'override_measurement'. * Lint * Fixed mocked entity_ids in InfluxDB tests to be in domain.entity_id format, to satisfy EntityValues requirements. * Added tests for new InfluxDB configuration parameters * Fixes to some docstrings
2017-08-03 14:26:01 +00:00
state=1, domain='fake', entity_id='fake.entity-id',
object_id='entity', attributes={})
2016-10-20 17:10:12 +00:00
event = mock.MagicMock(data={'new_state': state}, time_fired=12345)
mock_client.return_value.write_points.side_effect = \
influx_client.exceptions.InfluxDBClientError('foo')
self.handler_method(event)
def test_event_listener_states(self, mock_client):
"""Test the event listener against ignored states."""
self._setup()
for state_state in (1, 'unknown', '', 'unavailable'):
state = mock.MagicMock(
InfluxDB component improvements (#8633) * Allow reporting some state attributes as tags to InfluxDB Some state attributes should really be tags in InfluxDB. E.g. it is helpful to be able to group by friendly_name, or add a custom attribute like "location" and group by that. Graphs in Grafana are much easier to read when friendly names are used, and not node ids. This commit adds an optional setting to InfluxDB config: 'tags_attributes'. Any attribute on this list will be reported as tag and not as field to InfluxDB. * Allow overriding InfluxDB measurement for each reported item separately Bundling all items with the same "unit of measurement" together does not always makes sense. For example, both "relatively humidity" and "battery level" are reported as "%", but I'd rather see them as separate measurements in InfluxDB. This commit allows for 'influxdb_measurement' attribute. When set on node, it will take precedence over the global 'override_measurement' and component-specific 'unit_of_measurement'. * Minor updates to InfluxDB component improvements, as suggested by @MartinHjelmare. * Moved per-component config from 'customize' into 'influxdb' configuration section. The following three sub-sections were added: 'component_config', 'component_config_domain' and 'component_config_glob'. The sole supported per-component attribute at this point is 'override_measurement'. * Lint * Fixed mocked entity_ids in InfluxDB tests to be in domain.entity_id format, to satisfy EntityValues requirements. * Added tests for new InfluxDB configuration parameters * Fixes to some docstrings
2017-08-03 14:26:01 +00:00
state=state_state, domain='fake', entity_id='fake.entity-id',
object_id='entity', attributes={})
event = mock.MagicMock(data={'new_state': state}, time_fired=12345)
body = [{
InfluxDB component improvements (#8633) * Allow reporting some state attributes as tags to InfluxDB Some state attributes should really be tags in InfluxDB. E.g. it is helpful to be able to group by friendly_name, or add a custom attribute like "location" and group by that. Graphs in Grafana are much easier to read when friendly names are used, and not node ids. This commit adds an optional setting to InfluxDB config: 'tags_attributes'. Any attribute on this list will be reported as tag and not as field to InfluxDB. * Allow overriding InfluxDB measurement for each reported item separately Bundling all items with the same "unit of measurement" together does not always makes sense. For example, both "relatively humidity" and "battery level" are reported as "%", but I'd rather see them as separate measurements in InfluxDB. This commit allows for 'influxdb_measurement' attribute. When set on node, it will take precedence over the global 'override_measurement' and component-specific 'unit_of_measurement'. * Minor updates to InfluxDB component improvements, as suggested by @MartinHjelmare. * Moved per-component config from 'customize' into 'influxdb' configuration section. The following three sub-sections were added: 'component_config', 'component_config_domain' and 'component_config_glob'. The sole supported per-component attribute at this point is 'override_measurement'. * Lint * Fixed mocked entity_ids in InfluxDB tests to be in domain.entity_id format, to satisfy EntityValues requirements. * Added tests for new InfluxDB configuration parameters * Fixes to some docstrings
2017-08-03 14:26:01 +00:00
'measurement': 'fake.entity-id',
'tags': {
'domain': 'fake',
'entity_id': 'entity',
},
'time': 12345,
'fields': {
'value': 1,
},
}]
self.handler_method(event)
if state_state == 1:
self.assertEqual(
mock_client.return_value.write_points.call_count, 1
)
self.assertEqual(
mock_client.return_value.write_points.call_args,
mock.call(body)
)
else:
self.assertFalse(mock_client.return_value.write_points.called)
mock_client.return_value.write_points.reset_mock()
def test_event_listener_blacklist(self, mock_client):
2016-03-09 09:25:50 +00:00
"""Test the event listener against a blacklist."""
self._setup()
for entity_id in ('ok', 'blacklisted'):
2016-10-20 17:10:12 +00:00
state = mock.MagicMock(
state=1, domain='fake', entity_id='fake.{}'.format(entity_id),
object_id=entity_id, attributes={})
event = mock.MagicMock(data={'new_state': state}, time_fired=12345)
body = [{
'measurement': 'fake.{}'.format(entity_id),
'tags': {
'domain': 'fake',
'entity_id': entity_id,
},
'time': 12345,
'fields': {
'value': 1,
},
}]
self.handler_method(event)
if entity_id == 'ok':
self.assertEqual(
mock_client.return_value.write_points.call_count, 1
)
self.assertEqual(
mock_client.return_value.write_points.call_args,
mock.call(body)
)
else:
self.assertFalse(mock_client.return_value.write_points.called)
mock_client.return_value.write_points.reset_mock()
def test_event_listener_blacklist_domain(self, mock_client):
"""Test the event listener against a blacklist."""
self._setup()
for domain in ('ok', 'another_fake'):
state = mock.MagicMock(
state=1, domain=domain,
entity_id='{}.something'.format(domain),
object_id='something', attributes={})
event = mock.MagicMock(data={'new_state': state}, time_fired=12345)
body = [{
'measurement': '{}.something'.format(domain),
'tags': {
'domain': domain,
'entity_id': 'something',
},
'time': 12345,
'fields': {
'value': 1,
},
}]
self.handler_method(event)
if domain == 'ok':
self.assertEqual(
mock_client.return_value.write_points.call_count, 1
)
self.assertEqual(
mock_client.return_value.write_points.call_args,
mock.call(body)
)
else:
self.assertFalse(mock_client.return_value.write_points.called)
mock_client.return_value.write_points.reset_mock()
def test_event_listener_whitelist(self, mock_client):
"""Test the event listener against a whitelist."""
config = {
'influxdb': {
'host': 'host',
'username': 'user',
'password': 'pass',
'include': {
'entities': ['fake.included'],
}
}
}
assert setup_component(self.hass, influxdb.DOMAIN, config)
self.handler_method = self.hass.bus.listen.call_args_list[0][0][1]
for entity_id in ('included', 'default'):
state = mock.MagicMock(
state=1, domain='fake', entity_id='fake.{}'.format(entity_id),
object_id=entity_id, attributes={})
event = mock.MagicMock(data={'new_state': state}, time_fired=12345)
body = [{
'measurement': 'fake.{}'.format(entity_id),
'tags': {
'domain': 'fake',
'entity_id': entity_id,
},
'time': 12345,
'fields': {
'value': 1,
},
}]
self.handler_method(event)
if entity_id == 'included':
self.assertEqual(
mock_client.return_value.write_points.call_count, 1
)
self.assertEqual(
mock_client.return_value.write_points.call_args,
mock.call(body)
)
else:
self.assertFalse(mock_client.return_value.write_points.called)
mock_client.return_value.write_points.reset_mock()
def test_event_listener_whitelist_domain(self, mock_client):
"""Test the event listener against a whitelist."""
config = {
'influxdb': {
'host': 'host',
'username': 'user',
'password': 'pass',
'include': {
'domains': ['fake'],
}
}
}
assert setup_component(self.hass, influxdb.DOMAIN, config)
self.handler_method = self.hass.bus.listen.call_args_list[0][0][1]
for domain in ('fake', 'another_fake'):
state = mock.MagicMock(
state=1, domain=domain,
entity_id='{}.something'.format(domain),
object_id='something', attributes={})
event = mock.MagicMock(data={'new_state': state}, time_fired=12345)
body = [{
'measurement': '{}.something'.format(domain),
'tags': {
'domain': domain,
'entity_id': 'something',
},
'time': 12345,
'fields': {
'value': 1,
},
}]
self.handler_method(event)
if domain == 'fake':
self.assertEqual(
mock_client.return_value.write_points.call_count, 1
)
self.assertEqual(
mock_client.return_value.write_points.call_args,
mock.call(body)
)
else:
self.assertFalse(mock_client.return_value.write_points.called)
mock_client.return_value.write_points.reset_mock()
def test_event_listener_invalid_type(self, mock_client):
InfluxDB component improvements (#8633) * Allow reporting some state attributes as tags to InfluxDB Some state attributes should really be tags in InfluxDB. E.g. it is helpful to be able to group by friendly_name, or add a custom attribute like "location" and group by that. Graphs in Grafana are much easier to read when friendly names are used, and not node ids. This commit adds an optional setting to InfluxDB config: 'tags_attributes'. Any attribute on this list will be reported as tag and not as field to InfluxDB. * Allow overriding InfluxDB measurement for each reported item separately Bundling all items with the same "unit of measurement" together does not always makes sense. For example, both "relatively humidity" and "battery level" are reported as "%", but I'd rather see them as separate measurements in InfluxDB. This commit allows for 'influxdb_measurement' attribute. When set on node, it will take precedence over the global 'override_measurement' and component-specific 'unit_of_measurement'. * Minor updates to InfluxDB component improvements, as suggested by @MartinHjelmare. * Moved per-component config from 'customize' into 'influxdb' configuration section. The following three sub-sections were added: 'component_config', 'component_config_domain' and 'component_config_glob'. The sole supported per-component attribute at this point is 'override_measurement'. * Lint * Fixed mocked entity_ids in InfluxDB tests to be in domain.entity_id format, to satisfy EntityValues requirements. * Added tests for new InfluxDB configuration parameters * Fixes to some docstrings
2017-08-03 14:26:01 +00:00
"""Test the event listener when an attribute has an invalid type."""
self._setup()
# map of HA State to valid influxdb [state, value] fields
valid = {
'1': [None, 1],
'1.0': [None, 1.0],
STATE_ON: [STATE_ON, 1],
STATE_OFF: [STATE_OFF, 0],
STATE_STANDBY: [STATE_STANDBY, None],
'foo': ['foo', None]
}
for in_, out in valid.items():
attrs = {
'unit_of_measurement': 'foobars',
'longitude': '1.1',
'latitude': '2.2',
'invalid_attribute': ['value1', 'value2']
}
state = mock.MagicMock(
InfluxDB component improvements (#8633) * Allow reporting some state attributes as tags to InfluxDB Some state attributes should really be tags in InfluxDB. E.g. it is helpful to be able to group by friendly_name, or add a custom attribute like "location" and group by that. Graphs in Grafana are much easier to read when friendly names are used, and not node ids. This commit adds an optional setting to InfluxDB config: 'tags_attributes'. Any attribute on this list will be reported as tag and not as field to InfluxDB. * Allow overriding InfluxDB measurement for each reported item separately Bundling all items with the same "unit of measurement" together does not always makes sense. For example, both "relatively humidity" and "battery level" are reported as "%", but I'd rather see them as separate measurements in InfluxDB. This commit allows for 'influxdb_measurement' attribute. When set on node, it will take precedence over the global 'override_measurement' and component-specific 'unit_of_measurement'. * Minor updates to InfluxDB component improvements, as suggested by @MartinHjelmare. * Moved per-component config from 'customize' into 'influxdb' configuration section. The following three sub-sections were added: 'component_config', 'component_config_domain' and 'component_config_glob'. The sole supported per-component attribute at this point is 'override_measurement'. * Lint * Fixed mocked entity_ids in InfluxDB tests to be in domain.entity_id format, to satisfy EntityValues requirements. * Added tests for new InfluxDB configuration parameters * Fixes to some docstrings
2017-08-03 14:26:01 +00:00
state=in_, domain='fake', entity_id='fake.entity-id',
object_id='entity', attributes=attrs)
event = mock.MagicMock(data={'new_state': state}, time_fired=12345)
body = [{
'measurement': 'foobars',
'tags': {
'domain': 'fake',
'entity_id': 'entity',
},
'time': 12345,
'fields': {
'longitude': 1.1,
'latitude': 2.2,
'invalid_attribute_str': "['value1', 'value2']"
},
}]
if out[0] is not None:
body[0]['fields']['state'] = out[0]
if out[1] is not None:
body[0]['fields']['value'] = out[1]
self.handler_method(event)
self.assertEqual(
mock_client.return_value.write_points.call_count, 1
)
self.assertEqual(
mock_client.return_value.write_points.call_args,
mock.call(body)
)
mock_client.return_value.write_points.reset_mock()
def test_event_listener_default_measurement(self, mock_client):
"""Test the event listener with a default measurement."""
config = {
'influxdb': {
'host': 'host',
'username': 'user',
'password': 'pass',
'default_measurement': 'state',
'exclude': {
'entities': ['fake.blacklisted']
}
}
}
assert setup_component(self.hass, influxdb.DOMAIN, config)
self.handler_method = self.hass.bus.listen.call_args_list[0][0][1]
for entity_id in ('ok', 'blacklisted'):
state = mock.MagicMock(
state=1, domain='fake', entity_id='fake.{}'.format(entity_id),
object_id=entity_id, attributes={})
event = mock.MagicMock(data={'new_state': state}, time_fired=12345)
body = [{
'measurement': 'state',
'tags': {
'domain': 'fake',
'entity_id': entity_id,
},
'time': 12345,
'fields': {
'value': 1,
},
}]
self.handler_method(event)
if entity_id == 'ok':
self.assertEqual(
mock_client.return_value.write_points.call_count, 1
)
self.assertEqual(
mock_client.return_value.write_points.call_args,
mock.call(body)
)
else:
self.assertFalse(mock_client.return_value.write_points.called)
mock_client.return_value.write_points.reset_mock()
InfluxDB component improvements (#8633) * Allow reporting some state attributes as tags to InfluxDB Some state attributes should really be tags in InfluxDB. E.g. it is helpful to be able to group by friendly_name, or add a custom attribute like "location" and group by that. Graphs in Grafana are much easier to read when friendly names are used, and not node ids. This commit adds an optional setting to InfluxDB config: 'tags_attributes'. Any attribute on this list will be reported as tag and not as field to InfluxDB. * Allow overriding InfluxDB measurement for each reported item separately Bundling all items with the same "unit of measurement" together does not always makes sense. For example, both "relatively humidity" and "battery level" are reported as "%", but I'd rather see them as separate measurements in InfluxDB. This commit allows for 'influxdb_measurement' attribute. When set on node, it will take precedence over the global 'override_measurement' and component-specific 'unit_of_measurement'. * Minor updates to InfluxDB component improvements, as suggested by @MartinHjelmare. * Moved per-component config from 'customize' into 'influxdb' configuration section. The following three sub-sections were added: 'component_config', 'component_config_domain' and 'component_config_glob'. The sole supported per-component attribute at this point is 'override_measurement'. * Lint * Fixed mocked entity_ids in InfluxDB tests to be in domain.entity_id format, to satisfy EntityValues requirements. * Added tests for new InfluxDB configuration parameters * Fixes to some docstrings
2017-08-03 14:26:01 +00:00
def test_event_listener_unit_of_measurement_field(self, mock_client):
"""Test the event listener for unit of measurement field."""
config = {
'influxdb': {
'host': 'host',
'username': 'user',
'password': 'pass',
'override_measurement': 'state',
}
}
assert setup_component(self.hass, influxdb.DOMAIN, config)
self.handler_method = self.hass.bus.listen.call_args_list[0][0][1]
attrs = {
'unit_of_measurement': 'foobars',
}
state = mock.MagicMock(
state='foo', domain='fake', entity_id='fake.entity-id',
object_id='entity', attributes=attrs)
event = mock.MagicMock(data={'new_state': state}, time_fired=12345)
body = [{
'measurement': 'state',
'tags': {
'domain': 'fake',
'entity_id': 'entity',
},
'time': 12345,
'fields': {
'state': 'foo',
'unit_of_measurement_str': 'foobars',
},
}]
self.handler_method(event)
self.assertEqual(
mock_client.return_value.write_points.call_count, 1
)
self.assertEqual(
mock_client.return_value.write_points.call_args,
mock.call(body)
)
mock_client.return_value.write_points.reset_mock()
InfluxDB component improvements (#8633) * Allow reporting some state attributes as tags to InfluxDB Some state attributes should really be tags in InfluxDB. E.g. it is helpful to be able to group by friendly_name, or add a custom attribute like "location" and group by that. Graphs in Grafana are much easier to read when friendly names are used, and not node ids. This commit adds an optional setting to InfluxDB config: 'tags_attributes'. Any attribute on this list will be reported as tag and not as field to InfluxDB. * Allow overriding InfluxDB measurement for each reported item separately Bundling all items with the same "unit of measurement" together does not always makes sense. For example, both "relatively humidity" and "battery level" are reported as "%", but I'd rather see them as separate measurements in InfluxDB. This commit allows for 'influxdb_measurement' attribute. When set on node, it will take precedence over the global 'override_measurement' and component-specific 'unit_of_measurement'. * Minor updates to InfluxDB component improvements, as suggested by @MartinHjelmare. * Moved per-component config from 'customize' into 'influxdb' configuration section. The following three sub-sections were added: 'component_config', 'component_config_domain' and 'component_config_glob'. The sole supported per-component attribute at this point is 'override_measurement'. * Lint * Fixed mocked entity_ids in InfluxDB tests to be in domain.entity_id format, to satisfy EntityValues requirements. * Added tests for new InfluxDB configuration parameters * Fixes to some docstrings
2017-08-03 14:26:01 +00:00
def test_event_listener_tags_attributes(self, mock_client):
"""Test the event listener when some attributes should be tags."""
config = {
'influxdb': {
'host': 'host',
'username': 'user',
'password': 'pass',
'tags_attributes': ['friendly_fake']
}
}
assert setup_component(self.hass, influxdb.DOMAIN, config)
self.handler_method = self.hass.bus.listen.call_args_list[0][0][1]
attrs = {
'friendly_fake': 'tag_str',
'field_fake': 'field_str',
}
state = mock.MagicMock(
state=1, domain='fake',
entity_id='fake.something',
object_id='something', attributes=attrs)
event = mock.MagicMock(data={'new_state': state}, time_fired=12345)
body = [{
'measurement': 'fake.something',
'tags': {
'domain': 'fake',
'entity_id': 'something',
'friendly_fake': 'tag_str'
},
'time': 12345,
'fields': {
'value': 1,
'field_fake_str': 'field_str'
},
}]
self.handler_method(event)
self.assertEqual(
mock_client.return_value.write_points.call_count, 1
)
self.assertEqual(
mock_client.return_value.write_points.call_args,
mock.call(body)
)
mock_client.return_value.write_points.reset_mock()
def test_event_listener_component_override_measurement(self, mock_client):
"""Test the event listener with overridden measurements."""
InfluxDB component improvements (#8633) * Allow reporting some state attributes as tags to InfluxDB Some state attributes should really be tags in InfluxDB. E.g. it is helpful to be able to group by friendly_name, or add a custom attribute like "location" and group by that. Graphs in Grafana are much easier to read when friendly names are used, and not node ids. This commit adds an optional setting to InfluxDB config: 'tags_attributes'. Any attribute on this list will be reported as tag and not as field to InfluxDB. * Allow overriding InfluxDB measurement for each reported item separately Bundling all items with the same "unit of measurement" together does not always makes sense. For example, both "relatively humidity" and "battery level" are reported as "%", but I'd rather see them as separate measurements in InfluxDB. This commit allows for 'influxdb_measurement' attribute. When set on node, it will take precedence over the global 'override_measurement' and component-specific 'unit_of_measurement'. * Minor updates to InfluxDB component improvements, as suggested by @MartinHjelmare. * Moved per-component config from 'customize' into 'influxdb' configuration section. The following three sub-sections were added: 'component_config', 'component_config_domain' and 'component_config_glob'. The sole supported per-component attribute at this point is 'override_measurement'. * Lint * Fixed mocked entity_ids in InfluxDB tests to be in domain.entity_id format, to satisfy EntityValues requirements. * Added tests for new InfluxDB configuration parameters * Fixes to some docstrings
2017-08-03 14:26:01 +00:00
config = {
'influxdb': {
'host': 'host',
'username': 'user',
'password': 'pass',
'component_config': {
'sensor.fake_humidity': {
'override_measurement': 'humidity'
}
},
'component_config_glob': {
'binary_sensor.*motion': {
'override_measurement': 'motion'
}
},
'component_config_domain': {
'climate': {
'override_measurement': 'hvac'
}
}
}
}
assert setup_component(self.hass, influxdb.DOMAIN, config)
self.handler_method = self.hass.bus.listen.call_args_list[0][0][1]
test_components = [
{'domain': 'sensor', 'id': 'fake_humidity', 'res': 'humidity'},
{'domain': 'binary_sensor', 'id': 'fake_motion', 'res': 'motion'},
{'domain': 'climate', 'id': 'fake_thermostat', 'res': 'hvac'},
{'domain': 'other', 'id': 'just_fake', 'res': 'other.just_fake'},
]
for comp in test_components:
state = mock.MagicMock(
state=1, domain=comp['domain'],
entity_id=comp['domain'] + '.' + comp['id'],
object_id=comp['id'], attributes={})
event = mock.MagicMock(data={'new_state': state}, time_fired=12345)
body = [{
'measurement': comp['res'],
'tags': {
'domain': comp['domain'],
'entity_id': comp['id']
},
'time': 12345,
'fields': {
'value': 1,
},
}]
self.handler_method(event)
self.assertEqual(
mock_client.return_value.write_points.call_count, 1
)
self.assertEqual(
mock_client.return_value.write_points.call_args,
mock.call(body)
)
mock_client.return_value.write_points.reset_mock()