Skip to content

Commit 533ce77

Browse files
committed
Add Magic Light support
1 parent 3240b53 commit 533ce77

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed

adafruit_ble/services/magic_light.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# The MIT License (MIT)
2+
#
3+
# Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
4+
#
5+
# Permission is hereby granted, free of charge, to any person obtaining a copy
6+
# of this software and associated documentation files (the "Software"), to deal
7+
# in the Software without restriction, including without limitation the rights
8+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
# copies of the Software, and to permit persons to whom the Software is
10+
# furnished to do so, subject to the following conditions:
11+
#
12+
# The above copyright notice and this permission notice shall be included in
13+
# all copies or substantial portions of the Software.
14+
#
15+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
# THE SOFTWARE.
22+
"""
23+
:py:mod:`~adafruit_ble.services.magic_light`
24+
====================================================
25+
26+
This module provides Services available on a Magic Light, BLE RGB light bulb.
27+
28+
"""
29+
30+
from . import Service
31+
from ..uuid import VendorUUID
32+
from ..characteristics import Characteristic
33+
34+
__version__ = "0.0.0-auto.0"
35+
36+
class MagicLightService(Service):
37+
# These UUIDs actually use the standard base UUID even though they aren't standard.
38+
uuid = VendorUUID("0000ffe5-0000-1000-8000-00805f9b34fb")
39+
40+
_control = Characteristic(uuid=VendorUUID("0000ffe9-0000-1000-8000-00805f9b34fb"), max_length=7)
41+
42+
def __init__(self, service=None):
43+
super().__init__(service=service)
44+
self._color = 0xffffff
45+
self._buf = bytearray(7)
46+
self._buf[0] = 0x56
47+
self._buf[6] = 0xaa
48+
self._brightness = 1.0
49+
50+
def __getitem__(self, index):
51+
if index > 0:
52+
raise IndexError()
53+
return self._color
54+
55+
def __setitem__(self, index, value):
56+
if index > 0:
57+
raise IndexError()
58+
if isinstance(value, int):
59+
r = (value >> 16) & 0xff
60+
g = (value >> 8) & 0xff
61+
b = value & 0xff
62+
else:
63+
r, g, b = value
64+
self._buf[1] = r
65+
self._buf[2] = g
66+
self._buf[3] = b
67+
self._buf[4] = 0x00
68+
self._buf[5] = 0xf0
69+
self._control = self._buf
70+
self._color = value
71+
72+
def __len__(self):
73+
return 1
74+
75+
# Brightness doesn't preserve the color so comment it out for now. There are many other
76+
# characteristics to try that may.
77+
# @property
78+
# def brightness(self):
79+
# return self._brightness
80+
#
81+
# @brightness.setter
82+
# def brightness(self, value):
83+
# for i in range(3):
84+
# self._buf[i + 1] = 0x00
85+
# self._buf[4] = int(0xff * value)
86+
# self._buf[5] = 0x0f
87+
# self._control = self._buf
88+
# self._brightness = value

examples/ble_magic_light.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
"""This demo connects to a magic light and has it do a color wheel."""
2+
import adafruit_ble
3+
import _bleio
4+
import time
5+
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
6+
from adafruit_ble.services.magic_light import MagicLightService
7+
8+
def find_connection():
9+
for connection in radio.connections:
10+
if MagicLightService not in connection:
11+
continue
12+
return connection, connection[MagicLightService]
13+
return None, None
14+
15+
# Start advertising before messing with the display so that we can connect immediately.
16+
radio = adafruit_ble.BLERadio()
17+
18+
def wheel(pos):
19+
# Input a value 0 to 255 to get a color value.
20+
# The colours are a transition r - g - b - back to r.
21+
if pos < 0 or pos > 255:
22+
return (0, 0, 0)
23+
if pos < 85:
24+
return (255 - pos * 3, pos * 3, 0)
25+
if pos < 170:
26+
pos -= 85
27+
return (0, 255 - pos * 3, pos * 3)
28+
pos -= 170
29+
return (pos * 3, 0, 255 - pos * 3)
30+
31+
active_connection, pixels = find_connection()
32+
current_notification = None
33+
app_icon_file = None
34+
while True:
35+
if not active_connection:
36+
print("Scanning for Magic Light")
37+
for scan in radio.start_scan(ProvideServicesAdvertisement):
38+
if MagicLightService in scan.services:
39+
active_connection = radio.connect(scan)
40+
try:
41+
pixels = active_connection[MagicLightService]
42+
except _bleio.ConnectionError:
43+
print("disconnected")
44+
continue
45+
break
46+
radio.stop_scan()
47+
48+
i = 0
49+
while active_connection.connected:
50+
pixels[0] = wheel(i % 256)
51+
i += 1
52+
53+
active_connection = None

0 commit comments

Comments
 (0)