mirror of
https://github.com/USA-RedDragon/badnest.git
synced 2025-01-18 13:05:26 +00:00
Implemented custom service for hot water boosting and hot water sensor
This commit is contained in:
parent
7ab48d968e
commit
40af195cb6
@ -1,10 +1,22 @@
|
||||
"""The example integration."""
|
||||
import logging
|
||||
import voluptuous as vol
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from datetime import datetime
|
||||
import time
|
||||
from homeassistant.util.dt import utcnow
|
||||
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID
|
||||
)
|
||||
|
||||
from .api import NestAPI
|
||||
from .const import DOMAIN, CONF_ISSUE_TOKEN, CONF_COOKIE, CONF_USER_ID, CONF_ACCESS_TOKEN, CONF_REGION
|
||||
|
||||
SERVICE_BOOST_HOT_WATER = "boost_hot_water"
|
||||
ATTR_TIME_PERIOD = "time_period"
|
||||
ATTR_MODE = "on_off"
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema(
|
||||
{
|
||||
DOMAIN: vol.All(
|
||||
@ -23,9 +35,36 @@ CONFIG_SCHEMA = vol.Schema(
|
||||
extra=vol.ALLOW_EXTRA,
|
||||
)
|
||||
|
||||
BOOST_HOT_WATER_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Required(ATTR_ENTITY_ID): cv.entity_id,
|
||||
vol.Optional(ATTR_TIME_PERIOD, default=30): cv.positive_int,
|
||||
vol.Required(ATTR_MODE): cv.string,
|
||||
}
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
def setup(hass, config):
|
||||
"""Set up the badnest component."""
|
||||
def hot_water_boost(service):
|
||||
"""Handle the service call."""
|
||||
node_id = hass.data.get(service.data[ATTR_ENTITY_ID])
|
||||
if not node_id:
|
||||
# log or raise error
|
||||
_LOGGER.error("Cannot boost entity id entered")
|
||||
return
|
||||
|
||||
minutes = service.data[ATTR_TIME_PERIOD]
|
||||
timeToEnd = int(time.mktime(datetime.timetuple(utcnow()))+(minutes*60))
|
||||
|
||||
mode = service.data[ATTR_MODE]
|
||||
|
||||
if mode == "on":
|
||||
api.hotwater_set_boost(node_id, timeToEnd)
|
||||
elif mode == "off":
|
||||
api.hotwater_set_boost(node_id, 0)
|
||||
|
||||
if config.get(DOMAIN) is not None:
|
||||
user_id = config[DOMAIN].get(CONF_USER_ID)
|
||||
access_token = config[DOMAIN].get(CONF_ACCESS_TOKEN)
|
||||
@ -49,4 +88,13 @@ def setup(hass, config):
|
||||
),
|
||||
}
|
||||
|
||||
api = hass.data[DOMAIN]['api']
|
||||
|
||||
hass.services.register(
|
||||
DOMAIN,
|
||||
SERVICE_BOOST_HOT_WATER,
|
||||
hot_water_boost,
|
||||
schema=BOOST_HOT_WATER_SCHEMA,
|
||||
)
|
||||
|
||||
return True
|
||||
|
@ -48,6 +48,7 @@ class NestAPI():
|
||||
self.cameras = []
|
||||
self.thermostats = []
|
||||
self.temperature_sensors = []
|
||||
self.hotwatercontrollers = []
|
||||
self.protects = []
|
||||
self.login()
|
||||
self._get_devices()
|
||||
@ -153,6 +154,7 @@ class NestAPI():
|
||||
sn = bucket.replace('device.', '')
|
||||
self.thermostats.append(sn)
|
||||
self.temperature_sensors.append(sn)
|
||||
self.hotwatercontrollers.append(sn)
|
||||
self.device_data[sn] = {}
|
||||
|
||||
self.cameras = self._get_cameras()
|
||||
@ -270,6 +272,9 @@ class NestAPI():
|
||||
self.device_data[sn]['eco'] = True
|
||||
else:
|
||||
self.device_data[sn]['eco'] = False
|
||||
# Hot water
|
||||
self.device_data[sn]['hot_water_active'] = \
|
||||
sensor_data["hot_water_active"]
|
||||
# Protect
|
||||
elif bucket["object_key"].startswith(
|
||||
f"topaz.{sn}"):
|
||||
@ -484,6 +489,34 @@ class NestAPI():
|
||||
self.login()
|
||||
self.thermostat_set_eco_mode(device_id, state)
|
||||
|
||||
def hotwater_set_boost(self, device_id, time):
|
||||
if device_id not in self.hotwatercontrollers:
|
||||
return
|
||||
|
||||
try:
|
||||
self._session.post(
|
||||
f"{self._czfe_url}/v5/put",
|
||||
json={
|
||||
"objects": [
|
||||
{
|
||||
"object_key": f'device.{device_id}',
|
||||
"op": "MERGE",
|
||||
"value": {"hot_water_boost_time_to_end": time},
|
||||
}
|
||||
]
|
||||
},
|
||||
headers={"Authorization": f"Basic {self._access_token}"},
|
||||
)
|
||||
except requests.exceptions.RequestException as e:
|
||||
_LOGGER.error(e)
|
||||
_LOGGER.error('Failed to boost hot water, trying again')
|
||||
self.hotwater_set_boost(device_id, time)
|
||||
except KeyError:
|
||||
_LOGGER.debug('Failed to boost hot water, trying to log in again')
|
||||
self.login()
|
||||
self.hotwater_set_boost(device_id, time)
|
||||
|
||||
|
||||
def _camera_set_properties(self, device_id, property, value):
|
||||
if device_id not in self.cameras:
|
||||
return
|
||||
|
@ -116,7 +116,10 @@ class NestClimate(ClimateDevice):
|
||||
|
||||
if self.device.device_data[device_id]['target_humidity_enabled']:
|
||||
self._support_flags = self._support_flags | SUPPORT_TARGET_HUMIDITY
|
||||
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""When entity is added to Home Assistant."""
|
||||
self.hass.data[self.entity_id] = self.device_id
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
@ -157,7 +160,7 @@ class NestClimate(ClimateDevice):
|
||||
def target_humidity(self):
|
||||
"""Return the target humidity."""
|
||||
return self.device.device_data[self.device_id]['target_humidity']
|
||||
|
||||
|
||||
@property
|
||||
def min_humidity(self):
|
||||
"""Return the min target humidity."""
|
||||
|
@ -32,7 +32,14 @@ async def async_setup_platform(hass,
|
||||
_LOGGER.info(f"Adding nest temp sensor uuid: {sensor}")
|
||||
temperature_sensors.append(NestTemperatureSensor(sensor, api))
|
||||
|
||||
hw_sensors = []
|
||||
_LOGGER.info("Adding hot water sensors")
|
||||
for hotwater in api['hotwatercontrollers']:
|
||||
_LOGGER.info(f"Adding nest hot water sensor uuid: {hotwater}")
|
||||
hw_sensors.append(NestHWSensor(hotwater, api))
|
||||
|
||||
async_add_entities(temperature_sensors)
|
||||
async_add_entities(hw_sensors)
|
||||
|
||||
protect_sensors = []
|
||||
_LOGGER.info("Adding protect sensors")
|
||||
@ -92,6 +99,43 @@ class NestTemperatureSensor(Entity):
|
||||
}
|
||||
|
||||
|
||||
class NestHWSensor(Entity):
|
||||
"""Implementation of the Nest Hot Water sensor."""
|
||||
|
||||
def __init__(self, device_id, api):
|
||||
"""Initialize the sensor."""
|
||||
self._name = "Nest Hot Water Sensor"
|
||||
self.device_id = device_id
|
||||
self.device = api
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return an unique ID."""
|
||||
return self.device_id + '_hw'
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the sensor."""
|
||||
return "{0} Hot Water".format(self.device.device_data[self.device_id]['name'])
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Return the icon to use in the frontend."""
|
||||
return "mdi:water"
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state of the sensor."""
|
||||
if self.device.device_data[self.device_id]['hot_water_active']:
|
||||
return 'On'
|
||||
else:
|
||||
return 'Off'
|
||||
|
||||
def update(self):
|
||||
"""Get the latest data from the Protect and updates the states."""
|
||||
self.device.update()
|
||||
|
||||
|
||||
class NestProtectSensor(Entity):
|
||||
"""Implementation of the Nest Protect sensor."""
|
||||
|
||||
|
11
custom_components/badnest/services.yaml
Normal file
11
custom_components/badnest/services.yaml
Normal file
@ -0,0 +1,11 @@
|
||||
boost_hot_water:
|
||||
description:
|
||||
"Set the boost mode ON or OFF defining the period of time for the boost."
|
||||
fields:
|
||||
entity_id:
|
||||
{
|
||||
description: Enter the entity_id for the device reuired to set the boost mode.,
|
||||
example: "water_heater.hot_water",
|
||||
}
|
||||
time_period: { description: Set the time period in minutes for the boost., example: 30}
|
||||
on_off: { description: Set the boost function on or off., example: "on" }
|
9
info.md
9
info.md
@ -14,6 +14,7 @@ This isn't an advertised or public API, it's still better than web scraping, but
|
||||
- Nest Thermostat support
|
||||
- Nest Thermostat Sensor support
|
||||
- Nest Camera support
|
||||
- Nest Hot Water support (UK)
|
||||
|
||||
## Drawbacks
|
||||
|
||||
@ -28,6 +29,14 @@ The camera's region is one of `us` or `eu` depending on your region.
|
||||
If you're not in the US or EU, you should be able to add your
|
||||
two-character country code, and it should work.
|
||||
|
||||
## Hot Water Control (UK)
|
||||
|
||||
Hot water boosting is controlled through the `badnest.boost_hot_water` service.
|
||||
The required variables are:
|
||||
`entity_id`
|
||||
`time_period` - integer in minutes
|
||||
`on_off`
|
||||
|
||||
### Example configuration.yaml - When you're not using the Google Auth Login
|
||||
|
||||
Google recently introduced reCAPTCHA when logging to Nest. That means username
|
||||
|
Loading…
Reference in New Issue
Block a user