forked from ikalchev/HAP-python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNeoPixelLightStrip.py
158 lines (129 loc) · 5.22 KB
/
NeoPixelLightStrip.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
156
157
158
"""
An Accessory for Adafruit NeoPixels attached to GPIO Pin18
Tested using Python 3.5/3.6 Raspberry Pi
This device uses all available services for the Homekit Lightbulb API
Note: RPi GPIO must be PWM. Neopixels.py will warn if wrong GPIO is used
at runtime
Note: This Class requires the installation of rpi_ws281x lib
Follow the instllation instructions;
git clone https://github.com/jgarff/rpi_ws281x.git
cd rpi_ws281x
scons
cd python
sudo python3.6 setup.py install
https://learn.adafruit.com/neopixels-on-raspberry-pi/software
Apple Homekit API Call Order
User changes light settings on iOS device
Changing Brightness - State - Hue - Brightness
Changing Color - Saturation - Hue
Changing Temp/Sat - Saturation - Hue
Changing State - State
"""
from neopixel import *
from pyhap.accessory import Accessory
from pyhap.const import CATEGORY_LIGHTBULB
class NeoPixelLightStrip(Accessory):
category = CATEGORY_LIGHTBULB
def __init__(self, LED_count, is_GRB, LED_pin,
LED_freq_hz, LED_DMA, LED_brightness,
LED_invert, *args, **kwargs):
"""
LED_Count - the number of LEDs in the array
is_GRB - most neopixels are GRB format - Normal:True
LED_pin - must be PWM pin 18 - Normal:18
LED_freq_hz - frequency of the neopixel leds - Normal:800000
LED_DMA - Normal:10
LED_Brightness - overall brightness - Normal:255
LED_invert - Normal:False
For more information regarding these settings
please review rpi_ws281x source code
"""
super().__init__(*args, **kwargs)
# Set our neopixel API services up using Lightbulb base
serv_light = self.add_preload_service(
'Lightbulb', chars=['On', 'Hue', 'Saturation', 'Brightness'])
# Configure our callbacks
self.char_hue = serv_light.configure_char(
'Hue', setter_callback=self.set_hue)
self.char_saturation = serv_light.configure_char(
'Saturation', setter_callback=self.set_saturation)
self.char_on = serv_light.configure_char(
'On', setter_callback=self.set_state)
self.char_on = serv_light.configure_char(
'Brightness', setter_callback=self.set_brightness)
# Set our instance variables
self.accessory_state = 0 # State of the neo light On/Off
self.hue = 0 # Hue Value 0 - 360 Homekit API
self.saturation = 100 # Saturation Values 0 - 100 Homekit API
self.brightness = 100 # Brightness value 0 - 100 Homekit API
self.is_GRB = is_GRB # Most neopixels are Green Red Blue
self.LED_count = LED_count
self.neo_strip = Adafruit_NeoPixel(LED_count, LED_pin, LED_freq_hz,
LED_DMA, LED_invert, LED_brightness)
self.neo_strip.begin()
def set_state(self, value):
self.accessory_state = value
if value == 1: # On
self.set_hue(self.hue)
else:
self.update_neopixel_with_color(0, 0, 0) # Off
def set_hue(self, value):
# Lets only write the new RGB values if the power is on
# otherwise update the hue value only
if self.accessory_state == 1:
self.hue = value
rgb_tuple = self.hsv_to_rgb(
self.hue, self.saturation, self.brightness)
if len(rgb_tuple) == 3:
self.update_neopixel_with_color(
rgb_tuple[0], rgb_tuple[1], rgb_tuple[2])
else:
self.hue = value
def set_brightness(self, value):
self.brightness = value
self.set_hue(self.hue)
def set_saturation(self, value):
self.saturation = value
self.set_hue(self.hue)
def update_neopixel_with_color(self, red, green, blue):
for i in range(self.LED_count):
if(self.is_GRB):
self.neo_strip.setPixelColor(i, Color(int(green),
int(red),
int(blue)))
else:
self.neo_strip.setPixelColor(i, Color(int(red),
int(green),
int(blue)))
self.neo_strip.show()
def hsv_to_rgb(self, h, s, v):
"""
This function takes
h - 0 - 360 Deg
s - 0 - 100 %
v - 0 - 100 %
"""
hPri = h / 60
s = s / 100
v = v / 100
if s <= 0.0:
return int(0), int(0), int(0)
C = v * s # Chroma
X = C * (1 - abs(hPri % 2 - 1))
RGB_Pri = [0.0, 0.0, 0.0]
if 0 <= hPri <= 1:
RGB_Pri = [C, X, 0]
elif 1 <= hPri <= 2:
RGB_Pri = [X, C, 0]
elif 2 <= hPri <= 3:
RGB_Pri = [0, C, X]
elif 3 <= hPri <= 4:
RGB_Pri = [0, X, C]
elif 4 <= hPri <= 5:
RGB_Pri = [X, 0, C]
elif 5 <= hPri <= 6:
RGB_Pri = [C, 0, X]
else:
RGB_Pri = [0, 0, 0]
m = v - C
return int((RGB_Pri[0] + m) * 255), int((RGB_Pri[1] + m) * 255), int((RGB_Pri[2] + m) * 255)