power: add RF transmitter support

Signed-off: Daniel Bauer <github@dbauer.me>
This commit is contained in:
danijoo 2021-10-01 07:45:15 +01:00 committed by Eric Callahan
parent 86764657cf
commit c3f1b290f8
2 changed files with 61 additions and 6 deletions

View File

@ -190,7 +190,7 @@ gcode:
```
## `[power]`
Enables device power control. Currently GPIO (relays), TPLink Smartplug,
Enables device power control. Currently GPIO (relays), RF transmitter, TPLink Smartplug,
and Tasmota (via http) devices, HomeAssistant switch are supported.
```ini
@ -198,7 +198,7 @@ and Tasmota (via http) devices, HomeAssistant switch are supported.
[power device_name]
type: gpio
# The type of device. Can be either gpio, tplink_smartplug, tasmota
# The type of device. Can be either gpio, rf, tplink_smartplug, tasmota
# shelly, homeseer, homeassistant, or loxonev1.
# This parameter must be provided.
off_when_shutdown: False
@ -217,7 +217,7 @@ restart_delay: 1.
# If "restart_klipper_when_powered" is set, this option specifies the amount
# of time (in seconds) to delay the restart. Default is 1 second.
pin: gpiochip0/gpio26
# The pin to use for GPIO devices. The chip is optional, if left out
# The pin to use for GPIO and RF devices. The chip is optional, if left out
# then the module will default to gpiochip0. If one wishes to invert
# the signal, a "!" may be prefixed to the pin. Valid examples:
# gpiochip0/gpio26
@ -297,6 +297,12 @@ output_id:
# The output_id is the name of a programmed output, virtual input or virtual
# output in the loxone config his output_id (name) may only be used once in
# the loxone config
on_code:
off_code:
# The above options are used for "rf" devices. The
# codes should be valid binary codes that are send via the RF transmitter.
# For example: 1011.
```
Below are some potential examples:
```ini

View File

@ -12,6 +12,7 @@ import json
import struct
import socket
import asyncio
import time
from tornado.iostream import IOStream
from tornado.httpclient import AsyncHTTPClient
from tornado.escape import json_decode
@ -68,7 +69,8 @@ class PrinterPower:
"shelly": Shelly,
"homeseer": HomeSeer,
"homeassistant": HomeAssistant,
"loxonev1": Loxonev1
"loxonev1": Loxonev1,
"rf": RFDevice
}
try:
for section in prefix_sections:
@ -79,7 +81,7 @@ class PrinterPower:
if dev_class is None:
raise config.error(f"Unsupported Device Type: {dev_type}")
dev = dev_class(cfg)
if isinstance(dev, GpioDevice):
if isinstance(dev, GpioDevice) or isinstance(dev, RFDevice):
if not HAS_GPIOD:
continue
dev.configure_line(cfg, self.chip_factory)
@ -470,6 +472,53 @@ class GpioDevice(PowerDevice):
def close(self) -> None:
self.line.release()
class RFDevice(GpioDevice):
# Protocol definition
# [1, 3] means HIGH is set for 1x pulse_len and LOW for 3x pulse_len
ZERO_BIT = [1, 3] # zero bit
ONE_BIT = [3, 1] # one bit
SYNC_BIT = [1, 31] # sync between
PULSE_LEN = 0.00035 # length of a single pulse
RETRIES = 10 # send the code this many times
def __init__(self, config: ConfigHelper):
super().__init__(config)
self.on = config.get("on_code").zfill(24)
self.off = config.get("off_code").zfill(24)
def initialize(self) -> None:
self.set_power("on" if self.initial_state else "off")
def _transmit_digit(self, waveform) -> None:
self.line.set_value(1)
time.sleep(waveform[0]*RFDevice.PULSE_LEN)
self.line.set_value(0)
time.sleep(waveform[1]*RFDevice.PULSE_LEN)
def _transmit_code(self, code) -> None:
for _ in range(RFDevice.RETRIES):
for i in code:
if i == "1":
self._transmit_digit(RFDevice.ONE_BIT)
elif i == "0":
self._transmit_digit(RFDevice.ZERO_BIT)
self._transmit_digit(RFDevice.SYNC_BIT)
def set_power(self, state) -> None:
try:
if state == "on":
code = self.on
else:
code = self.off
self._transmit_code(code)
except Exception:
self.state = "error"
msg = f"Error Toggling Device Power: {self.name}"
logging.exception(msg)
raise self.server.error(msg) from None
self.state = state
# This implementation based off the work tplink_smartplug
# script by Lubomir Stroetmann available at: