diff --git a/classes/http_request.py b/classes/http_request.py new file mode 100644 index 0000000..c85063c --- /dev/null +++ b/classes/http_request.py @@ -0,0 +1,72 @@ +import json +import ure as re + + +class HttpRequest: + + METHOD = { + "GET": "GET", + "POST": "POST" + } + + method = '' + path = '' + raw_content = '' + headers = {} + + def __init__(self, request): + self.original_request = request + # self.method = method + # self.path = path + # self.headers = headers + # self.raw_content = content + print("http request initialized") + self.parse_request(request) + + def parse_request(self, request): + # Split the request into lines + lines = request.decode().split('\r\n') + + # Extract method, path, and HTTP version from the first line + self.method, self.path, _ = lines[0].split() + + # Parse headers + for line in lines[1:]: + if not line: + break # Empty line indicates end of headers + key, value = line.split(': ', 1) + self.headers[key] = value + + # Content is assumed to be in the last line + self.raw_content = lines[-1] + + def get_content_json(self): + # Parse the POST request content into a dictionary + parsed_content = {} + pairs = self.raw_content.split('&') + for pair in pairs: + key, value = pair.split('=') + parsed_content[key] = value + + # Encode the values in the dictionary + encoded_content = {} + for key, value in parsed_content.items(): + encoded_value = re.sub(r'%([0-9A-Fa-f]{2})', lambda m: chr(int(m.group(1), 16)), value) + encoded_content[key] = encoded_value + + return encoded_content + + def __str__(self): + return { + "method": self.method, + "headers": self.headers, + "content": self.raw_content, + "content_json": self.get_content_json() + } + + + + + + + diff --git a/config/app.py b/config/app.py new file mode 100644 index 0000000..8a5b5e3 --- /dev/null +++ b/config/app.py @@ -0,0 +1 @@ +api_url = 'https://growsystem.muellerdev.kozow.com/api/' diff --git a/grow_system_api.py b/grow_system_api.py index 0e3376c..8a73310 100644 --- a/grow_system_api.py +++ b/grow_system_api.py @@ -13,6 +13,10 @@ class GrowSystemApi: def __init__(self): self.base_url = self.device_info.server_url + + def activate(self, config): + response = self.http_client.post(self.base_url + "/api/device/activate", self._get_device_data()) + return self_get_json_encoded(response.text) def say_hello(self): response = self.http_client.post(self.base_url + "/api/device", self._get_device_data()) @@ -29,3 +33,6 @@ class GrowSystemApi: def _get_device_data(self): return self.device_info.get_all_device_infos() + def _get_json_encoded(self, text): + return json.loads(text) + diff --git a/growsystem.py b/growsystem.py new file mode 100644 index 0000000..31a151c --- /dev/null +++ b/growsystem.py @@ -0,0 +1,41 @@ +from gs.setup import Setup +import os + + +class GrowSystem: + + version = "1.0" + + def __init__(self): + print("Initialize Growsystem", self.version) + if self._is_config_existing(): + print("Skip Setup. Config existing.") + elif self._is_initial_config_existing(): + self._activate() + else: + print("No config existing. Start setup ...") + self._setup() + + def _setup(self): + setup = Setup() + setup.setup_pico() + + def _activate(self): + print("Start activation!") + + def _is_config_existing(self): + return self._is_file_existing('/gs/config/config.py') + + def _is_initial_config_existing(self): + return self._is_file_existing('/gs/config/initial_config.py') + + def _is_file_existing(self, filepath): + try: + f = open(filepath, "r") + f.close() + # continue with the file. + return True + except OSError: # open failed + # handle the file open cas + return False + diff --git a/gs/classes/http_request.py b/gs/classes/http_request.py new file mode 100644 index 0000000..c85063c --- /dev/null +++ b/gs/classes/http_request.py @@ -0,0 +1,72 @@ +import json +import ure as re + + +class HttpRequest: + + METHOD = { + "GET": "GET", + "POST": "POST" + } + + method = '' + path = '' + raw_content = '' + headers = {} + + def __init__(self, request): + self.original_request = request + # self.method = method + # self.path = path + # self.headers = headers + # self.raw_content = content + print("http request initialized") + self.parse_request(request) + + def parse_request(self, request): + # Split the request into lines + lines = request.decode().split('\r\n') + + # Extract method, path, and HTTP version from the first line + self.method, self.path, _ = lines[0].split() + + # Parse headers + for line in lines[1:]: + if not line: + break # Empty line indicates end of headers + key, value = line.split(': ', 1) + self.headers[key] = value + + # Content is assumed to be in the last line + self.raw_content = lines[-1] + + def get_content_json(self): + # Parse the POST request content into a dictionary + parsed_content = {} + pairs = self.raw_content.split('&') + for pair in pairs: + key, value = pair.split('=') + parsed_content[key] = value + + # Encode the values in the dictionary + encoded_content = {} + for key, value in parsed_content.items(): + encoded_value = re.sub(r'%([0-9A-Fa-f]{2})', lambda m: chr(int(m.group(1), 16)), value) + encoded_content[key] = encoded_value + + return encoded_content + + def __str__(self): + return { + "method": self.method, + "headers": self.headers, + "content": self.raw_content, + "content_json": self.get_content_json() + } + + + + + + + diff --git a/gs/config/app.py b/gs/config/app.py new file mode 100644 index 0000000..8a5b5e3 --- /dev/null +++ b/gs/config/app.py @@ -0,0 +1 @@ +api_url = 'https://growsystem.muellerdev.kozow.com/api/' diff --git a/gs/config/initial_config.py b/gs/config/initial_config.py new file mode 100644 index 0000000..fb8b537 --- /dev/null +++ b/gs/config/initial_config.py @@ -0,0 +1 @@ +config = {"pin": "4628", "password": "95%04-MM", "ssid": "Oppa-95.lan"} \ No newline at end of file diff --git a/gs/device_info.py b/gs/device_info.py new file mode 100644 index 0000000..c88ffa7 --- /dev/null +++ b/gs/device_info.py @@ -0,0 +1,68 @@ +import network + + +class DeviceInfo: + + # Device Infos + name = "Dev Device 1" + + token = "PC]-0Bmp83h7F5#U!D6KJ(A&" + + #server_url = 'api.growsystem.muelleronline.org' + server_url = 'api.growsystem.muellerdev.kozow.com' + + wlan_ssid = 'Oppa-95.lan' + wlan_pw = '95%04-MM' + + sensors = [ + { + 'type': 'moisture', + 'pin_int': 26 + }, + { + 'type': 'ambilight', + 'pin_int': 8, # for compatibility only + 'pin_int_sda': 8, + 'pin_int_scl': 9 + }, + + + # { + # 'type': 'dht22', + # 'pin_int': 15 + # } + ] + + engines = [ + { + 'type': 'pump', + 'pins': [15] + } + ] + + read_secs = 5 + # Device Infos End + + wlan = network.WLAN(network.STA_IF) + + def get_macaddress(self): + return self._format_mac(self.wlan.config('mac').hex()) + + def get_ipaddress(self): + return self.wlan.ifconfig()[0] + + def get_all_device_infos(self): + return { + 'name': self.name, + 'mac_address': self.get_macaddress(), + 'ip_address': self.get_ipaddress(), + 'token': self.token} + + def _format_mac(self, mac): + # Split the MAC address into pairs of two characters each + pairs = [mac[i:i+2] for i in range(0, len(mac), 2)] + # Join the pairs with colons to create the formatted MAC address + formatted_mac = ":".join(pairs) + return formatted_mac + + \ No newline at end of file diff --git a/gs/grow_system_api.py b/gs/grow_system_api.py new file mode 100644 index 0000000..a40ed6b --- /dev/null +++ b/gs/grow_system_api.py @@ -0,0 +1,52 @@ +from gs.http_client import HTTPClient +from gs.device_info import DeviceInfo +from gs.wlan_client import WlanClient +import json +import gs.config.initial_config as ic + + +class GrowSystemApi: + + http_client = HTTPClient() + + device_info = DeviceInfo() + + base_url = '' + + def __init__(self): + self.base_url = self.device_info.server_url + self.connect_wifi(ic.config['ssid'], ic.config['password']) + + def activate(self, config): + data = self._get_device_data() + data.update({ + 'user_id': 1, + 'pin': config['pin'] + }) + print("activate ...", data) + response = self.http_client.post(self.base_url + "/api/device/activate", data) + return self._get_json_encoded(response.text) + + def say_hello(self): + response = self.http_client.post(self.base_url + "/api/device", self._get_device_data()) + print(response.text) + jsonResult = json.loads(response.text) + print(jsonResult) + return jsonResult; + + def send_measurements(self, device_id, data): + url = self.base_url + "/api/device/" + str(device_id) + "/sensor-log" + response = self.http_client.post(url, data) + return json.loads(response.text) + + def _get_device_data(self): + return self.device_info.get_all_device_infos() + + def _get_json_encoded(self, text): + return json.loads(text) + + def connect_wifi(self, ssid, password): + print("Connect WLAN") + self.wlan_client = WlanClient(ssid, password) + self.wlan_client.connect() + diff --git a/gs/growsystem.py b/gs/growsystem.py new file mode 100644 index 0000000..fad5818 --- /dev/null +++ b/gs/growsystem.py @@ -0,0 +1,54 @@ +from gs.setup import Setup +import os + + +class GrowSystem: + + version = "1.0" + + initial_config = None + + def __init__(self): + print("Initialize Growsystem", self.version) + + if not self._is_initial_config_existing(): + print("No config existing. Start setup ...") + self._setup() + return + + from gs.grow_system_api import GrowSystemApi as GSA + self.gsapi = GSA() + + if self._is_config_existing(): + print("Skip Setup. Config existing.") + elif self._is_initial_config_existing(): + print("Initial config only existing (no base config). Start activation ...") + self._activate() + + def _setup(self): + setup = Setup() + setup.setup_pico() + + def _activate(self): + print("Start activation!") + import gs.config.initial_config as ic + self.initial_config = ic.config + device_config = self.gsapi.activate(self.initial_config) + print("Device Config:", device_config) + + def _is_config_existing(self): + return self._is_file_existing('/gs/config/config.py') + + def _is_initial_config_existing(self): + return self._is_file_existing('/gs/config/initial_config.py') + + def _is_file_existing(self, filepath): + try: + f = open(filepath, "r") + f.close() + # continue with the file. + return True + except OSError: # open failed + # handle the file open cas + return False + diff --git a/gs/http_client.py b/gs/http_client.py new file mode 100644 index 0000000..fd197ed --- /dev/null +++ b/gs/http_client.py @@ -0,0 +1,35 @@ +import urequests +import json + +class HTTPClient: + def __init__(self): + pass + + def get(self, url): + url = 'https://' + url + try: + # headers = {'Content-Type': 'application/json'} + response = urequests.get(url) + if response.status_code == 200: + print("Data sent, got response") + return response + else: + print("Failed to get data. Status code:", response.status_code) + except Exception as e: + print("Exception occurred:", e) + + def post(self, url, data): + url = 'https://' + url + try: + headers = {'Content-Type': 'application/json', 'Accept': 'application/json, text/plain, */*'} + json_data = json.dumps(data) + print("Send post request to: " + url) + response = urequests.post(url, data=json_data, headers=headers) + if response.status_code == 200: + return response + else: + print("Failed to send data. Status code:", response.status_code) + print(response.text) + except Exception as e: + print("Exception occurred:", e) + diff --git a/gs/little_apache.py b/gs/little_apache.py new file mode 100644 index 0000000..841c96c --- /dev/null +++ b/gs/little_apache.py @@ -0,0 +1,110 @@ +import socket +from gs.classes.http_request import HttpRequest + + +class LittleApache(): + + available_wifis = [] + keep_webserver_alive = True + + + def __init__(self, net): + self.net = net + addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1] + self.s = socket.socket() + self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.s.bind(addr) + self.s.listen() + # print('Listening on', addr) + + def start(self): + print("Webserver started. Connect to: " + self.net.ifconfig()[0]) + print(self.net.ifconfig()) + + while self.keep_webserver_alive: + try: + conn, addr = self.s.accept() + #print('Got a connection from', addr) + + # Receive and parse the request + request = conn.recv(1024) + # print("Request (RAW)", request) + http_request = HttpRequest(request) + self.http_request = http_request + request = str(request) + # print('Request content = %s' % request) + #try: + # request = request.split()[1] + # print('Request:', request) + #except IndexError: + # pass + response = self.response(http_request) + # Send the HTTP response and close the connection + conn.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n') + conn.send(response) + conn.close() + except OSError as e: + conn.close() + print('Connection closed') + return self + + def response(self, request: HttpRequest): + #print("Webpage: ", request) + print("Request method: ", request.method, "Request path: ", request.path) + + header = f""" + + + + Growsystem + + + + """ + + footer = f""" + + + """ + + body = "" + + if self.is_path_match(request, '/test1'): + body = f""" +
Test 1!!!
+ """ + elif (self.is_path_match(request, '') or self.is_path_match(request, '/')): + options = [] + for w in self.available_wifis: + options.append(''.format(w, w)) + body = """ +

Setup Pico

+
+ SSID:
+ Password:
+ PIN:
+ +
+ """ + body = body.format(''.join(options)) + elif self.is_path_match(request, '/save', 'POST'): + print("Save config path: ", request) + self.keep_webserver_alive = False + body = """ +

Setup Pico

+
Setup abgeschlossen. Bitte ein paar Sekunden warten, dann neu starten.
+ """ + else: + body = f""" +
Unknown page
+ """ + + html = '' + html_arr = [header, body, footer] + html = html.join(html_arr) + return str(html) + + def is_path_match(self, request, path, method='GET'): + return path == request.path and method == request.method + + diff --git a/gs/setup.py b/gs/setup.py new file mode 100644 index 0000000..5b89e9d --- /dev/null +++ b/gs/setup.py @@ -0,0 +1,84 @@ +import network +import ujson +import ure as re +import usocket as socket +import time +from gs.little_apache import LittleApache + + +class Setup: + + wlans = [] + + def __init__(self): + self.ap_ssid = "Growsystem 1.0" + self.ap_password = "password" + self.wlans = [] + self.selected_ssid = "" + self.wlan_password = "" + self.pin = "" + + def scan_wlans(self): + print("Scan for WiFis") + wlan = network.WLAN(network.STA_IF) + wlan.active(True) + self.wlans = [w[0].decode() for w in wlan.scan()] + print("Detected WiFis: ", self.wlans) + wlan.active(False) + + def start_ap_mode(self): + wlan = network.WLAN(network.STA_IF) + wlan.active(False) + wlan_config = { + "ssid": self.ap_ssid, + "pw": self.ap_password + } + print("Switch to ap mode with data:", wlan_config) + ap = network.WLAN(network.AP_IF) + ap.config(essid=self.ap_ssid, password=self.ap_password) + ap.active(True) + self.net = ap + print("Connect with your browser to:", ap.ifconfig()[0]) + + def stop_ap_mode(self): + print("Stop ap mode") + ap = network.WLAN(network.AP_IF) + ap.active(False) + + def get_initial_config_webserver(self): + self.la = LittleApache(self.net) + self.la.available_wifis = self.wlans + self.la.start() + config = self.la.http_request.get_content_json() + print("start webserver end:", config) + return config + + def save_config(self, config): + config = { + "ssid": config['ssid'], + "password": config['password'], + "pin": config['pin'] + } + print("Save config:", config) + with open("/gs/config/initial_config.py", "w") as f: + f.write("config = " + ujson.dumps(config)) + + def switch_to_client_mode(self): + print("Switch to client mode") + ap = network.WLAN(network.AP_IF) + ap.active(False) + wlan = network.WLAN(network.STA_IF) + wlan.active(True) + wlan.connect(self.selected_ssid, self.wlan_password) + while not wlan.isconnected(): + time.sleep(1) + print("Connected to", self.selected_ssid) + + def setup_pico(self): + self.scan_wlans() + self.start_ap_mode() + config = self.get_initial_config_webserver() + self.save_config(config) + # self.stop_ap_mode() + # self.switch_to_client_mode() + diff --git a/gs/wlan_client.py b/gs/wlan_client.py new file mode 100644 index 0000000..723832f --- /dev/null +++ b/gs/wlan_client.py @@ -0,0 +1,40 @@ +import machine +import network +import time +# network.country('DE') + + +class WlanClient: + + ssid = '' + pw = '' + wlan = None + # Status-LED + led_onboard = machine.Pin('LED', machine.Pin.OUT) + led_onboard.value(False) + + def __init__(self, ssid, pw): + # print("Hello from wlan class") + self.ssid = ssid + self.pw = pw + self.wlan = network.WLAN(network.STA_IF) + + def connect(self): + if not self.is_connected(): + print('No WLAN connected. Connecting ...' + self.ssid + ' ' + self.pw) + self.wlan.active(True) + self.wlan.connect(self.ssid, self.pw) + for i in range(10): + if self.wlan.status() < 0 or self.wlan.status() >= 3: + break + time.sleep(1) + # led_value = self.led_onboard.value() == 1 + # self.led_onboard.value(led_value) + if self.wlan.isconnected(): + net_config = self.wlan.ifconfig() + print("NetConfig:") + print(net_config) + + def is_connected(self): + return self.wlan.isconnected() + diff --git a/little_apache.py b/little_apache.py new file mode 100644 index 0000000..841c96c --- /dev/null +++ b/little_apache.py @@ -0,0 +1,110 @@ +import socket +from gs.classes.http_request import HttpRequest + + +class LittleApache(): + + available_wifis = [] + keep_webserver_alive = True + + + def __init__(self, net): + self.net = net + addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1] + self.s = socket.socket() + self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.s.bind(addr) + self.s.listen() + # print('Listening on', addr) + + def start(self): + print("Webserver started. Connect to: " + self.net.ifconfig()[0]) + print(self.net.ifconfig()) + + while self.keep_webserver_alive: + try: + conn, addr = self.s.accept() + #print('Got a connection from', addr) + + # Receive and parse the request + request = conn.recv(1024) + # print("Request (RAW)", request) + http_request = HttpRequest(request) + self.http_request = http_request + request = str(request) + # print('Request content = %s' % request) + #try: + # request = request.split()[1] + # print('Request:', request) + #except IndexError: + # pass + response = self.response(http_request) + # Send the HTTP response and close the connection + conn.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n') + conn.send(response) + conn.close() + except OSError as e: + conn.close() + print('Connection closed') + return self + + def response(self, request: HttpRequest): + #print("Webpage: ", request) + print("Request method: ", request.method, "Request path: ", request.path) + + header = f""" + + + + Growsystem + + + + """ + + footer = f""" + + + """ + + body = "" + + if self.is_path_match(request, '/test1'): + body = f""" +
Test 1!!!
+ """ + elif (self.is_path_match(request, '') or self.is_path_match(request, '/')): + options = [] + for w in self.available_wifis: + options.append(''.format(w, w)) + body = """ +

Setup Pico

+
+ SSID:
+ Password:
+ PIN:
+ +
+ """ + body = body.format(''.join(options)) + elif self.is_path_match(request, '/save', 'POST'): + print("Save config path: ", request) + self.keep_webserver_alive = False + body = """ +

Setup Pico

+
Setup abgeschlossen. Bitte ein paar Sekunden warten, dann neu starten.
+ """ + else: + body = f""" +
Unknown page
+ """ + + html = '' + html_arr = [header, body, footer] + html = html.join(html_arr) + return str(html) + + def is_path_match(self, request, path, method='GET'): + return path == request.path and method == request.method + + diff --git a/main.py b/main.py index 12935fd..71b2e28 100644 --- a/main.py +++ b/main.py @@ -1,63 +1,12 @@ -# GrowSystem -# Author: Maik Müller (maik@muelleronlineorg) - -# WIP! -# This file should do only: -# - first start check and actions if not configured -# - provide constants for settings -# - eventually necessary system settings -# - init wlan connection -# - Call base class, permitting the configured constants -import network -import urequests -from grow_system import GrowSystem -from wlan import WlanClient -from http_client import HTTPClient -from device_info import DeviceInfo -from setup import Setup +## Only start grow system +from gs.growsystem import GrowSystem +from time import sleep -settings = { - 'wlan_ssid': 'Oppa-95.lan', - 'wlan_pw': '95%04-MM', - 'moisture_sensor': { - 'pin_int': 26 - }, - 'temperature_humidity_sensor': { - 'pin_int': 15 - }, - 'pump_pin_int': 24 -} - - -def wlan_scan(): - # Client-Betrieb - wlan = network.WLAN(network.STA_IF) - # WLAN-Interface aktivieren - wlan.active(True) - # WLANs ausgeben - found_wlans = wlan.scan() - return found_wlans - - -# Press the green button in the gutter to run the script. if __name__ == '__main__': - pico_setup = Setup() - pico_setup.setup_pico() + gs = GrowSystem() - if false: - #print(wlan_scan()) - print("Connect WLAN") - wlanClient = WlanClient(settings['wlan_ssid'], settings['wlan_pw']) - wlanClient.connect() - print("") - - di = DeviceInfo() - print("Device Infos:") - print(di.get_all_device_infos()) - print("") - - print("Start grow system") - gs = GrowSystem(settings) - gs.start() - + while True: + print("Keep running in main.py") + sleep(5) + diff --git a/README.md b/old_version/README.md similarity index 100% rename from README.md rename to old_version/README.md diff --git a/REDME.md b/old_version/REDME.md similarity index 100% rename from REDME.md rename to old_version/REDME.md diff --git a/ambilight_sensor.py b/old_version/ambilight_sensor.py similarity index 100% rename from ambilight_sensor.py rename to old_version/ambilight_sensor.py diff --git a/bh1750.old_1/__init__.py b/old_version/bh1750.old_1/__init__.py similarity index 100% rename from bh1750.old_1/__init__.py rename to old_version/bh1750.old_1/__init__.py diff --git a/bh1750.old_1/bh1750.py b/old_version/bh1750.old_1/bh1750.py similarity index 100% rename from bh1750.old_1/bh1750.py rename to old_version/bh1750.old_1/bh1750.py diff --git a/device_info.py b/old_version/device_info.py similarity index 100% rename from device_info.py rename to old_version/device_info.py diff --git a/dht22.py b/old_version/dht22.py similarity index 100% rename from dht22.py rename to old_version/dht22.py diff --git a/engine.py b/old_version/engine.py similarity index 100% rename from engine.py rename to old_version/engine.py diff --git a/grow_system.py b/old_version/grow_system.py similarity index 100% rename from grow_system.py rename to old_version/grow_system.py diff --git a/old_version/grow_system_api.py b/old_version/grow_system_api.py new file mode 100644 index 0000000..8a73310 --- /dev/null +++ b/old_version/grow_system_api.py @@ -0,0 +1,38 @@ +from http_client import HTTPClient +from device_info import DeviceInfo +import json + + +class GrowSystemApi: + + http_client = HTTPClient() + + device_info = DeviceInfo() + + base_url = '' + + def __init__(self): + self.base_url = self.device_info.server_url + + def activate(self, config): + response = self.http_client.post(self.base_url + "/api/device/activate", self._get_device_data()) + return self_get_json_encoded(response.text) + + def say_hello(self): + response = self.http_client.post(self.base_url + "/api/device", self._get_device_data()) + print(response.text) + jsonResult = json.loads(response.text) + print(jsonResult) + return jsonResult; + + def send_measurements(self, device_id, data): + url = self.base_url + "/api/device/" + str(device_id) + "/sensor-log" + response = self.http_client.post(url, data) + return json.loads(response.text) + + def _get_device_data(self): + return self.device_info.get_all_device_infos() + + def _get_json_encoded(self, text): + return json.loads(text) + diff --git a/old_version/http_client.py b/old_version/http_client.py new file mode 100644 index 0000000..fd197ed --- /dev/null +++ b/old_version/http_client.py @@ -0,0 +1,35 @@ +import urequests +import json + +class HTTPClient: + def __init__(self): + pass + + def get(self, url): + url = 'https://' + url + try: + # headers = {'Content-Type': 'application/json'} + response = urequests.get(url) + if response.status_code == 200: + print("Data sent, got response") + return response + else: + print("Failed to get data. Status code:", response.status_code) + except Exception as e: + print("Exception occurred:", e) + + def post(self, url, data): + url = 'https://' + url + try: + headers = {'Content-Type': 'application/json', 'Accept': 'application/json, text/plain, */*'} + json_data = json.dumps(data) + print("Send post request to: " + url) + response = urequests.post(url, data=json_data, headers=headers) + if response.status_code == 200: + return response + else: + print("Failed to send data. Status code:", response.status_code) + print(response.text) + except Exception as e: + print("Exception occurred:", e) + diff --git a/lib/bh1750.py b/old_version/lib/bh1750.py similarity index 100% rename from lib/bh1750.py rename to old_version/lib/bh1750.py diff --git a/old_version/main.py b/old_version/main.py new file mode 100644 index 0000000..12935fd --- /dev/null +++ b/old_version/main.py @@ -0,0 +1,63 @@ +# GrowSystem +# Author: Maik Müller (maik@muelleronlineorg) + +# WIP! +# This file should do only: +# - first start check and actions if not configured +# - provide constants for settings +# - eventually necessary system settings +# - init wlan connection +# - Call base class, permitting the configured constants +import network +import urequests +from grow_system import GrowSystem +from wlan import WlanClient +from http_client import HTTPClient +from device_info import DeviceInfo +from setup import Setup + + +settings = { + 'wlan_ssid': 'Oppa-95.lan', + 'wlan_pw': '95%04-MM', + 'moisture_sensor': { + 'pin_int': 26 + }, + 'temperature_humidity_sensor': { + 'pin_int': 15 + }, + 'pump_pin_int': 24 +} + + +def wlan_scan(): + # Client-Betrieb + wlan = network.WLAN(network.STA_IF) + # WLAN-Interface aktivieren + wlan.active(True) + # WLANs ausgeben + found_wlans = wlan.scan() + return found_wlans + + +# Press the green button in the gutter to run the script. +if __name__ == '__main__': + pico_setup = Setup() + pico_setup.setup_pico() + + if false: + #print(wlan_scan()) + print("Connect WLAN") + wlanClient = WlanClient(settings['wlan_ssid'], settings['wlan_pw']) + wlanClient.connect() + print("") + + di = DeviceInfo() + print("Device Infos:") + print(di.get_all_device_infos()) + print("") + + print("Start grow system") + gs = GrowSystem(settings) + gs.start() + diff --git a/moisture_sensor.py b/old_version/moisture_sensor.py similarity index 100% rename from moisture_sensor.py rename to old_version/moisture_sensor.py diff --git a/notes/code_sample_moisture_sensor.txt b/old_version/notes/code_sample_moisture_sensor.txt similarity index 100% rename from notes/code_sample_moisture_sensor.txt rename to old_version/notes/code_sample_moisture_sensor.txt diff --git a/pump.py b/old_version/pump.py similarity index 100% rename from pump.py rename to old_version/pump.py diff --git a/sensor_data_manager.py b/old_version/sensor_data_manager.py similarity index 100% rename from sensor_data_manager.py rename to old_version/sensor_data_manager.py diff --git a/sensors.py b/old_version/sensors.py similarity index 100% rename from sensors.py rename to old_version/sensors.py diff --git a/old_version/setup.py b/old_version/setup.py new file mode 100644 index 0000000..2aa6cee --- /dev/null +++ b/old_version/setup.py @@ -0,0 +1,113 @@ +import network +import ujson +import ure as re +import usocket as socket +import time + +class Setup: + def __init__(self): + self.ap_ssid = "Growsystem" + self.ap_password = "12345678" + self.wlans = [] + self.selected_ssid = "" + self.wlan_password = "" + self.pin = "" + self.html = """ + + Pico Setup + +

Setup Pico

+
+ SSID:
+ Password:
+ PIN:
+ +
+ + + """ + + def scan_wlans(self): + print("Scan WLANs") + wlan = network.WLAN(network.STA_IF) + wlan.active(True) + self.wlans = [w[0].decode() for w in wlan.scan()] + print("Found:", self.wlans) + wlan.active(False) + + def start_ap_mode(self): + self.ap = network.WLAN(network.AP_IF) + self.ap.active(True) + while self.ap.active() == False: + pass + self.ap.config(essid=self.ap_ssid, password=self.ap_password) + print("AP SSID:", self.ap.config("essid")) + # print("AP Password:", self.ap.config("password")) + + def stop_ap_mode(self): + ap = network.WLAN(network.AP_IF) + ap.active(False) + + def start_webserver(self): + addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1] + s = socket.socket() + s.bind(addr) + s.listen(1) + print("Listening on", addr) + while True: + conn, addr = s.accept() + print("Got a connection from", addr) + request = conn.recv(1024) + print("Content =", request) + conn.send("HTTP/1.1 200 OK\n") + conn.send("Content-Type: text/html\n") + conn.send("Connection: close\n\n") + conn.sendall(self.html.format(''.join([''.format(w, w) for w in self.wlans]))) + conn.close() + + def parse_request(self, request): + request = request.decode() + ssid_match = re.search("ssid=([^&]+)", request) + if ssid_match: + self.selected_ssid = ssid_match.group(1) + password_match = re.search("password=([^&]+)", request) + if password_match: + self.wlan_password = password_match.group(1) + pin_match = re.search("pin=([^&]+)", request) + if pin_match: + self.pin = pin_match.group(1) + + def save_config(self): + config = { + "ssid": self.selected_ssid, + "password": self.wlan_password, + "pin": self.pin + } + with open("initial_config.py", "w") as f: + f.write("config = " + ujson.dumps(config)) + + def switch_to_client_mode(self): + ap = network.WLAN(network.AP_IF) + ap.active(False) + wlan = network.WLAN(network.STA_IF) + wlan.active(True) + wlan.connect(self.selected_ssid, self.wlan_password) + while not wlan.isconnected(): + time.sleep(1) + print("Connected to", self.selected_ssid) + + def setup_pico(self): + print("Start PICO setup") + self.scan_wlans() + self.start_ap_mode() + self.start_webserver() + while True: + conn, addr = self.s.accept() + request = conn.recv(1024) + self.parse_request(request) + self.save_config() + conn.close() + break # Assuming only one request is handled + self.stop_ap_mode() + self.switch_to_client_mode() + diff --git a/wlan.py b/old_version/wlan.py similarity index 100% rename from wlan.py rename to old_version/wlan.py diff --git a/setup.py b/setup.py index 2aa6cee..5b89e9d 100644 --- a/setup.py +++ b/setup.py @@ -3,90 +3,68 @@ import ujson import ure as re import usocket as socket import time +from gs.little_apache import LittleApache + class Setup: + + wlans = [] + def __init__(self): - self.ap_ssid = "Growsystem" - self.ap_password = "12345678" + self.ap_ssid = "Growsystem 1.0" + self.ap_password = "password" self.wlans = [] self.selected_ssid = "" self.wlan_password = "" self.pin = "" - self.html = """ - - Pico Setup - -

Setup Pico

-
- SSID:
- Password:
- PIN:
- -
- - - """ def scan_wlans(self): - print("Scan WLANs") + print("Scan for WiFis") wlan = network.WLAN(network.STA_IF) wlan.active(True) self.wlans = [w[0].decode() for w in wlan.scan()] - print("Found:", self.wlans) + print("Detected WiFis: ", self.wlans) wlan.active(False) def start_ap_mode(self): - self.ap = network.WLAN(network.AP_IF) - self.ap.active(True) - while self.ap.active() == False: - pass - self.ap.config(essid=self.ap_ssid, password=self.ap_password) - print("AP SSID:", self.ap.config("essid")) - # print("AP Password:", self.ap.config("password")) + wlan = network.WLAN(network.STA_IF) + wlan.active(False) + wlan_config = { + "ssid": self.ap_ssid, + "pw": self.ap_password + } + print("Switch to ap mode with data:", wlan_config) + ap = network.WLAN(network.AP_IF) + ap.config(essid=self.ap_ssid, password=self.ap_password) + ap.active(True) + self.net = ap + print("Connect with your browser to:", ap.ifconfig()[0]) def stop_ap_mode(self): + print("Stop ap mode") ap = network.WLAN(network.AP_IF) ap.active(False) - def start_webserver(self): - addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1] - s = socket.socket() - s.bind(addr) - s.listen(1) - print("Listening on", addr) - while True: - conn, addr = s.accept() - print("Got a connection from", addr) - request = conn.recv(1024) - print("Content =", request) - conn.send("HTTP/1.1 200 OK\n") - conn.send("Content-Type: text/html\n") - conn.send("Connection: close\n\n") - conn.sendall(self.html.format(''.join([''.format(w, w) for w in self.wlans]))) - conn.close() + def get_initial_config_webserver(self): + self.la = LittleApache(self.net) + self.la.available_wifis = self.wlans + self.la.start() + config = self.la.http_request.get_content_json() + print("start webserver end:", config) + return config - def parse_request(self, request): - request = request.decode() - ssid_match = re.search("ssid=([^&]+)", request) - if ssid_match: - self.selected_ssid = ssid_match.group(1) - password_match = re.search("password=([^&]+)", request) - if password_match: - self.wlan_password = password_match.group(1) - pin_match = re.search("pin=([^&]+)", request) - if pin_match: - self.pin = pin_match.group(1) - - def save_config(self): + def save_config(self, config): config = { - "ssid": self.selected_ssid, - "password": self.wlan_password, - "pin": self.pin + "ssid": config['ssid'], + "password": config['password'], + "pin": config['pin'] } - with open("initial_config.py", "w") as f: + print("Save config:", config) + with open("/gs/config/initial_config.py", "w") as f: f.write("config = " + ujson.dumps(config)) def switch_to_client_mode(self): + print("Switch to client mode") ap = network.WLAN(network.AP_IF) ap.active(False) wlan = network.WLAN(network.STA_IF) @@ -97,17 +75,10 @@ class Setup: print("Connected to", self.selected_ssid) def setup_pico(self): - print("Start PICO setup") self.scan_wlans() self.start_ap_mode() - self.start_webserver() - while True: - conn, addr = self.s.accept() - request = conn.recv(1024) - self.parse_request(request) - self.save_config() - conn.close() - break # Assuming only one request is handled - self.stop_ap_mode() - self.switch_to_client_mode() + config = self.get_initial_config_webserver() + self.save_config(config) + # self.stop_ap_mode() + # self.switch_to_client_mode() diff --git a/teststuff/main.py b/teststuff/main.py new file mode 100644 index 0000000..27c3051 --- /dev/null +++ b/teststuff/main.py @@ -0,0 +1,50 @@ +import network +import time +import socket + +ssid="Growsystem" +password="12345678" + +def web_page(): + html = """ +

Hello World

+ """ + return html + +# if you do not see the network you may have to power cycle +# unplug your pico w for 10 seconds and plug it in again +def ap_mode(ssid, password): + """ + Description: This is a function to activate AP mode + + Parameters: + + ssid[str]: The name of your internet connection + password[str]: Password for your internet connection + + Returns: Nada + """ + # Just making our internet connection + ap = network.WLAN(network.AP_IF) + ap.config(essid=ssid, password=password) + ap.active(True) + + while ap.active() == False: + pass + print('AP Mode Is Active, You can Now Connect') + print('IP Address To Connect to:: ' + ap.ifconfig()[0]) + + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #creating socket object + s.bind(('', 80)) + s.listen(5) + + while True: + conn, addr = s.accept() + print('Got a connection from %s' % str(addr)) + request = conn.recv(1024) + print('Content = %s' % str(request)) + response = web_page() + conn.send(response) + conn.close() + +ap_mode('Growsystem95','PASSWORD') \ No newline at end of file