Skip to content

Instantly share code, notes, and snippets.

@loxK
Created May 16, 2018 01:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save loxK/194794ea02ac5906e75f6ba93dc4feec to your computer and use it in GitHub Desktop.
Save loxK/194794ea02ac5906e75f6ba93dc4feec to your computer and use it in GitHub Desktop.
"""
Support for reading json output of commands.
{
"timestamp": 156435434373
"data": {
"sensor_name" : {
"value": 10,
"unit": "W",
"name": "sensor cool name"
}
}
}
configuration.yaml
sensor:
- platform: command_line_json
prefix: myprefix
command: mycommand
scan_interval: 1
resources:
- sensor_name
"""
import asyncio
import logging
import voluptuous as vol
import subprocess
import json
from datetime import timedelta
from homeassistant.components.sensor import PLATFORM_SCHEMA
import homeassistant.helpers.config_validation as cv
from homeassistant.const import (
CONF_COMMAND,
CONF_PREFIX,
CONF_RESOURCES
)
from homeassistant.util import Throttle
from homeassistant.helpers.entity import Entity
_LOGGER = logging.getLogger(__name__)
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=1)
SENSOR_TYPES = { }
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_COMMAND): cv.string,
vol.Required(CONF_PREFIX): cv.string,
vol.Required(CONF_RESOURCES, default=[]): cv.ensure_list,
})
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Setup the Command Line Json sensors."""
command = config.get(CONF_COMMAND)
prefix = config.get(CONF_PREFIX)
try:
data = CommandLineJsonData(command)
except RunTimeError:
_LOGGER.error("Unable to fetch data from Command Line Json.")
return False
entities = []
for resource in config[CONF_RESOURCES]:
sensor_type = resource.lower()
if sensor_type in data.data['data']:
icon = 'mdi:information-outline'
if data.data['data'][sensor_type]['unit'] in ['W', 'A', 'kWh', 'V']:
icon = 'mdi:flash'
elif data.data['data'][sensor_type]['unit'] in ['°C']:
icon = 'mdi:thermometer'
elif data.data['data'][sensor_type]['unit'] in ['Ah']:
icon = 'mdi:battery'
elif data.data['data'][sensor_type]['unit'] in ['days']:
icon = 'mdi:calendar'
elif data.data['data'][sensor_type]['unit'] in ['hours', 'seconds']:
icon = 'mdi:clock'
SENSOR_TYPES[sensor_type] = [
data.data['data'][sensor_type]['name'], data.data['data'][sensor_type]['unit'], icon]
else:
SENSOR_TYPES[sensor_type] = [
sensor_type.title(), '', '']
entities.append(CommandLineJsonSensor(data, sensor_type, prefix))
async_add_devices(entities)
# pylint: disable=abstract-method
class CommandLineJsonData(object):
"""Representation of a Command Line Json sensor."""
def __init__(self,command):
"""Initialize the portal."""
self._command = command
self.data = None
self.timestamp = None
output = subprocess.check_output(self._command, shell=True)
self.data = json.loads(output.decode("utf-8"))
self.timestamp = self.data['timestamp']
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self):
"""Update the data."""
output = subprocess.check_output(self._command, shell=True)
data = json.loads(output.decode("utf-8"))
self.data = data
class CommandLineJsonSensor(Entity):
"""Representation of a CommandLineJson sensor from the portal."""
def __init__(self, data, sensor_type, prefix):
"""Initialize the sensor."""
entity_id_format = 'sensor.{}'
self.entity_id = entity_id_format.format(prefix + '_' + sensor_type)
self.data = data
self.type = sensor_type
self._name = SENSOR_TYPES[self.type][0]
self._unit_of_measurement = SENSOR_TYPES[self.type][1]
if sensor_type == 'timestamp':
self._icon = 'mdi:clock'
else:
self._icon = SENSOR_TYPES[self.type][2]
self._state = None
self.update()
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def icon(self):
"""Icon to use in the frontend, if any."""
return self._icon
@property
def state(self):
"""Return the state of the sensor."""
return self._state
@property
def unit_of_measurement(self):
"""Return the unit of measurement of this entity, if any."""
return self._unit_of_measurement
def update(self):
"""Get the latest data and use it to update our sensor state."""
self.data.update()
if self.type == 'timestamp':
self._state = self.data.data['timestamp']
else:
self._state = self.data.data['data'][self.type]['value']
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment