-
-
Notifications
You must be signed in to change notification settings - Fork 360
Lightbulb
A HomeKit Dimmable Lightbulb service with auto-dimmer managed by external switches/buttons. It can be Single Color, 2-channels selectable temperature color, RGB, RGBW, RGB-CW-WW and RGBW-CW-WW.
The lightbulb service has an automatic dimmer function that will continuously apply the next brightness step, with a delay between each step.
To activate it, ensure that light is on. Then, toggle twice switch or double press button. To stop, press it again once.
To use PWM, hardware must be PWM controlled.
Type | Service Type |
---|---|
30 |
Lightbulb |
The following configuration is available for lightbulbs:
Section | Key | Description |
---|---|---|
Type | "ty" |
Type of lightbulb |
Actions |
"0" , "1" , etc. |
The actions performed by the service |
Binary Inputs | "b" |
GPIOs that invoke specific actions |
State & Status Inputs |
"f[n]" & "g[n]"
|
Inputs that manage service state |
Service Notifications | "m" |
Notifications sent by other services |
Wildcard Actions | "y[n]" |
Perform an action when a service reaches a target value |
Initial Lock State | "ks" |
Lock state at boot |
Initial State | "s" |
State a lightbulb service enters on boot |
GPIOs | "g" |
GPIO pins for colour controls |
NRZ Protocol | "nrz" |
NRZ Protocol to use |
Color Map | "cm" |
Set order of colors for some lightbulb types |
Channels | "n" |
Number of channels |
LED coordinates | "ca" |
XY chromaticity coordinates for each LED |
Flux array | "fa" |
Each channel will be rescaled by the entry in the flux array |
Color matching |
"rgb" & "cmy"
|
To calibrate colors |
White point | "wp" |
Make colors warmer or cooler |
Max power | "mp" |
Limit the maximum LED usage |
Curve factor | "cf" |
|
Initial values | "it" |
Brightness, hue and saturation values used at boot |
Colour Transition Step | "st" |
Colour step value |
Automatic Dimmer Step Delay | "d" |
Dimmer step delay |
Automatic Dimmer Step | "e" |
Dimmer step value |
Service Characteristics |
Software PWM.
{
"c":{"q":500,"io":[[[15,13,12],7],[[0],6]],"b":[[0,5]]},
"a":[{
"t":30,
"g":[15,13,12],
"b":[[0]]
}]
}
This is an example of a RGB Lightbulb ("t":30
).
The PWM frequency has been set to 500Hz ("q":500
) in the general configuration.
The GPIO lines for the red, green & blue lights are 15, 13 & 12 respectively ("g":[15,13,12]
).
The on/off button is connected to GPIO 0 ("b":[{"g":0}]
).
Rotary Encoder to control brightness.
{
"c":{
"io":[[[12],6],[[4,5],6,0,0,1]],
"z":0,"b":[[12,5]]
},
"a":[
{"t":30,"b":[[12]]},
{"h":0,"i":0.2,"1":{"m":[[7001,-10000],[7003,1],[7003,-1],[1,305]]},"f1":[[4,0]]},
{"h":0,"i":0.2,"1":{"m":[[-1,-10000],[7001,1],[7001,-1],[1,605]]},"f1":[[5,0]]},
{"h":0,"i":0.4,"0":{"m":[[-2,-10001]]}},
{"h":0,"i":0.4,"0":{"m":[[-2,-10001]]}}
]
}
This is an example of a rotary encoder managing a Virtual Lightbulb ("t":30
).
The on/off button is connected to GPIO 12.
Rotary encoder pins are connected to GPIOs 4 and 5.
It defines type of lightbulb based on hardware to use.
Key | Value | Description |
---|---|---|
"ty" |
0 |
Virtual lightbulb, without any hardware management. Default channels: 1 |
1 |
Standard PWM system. Default channels: number of GPIOs. | |
2 |
2 Channels PWM. One to manage brightness and other temperature color. Default channels: 2 | |
8 |
NRZ Protocol. Default channels: 3. |
Action | State | Description |
---|---|---|
"0" |
Off | The default action after boot unless the Initial State has been set |
"1" |
On |
A lightbulb has two actions. The Binary Outputs
"r": [ ]
for each should be configured to attain the desired state.
Depending on the lightbulb type connected to the device you will need to define the GPIO channels to control it. Available channels must be in a array.
Remember to declare used GPIOs as PWM Output into "io":[...]
array. See GPIOs Configuration
The rules for setting these channels with a PWM Lightbulb type are as follows:
Colours | Rule |
---|---|
Single | "g": [ W ] |
Two Colour | "g": [ CW, WW ] |
RGB | "g": [ R, G, B ] |
RGBW | "g": [ R, G, B, W ] |
RGB-CW-WW | "g": [ R, G, B, CW, WW ] |
NOTE: A two colour light is a light with 2 channels to enable a colour temperature
Mixing up this order will result in anomalous colors, so first verify these are correct.
NRZ Protocol type uses declaration as follow:
Array |
---|
"g": [ GPIO, First LED of range, Last LED of range ] |
Different NRZ Lightbulbs can be declared using same GPIO but different LED ranges.
There are some hardware limitations of number of GPIOs that can be used as NRZ output, depending of used SoC. For ESP32, ESP32C AND ESP32S, check official datasheets to know more details about RMT peripheral, used by HAA NRZ:
Chip | Max Different GPIOs |
---|---|
ESP8266 | No limit (RavenSystem's Software driver) |
ESP32 | 8 |
ESP32S2 | 4 |
ESP32S3 | 4 |
ESP32C2 | 0 (NRZ is not supported) |
ESP32C3 | 2 |
ESP32C6 | 2 |
When NRZ Lightbulb type is selected, a NRZ Protocol must be defined. This protocol uses different times of pulses to manage an array of LEDs. By default, NRZ Protocol uses WS2812b at 800MHz times, but any other protocol times can be used.
Used GPIOs must not be into "io":[...]
array.
Times are available in datasheet of each LED type. Needed vales are T0H
, T1H
and T0L
, and must be in us (microseconds).
If several lightbulbs with NRZ Protocol and same GPIO are declared, "nrz"
array must be declare only once, in one of them.
Format and some of them are:
Protocol | Array |
---|---|
"nrz" : [ T0H, T1H, T0L ] |
|
WS2812B 800Mhz |
"nrz" : [ 0.4, 0.8, 0.85 ] Default
|
WS2811 Slow | "nrz" : [ 0.5, 1.2, 2 ] |
WS2811 Fast | "nrz" : [ 0.25, 0.6, 1 ] |
WS2812 | "nrz" : [ 0.35, 0.7, 0.9 ] |
WS2812B 400MHz | "nrz" : [ 0.8, 1.6, 1.7 ] |
WS2812B V2 | "nrz" : [ 0.4, 0.85, 0.85 ] |
WS2812B V3 | "nrz" : [ 0.35, 0.9, 0.9 ] |
WS2813 | "nrz" : [ 0.22, 0.58, 1.03 ] |
WS2815 | "nrz" : [ 0.22, 0.75, 0.75 ] |
SK6812 | "nrz" : [ 0.3, 0.6, 0.9 ] |
A WS2812B 800MHz RGB LED strip with a total of 20 LEDs attached to GPIO 5:
{
"a":[{
"t":30,
"ty":8,
"g":[5,1,20]
}]
}
A SK6812 RGBW LED strip configured in 3 segments (5, 10 and 5 LEDs) attached to GPIO 5:
{
"a":[{
"t":30,
"ty":8,
"n":4,
"nrz":[0.3,0.6,0.9],
"g":[5,1,5],
"es":[{
"t":30,
"ty":8,
"n":4,
"g":[5,6,15]
},{
"t":30,
"ty":8,
"n":4,
"g":[5,16,20]
}]
}]
}
Used by NRZ Protocol Lightbulb to swap channels.
Definitions are:
-
0
: Red -
1
: Green -
2
: Blue -
3
: Cool white -
4
: Warm white
By default, "cm" : [ 1, 0, 2, 3, 4 ]
is used, meaning that LED order is GRB (default for WS2812B 800MHz).
Declare each color in right order.
It is possible to set number of channels manually.
Key | Value | Description |
---|---|---|
"n" |
1 |
Single channel. Only brightness is managed. (default) |
2 |
Dual channel. To manage colour temperature | |
3 |
Full color RGB | |
4 |
Full color RGBW | |
5 |
Full color RGB-CW-WW |
The new color mixing function created by Kevin Cutler (@kevinjohncutler) at https://github.com/kevinjohncutler/colormixing supports RGB, RGBW, and RGB-CW-WW, and by default it maximizes brightness and stretches the sRGB color gamut to fill the gamut of your LEDs, meaning that that colors are as saturated as possible. The defaults in HAA work well for typical LED strips, but there are a number of ways to get your bulbs looking just right. Logs are suggested. Throughout this guide we will refer to ‘chromaticity coordinates’, meaning the tuple [x,y]
in the CIE xyY color space corresponding to a unique color.
Attempt to get the ‘spectrum test report’ for your bulbs. This will give the xy chromaticity coordinates for each LED, and you can put this into your MEPLHAA script as the coordinate array "ca"
:
Type | Format |
---|---|
RGB | "ca": [ rx, ry, gx, gy, bx, by ] |
RGBW | "ca": [ rx, ry, gx, gy, bx, by, wx, wy] |
RGB-CW-WW | "ca": [ rx, ry, gx, gy, bx, by, cwx, cwy, wwx, wwy ] |
The reports collected so far show that typical bulbs and strips have very similar reds and blues, with he most variation being in green and warm white. If you cannot get the test report, then you can continue to the next steps and still get good results.
Internal color calculations assume the brightness of each channel is the same, but this is never true, especially for lightbulbs, which will have many more white LEDs than RGB LEDs. Each channel will be rescaled by the entry in the flux array. The MEPLHAA script syntax is
Type | Format |
---|---|
W | "fa": [ W ] |
CW-WW | "fa": [ CW, WW ] |
RGB | "fa": [ R, G, B ] |
RGBW | "fa": [ R, G, B, W ] |
RGB-CW-WW | "fa": [ R, G, B, CW, WW ] |
For example, an RGB-CW-WW bulb with 4 RGB modules, 12 CW modules, and 14 WW modules should be "fa": [ 4, 4, 4, 12, 14 ]
. This is equivalent to "fa": [ 2, 2, 2, 6, 7 ]
. These numbers can be changed further to reflect differences in intrinsic LED flux as well (white LEDS are usually brighter than RGB, and the green LED may be brighter than the red etc.). Since channel outputs are divided by the flux array, this will lead to more accurate but less bright colors.
The current software enables users to set the act chromaticity coordinates to which the following Siri colors correspond: red, green, blue, cyan, magenta, and yellow. By default, red, green, and blue are mapped to the LED coordinates so that you will see the purest red, green, and blue that your hardware can make (that is, only one color LED is turned on). Cyan (the same as Siri teal), magenta (the same as Siri purple), and yellow are much more likely to look off, so there are two separate arrays:
"rgb": [ rx, ry, gx, gy, bx, by ]
"cmy": [ cx, cy, mx, my, yx, yy ]
To calibrate your lights, enable logs and tell Siri to set the light cyan. Adjust this in the Home app until you get a color that you think looks the most ‘cyan’ to you. The logs will show a "new chromaticity" every time you change a color, and once you found one you like, write it down to use as [ cx, cy ]
. Do the same for magenta and yellow. Once the CMY array is in your MEPLHAA script, the bulb will now perfectly reproduce the cyan, magenta, and yellow that you chose, which should also improve the look of interpolated colors (such as orange).
The D50 standard illuminant is the default, but you can change this to make your colors warmer or cooler. For example, standard illuminant A Is a lot warmer and will shift all your whites towards the warm end of the Planckian locus. Refer to the table here for a list of standard illuminates to try. The MEPLHAA script syntax is "wp": [ wx, wy ]
.
Table: TO-DO
This variable is between 0 and 1 and can be used to limit the maximum LED usage to prevent overheating (though it seems like lower PWM has fixed that).
Key | Value | Description |
---|---|---|
"mp" |
1.00 |
(default) |
0.01 to 1
|
Total factor applied to each PWM channel value |
If you wish to keep your whites as bright as possible but also subdue the white LEDs for better pastels, this may be for you. This curve factor is the parameter "a" in the ‘power curve’ function 1-(exp(ax)-1)/(exp(a)-1), where x is the saturation in the range (0,1). The syntax is "cf":#
, and typical ranges would be between -5 and 5. Negative values suppress the white LEDs and positive values keep them turned on (relative to how they are to begin with), so start with something like "cf":-1 if you want to play with it. While 0 technically corresponds to a linear power curve, I use this case to turn off the power curve altogether. If you want something close to linear, use "cf":0.1
.
By default, lightbulb service will load last brightness, hue and saturation
used values. To set initial BRI, HUE and SAT at boot, "it:"
key is used.
- 1 channel:
"it": [ BRI ]
- 2 channels:
"it": [ BRI, TEMP ]
- 3+ channels:
"it": [ BRI, HUE, SAT ]
Colour transition step is defined by the "st"
key contained within the
service object.
Key | Value | Description |
---|---|---|
"st" |
2048 |
Step the colour transition value by 2048 (default)
|
1 to 65535
|
Step value to apply to colour transitions |
The "st"
option defines the colour step value. This is the increment that will
be applied to a colour value each time a step is requested, each 20ms.
Automatic dimmer step delay is defined by the "d"
key contained within the
service object.
Key | Value | Description |
---|---|---|
"d" |
1.00 |
Delay between dimmer steps is 1 second (default) |
0.01 to 65.50
|
Delay to apply between each step when dimming |
This option specifies the delay in seconds to apply between each automatic dimmer step.
The option uses is a floating point value, accurate to 2 decimal places e.g. 1.14
Automatic dimmer step is defined by the "e"
key contained within the
service object.
Key | Value | Description |
---|---|---|
"e" |
20 |
Automatically step the dimmer brightness by 20% (default) |
1 to 100
|
Brightness percentage step to apply when dimming | |
0 |
Disable feature |
This option defines the brightness step percentage that will be applied to each automatic dimmer step.
A value of 0
will disable Automatic dimmer feature.
The list of notifications "m"
supported by a lightbulb are as follows:
Value | Notification |
---|---|
0 |
Switch is OFF (default) |
1 |
Switch is ON |
2 to 102
|
Change brightness from 0 to 100. Final value will be value - 2 . |
301 to 400
|
Reduce brightness from 1 to 100. Final value will be value - 300 . |
601 to 700
|
Increase brightness from 1 to 100. Final value will be value - 600 . |
1000 to 1360
|
Change hue from 0 to 360. Final value will be value - 1000 . |
2000 to 2100
|
Change saturation from 0 to 100. Final value will be value - 2000 . |
3050 to 3400
|
Change color temperature from 50 to 400. Final value will be value - 3000 . |
-1 |
Start autodimmer |
-2 |
Stop autodimmer |
Service notifications can be included as part of an action definition.
When an action occurs any one of the above notifications can be sent to
another service using the "m"
option within the action object.
See the general Service Notifications section for details of how to configure these notifications.
Binary Inputs "b"
are supported by this service.
See Binary Inputs for details on how to define this mandatory option.
State inputs "f[n]"
& Status Inputs "g[n]"
are supported by this service.
The supported list is:
Key | Required State |
---|---|
"f0" |
Lightbulb off |
"f1" |
Lightbulb on |
"f2" |
Increase brightness by 10% |
"f3" |
Decrease brightness by 10% |
Refer to State Inputs for more detail and examples.
ICMP Ping inputs "p[n]"
and "q[n]"
are supported by this service.
Refer to ICMP Ping Inputs for
more detail.
Wildcard Actions "y[n]"
are supported by this service.
The supported list is:
Key | Action |
---|---|
"y0" |
Trigger action when lightbulb reaches a specific brightness |
The brightness is expressed as a percentage e.g. if you want to trigger a
wildcard action when a lightbulb reaches 20% brightness then use
{"y0": [{"v":20, "0":{...}}]}
Refer to Wildcard Actions for more detail.
The Initial Lock State about Service and Physical controls.
Key | Value | Notification |
---|---|---|
"ks" |
0 |
All locked |
1 |
Service unlocked. Physical controls locked | |
2 |
Service locked. Physical controls unlocked | |
3 |
All unlocked (default) |
The Initial State key is supported by this service. Refer to Initial State for details of the available values.
Characteristic | Description |
---|---|
0 |
On / Off |
1 |
Brightness |
2 |
Hue or Color temperature |
3 |
Saturation |
Home Accessory Architect
Home Accessory
Installation
Setup Mode
HAA Home Manager App
Configuration
About
General
| GPIOs Configuration
Accessory
| Actions
Service Types
Air Quality
Battery
Data History
Fan
Free Monitor
Garage Door
HAA iAirZoning
Heater Cooler
Humidifier
Light Sensor
Lightbulb
Lock Mechanism
Sensors
Power Measure
Security System
Stateless Button & Doorbell
Switch & Outlet
Temperature & Humidity
TV
Water Valve
Window Covering