diff --git a/homeassistant/components/statsd.py b/homeassistant/components/statsd.py index 950d51fd381..f2db14cceb7 100644 --- a/homeassistant/components/statsd.py +++ b/homeassistant/components/statsd.py @@ -26,6 +26,7 @@ CONF_HOST = 'host' CONF_PORT = 'port' CONF_PREFIX = 'prefix' CONF_RATE = 'rate' +CONF_ATTR = 'log_attributes' def setup(hass, config): @@ -38,6 +39,7 @@ def setup(hass, config): port = util.convert(conf.get(CONF_PORT), int, DEFAULT_PORT) sample_rate = util.convert(conf.get(CONF_RATE), int, DEFAULT_RATE) prefix = util.convert(conf.get(CONF_PREFIX), str, DEFAULT_PREFIX) + show_attribute_flag = conf.get(CONF_ATTR, False) statsd_client = statsd.StatsClient( host=host, @@ -57,8 +59,25 @@ def setup(hass, config): except ValueError: return + states = dict(state.attributes) + _LOGGER.debug('Sending %s.%s', state.entity_id, _state) - statsd_client.gauge(state.entity_id, _state, sample_rate) + + if show_attribute_flag is True: + statsd_client.gauge( + "%s.state" % state.entity_id, + _state, + sample_rate + ) + + # Send attribute values + for key, value in states.items(): + if isinstance(value, (float, int)): + stat = "%s.%s" % (state.entity_id, key.replace(' ', '_')) + statsd_client.gauge(stat, value, sample_rate) + + else: + statsd_client.gauge(state.entity_id, _state, sample_rate) # Increment the count statsd_client.incr(state.entity_id, rate=sample_rate) diff --git a/tests/components/test_statsd.py b/tests/components/test_statsd.py index 1c3fb002879..6209f1986f5 100644 --- a/tests/components/test_statsd.py +++ b/tests/components/test_statsd.py @@ -49,7 +49,7 @@ class TestStatsd(unittest.TestCase): self.assertTrue(hass.bus.listen.called) @mock.patch('statsd.StatsClient') - def test_event_listener(self, mock_client): + def test_event_listener_defaults(self, mock_client): """Test event listener.""" config = { 'statsd': { @@ -66,10 +66,54 @@ class TestStatsd(unittest.TestCase): STATE_ON: 1, STATE_OFF: 0} for in_, out in valid.items(): - state = mock.MagicMock(state=in_) + state = mock.MagicMock(state=in_, + attributes={"attribute key": 3.2}) handler_method(mock.MagicMock(data={'new_state': state})) - mock_client.return_value.gauge.assert_called_once_with( - state.entity_id, out, statsd.DEFAULT_RATE) + mock_client.return_value.gauge.assert_has_calls([ + mock.call(state.entity_id, out, statsd.DEFAULT_RATE), + ]) + + mock_client.return_value.gauge.reset_mock() + + mock_client.return_value.incr.assert_called_once_with( + state.entity_id, rate=statsd.DEFAULT_RATE) + mock_client.return_value.incr.reset_mock() + + for invalid in ('foo', '', object): + handler_method(mock.MagicMock(data={ + 'new_state': ha.State('domain.test', invalid, {})})) + self.assertFalse(mock_client.return_value.gauge.called) + self.assertFalse(mock_client.return_value.incr.called) + + @mock.patch('statsd.StatsClient') + def test_event_listener_attr_details(self, mock_client): + """Test event listener.""" + config = { + 'statsd': { + 'host': 'host', + 'log_attributes': True + } + } + hass = mock.MagicMock() + statsd.setup(hass, config) + self.assertTrue(hass.bus.listen.called) + handler_method = hass.bus.listen.call_args_list[0][0][1] + + valid = {'1': 1, + '1.0': 1.0, + STATE_ON: 1, + STATE_OFF: 0} + for in_, out in valid.items(): + state = mock.MagicMock(state=in_, + attributes={"attribute key": 3.2}) + handler_method(mock.MagicMock(data={'new_state': state})) + mock_client.return_value.gauge.assert_has_calls([ + mock.call("%s.state" % state.entity_id, + out, statsd.DEFAULT_RATE), + mock.call("%s.attribute_key" % state.entity_id, + 3.2, statsd.DEFAULT_RATE), + ]) + mock_client.return_value.gauge.reset_mock() mock_client.return_value.incr.assert_called_once_with(