forked from BioBoost/saito_mqtt_bed_neopixels
-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.py
155 lines (133 loc) · 5.18 KB
/
app.py
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/python
import paho.mqtt.client as mqtt
import time
import json
from jsonschema import validate
from jsonschema import exceptions
from uuid import getnode as get_mac
from lib.neo_pixel_string import *
from random import *
# LED strip configuration:
LED_COUNT = 8 # Number of LED pixels.
LED_PIN = 18 # GPIO pin connected to the pixels (must support PWM!).
BROKER_ADDRESS = "10.0.0.100" # broker.mqttdashboard.com
BROKER_PORT = 1883 # 1883
QOS_STATE_PUBLISH = 1
# At most once (0)
# At least once (1)
# Exactly once (2)
RETAIN_STATE_PUBLISH = True
loopflag = False
animation = 'none'
full_state_schema = {
"type" : "object",
"properties" : {
"state" : {"enum" : ["ON", "OFF"]},
"effect" : {"enum" : ["rainbow", "rainbowcycle", "theaterchaserainbow", "colorwipe", "theaterchase"]},
"brightness" : {"type": "number", "minimum": 0, "maximum": 255 },
"color": {
"type" : "object",
"properties" : {
"r" : {"type": "number", "minimum": 0, "maximum": 255 },
"g" : {"type": "number", "minimum": 0, "maximum": 255 },
"b" : {"type": "number", "minimum": 0, "maximum": 255 }
},
"required": ["r", "g", "b"]
}
}
}
neopixelstring = None
def on_connect(client, userdata, flags, rc):
m = "Connected flags" + str(flags) + "result code " \
+ str(rc) + "client1_id " + str(client)
print(m)
# This is an interface that is compatible with Home Assistant MQTT JSON Light
def on_message_full_state(client, userdata, message):
global json_message, loopflag, animation
json_message = str(message.payload.decode("utf-8"))
print("message received: ", json_message)
try:
data = json.loads(json_message)
validate(data, full_state_schema)
if (data.has_key('state')):
if (data['state'] == 'ON'):
neopixelstring.all_on()
else:
neopixelstring.all_off()
if (data.has_key('brightness')):
neopixelstring.set_brightness(data['brightness'])
if (data.has_key('color')):
# For some reason we need to switch r and g. Don't get it
color = Color(data['color']['g'], data['color']['r'], data['color']['b'])
neopixelstring.set_color(color)
if (data.has_key('effect')):
loopflag = True
if (data['effect'] == 'rainbow'):
animation = 'rainbow'
elif (data['effect'] == 'rainbowcycle'):
animation = 'rainbowcycle'
elif (data['effect'] == 'theaterchaserainbow'):
animation = 'theaterchaserainbow'
elif (data['effect'] == 'colorwipe'):
animation = 'colorwipe'
elif (data['effect'] == 'theaterchase'):
animation = 'theaterchase'
else:
animation = 'none'
loopflag = False
publish_state(client)
except exceptions.ValidationError:
print "Message failed validation"
except ValueError:
print "Invalid json string"
def publish_state(client):
json_state = {
"brightness": neopixelstring.get_brightness(),
"state": "OFF" if neopixelstring.is_off() else "ON",
"color": {
"r": neopixelstring.get_color()['red'],
"g": neopixelstring.get_color()['green'],
"b": neopixelstring.get_color()['blue']
}
}
(status, mid) = client.publish("saito/bed/neopixels", json.dumps(json_state), \
QOS_STATE_PUBLISH, RETAIN_STATE_PUBLISH)
if status != 0:
print("Could not send state")
# Main program logic follows:
if __name__ == '__main__':
neopixelstring = NeoPixelString(LED_COUNT, LED_PIN)
mac = get_mac()
client1 = mqtt.Client(str(mac) + "-python_client")
client1.on_connect = on_connect
# Home Assistant compatible
client1.message_callback_add("saito/bed/neopixels/set", on_message_full_state)
time.sleep(1)
client1.connect(BROKER_ADDRESS, BROKER_PORT)
client1.loop_start()
client1.subscribe("saito/bed/neopixels/set")
justoutofloop = False
print ('Press Ctrl-C to quit.')
while True:
if loopflag and animation != 'none':
justoutofloop = True
if animation == 'rainbow':
neopixelstring.rainbow()
elif (animation == 'rainbowcycle'):
neopixelstring.rainbowCycle()
elif (animation == 'theaterchaserainbow'):
neopixelstring.theaterChaseRainbow()
elif (animation == 'colorwipe'):
neopixelstring.colorWipe(Color(randint(0,255), randint(0,255), randint(0,255)))
elif (animation == 'theaterchase'):
neopixelstring.theaterChase(Color(randint(0,127), randint(0,127), randint(0,127)))
if not loopflag and justoutofloop:
justoutofloop = False
client1.publish("saito/bed/neopixels/set", json_message, 0, False)
time.sleep(.1)
# This should happen but it doesnt because CTRL-C kills process.
# Fix later
print "Disconnecting"
publish_state(client1)
client1.disconnect()
client1.loop_stop()