2015-11-21 18:01:47 +00:00
|
|
|
"""
|
2016-02-26 22:52:54 +00:00
|
|
|
A component which allows you to send data to an Influx database.
|
2015-11-21 18:01:47 +00:00
|
|
|
|
|
|
|
For more details about this component, please refer to the documentation at
|
2015-12-07 06:33:07 +00:00
|
|
|
https://home-assistant.io/components/influxdb/
|
2015-11-21 18:01:47 +00:00
|
|
|
"""
|
|
|
|
import logging
|
2016-02-19 05:27:50 +00:00
|
|
|
|
2016-09-18 22:32:18 +00:00
|
|
|
import voluptuous as vol
|
|
|
|
|
|
|
|
from homeassistant.const import (
|
|
|
|
EVENT_STATE_CHANGED, STATE_UNAVAILABLE, STATE_UNKNOWN, CONF_HOST,
|
|
|
|
CONF_PORT, CONF_SSL, CONF_VERIFY_SSL, CONF_USERNAME, CONF_BLACKLIST,
|
|
|
|
CONF_PASSWORD, CONF_WHITELIST)
|
2016-02-11 17:13:57 +00:00
|
|
|
from homeassistant.helpers import state as state_helper
|
2016-09-18 22:32:18 +00:00
|
|
|
import homeassistant.helpers.config_validation as cv
|
|
|
|
|
|
|
|
REQUIREMENTS = ['influxdb==3.0.0']
|
2015-11-21 18:01:47 +00:00
|
|
|
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
2016-09-18 22:32:18 +00:00
|
|
|
CONF_DB_NAME = 'database'
|
|
|
|
CONF_TAGS = 'tags'
|
2015-11-21 18:01:47 +00:00
|
|
|
|
2016-09-18 22:32:18 +00:00
|
|
|
DEFAULT_DATABASE = 'home_assistant'
|
2015-11-21 18:01:47 +00:00
|
|
|
DEFAULT_HOST = 'localhost'
|
|
|
|
DEFAULT_PORT = 8086
|
2016-02-02 19:51:18 +00:00
|
|
|
DEFAULT_SSL = False
|
|
|
|
DEFAULT_VERIFY_SSL = False
|
2016-09-18 22:32:18 +00:00
|
|
|
DOMAIN = 'influxdb'
|
|
|
|
|
|
|
|
CONFIG_SCHEMA = vol.Schema({
|
|
|
|
DOMAIN: vol.Schema({
|
|
|
|
vol.Optional(CONF_HOST, default=DEFAULT_HOST): cv.string,
|
|
|
|
vol.Required(CONF_USERNAME): cv.string,
|
|
|
|
vol.Required(CONF_PASSWORD): cv.string,
|
|
|
|
vol.Optional(CONF_BLACKLIST, default=[]):
|
|
|
|
vol.All(cv.ensure_list, [cv.entity_id]),
|
|
|
|
vol.Optional(CONF_DB_NAME, default=DEFAULT_DATABASE): cv.string,
|
|
|
|
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
|
|
|
|
vol.Optional(CONF_PORT, default=False): cv.boolean,
|
|
|
|
vol.Optional(CONF_SSL, default=False): cv.boolean,
|
|
|
|
vol.Optional(CONF_TAGS, default={}):
|
|
|
|
vol.Schema({cv.string: cv.string}),
|
|
|
|
vol.Optional(CONF_WHITELIST, default=[]):
|
|
|
|
vol.All(cv.ensure_list, [cv.entity_id]),
|
|
|
|
vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean,
|
|
|
|
}),
|
|
|
|
}, extra=vol.ALLOW_EXTRA)
|
2015-11-21 18:01:47 +00:00
|
|
|
|
|
|
|
|
2016-03-03 10:09:37 +00:00
|
|
|
# pylint: disable=too-many-locals
|
2015-11-21 18:01:47 +00:00
|
|
|
def setup(hass, config):
|
2016-02-26 22:52:54 +00:00
|
|
|
"""Setup the InfluxDB component."""
|
2015-11-25 21:47:00 +00:00
|
|
|
from influxdb import InfluxDBClient, exceptions
|
2015-11-21 18:01:47 +00:00
|
|
|
|
|
|
|
conf = config[DOMAIN]
|
|
|
|
|
2016-09-18 22:32:18 +00:00
|
|
|
host = conf.get(CONF_HOST)
|
|
|
|
port = conf.get(CONF_PORT)
|
|
|
|
database = conf.get(CONF_DB_NAME)
|
|
|
|
username = conf.get(CONF_USERNAME)
|
|
|
|
password = conf.get(CONF_PASSWORD)
|
|
|
|
ssl = conf.get(CONF_SSL)
|
|
|
|
verify_ssl = conf.get(CONF_VERIFY_SSL)
|
|
|
|
blacklist = conf.get(CONF_BLACKLIST)
|
|
|
|
whitelist = conf.get(CONF_WHITELIST)
|
|
|
|
tags = conf.get(CONF_TAGS)
|
2015-11-21 18:01:47 +00:00
|
|
|
|
|
|
|
try:
|
2016-09-18 22:32:18 +00:00
|
|
|
influx = InfluxDBClient(
|
|
|
|
host=host, port=port, username=username, password=password,
|
|
|
|
database=database, ssl=ssl, verify_ssl=verify_ssl)
|
2016-01-20 21:43:35 +00:00
|
|
|
influx.query("select * from /.*/ LIMIT 1;")
|
|
|
|
except exceptions.InfluxDBClientError as exc:
|
|
|
|
_LOGGER.error("Database host is not accessible due to '%s', please "
|
2016-02-26 22:52:54 +00:00
|
|
|
"check your entries in the configuration file and that "
|
|
|
|
"the database exists and is READ/WRITE.", exc)
|
2015-11-25 21:47:00 +00:00
|
|
|
return False
|
2015-11-21 18:01:47 +00:00
|
|
|
|
2015-12-06 17:45:58 +00:00
|
|
|
def influx_event_listener(event):
|
2016-02-26 22:52:54 +00:00
|
|
|
"""Listen for new messages on the bus and sends them to Influx."""
|
2015-12-06 17:45:58 +00:00
|
|
|
state = event.data.get('new_state')
|
2016-04-16 14:05:05 +00:00
|
|
|
if state is None or state.state in (
|
|
|
|
STATE_UNKNOWN, '', STATE_UNAVAILABLE) or \
|
|
|
|
state.entity_id in blacklist:
|
2016-03-03 10:09:37 +00:00
|
|
|
return
|
2015-11-25 21:47:00 +00:00
|
|
|
|
2016-02-11 17:13:57 +00:00
|
|
|
try:
|
2016-08-04 15:35:01 +00:00
|
|
|
if len(whitelist) > 0 and state.entity_id not in whitelist:
|
|
|
|
return
|
|
|
|
|
2016-02-11 17:13:57 +00:00
|
|
|
_state = state_helper.state_as_number(state)
|
|
|
|
except ValueError:
|
|
|
|
_state = state.state
|
2015-11-25 21:47:00 +00:00
|
|
|
|
2016-02-03 21:54:41 +00:00
|
|
|
measurement = state.attributes.get('unit_of_measurement')
|
|
|
|
if measurement in (None, ''):
|
2016-02-07 03:33:43 +00:00
|
|
|
measurement = state.entity_id
|
2015-11-25 21:47:00 +00:00
|
|
|
|
|
|
|
json_body = [
|
|
|
|
{
|
|
|
|
'measurement': measurement,
|
|
|
|
'tags': {
|
|
|
|
'domain': state.domain,
|
|
|
|
'entity_id': state.object_id,
|
|
|
|
},
|
2015-12-06 17:45:58 +00:00
|
|
|
'time': event.time_fired,
|
2015-11-25 21:47:00 +00:00
|
|
|
'fields': {
|
|
|
|
'value': _state,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
2015-11-21 18:01:47 +00:00
|
|
|
|
2016-09-18 22:32:18 +00:00
|
|
|
json_body[0]['tags'].update(tags)
|
2016-07-26 06:01:57 +00:00
|
|
|
|
2015-12-06 17:45:58 +00:00
|
|
|
try:
|
|
|
|
influx.write_points(json_body)
|
|
|
|
except exceptions.InfluxDBClientError:
|
2016-01-20 21:43:35 +00:00
|
|
|
_LOGGER.exception('Error saving event "%s" to InfluxDB', json_body)
|
2015-11-21 18:01:47 +00:00
|
|
|
|
2015-12-06 17:45:58 +00:00
|
|
|
hass.bus.listen(EVENT_STATE_CHANGED, influx_event_listener)
|
2015-11-21 18:01:47 +00:00
|
|
|
|
|
|
|
return True
|