Skip to content

Commit

Permalink
Merge cc87f43 into a9140dc
Browse files Browse the repository at this point in the history
  • Loading branch information
jkeljo committed Nov 1, 2018
2 parents a9140dc + cc87f43 commit 2a7a935
Show file tree
Hide file tree
Showing 4 changed files with 459 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .coveragerc
Expand Up @@ -126,6 +126,9 @@ omit =
homeassistant/components/google.py
homeassistant/components/*/google.py

homeassistant/components/greeneye_monitor.py
homeassistant/components/sensor/greeneye_monitor.py

homeassistant/components/habitica/*
homeassistant/components/*/habitica.py

Expand Down
171 changes: 171 additions & 0 deletions homeassistant/components/greeneye_monitor.py
@@ -0,0 +1,171 @@
"""
Support for monitoring a GreenEye Monitor energy monitor.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/greeneye_monitor/
"""
import logging

import voluptuous as vol

from homeassistant.const import (
CONF_NAME,
CONF_PORT,
CONF_TEMPERATURE_UNIT,
EVENT_HOMEASSISTANT_STOP)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.discovery import async_load_platform

REQUIREMENTS = ['greeneye_monitor==0.1']

_LOGGER = logging.getLogger(__name__)

CONF_CHANNELS = 'channels'
CONF_COUNTED_QUANTITY = 'counted_quantity'
CONF_COUNTED_QUANTITY_PER_PULSE = 'counted_quantity_per_pulse'
CONF_MONITOR_SERIAL_NUMBER = 'monitor'
CONF_MONITORS = 'monitors'
CONF_NET_METERING = 'net_metering'
CONF_NUMBER = 'number'
CONF_PULSE_COUNTERS = 'pulse_counters'
CONF_SERIAL_NUMBER = 'serial_number'
CONF_SENSORS = 'sensors'
CONF_SENSOR_TYPE = 'sensor_type'
CONF_TEMPERATURE_SENSORS = 'temperature_sensors'
CONF_TIME_UNIT = 'time_unit'

DATA_GREENEYE_MONITOR = 'greeneye_monitor'
DOMAIN = 'greeneye_monitor'

SENSOR_TYPE_CURRENT = 'current_sensor'
SENSOR_TYPE_PULSE_COUNTER = 'pulse_counter'
SENSOR_TYPE_TEMPERATURE = 'temperature_sensor'

TEMPERATURE_UNIT_CELSIUS = 'C'

TIME_UNIT_SECOND = 's'
TIME_UNIT_MINUTE = 'min'
TIME_UNIT_HOUR = 'h'

TEMPERATURE_SENSOR_SCHEMA = vol.Schema({
vol.Required(CONF_NUMBER): vol.Range(1, 8),
vol.Required(CONF_NAME): cv.string,
})

TEMPERATURE_SENSORS_SCHEMA = vol.Schema({
vol.Required(CONF_TEMPERATURE_UNIT): cv.temperature_unit,
vol.Required(CONF_SENSORS): vol.All(cv.ensure_list,
[TEMPERATURE_SENSOR_SCHEMA]),
})

PULSE_COUNTER_SCHEMA = vol.Schema({
vol.Required(CONF_NUMBER): vol.Range(1, 4),
vol.Required(CONF_NAME): cv.string,
vol.Required(CONF_COUNTED_QUANTITY): cv.string,
vol.Optional(
CONF_COUNTED_QUANTITY_PER_PULSE, default=1.0): vol.Coerce(float),
vol.Optional(CONF_TIME_UNIT, default=TIME_UNIT_SECOND): vol.Any(
TIME_UNIT_SECOND,
TIME_UNIT_MINUTE,
TIME_UNIT_HOUR),
})

PULSE_COUNTERS_SCHEMA = vol.All(cv.ensure_list, [PULSE_COUNTER_SCHEMA])

CHANNEL_SCHEMA = vol.Schema({
vol.Required(CONF_NUMBER): vol.Range(1, 48),
vol.Required(CONF_NAME): cv.string,
vol.Optional(CONF_NET_METERING, default=False): cv.boolean,
})

CHANNELS_SCHEMA = vol.All(cv.ensure_list, [CHANNEL_SCHEMA])

MONITOR_SCHEMA = vol.Schema({
vol.Required(CONF_SERIAL_NUMBER): cv.positive_int,
vol.Optional(CONF_CHANNELS, default=[]): CHANNELS_SCHEMA,
vol.Optional(
CONF_TEMPERATURE_SENSORS,
default={
CONF_TEMPERATURE_UNIT: TEMPERATURE_UNIT_CELSIUS,
CONF_SENSORS: [],
}): TEMPERATURE_SENSORS_SCHEMA,
vol.Optional(CONF_PULSE_COUNTERS, default=[]): PULSE_COUNTERS_SCHEMA,
})

MONITORS_SCHEMA = vol.All(cv.ensure_list, [MONITOR_SCHEMA])

COMPONENT_SCHEMA = vol.Schema({
vol.Required(CONF_PORT): cv.port,
vol.Required(CONF_MONITORS): MONITORS_SCHEMA,
})

CONFIG_SCHEMA = vol.Schema({
DOMAIN: COMPONENT_SCHEMA,
}, extra=vol.ALLOW_EXTRA)


async def async_setup(hass, config):
"""Set up the GreenEye Monitor component."""
from greeneye import Monitors

monitors = Monitors()
hass.data[DATA_GREENEYE_MONITOR] = monitors

server_config = config[DOMAIN]
server = await monitors.start_server(server_config[CONF_PORT])

async def close_server(*args):
"""Close the monitoring server."""
await server.close()

hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, close_server)

all_sensors = []
for monitor_config in server_config[CONF_MONITORS]:
monitor_serial_number = {
CONF_MONITOR_SERIAL_NUMBER: monitor_config[CONF_SERIAL_NUMBER],
}

channel_configs = monitor_config[CONF_CHANNELS]
for channel_config in channel_configs:
all_sensors.append({
CONF_SENSOR_TYPE: SENSOR_TYPE_CURRENT,
**monitor_serial_number,
**channel_config,
})

sensor_configs = \
monitor_config[CONF_TEMPERATURE_SENSORS]
if sensor_configs:
temperature_unit = {
CONF_TEMPERATURE_UNIT: sensor_configs[CONF_TEMPERATURE_UNIT],
}
for sensor_config in sensor_configs[CONF_SENSORS]:
all_sensors.append({
CONF_SENSOR_TYPE: SENSOR_TYPE_TEMPERATURE,
**monitor_serial_number,
**temperature_unit,
**sensor_config,
})

counter_configs = monitor_config[CONF_PULSE_COUNTERS]
for counter_config in counter_configs:
all_sensors.append({
CONF_SENSOR_TYPE: SENSOR_TYPE_PULSE_COUNTER,
**monitor_serial_number,
**counter_config,
})

if not all_sensors:
_LOGGER.error("Configuration must specify at least one "
"channel, pulse counter or temperature sensor")
return False

hass.async_create_task(async_load_platform(
hass,
'sensor',
DOMAIN,
all_sensors,
config))

return True

0 comments on commit 2a7a935

Please sign in to comment.