-
Notifications
You must be signed in to change notification settings - Fork 98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/sensor ac #48
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,10 +6,13 @@ | |
from custom_components.smartthinq import ( | ||
CONF_LANGUAGE, KEY_SMARTTHINQ_DEVICES, LGDevice) | ||
import homeassistant.helpers.config_validation as cv | ||
from homeassistant.const import CONF_REGION, CONF_TOKEN | ||
from homeassistant.const import CONF_REGION, CONF_TOKEN, DEVICE_CLASS_POWER, POWER_WATT | ||
|
||
import wideq | ||
from wideq import dishwasher | ||
from . import wideq | ||
from .wideq import dishwasher | ||
from .wideq import ac | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
|
||
REQUIREMENTS = ['https://github.com/dacrypt/wideq/archive/master.zip#wideq==1.3.1'] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I could be wrong, but I thought this was already enforced in the top-level module? |
||
|
||
ATTR_DW_STATE = 'state' | ||
ATTR_DW_REMAINING_TIME = 'remaining_time' | ||
|
@@ -22,6 +25,9 @@ | |
ATTR_DW_ERROR = 'error' | ||
ATTR_DW_DEVICE_TYPE = 'device_type' | ||
|
||
ATTR_AC_STATE = 'state' | ||
ATTR_AC_POWER = 'power' | ||
|
||
MAX_RETRIES = 5 | ||
|
||
KEY_DW_OFF = 'Off' | ||
|
@@ -39,11 +45,15 @@ def setup_platform(hass, config, add_entities, discovery_info=None): | |
|
||
client = wideq.Client.from_token(refresh_token, region, language) | ||
dishwashers = [] | ||
acs = [] | ||
|
||
for device_id in hass.data[KEY_SMARTTHINQ_DEVICES]: | ||
device = client.get_device(device_id) | ||
model = client.model_info(device) | ||
|
||
LOGGER.debug('SMARTTHINQ_DEVICE: %s' % device.type) | ||
LOGGER.debug('SMARTTHINQ_DEVICE: %s' % wideq.DeviceType.AC) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also perhaps unnecessary now? Or perhaps we could just make the messages more readable with English phrases? |
||
|
||
if device.type == wideq.DeviceType.DISHWASHER: | ||
base_name = "lg_dishwasher_" + device.id | ||
LOGGER.debug("Creating new LG DishWasher: %s" % base_name) | ||
|
@@ -53,11 +63,24 @@ def setup_platform(hass, config, add_entities, discovery_info=None): | |
# Dishwashers are only connected when in use. Ignore | ||
# NotConnectedError on platform setup. | ||
pass | ||
elif device.type == wideq.DeviceType.AC: | ||
# base_name = "lg_ac_" + device.id | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Delete? |
||
base_name = device.name + " Power" | ||
LOGGER.debug("Creating new LG AC power sensot: %s" % base_name) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sensot (spelling) |
||
try: | ||
acs.append(LGACPowerSensor(client, device, base_name)) | ||
except wideq.NotConnectedError: | ||
# AC are only connected when in use. Ignore | ||
# NotConnectedError on platform setup. | ||
pass | ||
|
||
if dishwashers: | ||
add_entities(dishwashers, True) | ||
return True | ||
|
||
if acs: | ||
add_entities(acs, True) | ||
|
||
return True | ||
|
||
class LGDishWasherDevice(LGDevice): | ||
def __init__(self, client, device, name): | ||
|
@@ -205,6 +228,207 @@ def update(self): | |
LOGGER.debug('No status available yet.') | ||
self._failed_request_count += 1 | ||
|
||
if self._failed_request_count >= MAX_RETRIES: | ||
# We tried several times but got no result. This might happen | ||
# when the monitoring request gets into a bad state, so we | ||
# restart the task. | ||
self._restart_monitor() | ||
self._failed_request_count = 0 | ||
# class LGACDevice(LGDevice): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe delete this stuff that's no longer in use? |
||
# def __init__(self, client, device, name): | ||
# """Initialize an LG AC Device.""" | ||
|
||
# super().__init__(client, device) | ||
|
||
# # This constructor is called during platform creation. It must not | ||
# # involve any API calls that actually need the ac to be | ||
# # connected, otherwise the device construction will fail and the entity | ||
# # will not get created. Specifically, calls that depend on ac | ||
# # interaction should only happen in update(...), including the start of | ||
# # the monitor task. | ||
# self._ac = ac.ACDevice(client, device) | ||
# self._name = name | ||
# self._status = None | ||
# self._failed_request_count = 0 | ||
|
||
# @property | ||
# def state_attributes(self): | ||
# """Return the optional state attributes for the ac.""" | ||
# data = {} | ||
# # For convenience, include the state as an attribute. | ||
# data[ATTR_AC_STATE] = self.state | ||
# return data | ||
|
||
# @property | ||
# def name(self): | ||
# return self._name | ||
|
||
# @property | ||
# def state(self): | ||
# if self._status: | ||
# # Process is a more refined string to use for state, if it's present, | ||
# # use it instead. | ||
# return self._status.mode.name | ||
# return 'OFF' | ||
|
||
# @property | ||
# def error(self): | ||
# if self._status: | ||
# return self._status.error | ||
# return KEY_AC_DISCONNECTED | ||
|
||
# def _restart_monitor(self): | ||
# try: | ||
# self._ac.monitor_start() | ||
# except wideq.NotConnectedError: | ||
# self._status = None | ||
# except wideq.NotLoggedInError: | ||
# LOGGER.info('Session expired. Refreshing.') | ||
# self._client.refresh() | ||
|
||
# def update(self): | ||
# """Poll for ac state updates.""" | ||
|
||
# # This method is polled, so try to avoid sleeping in here. If an error | ||
# # occurs, it will naturally be retried on the next poll. | ||
|
||
# LOGGER.debug('Updating sensor %s.', self.name) | ||
|
||
# # On initial construction, the ac monitor task | ||
# # will not have been created. If so, start monitoring here. | ||
# if getattr(self._ac, 'mon', None) is None: | ||
# self._restart_monitor() | ||
|
||
# try: | ||
# status = self._ac.poll() | ||
# except wideq.NotConnectedError: | ||
# self._status = None | ||
# return | ||
# except wideq.NotLoggedInError: | ||
# LOGGER.info('Session expired. Refreshing.') | ||
# self._client.refresh() | ||
# self._restart_monitor() | ||
# return | ||
|
||
# if status: | ||
# LOGGER.debug('Status updated.') | ||
# self._status = status | ||
# self._failed_request_count = 0 | ||
# return | ||
|
||
# LOGGER.debug('No status available yet.') | ||
# self._failed_request_count += 1 | ||
|
||
# if self._failed_request_count >= MAX_RETRIES: | ||
# # We tried several times but got no result. This might happen | ||
# # when the monitoring request gets into a bad state, so we | ||
# # restart the task. | ||
# self._restart_monitor() | ||
# self._failed_request_count = 0 | ||
|
||
class LGACPowerSensor(LGDevice): | ||
def __init__(self, client, device, name): | ||
"""Initialize an LG AC Power Sensor.""" | ||
|
||
super().__init__(client, device) | ||
|
||
# This constructor is called during platform creation. It must not | ||
# involve any API calls that actually need the ac to be | ||
# connected, otherwise the device construction will fail and the entity | ||
# will not get created. Specifically, calls that depend on ac | ||
# interaction should only happen in update(...), including the start of | ||
# the monitor task. | ||
self._ac = ac.ACDevice(client, device) | ||
self._name = name | ||
# self._status = None | ||
self._state = None | ||
self._unit_of_measurement = POWER_WATT | ||
self._device_class = DEVICE_CLASS_POWER | ||
self._failed_request_count = 0 | ||
|
||
# @property | ||
# def state_attributes(self): | ||
# """Return the optional state attributes for the ac.""" | ||
# data = {} | ||
# data[ATTR_AC_POWER] = self.power | ||
|
||
# # For convenience, include the state as an attribute. | ||
# # data[ATTR_AC_STATE] = self.state | ||
# return data | ||
|
||
@property | ||
def name(self): | ||
"""Return the name of the sensor.""" | ||
LOGGER.info('Sensor name: %s', self._name) | ||
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 of this entity.""" | ||
return self._unit_of_measurement | ||
|
||
@property | ||
def device_class(self): | ||
"""Type of sensor.""" | ||
return self._device_class | ||
|
||
# @property | ||
# def error(self): | ||
# if self._status: | ||
# return self._status.error | ||
# return KEY_AC_DISCONNECTED | ||
|
||
def _restart_monitor(self): | ||
try: | ||
self._ac.monitor_start() | ||
except wideq.NotConnectedError: | ||
self._state = None | ||
except wideq.NotLoggedInError: | ||
LOGGER.info('Session expired. Refreshing.') | ||
self._client.refresh() | ||
|
||
def update(self): | ||
"""Poll for ac power updates.""" | ||
|
||
# This method is polled, so try to avoid sleeping in here. If an error | ||
# occurs, it will naturally be retried on the next poll. | ||
|
||
LOGGER.debug('Updating sensor %s.', self.name) | ||
|
||
# On initial construction, the ac monitor task | ||
# will not have been created. If so, start monitoring here. | ||
if getattr(self._ac, 'mon', None) is None: | ||
LOGGER.debug('Restart monitor') | ||
self._restart_monitor() | ||
|
||
try: | ||
state = float(self._ac.get_power()) | ||
LOGGER.debug('Power %d', state) | ||
|
||
except wideq.NotConnectedError: | ||
LOGGER.debug('Not connected') | ||
self._state = None | ||
return | ||
except wideq.NotLoggedInError: | ||
LOGGER.info('Session expired. Refreshing.') | ||
self._client.refresh() | ||
self._restart_monitor() | ||
return | ||
|
||
if state: | ||
LOGGER.debug('state updated. %d', state) | ||
self._state = state | ||
self._failed_request_count = 0 | ||
return | ||
|
||
LOGGER.debug('No state available yet.') | ||
self._failed_request_count += 1 | ||
|
||
if self._failed_request_count >= MAX_RETRIES: | ||
# We tried several times but got no result. This might happen | ||
# when the monitoring request gets into a bad state, so we | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we can take out these extra debug statements now?