Hi dude,
uhm, right, let's see (this is going to be a loooong read):
- Unfortunately there is no log for the actions, it would take petabytes of storage per server if we were to log every users action execution. I have some actions that execute every 10sec to create a sort of mesh network so 3 devices are working as a single brain (one primary and two as remote satellite sensors) and that alone generates around 800,000 action calls per month! :-)
- But...why don't you enable the log on that outdoor light switch component? Just set it to log like 1 hour, you could probably have a log that spans a month or more on that component and you can check it any time. That would show you if the device is getting the instructions.
- If possible I would change the way you use the action. At the moment as you have figured you can't have the same device component as a trigger and target. That's simply to prevent infinite loop conditions (click/clack/click/clack....) that could get ChipChop engine to ban your device :-)
The way I do it involves a secondary device, it can be anything, any additional device that sends a regular heartbeat (if cost is an issue I'll send you one...have a ton of ESPs asking to be used :-)
So, the trick is to have an action that is "guaranteed" to execute on "every" heartbeat, that means that whatever the status of that secondary device "will be" you have to match and that usually means testing for a negative impossible condition!
For example - I use a temperature & humidity esp for that purpose, the action checks if the temperature is
not != -1000 which it will never be so the IF statement will always be correct and the action will execute on every heartbeat
or
- you create a fake component on that secondary device, let's call it "pulse" that only do ChipChop.updateStatus("pulse",1)
The action checks if
pulse == 1 and executes on every heartbeat
Then you simply target your
outdoor lights switch 1 > light-01 to be OFF and same time/day settings
The good thing doing it this way is that the action will first check if the
outdoor lights switch 1 > light-01 == ON and only execute once in that time period (assuming it get's the status OFF confirmed through the heartbeat), that reduces a flood of commands sent to your light switch. Also, you don't have to add anything extra in your code to check for command target "any"
Another optionThis is a more elegant option that I use a lot and will also work for some period of time even if the device looses wifi so hear me out.
- If you've set the device timezone correctly the ChipChop library gets a correct timestamp back on every heartbeat and synchronises its internal clock.
- You need some way to save a little "settings" file on the esp, you can use the PreferencesManager plugin from the ChipChop Code Builder or you can do it yourself with LittleFS or something like that
- Create two extra components (time1_off, time2_off) and program the logic that when you send a command to change those times to save those values and set up some off_time variables
and also on every restart to load the strings from the file and again adjust those variables
That way you can re-program the schedule whenever you want without even using actions
- In the loop you check what the time is from the ChipChop library and if it falls within your off schedule you switch the light off
Here is a quick and dirty example, you would need to generate a code templkate through the Code Builder first just to get the structure with the PreferencesManager and plugin manager
int light_pin = 2;
String light_swicth_1_state = "OFF";
void ChipChop_onCommandReceived(String target_component,String command_value, String command_source, int command_age){
//this would be using two components added to the device in the Dev Console
// the value will be in "minute of the day" format (hour * 60 + minute)
if(target_component == "off_1" || target_component == "off_2"){
int time = command_value.toInt();
PrefsManager.save("schedule",target_component,time);
}
if(target_component == "light-01"){
if(command_value == "ON"){
digitalWrite(light_pin, HIGH);
}else{
digitalWrite(light_pin, LOW);
}
light_swicth_1_state = command_value;
ChipChop.updateStatus("light-01",command_value);
}
}
//default setting that will potentially get overwritten but we need something to start
int time1_off = (6 * 60) + 30; //<< cheeky trick, convert the time to a "minute of the day"
int time2_off = (18 * 60) + 30;
void setup(){
///bla blah Wifi etc
String saved_off_1 = PrefsManager.get("schedule","off_1");
time1_off = saved_off_1.toInt();
String saved_off_2 = PrefsManager.get("schedule","off_2");
time2_off = saved_off_2.toInt();
}
void loop(){
if(ChipChop.Date.timestamp != 0){ // << will be zero before the first heartbeat is sent
int currTime = (ChipChop.Date.hour * 60) + ChipChop.Date.minute; //convert to minute of the day
if(currTime >= time1_off && currTime <= time2_off && light_swicth_1_state == "ON"){
//switch your light off
digitalWrite(light_pin, LOW);
ChipChop.updateStatus("light-01","OFF");
}
}
}
And now you are effectively re-programming your device without re-compiling or hardcoding or scripting.
This will also work if wifi goes off as once the ChipChop lib sends the first heartbeat and gets its first timestamp it keeps updating its internal clock every second up to the max integer (when millis() rollover to zero) or the device is restarted
The first thing I've implemented was the timezone timestamp (still have nightmares) so you don't need an RTC or NTP server and then have to do all timezone offsets, day light saving etc crap. ChipChop does it for you automatically (I've built a dedicated server that recalculates all timezones every minute, was cheaper than paying for API calls to some of the online services (frigging expensive stuff :-)
What do you think, would some of this work?
G