-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbrel.py
More file actions
94 lines (83 loc) · 2.93 KB
/
Copy pathbrel.py
File metadata and controls
94 lines (83 loc) · 2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/usr/bin/env python3
"""
Brel blind control via RFXtrx433XL
Usage: python3 brel.py [device] [command] [percent]
Devices: screen, rolluik1, rolluik2, all
Commands: up, down, stop, position
Example: python3 brel.py screen position 50
python3 brel.py all up
"""
import serial
import time
import sys
SERIAL_PORT = '/dev/ttyUSB0'
BAUD_RATE = 38400
# ID: 10 20 30, unit codes per device
DEVICES = {
'screen': (0x41, 0x01), # (BlindsT21 unit byte, DDxxxx unit code)
'rolluik1': (0x42, 0x02),
'rolluik2': (0x43, 0x03),
}
def send_blindst21(unit_byte, cmd_byte):
"""Send up/down/stop via BlindsT21 (subtype 0x15)."""
with serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=2) as ser:
ser.flushInput()
packet = bytes([
0x09, 0x19, 0x15, 0x00,
0x10, 0x20, 0x30,
unit_byte,
cmd_byte,
0x00,
])
ser.write(packet)
time.sleep(0.3)
response = ser.read(10)
print(f" → {' '.join(f'{b:02X}' for b in packet)} ACK: {' '.join(f'{b:02X}' for b in response)}")
def send_position(unit_code, percent):
"""Send percentage position via DDxxxx (packet type 0x31)."""
percent = max(0, min(100, int(percent)))
with serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=2) as ser:
ser.flushInput()
packet = bytes([
0x0C, 0x31, 0x00, 0x00,
0x10, 0x20, 0x30, 0x40,
unit_code,
0x04, # percent command
percent,
0x00, 0x00,
])
ser.write(packet)
time.sleep(0.3)
response = ser.read(10)
print(f" → {' '.join(f'{b:02X}' for b in packet)} ACK: {' '.join(f'{b:02X}' for b in response)}")
def run(device, command, percent=None):
targets = list(DEVICES.items()) if device == 'all' else []
if device != 'all':
if device not in DEVICES:
print(f"Unknown device '{device}'. Use: {', '.join(DEVICES.keys())}, all")
sys.exit(1)
targets = [(device, DEVICES[device])]
for name, (unit_byte, unit_code) in targets:
print(f"Sending {command.upper()} to {name}...")
if command == 'up':
send_blindst21(unit_byte, 0x00)
elif command == 'down':
send_blindst21(unit_byte, 0x01)
elif command == 'stop':
send_blindst21(unit_byte, 0x02)
elif command == 'position':
if percent is None:
print("position command requires a percentage value (0-100)")
sys.exit(1)
send_position(unit_code, percent)
else:
print(f"Unknown command '{command}'. Use: up, down, stop, position")
sys.exit(1)
if __name__ == '__main__':
if len(sys.argv) < 3:
print(__doc__)
sys.exit(1)
device = sys.argv[1].lower()
command = sys.argv[2].lower()
percent = sys.argv[3] if len(sys.argv) > 3 else None
run(device, command, percent)