375 lines
11 KiB
C++
375 lines
11 KiB
C++
#include <Homie.h>
|
|
#include <ArduinoOTA.h>
|
|
|
|
//curl -X PUT http://homie.config/config -d @config.json --header "Content-Type: application/json"
|
|
|
|
// homie/ledstoffroehre/lamp/fluorescent0/set
|
|
|
|
#define PIN_LAMP0_EDGE D5
|
|
#define PIN_LAMP0 D6
|
|
#define PIN_LAMP1_EDGE D7
|
|
#define PIN_LAMP1 D8
|
|
#define PIN_SENSOR D0
|
|
|
|
#define PIN_BUTTON0 D2
|
|
#define PIN_BUTTON1 D3
|
|
|
|
//#define FULL 255
|
|
//#define LOWER 50
|
|
//#define MINIMUM 1
|
|
//#define OFF 0
|
|
//int timeout = (1000 - 50);
|
|
|
|
#define FW_NAME "ledstoffroehre"
|
|
#define FW_VERSION "1.0.1"
|
|
|
|
|
|
int lamp0e=0;
|
|
int lamp0=0;
|
|
int lamp1e=0;
|
|
int lamp1=0;
|
|
|
|
long fluorescentLastUpdated=0; //global
|
|
#define FLUORESCENTUPDATEINTERVAL 20
|
|
long fluorescent0LastActivated = 0;
|
|
long fluorescent1LastActivated = 0;
|
|
|
|
int setbrightness0 = 0;
|
|
int setbrightness1 = 0;
|
|
bool fluorescent0Active=false;
|
|
bool fluorescent1Active=false;
|
|
int fluorescent0Quality=50; // 0 to 100
|
|
int fluorescent1Quality=50;
|
|
#define FLUORESCENQUALITYMAX 100
|
|
#define FLUORESCENTTEMPMAX 1000
|
|
int fluorescent0Temp=0;
|
|
int fluorescent1Temp=0;
|
|
#define GLOWBRIGHTNESS 10
|
|
|
|
|
|
int flashprobability0=300; //the higher the lesser
|
|
int flashprobabilitymin0=100; //the higher the lesser (at peak)
|
|
int tempincreasemax0=10; //the higher the faster lightup
|
|
|
|
int flashprobability1=300; //the higher the lesser
|
|
int flashprobabilitymin1=100; //the higher the lesser (at peak)
|
|
int tempincreasemax1=10; //the higher the faster lightup
|
|
|
|
#define FLASHPROBABILITY_MIN 100
|
|
#define FLASHPROBABILITY_MAX 600
|
|
#define FLASHPROBABILITYMIN_MIN 50
|
|
#define FLASHPROBABILITYMIN_MAX 100 //should not be more than FLASHPROBABILITY_MIN
|
|
#define TEMPINCREASEMAX_MIN 1
|
|
#define TEMPINCREASEMAX_MAX FLUORESCENTTEMPMAX/5
|
|
|
|
|
|
bool lastSensorValue = false;
|
|
|
|
HomieNode lightNode("lamp", "lamp");
|
|
HomieNode sensorNode("sensor", "sensor");
|
|
Bounce debouncer = Bounce();
|
|
|
|
Bounce debouncer_btn0 = Bounce();
|
|
Bounce debouncer_btn1 = Bounce();
|
|
|
|
|
|
|
|
bool fluorescentHandler(const HomieRange& range, const String& value) {
|
|
Homie.getLogger() << "fluorescent " << ": " << value << endl;
|
|
lightNode.setProperty("fluorescent").send(value);
|
|
setbrightness0 = value.toInt();
|
|
setbrightness1 = value.toInt();
|
|
fluorescent0Temp=0;
|
|
fluorescent1Temp=0;
|
|
|
|
if (setbrightness0 == 0 || setbrightness1 == 0) { // turned off
|
|
resetLamp0();
|
|
resetLamp1();
|
|
} else { //turned on
|
|
//Initialization
|
|
fluorescent0Active = true; //start effect
|
|
fluorescent1Active = true; //start effect
|
|
}
|
|
output();
|
|
return true;
|
|
}
|
|
bool fluorescent0Handler(const HomieRange& range, const String& value) {
|
|
return fluorescent0Handler_change(value);
|
|
}
|
|
|
|
bool fluorescent0Handler_change(String value){
|
|
Homie.getLogger() << "fluorescent0 " << ": " << value << endl;
|
|
lightNode.setProperty("fluorescent0").send(value);
|
|
setbrightness0 = value.toInt();
|
|
fluorescent0Temp=0;
|
|
|
|
if (setbrightness0 == 0) { // turned off
|
|
resetLamp0();
|
|
} else { //turned on
|
|
//Initialization
|
|
fluorescent0Active = true; //start effect
|
|
}
|
|
output();
|
|
return true;
|
|
}
|
|
bool fluorescent1Handler(const HomieRange& range, const String& value) {
|
|
return fluorescent1Handler_change(value);
|
|
}
|
|
bool fluorescent1Handler_change(String value){
|
|
Homie.getLogger() << "fluorescent1 " << ": " << value << endl;
|
|
lightNode.setProperty("fluorescent1").send(value);
|
|
setbrightness1 = value.toInt();
|
|
fluorescent1Temp=0;
|
|
|
|
if (setbrightness1 == 0) { // turned off
|
|
resetLamp1();
|
|
} else { //turned on
|
|
//Initialization
|
|
fluorescent1Active = true; //start effect
|
|
}
|
|
output();
|
|
return true;
|
|
}
|
|
|
|
|
|
void resetLamp0(){
|
|
fluorescent0Active = false; //set effect off
|
|
fluorescent0LastActivated = millis();
|
|
lamp0e=0;
|
|
lamp0=0;
|
|
float speedpercent=fluorescent0Quality*1.0/FLUORESCENQUALITYMAX;
|
|
flashprobability0=random(FLASHPROBABILITY_MIN,FLASHPROBABILITY_MAX);
|
|
flashprobabilitymin0=random(FLASHPROBABILITYMIN_MIN,FLASHPROBABILITYMIN_MAX);
|
|
tempincreasemax0=TEMPINCREASEMAX_MIN+speedpercent*(TEMPINCREASEMAX_MAX-TEMPINCREASEMAX_MIN);//random(TEMPINCREASEMAX_MIN,TEMPINCREASEMAX_MAX);
|
|
}
|
|
void resetLamp1(){
|
|
fluorescent1Active = false; //set effect off
|
|
fluorescent1LastActivated = millis();
|
|
lamp1e=0;
|
|
lamp1=0;
|
|
float speedpercent=fluorescent1Quality*1.0/FLUORESCENQUALITYMAX;
|
|
flashprobability1=random(FLASHPROBABILITY_MIN,FLASHPROBABILITY_MAX);
|
|
flashprobabilitymin1=random(FLASHPROBABILITYMIN_MIN,FLASHPROBABILITYMIN_MAX);
|
|
tempincreasemax1=TEMPINCREASEMAX_MIN+speedpercent*(TEMPINCREASEMAX_MAX-TEMPINCREASEMAX_MIN);
|
|
}
|
|
|
|
bool fluorescentQualityHandler(const HomieRange& range, const String& value) {
|
|
Homie.getLogger() << "fluorescentAge " << ": " << value << endl;
|
|
fluorescent0Quality = constrain(value.toInt(),0,FLUORESCENQUALITYMAX);
|
|
fluorescent1Quality = constrain(value.toInt(),0,FLUORESCENQUALITYMAX);
|
|
return true;
|
|
}
|
|
bool fluorescent0QualityHandler(const HomieRange& range, const String& value) {
|
|
Homie.getLogger() << "fluorescent0Quality " << ": " << value << endl;
|
|
fluorescent0Quality = constrain(value.toInt(),0,FLUORESCENQUALITYMAX);
|
|
return true;
|
|
}
|
|
bool fluorescent1QualityHandler(const HomieRange& range, const String& value) {
|
|
Homie.getLogger() << "fluorescent1Quality " << ": " << value << endl;
|
|
fluorescent1Quality = constrain(value.toInt(),0,FLUORESCENQUALITYMAX);
|
|
return true;
|
|
}
|
|
|
|
|
|
bool lampHandler(const HomieRange& range, const String& value) {
|
|
Homie.getLogger() << "lamp0,1 " << ": " << value << endl;
|
|
lamp0 = value.toInt();
|
|
lamp0e = value.toInt();
|
|
lamp1 = value.toInt();
|
|
lamp1e = value.toInt();
|
|
lightNode.setProperty("lamp0").send(value);
|
|
lightNode.setProperty("lamp1").send(value);
|
|
fluorescent0Active = false;
|
|
fluorescent1Active = false;
|
|
output();
|
|
return true;
|
|
}
|
|
|
|
bool lamp0Handler(const HomieRange& range, const String& value) {
|
|
Homie.getLogger() << "lamp0 " << ": " << value << endl;
|
|
lamp0 = value.toInt();
|
|
lamp0e = value.toInt();
|
|
lightNode.setProperty("lamp0").send(value);
|
|
fluorescent0Active = false;
|
|
output();
|
|
return true;
|
|
}
|
|
|
|
bool lamp1Handler(const HomieRange& range, const String& value) {
|
|
Homie.getLogger() << "lamp1 " << ": " << value << endl;
|
|
lamp1 = value.toInt();
|
|
lamp1e = value.toInt();
|
|
lightNode.setProperty("lamp1").send(value);
|
|
fluorescent1Active = false;
|
|
output();
|
|
return true;
|
|
}
|
|
|
|
|
|
void output() {
|
|
// * 4 to scale the input up for ESP Arduino default 10 bit PWM
|
|
analogWrite(PIN_LAMP0_EDGE, constrain(lamp0e * 4,0,1023));
|
|
analogWrite(PIN_LAMP0, constrain(lamp0 * 4,0,1023));
|
|
analogWrite(PIN_LAMP1_EDGE, constrain(lamp1e * 4,0,1023));
|
|
analogWrite(PIN_LAMP1, constrain(lamp1 * 4,0,1023));
|
|
}
|
|
|
|
void loopHandler()
|
|
{
|
|
//mosquitto_pub -h raum.ctdo.de -t "homie/ledstoffroehre/lamp/fluorescent0/set" -m "255"
|
|
|
|
|
|
if (millis() > fluorescentLastUpdated + FLUORESCENTUPDATEINTERVAL) { //Update values
|
|
fluorescentLastUpdated = millis();
|
|
|
|
if (fluorescent0Active) {
|
|
//long _time = millis() - fluorescent0LastActivated; //time since activated
|
|
|
|
fluorescent0Temp+=random(1,tempincreasemax0);
|
|
if (random(0,flashprobability0-constrain(fluorescent0Temp*flashprobability0/FLUORESCENTTEMPMAX,0,flashprobability0-flashprobabilitymin0))==0)
|
|
{
|
|
lamp0=setbrightness0*random(30,100)/10;
|
|
lamp0e=lamp0; //flash everything
|
|
}
|
|
lamp0-=40;
|
|
if (random(0,100)>95){
|
|
lamp0e+=constrain(random(0,fluorescent0Temp*10/FLUORESCENTTEMPMAX) , 0, 10); //start glowing slowly
|
|
}
|
|
|
|
if (lamp0e>GLOWBRIGHTNESS)
|
|
{
|
|
lamp0e-=constrain(lamp0e-GLOWBRIGHTNESS,0,20); //make sides darker until glowbrightness
|
|
}
|
|
|
|
if (fluorescent0Temp>=FLUORESCENTTEMPMAX){
|
|
fluorescent0Active=false;
|
|
lamp0=setbrightness0;
|
|
lamp0e=setbrightness0;
|
|
}
|
|
|
|
|
|
lamp0=constrain(lamp0, 0,255);
|
|
lamp0e=constrain(lamp0e, 0,255);
|
|
output();
|
|
}
|
|
|
|
|
|
if (fluorescent1Active) {
|
|
//long _time = millis() - fluorescent0LastActivated; //time since activated
|
|
|
|
fluorescent1Temp+=random(1,tempincreasemax1);
|
|
if (random(0,flashprobability1-constrain(fluorescent1Temp*flashprobability1/FLUORESCENTTEMPMAX,0,flashprobability1-flashprobabilitymin1))==0)
|
|
{
|
|
lamp1=setbrightness1*random(30,100)/10;
|
|
lamp1e=lamp1; //flash everything
|
|
}
|
|
lamp1-=40;
|
|
if (random(0,100)>95){
|
|
lamp1e+=constrain(random(0,fluorescent1Temp*10/FLUORESCENTTEMPMAX) , 0, 10); //start glowing slowly
|
|
}
|
|
|
|
if (lamp1e>GLOWBRIGHTNESS)
|
|
{
|
|
lamp1e-=constrain(lamp1e-GLOWBRIGHTNESS,0,20); //make sides darker until glowbrightness
|
|
}
|
|
|
|
if (fluorescent1Temp>=FLUORESCENTTEMPMAX){
|
|
fluorescent1Active=false;
|
|
lamp1=setbrightness1;
|
|
lamp1e=setbrightness1;
|
|
}
|
|
|
|
|
|
lamp1=constrain(lamp1, 0,255);
|
|
lamp1e=constrain(lamp1e, 0,255);
|
|
output();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool sensorValue = debouncer.read();
|
|
if (Homie.isConfigured() && Homie.isConnected() && sensorValue != lastSensorValue) {
|
|
sensorNode.setProperty("motion").send(sensorValue ? "true" : "false");
|
|
lastSensorValue = sensorValue;
|
|
}
|
|
|
|
bool btn0 = debouncer_btn0.read();
|
|
bool btn1 = debouncer_btn1.read();
|
|
|
|
if (!btn0){
|
|
if (setbrightness0==0){
|
|
fluorescent0Handler_change("255");
|
|
}else{
|
|
fluorescent0Handler_change("0");
|
|
}
|
|
}
|
|
if (!btn1){
|
|
if (setbrightness1==0){
|
|
fluorescent1Handler_change("255");
|
|
}else{
|
|
fluorescent1Handler_change("0");
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void setup() {
|
|
Serial.begin(115200);
|
|
Serial << endl << endl;
|
|
|
|
pinMode(PIN_LAMP0_EDGE, OUTPUT);
|
|
pinMode(PIN_LAMP0, OUTPUT);
|
|
pinMode(PIN_LAMP1_EDGE, OUTPUT);
|
|
pinMode(PIN_LAMP1, OUTPUT);
|
|
|
|
|
|
debouncer_btn0.attach(PIN_BUTTON0, INPUT_PULLUP);
|
|
debouncer_btn0.interval(50);
|
|
debouncer_btn1.attach(PIN_BUTTON1, INPUT_PULLUP);
|
|
debouncer_btn1.interval(50);
|
|
|
|
debouncer.attach(PIN_SENSOR, INPUT);
|
|
debouncer.interval(50);
|
|
|
|
|
|
Homie_setFirmware(FW_NAME, FW_VERSION);
|
|
Homie_setBrand(FW_NAME);
|
|
Homie.setLoopFunction(loopHandler);
|
|
|
|
lightNode.advertise("lamp").settable(lampHandler);
|
|
lightNode.advertise("lamp0").settable(lamp0Handler);
|
|
lightNode.advertise("lamp1").settable(lamp1Handler);
|
|
lightNode.advertise("fluorescent").settable(fluorescentHandler);
|
|
lightNode.advertise("fluorescentquality").settable(fluorescentQualityHandler);
|
|
lightNode.advertise("fluorescent0").settable(fluorescent0Handler);
|
|
lightNode.advertise("fluorescent0Quality").settable(fluorescent0QualityHandler);
|
|
lightNode.advertise("fluorescent1").settable(fluorescent1Handler);
|
|
lightNode.advertise("fluorescent1Quality").settable(fluorescent1QualityHandler);
|
|
|
|
sensorNode.advertise("motion");
|
|
|
|
// Activate other PWM frequency. 1000 (1 KHz) is default
|
|
analogWriteFreq(20000);
|
|
|
|
// Restore last state
|
|
output();
|
|
|
|
Homie.setup();
|
|
|
|
ArduinoOTA.setHostname(Homie.getConfiguration().deviceId);
|
|
ArduinoOTA.begin();
|
|
}
|
|
|
|
void loop() {
|
|
Homie.loop();
|
|
debouncer.update();
|
|
debouncer_btn0.update();
|
|
debouncer_btn1.update();
|
|
ArduinoOTA.handle();
|
|
|
|
|
|
}
|