From e138ec8c2ee8b7c05ff279874638995e7e4da52c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maik=20Mu=CC=88ller?= Date: Thu, 9 May 2024 16:20:50 +0200 Subject: [PATCH 1/2] improved startup a lot --- gs/config/app.py | 1 + gs/config/device_config.json | 1 + gs/config/initial_config.py | 1 + gs/grow_system_api.py | 21 ++++---- gs/growsystem.py | 88 ++++++++++++++-------------------- gs/http_client.py | 2 + helper/file_helper.py | 36 ++++++++++++++ helper/token_helper.py | 9 ++++ http_client.py | 35 -------------- main.py | 44 +++++++++++++++-- {gs => setup}/little_apache.py | 86 +++++++++++++++++++++++++++++---- {gs => setup}/setup.py | 4 +- 12 files changed, 221 insertions(+), 107 deletions(-) create mode 100644 gs/config/device_config.json create mode 100644 gs/config/initial_config.py create mode 100644 helper/file_helper.py create mode 100644 helper/token_helper.py delete mode 100644 http_client.py rename {gs => setup}/little_apache.py (67%) rename {gs => setup}/setup.py (96%) diff --git a/gs/config/app.py b/gs/config/app.py index f066dbd..939fb3e 100644 --- a/gs/config/app.py +++ b/gs/config/app.py @@ -1,2 +1,3 @@ api_url = 'api.growsystem.muellerdev.kozow.com' read_secs = 1 * 60 +token = "lIEOISAH4DUfNvNP" diff --git a/gs/config/device_config.json b/gs/config/device_config.json new file mode 100644 index 0000000..0425b62 --- /dev/null +++ b/gs/config/device_config.json @@ -0,0 +1 @@ +{"sensors": [{"pin_int": 15, "type": "dht22"}, {"pin_int": 26, "type": "moisture"}], "device_id": 10, "name": "Proto Robin", "token": "lIEOISAH4DUfNvNP", "user_id": 1} \ No newline at end of file diff --git a/gs/config/initial_config.py b/gs/config/initial_config.py new file mode 100644 index 0000000..8095a07 --- /dev/null +++ b/gs/config/initial_config.py @@ -0,0 +1 @@ +config = {"ssid": "Oppa-95.lan", "user_id": "1", "password": "95%04-MM", "pin": "9941"} \ No newline at end of file diff --git a/gs/grow_system_api.py b/gs/grow_system_api.py index 2c85799..66cad14 100644 --- a/gs/grow_system_api.py +++ b/gs/grow_system_api.py @@ -3,6 +3,7 @@ from gs.device_info import DeviceInfo from gs.wlan_client import WlanClient import json import gs.config.initial_config as ic +import helper.token_helper as th class GrowSystemApi: @@ -30,16 +31,20 @@ class GrowSystemApi: }) print("activate ...", data) response = self.http_client.post(self.base_url + "/api/device/activate", data) - print("REsponse ...", response) + print("REsponse ...", response.content) 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 update_device_info(self, config): + device_id = self.device_info.get_device_id() + + token = self.device_info.get_token() + + print("update device info. Token ...", token) + url = self.base_url + "/api/device/" + str(device_id) + "/update-device-info/" + token + response = self.http_client.get(url) + print("Device Info Update Response ...", response.text) + return self._get_json_encoded(response.text) + 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) diff --git a/gs/growsystem.py b/gs/growsystem.py index 6046be1..f5fb200 100644 --- a/gs/growsystem.py +++ b/gs/growsystem.py @@ -1,18 +1,18 @@ -from gs.setup import Setup from gs.device_info import DeviceInfo -from gs.sensor_data_manager import SensorDataManager import os import ujson import machine import time +from gs.grow_system_api import GrowSystemApi from gs.classes.sensors.ambilight_sensor import AmbilightSensor from gs.classes.sensors.dht22 import TemperatureHumiditySensor from gs.classes.sensors.moisture_sensor import MoistureSensor - +import gs.config.initial_config as ic +import helper.token_helper as th class GrowSystem: - version = "1.0" + version = "1.0.0.1" initial_config = None @@ -22,25 +22,16 @@ class GrowSystem: 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.") - self._initialize_sensors() - elif self._is_initial_config_existing(): - print("Initial config only existing (no base config). Start activation ...") - self._activate() + self.initial_config = ic + self.gsapi = GrowSystemApi() def start(self): - self.sensor_data_manager = SensorDataManager(self.device_info.get_device_id()) - + from gs.device_info import DeviceInfo + di = DeviceInfo() + from gs.sensor_data_manager import SensorDataManager + self.sensor_data_manager = SensorDataManager(di.get_device_id()) + + self._initialize_sensors() print("Start reading sensors ...") read_secs = self.device_info.app_config().read_secs @@ -59,52 +50,45 @@ class GrowSystem: self.sensor_data_manager.handleData(self.most_recent_values) time.sleep(read_secs) - - def _setup(self): - setup = Setup() - setup.setup_pico() - machine.reset - def _activate(self): + 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['data']) - + print("Device Config:", device_config['data'], device_config['data']['token']) + th.write_token(device_config['data']['token']) + self.write_device_infos(device_config['data']) + machine.reset() + + def update_device_info(self): + print("Start Device Info Update!") + self.initial_config = ic.config + device_config = self.gsapi.update_device_info(self.initial_config) + print("Device Config:", device_config['data']) + self.write_device_infos(device_config['data']) + + def write_device_infos(self, device_config): + print("Function received data:", device_config) if True: - sensors = device_config['data']['sensors'] + sensors = device_config['sensors'] sensor_configs = [] for sensor in sensors: sensor_configs.append(sensor['config']) print(sensor['config']) device_configs = { - 'name': device_config['data']['name'], - 'device_id': device_config['data']['id'], - 'token': device_config['data']['token'], - 'user_id': device_config['data']['user_id'], + 'name': device_config['name'], + 'device_id': device_config['id'], + 'token': device_config['token'], + 'user_id': device_config['user_id'], 'sensors': sensor_configs } + print("Update device_config.json with:", device_configs) with open("/gs/config/device_config.json", "w") as f: f.write(ujson.dumps(device_configs)) - if self._is_config_existing(): - machine.reset + f.close() - def _is_config_existing(self): - return self._is_file_existing('/gs/config/device_config.json') - - 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 + def _initialize_sensors(self): # Init sensors diff --git a/gs/http_client.py b/gs/http_client.py index b819ff8..0053a01 100644 --- a/gs/http_client.py +++ b/gs/http_client.py @@ -9,12 +9,14 @@ class HTTPClient: url = 'https://' + url try: # headers = {'Content-Type': 'application/json'} + print("GET request to: ", url) 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) + return response except Exception as e: print("Exception occurred:", e) diff --git a/helper/file_helper.py b/helper/file_helper.py new file mode 100644 index 0000000..b6289a9 --- /dev/null +++ b/helper/file_helper.py @@ -0,0 +1,36 @@ +config_path = '/gs/config/' + +def is_config_existing(): + return is_file_existing(config_path + 'device_config.json') + +def is_initial_config_existing(): + return is_file_existing(config_path + 'initial_config.py') + +def is_file_existing(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 + +def replace_value(filepath, prop, newvalue): + with open(filepath, 'r') as file: + config_lines = file.readlines() + file.close() + +# Parse the config data into a dictionary + config_dict = {} + for line in config_lines: + if '=' in line: + key, value = line.strip().split('=') + config_dict[key.strip()] = value.strip() +# Add or Update the value of the property + config_dict[prop] = newvalue + +# Write the modified data back to the file + with open(filepath, 'w') as file: + for key, value in config_dict.items(): + file.write(f"{key} = {value}\n") diff --git a/helper/token_helper.py b/helper/token_helper.py new file mode 100644 index 0000000..45b4a3b --- /dev/null +++ b/helper/token_helper.py @@ -0,0 +1,9 @@ +import helper.file_helper as fh + +app_config_path = '/gs/config/app.py' + +def write_token(token): + print("Write new token: " + token) + fh.replace_value(app_config_path, 'token', '"' + token + '"') + #with open(app_config_path, "a") as app_config: + # app_config.write(token) diff --git a/http_client.py b/http_client.py deleted file mode 100644 index fd197ed..0000000 --- a/http_client.py +++ /dev/null @@ -1,35 +0,0 @@ -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/main.py b/main.py index ae2ca15..171e436 100644 --- a/main.py +++ b/main.py @@ -1,11 +1,49 @@ ## Only start grow system -from gs.growsystem import GrowSystem from time import sleep +import helper.file_helper as fh + +if False: + if not self._is_initial_config_existing(): + print("No config existing. Start setup ...") + self._setup() + return + + from gs.sensor_data_manager import SensorDataManager + self.sensor_data_manager = SensorDataManager(self.device_info.get_device_id()) + from gs.grow_system_api import GrowSystemApi as GSA + self.gsapi = GSA() + + if self._is_config_existing(): + print("Skip Setup. Config existing.") + self._initialize_sensors() + elif self._is_initial_config_existing(): + print("Initial config only existing (no base config). Start activation ...") + self._activate() + + +def setup(): + from setup.setup import Setup + setup = Setup() + setup.setup_pico() + machine.reset if __name__ == '__main__': - gs = GrowSystem() - gs.start() + # 1) Check and in case of update Growsystem + # 2) Check if initial_config is existing -> Setup if not + + if not fh.is_initial_config_existing(): + setup() + else: + from gs.growsystem import GrowSystem + gs = GrowSystem() + # 3) if device info exists update Device Info else activate + if fh.is_config_existing(): + gs.update_device_info() + else: + gs.activate() + # 4) Start growsystem + gs.start() while True: print("Keep running in main.py") diff --git a/gs/little_apache.py b/setup/little_apache.py similarity index 67% rename from gs/little_apache.py rename to setup/little_apache.py index 774a383..dfb1ae6 100644 --- a/gs/little_apache.py +++ b/setup/little_apache.py @@ -77,16 +77,85 @@ class LittleApache(): options = [] for w in self.available_wifis: options.append(''.format(w, w)) + body = """ -

Setup Pico

-
- SSID:
- Password:

- ID:
- PIN:
+ + + + + + Growsystem Setup + + + +

Growsystem Setup

+ +
+
+
+

+
+
+
+
-
- """ + + + +""" body = body.format(''.join(options)) elif self.is_path_match(request, '/save', 'POST'): print("Save config path: ", request) @@ -109,3 +178,4 @@ class LittleApache(): return path == request.path and method == request.method + diff --git a/gs/setup.py b/setup/setup.py similarity index 96% rename from gs/setup.py rename to setup/setup.py index fd5fea9..4ff01b9 100644 --- a/gs/setup.py +++ b/setup/setup.py @@ -3,7 +3,7 @@ import ujson import ure as re import usocket as socket import time -from gs.little_apache import LittleApache +from setup.little_apache import LittleApache class Setup: @@ -11,6 +11,7 @@ class Setup: wlans = [] def __init__(self): + print("Start Pico Setup") self.ap_ssid = "Growsystem 1.0" self.ap_password = "password" self.wlans = [] @@ -83,3 +84,4 @@ class Setup: # self.stop_ap_mode() # self.switch_to_client_mode() + From 9e06bd387a7b39195d0735d60509fa10195f7bc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maik=20Mu=CC=88ller?= Date: Thu, 9 May 2024 17:14:36 +0200 Subject: [PATCH 2/2] final for Robin --- gs/classes/http_request.py | 3 ++- gs/config/app.py | 5 +++-- gs/config/device_config.json | 1 - gs/config/initial_config.py | 1 - gs/growsystem.py | 5 +---- setup/little_apache.py | 1 - 6 files changed, 6 insertions(+), 10 deletions(-) delete mode 100644 gs/config/device_config.json delete mode 100644 gs/config/initial_config.py diff --git a/gs/classes/http_request.py b/gs/classes/http_request.py index c85063c..de04b87 100644 --- a/gs/classes/http_request.py +++ b/gs/classes/http_request.py @@ -51,7 +51,8 @@ class HttpRequest: # 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_value = re.sub(r'\%([0-9A-Fa-f]{2})', lambda m: chr(int(m.group(1), 16)), value) + print("encoding ...", key, value, encoded_value) encoded_content[key] = encoded_value return encoded_content diff --git a/gs/config/app.py b/gs/config/app.py index 939fb3e..963a867 100644 --- a/gs/config/app.py +++ b/gs/config/app.py @@ -1,3 +1,4 @@ +dev_api_url = 'api.growsystem.muellerdev.kozow.com' api_url = 'api.growsystem.muellerdev.kozow.com' -read_secs = 1 * 60 -token = "lIEOISAH4DUfNvNP" +read_secs = 15 * 60 +token = "dummy" diff --git a/gs/config/device_config.json b/gs/config/device_config.json deleted file mode 100644 index 0425b62..0000000 --- a/gs/config/device_config.json +++ /dev/null @@ -1 +0,0 @@ -{"sensors": [{"pin_int": 15, "type": "dht22"}, {"pin_int": 26, "type": "moisture"}], "device_id": 10, "name": "Proto Robin", "token": "lIEOISAH4DUfNvNP", "user_id": 1} \ No newline at end of file diff --git a/gs/config/initial_config.py b/gs/config/initial_config.py deleted file mode 100644 index 8095a07..0000000 --- a/gs/config/initial_config.py +++ /dev/null @@ -1 +0,0 @@ -config = {"ssid": "Oppa-95.lan", "user_id": "1", "password": "95%04-MM", "pin": "9941"} \ No newline at end of file diff --git a/gs/growsystem.py b/gs/growsystem.py index f5fb200..348550d 100644 --- a/gs/growsystem.py +++ b/gs/growsystem.py @@ -35,7 +35,7 @@ class GrowSystem: print("Start reading sensors ...") read_secs = self.device_info.app_config().read_secs - + print("Reading and sending every " + str(read_secs) + " seconds") while True: # Reset data self.most_recent_values = [] @@ -59,7 +59,6 @@ class GrowSystem: print("Device Config:", device_config['data'], device_config['data']['token']) th.write_token(device_config['data']['token']) self.write_device_infos(device_config['data']) - machine.reset() def update_device_info(self): print("Start Device Info Update!") @@ -88,8 +87,6 @@ class GrowSystem: f.write(ujson.dumps(device_configs)) f.close() - - def _initialize_sensors(self): # Init sensors sensors = self.device_info.config()['sensors'] diff --git a/setup/little_apache.py b/setup/little_apache.py index dfb1ae6..baacc95 100644 --- a/setup/little_apache.py +++ b/setup/little_apache.py @@ -168,7 +168,6 @@ select {{ body = f"""
Unknown page
""" - html = '' html_arr = [header, body, footer] html = html.join(html_arr)