Skip to content

Commit e543fc2

Browse files
committed
victory. now python can talk to cbus. helps when my panel is programmed with group addresses
1 parent afeb6ba commit e543fc2

File tree

1 file changed

+54
-5
lines changed

1 file changed

+54
-5
lines changed

libcbus.py

+54-5
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@
22
import struct
33
from serial import Serial
44

5+
END_COMMAND = '\r\n'
6+
57
# command types
6-
POINT_TO_MULTIPOINT = '\\05'
8+
POINT_TO_MULTIPOINT = '~\\05'
79

810
# Applications
911
APP_LIGHTING = '38'
1012

1113
# Routing buffer
1214
ROUTING_NONE = '00'
1315

14-
16+
LIGHT_ON = '79'
17+
LIGHT_OFF = '01'
1518
# light on
1619
#\0538007964 (GA 100)
1720

@@ -21,6 +24,26 @@
2124
# set to level
2225
#\053800rr64FF (GA 100, to level 100%/0xff)
2326

27+
RAMP_RATES = {
28+
'02': 0,
29+
'0A': 4,
30+
'12': 8,
31+
'1A': 12,
32+
'22': 20,
33+
'2A': 30,
34+
'32': 40,
35+
'3A': 60,
36+
'42': 90,
37+
'4A': 120,
38+
'52': 180,
39+
'5A': 300,
40+
'62': 420,
41+
'6A': 600,
42+
'72': 900,
43+
'7A': 1020
44+
}
45+
46+
2447
def duration_to_ramp_rate(seconds):
2548
if seconds == 0:
2649
return '02'
@@ -56,15 +79,41 @@ def duration_to_ramp_rate(seconds):
5679
return '7A'
5780
raise OutOfRangeException, 'That duration is too long'
5881

82+
def ramp_rate_to_duration(rate):
83+
assert len(rate) == 2, "Ramp rate must be two characters."
84+
rate = rate.upper()
85+
return RAMP_RATES[rate]
86+
87+
def cbus_checksum(input):
88+
"Calculates the checksum of a C-Bus command string."
89+
if input[0] == '\\':
90+
input = input[1:]
91+
92+
input = input.decode('base16')
93+
c = 0
94+
for x in input:
95+
c += ord(x)
96+
97+
return ((c % 256) ^ 256) + 1
5998

6099
class CBusPCISerial(object):
61100
def __init__(self, device):
62101
self.s = Serial(device, 9600)
63102
self.reset()
64103

65104
def reset(self):
66-
# reset the PCI
67-
self.s.write('~')
105+
# reset the PCI, enable MMI reports so we know when buttons are pressed.
106+
# (mmi is actually disabled, 59g vs 79g
107+
self.write('~~~\r\nA3210038g\r\nA3420002g\r\nA3300059g\r\n')
68108

109+
def write(self, msg):
110+
print "Message = %r" % msg
111+
self.s.write(msg)
69112

70-
113+
def lighting_group_on(self, group_id):
114+
# TODO: Implement checksumming
115+
self.write(POINT_TO_MULTIPOINT + APP_LIGHTING + ROUTING_NONE + LIGHT_ON + ('%02X' % group_id) + 'g' + END_COMMAND)
116+
117+
def lighting_group_off(self, group_id):
118+
# TODO: Implement checksumming
119+
self.write(POINT_TO_MULTIPOINT + APP_LIGHTING + ROUTING_NONE + LIGHT_OFF + ('%02X' % group_id) + 'g' + END_COMMAND)

0 commit comments

Comments
 (0)