From fb760582eda04a887a95e7f4e2ac0a2bd26b5f15 Mon Sep 17 00:00:00 2001 From: Konstantin Koslowski Date: Fri, 24 May 2019 19:34:21 +0200 Subject: [PATCH] scheduler: config should be done --- .idea/vcs.xml | 6 -- DS3231.py | 158 +++++++++++++++++++++++++++ boot.py | 288 +++++++++++++++++++++++++------------------------- footer.html | 9 ++ header.html | 15 +++ web.py | 37 +++++++ 6 files changed, 364 insertions(+), 149 deletions(-) delete mode 100644 .idea/vcs.xml create mode 100644 DS3231.py create mode 100644 footer.html create mode 100644 header.html create mode 100644 web.py diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/DS3231.py b/DS3231.py new file mode 100644 index 0000000..ec9a56c --- /dev/null +++ b/DS3231.py @@ -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 diff --git a/boot.py b/boot.py index bde15ec..e0da0eb 100644 --- a/boot.py +++ b/boot.py @@ -1,10 +1,13 @@ # ssid, password import wifi import usocket as socket +from utime import sleep # from machine import Pin, RTC import machine import network +from DS3231 import DS3231 +import web import esp esp.osdebug(None) @@ -13,89 +16,53 @@ import ure import uos import ujson -# import gc -# gc.collect() +import gc +gc.collect() -CONFIG_FILE='schedule.json' -def web_page(config, datetime): - print(datetime) - dt = ("%04d-%02d-%02d %02d-%02d-%02d" % (datetime[0], datetime[1], datetime[2], datetime[4], datetime[5], datetime[6])) - cfg_date = "2019-01-01" - cfg_time = "15-45" - cfg_1on = "00-00" - 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 = """ - - Scheduler - - - - - -

CONFIG - """ + dt + """

-
-

date (e.g. 2019-05-20)

-

time (e.g. 18-05)

-

1-on   - 1-off

-

2-on   - 2-off

-

-
- - """ - return html - -# D1 -pin_cfgled = machine.Pin(16, machine.Pin.OUT) -# D0 +# global variables +## PIN +# - D0 - Pin16 - WAKE +# - D1 - Pin05 - I2C-SDA +# - D2 - Pin04 - I2C-SCL +# - D3 - Pin00 - CONFIG +# - D4 - Pin02 - LED +## pin_cfg = machine.Pin(5, machine.Pin.IN) -# D4 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 = {} +# 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() if CONFIG_FILE in files: - f = open(CONFIG_FILE, 'r') + f = open(CONFIG_FILE, "r") config_raw=f.read() config = ujson.loads(config_raw) 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) -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): ssid = wifi.ssid @@ -108,93 +75,128 @@ if (pin_cfg.value() == 1): while station.isconnected() == False: pass - print('Connection successful', station.ifconfig()) + # print("Connection successful", station.ifconfig()) # ON - pin_cfgled.value(0) - pin_led.value(1) + pin_led.value(0) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.bind(('', 80)) + s.bind(("", 80)) s.listen(5) - print('Configuration now...') + print("Configuration now...") while True: conn, addr = s.accept() - print('Got a connection from %s' % str(addr)) - request = conn.recv(1024) - request = request.decode() - print('Content = %s' % request) - reg = ure.search("date=[0-9-]+", request) - if reg: - config["date"] = reg.group(0).replace("date=", "") - reg = ure.search("time=[0-9-]+", request) - if reg: - config["time"] = reg.group(0).replace("time=", "") + req_recv = conn.recv(512) + req_decode = req_recv.decode() + req_split = req_decode.split("\n") + request = req_split[0] + print("request: ", request) - reg = ure.search("1on=[0-9-]+", request) - if reg: - config["1on"] = reg.group(0).replace("1on=", "") + response = "" - reg = ure.search("1off=[0-9-]+", request) - if reg: - config["1off"] = reg.group(0).replace("1off=", "") + mode = "default" + if "/config_dt" in request: + mode = "config_dt" + elif "/config_day" in request: + mode = "config_day" + elif "/favicon" in request: + mode = "none" - reg = ure.search("2on=[0-9-]+", request) - if reg: - config["2on"] = reg.group(0).replace("2on=", "") + ## config_* --> save + if ("config" in mode) and ("save=1" in request): + update = False + ## DATE + reg = ure.search("date=[0-9-]+", request) + if reg: + 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) - reg = ure.search("2off=[0-9-]+", request) - if reg: - config["2off"] = reg.group(0).replace("2off=", "") + ## TIME + reg = ure.search("time=[0-9-]+", request) + if reg: + 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) - print("config:\n %s" % (ujson.dumps(config))) + if update: + update = False + tmp_dt = ds.DateTime() + tmp_dt.append(0) + rtc.datetime(tmp_dt) + print("Updated datetime", rtc.datetime()) - f = open(CONFIG_FILE, 'w') - f.write(ujson.dumps(config)) - f.close() + ## DAY + reg = ure.search("day=[0-6]+", request) + if reg: + update = True + tmp = reg.group(0).replace("day=", "") + day = int(tmp) + for p in [1, 2]: + # on + reg = ure.search(("p%d_on=[0-9-]+" % p), request) + if reg: + tmp = reg.group(0).replace(("p%d_on=" % p), "").split("-") + if len(tmp) == 2: + 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: + 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} - # led_on = request.find('/?led=on') - # led_off = request.find('/?led=off') - # if led_on == 6: - # print('LED ON') - # ledpin.value(1) - # if led_off == 6: - # print('LED OFF') - # ledpin.value(0) - response = web_page(config, rtc.datetime()) - 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.close() + if update: + f = open(CONFIG_FILE, "w") + f.write(ujson.dumps(config)) + f.close() + # print("updated config:\n %s" % (ujson.dumps(config))) + print("updated config") + + ## default + if mode == "default": + print("web_default") + response = header + web.default() + footer + ## config_dt + elif mode == "config_dt": + response = header + web.config_datetime(rtc) + footer + ## config_day + elif mode == "config_day": + reg = ure.search("day=[0-6-]+", request) + if reg: + 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) + sleep(1) + conn.close() + # print("connection closed successfully") + except: + print("connection closed with error") else: - # # set alarms - # 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...") + while True: + print("running scheduler...") + sleep(1) diff --git a/footer.html b/footer.html new file mode 100644 index 0000000..274ba04 --- /dev/null +++ b/footer.html @@ -0,0 +1,9 @@ +

Configure + Date/Time | + Mon | Tue | + Wed | Thu | + Fri | Sat | + Sun +

+ + \ No newline at end of file diff --git a/header.html b/header.html new file mode 100644 index 0000000..6d7aac5 --- /dev/null +++ b/header.html @@ -0,0 +1,15 @@ + + + SCHEDULE CONFIGURATION + + + + + +

SCHEDULE CONFIGURATION

diff --git a/web.py b/web.py new file mode 100644 index 0000000..8d8c689 --- /dev/null +++ b/web.py @@ -0,0 +1,37 @@ +days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] +def default(): + content = """

select item below

""" + 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 = """ +
+

Date/Time (Only fill to update current date/time!)

+

current date: """ + d + """   current time: """ + t + """

+ +

new date:   + new time:

+

 

+
+ """ + return content + +def config_day(config, day): + content = """ +
+

Power-on/off (hh-mm)

+

Selected: """ + days[day] + """

+ + +

P1-On   + P1-Off

+

P2-On   + P2-Off

+

 

+
+ """ + return content