From 87cfa83af9f78b12093df48a3cd4a8e301118cb7 Mon Sep 17 00:00:00 2001 From: pndadm Date: Wed, 1 Oct 2025 18:30:41 +0000 Subject: [PATCH] Dateien nach "old" hochladen --- old/boot.py | 4 + old/main.py | 16 ++++ old/mqtt.py | 202 +++++++++++++++++++++++++++++++++++++++++++++++ old/pnd.py | 190 ++++++++++++++++++++++++++++++++++++++++++++ old/pndConfig.py | 32 ++++++++ 5 files changed, 444 insertions(+) create mode 100644 old/boot.py create mode 100644 old/main.py create mode 100644 old/mqtt.py create mode 100644 old/pnd.py create mode 100644 old/pndConfig.py diff --git a/old/boot.py b/old/boot.py new file mode 100644 index 0000000..c449ecc --- /dev/null +++ b/old/boot.py @@ -0,0 +1,4 @@ +# This file is executed on every boot (including wake-boot from deepsleep) +import uos, machine +import gc +gc.collect() diff --git a/old/main.py b/old/main.py new file mode 100644 index 0000000..84e9714 --- /dev/null +++ b/old/main.py @@ -0,0 +1,16 @@ +import pnd +import _thread +import time +print(pnd.cfg.tasks.gc_tasks) + + + +## init pundo system +runtime = pnd.rt() +runtime.init(0) + +## run backgroundtasks +#_thread.start_new_thread(runtime.backgroundTask, ()) + +## run main Task +runtime.run() diff --git a/old/mqtt.py b/old/mqtt.py new file mode 100644 index 0000000..0814c8a --- /dev/null +++ b/old/mqtt.py @@ -0,0 +1,202 @@ +#!/usr/bin/env python +# +# Copyright (c) 2019, Pycom Limited. +# +# This software is licensed under the GNU GPL version 3 or any +# later version, with permitted additional terms. For more information +# see the Pycom Licence v1.0 document supplied with this file, or +# available at https://www.pycom.io/opensource/licensing +# + +import usocket as socket +import ustruct as struct +from ubinascii import hexlify + +class MQTTException(Exception): + pass + +class MQTTClient: + + def __init__(self, client_id, server, port=0, user=None, password=None, keepalive=0, + ssl=False, ssl_params={}): + if port == 0: + port = 8883 if ssl else 1883 + self.client_id = client_id + self.sock = None + self.addr = socket.getaddrinfo(server, port)[0][-1] + self.ssl = ssl + self.ssl_params = ssl_params + self.pid = 0 + self.cb = None + self.user = user + self.pswd = password + self.keepalive = keepalive + self.lw_topic = None + self.lw_msg = None + self.lw_qos = 0 + self.lw_retain = False + + def _send_str(self, s): + self.sock.write(struct.pack("!H", len(s))) + self.sock.write(s) + + def _recv_len(self): + n = 0 + sh = 0 + while 1: + b = self.sock.read(1)[0] + n |= (b & 0x7f) << sh + if not b & 0x80: + return n + sh += 7 + + def set_callback(self, f): + self.cb = f + + def set_last_will(self, topic, msg, retain=False, qos=0): + assert 0 <= qos <= 2 + assert topic + self.lw_topic = topic + self.lw_msg = msg + self.lw_qos = qos + self.lw_retain = retain + + def connect(self, clean_session=True): + self.sock = socket.socket() + self.sock.connect(self.addr) + self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + if self.ssl: + import ussl + self.sock = ussl.wrap_socket(self.sock, **self.ssl_params) + msg = bytearray(b"\x10\0\0\x04MQTT\x04\x02\0\0") + msg[1] = 10 + 2 + len(self.client_id) + msg[9] = clean_session << 1 + if self.user is not None: + msg[1] += 2 + len(self.user) + 2 + len(self.pswd) + msg[9] |= 0xC0 + if self.keepalive: + assert self.keepalive < 65536 + msg[10] |= self.keepalive >> 8 + msg[11] |= self.keepalive & 0x00FF + if self.lw_topic: + msg[1] += 2 + len(self.lw_topic) + 2 + len(self.lw_msg) + msg[9] |= 0x4 | (self.lw_qos & 0x1) << 3 | (self.lw_qos & 0x2) << 3 + msg[9] |= self.lw_retain << 5 + self.sock.write(msg) + #print(hex(len(msg)), hexlify(msg, ":")) + self._send_str(self.client_id) + if self.lw_topic: + self._send_str(self.lw_topic) + self._send_str(self.lw_msg) + if self.user is not None: + self._send_str(self.user) + self._send_str(self.pswd) + resp = self.sock.read(4) + assert resp[0] == 0x20 and resp[1] == 0x02 + if resp[3] != 0: + raise MQTTException(resp[3]) + return resp[2] & 1 + + def disconnect(self): + ##self.sock.write(b"\xe0\0") + self.sock.close() + + def ping(self): + self.sock.write(b"\xc0\0") + + def publish(self, topic, msg, retain=False, qos=0): + pkt = bytearray(b"\x30\0\0\0") + pkt[0] |= qos << 1 | retain + sz = 2 + len(topic) + len(msg) + if qos > 0: + sz += 2 + assert sz < 2097152 + i = 1 + while sz > 0x7f: + pkt[i] = (sz & 0x7f) | 0x80 + sz >>= 7 + i += 1 + pkt[i] = sz + #print(hex(len(pkt)), hexlify(pkt, ":")) + self.sock.write(pkt, i + 1) + self._send_str(topic) + if qos > 0: + self.pid += 1 + pid = self.pid + struct.pack_into("!H", pkt, 0, pid) + self.sock.write(pkt, 2) + self.sock.write(msg) + if qos == 1: + while 1: + op = self.wait_msg() + if op == 0x40: + sz = self.sock.read(1) + assert sz == b"\x02" + rcv_pid = self.sock.read(2) + rcv_pid = rcv_pid[0] << 8 | rcv_pid[1] + if pid == rcv_pid: + return + elif qos == 2: + assert 0 + + def subscribe(self, topic, qos=0): + assert self.cb is not None, "Subscribe callback is not set" + pkt = bytearray(b"\x82\0\0\0") + self.pid += 1 + struct.pack_into("!BH", pkt, 1, 2 + 2 + len(topic) + 1, self.pid) + #print(hex(len(pkt)), hexlify(pkt, ":")) + self.sock.write(pkt) + self._send_str(topic) + self.sock.write(qos.to_bytes(1, "little")) + while 1: + op = self.wait_msg() + if op == 0x90: + resp = self.sock.read(4) + #print(resp) + assert resp[1] == pkt[2] and resp[2] == pkt[3] + if resp[3] == 0x80: + raise MQTTException(resp[3]) + return + + # Wait for a single incoming MQTT message and process it. + # Subscribed messages are delivered to a callback previousl + # set by .set_callback() method. Other (internal) MQTT + # messages processed internally. + def wait_msg(self): + res = self.sock.read(1) + self.sock.setblocking(True) + if res is None: + return None + if res == b"": + raise OSError(-1) + if res == b"\xd0": # PINGRESP + sz = self.sock.read(1)[0] + assert sz == 0 + return None + op = res[0] + if op & 0xf0 != 0x30: + return op + sz = self._recv_len() + topic_len = self.sock.read(2) + topic_len = (topic_len[0] << 8) | topic_len[1] + topic = self.sock.read(topic_len) + sz -= topic_len + 2 + if op & 6: + pid = self.sock.read(2) + pid = pid[0] << 8 | pid[1] + sz -= 2 + msg = self.sock.read(sz) + self.cb(topic, msg) + if op & 6 == 2: + pkt = bytearray(b"\x40\x02\0\0") + struct.pack_into("!H", pkt, 2, pid) + self.sock.write(pkt) + elif op & 6 == 4: + assert 0 + + # Checks whether a pending message from server is available. + # If not, returns immediately with None. Otherwise, does + # the same processing as wait_msg. + def check_msg(self): + self.sock.setblocking(False) + return self.wait_msg() diff --git a/old/pnd.py b/old/pnd.py new file mode 100644 index 0000000..8520581 --- /dev/null +++ b/old/pnd.py @@ -0,0 +1,190 @@ +import pndSRC as mypnd +import pndConfig as cfg +import ntptime +import ujson +import time +import machine +import array +import gc + +gc.enable() + +from machine import Pin, I2C, ADC +gc.enable() + +class rt(): + + wifi = mypnd.wifi + Psystem = mypnd.Psystem + lastTry = 0 + cycle = 0 + looping = 0 + + def run(self): + self.cycle = 1 + timer = "s" + while True: + try: + ## main loop + gc.collect() + + machine.idle() + print(self.Psystem.status()) + ##display + temp, hum = self.Sensors[0].getStr() + mois = self.Sensors[1].getStr() + ptemp = "T:" + str(temp) + ptemp += " C" + phum = "H:" + str(hum) + phum += " %" + pmoi = "M:" + str(mois[:6]) + pmoi += " %" + #up = self.cycle * self.looping + + if(up > 300 and timer == "s"): + runtime = up / 60 + timer = "m" + elif(timer == "m" and up > 3600): + runtime = up / 3600 + timer = "h" + elif(timer == "m"): + runtime = up / 60 + elif(timer == "h"): + runtime = up / 3600 + else: + runtime = up + + year, mon, day, h, m, s, nope, nope2 = time.localtime() + if((m % 55) == 0): + # self.wifi.reconnect() + # self.cycle = self.cycle + 1 + if(self.cycle > 10000): self.cycle = 1 + machine.idle() + time.sleep(self.looping) + except OSError as e: + mypnd.ecx.handle(mypnd.ecx(),self,e) + + def backgroundTask(self): + if(not self.online): + lhttp = mypnd.webserver() + print('starting Webserver...') + + ## method with main loop goes here + lhttp.showStatusPage() + else: + print('offline Mode: no Webserver...') + + def init(self, lastTry): + try: + self.online = cfg.defaults.gc_offline + self.Psystem.setCallback(self) + i = 0 + self.lastTry = lastTry + if(not self.online): + self.wifi.connect() + ntptime.host = cfg.defaults.gc_ntp_host + try: + ntptime.settime() + except: + pass + if hasattr(cfg.tasks, "gc_sensors"): + self.Sensors = {} + for sens in cfg.tasks.gc_sensors: + if cfg.tasks.gc_sensors[sens]['ADC']: + self.Sensors[i] = mypnd.adcsens(cfg.tasks.gc_sensors[sens]['name'],cfg.tasks.gc_sensors[sens]['pin']) + else: + self.Sensors[i] = mypnd.sens(cfg.tasks.gc_sensors[sens]['name'],cfg.tasks.gc_sensors[sens]['type'],cfg.tasks.gc_sensors[sens]['pin']) + i += 1 + if hasattr(cfg.tasks, "gc_display"): + self.dispService = dispService(); + + self.looping = cfg.defaults.gc_looping + except OSError as e: + mypnd.ecx.handle(mypnd.ecx(),self,e) + + +class mqService(): + def __init__(self): + try: + self.mqtt = mypnd.mqtt() + self.mqclient = self.mqtt.connect() + except OSError as e: + self.lastTry = 1 + mypnd.ecx.handle(mypnd.ecx(),self,e) + + def logConf(self): + topic = cfg.mqtt.gc_topic_config + sys = mypnd.Psystem + ip = mypnd.wifi.getIp() + status = sys.statusJSON() + self.mqtt.publish(self.mqclient, topic, status) + + def logSensors(self, sensors): + year, mon, day, h, m, s, nope, nope2 = time.localtime() + date = str(year) + "-" + str(mon) + "-" + str(day) + "T" + str(h) + ":" + str(m) + ":" + str(s) + for sens in sensors: + if sensors[sens].ADC: + jsens = ujson.dumps({ "name" : cfg.gc_name, "Time": date, "senso_name": sensors[sens].id, "value": sensors[sens].update()}) + self.mqtt.publish(self.mqclient, cfg.mqtt.gc_topic_sensor, jsens) + else: + temp, hum = sensors[sens].update() + jsens = ujson.dumps({ "name" : cfg.gc_name, "Time": date, "senso_name": "Temperature_" + sensors[sens].id[-1], "value": temp}) + self.mqtt.publish(self.mqclient, cfg.mqtt.gc_topic_sensor, jsens) + jsens = ujson.dumps({ "name" : cfg.gc_name, "Time": date, "senso_name": "Humidity_" + sensors[sens].id[-1], "value": hum}) + self.mqtt.publish(self.mqclient, cfg.mqtt.gc_topic_sensor, jsens) + + def close(self): + self.mqtt.disconnect(self.mqclient) + del self.mqclient + del self.mqtt + +class dispService(): + def __init__(self): + import pndSRC as mypnd + self.disp = mypnd.display(cfg.tasks.gc_display) + self.disp.contrast(50) + self.disp.flush() + + def show4TxtLines(self, l1, l2, l3, l4 ): + self.disp.flush() + year, mon, day, h, m, s, nope, nope2 = time.localtime() + if((m % 2) == 0): + self.disp.addTxt(l1, 0, 0, 1) + self.disp.addTxt(l2, 0, 13, 1) + self.disp.addTxt(l3, 0, 25, 1) + self.disp.addTxt(l4.date, 0, 37, 1) + elif((m % 3) == 0): + self.disp.addTxt(l2, 0, 0, 1) + self.disp.addTxt(l4.time, 0, 13, 1) + self.disp.addTxt(l1, 0, 25, 1) + self.disp.addTxt(l3, 0, 37, 1) + + else: + self.disp.addTxt(l4.time, 0, 0, 1) + self.disp.addTxt(l3, 0, 13, 1) + self.disp.addTxt(l2, 0, 25, 1) + self.disp.addTxt(l1, 0, 37, 1) + self.disp.show() + self.disp.invert() + + def showTxtLines(self, texts ): + self.disp.flush() + year, mon, day, h, m, s, nope, nope2 = time.localtime() + y = 0 + if((m % 2) == 0): + for text in texts: + self.disp.addTxt(str(text), 0, y, 1) + y += 13 + elif((m % 3) == 0): + y = 64 + for text in texts: + y -= 13 + self.disp.addTxt(str(text), 0, y, 1) + + + else: + for text in texts: + self.disp.addTxt(str(text), 0, y, 1) + y += 13 + self.disp.show() + self.disp.invert() \ No newline at end of file diff --git a/old/pndConfig.py b/old/pndConfig.py new file mode 100644 index 0000000..968b975 --- /dev/null +++ b/old/pndConfig.py @@ -0,0 +1,32 @@ +gc_name = "pndESP_420_rc1.4a" + +class tasks: + gc_tasks = "Sensor;MQTT" + gc_sensors = {0:{"name":"DHT22_1", "type":"DHT22","pin": 26, "ADC": False}, + ## 1:{"name":"DHT11_2", "type":"DHT11","pin": 27, "ADC": False}, + ## 2:{"name":"DHT11_3", "type":"DHT11","pin": 28, "ADC": False}, + # 3:{"name":"Moisture_1", "type":"MOIST","pin": 32, "ADC": True}, + # 4:{"name":"Moisture_2", "type":"MOIST","pin": 33, "ADC": True}, + # 5:{"name":"Moisture_3", "type":"MOIST","pin": 35, "ADC": True} + } + ##gc_display = { "sdaPin":6, "sclPin":7, "type": "SSD1306_I2C", "name": "myDisp", "widht":128, "height": 64} + +class defaults: + gc_offline = True + gc_adc_min = 1792 + gc_adc_max = 4096 + gc_ntp_host = "time.pundoria.de" + gc_looping = 30 + +class wifi: + gc_ssid = "Schnell2.4" + gc_secret = "llenhcS1!" + +class mqtt: + gc_host = "mqdata.pundoria.de" + gc_port = 1883 + gc_topic_config ="tasmota/ESP32_PND/config" + gc_topic_sensor ="tasmota/ESP32_PND/sensors" + gc_user = "pndCloud" + gc_secret = "pndCloud420!" + \ No newline at end of file