-->
Page 1 of 3

ESP8266 Basic Relay Clock

PostPosted: Sat Jan 07, 2017 1:08 pm
by robert badiduwitz
Here is a little project I made for a friend of mine. Its a programmable relay/clock. All relay times are added using the web interface. It only uses 2 components, 4 dupont wires and a 5 volt wall wart. The main module is from Olimex and has an ESP8266 with 2M, power supply, button, relay and gpio pins. The display is an I2C module from Adafruit. The Olimex board has the pullups on GPIO 2 and GPIO 4 already for the I2C (how convenient). There are more things that can be added of course, like dim the display with a slider or at a certain time, or getting rid of the 30 second start up time, etc. I am not the greatest coder, so if you see something that can be improved, please let me know.

When you first power it up and it hasn't connected to your wifi network, it will display 192 then 168 then 4 then 1, then you would connect to the AP and go to 192.168.4.1 in your browser. It will display a simple web page to ask for your wifi data then reboot. It will then display the IP address so you can connect to it using a browser. It will then just display the current time and check every second to see if the relay should be on or off. It will also adjust for the daylight savings time. You can also toggle the relay from the webpage. The stand is 1/8" acrylic that was bent using a hotwire bender. Other than putting the adafruit display together, there is no other soldering necessary.

The on board button has 2 operations. If you press it quickly, it will toggle the relay. If you hold it for more than 2 seconds and release, it will display its IP address in case you forget it. This excellent piece of code is from Electroguard. The I2C display code is from Viscomjim. Most all of the code was found on this forum and of course, the excellent work of Mike!!!

I am still having a problem with adding more than 5 on off times and the winsock connect/disconnect working correctly, but will keep playing. Please let me know if you have any ideas about this.

Display - https://www.adafruit.com/product/879

ESPboard - https://www.olimex.com/Products/IoT/ESP ... e-hardware
available here... https://www.digikey.com/product-detail/ ... ND/5226245


Image

Image

Image

Image

Image

The power and I2C connections for the display are shown in red in the board schematic below...

Image

Code: Select allcls
memclear

localip = ip()

brightness = 15
relay = D1
'led = 1
buttonpin = D3
address = 112
count = 1
col = 0
dot = 0
timer 0

gosub [relayoff]

dim digits(11)
digits(0) = 63
digits(1) = 6
digits(2) = 91
digits(3) = 79
digits(4) = 102
digits(5) = 109
digits(6) = 125
digits(7) = 7
digits(8) = 127
digits(9) = 111
digits(10) = 0

'************ INITIALIZE DISPLAY
i2c.setup(D4,D2)
i2c.begin(address)
i2c.write(33)
i2c.end()
i2c.begin(address)   
i2c.write(129)
i2c.end()
i2c.begin(address)
bright = 224 + brightness
i2c.write(bright) 
i2c.end()
delay 10

i2c.begin(address)
i2c.write(4)
i2c.write(0)
i2c.end()

gosub [showip]

'************ CHECK IF AP MODE
if localip = "192.168.4.1" then
cls
wprint "Welcome to Relay Clock <br>"
wprint "Enter your WIFI info below <br>"
wprint "Hit Save and Reboot <br><br>"

wprint "WIFI Name:"
textbox wifiname
wprint "<br>"
wprint "WIFI Pass:"
textbox wifipass
wprint "<br><br>"
button "Save WIFI Settings",[wifiupdate]
wprint "<br> <br>"
button "Reboot Clock",[reboot]
wprint "<br> <br>"
wait
end if

'************ GET SAVED INFO
dst = read.val(DaylightSavings)
timezone = read.val(TZ)
wifiname = read(WIFIname)
wifipass = read(WIFIpass)

ontime1 = read(ontimes1)
ontime2 = read(ontimes2)
ontime3 = read(ontimes3)
ontime4 = read(ontimes4)
ontime5 = read(ontimes5)

offtime1 = read(offtimes1)
offtime2 = read(offtimes2)
offtime3 = read(offtimes3)
offtime4 = read(offtimes4)
offtime5 = read(offtimes5)

if dst = 1 then
tz = timezone + 1
else
tz = timezone
endif

timesetup(tz,dst)
delay 5000

interrupt buttonpin, [pressed]

serialprintln "flash 1 " & flashfree()
serialprintln "ram 1 " & ramfree()

wprint "<h2>RELAY CLOCK V1.0</h2>"
wprint "<br>"
curtime = time("hour:min:sec")
wprint "Time Now:  "
textbox curtime

wprint "<br><br>"
wprint "Timezone:  "
textbox timezone
wprint "<br>"
wprint "DST 1 or 0:  "
textbox dst
wprint "<br><br>"
button "Update Time Info",[timeupdate]
wprint "<br><br>"

wprint "Enter relay times in HH:MM:SS 24 hour format"
wprint "<br>"
wprint |Press "Save Relay Times" button when done|
wprint "<br><br>"

wprint "On Time 1 "
textbox ontime1
wprint "Off Time 1"
textbox offtime1
wprint "<br>"

wprint "On Time 2 "
textbox ontime2
wprint "Off Time 2"
textbox offtime2
wprint "<br>"

wprint "On Time 3 "
textbox ontime3
wprint "Off Time 3"
textbox offtime3
wprint "<br>"

wprint "On Time 4 "
textbox ontime4
wprint "Off Time 4"
textbox offtime4
wprint "<br>"

wprint "On Time 5 "
textbox ontime5
wprint "Off Time 5"
textbox offtime5
wprint "<br>"

button "Save Relay Times",[updrelay]

wprint "<br><br>"
button "Toggle Relay",[togrelay]
textbox relaystat
wprint "<br><br>"
button "End Program",[exit]

returngui

timer 1000,[colon]

wait


'************ COLON 1000ms  *************
[colon]
if col = 0 then dot = 0 else dot = 2
i2c.begin(address)
i2c.write(4)
i2c.write(dot)
i2c.end()
delay 10
if col = 1 then col = 0 else col = 1

curtime = time("hour:min:sec")
gosub [checkrelay]
gosub [refresh]

wait

'************ BUTTON PRESSED  *************
[pressed]
if io(laststat,buttonpin) == 0 then start = millis() else stop = millis()
if stop > start then
if stop-start < 2000 then goto [togrelay] else gosub [showip]
endif
wait

'************ CHECK RELAY TIMES  *************
[checkrelay]
if curtime = ontime1 then gosub [relayon]
if curtime = offtime1 then gosub [relayoff]
if curtime = ontime2 then gosub [relayon]
if curtime = offtime2 then gosub [relayoff]
if curtime = ontime3 then gosub [relayon]
if curtime = offtime3 then gosub [relayoff]
if curtime = ontime4 then gosub [relayon]
if curtime = offtime4 then gosub [relayoff]
if curtime = ontime5 then gosub [relayon]
if curtime = offtime5 then gosub [relayoff]
return

'************ REFRESH TIME  *************
[refresh]
minx = val(time("min"))
hourx = val(time("hour"))
dig4 = minx%10
dig3 = int((minx/10))
dig2 = hourx%10
dig1 = int((hourx/10))

'remove leading zeros
if dig1 = 0 then
dig1 = 10
if dig2 = 0 then
dig2 = 10
if dig3 = 0 then
dig3 = 10
if dig4 = 0 then
dig4 = 10
end if
end if
end if
end if

gosub [write4dig]

if curtime = "02:00:00" then
gosub [checkdst]
timesetup(tz,dst) 
delay 5000
endif

return

'************  SHOW IP ADDRESS  *************
[showip]
i2c.begin(address)
i2c.write(4)
i2c.write(0)
i2c.end()

connum = 0
gosub [convertdig]
gosub [write4dig]

for zz = 1 to 4
ipnumstr = word(localip,zz,".")
connum = val(ipnumstr)
gosub [convertdig]
gosub [write4dig]
delay 1000
connum = 0
gosub [convertdig]
gosub [write4dig]
delay 400
next zz
delay 500
return

'************  CONVERT DIGITS  *************
[convertdig]
 
dig1 = int(connum/1000)
dig2 = int((connum%1000)/100)
dig3 = int((connum%100)/10)
dig4 = int(connum%10)
'remove leading zeros
if dig1 = 0 then
dig1 = 10
if dig2 = 0 then
dig2 = 10
if dig3 = 0 then
dig3 = 10
if dig4 = 0 then
dig4 = 10
end if
end if
end if
end if
return

'************  WRITE 4 DIGITS  *************
[write4dig]
i2c.begin(address)
i2c.write(0)
i2c.write(digits(dig1))
i2c.end()
delay 10
i2c.begin(address) 
i2c.write(2)
i2c.write(digits(dig2))
i2c.end()
delay 10
i2c.begin(address) 
i2c.write(6)
i2c.write(digits(dig3))
i2c.end()
delay 10
i2c.begin(address) 
i2c.write(8)
i2c.write(digits(dig4))
i2c.end()
delay 10
return


'************  TOGGLE RELAY  *************
[togrelay]
if io(laststat,relay) = 0 then gosub [relayon] else gosub [relayoff]
wait

'************ UPDATE RELAY ON/OFF TIMES  *************
[updrelay]
write(ontimes1,ontime1)
write(offtimes1,offtime1)
write(ontimes2,ontime2)
write(offtimes2,offtime2)
write(ontimes3,ontime3)
write(offtimes3,offtime3)
write(ontimes4,ontime4)
write(offtimes4,offtime4)
write(ontimes5,ontime5)
write(offtimes5,offtime5)
wait

'************  UPDATE TIME INFO  *************
[timeupdate]
write(DaylightSavings,str(dst))
write(TZ,str(timezone))
if dst = 1 then
 tz = timezone + 1
else
 tz = timezone
endif
timesetup(tz,dst)
delay 5000
curtime = time("hour:min:sec")
wait

'************  UPDATE WIFI INFO  *************
[wifiupdate]
write(WIFIname,wifiname)
write(WIFIpass,wifipass)
wprint "WIFI info saved..."
wait

'************  REBOOT CLOCK  *************
[reboot]
cls
wprint "REBOOTING..."
delay 1000
reboot
wait

'************ RELAY ON SUB  *************
[relayon]
relaystat = "Relay is ON"
io(po,relay,1)
return

'************ RELAY OFF SUB  *************
[relayoff]
relaystat = "Relay is OFF"
io(po,relay,0)
return

'************ CHECK DST  *************
[checkdst]

dow = time("dow")
day = time("day")
month = time("month")
hour = time("hour")

if ((dst = 1) and (dow = "Sun") and (month = "Nov") and (day >= 3) and (day <= 5)) then
 dst = 0
 write(DaylightSavings,str(dst))
endif

if ((dst = 0) and (dow = "Sun") and (month = "Mar") and (day >=8) and (day < 15)) then
 dst = 1
 write(DaylightSavings,str(dst))
endif

return

'************ EXIT PROGRAM  *************
[exit]
timer 0
wprint "<a href='/'>Menu</a>"
end


Re: ESP8266 Basic Relay Clock

PostPosted: Wed Jan 25, 2017 9:29 pm
by forlotto
Variables in memory have been exceeded so what needs to be done is that you need to store array's of time and be able to save them back as a single array then you could load timelist 1, timelist 2, timelist 3, etc.... This is the only way to deal with so many variables that I could think of. It was mentioned by mike that it is entirely possible to do so however I am a bit shaky on how to go from array to variable back to array using it like a saved data personally I wish there was something in basic that could read and write to lists like csv or just a list rsv (return separated value) and there may very well be as it is already done for saving things like wifi password etc but would be excellent to allow the user to specify a file and use it for storage as well. However you would then just load List 1 and search for on off times that are the 10 closest times or the routine could simply load each list one after another and check the times and return there has to be a way for mike to allow us to handle larger numbers of timers and variables would be great to see some example code of this personally I'd like to have a weekly timer that would operate on 80 timers per day ... However while I believe it is possible for basic maybe it is not best suited it is plausible that something like domoticz may be a better solution really. But personally the less devices and less power used I believe the better off we will be if thinking in a green train of mind.

Very nicely done what an intense project for a clock I love how you handled timers well done for not being good at code etc you sure have me fooled ;)

Code: Select allcls
memclear

localip = ip()

brightness = 15
relay = D1
'led = 1
buttonpin = D3
address = 112
count = 1
col = 0
dot = 0
timer 0

gosub [relayoff]

dim digits(11)
digits(0) = 63
digits(1) = 6
digits(2) = 91
digits(3) = 79
digits(4) = 102
digits(5) = 109
digits(6) = 125
digits(7) = 7
digits(8) = 127
digits(9) = 111
digits(10) = 0

'************ INITIALIZE DISPLAY
i2c.setup(D4,D2)
i2c.begin(address)
i2c.write(33)
i2c.end()
i2c.begin(address)   
i2c.write(129)
i2c.end()
i2c.begin(address)
bright = 224 + brightness
i2c.write(bright)
i2c.end()
delay 10

i2c.begin(address)
i2c.write(4)
i2c.write(0)
i2c.end()

gosub [showip]

'************ CHECK IF AP MODE
if localip = "192.168.4.1" then
cls
wprint "Welcome to Relay Clock <br>"
wprint "Enter your WIFI info below <br>"
wprint "Hit Save and Reboot <br><br>"

wprint "WIFI Name:"
textbox wifiname
wprint "<br>"
wprint "WIFI Pass:"
textbox wifipass
wprint "<br><br>"
button "Save WIFI Settings",[wifiupdate]
wprint "<br> <br>"
button "Reboot Clock",[reboot]
wprint "<br> <br>"
wait
end if

'************ GET SAVED INFO
dst = read.val(DaylightSavings)
timezone = read.val(TZ)
wifiname = read(WIFIname)
wifipass = read(WIFIpass)

ontime1 = read(ontimes1)
ontime2 = read(ontimes2)
ontime3 = read(ontimes3)
ontime4 = read(ontimes4)
ontime5 = read(ontimes5)

offtime1 = read(offtimes1)
offtime2 = read(offtimes2)
offtime3 = read(offtimes3)
offtime4 = read(offtimes4)
offtime5 = read(offtimes5)

if dst = 1 then
tz = timezone + 1
else
tz = timezone
endif

timesetup(tz,dst)
delay 5000

interrupt buttonpin, [pressed]

serialprintln "flash 1 " & flashfree()
serialprintln "ram 1 " & ramfree()

wprint "<h2>RELAY CLOCK V1.0</h2>"
wprint "<br>"
curtime = time("hour:min:sec")
wprint "Time Now:  "
textbox curtime

wprint "<br><br>"
wprint "Timezone:  "
textbox timezone
wprint "<br>"
wprint "DST 1 or 0:  "
textbox dst
wprint "<br><br>"
button "Update Time Info",[timeupdate]
wprint "<br><br>"

wprint "Enter relay times in HH:MM:SS 24 hour format"
wprint "<br>"
wprint |Press "Save Relay Times" button when done|
wprint "<br><br>"

wprint "On Time 1 "
textbox ontime1
wprint "Off Time 1"
textbox offtime1
wprint "<br>"

wprint "On Time 2 "
textbox ontime2
wprint "Off Time 2"
textbox offtime2
wprint "<br>"

wprint "On Time 3 "
textbox ontime3
wprint "Off Time 3"
textbox offtime3
wprint "<br>"

wprint "On Time 4 "
textbox ontime4
wprint "Off Time 4"
textbox offtime4
wprint "<br>"

wprint "On Time 5 "
textbox ontime5
wprint "Off Time 5"
textbox offtime5
wprint "<br>"

button "Save Relay Times",[updrelay]

wprint "<br><br>"
button "Toggle Relay",[togrelay]
textbox relaystat
wprint "<br><br>"
button "End Program",[exit]

returngui

timer 1000,[colon]

wait


'************ COLON 1000ms  *************
[colon]
if col = 0 then dot = 0 else dot = 2
i2c.begin(address)
i2c.write(4)
i2c.write(dot)
i2c.end()
delay 10
if col = 1 then col = 0 else col = 1

curtime = time("hour:min:sec")
gosub [checkrelay]
gosub [refresh]

wait

'************ BUTTON PRESSED  *************
[pressed]
if io(laststat,buttonpin) == 0 then start = millis() else stop = millis()
if stop > start then
if stop-start < 2000 then goto [togrelay] else gosub [showip]
endif
wait

'************ CHECK RELAY TIMES  *************
[checkrelay]
if curtime = ontime1 then gosub [relayon]
if curtime = offtime1 then gosub [relayoff]
if curtime = ontime2 then gosub [relayon]
if curtime = offtime2 then gosub [relayoff]
if curtime = ontime3 then gosub [relayon]
if curtime = offtime3 then gosub [relayoff]
if curtime = ontime4 then gosub [relayon]
if curtime = offtime4 then gosub [relayoff]
if curtime = ontime5 then gosub [relayon]
if curtime = offtime5 then gosub [relayoff]
return

'************ REFRESH TIME  *************
[refresh]
minx = val(time("min"))
hourx = val(time("hour"))
dig4 = minx%10
dig3 = int((minx/10))
dig2 = hourx%10
dig1 = int((hourx/10))

'remove leading zeros
if dig1 = 0 then
dig1 = 10
if dig2 = 0 then
dig2 = 10
if dig3 = 0 then
dig3 = 10
if dig4 = 0 then
dig4 = 10
end if
end if
end if
end if

gosub [write4dig]

if curtime = "02:00:00" then
gosub [checkdst]
timesetup(tz,dst)
delay 5000
endif

return

'************  SHOW IP ADDRESS  *************
[showip]
i2c.begin(address)
i2c.write(4)
i2c.write(0)
i2c.end()

connum = 0
gosub [convertdig]
gosub [write4dig]

for zz = 1 to 4
ipnumstr = word(localip,zz,".")
connum = val(ipnumstr)
gosub [convertdig]
gosub [write4dig]
delay 1000
connum = 0
gosub [convertdig]
gosub [write4dig]
delay 400
next zz
delay 500
return

'************  CONVERT DIGITS  *************
[convertdig]
 
dig1 = int(connum/1000)
dig2 = int((connum%1000)/100)
dig3 = int((connum%100)/10)
dig4 = int(connum%10)
'remove leading zeros
if dig1 = 0 then
dig1 = 10
if dig2 = 0 then
dig2 = 10
if dig3 = 0 then
dig3 = 10
if dig4 = 0 then
dig4 = 10
end if
end if
end if
end if
return

'************  WRITE 4 DIGITS  *************
[write4dig]
i2c.begin(address)
i2c.write(0)
i2c.write(digits(dig1))
i2c.end()
delay 10
i2c.begin(address)
i2c.write(2)
i2c.write(digits(dig2))
i2c.end()
delay 10
i2c.begin(address)
i2c.write(6)
i2c.write(digits(dig3))
i2c.end()
delay 10
i2c.begin(address)
i2c.write(8)
i2c.write(digits(dig4))
i2c.end()
delay 10
return


'************  TOGGLE RELAY  *************
[togrelay]
if io(laststat,relay) = 0 then gosub [relayon] else gosub [relayoff]
wait

'************ UPDATE RELAY ON/OFF TIMES  *************
[updrelay]
write(ontimes1,ontime1)
write(offtimes1,offtime1)
write(ontimes2,ontime2)
write(offtimes2,offtime2)
write(ontimes3,ontime3)
write(offtimes3,offtime3)
write(ontimes4,ontime4)
write(offtimes4,offtime4)
write(ontimes5,ontime5)
write(offtimes5,offtime5)
wait

'************  UPDATE TIME INFO  *************
[timeupdate]
write(DaylightSavings,str(dst))
write(TZ,str(timezone))
if dst = 1 then
 tz = timezone + 1
else
 tz = timezone
endif
timesetup(tz,dst)
delay 5000
curtime = time("hour:min:sec")
wait

'************  UPDATE WIFI INFO  *************
[wifiupdate]
write(WIFIname,wifiname)
write(WIFIpass,wifipass)
wprint "WIFI info saved..."
wait

'************  REBOOT CLOCK  *************
[reboot]
cls
wprint "REBOOTING..."
delay 1000
reboot
wait

'************ RELAY ON SUB  *************
[relayon]
relaystat = "Relay is ON"
io(po,relay,1)
return

'************ RELAY OFF SUB  *************
[relayoff]
relaystat = "Relay is OFF"
io(po,relay,0)
return

'************ CHECK DST  *************
[checkdst]

dow = time("dow")
day = time("day")
month = time("month")
hour = time("hour")

if ((dst = 1) and (dow = "Sun") and (month = "Nov") and (day >= 3) and (day <= 5)) then
 dst = 0
 write(DaylightSavings,str(dst))
endif

if ((dst = 0) and (dow = "Sun") and (month = "Mar") and (day >=8) and (day < 15)) then
 dst = 1
 write(DaylightSavings,str(dst))
endif

return

'************ EXIT PROGRAM  *************
[exit]
timer 0
wprint "<a href='/'>Menu</a>"
end




I am a bit curious how long this project has been on going for you?

Either way no matter the duration you have something you made to your specifications and the example is excellent for those seeking how to handle time have user upgraded timers etc. I need to read the code more but this would put basic at the point of capable of carrying out tasks at a specific time of the day every day if so hats off. With a slight mod one could also check the day of the week and act upon stored time values in this manner.

This is something I have been meaning to do as well but priority has been low. Well this voice control and IR which has been a rather low thing on the todo as well but with the combination of IR, voice, and now possibly a weekly timer in basic along with all of its other elements I would say that automation can nearly be automated nearly hands free with little need for physical interaction. Imagine for a moment a person could indeed save an extraordinary amount of electricity over a year with little to no sacrifice of time energy or thought all of these little puzzle pieces open up an array of possibles.

Thanks for sharing.

JSON is also supported.

I would look into those three things.

JSON, Arrays, maybe how mike uses lists to store info in basic for variables as dat files this way when triggered you could simply load next variable on list into the place I don't know it is all likely possible so much of basic is not used do to lack of examples I believe a way to handle timers would be most excellent for basic I've hashed over this and the IR things a couple of times but the problem is it has not been that important for me to take time to look in depth for solutions I just was asking for an example for timers because the same principals would apply to everything really. Unleash the beast so to speak.

Re: ESP8266 Basic Relay Clock

PostPosted: Thu Jan 26, 2017 5:08 am
by Electroguard
personally I wish there was something in basic that could read and write to lists like csv or just a list rsv (return separated value) and there may very well be as it is already done for saving things like wifi password etc but would be excellent to allow the user to specify a file and use it for storage as well.

Forlotto, I'm afraid your mention of rsv (return separated value) isn't likely to be practical because a carraige return terminates data entry.

And there are a couple of useful but disjointed commands like 'WORD' and 'REPLACE' which can partially do something or other, but there is no cohesive set of effective Word (as distinct from Character) tools for counting, locating, extracting, editing or deleting words from a string list (else EasyNet functionality would have been easily available a long time ago). Although my suggestions weren't considered, perhaps the time might be right for you to make such a suggestion... in which case don't forget to suggest the Word equivalents of LeftStr and RightStr also, because the ability to manipulate words from a comma or space-delimited string list (or file) could open many new doors for Esp_Basic.

Re: ESP8266 Basic Relay Clock

PostPosted: Sun Jan 29, 2017 1:38 am
by forlotto
Okay so what I am trying to do here is pick apart just the code responsible for the time and realay and the components that make it function.

I have not tested it yet but I believe this is a good start we will see in time ;)

From here I will attempt whenever I have spare time to build upon the code to allow for more timers possibly I've been giving it a little bit of thought myself on how to skirt the issue you are having currently I believe there may be too many variables.

It may also be worthwhile to note that you may miss a specific timer during the 5 seconds it takes to update the time zone if someone were to view the page for instance. So if possible you may want to stop this from happening I have never really messed with timers much only delays in programming to be honest so I could be wrong here as well so keep this in mind! So it may be able to preform multiple processes at the same time thus no worries about displaying the webpage etc actually thinking about it is very likely I am wrong here but for all intensive purposes I personally believe that HH:MM is likely a better substitute if possible. In most automated situations you will have things turning on and off at a specific time based on minutes not seconds. There are few practical applications for seconds unless you are filling something or microwaving something I suppose. IDK where seconds is going to be all that handy but there may be a million things I'm not thinking about right now so the timer could be set to 30 seconds and the format for time could be HH:MM this should reduce stress on the esp considerably I would think.

Here is the modified code with that in mind I would like to rid all the clock stuff and just focus on the problem. I also did leave the AP mode check in place because it is critical that connection to the internet is available for any time to work with ESPbasic so this was an excellent way of doing so.

This is where I managed to get after reading a bit more through your code at current obviously there may be many things I am incorrect about here this is fine it is a learning process for me at this point but needless to say maybe I can help achieve something here I have already laid out some possibilities as ways of activating different variables without using variables but instead using flags with one variable to handle multiple variables. So it may be doable this way or with arrays or json like I stated earlier. Now for me I am fairly slow and learn as I go type programmer. So I will warn you this may take some time but I am interested in finding your solution because it also has a personal usage for everyone. Automation based on time is a common application for just about anything. The only place we seem to make good use of it however is when controlling temperature via a thermostat. Do I think that many people would not use it in other places it is hard to say. But I can think of using it for things like indoor gardens, a heating pad for your dogs bed, saving electricity by killing all those electronic consoles and cable boxes that don't work, fish tanks, lighting and keeping your motorcycle battery topped up in the winter. There are many many more applications for such a thing I am sure!

Enough babble for now but here is the attempt at code isolation of the portion we are trying to fix.
I have not tested as this is where I left off at modification and removal of bits of code not important to the issue at current.

Code: Select allcls
memclear
localip = ip()
relay = D1
timer 0
gosub [relayoff]

'************ CHECK IF AP MODE
if localip = "192.168.4.1" then
cls
wprint "Welcome to Relay Clock <br>"
wprint "Enter your WIFI info below <br>"
wprint "Hit Save and Reboot <br><br>"

wprint "WIFI Name:"
textbox wifiname
wprint "<br>"
wprint "WIFI Pass:"
textbox wifipass
wprint "<br><br>"
button "Save WIFI Settings",[wifiupdate]
wprint "<br> <br>"
button "Reboot Clock",[reboot]
wprint "<br> <br>"
wait
end if

'************ GET SAVED INFO
dst = read.val(DaylightSavings)
timezone = read.val(TZ)

ontime1 = read(ontimes1)
ontime2 = read(ontimes2)
ontime3 = read(ontimes3)
ontime4 = read(ontimes4)
ontime5 = read(ontimes5)

offtime1 = read(offtimes1)
offtime2 = read(offtimes2)
offtime3 = read(offtimes3)
offtime4 = read(offtimes4)
offtime5 = read(offtimes5)

if dst = 1 then
tz = timezone + 1
else
tz = timezone
endif

timesetup(tz,dst)
delay 5000

wprint "<h2>RELAY TIMER ONLY NO CLOCK!!!</h2>"
wprint "<br>"
curtime = time("hour:min")
wprint "Time Now:  "
textbox curtime

wprint "<br><br>"
wprint "Timezone:  "
textbox timezone
wprint "<br>"
wprint "DST 1 or 0:  "
textbox dst
wprint "<br><br>"
button "Update Time Info",[timeupdate]
wprint "<br><br>"

wprint "Enter relay times in HH:MM 24 hour format"
wprint "<br>"
wprint |Press "Save Relay Times" button when done|
wprint "<br><br>"

wprint "On Time 1 "
textbox ontime1
wprint "Off Time 1"
textbox offtime1
wprint "<br>"

wprint "On Time 2 "
textbox ontime2
wprint "Off Time 2"
textbox offtime2
wprint "<br>"

wprint "On Time 3 "
textbox ontime3
wprint "Off Time 3"
textbox offtime3
wprint "<br>"

wprint "On Time 4 "
textbox ontime4
wprint "Off Time 4"
textbox offtime4
wprint "<br>"

wprint "On Time 5 "
textbox ontime5
wprint "Off Time 5"
textbox offtime5
wprint "<br>"

button "Save Relay Times",[updrelay]

wprint "<br><br>"
button "Toggle Relay",[togrelay]
textbox relaystat
wprint "<br><br>"
button "End Program",[exit]

returngui

timer 30000,[checkrelay]

wait



'************ CHECK RELAY TIMES  *************
[checkrelay]
curtime = time("hour:min")
if curtime = ontime1 then gosub [relayon]
if curtime = offtime1 then gosub [relayoff]
if curtime = ontime2 then gosub [relayon]
if curtime = offtime2 then gosub [relayoff]
if curtime = ontime3 then gosub [relayon]
if curtime = offtime3 then gosub [relayoff]
if curtime = ontime4 then gosub [relayon]
if curtime = offtime4 then gosub [relayoff]
if curtime = ontime5 then gosub [relayon]
if curtime = offtime5 then gosub [relayoff]
return



'************  TOGGLE RELAY  *************
[togrelay]
if io(laststat,relay) = 0 then gosub [relayon] else gosub [relayoff]
wait

'************ UPDATE RELAY ON/OFF TIMES  *************
[updrelay]
write(ontimes1,ontime1)
write(offtimes1,offtime1)
write(ontimes2,ontime2)
write(offtimes2,offtime2)
write(ontimes3,ontime3)
write(offtimes3,offtime3)
write(ontimes4,ontime4)
write(offtimes4,offtime4)
write(ontimes5,ontime5)
write(offtimes5,offtime5)
wait

'************  UPDATE TIME INFO  *************
[timeupdate]
write(DaylightSavings,str(dst))
write(TZ,str(timezone))
if dst = 1 then
 tz = timezone + 1
else
 tz = timezone
endif
timesetup(tz,dst)
delay 5000
curtime = time("hour:min:sec")
wait

'************  UPDATE WIFI INFO  *************
[wifiupdate]
write(WIFIname,wifiname)
write(WIFIpass,wifipass)
wprint "WIFI info saved..."
wait

'************  REBOOT  *************
[reboot]
cls
wprint "REBOOTING..."
delay 1000
reboot
wait

'************ RELAY ON SUB  *************
[relayon]
relaystat = "Relay is ON"
io(po,relay,1)
return

'************ RELAY OFF SUB  *************
[relayoff]
relaystat = "Relay is OFF"
io(po,relay,0)
return

'************ CHECK DST  *************
[checkdst]

dow = time("dow")
day = time("day")
month = time("month")
hour = time("hour")

if ((dst = 1) and (dow = "Sun") and (month = "Nov") and (day >= 3) and (day <= 5)) then
 dst = 0
 write(DaylightSavings,str(dst))
endif

if ((dst = 0) and (dow = "Sun") and (month = "Mar") and (day >=8) and (day < 15)) then
 dst = 1
 write(DaylightSavings,str(dst))
endif

return

'************ EXIT PROGRAM  *************
[exit]
timer 0
wprint "<a href='/'>Menu</a>"
end




EDIT ADDITIONAL AFTER THOUGHT

There may be a limit on the amount of text boxes allowed to be displayed on the page and it may be this causing the issue not the variables themselves I have not counted all of your variables while I am sure there are plenty.

If that is the case you may be able to display the variables in sets by having a drop down or check box this would allow editing of 5 on and 5 off variables at a time.

Would be nice to check with mmiscool on this one.

What should be done is limitations should be denoted in the programming reference material so people are not so shocked by "GHOST BUGS" I think this is where a lot of these ghost issues come in is the lack of awareness of the limitations on the number of variables etc...

Variable limit = 70 (I think I recall this quoted somewhere)
Go Sub = 50 (I think without a return)
Lines of Code = 5000 (I think errr I wrote that in beginners guide.)
There was discussion of other limits to GUI Items etc... Maybe just for touchscreen I can't recall.
Timers also had a limitation of 1 I believe. Not sure.

Ghost bugs I believe are mostly limits at this point but they are undocumented this is a huge problem for anyone trying to write complex code like this or like easynet if we can document these limitations at least people could work around them. These things are very important to note I believe. I would have to go back and read everything problem is I think a lot of these things were given to me in chat and don't exist on the board so I kind of dropped the ball not taking notes and my memory is a bit foggy after coming back from my solar/wind project.

I think I will post this as a feature request.

I do have a request for you though would you mind posting a video of the device in operation this thing is too cool not to actually see working I am curious of your application I can think of many like enabling your surround sound to come on and start Jamming Some Sound On full blast to wake you up instantly no matter how rough it was last night or possibly enabling a wall wart connected to DC Voltage With a device that is connected to your bed frame which would rattle the bed frame causing an obnoxious vibration this could be done likely with a 20 dollar jigsaw from harbor frieght even :P