Compare commits

..

No commits in common. "56254d58eb5a17a9b94b5a4517714dff67bf3fcd" and "6087c38e8a137c59d0617f265f0295054c319c65" have entirely different histories.

12 changed files with 1008 additions and 1103 deletions

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 MiB

View file

@ -329,24 +329,20 @@ if (xhr.status === 200) {
button.classList.remove("pure-button-primary");
button.classList.add("success");
button.innerHTML = "Disabled!";
button.style.backgroundColor = "green";
setTimeout(function () {
button.classList.remove("success");
button.classList.add("pure-button-primary");
button.innerHTML = "OFF";
button.style.backgroundColor = "";
}, 2000);
console.log('Data successfully sent to server!');
} else {
button.classList.remove("pure-button-primary");
button.classList.add("error");
button.innerHTML = "Error!";
button.style.backgroundColor = "red";
setTimeout(function () {
button.classList.remove("error");
button.classList.add("pure-button-primary");
button.innerHTML = "OFF";
button.style.backgroundColor = "";
}, 2000);
showToast('Error while sending data to server.', 'error');
console.log('Error while sending data to server.');
@ -374,24 +370,20 @@ if (xhr.status === 200) {
button.classList.remove("pure-button-primary");
button.classList.add("success");
button.innerHTML = "Enabled!";
button.style.backgroundColor = "green";
setTimeout(function () {
button.classList.remove("success");
button.classList.add("pure-button-primary");
button.innerHTML = "ON";
button.style.backgroundColor = "";
}, 2000);
console.log('Data successfully sent to server!');
} else {
button.classList.remove("pure-button-primary");
button.classList.add("error");
button.innerHTML = "Error!";
button.style.backgroundColor = "red";
setTimeout(function () {
button.classList.remove("error");
button.classList.add("pure-button-primary");
button.innerHTML = "ON";
button.style.backgroundColor = "";
}, 2000);
showToast('Error while sending data to server.', 'error');
console.log('Error while sending data to server.');
@ -445,13 +437,13 @@ input.value = value;
input.style = "1px solod darkgray";
input.classList.add("pure-slider-range");
if (id.startsWith("ch1_")) {
input.style.background = "linear-gradient(to left, " + rgb2Hex(31, 119, 180) + ", white)";
input.style.background = "linear-gradient(to bottom, " + rgb2Hex(31, 119, 180) + ", white)";
} else if (id.startsWith("ch2_")) {
input.style.background = "linear-gradient(to left, " + rgb2Hex(255, 127, 14) + ", white)";
input.style.background = "linear-gradient(to bottom, " + rgb2Hex(255, 127, 14) + ", white)";
} else if (id.startsWith("ch3_")) {
input.style.background = "linear-gradient(to left, " + rgb2Hex(44, 160, 44) + ", white)";
input.style.background = "linear-gradient(to bottom, " + rgb2Hex(44, 160, 44) + ", white)";
} else if (id.startsWith("ch4_")) {
input.style.background = "linear-gradient(to left, " + rgb2Hex(214, 39, 40) + ", white)";
input.style.background = "linear-gradient(to bottom, " + rgb2Hex(214, 39, 40) + ", white)";
}
div = document.createElement("div");
div.appendChild(input);
@ -531,11 +523,9 @@ if (!jsonData) {
button.classList.remove("pure-button-primary");
button.classList.add("error");
button.innerHTML = "Error!";
button.style.backgroundColor = "red";
setTimeout(function () {
button.classList.remove("error");
button.classList.add("pure-button-primary");
button.style.backgroundColor = "";
button.innerHTML = "save";
}, 2000);
console.log('Error while generating timing control data.');
@ -552,24 +542,20 @@ if (xhr.status === 200) {
button.classList.remove("pure-button-primary");
button.classList.add("success");
button.innerHTML = "Saved!";
button.style.backgroundColor = "green";
setTimeout(function () {
button.classList.remove("success");
button.classList.add("pure-button-primary");
button.innerHTML = "save";
button.style.backgroundColor = "";
}, 2000);
console.log('Data successfully sent to server!');
} else {
button.classList.remove("pure-button-primary");
button.classList.add("error");
button.innerHTML = "Error!";
button.style.backgroundColor = "red";
setTimeout(function () {
button.classList.remove("error");
button.classList.add("pure-button-primary");
button.innerHTML = "save";
button.style.backgroundColor = "";
}, 2000);
showToast('Error while sending timing control data to server.', 'error');
console.log('Error while sending data to server.');

View file

@ -11,24 +11,20 @@ if (xhr.status === 200) {
button.classList.remove("pure-button-primary");
button.classList.add("success");
button.innerHTML = "Enabled!";
button.style.backgroundColor = "green";
setTimeout(function () {
button.classList.remove("success");
button.classList.add("pure-button-primary");
button.innerHTML = "ON";
button.style.backgroundColor = "";
}, 2000);
console.log('Data successfully sent to server!');
} else {
button.classList.remove("pure-button-primary");
button.classList.add("error");
button.innerHTML = "Error!";
button.style.backgroundColor = "";
setTimeout(function () {
button.classList.remove("error");
button.classList.add("pure-button-primary");
button.innerHTML = "ON";
button.style.backgroundColor = "";
}, 2000);
showToast('Error while sending data to server.', 'error');
console.log('Error while sending data to server.');
@ -53,24 +49,20 @@ if (xhr.status === 200) {
button.classList.remove("pure-button-primary");
button.classList.add("success");
button.innerHTML = "Disabled!";
button.style.backgroundColor = "green";
setTimeout(function () {
button.classList.remove("success");
button.classList.add("pure-button-primary");
button.innerHTML = "OFF";
button.style.backgroundColor = "";
}, 2000);
console.log('Data successfully sent to server!');
} else {
button.classList.remove("pure-button-primary");
button.classList.add("error");
button.innerHTML = "Error!";
button.style.backgroundColor = "red";
setTimeout(function () {
button.classList.remove("error");
button.classList.add("pure-button-primary");
button.innerHTML = "OFF";
button.style.backgroundColor = "";
}, 2000);
showToast('Error while sending data to server.', 'error');
console.log('Error while sending data to server.');

File diff suppressed because it is too large Load diff

View file

@ -383,24 +383,20 @@ links.forEach(function(link) {
button.classList.remove("pure-button-primary");
button.classList.add("success");
button.innerHTML = "Disabled!";
button.style.backgroundColor = "green";
setTimeout(function () {
button.classList.remove("success");
button.classList.add("pure-button-primary");
button.innerHTML = "OFF";
button.style.backgroundColor = "";
}, 2000);
console.log('Data successfully sent to server!');
} else {
button.classList.remove("pure-button-primary");
button.classList.add("error");
button.innerHTML = "Error!";
button.style.backgroundColor = "red";
setTimeout(function () {
button.classList.remove("error");
button.classList.add("pure-button-primary");
button.innerHTML = "OFF";
button.style.backgroundColor = "";
}, 2000);
showToast('Error while sending data to server.', 'error');
console.log('Error while sending data to server.');
@ -436,24 +432,20 @@ links.forEach(function(link) {
button.classList.remove("pure-button-primary");
button.classList.add("success");
button.innerHTML = "Enabled!";
button.style.backgroundColor = "green";
setTimeout(function () {
button.classList.remove("success");
button.classList.add("pure-button-primary");
button.innerHTML = "ON";
button.style.backgroundColor = "";
}, 2000);
console.log('Data successfully sent to server!');
} else {
button.classList.remove("pure-button-primary");
button.classList.add("error");
button.innerHTML = "Error!";
button.style.backgroundColor = "red";
setTimeout(function () {
button.classList.remove("error");
button.classList.add("pure-button-primary");
button.innerHTML = "ON";
button.style.backgroundColor = "";
}, 2000);
showToast('Error while sending data to server.', 'error');
console.log('Error while sending data to server.');
@ -528,13 +520,13 @@ function createSlider(id, max, value, step) {
input.classList.add("pure-slider-range");
// Change the color of the slider based on the id
if (id.startsWith("ch1_")) {
input.style.background = "linear-gradient(to left, " + rgb2Hex(31, 119, 180) + ", white)";
input.style.background = "linear-gradient(to bottom, " + rgb2Hex(31, 119, 180) + ", white)";
} else if (id.startsWith("ch2_")) {
input.style.background = "linear-gradient(to left, " + rgb2Hex(255, 127, 14) + ", white)";
input.style.background = "linear-gradient(to bottom, " + rgb2Hex(255, 127, 14) + ", white)";
} else if (id.startsWith("ch3_")) {
input.style.background = "linear-gradient(to left, " + rgb2Hex(44, 160, 44) + ", white)";
input.style.background = "linear-gradient(to bottom, " + rgb2Hex(44, 160, 44) + ", white)";
} else if (id.startsWith("ch4_")) {
input.style.background = "linear-gradient(to left, " + rgb2Hex(214, 39, 40) + ", white)";
input.style.background = "linear-gradient(to bottom, " + rgb2Hex(214, 39, 40) + ", white)";
}
div = document.createElement("div");
@ -650,11 +642,9 @@ function sendDataToServer() {
button.classList.remove("pure-button-primary");
button.classList.add("error");
button.innerHTML = "Error!";
button.style.backgroundColor = "red";
setTimeout(function () {
button.classList.remove("error");
button.classList.add("pure-button-primary");
button.style.backgroundColor = "";
button.innerHTML = "save";
}, 2000);
console.log('Error while generating timing control data.');
@ -672,24 +662,20 @@ function sendDataToServer() {
button.classList.remove("pure-button-primary");
button.classList.add("success");
button.innerHTML = "Saved!";
button.style.backgroundColor = "green";
setTimeout(function () {
button.classList.remove("success");
button.classList.add("pure-button-primary");
button.innerHTML = "save";
button.style.backgroundColor = "";
}, 2000);
console.log('Data successfully sent to server!');
} else {
button.classList.remove("pure-button-primary");
button.classList.add("error");
button.innerHTML = "Error!";
button.style.backgroundColor = "red";
setTimeout(function () {
button.classList.remove("error");
button.classList.add("pure-button-primary");
button.innerHTML = "save";
button.style.backgroundColor = "";
}, 2000);
showToast('Error while sending timing control data to server.', 'error');
console.log('Error while sending data to server.');

View file

@ -12,24 +12,20 @@ links.forEach(function(link) {
button.classList.remove("pure-button-primary");
button.classList.add("success");
button.innerHTML = "Enabled!";
button.style.backgroundColor = "green";
setTimeout(function () {
button.classList.remove("success");
button.classList.add("pure-button-primary");
button.innerHTML = "ON";
button.style.backgroundColor = "";
}, 2000);
console.log('Data successfully sent to server!');
} else {
button.classList.remove("pure-button-primary");
button.classList.add("error");
button.innerHTML = "Error!";
button.style.backgroundColor = "";
setTimeout(function () {
button.classList.remove("error");
button.classList.add("pure-button-primary");
button.innerHTML = "ON";
button.style.backgroundColor = "";
}, 2000);
showToast('Error while sending data to server.', 'error');
console.log('Error while sending data to server.');
@ -57,24 +53,20 @@ links.forEach(function(link) {
button.classList.remove("pure-button-primary");
button.classList.add("success");
button.innerHTML = "Disabled!";
button.style.backgroundColor = "green";
setTimeout(function () {
button.classList.remove("success");
button.classList.add("pure-button-primary");
button.innerHTML = "OFF";
button.style.backgroundColor = "";
}, 2000);
console.log('Data successfully sent to server!');
} else {
button.classList.remove("pure-button-primary");
button.classList.add("error");
button.innerHTML = "Error!";
button.style.backgroundColor = "red";
setTimeout(function () {
button.classList.remove("error");
button.classList.add("pure-button-primary");
button.innerHTML = "OFF";
button.style.backgroundColor = "";
}, 2000);
showToast('Error while sending data to server.', 'error');
console.log('Error while sending data to server.');

View file

@ -1,118 +0,0 @@
//********************************//
void apply_scene(uint8_t new_scene, uint8_t light)
{
if (new_scene == SCENE_RELEAX)
{
bri[light] = 144;
} else if (new_scene == SCENE_BRIGHT)
{
bri[light] = 254;
} else if (new_scene == SCENE_NIGHTLY)
{
bri[0] = 25;
bri[1] = 0;
bri[2] = 0;
bri[3] = 0;
}
}
//********************************//
void process_lightdata(uint8_t light, float tt)
{
if (tt <= 0)
{
tt = default_transitiontime;
}
if (light_state[light])
{
step_level[light] = (bri[light] - current_bri[light]) / tt;
} else {
step_level[light] = current_bri[light] / tt;
}
}
//********************************//
void lightEngine()
{
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++)
{
if (light_state[i] == true)
{
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]))
{
current_bri[i] = bri[i];
//Serial.println("Reached target bri[" + (String)i + "] = " + (String)bri[i]);
}
uint16_t tmp_pwm = calcPWM(current_bri[i]);
current_pwm[i] = tmp_pwm;
//Serial.println("lon: pin" + (String)i + " = PWM(" + (String)tmp_pwm + ")");
analogWrite(pins[i], tmp_pwm);
}
} else { // light state is off
if (current_bri[i] != 0)
{
in_transition = true;
current_bri[i] -= step_level[i] / BRI_MOD_STEPS_PER_SEC;
if (current_bri[i] < 0)
{
current_bri[i] = 0;
//Serial.println("Reached target bri[" + (String)i + "] = " + (String)bri[i]);
}
uint16_t tmp_pwm = calcPWM(current_bri[i]);
current_pwm[i] = tmp_pwm;
//Serial.println("loff: pin" + (String)i + " = PWM(" + (String)tmp_pwm + ")");
analogWrite(pins[i], tmp_pwm);
}
}
} // for loop end
if (in_transition)
{
delay(6);
in_transition = false;
}
}
//********************************//
uint16_t calcPWM(float tbri)
{
uint16_t tmp_pwm = PWM_OFF;
if (tbri > 0.0)
{
tmp_pwm = PWM_MIN + (int)(tbri * BRI_TO_PWM_FACTOR);
}
if (tmp_pwm > PWM_MAX)
{
tmp_pwm = PWM_MAX;
}
return tmp_pwm;
}
//********************************//

View file

@ -1,225 +0,0 @@
//********************************//
#define TEST_PWM_STATE_INIT 0
#define TEST_PWM_STATE_CH1_INC 1
#define TEST_PWM_STATE_CH1_DEC 2
#define TEST_PWM_STATE_CH2_INC 3
#define TEST_PWM_STATE_CH2_DEC 4
#define TEST_PWM_STATE_CH3_INC 5
#define TEST_PWM_STATE_CH3_DEC 6
#define TEST_PWM_STATE_CH4_INC 7
#define TEST_PWM_STATE_CH4_DEC 8
//********************************//
bool test_pwm = false;
uint32_t test_pwm_lastcheck_ms = 0;
uint8_t test_pwm_state = TEST_PWM_STATE_INIT;
//********************************//
void test_pwm_main()
{
if (test_pwm == false)
{
return;
} else if ((test_pwm_lastcheck_ms + PWM_TEST_INTERVA_MS) <= millis())
{
test_pwm_lastcheck_ms = millis();
switch (test_pwm_state)
{
// ----------------------- //
case TEST_PWM_STATE_INIT:
// disable the lights
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
{
light_state[i] = false;
bri[i] = 0;
current_bri[i] = 0;
current_pwm[i] = 0;
transitiontime[i] = 0;
process_lightdata(i, transitiontime[i]);
}
light_state[0] = true;
test_pwm_state = TEST_PWM_STATE_CH1_INC;
break;
// ----------------------- //
case TEST_PWM_STATE_CH1_INC:
if (bri[0] < 255)
{
bri[0] += TEST_PWM_CHG_CNT;
transitiontime[0] = 1;
process_lightdata(0, transitiontime[0]);
} else {
test_pwm_state = TEST_PWM_STATE_CH1_DEC;
}
break;
case TEST_PWM_STATE_CH1_DEC:
if (bri[0] > 0)
{
bri[0] -= TEST_PWM_CHG_CNT;
transitiontime[0] = 1;
process_lightdata(0, transitiontime[0]);
} else {
light_state[0] = false;
bri[0] = 0;
current_bri[0] = 0;
current_pwm[0] = 0;
transitiontime[0] = default_transitiontime;
process_lightdata(0, transitiontime[0]);
light_state[1] = true;
test_pwm_state = TEST_PWM_STATE_CH2_INC;
}
break;
// ----------------------- //
case TEST_PWM_STATE_CH2_INC:
if (bri[1] < 255)
{
bri[1] += TEST_PWM_CHG_CNT;
transitiontime[1] = 1;
process_lightdata(1, transitiontime[1]);
} else {
test_pwm_state = TEST_PWM_STATE_CH2_DEC;
}
break;
case TEST_PWM_STATE_CH2_DEC:
if (bri[1] > 0)
{
bri[1] -= TEST_PWM_CHG_CNT;
transitiontime[1] = 1;
process_lightdata(1, transitiontime[1]);
} else {
light_state[1] = false;
bri[1] = 0;
current_bri[1] = 0;
current_pwm[1] = 0;
transitiontime[1] = default_transitiontime;
process_lightdata(1, transitiontime[1]);
light_state[2] = true;
test_pwm_state = TEST_PWM_STATE_CH3_INC;
}
break;
// ----------------------- //
case TEST_PWM_STATE_CH3_INC:
if (bri[2] < 255)
{
bri[2] += TEST_PWM_CHG_CNT;
transitiontime[2] = 1;
process_lightdata(2, transitiontime[2]);
} else {
test_pwm_state = TEST_PWM_STATE_CH3_DEC;
}
break;
case TEST_PWM_STATE_CH3_DEC:
if (bri[2] > 0)
{
bri[2] -= TEST_PWM_CHG_CNT;
transitiontime[2] = 1;
process_lightdata(2, transitiontime[2]);
} else {
light_state[2] = false;
bri[2] = 0;
current_bri[2] = 0;
current_pwm[2] = 0;
transitiontime[2] = default_transitiontime;
process_lightdata(2, transitiontime[2]);
light_state[3] = true;
test_pwm_state = TEST_PWM_STATE_CH4_INC;
}
break;
// ----------------------- //
case TEST_PWM_STATE_CH4_INC:
if (bri[3] < 255)
{
bri[3] += TEST_PWM_CHG_CNT;
transitiontime[3] = 1;
process_lightdata(3, transitiontime[3]);
} else {
test_pwm_state = TEST_PWM_STATE_CH4_DEC;
}
break;
case TEST_PWM_STATE_CH4_DEC:
if (bri[3] > 0)
{
bri[3] -= TEST_PWM_CHG_CNT;
transitiontime[3] = 1;
process_lightdata(3, transitiontime[3]);
} else {
test_pwm = false;
tc_enabled = tc_enabled_old;
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
{
light_state[i] = false;
bri[i] = 0;
current_bri[i] = 0;
current_pwm[i] = 0;
transitiontime[i] = default_transitiontime;
process_lightdata(i, transitiontime[i]);
}
tc_reset();
tc_update_main(); // load the tc if required
test_pwm_state = TEST_PWM_STATE_INIT;
}
break;
// ----------------------- //
default:
test_pwm_state = TEST_PWM_STATE_INIT;
}
Serial.println("---");
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
{
Serial.println("light_state[" + (String)i + "] = " + (String)light_state[i]);
Serial.println("bri[" + (String)i + "] = " + (String)bri[i]);
Serial.println("current_bri[" + (String)i + "] = " + (String)current_bri[i]);
Serial.println("current_pwm[" + (String)i + "] = " + (String)current_pwm[i]);
Serial.println("transitiontime[" + (String)i + "] = " + (String)transitiontime[i]);
}
}
}
//********************************//

View file

@ -180,15 +180,14 @@ void tc_update_main()
// no new predecessor or successor found, start over
current_target_data_block = 255;
Serial.println("No predecessor or successor found, start over...");
// disable the lights
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
{
light_state[i] = false;
bri[i] = 0;
current_bri[i] = 0;
current_pwm[i] = 0;
transitiontime[i] = default_transitiontime;
transitiontime[i] = 0;
process_lightdata(i, transitiontime[i]);
}
@ -208,15 +207,10 @@ void tc_update_main()
if (target_data_block >= NUMBER_OF_TIMER_DATA_BLOCKS)
{
// we are not between two valid data points, do nothing
Serial.println("tdb is >= num data blocks, abort operation...");
// TODO check if setting all lights to false is correct here
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
{
light_state[i] = false;
bri[i] = 0;
current_bri[i] = 0;
current_pwm[i] = 0;
transitiontime[i] = default_transitiontime;
process_lightdata(i, transitiontime[i]);
light_state[i] = false;
}
target_data_block = 255;
current_target_data_block = 255;
@ -239,7 +233,7 @@ void tc_update_main()
}
Serial.println("-----\ntdb = " + (String)target_data_block);
Serial.print("target dataset time: ");
Serial.print("target time: ");
Serial.print(tc_data[target_data_block].hh);
Serial.print(":");
Serial.print(tc_data[target_data_block].mm);
@ -277,9 +271,13 @@ void tc_update_main()
}
// enable the lights
light_state[0] = true;
light_state[1] = true;
light_state[2] = true;
light_state[3] = true;
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
{
light_state[i] = true;
Serial.println("light_state[" + (String)i + "] = " + (String)light_state[i]);
}

View file

@ -1,618 +0,0 @@
//********************************//
void handleNotFound()
{
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++)
{
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
}
//********************************//
void init_webserver()
{
// -------------------- //
server.on("/state", HTTP_PUT, []()
{ // HTTP PUT request used to set a new light state
DynamicJsonDocument root(512);
DeserializationError error = deserializeJson(root, server.arg("plain"));
if (error) {
server.send(404, "text/plain", "FAIL. " + server.arg("plain"));
} else {
for (JsonPair state : root.as<JsonObject>())
{
const char* key = state.key().c_str();
int light = atoi(key) - 1;
if (light < 0)
{
light = 0;
} else if (light > (LIGHTS_COUNT-1))
{
light = (LIGHTS_COUNT-1);
}
JsonObject values = state.value();
uint8_t tmp = EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS);
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)
{
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)
{
EEPROM.write(EEPROM_LAST_STATE_ADDRESS + light, LIGHT_STATE_OFF);
}
}
}
if (values.containsKey("bri"))
{
bri[light] = values["bri"];
}
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"))
{
default_transitiontime = values["transitiontime"];
if (default_transitiontime <= 0)
{
default_transitiontime = 1;
}
if (tc_enabled == TIMING_CONTROL_DISABLED)
{
for (uint8_t i = 0 ; i < LIGHTS_COUNT; i++)
{
// set the default transition time for all lights
process_lightdata(i, default_transitiontime);
}
}
}
}
String output;
serializeJson(root, output);
server.send(200, "text/plain", output);
}
});
// -------------------- //
server.on("/state", HTTP_GET, []()
{ // HTTP GET request used to fetch current light state
uint8_t light = server.arg("light").toInt() - 1;
if (light < 0)
{
light = 0;
} else if (light > (LIGHTS_COUNT-1))
{
light = (LIGHTS_COUNT-1);
}
DynamicJsonDocument root(512);
root["on"] = light_state[light];
root["bri"] = bri[light];
root["curbri"] = (int)current_bri[light];
root["curpwm"] = current_pwm[light];
String output;
serializeJson(root, output);
server.send(200, "text/plain", output);
});
// -------------------- //
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;
root["lights"] = LIGHTS_COUNT;
root["protocol"] = "native_multi";
root["modelid"] = "LWB010";
root["type"] = "dimmable_light";
root["mac"] = String(macString);
root["version"] = LIGHT_VERSION;
String output;
serializeJson(root, output);
server.send(200, "text/plain", output);
});
// -------------------- //
server.on("/test_pwm", []()
{
test_pwm = true;
tc_enabled_old = tc_enabled;
tc_enabled = TIMING_CONTROL_DISABLED;
server.send(200, "text/html", "OK");
});
// -------------------- //
server.on("/tc_data_blocks_read", []()
{
String output = tc_getJsonData();
server.send(200, "application/json", output);
});
// -------------------- //
server.on("/tc_data_blocks_store", []()
{
if (server.hasArg("data"))
{
String jsonData = server.arg("data");
Serial.println("Received: " + jsonData);
tc_jsonDataBlocksToEEPROM(jsonData);
server.send(200, "text/html", "tcdata saved");
}
});
// -------------------- //
server.on("/js_top", []()
{
server.send(200, "text/html", replacePlaceholder(loadSPIFFSFile("/top.js")));
});
// -------------------- //
server.on("/js_bottom", []()
{
server.send(200, "text/html", replacePlaceholder(loadSPIFFSFile("/bottom.js")));
});
// -------------------- //
server.on("/css", []()
{
server.send(200, "text/css", loadSPIFFSFile("/style.css"));
});
// -------------------- //
server.on("/", []()
{
if (server.hasArg("transition"))
{
default_transitiontime = server.arg("transition").toFloat();
if (default_transitiontime <= 0)
{
default_transitiontime = 1;
}
if (tc_enabled == TIMING_CONTROL_DISABLED)
{
for (uint8_t i = 0 ; i < LIGHTS_COUNT; i++)
{
// set the default transition time for all lights
process_lightdata(i, default_transitiontime);
Serial.println("transition for light " + (String)i + " set to " + (String)default_transitiontime);
}
}
}
// startup behavior switch handling
if (server.hasArg("startup"))
{
int startup = server.arg("startup").toInt();
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++) {
uint8_t tmp = (light_state[i] == true ? LIGHT_STATE_ON : LIGHT_STATE_OFF);
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));
}
}
// 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)
{
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));
tc_update_main(); // call the main update function to read data and set the light states
}
}
} else { // tc is set to false or something else
if (tc_enabled == TIMING_CONTROL_ENABLED)
{
tc_enabled = 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));
for (uint8_t i = 0 ; i < LIGHTS_COUNT; i++)
{
// set the default transition time for all lights
process_lightdata(i, default_transitiontime);
}
}
}
}
}
// scene switch handling
if (server.hasArg("scene"))
{
scene = server.arg("scene").toInt();
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));
}
}
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)
{
EEPROM.write(EEPROM_DYNAMIC_IP_ADDRESS, tmp2);
EEPROM.commit();
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++)
{
if (server.hasArg("bri" + (String)light))
{
int tmp = (int)server.arg("bri" + (String)light).toInt();
if (tmp > 255)
{
tmp = 255;
} else if (tmp < 0) {
tmp = 0;
}
bri[light] = tmp;
Serial.print("Brightness ");
Serial.print(light);
Serial.print(" set to ");
Serial.println(bri[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)
{
light_state[light] = true;
if (tmp == 0 && EEPROM.read(EEPROM_LAST_STATE_ADDRESS + light) == 0)
{
EEPROM.write(EEPROM_LAST_STATE_ADDRESS + light, LIGHT_STATE_ON);
EEPROM.commit();
}
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)
{
light_state[light] = false;
bri[light] = 0;
if (tmp == 0 && EEPROM.read(EEPROM_LAST_STATE_ADDRESS + light) == 1)
{
EEPROM.write(EEPROM_LAST_STATE_ADDRESS + light, LIGHT_STATE_OFF);
EEPROM.commit();
}
Serial.print("Light ");
Serial.print(light);
Serial.print(" state set to ");
Serial.println(light_state[light]);
}
if (tc_enabled == TIMING_CONTROL_DISABLED)
{
process_lightdata(light, default_transitiontime);
}
} else {
// light is off
if (tc_enabled == TIMING_CONTROL_DISABLED)
{
process_lightdata(light, default_transitiontime);
}
}
// start alerting for every light
if (server.hasArg("alert"))
{
if (light_state[light])
{
current_bri[light] = 0;
} else {
current_bri[light] = 255;
}
}
} // process all lights
if (server.hasArg("resettc"))
{ // reqrite the tc config and reboot
tc_write_default();
ESP.reset();
}
if (server.hasArg("reset"))
{
ESP.reset();
}
// ***** Generate static HTML page ***** //
String tmp1 = genHMTLTop();
String tmp2 = genLightControlHTML();
String tmp3 = getIndexHTMLMiddle();
String tmp4 = genConfigHTML();
String tmp5 = genHMTLBottom();
server.send(200, "text/html", tmp1 + tmp2 + tmp3 + tmp4 + tmp5);
});
// -------------------- //
server.on("/reset", []()
{ // trigger manual reset
server.send(200, "text/html", "reset");
delay(1000);
ESP.restart();
});
server.onNotFound(handleNotFound);
}
//********************************//
String genHMTLTop()
{
return replacePlaceholder(getIndexHTMLTop());
}
String genHMTLBottom()
{
return replacePlaceholder(getIndexHTMLBottom());
}
String genConfigHTML()
{
// +++++ Generate config part of the page +++++
return replacePlaceholder(getConfigHTML());
}
String genTCEditHTML()
{
return replacePlaceholder(getTCDataEditHTML());
}
String genLightControlHTML()
{
String http_content = "";
// +++++ Generate lights part of the HTML page +++++
// Light control
for (uint8 light_num = 0; light_num < LIGHTS_COUNT; light_num++)
{
// Generate lights part of the HTML page
String tmp_light_content = getLightControlHTML();
// on/off buttons and slider
tmp_light_content.replace("{{LIGHT_NUMBER}}", (String)(light_num + 1));
tmp_light_content.replace("{{LIGHT_NUMBER_DEC}}", (String)light_num);
// add the lights code to the html output string
http_content += tmp_light_content;
}
return http_content;
}
//********************************//
String replacePlaceholder(String http_content)
{
http_content.replace("{{LIGHT_NAME}}", (String)LIGHT_NAME);
http_content.replace("{{LIGHT_COUNT}}", (String)LIGHTS_COUNT);
int tc_val = EEPROM.read(EEPROM_TIMING_CONTROL_ENABLED_ADDRESS);
if (tc_val == TIMING_CONTROL_ENABLED)
{
http_content.replace("{{TC_LINK_PRIMARY_ON}}", "pure-button-primary");
} else {
http_content.replace("{{TC_LINK_PRIMARY_ON}}", "");
}
if (tc_val == TIMING_CONTROL_DISABLED)
{
http_content.replace("{{TC_LINK_PRIMARY_OFF}}", "pure-button-primary");
} else {
http_content.replace("{{TC_LINK_PRIMARY_OFF}}", "");
}
http_content.replace("{{TRANSITION_TIME}}", (String)default_transitiontime);
int ls_val = EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS);
if (ls_val == LAST_STATE_STARTUP_LIGHT_LAST_STATE)
{
http_content.replace("{{STARTUP_SELECTED_LS_0}}", "selected=\"selected\"");
} else {
http_content.replace("{{STARTUP_SELECTED_LS_0}}", "");
}
if (ls_val == LAST_STATE_STARTUP_LIGHT_ON_STATE)
{
http_content.replace("{{STARTUP_SELECTED_ON_1}}", "selected=\"selected\"");
} else {
http_content.replace("{{STARTUP_SELECTED_ON_1}}", "");
}
if (ls_val == LAST_STATE_STARTUP_LIGHT_OFF_STATE)
{
http_content.replace("{{STARTUP_SELECTED_OFF_2}}", "selected=\"selected\"");
} else {
http_content.replace("{{STARTUP_SELECTED_OFF_2}}", "");
}
// scene
int sc_val = EEPROM.read(EEPROM_SCENE_ADDRESS);
if (sc_val == SCENE_RELEAX)
{
http_content.replace("{{SCENE_SELECTED_RELAX_0}}", "selected=\"selected\"");
} else {
http_content.replace("{{SCENE_SELECTED_RELAX_0}}", "");
}
if (sc_val == SCENE_BRIGHT)
{
http_content.replace("{{SCENE_SELECTED_BRIGHT_1}}", "selected=\"selected\"");
} else {
http_content.replace("{{SCENE_SELECTED_BRIGHT_1}}", "");
}
if (sc_val == SCENE_NIGHTLY)
{
http_content.replace("{{SCENE_SELECTED_NIGHT_2}}", "selected=\"selected\"");
} else {
http_content.replace("{{SCENE_SELECTED_NIGHT_2}}", "");
}
// Wifi settings
http_content.replace("{{WIFI_SSID}}", WiFi.SSID());
// Network settings
uint8_t dip = EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS);
if (dip)
{
http_content.replace("{{DIP_LINK_ON_PRIMARY}}", "pure-button-primary");
http_content.replace("{{DIP_LINK_OFF_PRIMARY}}", "");
} else {
http_content.replace("{{DIP_LINK_OFF_PRIMARY}}", "pure-button-primary");
http_content.replace("{{DIP_LINK_ON_PRIMARY}}", "");
}
// network config
http_content.replace("{{WIFI_CFG_IP}}", WiFi.localIP().toString());
http_content.replace("{{WIFI_CFG_GW}}", WiFi.gatewayIP().toString());
http_content.replace("{{WIFI_CFG_NM}}", WiFi.subnetMask().toString());
http_content.replace("{{WIFI_CFG_DNS}}", WiFi.dnsIP().toString());
// add the current ip address to the page
http_content.replace("{{IP_ADDRESS}}", WiFi.localIP().toString());
// set the pwm values
http_content.replace("{{PWM_MIN}}", (String)PWM_MIN);
http_content.replace("{{PWM_MAX}}", (String)PWM_MAX);
return http_content;
}
//********************************//
String loadSPIFFSFile(String fname)
{
File file = SPIFFS.open(fname, "r");
if (!file)
{
Serial.println("Failed to open file " + fname);
return "";
}
String contents = file.readString();
file.close();
return contents;
}
//********************************//
String getIndexHTMLTop()
{
// load file
return loadSPIFFSFile("/index_template_top.html");
}
String getIndexHTMLMiddle()
{
// load file
return loadSPIFFSFile("/index_template_middle.html");
}
String getIndexHTMLBottom()
{
// load file
return loadSPIFFSFile("/index_template_bottom.html");
}
//********************************//
String getConfigHTML()
{
// load file
return loadSPIFFSFile("/config_template.html");
}
//********************************//
String getTCDataEditHTML()
{
// load file
return loadSPIFFSFile("/tc_data_edit.html");
}
//********************************//
String getLightControlHTML()
{
// load file
return loadSPIFFSFile("/light_control_template.html");
}
//********************************//