Skip to content

Commit

Permalink
Merge pull request #51 from RainerStaude/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
RainerStaude authored Oct 14, 2024
2 parents c10dab1 + 5be09e7 commit 330dfa2
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 6 deletions.
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Becker cover support for Home Assistant

A native Home Assistant component to control Becker RF shutters with a Becker Centronic USB stick.
It supports the Becker ***Centronic USB Stick*** with the Becker order number ***4035 200 041 0***.
It works with the Becker ***Centronic USB Stick*** with the Becker order number ***4035 200 041 0*** and ***4035 000 041 0***.
It works for the Becker ***Centronic*** roller shutters, blinds and sun protection as well as for Roto roof windows with RF remotes.
It is based on the work of [ole](https://github.com/ole1986) and [Nicolas Berthel](https://github.com/nicolasberthel).

Expand Down Expand Up @@ -244,6 +244,24 @@ data:
unit: 1
```

# Events for Remote Commands
In addition to processing remote commands to update cover states, the
integration also fires explicit events of type
`becker_remote_packet_received` for each command it receives from a remote.
Those events can be used to trigger automations when remote buttons are pressed
or for other custom purposes.

Each event contains data about the remote unit, channel and the command
that has been received, for instance:

```yaml
event_type: becker_remote_packet_received
data:
unit: "12345"
channel: "1"
command: "up"
```

# Troubleshooting
If you have any trouble follow these steps:
- Restart Home Assistant after you have plugged in the USB stick
Expand Down
1 change: 1 addition & 0 deletions const.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
DEVICE_CLASS = "shutter"

RECEIVE_MESSAGE = "receive_message"
REMOTE_PACKET_EVENT = "remote_packet_received"

CONF_CHANNEL = "channel"
CONF_COVERS = "covers"
Expand Down
5 changes: 3 additions & 2 deletions cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
async_track_template_result,
)
from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.helpers.dispatcher import async_dispatcher_connect

from .const import (
CLOSED_POSITION,
Expand Down Expand Up @@ -250,8 +251,8 @@ async def async_added_to_hass(self):
if self._tc.current_position() is None:
self._tc.set_position(100 - CLOSED_POSITION)
# Setup callback on received packets
receive = self.hass.helpers.dispatcher.async_dispatcher_connect(
f"{DOMAIN}.{RECEIVE_MESSAGE}", self._async_message_received
receive = async_dispatcher_connect(
self.hass, f"{DOMAIN}.{RECEIVE_MESSAGE}", self._async_message_received
)
self.async_on_remove(receive)
# Setup callback on template changes
Expand Down
4 changes: 2 additions & 2 deletions pybecker/becker_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
)

COMMANDS = {b'0': 'RELEASE', b'1': 'HALT', b'2': 'UP', b'4': 'DOWN', b'8': 'TRAIN'}
COMMUNICATION_TIMEOUT = 0.1
COMMUNICATION_TIMEOUT = 0.3

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -244,7 +244,7 @@ def run(self) -> None:
self._log(packet, "Sent packet: ")

# Sleep for thread switch and wait time between packets
time.sleep(0.01)
time.sleep(0.1)
# Ensure all packets in queue are send before thread is stopped
if self._stop_flag.is_set() and self._write_queue.empty():
break
Expand Down
22 changes: 21 additions & 1 deletion rf_device.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
"""Handling of the Becker USB device."""

import codecs
import logging
import os

import voluptuous as vol
from .pybecker.becker import Becker
from .pybecker.database import FILE_PATH, SQL_DB_FILE

from .const import CONF_CHANNEL, CONF_UNIT, DOMAIN, RECEIVE_MESSAGE
from .const import (
COMMANDS,
CONF_CHANNEL,
CONF_UNIT,
DOMAIN,
RECEIVE_MESSAGE,
REMOTE_PACKET_EVENT,
)

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -93,3 +101,15 @@ def callback(hass, packet):
"""Handle Becker device callback for received packets."""
_LOGGER.debug("Received packet for dispatcher")
hass.helpers.dispatcher.dispatcher_send(f"{DOMAIN}.{RECEIVE_MESSAGE}", packet)

# Also fire an explicit event that external applications can listen to
# if that is of use to them.
data = {
"unit": codecs.decode(packet.group("unit_id"), "ascii"),
"channel": codecs.decode(packet.group("channel"), "ascii"),
}
command = packet.group("command") + b"0"
command_name = [nm for nm, cmd in COMMANDS.items() if cmd == command]
if command_name:
data["command"] = command_name[0]
hass.bus.fire(f"{DOMAIN}_{REMOTE_PACKET_EVENT}", data)

0 comments on commit 330dfa2

Please sign in to comment.