Added dynamic handling of the on/off buttons of the lights. Added a graph which shows the current timing control data.
This commit is contained in:
parent
b553db6206
commit
fb98d1c28b
2 changed files with 290 additions and 240 deletions
|
@ -10,12 +10,12 @@
|
|||
|
||||
//********* Config block *********//
|
||||
|
||||
uint8_t pins[LIGHTS_COUNT] = {12, 15, 13, 14};
|
||||
uint8_t pins[LIGHTS_COUNT] = { 12, 15, 13, 14 };
|
||||
|
||||
IPAddress strip_ip ( 192, 168, 0, 26); // choose an unique IP Adress
|
||||
IPAddress gateway_ip ( 192, 168, 0, 1); // Router IP
|
||||
IPAddress subnet_mask( 255, 255, 255, 0);
|
||||
IPAddress dns ( 192, 168, 0, 1);
|
||||
IPAddress strip_ip(192, 168, 0, 26); // choose an unique IP Adress
|
||||
IPAddress gateway_ip(192, 168, 0, 1); // Router IP
|
||||
IPAddress subnet_mask(255, 255, 255, 0);
|
||||
IPAddress dns(192, 168, 0, 1);
|
||||
|
||||
//********************************//
|
||||
|
||||
|
@ -63,16 +63,12 @@ uint32_t last_lightengine_activity = 0;
|
|||
|
||||
//********************************//
|
||||
|
||||
void apply_scene(uint8_t new_scene, uint8_t light)
|
||||
{
|
||||
if (new_scene == SCENE_RELEAX)
|
||||
{
|
||||
void apply_scene(uint8_t new_scene, uint8_t light) {
|
||||
if (new_scene == SCENE_RELEAX) {
|
||||
bri[light] = 144;
|
||||
} else if (new_scene == SCENE_BRIGHT)
|
||||
{
|
||||
} else if (new_scene == SCENE_BRIGHT) {
|
||||
bri[light] = 254;
|
||||
} else if (new_scene == SCENE_NIGHTLY)
|
||||
{
|
||||
} else if (new_scene == SCENE_NIGHTLY) {
|
||||
bri[0] = 25;
|
||||
bri[1] = 0;
|
||||
bri[2] = 0;
|
||||
|
@ -82,10 +78,8 @@ void apply_scene(uint8_t new_scene, uint8_t light)
|
|||
|
||||
//********************************//
|
||||
|
||||
void process_lightdata(uint8_t light, float tt)
|
||||
{
|
||||
if (light_state[light])
|
||||
{
|
||||
void process_lightdata(uint8_t light, float tt) {
|
||||
if (light_state[light]) {
|
||||
step_level[light] = (bri[light] - current_bri[light]) / tt;
|
||||
|
||||
} else {
|
||||
|
@ -95,29 +89,22 @@ void process_lightdata(uint8_t light, float tt)
|
|||
|
||||
//********************************//
|
||||
|
||||
void lightEngine()
|
||||
{
|
||||
void lightEngine() {
|
||||
|
||||
if (millis() < (last_lightengine_activity + TIME_LIGHTENGINE_INTERVAL_MS))
|
||||
{
|
||||
if (millis() < (last_lightengine_activity + TIME_LIGHTENGINE_INTERVAL_MS)) {
|
||||
// abort processing, the transition setting is a delay of seconds
|
||||
return;
|
||||
}
|
||||
|
||||
last_lightengine_activity = millis();
|
||||
|
||||
for (int i = 0; i < LIGHTS_COUNT; i++)
|
||||
{
|
||||
for (int i = 0; i < LIGHTS_COUNT; i++) {
|
||||
|
||||
if (light_state[i])
|
||||
{
|
||||
if (bri[i] != current_bri[i])
|
||||
{
|
||||
if (light_state[i]) {
|
||||
if (bri[i] != current_bri[i]) {
|
||||
in_transition = true;
|
||||
current_bri[i] += step_level[i] / BRI_MOD_STEPS_PER_SEC;
|
||||
if ((step_level[i] > 0.0 && current_bri[i] > bri[i]) ||
|
||||
(step_level[i] < 0.0 && current_bri[i] < bri[i]))
|
||||
{
|
||||
if ((step_level[i] > 0.0 && current_bri[i] > bri[i]) || (step_level[i] < 0.0 && current_bri[i] < bri[i])) {
|
||||
current_bri[i] = bri[i];
|
||||
//Serial.println("Reached target bri[" + (String)i + "] = " + (String)bri[i]);
|
||||
}
|
||||
|
@ -128,12 +115,10 @@ void lightEngine()
|
|||
}
|
||||
} else {
|
||||
|
||||
if (current_bri[i] != 0)
|
||||
{
|
||||
if (current_bri[i] != 0) {
|
||||
in_transition = true;
|
||||
current_bri[i] -= step_level[i] / BRI_MOD_STEPS_PER_SEC;
|
||||
if (current_bri[i] < 0)
|
||||
{
|
||||
if (current_bri[i] < 0) {
|
||||
current_bri[i] = 0;
|
||||
//Serial.println("Reached target bri[" + (String)i + "] = " + (String)bri[i]);
|
||||
}
|
||||
|
@ -146,8 +131,7 @@ void lightEngine()
|
|||
|
||||
} // for loop end
|
||||
|
||||
if (in_transition)
|
||||
{
|
||||
if (in_transition) {
|
||||
delay(6);
|
||||
in_transition = false;
|
||||
}
|
||||
|
@ -155,15 +139,12 @@ void lightEngine()
|
|||
|
||||
//********************************//
|
||||
|
||||
uint16_t calcPWM(float tbri)
|
||||
{
|
||||
uint16_t calcPWM(float tbri) {
|
||||
uint16_t tmp_pwm = PWM_OFF;
|
||||
if (tbri > 0.0)
|
||||
{
|
||||
if (tbri > 0.0) {
|
||||
tmp_pwm = PWM_MIN + (int)(tbri * BRI_TO_PWM_FACTOR);
|
||||
}
|
||||
if (tmp_pwm > PWM_MAX)
|
||||
{
|
||||
if (tmp_pwm > PWM_MAX) {
|
||||
tmp_pwm = PWM_MAX;
|
||||
}
|
||||
//Serial.println((String)tbri + " => " + (String)tmp_pwm);
|
||||
|
@ -172,28 +153,21 @@ uint16_t calcPWM(float tbri)
|
|||
|
||||
//********************************//
|
||||
|
||||
void read_eeprom_config()
|
||||
{
|
||||
for (uint8_t light = 0; light < LIGHTS_COUNT; light++)
|
||||
{
|
||||
void read_eeprom_config() {
|
||||
for (uint8_t light = 0; light < LIGHTS_COUNT; light++) {
|
||||
apply_scene(EEPROM.read(EEPROM_SCENE_ADDRESS), light);
|
||||
step_level[light] = bri[light] / 150.0;
|
||||
|
||||
if (EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS) == LAST_STATE_STARTUP_LIGHT_LAST_STATE ||
|
||||
(EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS) == LAST_STATE_STARTUP_LIGHT_ON_STATE &&
|
||||
EEPROM.read(EEPROM_LAST_STATE_ADDRESS + light) == LIGHT_STATE_ON))
|
||||
{
|
||||
if (EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS) == LAST_STATE_STARTUP_LIGHT_LAST_STATE || (EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS) == LAST_STATE_STARTUP_LIGHT_ON_STATE && EEPROM.read(EEPROM_LAST_STATE_ADDRESS + light) == LIGHT_STATE_ON)) {
|
||||
light_state[light] = true; // set the light state to on
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t tmp = EEPROM.read(EEPROM_TIMING_CONTROL_ENABLED_ADDRESS);
|
||||
if (tmp == TIMING_CONTROL_DISABLED)
|
||||
{
|
||||
if (tmp == TIMING_CONTROL_DISABLED) {
|
||||
tc_enabled = TIMING_CONTROL_DISABLED;
|
||||
|
||||
} else if (tmp == TIMING_CONTROL_ENABLED)
|
||||
{
|
||||
} else if (tmp == TIMING_CONTROL_ENABLED) {
|
||||
tc_enabled = TIMING_CONTROL_ENABLED;
|
||||
|
||||
} else {
|
||||
|
@ -203,22 +177,19 @@ void read_eeprom_config()
|
|||
tc_enabled = TIMING_CONTROL_DISABLED;
|
||||
}
|
||||
|
||||
if (EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS) == 255)
|
||||
{
|
||||
if (EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS) == 255) {
|
||||
// set the default value on uninitialized EEPROM
|
||||
EEPROM.write(EEPROM_LAST_STATE_STARTUP_ADDRESS, 0);
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
#ifdef USE_STATIC_IP
|
||||
if (EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS) == 255)
|
||||
{
|
||||
if (EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS) == 255) {
|
||||
EEPROM.write(EEPROM_DYNAMIC_IP_ADDRESS, 0);
|
||||
EEPROM.commit();
|
||||
}
|
||||
#else
|
||||
if (EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS) == 255)
|
||||
{
|
||||
if (EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS) == 255) {
|
||||
EEPROM.write(EEPROM_DYNAMIC_IP_ADDRESS, 1);
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
@ -227,21 +198,18 @@ void read_eeprom_config()
|
|||
|
||||
//********************************//
|
||||
|
||||
void setup()
|
||||
{
|
||||
void setup() {
|
||||
EEPROM.begin(256);
|
||||
|
||||
Serial.begin(SERIAL_BAUD_RATE);
|
||||
|
||||
if (EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS) == 0)
|
||||
{
|
||||
if (EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS) == 0) {
|
||||
WiFi.config(strip_ip, gateway_ip, subnet_mask, dns);
|
||||
}
|
||||
|
||||
read_eeprom_config();
|
||||
|
||||
for (int j = 0; j < 200; j++)
|
||||
{
|
||||
for (int j = 0; j < 200; j++) {
|
||||
lightEngine();
|
||||
}
|
||||
|
||||
|
@ -254,8 +222,7 @@ void setup()
|
|||
Serial.print("IP: ");
|
||||
Serial.println(myIP);
|
||||
|
||||
if (!light_state[0])
|
||||
{
|
||||
if (!light_state[0]) {
|
||||
// Show that we are connected
|
||||
analogWrite(pins[0], 100);
|
||||
delay(500);
|
||||
|
@ -278,21 +245,18 @@ void setup()
|
|||
|
||||
//********************************//
|
||||
|
||||
void loop()
|
||||
{
|
||||
void loop() {
|
||||
server.handleClient();
|
||||
lightEngine();
|
||||
|
||||
if (tc_enabled == TIMING_CONTROL_ENABLED)
|
||||
{
|
||||
if (tc_enabled == TIMING_CONTROL_ENABLED) {
|
||||
tc_update_loop();
|
||||
}
|
||||
}
|
||||
|
||||
//********************************//
|
||||
|
||||
void handleNotFound()
|
||||
{
|
||||
void handleNotFound() {
|
||||
String message = "File Not Found\n\n";
|
||||
message += "URI: ";
|
||||
message += server.uri();
|
||||
|
@ -302,8 +266,7 @@ void handleNotFound()
|
|||
message += server.args();
|
||||
message += "\n";
|
||||
|
||||
for (uint8_t i = 0; i < server.args(); i++)
|
||||
{
|
||||
for (uint8_t i = 0; i < server.args(); i++) {
|
||||
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
|
||||
}
|
||||
server.send(404, "text/plain", message);
|
||||
|
@ -311,62 +274,49 @@ void handleNotFound()
|
|||
|
||||
//********************************//
|
||||
|
||||
void init_webserver()
|
||||
{
|
||||
void init_webserver() {
|
||||
|
||||
#ifndef DISABLE_WEB_CONTROL
|
||||
server.on("/state", HTTP_PUT, []()
|
||||
{ // HTTP PUT request used to set a new light state
|
||||
server.on("/state", HTTP_PUT, []() { // HTTP PUT request used to set a new light state
|
||||
DynamicJsonDocument root(1024);
|
||||
DeserializationError error = deserializeJson(root, server.arg("plain"));
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (error) {
|
||||
server.send(404, "text/plain", "FAIL. " + server.arg("plain"));
|
||||
} else {
|
||||
|
||||
for (JsonPair state : root.as<JsonObject>())
|
||||
{
|
||||
for (JsonPair state : root.as<JsonObject>()) {
|
||||
const char* key = state.key().c_str();
|
||||
int light = atoi(key) - 1;
|
||||
JsonObject values = state.value();
|
||||
int transitiontime = 4;
|
||||
|
||||
uint8_t tmp = EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS);
|
||||
if (values.containsKey("on"))
|
||||
{
|
||||
if (values["on"])
|
||||
{
|
||||
if (values.containsKey("on")) {
|
||||
if (values["on"]) {
|
||||
light_state[light] = true;
|
||||
if (tmp == LAST_STATE_STARTUP_LIGHT_LAST_STATE &&
|
||||
EEPROM.read(EEPROM_LAST_STATE_ADDRESS + light) == LIGHT_STATE_OFF)
|
||||
{
|
||||
if (tmp == LAST_STATE_STARTUP_LIGHT_LAST_STATE && EEPROM.read(EEPROM_LAST_STATE_ADDRESS + light) == LIGHT_STATE_OFF) {
|
||||
EEPROM.write(EEPROM_LAST_STATE_ADDRESS + light, LIGHT_STATE_ON);
|
||||
}
|
||||
} else {
|
||||
light_state[light] = false;
|
||||
if (tmp == LAST_STATE_STARTUP_LIGHT_LAST_STATE &&
|
||||
EEPROM.read(EEPROM_LAST_STATE_ADDRESS + light) == LIGHT_STATE_ON)
|
||||
{
|
||||
if (tmp == LAST_STATE_STARTUP_LIGHT_LAST_STATE && EEPROM.read(EEPROM_LAST_STATE_ADDRESS + light) == LIGHT_STATE_ON) {
|
||||
EEPROM.write(EEPROM_LAST_STATE_ADDRESS + light, LIGHT_STATE_OFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (values.containsKey("bri"))
|
||||
{
|
||||
if (values.containsKey("bri")) {
|
||||
bri[light] = values["bri"];
|
||||
}
|
||||
|
||||
if (values.containsKey("bri_inc"))
|
||||
{
|
||||
bri[light] += (int) values["bri_inc"];
|
||||
if (values.containsKey("bri_inc")) {
|
||||
bri[light] += (int)values["bri_inc"];
|
||||
if (bri[light] > 255) bri[light] = 255;
|
||||
else if (bri[light] < 1) bri[light] = 1;
|
||||
}
|
||||
|
||||
if (values.containsKey("transitiontime"))
|
||||
{
|
||||
if (values.containsKey("transitiontime")) {
|
||||
transitiontime = values["transitiontime"];
|
||||
}
|
||||
process_lightdata(light, transitiontime);
|
||||
|
@ -377,8 +327,7 @@ void init_webserver()
|
|||
}
|
||||
});
|
||||
|
||||
server.on("/state", HTTP_GET, []()
|
||||
{ // HTTP GET request used to fetch current light state
|
||||
server.on("/state", HTTP_GET, []() { // HTTP GET request used to fetch current light state
|
||||
uint8_t light = server.arg("light").toInt() - 1;
|
||||
DynamicJsonDocument root(1024);
|
||||
root["on"] = light_state[light];
|
||||
|
@ -388,9 +337,8 @@ void init_webserver()
|
|||
server.send(200, "text/plain", output);
|
||||
});
|
||||
|
||||
server.on("/detect", []()
|
||||
{ // HTTP GET request used to discover the light type
|
||||
char macString[32] = {0};
|
||||
server.on("/detect", []() { // HTTP GET request used to discover the light type
|
||||
char macString[32] = { 0 };
|
||||
sprintf(macString, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
DynamicJsonDocument root(1024);
|
||||
root["name"] = light_name;
|
||||
|
@ -405,8 +353,7 @@ void init_webserver()
|
|||
server.send(200, "text/plain", output);
|
||||
});
|
||||
|
||||
server.on("/tc_data_blocks", []()
|
||||
{
|
||||
server.on("/tc_data_blocks", []() {
|
||||
String output = tc_getJsonData();
|
||||
|
||||
server.send(200, "application/json", output);
|
||||
|
@ -414,66 +361,57 @@ void init_webserver()
|
|||
|
||||
#endif // DISABLE_WEB_CONTROL
|
||||
|
||||
server.on("/", []()
|
||||
{
|
||||
server.on("/", []() {
|
||||
|
||||
#ifndef DISABLE_WEB_CONTROL
|
||||
static float transitiontime = 4.0;
|
||||
|
||||
if (server.hasArg("transition"))
|
||||
{
|
||||
if (server.hasArg("transition")) {
|
||||
transitiontime = server.arg("transition").toFloat();
|
||||
}
|
||||
|
||||
// startup behavior switch handling
|
||||
if (server.hasArg("startup"))
|
||||
{
|
||||
if (server.hasArg("startup")) {
|
||||
int startup = server.arg("startup").toInt();
|
||||
if (EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS) != startup)
|
||||
{
|
||||
if (EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS) != startup) {
|
||||
EEPROM.write(EEPROM_LAST_STATE_STARTUP_ADDRESS, startup);
|
||||
|
||||
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
|
||||
{
|
||||
for (uint8_t i = 0; i < LIGHTS_COUNT; i++) {
|
||||
uint8_t tmp = (light_state[i] == true ? LIGHT_STATE_ON : LIGHT_STATE_OFF);
|
||||
if (EEPROM.read(EEPROM_LAST_STATE_ADDRESS + i) != tmp)
|
||||
{
|
||||
if (EEPROM.read(EEPROM_LAST_STATE_ADDRESS + i) != tmp) {
|
||||
EEPROM.write(EEPROM_LAST_STATE_ADDRESS + i, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
EEPROM.commit();
|
||||
Serial.print("Startup behavior set to "); Serial.println(EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS));
|
||||
Serial.print("Startup behavior set to ");
|
||||
Serial.println(EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS));
|
||||
}
|
||||
}
|
||||
#endif // DISABLE_WEB_CONTROL
|
||||
|
||||
// timing controller switch handling
|
||||
if (server.hasArg("tc"))
|
||||
{
|
||||
if (server.arg("tc") == "true")
|
||||
{
|
||||
if (tc_enabled == TIMING_CONTROL_DISABLED)
|
||||
{
|
||||
if (EEPROM.read(EEPROM_TIMING_CONTROL_ENABLED_ADDRESS) != TIMING_CONTROL_ENABLED)
|
||||
{
|
||||
if (server.hasArg("tc")) {
|
||||
if (server.arg("tc") == "true") {
|
||||
if (tc_enabled == TIMING_CONTROL_DISABLED) {
|
||||
if (EEPROM.read(EEPROM_TIMING_CONTROL_ENABLED_ADDRESS) != TIMING_CONTROL_ENABLED) {
|
||||
tc_enabled = TIMING_CONTROL_ENABLED;
|
||||
EEPROM.write(EEPROM_TIMING_CONTROL_ENABLED_ADDRESS, TIMING_CONTROL_ENABLED);
|
||||
EEPROM.commit();
|
||||
Serial.print("Timing control = "); Serial.println(EEPROM.read(EEPROM_TIMING_CONTROL_ENABLED_ADDRESS));
|
||||
Serial.print("Timing control = ");
|
||||
Serial.println(EEPROM.read(EEPROM_TIMING_CONTROL_ENABLED_ADDRESS));
|
||||
}
|
||||
}
|
||||
|
||||
} else { // tc is set to false or something else
|
||||
|
||||
if (tc_enabled == TIMING_CONTROL_ENABLED)
|
||||
{
|
||||
if (tc_enabled == TIMING_CONTROL_ENABLED) {
|
||||
tc_enabled = TIMING_CONTROL_DISABLED;
|
||||
if (EEPROM.read(EEPROM_TIMING_CONTROL_ENABLED_ADDRESS) != TIMING_CONTROL_DISABLED)
|
||||
{
|
||||
if (EEPROM.read(EEPROM_TIMING_CONTROL_ENABLED_ADDRESS) != TIMING_CONTROL_DISABLED) {
|
||||
EEPROM.write(EEPROM_TIMING_CONTROL_ENABLED_ADDRESS, TIMING_CONTROL_DISABLED);
|
||||
EEPROM.commit();
|
||||
Serial.print("Timing control = "); Serial.println(EEPROM.read(EEPROM_TIMING_CONTROL_ENABLED_ADDRESS));
|
||||
Serial.print("Timing control = ");
|
||||
Serial.println(EEPROM.read(EEPROM_TIMING_CONTROL_ENABLED_ADDRESS));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -482,82 +420,73 @@ void init_webserver()
|
|||
#ifndef DISABLE_WEB_CONTROL
|
||||
|
||||
// scene switch handling
|
||||
if (server.hasArg("scene"))
|
||||
{
|
||||
if (server.hasArg("scene")) {
|
||||
scene = server.arg("scene").toInt();
|
||||
if (EEPROM.read(EEPROM_SCENE_ADDRESS) != scene)
|
||||
{
|
||||
if (EEPROM.read(EEPROM_SCENE_ADDRESS) != scene) {
|
||||
EEPROM.write(EEPROM_SCENE_ADDRESS, scene);
|
||||
EEPROM.commit();
|
||||
Serial.print("Scene set to "); Serial.println(EEPROM.read(EEPROM_SCENE_ADDRESS));
|
||||
Serial.print("Scene set to ");
|
||||
Serial.println(EEPROM.read(EEPROM_SCENE_ADDRESS));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (server.hasArg("dip"))
|
||||
{
|
||||
if (server.hasArg("dip")) {
|
||||
uint8_t tmp = EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS);
|
||||
uint8_t tmp2 = (server.arg("dip") == "true" ? 1 : 0);
|
||||
if (tmp != tmp2)
|
||||
{
|
||||
if (tmp != tmp2) {
|
||||
EEPROM.write(EEPROM_DYNAMIC_IP_ADDRESS, tmp2);
|
||||
EEPROM.commit();
|
||||
Serial.print("Set dynamic IP to "); Serial.println(EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS));
|
||||
Serial.print("Set dynamic IP to ");
|
||||
Serial.println(EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS));
|
||||
}
|
||||
}
|
||||
|
||||
// process the received data for every light
|
||||
for (int light = 0; light < LIGHTS_COUNT; light++)
|
||||
{
|
||||
for (int light = 0; light < LIGHTS_COUNT; light++) {
|
||||
|
||||
if (server.hasArg("bri" + (String)light))
|
||||
{
|
||||
if (server.hasArg("bri" + (String)light)) {
|
||||
bri[light] = (int)server.arg("bri" + (String)light).toInt();
|
||||
Serial.print("Brightness set to "); Serial.println(bri[light]);
|
||||
|
||||
Serial.print("Brightness set to ");
|
||||
Serial.println(bri[light]);
|
||||
}
|
||||
|
||||
if (server.hasArg("on" + (String)light))
|
||||
{
|
||||
if (server.hasArg("on" + (String)light)) {
|
||||
uint8_t tmp = EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS);
|
||||
if (server.arg("on" + (String)light) == "true" && light_state[light] == false)
|
||||
{
|
||||
if (server.arg("on" + (String)light) == "true" && light_state[light] == false) {
|
||||
light_state[light] = true;
|
||||
if (tmp == 0 && EEPROM.read(EEPROM_LAST_STATE_ADDRESS + light) == 0)
|
||||
{
|
||||
if (tmp == 0 && EEPROM.read(EEPROM_LAST_STATE_ADDRESS + light) == 0) {
|
||||
EEPROM.write(EEPROM_LAST_STATE_ADDRESS + light, LIGHT_STATE_ON);
|
||||
}
|
||||
Serial.print("Light "); Serial.print(light); Serial.print(" state set to "); Serial.println(light_state[light]);
|
||||
Serial.print("Light ");
|
||||
Serial.print(light);
|
||||
Serial.print(" state set to ");
|
||||
Serial.println(light_state[light]);
|
||||
|
||||
} else if (server.arg("on" + (String)light) == "false" && light_state[light] == true)
|
||||
{
|
||||
} else if (server.arg("on" + (String)light) == "false" && light_state[light] == true) {
|
||||
light_state[light] = false;
|
||||
if (tmp == 0 && EEPROM.read(EEPROM_LAST_STATE_ADDRESS + light) == 1)
|
||||
{
|
||||
if (tmp == 0 && EEPROM.read(EEPROM_LAST_STATE_ADDRESS + light) == 1) {
|
||||
EEPROM.write(EEPROM_LAST_STATE_ADDRESS + light, LIGHT_STATE_OFF);
|
||||
}
|
||||
Serial.print("Light "); Serial.print(light); Serial.print(" state set to "); Serial.println(light_state[light]);
|
||||
Serial.print("Light ");
|
||||
Serial.print(light);
|
||||
Serial.print(" state set to ");
|
||||
Serial.println(light_state[light]);
|
||||
}
|
||||
|
||||
EEPROM.commit();
|
||||
|
||||
}
|
||||
|
||||
// start alerting for every light
|
||||
if (server.hasArg("alert"))
|
||||
{
|
||||
if (light_state[light])
|
||||
{
|
||||
if (server.hasArg("alert")) {
|
||||
if (light_state[light]) {
|
||||
current_bri[light] = 0;
|
||||
} else {
|
||||
current_bri[light] = 255;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// set the light step level
|
||||
if (server.hasArg("transition") && light_state[light])
|
||||
{
|
||||
if (server.hasArg("transition") && light_state[light]) {
|
||||
Serial.println("Webinterface transitiontime = " + (String)transitiontime);
|
||||
transitiontime = server.arg("transition").toFloat();
|
||||
step_level[light] = ((float)bri[light] - current_bri[light]) / transitiontime;
|
||||
|
@ -566,14 +495,12 @@ void init_webserver()
|
|||
|
||||
#endif // DISABLE_WEB_CONTROL
|
||||
|
||||
if (server.hasArg("resettc"))
|
||||
{ // reqrite the tc config and reboot
|
||||
if (server.hasArg("resettc")) { // reqrite the tc config and reboot
|
||||
tc_write_default();
|
||||
ESP.reset();
|
||||
}
|
||||
|
||||
if (server.hasArg("reset"))
|
||||
{
|
||||
if (server.hasArg("reset")) {
|
||||
ESP.reset();
|
||||
}
|
||||
|
||||
|
@ -583,8 +510,10 @@ void init_webserver()
|
|||
http_content += "<head>";
|
||||
http_content += "<meta charset=\"utf-8\">";
|
||||
http_content += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">";
|
||||
http_content += "<meta http-equiv=\"refresh\" content=\"15\">"; // Reload the page every 15 seconds automatically
|
||||
//http_content += "<meta http-equiv=\"refresh\" content=\"15\">"; // Reload the page every 15 seconds automatically
|
||||
http_content += "<title>Light Setup</title>";
|
||||
http_content += "<script src=\"https://code.jquery.com/jquery-3.6.0.min.js\"></script>";
|
||||
http_content += "<script src=\"https://cdn.plot.ly/plotly-latest.min.js\"></script>";
|
||||
http_content += "<link rel=\"stylesheet\" href=\"https://unpkg.com/purecss@0.6.2/build/pure-min.css\">";
|
||||
http_content += "</head>";
|
||||
http_content += "<body>";
|
||||
|
@ -600,15 +529,16 @@ void init_webserver()
|
|||
http_content += "<form class=\"pure-form pure-form-aligned\" action=\"/\" method=\"post\">";
|
||||
|
||||
#ifndef DISABLE_WEB_CONTROL
|
||||
http_content += "<br>";
|
||||
http_content += "<br><table border=0><tr><td>";
|
||||
// Light control
|
||||
for (uint8 light_num = 0; light_num < LIGHTS_COUNT; light_num++)
|
||||
{
|
||||
http_content += "<h4>Light " + (String)(light_num+1) + "</h4>";
|
||||
for (uint8 light_num = 0; light_num < LIGHTS_COUNT; light_num++) {
|
||||
http_content += "<h4>Light " + (String)(light_num + 1) + "</h4>";
|
||||
http_content += "<div class=\"pure-control-group\">";
|
||||
http_content += "<label for=\"power\"><strong>Power</strong></label>";
|
||||
http_content += "<a class=\"pure-button"; if ( light_state[light_num]) http_content += " pure-button-primary"; http_content += "\" href=\"/?on" + (String)light_num + "=true\">ON</a>";
|
||||
http_content += "<a class=\"pure-button"; if (!light_state[light_num]) http_content += " pure-button-primary"; http_content += "\" href=\"/?on" + (String)light_num + "=false\">OFF</a>";
|
||||
http_content += "<a id=\"on" + (String)light_num + "_on\" class=\"pure-button";
|
||||
http_content += "\" href=\"/?on" + (String)light_num + "=true\">ON</a>";
|
||||
http_content += "<a id=\"on" + (String)light_num + "_off\" class=\"pure-button";
|
||||
http_content += "\" href=\"/?on" + (String)light_num + "=false\">OFF</a>";
|
||||
http_content += "</div>";
|
||||
|
||||
http_content += "<div class=\"pure-control-group\">";
|
||||
|
@ -627,15 +557,23 @@ void init_webserver()
|
|||
}
|
||||
|
||||
// timer data processing, startup state and scene for all of the lights
|
||||
http_content += "<br>";
|
||||
http_content += "</td><td>";
|
||||
http_content += "<div id=\"plot_chart\"></div>";
|
||||
http_content += "</td></tr></table><br>";
|
||||
http_content += "<h3>Config</h3>";
|
||||
http_content += "<div class=\"pure-control-group\">";
|
||||
http_content += "<label for=\"startup\"><strong>Startup</strong></label>";
|
||||
http_content += "<select onchange=\"this.form.submit()\" id=\"startup\" name=\"startup\">";
|
||||
int ls_val = EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS);
|
||||
http_content += "<option "; if (ls_val == LAST_STATE_STARTUP_LIGHT_LAST_STATE) http_content += "selected=\"selected\""; http_content += " value=\"0\">Last state</option>";
|
||||
http_content += "<option "; if (ls_val == LAST_STATE_STARTUP_LIGHT_ON_STATE) http_content += "selected=\"selected\""; http_content += " value=\"1\">On</option>";
|
||||
http_content += "<option "; if (ls_val == LAST_STATE_STARTUP_LIGHT_OFF_STATE) http_content += "selected=\"selected\""; http_content += " value=\"2\">Off</option>";
|
||||
http_content += "<option ";
|
||||
if (ls_val == LAST_STATE_STARTUP_LIGHT_LAST_STATE) http_content += "selected=\"selected\"";
|
||||
http_content += " value=\"0\">Last state</option>";
|
||||
http_content += "<option ";
|
||||
if (ls_val == LAST_STATE_STARTUP_LIGHT_ON_STATE) http_content += "selected=\"selected\"";
|
||||
http_content += " value=\"1\">On</option>";
|
||||
http_content += "<option ";
|
||||
if (ls_val == LAST_STATE_STARTUP_LIGHT_OFF_STATE) http_content += "selected=\"selected\"";
|
||||
http_content += " value=\"2\">Off</option>";
|
||||
http_content += "</select>";
|
||||
http_content += "</div>";
|
||||
|
||||
|
@ -643,17 +581,27 @@ void init_webserver()
|
|||
http_content += "<label for=\"scene\"><strong>Scene</strong></label>";
|
||||
http_content += "<select onchange = \"this.form.submit()\" id=\"scene\" name=\"scene\">";
|
||||
int sc_val = EEPROM.read(EEPROM_SCENE_ADDRESS);
|
||||
http_content += "<option "; if (sc_val == SCENE_RELEAX) http_content += "selected=\"selected\""; http_content += " value=\"0\">Relax</option>";
|
||||
http_content += "<option "; if (sc_val == SCENE_BRIGHT) http_content += "selected=\"selected\""; http_content += " value=\"1\">Bright</option>";
|
||||
http_content += "<option "; if (sc_val == SCENE_NIGHTLY) http_content += "selected=\"selected\""; http_content += " value=\"2\">Night</option>";
|
||||
http_content += "<option ";
|
||||
if (sc_val == SCENE_RELEAX) http_content += "selected=\"selected\"";
|
||||
http_content += " value=\"0\">Relax</option>";
|
||||
http_content += "<option ";
|
||||
if (sc_val == SCENE_BRIGHT) http_content += "selected=\"selected\"";
|
||||
http_content += " value=\"1\">Bright</option>";
|
||||
http_content += "<option ";
|
||||
if (sc_val == SCENE_NIGHTLY) http_content += "selected=\"selected\"";
|
||||
http_content += " value=\"2\">Night</option>";
|
||||
http_content += "</select>";
|
||||
http_content += "</div>";
|
||||
|
||||
http_content += "<div class=\"pure-control-group\">";
|
||||
http_content += "<label for=\"power\"><strong>Timing control</strong></label>";
|
||||
int tc_val = EEPROM.read(EEPROM_TIMING_CONTROL_ENABLED_ADDRESS);
|
||||
http_content += "<a class=\"pure-button"; if (tc_val == TIMING_CONTROL_ENABLED) http_content += " pure-button-primary"; http_content += "\" href=\"/?tc=true\">ON</a>";
|
||||
http_content += "<a class=\"pure-button"; if (tc_val == TIMING_CONTROL_DISABLED) http_content += " pure-button-primary"; http_content += "\" href=\"/?tc=false\">OFF</a>";
|
||||
http_content += "<a class=\"pure-button";
|
||||
if (tc_val == TIMING_CONTROL_ENABLED) http_content += " pure-button-primary";
|
||||
http_content += "\" href=\"/?tc=true\">ON</a>";
|
||||
http_content += "<a class=\"pure-button";
|
||||
if (tc_val == TIMING_CONTROL_DISABLED) http_content += " pure-button-primary";
|
||||
http_content += "\" href=\"/?tc=false\">OFF</a>";
|
||||
http_content += "</div>";
|
||||
http_content += "<br>";
|
||||
|
||||
|
@ -680,12 +628,15 @@ void init_webserver()
|
|||
http_content += "<h3>Network</h3>";
|
||||
http_content += "<div class=\"pure-control-group\">";
|
||||
http_content += "<label for=\"dip\"><strong>Dynamic-IP</strong></label>";
|
||||
http_content += "<a class=\"pure-button"; if ( dip) http_content += " pure-button-primary"; http_content += "\" href=\"/?dip=true\">ON</a>";
|
||||
http_content += "<a class=\"pure-button"; if (!dip) http_content += " pure-button-primary"; http_content += "\" href=\"/?dip=false\">OFF</a>";
|
||||
http_content += "<a class=\"pure-button";
|
||||
if (dip) http_content += " pure-button-primary";
|
||||
http_content += "\" href=\"/?dip=true\">ON</a>";
|
||||
http_content += "<a class=\"pure-button";
|
||||
if (!dip) http_content += " pure-button-primary";
|
||||
http_content += "\" href=\"/?dip=false\">OFF</a>";
|
||||
http_content += "</div>";
|
||||
|
||||
if (dip == 0)
|
||||
{
|
||||
if (dip == 0) {
|
||||
http_content += "<div class=\"pure-control-group\">";
|
||||
http_content += "<label for=\"ip\">IP</label>";
|
||||
http_content += "<input id=\"ip\" name=\"ip\" type=\"text\" value=\"" + WiFi.localIP().toString() + "\">";
|
||||
|
@ -700,10 +651,111 @@ void init_webserver()
|
|||
http_content += "</div>";
|
||||
}
|
||||
|
||||
// The save button
|
||||
http_content += "<div class=\"pure-controls\">";
|
||||
http_content += "<button type=\"submit\" class=\"pure-button pure-button-primary\">Save</button>";
|
||||
http_content += "</div>";
|
||||
|
||||
http_content += "<script>"
|
||||
"function loadData() {"
|
||||
"$.getJSON('/tc_data_blocks', function(data) {"
|
||||
"var currenttime = '';"
|
||||
"var time = [];"
|
||||
"var channel1 = [];"
|
||||
"var channel2 = [];"
|
||||
"var channel3 = [];"
|
||||
"var channel4 = [];"
|
||||
"for (var i = 0; i < data['tcdata'].length; i++) {"
|
||||
"time.push(data['tcdata'][i]['hour'] + ':' + (data['tcdata'][i]['min'] < 10 ? '0' : '') + data['tcdata'][i]['min']);"
|
||||
"channel1.push(data['tcdata'][i]['ch1']);"
|
||||
"channel2.push(data['tcdata'][i]['ch2']);"
|
||||
"channel3.push(data['tcdata'][i]['ch3']);"
|
||||
"channel4.push(data['tcdata'][i]['ch4']);"
|
||||
"}"
|
||||
"currenttime=data['currenttime'];"
|
||||
"var trace1 = {"
|
||||
"x: time,"
|
||||
"y: channel1,"
|
||||
"name: 'Channel 1',"
|
||||
"type: 'scatter',"
|
||||
"mode: 'lines+markers',"
|
||||
"};"
|
||||
"var trace2 = {"
|
||||
"x: time,"
|
||||
"y: channel2,"
|
||||
"name: 'Channel 2',"
|
||||
"type: 'scatter',"
|
||||
"mode: 'lines+markers',"
|
||||
"};"
|
||||
"var trace3 = {"
|
||||
"x: time,"
|
||||
"y: channel3,"
|
||||
"name: 'Channel 3',"
|
||||
"type: 'scatter',"
|
||||
"mode: 'lines+markers',"
|
||||
"};"
|
||||
"var trace4 = {"
|
||||
"x: time,"
|
||||
"y: channel4,"
|
||||
"name: 'Channel 4',"
|
||||
"type: 'scatter',"
|
||||
"mode: 'lines+markers',"
|
||||
"};"
|
||||
"var layout = {"
|
||||
"title: 'Timing Control Data Blocks',"
|
||||
"xaxis: {"
|
||||
"title: 'Time',"
|
||||
"tickangle: -45,"
|
||||
"},"
|
||||
"yaxis: {"
|
||||
"title: 'Brightness',"
|
||||
"range: [0, 255],"
|
||||
"},"
|
||||
"shapes: [{"
|
||||
"type: 'line',"
|
||||
"x0: currenttime,"
|
||||
"y0: 0,"
|
||||
"x1: currenttime,"
|
||||
"y1: 255,"
|
||||
"line: {"
|
||||
"color: 'lightgrey',"
|
||||
"width: 3,"
|
||||
"dash: 'dot'"
|
||||
"}"
|
||||
"}]"
|
||||
"};"
|
||||
"Plotly.newPlot('plot_chart', [trace1, trace2, trace3, trace4], layout);"
|
||||
"});"
|
||||
"}"
|
||||
"setInterval(loadData, 10000);"
|
||||
"loadData();"
|
||||
"function updateLightState() {"
|
||||
"for (let i = 1; i <= 4; i++) {"
|
||||
"const lightURL = `http://192.168.0.26/state?light=${i}`;"
|
||||
"fetch(lightURL)"
|
||||
".then(response => response.json())"
|
||||
".then(data => {"
|
||||
"const briSlider = document.getElementById(`bri${i - 1}`);"
|
||||
"const briSliderVal = document.getElementById(`bri${i - 1}_val`);"
|
||||
"const onLinkOn = document.getElementById(`on${i - 1}_on`);"
|
||||
"const onLinkOff = document.getElementById(`on${i - 1}_off`);"
|
||||
"briSlider.value = data.bri;"
|
||||
"briSliderVal.innerHTML = (Math.round((data.bri * 100.0 / 255.0) * 100) / 100).toFixed(2);"
|
||||
"if (data.on == 'true') {"
|
||||
"onLinkOn.classList.remove('pure-button-primary');"
|
||||
"onLinkOff.classList.add('pure-button-primary');"
|
||||
"} else {"
|
||||
"onLinkOn.classList.add('pure-button-primary');"
|
||||
"onLinkOff.classList.remove('pure-button-primary');"
|
||||
"}"
|
||||
"})"
|
||||
".catch(error => console.error(error));"
|
||||
"}"
|
||||
"}"
|
||||
"setInterval(updateLightState, 10000);"
|
||||
"updateLightState();"
|
||||
"</script>";
|
||||
|
||||
#endif // DISABLE_WEB_CONTROL
|
||||
|
||||
http_content += "</fieldset>";
|
||||
|
@ -712,11 +764,9 @@ void init_webserver()
|
|||
http_content += "</html>";
|
||||
|
||||
server.send(200, "text/html", http_content);
|
||||
|
||||
});
|
||||
|
||||
server.on("/reset", []()
|
||||
{ // trigger manual reset
|
||||
server.on("/reset", []() { // trigger manual reset
|
||||
server.send(200, "text/html", "reset");
|
||||
delay(1000);
|
||||
ESP.restart();
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
//***********************************//
|
||||
/* Globals */
|
||||
|
||||
bool tc_testOngoing = true;
|
||||
bool tc_testOngoing = false;
|
||||
|
||||
uint32_t tc_last_check = 60000;
|
||||
|
||||
|
@ -49,9 +49,9 @@ uint8_t example_timer_data_block[] = {
|
|||
18, 0, 205, 205, 205, 205, // 4: 80% all for 5 hours
|
||||
19, 0, 50, 50, 50, 50, // 5: 20% all
|
||||
19, 30, 50, 0, 50, 0, // 6: 20% all blues
|
||||
20, 0, 25, 0, 25, 0, // 9: disabled
|
||||
20, 30, 25, 0, 0, 0, // 7: 10% ch1 blues
|
||||
21, 0, 0, 0, 0, 0, // 8: 0% all
|
||||
20, 0, 0, 0, 0, 0, // 9: disabled
|
||||
};
|
||||
|
||||
uint8_t test_timer_data_block[] = {
|
||||
|
@ -141,7 +141,7 @@ void tc_update_main()
|
|||
tc_updateTime();
|
||||
|
||||
// search for the current active time slot
|
||||
for (int i = NUMBER_OF_TIMER_DATA_BLOCKS-1; i >= 0 && target_data_block == 255; i--)
|
||||
for (int i = NUMBER_OF_TIMER_DATA_BLOCKS-1; i >= 0 && target_data_block == 255; --i)
|
||||
{
|
||||
//Serial.println((String)tc_data[i].hh + ":" + (String)tc_data[i].mm);
|
||||
|
||||
|
@ -369,8 +369,8 @@ bool tc_check_no_data_block()
|
|||
|
||||
String tc_getJsonData()
|
||||
{
|
||||
String output = "[";
|
||||
for (uint8_t i = 0; i < LENGTH_OF_TIMER_DATA_BLOCK; i++)
|
||||
String output = "{\"tcdata\":[";
|
||||
for (uint8_t i = 0; i < NUMBER_OF_TIMER_DATA_BLOCKS; i++)
|
||||
{
|
||||
output += "{\"hour\":" + (String)(int)tc_data[i].hh + ",";
|
||||
output += "\"min\":" + (String)(int)tc_data[i].mm + ",";
|
||||
|
@ -378,24 +378,24 @@ String tc_getJsonData()
|
|||
output += "\"ch2\":" + (String)(int)tc_data[i].ch2 + ",";
|
||||
output += "\"ch3\":" + (String)(int)tc_data[i].ch3 + ",";
|
||||
output += "\"ch4\":" + (String)(int)tc_data[i].ch4 + "}";
|
||||
if (i < LENGTH_OF_TIMER_DATA_BLOCK-1)
|
||||
if (i < NUMBER_OF_TIMER_DATA_BLOCKS-1)
|
||||
{
|
||||
output += ",";
|
||||
}
|
||||
}
|
||||
output += "]";
|
||||
output += "], \"currenttime\": \"" + (String)timeClient.getHours() + ":" + (String)timeClient.getMinutes() + "\"}";
|
||||
return output;
|
||||
}
|
||||
|
||||
//********************************//
|
||||
|
||||
tc_jsonDataBlockToEEPROM(String json_data_string)
|
||||
void tc_jsonDataBlocksToEEPROM(String json_data_string)
|
||||
{
|
||||
StaticJsonDocument<512> doc;
|
||||
deserializeJson(doc, json_data_string);
|
||||
|
||||
// Loop through each data block in the JSON data and store it in the tc_data array
|
||||
for (uint8_t i = 0; i < LENGTH_OF_TIMER_DATA_BLOCK; i++)
|
||||
for (uint8_t i = 0; i < NUMBER_OF_TIMER_DATA_BLOCKS; i++)
|
||||
{
|
||||
JsonObject obj = doc[i];
|
||||
tc_data[i].hh = obj["hour"];
|
||||
|
|
Loading…
Reference in a new issue