Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,7 @@ omit =
homeassistant/components/rainmachine/binary_sensor.py
homeassistant/components/rainmachine/sensor.py
homeassistant/components/rainmachine/switch.py
homeassistant/components/rainforest_eagle/sensor.py
homeassistant/components/raspihats/*
homeassistant/components/raspyrfm/*
homeassistant/components/recollect_waste/sensor.py
Expand Down
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ homeassistant/components/qnap/* @colinodell
homeassistant/components/quantum_gateway/* @cisasteelersfan
homeassistant/components/qwikswitch/* @kellerza
homeassistant/components/raincloud/* @vanstinator
homeassistant/components/rainforest_eagle/* @gtdiehl
homeassistant/components/rainmachine/* @bachya
homeassistant/components/random/* @fabaff
homeassistant/components/repetier/* @MTrab
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/rainforest_eagle/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""The rainforest_eagle component."""
10 changes: 10 additions & 0 deletions homeassistant/components/rainforest_eagle/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"domain": "rainforest_eagle",
"name": "Rainforest Eagle-200",
"documentation": "https://www.home-assistant.io/components/rainforest_eagle",
"requirements": [
"eagle200_reader==0.1.4"
],
"dependencies": [],
"codeowners": ["@gtdiehl"]
}
135 changes: 135 additions & 0 deletions homeassistant/components/rainforest_eagle/sensor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
"""Support for the Rainforest Eagle-200 energy monitor."""
from datetime import timedelta
import logging

from requests.exceptions import (
ConnectionError as ConnectError, HTTPError, Timeout)
import voluptuous as vol

from homeassistant.components.sensor import PLATFORM_SCHEMA
from homeassistant.const import (
CONF_IP_ADDRESS, CONF_SCAN_INTERVAL, ENERGY_KILO_WATT_HOUR)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity
from homeassistant.util import Throttle

CONF_CLOUD_ID = 'cloud_id'
CONF_INSTALL_CODE = 'install_code'
POWER_KILO_WATT = 'kW'

_LOGGER = logging.getLogger(__name__)

SCAN_INTERVAL = timedelta(seconds=30)

SENSORS = {
"instantanous_demand": (
"Eagle-200 Meter Power Demand", POWER_KILO_WATT),
Comment thread
gtdiehl marked this conversation as resolved.
"summation_delivered": (
"Eagle-200 Total Meter Energy Delivered",
ENERGY_KILO_WATT_HOUR),
"summation_received": (
"Eagle-200 Total Meter Energy Received",
ENERGY_KILO_WATT_HOUR),
"summation_total": (
"Eagle-200 Net Meter Energy (Delivered minus Received)",
ENERGY_KILO_WATT_HOUR)
}

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_IP_ADDRESS): cv.string,
vol.Required(CONF_CLOUD_ID): cv.string,
vol.Required(CONF_INSTALL_CODE): cv.string
})


def setup_platform(hass, config, add_devices, discovery_info=None):
Comment thread
gtdiehl marked this conversation as resolved.
Outdated
"""Create the Eagle-200 sensor."""
ip_address = config[CONF_IP_ADDRESS]
cloud_id = config[CONF_CLOUD_ID]
install_code = config[CONF_INSTALL_CODE]
interval = config.get(CONF_SCAN_INTERVAL, SCAN_INTERVAL)

eagle_data = EagleData(ip_address, cloud_id, install_code, interval)
eagle_data.update()

monitored_conditions = list(SENSORS)
sensors = []
for condition in monitored_conditions:
sensors.append(EagleSensor(
eagle_data, condition, SENSORS[condition][0],
SENSORS[condition][1]))

add_devices(sensors)


class EagleSensor(Entity):
"""Implementation of the Rainforest Eagle-200 sensor."""

def __init__(
self, eagle_data, sensor_type, name, unit):
"""Initialize the sensor."""
self.eagle_data = eagle_data
self._type = sensor_type
self._name = name
self._unit_of_measurement = unit
self._state = None

@property
def name(self):
"""Return the name of the sensor."""
return self._name

@property
def state(self):
"""Return the state of the sensor."""
return self._state

@property
def unit_of_measurement(self):
"""Return the unit of measurement."""
return self._unit_of_measurement

def update(self):
"""Get the energy information from the Rainforest Eagle."""
self.eagle_data.update()
data = self.eagle_data.data
Comment thread
gtdiehl marked this conversation as resolved.
Outdated
self._state = self.get_state(data)

def get_state(self, data):
Comment thread
gtdiehl marked this conversation as resolved.
Outdated
"""Get the sensor value from the dictionary."""
if data is None:
return None

state = data.get(self._type)
return state


class EagleData:
"""Get the latest data from the Eagle-200 device."""

def __init__(self, ip_address, cloud_id, install_code, interval):
"""Initialize the data object."""
self._ip_address = ip_address
self._cloud_id = cloud_id
self._install_code = install_code
self.interval = interval
Comment thread
gtdiehl marked this conversation as resolved.
Outdated

self.data = {}

# Apply throttling to update method using configured interval.
self.update = Throttle(interval)(self._update)

def _update(self):
Comment thread
gtdiehl marked this conversation as resolved.
Outdated
"""Get the latest data from the Eagle-200 device."""
from eagle200_reader import EagleReader
Comment thread
gtdiehl marked this conversation as resolved.
Outdated

try:
eagle_reader = EagleReader(
Comment thread
gtdiehl marked this conversation as resolved.
Outdated
self._ip_address, self._cloud_id, self._install_code)

for sensor_type in SENSORS:
self.data.update({sensor_type: getattr(
eagle_reader, sensor_type)()})
Comment thread
gtdiehl marked this conversation as resolved.
Outdated
except (ConnectError, HTTPError, Timeout, ValueError) as error:
_LOGGER.error("Unable to connect to the Eagle-200: %s", error)
self.data = None
Comment thread
gtdiehl marked this conversation as resolved.
Outdated
3 changes: 3 additions & 0 deletions requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,9 @@ dsmr_parser==0.12
# homeassistant.components.dweet
dweepy==0.3.0

# homeassistant.components.rainforest_eagle
eagle200_reader==0.1.4

# homeassistant.components.ebusd
ebusdpy==0.0.16

Expand Down