-
-
Notifications
You must be signed in to change notification settings - Fork 37.7k
KNX Cover tilt control #8159
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
KNX Cover tilt control #8159
Changes from 8 commits
1a14ebe
e36a7b6
b496a42
560050c
b110988
82ee0d4
7432031
d9108b1
0827a63
f1e7e3d
c494ee3
5b8755e
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 |
|---|---|---|
|
|
@@ -9,7 +9,9 @@ | |
| import voluptuous as vol | ||
|
|
||
| from homeassistant.components.cover import ( | ||
| CoverDevice, PLATFORM_SCHEMA, ATTR_POSITION, DEVICE_CLASSES_SCHEMA | ||
| CoverDevice, PLATFORM_SCHEMA, ATTR_POSITION, DEVICE_CLASSES_SCHEMA, | ||
| SUPPORT_OPEN, SUPPORT_CLOSE, SUPPORT_SET_POSITION, SUPPORT_STOP, | ||
| SUPPORT_SET_TILT_POSITION | ||
| ) | ||
| from homeassistant.components.knx import (KNXConfig, KNXMultiAddressDevice) | ||
| from homeassistant.const import (CONF_NAME, CONF_DEVICE_CLASS) | ||
|
|
@@ -19,9 +21,12 @@ | |
|
|
||
| CONF_GETPOSITION_ADDRESS = 'getposition_address' | ||
| CONF_SETPOSITION_ADDRESS = 'setposition_address' | ||
| CONF_GETANGLE_ADDRESS = 'getangle_address' | ||
| CONF_SETANGLE_ADDRESS = 'setangle_address' | ||
| CONF_STOP = 'stop_address' | ||
| CONF_UPDOWN = 'updown_address' | ||
| CONF_INVERT_POSITION = 'invert_position' | ||
| CONF_INVERT_ANGLE = 'invert_angle' | ||
|
|
||
| DEFAULT_NAME = 'KNX Cover' | ||
| DEPENDENCIES = ['knx'] | ||
|
|
@@ -34,6 +39,9 @@ | |
| vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, | ||
| vol.Optional(CONF_SETPOSITION_ADDRESS): cv.string, | ||
| vol.Optional(CONF_INVERT_POSITION, default=False): cv.boolean, | ||
| vol.Optional(CONF_GETANGLE_ADDRESS): cv.string, | ||
| vol.Optional(CONF_SETANGLE_ADDRESS): cv.string, | ||
|
Member
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. use
Author
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. Thee options are optional. There are shutter with and without the angle feature. The code supports both now.
Member
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. Yes that is what I mean with this change. It would be also nice to use
Author
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. In this case, I don't understand how the code should look like. While it would be possible to define regexps for the addresses, these would become quite ugly (there are multiple address formats).
Member
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. |
||
| vol.Optional(CONF_INVERT_ANGLE, default=False): cv.boolean, | ||
| }) | ||
|
|
||
|
|
||
|
|
@@ -50,19 +58,41 @@ def __init__(self, hass, config): | |
| KNXMultiAddressDevice.__init__( | ||
| self, hass, config, | ||
| ['updown', 'stop'], # required | ||
| optional=['setposition', 'getposition'] | ||
| optional=['setposition', 'getposition', | ||
| 'getangle', 'setangle'] | ||
| ) | ||
| self._device_class = config.config.get(CONF_DEVICE_CLASS) | ||
| self._invert_position = config.config.get(CONF_INVERT_POSITION) | ||
| self._invert_angle = config.config.get(CONF_INVERT_ANGLE) | ||
| self._hass = hass | ||
| self._current_pos = None | ||
| self._target_pos = None | ||
| self._current_tilt = None | ||
| self._target_tilt = None | ||
| self._supported_features = SUPPORT_OPEN | SUPPORT_CLOSE | \ | ||
| SUPPORT_SET_POSITION | SUPPORT_STOP | ||
|
|
||
| # Tilt is only supported, if there is a angle get and set address | ||
| if (config.config.get(CONF_SETANGLE_ADDRESS) is not None) and \ | ||
|
Member
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. With new vol check you can simplify that please.
Member
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. Remove also |
||
| (config.config.get(CONF_GETANGLE_ADDRESS) is not None): | ||
| _LOGGER.debug("%s: Tilt supported at addresses %s, %s", | ||
| self.name, config.config.get(CONF_SETANGLE_ADDRESS), | ||
| config.config.get(CONF_GETANGLE_ADDRESS)) | ||
| self._supported_features = self._supported_features | \ | ||
| SUPPORT_SET_TILT_POSITION | ||
| else: | ||
| _LOGGER.debug("%s: Tilt not supported", self.name) | ||
|
|
||
| @property | ||
| def should_poll(self): | ||
| """Polling is needed for the KNX cover.""" | ||
| return True | ||
|
|
||
| @property | ||
| def supported_features(self): | ||
| """Flag supported features.""" | ||
| return self._supported_features | ||
|
|
||
| @property | ||
| def is_closed(self): | ||
| """Return if the cover is closed.""" | ||
|
|
@@ -85,6 +115,19 @@ def target_position(self): | |
| """Return the position we are trying to reach: 0 - 100.""" | ||
| return self._target_pos | ||
|
|
||
| @property | ||
|
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. too many blank lines (2) |
||
| def current_cover_tilt_position(self): | ||
| """Return current position of cover. | ||
|
|
||
| None is unknown, 0 is closed, 100 is fully open. | ||
| """ | ||
| return self._current_tilt | ||
|
|
||
| @property | ||
|
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. too many blank lines (2) |
||
| def target_tilt(self): | ||
| """Return the tilt angle (in %) we are trying to reach: 0 - 100.""" | ||
| return self._target_tilt | ||
|
|
||
| def set_cover_position(self, **kwargs): | ||
| """Set new target position.""" | ||
| position = kwargs.get(ATTR_POSITION) | ||
|
|
@@ -108,6 +151,14 @@ def update(self): | |
| self._current_pos = 100-value | ||
| _LOGGER.debug("%s: position = %d", self.name, value) | ||
|
|
||
| if self._supported_features & SUPPORT_SET_TILT_POSITION: | ||
| value = self.get_percentage('getangle') | ||
| if value is not None: | ||
| self._current_tilt = value | ||
| if self._invert_angle: | ||
| self._current_tilt = 100-value | ||
| _LOGGER.debug("%s: tilt = %d", self.name, value) | ||
|
|
||
| def open_cover(self, **kwargs): | ||
| """Open the cover.""" | ||
| _LOGGER.debug("%s: open: updown = 0", self.name) | ||
|
|
@@ -123,6 +174,14 @@ def stop_cover(self, **kwargs): | |
| _LOGGER.debug("%s: stop: stop = 1", self.name) | ||
| self.set_int_value('stop', 1) | ||
|
|
||
| def set_cover_tilt_position(self, tilt_position, **kwargs): | ||
| """Move the cover til to a specific position.""" | ||
| if self._invert_angle: | ||
| tilt_position = 100-tilt_position | ||
|
|
||
| self._target_tilt = round(tilt_position, -1) | ||
| self.set_percentage('setangle', tilt_position) | ||
|
|
||
| @property | ||
| def device_class(self): | ||
| """Return the class of this device, from component DEVICE_CLASSES.""" | ||
|
|
||
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.
You can not use the same invert flag for all?
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.
No, there might be cases were one is inverted, but not the other.