lumini_p30_control/firmware/timing_control.ino
2023-04-27 11:26:21 +02:00

368 lines
11 KiB
C++

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include "config.h"
//***********************************//
// 6 byte
#define TIMER_DATA_HH 0
#define TIMER_DATA_MM 1
#define TIMER_DATA_CH1 2 // the brightness of the channel
#define TIMER_DATA_CH2 3 // the brightness of the channel
#define TIMER_DATA_CH3 4 // the brightness of the channel
#define TIMER_DATA_CH4 5 // the brightness of the channel
#define LENGTH_OF_TIMER_DATA_BLOCK (TIMER_DATA_CH4 + 1)
#define NUMBER_OF_TIMER_DATA_BLOCKS 10
//***********************************//
/* Globals */
bool tc_testOngoing = true;
uint32_t tc_last_check = 60000;
long utcOffsetInSeconds = 3600;
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, MY_NTP_SERVER, utcOffsetInSeconds);
struct tc_data_st {
uint8_t hh;
uint8_t mm;
uint8_t ch1;
uint8_t ch2;
uint8_t ch3;
uint8_t ch4;
};
struct tc_data_st tc_data[10];
uint8_t example_timer_data_block[] = {
// hour min ch1 ch2 ch3 ch3
8, 0, 0, 0, 0, 0, // 0: off
8, 30, 25, 0, 0, 0, // 1: 10% ch1 blues
9, 0, 25, 0, 25, 0, // 2: 10% all blues
13, 0, 205, 205, 205, 205, // 3: 80% all
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, 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[] = {
// state hour min ch1 ch2 ch3 ch3
9, 20, 0, 0, 0, 0, // 0: off
9, 30, 25, 0, 0, 0, // 1: 10% ch1 blues
9, 40, 25, 0, 25, 0, // 2: 10% all blues
9, 50, 205, 205, 205, 205, // 3: 80% all
10, 0, 100, 100, 100, 100, // 4: 80% all for 5 hours
10, 10, 50, 50, 50, 50, // 5: 20% all
10, 20, 50, 0, 50, 0, // 6: 20% all blues
10, 30, 25, 0, 0, 0, // 7: 10% ch1 blues
10, 40, 0, 0, 0, 0, // 8: all off
11, 0, 0, 0, 0, 0, // 9: all off
};
//***********************************//
void tc_init()
{
if (tc_check_no_data_block() == true)
{
//Serial.println("TC: No data block found, writing example block to EEPROM.");
tc_write_default();
}
while ( WiFi.status() != WL_CONNECTED )
{
delay (500);
Serial.print ( "." );
}
tc_last_check = millis();
timeClient.begin();
Serial.println("TC: Read data block from eeprom");
tc_readConfig();
if (tc_testOngoing == true)
{
Serial.println("TC: Test ongoing, reading test data");
for (uint8_t i = 0; i < NUMBER_OF_TIMER_DATA_BLOCKS * LENGTH_OF_TIMER_DATA_BLOCK; i += LENGTH_OF_TIMER_DATA_BLOCK)
{
tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].hh = test_timer_data_block[i];
tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].mm = test_timer_data_block[i+1];
tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].ch1 = test_timer_data_block[i+2];
tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].ch2 = test_timer_data_block[i+3];
tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].ch3 = test_timer_data_block[i+4];
tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].ch4 = test_timer_data_block[i+5];
Serial.print("data block: "); Serial.println(i / LENGTH_OF_TIMER_DATA_BLOCK);
Serial.print(" hh: "); Serial.println(tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].hh);
Serial.print(" mm: "); Serial.println(tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].mm);
Serial.print(" ch1: "); Serial.println(tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].ch1);
Serial.print(" ch2: "); Serial.println(tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].ch2);
Serial.print(" ch3: "); Serial.println(tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].ch3);
Serial.print(" ch4: "); Serial.println(tc_data[i / LENGTH_OF_TIMER_DATA_BLOCK].ch4);
}
}
tc_update_main();
}
//********************************//
void tc_update_loop()
{
static uint8_t last_min_check = 255;
if ((timeClient.getMinutes() % 10) != 0 || last_min_check == timeClient.getMinutes()) // && tc_testOngoing == false
{
last_min_check = timeClient.getMinutes();
return; // only run every 10 minutes
}
tc_update_main();
}
void tc_update_main()
{
static uint8_t current_target_data_block = 255;
uint8_t target_data_block = 255;
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--)
{
//Serial.println((String)tc_data[i].hh + ":" + (String)tc_data[i].mm);
if (tc_data[i].hh <= timeClient.getHours() &&
tc_data[i].mm <= timeClient.getMinutes())
{
target_data_block = i+1; // found the next block to load
}
//Serial.println((String)i + " => " + target_data_block);
}
if (target_data_block == 255)
{
// no new predecessor or successor found, start over
current_target_data_block = 255;
return;
}
if (current_target_data_block != target_data_block)
{
// new target block should be reached
current_target_data_block = target_data_block;
} else {
// drop the found target block, we are already going on to reach it
return;
}
if (target_data_block >= NUMBER_OF_TIMER_DATA_BLOCKS)
{
target_data_block = 255;
current_target_data_block = 255;
return;
}
// print out the current light state
Serial.println("-----\nCurrent values");
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
{
Serial.println("current_bri[" + (String)i + "] = " + (String)current_bri[i]);
}
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
{
Serial.println("bri[" + (String)i + "] = " + (String)bri[i]);
}
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
{
Serial.println("step_level[" + (String)i + "] = " + (String)step_level[i]);
}
Serial.println("-----\ntdb = " + (String)target_data_block);
Serial.print("target time: "); Serial.print(tc_data[target_data_block].hh); Serial.print(":"); Serial.print(tc_data[target_data_block].mm); Serial.println();
// set the channels current and target brightness
bri[0] = tc_data[target_data_block].ch1;
bri[1] = tc_data[target_data_block].ch2;
bri[2] = tc_data[target_data_block].ch3;
bri[3] = tc_data[target_data_block].ch4;
if (tc_data[target_data_block-1].ch1 != current_bri[0])
{
current_bri[0] = tc_data[target_data_block-1].ch1;
}
if (tc_data[target_data_block-1].ch2 != current_bri[1])
{
current_bri[1] = tc_data[target_data_block-1].ch2;
}
if (tc_data[target_data_block-1].ch3 != current_bri[2])
{
current_bri[2] = tc_data[target_data_block-1].ch3;
}
if (tc_data[target_data_block-1].ch4 != current_bri[3])
{
current_bri[3] = tc_data[target_data_block-1].ch4;
}
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
{
Serial.println("current_bri[" + (String)i + "] = " + (String)current_bri[i]);
}
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
{
Serial.println("bri[" + (String)i + "] = " + (String)bri[i]);
}
// 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++)
{
Serial.println("light_state[" + (String)i + "] = " + (String)light_state[i]);
}
// set the transition time
int t_time = 0;
if (target_data_block > 0)
{
// hours as seconds from now on to the next enabled block
t_time = ((uint16_t)tc_data[target_data_block].hh * 60 * 60) - ((uint16_t)timeClient.getHours() * 60 * 60);
// add the left over seconds to the next enabled block
t_time += ((uint16_t)tc_data[target_data_block].mm * 60) - ((uint16_t)timeClient.getMinutes() * 60);
}
transitiontime[0] = t_time;
transitiontime[1] = t_time;
transitiontime[2] = t_time;
transitiontime[3] = t_time;
// calculate the step level
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
{
process_lightdata(i, transitiontime[i]);
Serial.println("transitiontime[" + (String)i + "] = " + (String)transitiontime[i]);
}
for (uint8_t i = 0; i < LIGHTS_COUNT; i++)
{
Serial.println("step_level[" + (String)i + "] = " + (String)step_level[i]);
}
}
//********************************//
void tc_updateTime()
{
/**/
if (timeClient.update() || millis() > (tc_last_check + TIME_CHECK_INTERVAL_MS))
{
tc_last_check = millis();
//Serial.println("TC: Read time from server...");
//Serial.println(timeClient.getFormattedTime());
/*
if (dow == 7 && mo == 10 && d >= 25 && h == 3 && DST==1)
{
// DST=0;
timeClient.setTimeOffset(utcOffsetInSeconds);
timeClient.forceUpdate();
} else if (dow == 7 && mo == 3 && d >= 25 && h ==2 && DST==0)
{
// DST = 1
timeClient.setTimeOffset(utcOffsetInSeconds * 2);
timeClient.forceUpdate();
}
*/
Serial.print("=====\nLocal time: ");
Serial.print(timeClient.getHours());
Serial.print(":");
Serial.println(timeClient.getMinutes());
}
/**/
}
//********************************//
void tc_readConfig()
{
for (uint8_t i = 0; i < NUMBER_OF_TIMER_DATA_BLOCKS; i++)
{
/*Serial.print("Reading from address: "); Serial.print(EEPROM_TIMING_DATA_ADDRESS);
Serial.print(" + (");
Serial.print(i);
Serial.print(" * ");
Serial.print(LENGTH_OF_TIMER_DATA_BLOCK);
Serial.print(") + ");
Serial.println(TIMER_DATA_ENSTATE);*/
tc_data[i].hh = EEPROM.read(EEPROM_TIMING_DATA_ADDRESS + i * LENGTH_OF_TIMER_DATA_BLOCK + TIMER_DATA_HH);
tc_data[i].mm = EEPROM.read(EEPROM_TIMING_DATA_ADDRESS + i * LENGTH_OF_TIMER_DATA_BLOCK + TIMER_DATA_MM);
tc_data[i].ch1 = EEPROM.read(EEPROM_TIMING_DATA_ADDRESS + i * LENGTH_OF_TIMER_DATA_BLOCK + TIMER_DATA_CH1);
tc_data[i].ch2 = EEPROM.read(EEPROM_TIMING_DATA_ADDRESS + i * LENGTH_OF_TIMER_DATA_BLOCK + TIMER_DATA_CH2);
tc_data[i].ch3 = EEPROM.read(EEPROM_TIMING_DATA_ADDRESS + i * LENGTH_OF_TIMER_DATA_BLOCK + TIMER_DATA_CH3);
tc_data[i].ch4 = EEPROM.read(EEPROM_TIMING_DATA_ADDRESS + i * LENGTH_OF_TIMER_DATA_BLOCK + TIMER_DATA_CH4);
/*Serial.print("data block: "); Serial.print(i);
Serial.print(" @ ");
Serial.println((EEPROM_TIMING_DATA_ADDRESS + (i * LENGTH_OF_TIMER_DATA_BLOCK) + TIMER_DATA_ENSTATE));
Serial.print(" es: "); Serial.println(tc_data[i].enstate);
Serial.print(" hh: "); Serial.println(tc_data[i].hh);
Serial.print(" mm: "); Serial.println(tc_data[i].mm);
Serial.print(" ch1: "); Serial.println(tc_data[i].ch1);
Serial.print(" ch2: "); Serial.println(tc_data[i].ch2);
Serial.print(" ch3: "); Serial.println(tc_data[i].ch3);
Serial.print(" ch4: "); Serial.println(tc_data[i].ch4);*/
}
}
//********************************//
void tc_write_default()
{
//Serial.print("-----\nWrite data block starting from address EEPROM_TIMING_DATA_ADDRESS = "); Serial.println(EEPROM_TIMING_DATA_ADDRESS);
for (int i = 0; i < NUMBER_OF_TIMER_DATA_BLOCKS * LENGTH_OF_TIMER_DATA_BLOCK; i++)
{
//Serial.print(EEPROM_TIMING_DATA_ADDRESS + i); Serial.print(" <= "); Serial.print(example_timer_data_block[i]); Serial.print(" <= ");
EEPROM.write(EEPROM_TIMING_DATA_ADDRESS + i, example_timer_data_block[i]);
EEPROM.commit();
//Serial.println(EEPROM.read(EEPROM_TIMING_DATA_ADDRESS + i));
}
//Serial.println("-----");
}
//********************************//
bool tc_check_no_data_block()
{
//Serial.print("Check data block address EEPROM_TIMING_DATA_ADDRESS = "); Serial.println(EEPROM_TIMING_DATA_ADDRESS);
uint8_t e = EEPROM.read(EEPROM_TIMING_DATA_ADDRESS);
//Serial.println(e);
if (e == 255)
{
return true;
}
return false;
}
//********************************//