-
-
Notifications
You must be signed in to change notification settings - Fork 38.3k
Venetian blind support for proprietary Fibaro FGRM-222 Roller Shutter devices #24405
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
Closed
Closed
Changes from 2 commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,21 +2,37 @@ | |
| import logging | ||
| from homeassistant.core import callback | ||
| from homeassistant.components.cover import ( | ||
| DOMAIN, SUPPORT_OPEN, SUPPORT_CLOSE, ATTR_POSITION) | ||
| DOMAIN, SUPPORT_OPEN, SUPPORT_CLOSE, ATTR_POSITION, ATTR_TILT_POSITION) | ||
| from homeassistant.components.cover import CoverDevice | ||
| from homeassistant.helpers.dispatcher import async_dispatcher_connect | ||
| from . import ( | ||
| ZWaveDeviceEntity, CONF_INVERT_OPENCLOSE_BUTTONS, CONF_INVERT_PERCENT, | ||
| workaround) | ||
| workaround, CONF_TILT_OPEN_POSITION) | ||
| from .const import ( | ||
| COMMAND_CLASS_SWITCH_MULTILEVEL, COMMAND_CLASS_SWITCH_BINARY, | ||
| COMMAND_CLASS_BARRIER_OPERATOR, DATA_NETWORK) | ||
| COMMAND_CLASS_BARRIER_OPERATOR, COMMAND_CLASS_MANUFACTURER_PROPRIETARY, | ||
| DATA_NETWORK) | ||
|
|
||
| _LOGGER = logging.getLogger(__name__) | ||
|
|
||
| SUPPORT_GARAGE = SUPPORT_OPEN | SUPPORT_CLOSE | ||
|
|
||
|
|
||
| def _to_hex_str(id_in_bytes): | ||
| """Convert a two byte value to a hex string. | ||
|
|
||
| Example: 0x1234 --> '0x1234' | ||
| """ | ||
| return '0x{:04x}'.format(id_in_bytes) | ||
|
|
||
|
|
||
| # For whatever reason node.manufacturer_id is of type string. So we need | ||
| # to convert the values. | ||
| FIBARO = _to_hex_str(workaround.FIBARO) | ||
| FIBARO_SHUTTERS = [_to_hex_str(workaround.FGR222_SHUTTER2), | ||
| _to_hex_str(workaround.FGRM222_SHUTTER2)] | ||
|
|
||
|
|
||
| async def async_setup_platform( | ||
| hass, config, async_add_entities, discovery_info=None): | ||
| """Old method of setting up Z-Wave covers.""" | ||
|
|
@@ -40,6 +56,10 @@ def get_device(hass, values, node_config, **kwargs): | |
| if (values.primary.command_class == | ||
| COMMAND_CLASS_SWITCH_MULTILEVEL | ||
| and values.primary.index == 0): | ||
| if values.primary.node.manufacturer_id == FIBARO \ | ||
| and values.primary.node.product_type in FIBARO_SHUTTERS: | ||
| return FibaroFGRM222(hass, values, invert_buttons, invert_percent, | ||
| node_config.get(CONF_TILT_OPEN_POSITION)) | ||
| return ZwaveRollershutter(hass, values, invert_buttons, invert_percent) | ||
| if values.primary.command_class == COMMAND_CLASS_SWITCH_BINARY: | ||
| return ZwaveGarageDoorSwitch(values) | ||
|
|
@@ -191,3 +211,110 @@ def close_cover(self, **kwargs): | |
| def open_cover(self, **kwargs): | ||
| """Open the garage door.""" | ||
| self.values.primary.data = "Opened" | ||
|
|
||
|
|
||
| class FibaroFGRM222(ZwaveRollershutter): | ||
| """Implementation of proprietary features for Fibaro FGR-222 / FGRM-222. | ||
|
|
||
| This adds support for the tilt feature for the ventian blind mode. | ||
| To enable this you need to configure the devices to use the venetian blind | ||
| mode and to enable the proprietary command class: | ||
| * Set "3: Reports type to Blind position reports sent" | ||
| to value "the main controller using Fibar Command Class" | ||
| * Set "10: Roller Shutter operating modes" | ||
| to value "2 - Venetian Blind Mode, with positioning" | ||
| """ | ||
|
|
||
| def __init__(self, hass, values, invert_buttons, invert_percent, | ||
| open_tilt_position: int): | ||
| """Initialize the FGRM-222.""" | ||
| self._value_blinds = None | ||
| self._value_tilt = None | ||
| self._has_tilt_mode = False # type: bool | ||
| self._open_tilt_position = 50 # type: int | ||
| if open_tilt_position is not None: | ||
| self._open_tilt_position = open_tilt_position | ||
| _LOGGER.debug('open_tilt_position: %s', open_tilt_position) | ||
|
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. We don't want side effects, eg logging, in init method. |
||
| super().__init__(hass, values, invert_buttons, invert_percent) | ||
|
|
||
| @property | ||
| def current_cover_tilt_position(self) -> int: | ||
| """Get the tilt of the blinds. | ||
|
|
||
| Saturate values <5 and >94 so that it's easier to detect the end | ||
| positions in automations. | ||
| """ | ||
| if not self._has_tilt_mode: | ||
| return None | ||
| if self._value_tilt.data <= 5: | ||
| return 0 | ||
| if self._value_tilt.data >= 95: | ||
| return 100 | ||
| return self._value_tilt.data | ||
|
|
||
| def set_cover_tilt_position(self, **kwargs): | ||
| """Move the cover tilt to a specific position.""" | ||
| if not self._has_tilt_mode: | ||
| _LOGGER.error("Can't set cover tilt as device is not yet set up.") | ||
| else: | ||
| # Limit the range to [0-99], as this what that the ZWave command | ||
| # accepts. | ||
| tilt_position = max(0, min(99, kwargs.get(ATTR_TILT_POSITION))) | ||
| _LOGGER.debug("setting tilt to %d", tilt_position) | ||
| self._value_tilt.data = tilt_position | ||
|
|
||
| def open_cover_tilt(self, **kwargs): | ||
| """Set slats to horizontal position.""" | ||
| self.set_cover_tilt_position(tilt_position=self._open_tilt_position) | ||
|
|
||
| def close_cover_tilt(self, **kwargs): | ||
| """Close the slats.""" | ||
| self.set_cover_tilt_position(tilt_position=0) | ||
|
|
||
| def set_cover_position(self, **kwargs): | ||
| """Move the roller shutter to a specific position. | ||
|
|
||
| If the venetian blinds mode is not activated, fall back to | ||
| the behavior of the parent class. | ||
| """ | ||
| if not self._has_tilt_mode: | ||
| super().set_cover_position(**kwargs) | ||
| else: | ||
| _LOGGER.debug('Setting cover position to %s', | ||
| kwargs.get(ATTR_POSITION)) | ||
| self._value_blinds.data = kwargs.get(ATTR_POSITION) | ||
|
|
||
| def _configure_values(self): | ||
| """Get the value objects from the node.""" | ||
| for value in self.node.get_values( | ||
| class_id=COMMAND_CLASS_MANUFACTURER_PROPRIETARY).values(): | ||
| if value is None: | ||
| continue | ||
| if value.index == 0: | ||
| self._value_blinds = value | ||
| elif value.index == 1: | ||
| self._value_tilt = value | ||
| else: | ||
| _LOGGER.warning('Undefined index %d for this command class', | ||
| value.index) | ||
|
|
||
| # If we've ever seen tilt != 0 assume we are in the venetian mode. | ||
| # This is not the best way to detect it. Once the bug below is | ||
| # resolved, check the config values of the node and only enable the | ||
| # tilt mode if they are set accordingly. | ||
| # https://github.com/home-assistant/home-assistant/issues/24404 | ||
|
|
||
| if self._value_tilt is not None and self._value_tilt.data > 0: | ||
| self._has_tilt_mode = True | ||
| _LOGGER.info('Zwave node %s is a Fibaro FGR-222/FGRM-222' | ||
| ' with tilt support.', | ||
| self.node_id) | ||
|
|
||
| def update_properties(self): | ||
| """React on properties being updated.""" | ||
| if not self._has_tilt_mode: | ||
| self._configure_values() | ||
| if self._value_blinds is not None: | ||
| self._current_position = self._value_blinds.data | ||
| else: | ||
| super().update_properties() | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.