Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[P043] Add support for %sunrise% and %sunset% based time-values #4903

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
afc3214
[P043] Add support for %sunrise% and %sunset% based time-values
tonhuisman Dec 7, 2023
0b95025
[TimeCalc] Fix parse errors
tonhuisman Dec 9, 2023
028fc6c
[Text input] Add `datalist` support, manually cherry picked from P123 PR
tonhuisman Dec 9, 2023
f62038a
[Text input] Implement `datalist` support
tonhuisman Dec 9, 2023
70b0679
[P043] Add selection list (datalist) support for input time string
tonhuisman Dec 9, 2023
56d97c6
[P043] Rework Day,Time inputs, add configurable Day,Time count
tonhuisman Dec 10, 2023
8112d06
[P043] Change Value input layout to be on same line as the Day,Time i…
tonhuisman Dec 11, 2023
8539527
[P043] Add option for On/Off value input
tonhuisman Dec 12, 2023
edcae4d
[P043] Add 'config' command support and get config value support
tonhuisman Dec 16, 2023
ce73e4c
[P043] Add documentation
tonhuisman Dec 16, 2023
20962f0
[Build] Disable some failing build envs
tonhuisman Dec 17, 2023
e28cac3
[Docs] Add P043 to commands and events reference pages
tonhuisman Dec 17, 2023
49d420b
[P043] Fix simple Yes/No behavior like GPIO mode
tonhuisman Dec 19, 2023
f091f1f
[P043] Update documentation
tonhuisman Dec 19, 2023
deb7cf3
Merge branch 'mega' of https://github.com/letscontrolit/ESPEasy into …
tonhuisman Dec 28, 2023
8713131
[Build] Remove RTTTL from `normal_IRext_no_rx` build for size, add so…
tonhuisman Dec 28, 2023
ed90c1c
[P043] Exclude some code that won't work for PLUGIN_BUILD_MINIMAL_OTA…
tonhuisman Dec 28, 2023
f79c3c0
Merge branch 'mega' into feature/P043-support-sunrise-and-sunset-in-s…
TD-er Dec 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions src/_P043_ClkOutput.ino
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@
// #################################### Plugin 043: Clock Output #########################################
// #######################################################################################################

/** Changelog:
* 2023-12-07 tonhuisman: Add support for %sunrise[+/-offsetHMS]% and %sunset[+/-offsetHMS]% format in constants
* also supports long offsets up to 32767 seconds using S suffix in offset
* 2023-12-06 tonhuisman: Add changelog
*/

# define PLUGIN_043
# define PLUGIN_ID_043 43
# define PLUGIN_NAME_043 "Output - Clock"
# define PLUGIN_VALUENAME_043 "Output"
# define PLUGIN_VALUENAME_043 "Output"

// #define PLUGIN_VALUENAME1_043 "Output"
// #define PLUGIN_VALUENAME2_043 "Output2"
Expand Down Expand Up @@ -125,11 +130,20 @@ boolean Plugin_043(uint8_t function, struct EventStruct *event, String& string)
{
for (uint8_t x = 0; x < PLUGIN_043_MAX_SETTINGS; x++)
{
unsigned long clockEvent = (unsigned long)node_time.minute() % 10 | (unsigned long)(node_time.minute() / 10) <<
4 | (unsigned long)(node_time.hour() % 10) << 8 | (unsigned long)(node_time.hour() / 10) << 12 | (unsigned long)node_time.weekday() <<
16;
unsigned long clockEvent = (unsigned long)node_time.minute() % 10
| (unsigned long)(node_time.minute() / 10) << 4
| (unsigned long)(node_time.hour() % 10) << 8
| (unsigned long)(node_time.hour() / 10) << 12
| (unsigned long)node_time.weekday() << 16;
unsigned long clockSet = Cache.getTaskDevicePluginConfigLong(event->TaskIndex, x);

if (bitRead(clockSet, 28) || bitRead(clockSet, 29)) { // sunrise or sunset string, apply todays values
String specialTime = timeLong2String(clockSet);

parseSystemVariables(specialTime, false); // Parse systemvariables only, to reduce processing
clockSet = string2TimeLong(specialTime);
}

if (matchClockEvent(clockEvent, clockSet))
{
uint8_t state = Cache.getTaskDevicePluginConfig(event->TaskIndex, x);
Expand All @@ -148,9 +162,7 @@ boolean Plugin_043(uint8_t function, struct EventStruct *event, String& string)
}

if (loglevelActiveFor(LOG_LEVEL_INFO)) {
String log = F("TCLK : State ");
log += state;
addLogMove(LOG_LEVEL_INFO, log);
addLog(LOG_LEVEL_INFO, strformat(F("TCLK : State %d"), state));
}
sendData(event);
}
Expand Down
64 changes: 60 additions & 4 deletions src/src/Helpers/ESPEasy_time_calc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "../Globals/ESPEasy_time.h"
#include "../Helpers/StringConverter.h"
#include "../Helpers/SystemVariables.h"


#define SECS_PER_MIN (60UL)
Expand Down Expand Up @@ -194,10 +195,28 @@ String timeLong2String(unsigned long lngTime)
if (x == 0x0f) {
x = 0;
}
String weekDays = F("AllSunMonTueWedThuFriSatWrkWkd");
const String weekDays = F("AllSunMonTueWedThuFriSatWrkWkd");

time = weekDays.substring(x * 3, x * 3 + 3);
time += ',';

#ifndef PLUGIN_BUILD_MINIMAL_OTA

if (bitRead(lngTime, 28) || bitRead(lngTime, 29)) { // Sunrise or Sunset handling
time += SystemVariables::toString(bitRead(lngTime, 29) ? SystemVariables::Enum::SUNRISE : SystemVariables::Enum::SUNSET);

if ((lngTime & 0xffff) > 0) {
time += bitRead(lngTime, 30) ? '-' : '+'; // Sign
time += lngTime & 0xffff;
const String hms = F("smh");
const uint8_t idx = (lngTime >> 26) & 0x3; // 0/1/2 = s/m/h
time += hms.substring(idx, idx + 1);
}
time += '%';
return time;
}
#endif // ifndef PLUGIN_BUILD_MINIMAL_OTA

x = (lngTime >> 12) & 0xf;

if (x == 0xf) {
Expand Down Expand Up @@ -254,8 +273,9 @@ String timeLong2String(unsigned long lngTime)

unsigned long string2TimeLong(const String& str)
{
// format 0000WWWWAAAABBBBCCCCDDDD
// format 0NRSHM000000WWWWAAAABBBBCCCCDDDD
// WWWW=weekday, AAAA=hours tens digit, BBBB=hours, CCCC=minutes tens digit DDDD=minutes
// N = Negative offset, R = sunRise, S = sunSet, H = offset hours, M = offset minutes -> AAAA..DDDD = offset (default: seconds, binary stored, not bcd)

char command[20];
int w, x, y;
Expand All @@ -271,8 +291,9 @@ unsigned long string2TimeLong(const String& str)

if (GetArgv(command, TmpStr1, 1))
{
String day = TmpStr1;
String weekDays = F("allsunmontuewedthufrisatwrkwkd");
String weekDays = F("AllSunMonTueWedThuFriSatWrkWkd"); // Deduplicated string takes a little less memory...
weekDays.toLowerCase();
tonhuisman marked this conversation as resolved.
Show resolved Hide resolved

y = weekDays.indexOf(TmpStr1) / 3;

if (y == 0) {
Expand All @@ -285,6 +306,41 @@ unsigned long string2TimeLong(const String& str)
{
y = 0;

#ifndef PLUGIN_BUILD_MINIMAL_OTA

uint8_t off = TmpStr1.startsWith(SystemVariables::toString(SystemVariables::Enum::SUNRISE)) ? 8u : 0u;

if (off || TmpStr1.startsWith(SystemVariables::toString(SystemVariables::Enum::SUNSET))) {
if (off == 0) { off = 7; }
int lperc = TmpStr1.indexOf('%', off + 1);

if (lperc > off) { // Valid variable used, having a second % sign?
bitSet(lngTime, 21u + off); // bit 28 = sunset, bit 29 = sunrise
int delta = ESPEasy_time::getSecOffset(TmpStr1.substring(off, lperc + 1));
const bool isSeconds = 's' == TmpStr1[lperc - 1];

if (delta < 0) {
bitSet(lngTime, 30); // bit 30 = negative offset
delta *= -1;
}

if (delta > 86400) { // > 24 hours = invalid, reset
delta = 0;
bitClear(lngTime, 30);
} else if (isSeconds && (delta < 32768)) { // Seconds, explicitly, max. delta we can store
} else if (delta >= 3600) { // Hours
delta /= 3600;
bitSet(lngTime, 27); // Bit 27: Stored as Hours
} else if (delta >= 60) { // Minutes
delta /= 60;
bitSet(lngTime, 26); // Bit 26: Stored as Minutes
} // else: Stored as seconds
lngTime += delta; // Store offset
return lngTime;
}
}
#endif // ifndef PLUGIN_BUILD_MINIMAL_OTA

for (x = TmpStr1.length() - 1; x >= 0; x--)
{
w = TmpStr1[x];
Expand Down