Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """Support for monitoring a GreenEye Monitor energy monitor."""
2 
3 from __future__ import annotations
4 
5 import logging
6 
7 import greeneye
8 import voluptuous as vol
9 
10 from homeassistant.const import (
11  CONF_NAME,
12  CONF_PORT,
13  CONF_SENSORS,
14  CONF_TEMPERATURE_UNIT,
15  EVENT_HOMEASSISTANT_STOP,
16  Platform,
17  UnitOfTime,
18 )
19 from homeassistant.core import Event, HomeAssistant
21 from homeassistant.helpers.discovery import async_load_platform
22 from homeassistant.helpers.typing import ConfigType
23 
24 from .const import (
25  CONF_CHANNELS,
26  CONF_COUNTED_QUANTITY,
27  CONF_COUNTED_QUANTITY_PER_PULSE,
28  CONF_MONITORS,
29  CONF_NET_METERING,
30  CONF_NUMBER,
31  CONF_PULSE_COUNTERS,
32  CONF_SERIAL_NUMBER,
33  CONF_TEMPERATURE_SENSORS,
34  CONF_TIME_UNIT,
35  CONF_VOLTAGE_SENSORS,
36  DATA_GREENEYE_MONITOR,
37  DOMAIN,
38  TEMPERATURE_UNIT_CELSIUS,
39 )
40 
41 _LOGGER = logging.getLogger(__name__)
42 
43 TEMPERATURE_SENSOR_SCHEMA = vol.Schema(
44  {vol.Required(CONF_NUMBER): vol.Range(1, 8), vol.Required(CONF_NAME): cv.string}
45 )
46 
47 TEMPERATURE_SENSORS_SCHEMA = vol.Schema(
48  {
49  vol.Required(CONF_TEMPERATURE_UNIT): cv.temperature_unit,
50  vol.Required(CONF_SENSORS): vol.All(
51  cv.ensure_list, [TEMPERATURE_SENSOR_SCHEMA]
52  ),
53  }
54 )
55 
56 VOLTAGE_SENSOR_SCHEMA = vol.Schema(
57  {vol.Required(CONF_NUMBER): vol.Range(1, 48), vol.Required(CONF_NAME): cv.string}
58 )
59 
60 VOLTAGE_SENSORS_SCHEMA = vol.All(cv.ensure_list, [VOLTAGE_SENSOR_SCHEMA])
61 
62 PULSE_COUNTER_SCHEMA = vol.Schema(
63  {
64  vol.Required(CONF_NUMBER): vol.Range(1, 4),
65  vol.Required(CONF_NAME): cv.string,
66  vol.Required(CONF_COUNTED_QUANTITY): cv.string,
67  vol.Optional(CONF_COUNTED_QUANTITY_PER_PULSE, default=1.0): vol.Coerce(float),
68  vol.Optional(CONF_TIME_UNIT, default=UnitOfTime.SECONDS): vol.Any(
69  UnitOfTime.SECONDS.value, UnitOfTime.MINUTES.value, UnitOfTime.HOURS.value
70  ),
71  }
72 )
73 
74 PULSE_COUNTERS_SCHEMA = vol.All(cv.ensure_list, [PULSE_COUNTER_SCHEMA])
75 
76 CHANNEL_SCHEMA = vol.Schema(
77  {
78  vol.Required(CONF_NUMBER): vol.Range(1, 48),
79  vol.Required(CONF_NAME): cv.string,
80  vol.Optional(CONF_NET_METERING, default=False): cv.boolean,
81  }
82 )
83 
84 CHANNELS_SCHEMA = vol.All(cv.ensure_list, [CHANNEL_SCHEMA])
85 
86 MONITOR_SCHEMA = vol.Schema(
87  {
88  vol.Required(CONF_SERIAL_NUMBER): vol.All(
89  cv.string,
90  vol.Length(
91  min=8,
92  max=8,
93  msg=(
94  "GEM serial number must be specified as an 8-character "
95  "string (including leading zeroes)."
96  ),
97  ),
98  vol.Coerce(int),
99  ),
100  vol.Optional(CONF_CHANNELS, default=[]): CHANNELS_SCHEMA,
101  vol.Optional(
102  CONF_TEMPERATURE_SENSORS,
103  default={CONF_TEMPERATURE_UNIT: TEMPERATURE_UNIT_CELSIUS, CONF_SENSORS: []},
104  ): TEMPERATURE_SENSORS_SCHEMA,
105  vol.Optional(CONF_PULSE_COUNTERS, default=[]): PULSE_COUNTERS_SCHEMA,
106  vol.Optional(CONF_VOLTAGE_SENSORS, default=[]): VOLTAGE_SENSORS_SCHEMA,
107  }
108 )
109 
110 MONITORS_SCHEMA = vol.All(cv.ensure_list, [MONITOR_SCHEMA])
111 
112 COMPONENT_SCHEMA = vol.Schema(
113  {vol.Required(CONF_PORT): cv.port, vol.Required(CONF_MONITORS): MONITORS_SCHEMA}
114 )
115 
116 CONFIG_SCHEMA = vol.Schema({DOMAIN: COMPONENT_SCHEMA}, extra=vol.ALLOW_EXTRA)
117 
118 
119 async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
120  """Set up the GreenEye Monitor component."""
121  monitors = greeneye.Monitors()
122  hass.data[DATA_GREENEYE_MONITOR] = monitors
123 
124  server_config = config[DOMAIN]
125  await monitors.start_server(server_config[CONF_PORT])
126 
127  async def close_monitors(event: Event) -> None:
128  """Close the Monitors object."""
129  await monitors.close()
130 
131  hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, close_monitors)
132 
133  num_sensors = 0
134  for monitor_config in config[DOMAIN][CONF_MONITORS]:
135  num_sensors += len(monitor_config[CONF_CHANNELS])
136  num_sensors += len(monitor_config[CONF_PULSE_COUNTERS])
137  num_sensors += len(monitor_config[CONF_TEMPERATURE_SENSORS][CONF_SENSORS])
138  num_sensors += len(monitor_config[CONF_VOLTAGE_SENSORS])
139 
140  if num_sensors == 0:
141  _LOGGER.error(
142  "Configuration must specify at least one "
143  "channel, voltage, pulse counter or temperature sensor"
144  )
145  return False
146 
147  hass.async_create_task(
148  async_load_platform(hass, Platform.SENSOR, DOMAIN, config[DOMAIN], config)
149  )
150 
151  return True
bool async_setup(HomeAssistant hass, ConfigType config)
Definition: __init__.py:119
None async_load_platform(core.HomeAssistant hass, Platform|str component, str platform, DiscoveryInfoType|None discovered, ConfigType hass_config)
Definition: discovery.py:152