muwerk mupplet Core Library
muwerk applets; mupplets: functional units that support specific hardware or reusable applications
Loading...
Searching...
No Matches
mup_light_pca9685.h
1// light_pca9685.h - muwerk 16 channel light applet using PCA 9685 PWM controller
2#pragma once
3
4#include "muwerk.h"
5#include "mupplet_core.h"
6#include "helper/light_controller.h"
7#include <Adafruit_PWMServoDriver.h>
8
9namespace ustd {
10// clang-format off
57// clang-format on
59 public:
60 static const char *version; // = "0.1.0";
61
62 private:
63 // muwerk task management
64 Scheduler *pSched;
65 int tID;
66
67 // device configuration
68 String name;
69
70 // hardware
71 Adafruit_PWMServoDriver *pPwm;
72 uint8_t addr;
73
74 // runtime
75 LightController light[16];
76 bool activeLogic;
77
78 public:
90 LightsPCA9685(String name, uint8_t addr = 0x40, bool activeLogic = false)
91 : name(name), addr(addr), activeLogic(activeLogic) {
92 }
93
106 void begin(Scheduler *_pSched, TwoWire *_pWire = nullptr, bool initialState = false) {
107 // standard muwerk task initialization
108 pSched = _pSched;
109 tID = pSched->add([this]() { this->loop(); }, name, 80000L);
110
111 // initialize hardware
112 pPwm = new Adafruit_PWMServoDriver(addr, _pWire == nullptr ? Wire : *_pWire);
113 pPwm->begin();
114 pPwm->setPWMFreq(1000);
115
116 // subscribe to light messages and pass to light controller
117 pSched->subscribe(tID, name + "/light/#", [this](String topic, String msg, String orig) {
118 topic = topic.substring(name.length() + 7);
119 int iPos = topic.indexOf('/');
120 if (iPos == -1) {
121 // invalid topic
122 return;
123 }
124 long index = ustd::parseLong(topic.substring(0, iPos), -1);
125 if (index < 0 || index > 15) {
126 // invalid topic
127 return;
128 }
129 this->light[index].commandParser(topic.substring(iPos + 1), msg);
130 });
131
132 // start light controller (register hardware implementation)
133 for (uint8_t channel = 0; channel < 16; channel++) {
134 light[channel].begin(
135 [this, channel](bool state, double level, bool control, bool notify) {
136 this->onLightControl(channel, state, level, control, notify);
137 },
138 initialState);
139 }
140 }
141
146 void set(int8_t channel, bool state) {
147 if (channel < 0) {
148 for (channel = 0; channel < 16; channel++) {
149 light[channel].set(state);
150 }
151 } else if (channel < 16) {
152 light[channel].set(state);
153 }
154 }
155
172 void setMode(int8_t channel, LightController::Mode mode, unsigned int interval_ms = 1000,
173 double phase_unit = 0.0, String pattern = "") {
174 if (channel < 0) {
175 for (channel = 0; channel < 16; channel++) {
176 light[channel].setMode(mode, interval_ms, phase_unit, pattern);
177 }
178 } else if (channel < 16) {
179 light[channel].setMode(mode, interval_ms, phase_unit, pattern);
180 }
181 }
182
191 void setMinMaxWaveBrightness(int8_t channel, double minBrightness, double maxBrightness) {
192 if (channel < 0) {
193 for (channel = 0; channel < 16; channel++) {
194 light[channel].setMinMaxWaveBrightness(minBrightness, maxBrightness);
195 }
196 } else if (channel < 16) {
197 light[channel].setMinMaxWaveBrightness(minBrightness, maxBrightness);
198 }
199 }
200
201#ifdef USTD_FEATURE_HOMEASSISTANT
209 void registerHomeAssistant(HomeAssistant *pHass, String human = "", String icon = "",
210 String attribs = "") {
211 pHass->addMultiLight(name, 16, human, HomeAssistant::LightDim, icon, attribs);
212 }
213
222 void registerHomeAssistant(HomeAssistant *pHass, int channel, String human = "",
223 String icon = "", String attribs = "") {
224 if (channel >= 0 && channel < 16) {
225 pHass->addLight(name, channel, human, HomeAssistant::LightDim, icon, attribs);
226 }
227 }
228#endif
229
230 private:
231 void loop() {
232 for (int channel = 0; channel < 16; channel++) {
233 light[channel].loop();
234 }
235 }
236
237 void onLightControl(uint8_t channel, bool state, double level, bool control, bool notify) {
238 if (control) {
239 uint16_t intensity = level * 4096;
240 if (intensity == 0 || state == false) {
241 // GPIO mode off
242 gpioSet(channel, false);
243 } else if (intensity == 4096) {
244 // GPIO mode on
245 gpioSet(channel, true);
246 } else {
247 // PWM mode
248 pwmSet(channel, intensity);
249 }
250 }
251 if (notify) {
252 pSched->publish(name + "/light/" + String(channel) + "/unitbrightness",
253 String(level, 3));
254 pSched->publish(name + "/light/" + String(channel) + "/state", state ? "on" : "off");
255 }
256 }
257
258 void gpioSet(uint8_t channel, bool on) {
259 if (activeLogic && on) {
260 pPwm->setPWM(channel, 4096, 0);
261 } else if (activeLogic) {
262 pPwm->setPWM(channel, 0, 4096);
263 } else if (on) {
264 pPwm->setPWM(channel, 0, 4096);
265 } else {
266 pPwm->setPWM(channel, 4096, 0);
267 }
268 }
269
270 void pwmSet(uint8_t channel, uint16_t intensity) {
271 if (activeLogic) {
272 pPwm->setPWM(channel, 0, intensity);
273 } else {
274 pPwm->setPWM(channel, 0, 4096 - intensity);
275 }
276 }
277};
278
279const char *LightsPCA9685::version = "0.1.0";
280
281} // namespace ustd
Definition: home_assistant.h:86
@ LightDim
A simple light that can only be switched on and off.
Definition: home_assistant.h:97
void addMultiLight(String name, int count, String human="", DeviceType type=LightDim, String icon="", String attribs="")
Definition: home_assistant.h:422
The Light Controller Class.
Definition: light_controller.h:16
void setMinMaxWaveBrightness(double minBrightness, double maxBrightness)
Definition: light_controller.h:321
void set(bool state)
Definition: light_controller.h:261
bool commandParser(String command, String args)
Definition: light_controller.h:153
void begin(T_CONTROL controller, bool initialState=false)
Definition: light_controller.h:75
void loop()
Definition: light_controller.h:88
Mode
Definition: light_controller.h:19
void setMode(Mode mode, unsigned int interval_ms=1000, double phase_unit=0.0, String pattern="")
Definition: light_controller.h:282
mupplet-core PCA 9685 Light class
Definition: mup_light_pca9685.h:58
void setMinMaxWaveBrightness(int8_t channel, double minBrightness, double maxBrightness)
Definition: mup_light_pca9685.h:191
void begin(Scheduler *_pSched, TwoWire *_pWire=nullptr, bool initialState=false)
Definition: mup_light_pca9685.h:106
LightsPCA9685(String name, uint8_t addr=0x40, bool activeLogic=false)
Definition: mup_light_pca9685.h:90
void setMode(int8_t channel, LightController::Mode mode, unsigned int interval_ms=1000, double phase_unit=0.0, String pattern="")
Definition: mup_light_pca9685.h:172
void set(int8_t channel, bool state)
Definition: mup_light_pca9685.h:146
The muwerk namespace.
Definition: home_assistant.h:10
long parseLong(String arg, long defaultVal)
Definition: mupplet_core.h:101