Time trigger - Sunrise/Sunset

Edit – Full code available here: https://github.com/joel-wehr/electric_imp_weather_ch_trigger

I’d like to configure the agent for one of my A/C switch Imps to turn on at sunset, and off at sunrise. I can pull the current time and sunrise/sunset from the weather channel API. (Thanks @beardedinventor and or @tombrew for the code). I’m trying to work through how to trigger that. I believe I can get the current time, determine if sunrise or sunset will be the next trigger, calculate the time between now and then, and have the imp wakeup and switch.

This agent is also regularly waking and searching Twitter, can I queue multiple wake events? Actually, I’m not completely sure when imp.wakeup means when it is executed by the agent, if you are only executing code from the agent.

Am I on the right track? Any easier ways to do this?

You can have multiple imp.wakeup’s queued in either imp or agent code. It’s bad naming I’m afraid - it does the same thing in either case (call some code in the agent or imp after the timer elapses).

It doesn’t, eg, wake the imp if you run it on the agent :slight_smile:

I was thinking about maybe you could use an array of sunrise/sunset times in the imp, but the imp doesn’t have a clock anyhow. I guess you need something external to the imp that sends it a ping when sunrise or sunset. Put a light sensor outside and a wireless receiver next to the imp? boy, this is a tough one.

I definitely want to use the WC API, as this is very much an exercise in figuring out how to get data and trigger things with the agent…though a light sensor would work.

I was thinking about using a clock first, but I don’t think I need to. I’ll get the current time and sunrise and sunset time, then convert them all to minutes. Then I’ll check if the next trigger is sunrise or sunset, and find the difference. I’ll throw that difference in a wakeup trigger, and recalculate at the trigger.

Here is what I am trying… I think this will work:

local response = http.jsondecode(res.body); local astronomy = response.moon_phase; local sunrise = ""; sunrise += (astronomy.sunrise.hour + ":" + astronomy.sunrise.minute); server.log("Sunrise: " + sunrise); local sunset = ""; sunset += (astronomy.sunset.hour + ":" + astronomy.sunset.minute); server.log("Sunset: " + sunset); // Get and convert the current time to minutes since zero hour. local mszh = (astronomy.current_time.hour.tointeger() * 60) + (astronomy.current_time.minute.tointeger()); server.log("MSZH: " + mszh); //convert sunset to minutes local sunsetmin = (astronomy.sunset.hour.tointeger() * 60) + (astronomy.sunset.minute.tointeger()); server.log("Sunset in Minutes: " + sunsetmin); local sunrisemin = (astronomy.sunrise.hour.tointeger() * 60) + (astronomy.sunrise.hour.tointeger()); server.log("Sunrise in Minutes: " + sunrisemin); local min_till = 0; //if the current time is prior to sunrise that day if (mszh <= sunrisemin && mszh < sunsetmin) { min_till = sunrisemin - mszh; server.log(min_till + " minutes until sunrise."); min_till = min_till + 1; imp.wakeup(min_till, switchOff); //Turn off switch } //if the current time is after sunrise and before sunset else if (mszh > sunrisemin && mszh <= sunsetmin) { min_till = sunsetmin - mszh; server.log(min_till + " minutes until sunset.") min_till = min_till + 1; imp.wakeup(min_till, switchOn); //Turn on switch } //if the current time is after sunset else { min_till = (1440 - mszh); server.log(min_till + " minutes until 2400 hours.") min_till = min_till + 1; imp.wakeup(min_till, getConditions); //Wait until tommorrow, and get data }

Why do I always feel like I am cheating when I program in a loosely typed language?

That’s the complete code? How does it know where I am?

It isn’t… That just the part I modified from the “wunderground” code on the GitHub page. I was specifically sharing how I set the triggers.

Wow… the pasted code randomly removed underscores in my min_till variable as well…

The underscores are actually there, just hidden - because of the terrible code formatting on the forums.

I have to say… I’m not a huge fan of the yellow… I’ve been tempted to just bold the code snippets…

Ooops… imp.wakeup takes seconds, not minutes… had to fix that…15 minutes till sunset, fingers crossed.

Sweet! Turned on my Jack-o-Lantern at sunset!

That’s awesome!!!

Made a few modifications… seems to be working correctly now. I posted the full agent code on this GitHub repo.

My code makes sure that imp.wakeup() is never passed 0 as a parameter. Would passing a 0 work?

Adding 1 minute also makes sure the function doesn’t cycle continuously during the sunrise/sunset minutes.

Passing a 0 to imp.wakeup makes it behave like imp.onidle.

So… imp.wakeup(0, someFunction) is identical to imp.onidle(someFunction)

Ahh, that makes sense. I think I’ll modify my code and just have it wait for a minute after a successful trigger to get the next trigger. Thanks!

@beardedinventor …almost identical. You can only have one onidle handler (the second call to register one (without idle happening between them) will replace the first.

Multiple imp.wakeup’s can be queued concurrently though.

I was thinking about the imp not knowing the time. When you are sleeping that much it’s difficult to keep up with time. But since the imp has SPI channels you may consider to add a small IC on your design such as NXP’s PCF2123, which is a an SPI real time clock and calender. Interesting features: 1. the supply current is below 1µm when only the clock runs and everything is sleeping; 2. it has an interrupt signal which can wake up the imp at a preset time. Digikey sells production quantities below USD 0.50.

@foehrr Thanks for the tip, I’ll grab one on my next Digikey order and check it out. The Weather Channel only gives me minute resolution, so my current trigger is generally off by some fraction of a minute. Not a big deal, unless you are trying to impress your niece by telling her that the great pumpkin rises and glows at the stroke of sunset, and then it doesn’t happen for another 34 seconds. :slight_smile: (She was still impressed.)