scheduler: config should be done

This commit is contained in:
Konstantin Koslowski 2019-05-24 19:34:21 +02:00
parent dc5185af3c
commit fb760582ed
6 changed files with 364 additions and 149 deletions

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

158
DS3231.py Normal file
View file

@ -0,0 +1,158 @@
'''
DS3231 RTC drive
Author: shaoziyang
Date: 2018.3
http://www.micropython.org.cn
'''
from machine import I2C, Pin
DS3231_I2C_ADDR = (0x68)
DS3231_REG_SEC = (0x00)
DS3231_REG_MIN = (0x01)
DS3231_REG_HOUR = (0x02)
DS3231_REG_WEEKDAY= (0x03)
DS3231_REG_DAY = (0x04)
DS3231_REG_MONTH = (0x05)
DS3231_REG_YEAR = (0x06)
DS3231_REG_A1SEC = (0x07)
DS3231_REG_A1MIN = (0x08)
DS3231_REG_A1HOUR = (0x09)
DS3231_REG_A1DAY = (0x0A)
DS3231_REG_A2MIN = (0x0B)
DS3231_REG_A2HOUR = (0x0C)
DS3231_REG_A2DAY = (0x0D)
DS3231_REG_CTRL = (0x0E)
DS3231_REG_STA = (0x0F)
DS3231_REG_AGOFF = (0x10)
DS3231_REG_TEMP = (0x11)
PER_DISABLE = (0)
PER_MINUTE = (1)
PER_HOUR = (2)
PER_DAY = (3)
PER_WEEKDAY = (4)
PER_MONTH = (5)
class DS3231():
def __init__(self, i2c):
self.i2c = i2c
self.setReg(DS3231_REG_CTRL, 0x4C)
def DecToHex(self, dat):
return (dat//10) * 16 + (dat%10)
def HexToDec(self, dat):
return (dat//16) * 10 + (dat%16)
def setReg(self, reg, dat):
self.i2c.writeto(DS3231_I2C_ADDR, bytearray([reg, dat]))
def getReg(self, reg):
self.i2c.writeto(DS3231_I2C_ADDR, bytearray([reg]))
return self.i2c.readfrom(DS3231_I2C_ADDR, 1)[0]
def Second(self, second = None):
if second == None:
return self.HexToDec(self.getReg(DS3231_REG_SEC))
else:
self.setReg(DS3231_REG_SEC, self.DecToHex(second%60))
def Minute(self, minute = None):
if minute == None:
return self.HexToDec(self.getReg(DS3231_REG_MIN))
else:
self.setReg(DS3231_REG_MIN, self.DecToHex(minute%60))
def Hour(self, hour = None):
if hour == None:
return self.HexToDec(self.getReg(DS3231_REG_HOUR))
else:
self.setReg(DS3231_REG_HOUR, self.DecToHex(hour%24))
def Weekday(self, weekday = None):
if weekday == None:
return self.HexToDec(self.getReg(DS3231_REG_WEEKDAY))
else:
self.setReg(DS3231_REG_WEEKDAY, self.DecToHex(weekday%8))
def Day(self, day = None):
if day == None:
return self.HexToDec(self.getReg(DS3231_REG_DAY))
else:
self.setReg(DS3231_REG_DAY, self.DecToHex(day%32))
def Month(self, month = None):
if month == None:
return self.HexToDec(self.getReg(DS3231_REG_MONTH))
else:
self.setReg(DS3231_REG_MONTH, self.DecToHex(month%13))
def Year(self, year = None):
if year == None:
return self.HexToDec(self.getReg(DS3231_REG_YEAR)) + 2000
else:
self.setReg(DS3231_REG_YEAR, self.DecToHex(year%100))
def Date(self, dat = None):
if dat == None:
return [self.Year(), self.Month(), self.Day()]
else:
self.Year(dat[0]%100)
self.Month(dat[1]%13)
self.Day(dat[2]%32)
def Time(self, dat = None):
if dat == None:
return [self.Hour(), self.Minute(), self.Second()]
else:
self.Hour(dat[0]%24)
self.Minute(dat[1]%60)
self.Second(dat[2]%60)
def DateTime(self, dat = None):
if dat == None:
return self.Date() + [self.Weekday()] + self.Time()
else:
self.Year(dat[0])
self.Month(dat[1])
self.Day(dat[2])
self.Weekday(dat[3])
self.Hour(dat[4])
self.Minute(dat[5])
self.Second(dat[6])
def ALARM(self, day, hour, minute, repeat):
IE = self.getReg(DS3231_REG_CTRL)
if repeat == PER_DISABLE:
self.setReg(DS3231_REG_CTRL, IE & 0xFC) # disable ALARM OUT
return
IE |= 0x46
self.setReg(DS3231_REG_CTRL, IE)
M2 = M3 = M4 = 0x80
DT = 0
if repeat == PER_MINUTE:
pass
elif repeat == PER_HOUR:
M2 = 0
elif repeat == PER_DAY:
M2 = M3 = 0
else:
M2 = M3 = M4 = 0
if repeat == PER_WEEKDAY:
DT = 0x40
self.setReg(DS3231_REG_A2MIN, self.DecToHex(minute%60)|M2)
self.setReg(DS3231_REG_A2HOUR, self.DecToHex(hour%24)|M3)
self.setReg(DS3231_REG_A2DAY, self.DecToHex(day%32)|M4|DT)
def ClearALARM(self):
self.setReg(DS3231_REG_STA, 0)
def Temperature(self):
t1 = self.getReg(DS3231_REG_TEMP)
t2 = self.getReg(DS3231_REG_TEMP + 1)
if t1>0x7F:
return t1 - t2/256 -256
else:
return t1 + t2/256

272
boot.py
View file

@ -1,10 +1,13 @@
# ssid, password # ssid, password
import wifi import wifi
import usocket as socket import usocket as socket
from utime import sleep
# from machine import Pin, RTC # from machine import Pin, RTC
import machine import machine
import network import network
from DS3231 import DS3231
import web
import esp import esp
esp.osdebug(None) esp.osdebug(None)
@ -13,89 +16,53 @@ import ure
import uos import uos
import ujson import ujson
# import gc import gc
# gc.collect() gc.collect()
CONFIG_FILE='schedule.json' # global variables
def web_page(config, datetime): ## PIN
print(datetime) # - D0 - Pin16 - WAKE
dt = ("%04d-%02d-%02d %02d-%02d-%02d" % (datetime[0], datetime[1], datetime[2], datetime[4], datetime[5], datetime[6])) # - D1 - Pin05 - I2C-SDA
cfg_date = "2019-01-01" # - D2 - Pin04 - I2C-SCL
cfg_time = "15-45" # - D3 - Pin00 - CONFIG
cfg_1on = "00-00" # - D4 - Pin02 - LED
cfg_1off = "00-00" ##
cfg_2on = "00-00"
cfg_2off = "00-00"
if "date" in config:
cfg_date = config["date"]
if "time" in config:
cfg_time = config["time"]
if "1on" in config:
cfg_1on = config["1on"]
if "1off" in config:
cfg_1off = config["1off"]
if "2on" in config:
cfg_2on = config["2on"]
if "2off" in config:
cfg_2off = config["2off"]
html = """<html>
<head>
<title>Scheduler</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
<style>
html{font-family: Helvetica; display:inline-block; margin: 0px auto; text-align: center;}
h1{color: #0F3376; padding: 2vh;}
p{font-size: 1.5rem;}
</style>
</head>
<body>
<h1>CONFIG - """ + dt + """</h1>
<form action="/" method="GET">
<p>date (e.g. 2019-05-20) <input type="text" name="date" value=""" + cfg_date + """ /></p>
<p>time (e.g. 18-05) <input type="text" name="time" value=""" + cfg_time + """ /></p>
<p>1-on <input type="text" name="1on" value=""" + cfg_1on + """ /> &nbsp;
1-off <input type="text" name="1off" value=""" + cfg_1off + """ /></p>
<p>2-on <input type="text" name="2on" value=""" + cfg_2on + """ /> &nbsp;
2-off <input type="text" name="2off" value=""" + cfg_2off + """ /></p>
<p><input type="submit" value="send" /></p>
</form>
</body>
</html>"""
return html
# D1
pin_cfgled = machine.Pin(16, machine.Pin.OUT)
# D0
pin_cfg = machine.Pin(5, machine.Pin.IN) pin_cfg = machine.Pin(5, machine.Pin.IN)
# D4
pin_led = machine.Pin(2, machine.Pin.OUT) pin_led = machine.Pin(2, machine.Pin.OUT)
CONFIG_FILE="schedule.json"
hf = open("header.html")
ff = open("footer.html")
header = hf.read()
footer = ff.read()
config = {} config = {}
# RTC
rtc = machine.RTC()
i2c = machine.I2C(scl=machine.Pin(4), sda=machine.Pin(5))
ds = DS3231(i2c)
tmp = ds.DateTime()
tmp.append(0)
rtc.datetime(tmp)
print("rtc", rtc.datetime())
# try loading config from filesystem
files = uos.listdir() files = uos.listdir()
if CONFIG_FILE in files: if CONFIG_FILE in files:
f = open(CONFIG_FILE, 'r') f = open(CONFIG_FILE, "r")
config_raw=f.read() config_raw=f.read()
config = ujson.loads(config_raw) config = ujson.loads(config_raw)
f.close() f.close()
for i in range(7):
if not config.get(i):
config[i] = {
1: {"on": {"h": 0, "m": 0}, "off": {"h": 0, "m": 0}},
2: {"on": {"h": 0, "m": 0}, "off": {"h": 0, "m": 0}}
}
print("initialized day: ", i)
print("CONFIG: %s" % config) print("CONFIG: %s" % config)
if (not "date" in config) and (not "time" in config):
config["date"] = "2010-01-01"
config["time"] = "00-00"
d = config["date"].split("-")
t = config["time"].split("-")
WEEKDAY = 0
dt = (int(d[0]), int(d[1]), int(d[2]), WEEKDAY, int(t[0]), int(t[1]), 0, 0)
rtc = machine.RTC()
rtc.datetime(dt)
print("dt", dt)
print("rtc.datetime()", rtc.datetime())
if (pin_cfg.value() == 1): if (pin_cfg.value() == 1):
ssid = wifi.ssid ssid = wifi.ssid
@ -108,93 +75,128 @@ if (pin_cfg.value() == 1):
while station.isconnected() == False: while station.isconnected() == False:
pass pass
print('Connection successful', station.ifconfig()) # print("Connection successful", station.ifconfig())
# ON # ON
pin_cfgled.value(0) pin_led.value(0)
pin_led.value(1)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80)) s.bind(("", 80))
s.listen(5) s.listen(5)
print('Configuration now...') print("Configuration now...")
while True: while True:
conn, addr = s.accept() conn, addr = s.accept()
print('Got a connection from %s' % str(addr)) req_recv = conn.recv(512)
request = conn.recv(1024) req_decode = req_recv.decode()
request = request.decode() req_split = req_decode.split("\n")
print('Content = %s' % request) request = req_split[0]
print("request: ", request)
response = ""
mode = "default"
if "/config_dt" in request:
mode = "config_dt"
elif "/config_day" in request:
mode = "config_day"
elif "/favicon" in request:
mode = "none"
## config_* --> save
if ("config" in mode) and ("save=1" in request):
update = False
## DATE
reg = ure.search("date=[0-9-]+", request) reg = ure.search("date=[0-9-]+", request)
if reg: if reg:
config["date"] = reg.group(0).replace("date=", "") tmp = reg.group(0).replace("date=", "").split("-")
if len(tmp) == 3:
update = True
new_date = [int(tmp[0]), int(tmp[1]), int(tmp[2])]
ds.Date(new_date)
## TIME
reg = ure.search("time=[0-9-]+", request) reg = ure.search("time=[0-9-]+", request)
if reg: if reg:
config["time"] = reg.group(0).replace("time=", "") tmp = reg.group(0).replace("time=", "").split("-")
if len(tmp) >= 2:
update = True
new_time = [int(tmp[0]), int(tmp[1]), 0]
if len(tmp) == 3:
new_time[2] = int(tmp[2])
ds.Time(new_time)
reg = ure.search("1on=[0-9-]+", request) if update:
update = False
tmp_dt = ds.DateTime()
tmp_dt.append(0)
rtc.datetime(tmp_dt)
print("Updated datetime", rtc.datetime())
## DAY
reg = ure.search("day=[0-6]+", request)
if reg: if reg:
config["1on"] = reg.group(0).replace("1on=", "") update = True
tmp = reg.group(0).replace("day=", "")
reg = ure.search("1off=[0-9-]+", request) day = int(tmp)
for p in [1, 2]:
# on
reg = ure.search(("p%d_on=[0-9-]+" % p), request)
if reg: if reg:
config["1off"] = reg.group(0).replace("1off=", "") tmp = reg.group(0).replace(("p%d_on=" % p), "").split("-")
if len(tmp) == 2:
reg = ure.search("2on=[0-9-]+", request) h = int(tmp[0])
m = int(tmp[1])
config[day][p]["on"] = {"h": h, "m": m}
# off
reg = ure.search(("p%d_off=[0-9-]+" % p), request)
if reg: if reg:
config["2on"] = reg.group(0).replace("2on=", "") tmp = reg.group(0).replace(("p%d_off=" % p), "").split("-")
if len(tmp) == 2:
h = int(tmp[0])
m = int(tmp[1])
config[day][p]["off"] = {"h": h, "m": m}
reg = ure.search("2off=[0-9-]+", request) if update:
if reg: f = open(CONFIG_FILE, "w")
config["2off"] = reg.group(0).replace("2off=", "")
print("config:\n %s" % (ujson.dumps(config)))
f = open(CONFIG_FILE, 'w')
f.write(ujson.dumps(config)) f.write(ujson.dumps(config))
f.close() f.close()
# print("updated config:\n %s" % (ujson.dumps(config)))
print("updated config")
# led_on = request.find('/?led=on') ## default
# led_off = request.find('/?led=off') if mode == "default":
# if led_on == 6: print("web_default")
# print('LED ON') response = header + web.default() + footer
# ledpin.value(1) ## config_dt
# if led_off == 6: elif mode == "config_dt":
# print('LED OFF') response = header + web.config_datetime(rtc) + footer
# ledpin.value(0) ## config_day
response = web_page(config, rtc.datetime()) elif mode == "config_day":
conn.send('HTTP/1.1 200 OK\n') reg = ure.search("day=[0-6-]+", request)
conn.send('Content-Type: text/html\n') if reg:
conn.send('Connection: close\n\n') tmp = reg.group(0).replace("day=", "")
day = int(tmp)
print("web_config, day ", day)
response = header + web.config_day(config, day) + footer
## favicon
elif mode == "favicon":
print("favicon")
response = ""
## send response
try:
conn.send("HTTP/1.1 200 OK\n")
conn.send("Content-Type: text/html\n")
conn.send("Connection: close\n\n")
conn.sendall(response) conn.sendall(response)
sleep(1)
conn.close() conn.close()
# print("connection closed successfully")
except:
print("connection closed with error")
else: else:
# # set alarms while True:
# WEEKDAY=0
# # ON
# alarm_on = {}
# tmp = config["1on"].split("-")
# alarm_on[0] = (int(tmp[0]), int(tmp[1]), int(tmp[2]), WEEKDAY, int(tmp[3]), int(tmp[4]), int(tmp[5]), 0)
# tmp = config["2on"].split("-")
# alarm_on[1] = (int(tmp[0]), int(tmp[1]), int(tmp[2]), WEEKDAY, int(tmp[3]), int(tmp[4]), int(tmp[5]), 0)
# print("alarm_on: ", alarm_on)
#
# # OFF
# alarm_off = {}
# tmp = config["1off"].split("-")
# alarm_off[0] = (int(tmp[0]), int(tmp[1]), int(tmp[2]), WEEKDAY, int(tmp[3]), int(tmp[4]), int(tmp[5]), 0)
# tmp = config["2off"].split("-")
# alarm_off[1] = (int(tmp[0]), int(tmp[1]), int(tmp[2]), WEEKDAY, int(tmp[3]), int(tmp[4]), int(tmp[5]), 0)
# print("alarm_off: ", alarm_off)
# rtc.alarm(0, alarm_on[0])
# rtc.alarm(1, alarm_on[1])
# rtc.alarm(2, alarm_off[0])
# rtc.alarm(3, alarm_off[1])
# RTC.irq(RTC.ALARM0, handler=None, wake=machine.DEEPSLEEP)
# machine.deepsleep()
# OFF
# pin_cfgled.on()
# print("Connection disabled")
print("running scheduler...") print("running scheduler...")
sleep(1)

9
footer.html Normal file
View file

@ -0,0 +1,9 @@
<p> Configure
<a href="/config_dt">Date/Time</a> |
<a href="/config_day?select_day=0">Mon</a> | <a href="/config_day?select_day=1">Tue</a> |
<a href="/config_day?select_day=2">Wed</a> | <a href="/config_day?select_day=3">Thu</a> |
<a href="/config_day?select_day=4">Fri</a> | <a href="/config_day?select_day=5">Sat</a> |
<a href="/config_day?select_day=6">Sun</a>
</p>
</body>
</html>

15
header.html Normal file
View file

@ -0,0 +1,15 @@
<html>
<head>
<title>SCHEDULE CONFIGURATION</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
<style>
html{font-family: Helvetica; display:inline-block; margin: 0px auto; text-align: center;}
body { background-color: #ffffff; color: #000000; }
h1{color: #002b36; padding: 2vh;}
h2{color: #073642; padding: 2vh;}
p{font-size: 1.5rem;}
</style>
</head>
<body>
<h1>SCHEDULE CONFIGURATION </h1>

37
web.py Normal file
View file

@ -0,0 +1,37 @@
days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
def default():
content = """ <h3> select item below </h3> """
return content
def config_datetime(rtc):
dt = rtc.datetime()
d = ("%04d-%02d-%02d" % (dt[0], dt[1], dt[2]))
t = ("%02d-%02d-%02d" % (dt[4], dt[5], dt[6]))
content = """
<form action="/config_dt" method="GET">
<h2>Date/Time (Only fill to update current date/time!)</h2>
<p>current date: """ + d + """ &nbsp; current time: """ + t + """ </p>
<input type="hidden" name="save" value="1" />
<p>new date: <input type="text" name="date" value="" /> &nbsp;
new time: <input type="text" name="time" value="" /></p>
<p><input type="reset" value="reset"> &nbsp; <input type="submit" value="save" /></p>
</form>
"""
return content
def config_day(config, day):
content = """
<form action="/config_day" method="GET">
<h2>Power-on/off (hh-mm) </h2>
<h3> Selected: """ + days[day] + """</h3>
<input type="hidden" name="save" value="1" />
<input type="hidden" name="day" value=""" + ("%s" % day) + """ />
<p>P1-On <input type="text" name="p1_on" value=""" + ("%02d-%02d" % (config[day][1]["on"]["h"], config[day][1]["on"]["m"])) + """ /> &nbsp;
P1-Off <input type="text" name="p1_off" value=""" + ("%02d-%02d" % (config[day][1]["off"]["h"], config[day][1]["off"]["m"])) + """ /> </p>
<p>P2-On <input type="text" name="p2_on" value=""" + ("%02d-%02d" % (config[day][2]["on"]["h"], config[day][2]["on"]["m"])) + """ /> &nbsp;
P2-Off <input type="text" name="p2_off" value=""" + ("%02d-%02d" % (config[day][2]["off"]["h"], config[day][2]["off"]["m"])) + """ /> </p>
<p><input type="reset" value="reset"> &nbsp; <input type="submit" value="save" /></p>
</form>
"""
return content