Compare commits
5 Commits
release/20
...
main
| Author | SHA1 | Date |
|---|---|---|
|
|
d25e541735 | |
|
|
9e06bd387a | |
|
|
e138ec8c2e | |
|
|
0d91084c2d | |
|
|
c451777705 |
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,2 +1,4 @@
|
|||
dev_api_url = 'api.growsystem.muellerdev.kozow.com'
|
||||
api_url = 'api.growsystem.muellerdev.kozow.com'
|
||||
read_secs = 1 * 60
|
||||
read_secs = 15 * 60
|
||||
token = "dummy"
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,29 +22,20 @@ 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
|
||||
|
||||
print("Reading and sending every " + str(read_secs) + " seconds")
|
||||
while True:
|
||||
# Reset data
|
||||
self.most_recent_values = []
|
||||
|
|
@ -59,52 +50,42 @@ 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'])
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
f.close()
|
||||
|
||||
def _initialize_sensors(self):
|
||||
# Init sensors
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
||||
44
main.py
44
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")
|
||||
|
|
|
|||
|
|
@ -77,16 +77,85 @@ class LittleApache():
|
|||
options = []
|
||||
for w in self.available_wifis:
|
||||
options.append('<option value="{}">{}</option>'.format(w, w))
|
||||
|
||||
body = """
|
||||
<h1>Setup Pico</h1>
|
||||
<form method="post" action="save">
|
||||
SSID: <select name="ssid">{}</select><br>
|
||||
Password: <input type="password" name="password"><br><br>
|
||||
ID: <input type="number" name="user_id"/><br/>
|
||||
PIN: <input type="number" name="pin" maxlength="4"><br>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Growsystem Setup</title>
|
||||
<style>
|
||||
body {{
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f2f2f2;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
}}
|
||||
|
||||
form {{
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
max-width: 400px;
|
||||
width: 100%;
|
||||
}}
|
||||
|
||||
h1 {{
|
||||
text-align: center;
|
||||
color: #333;
|
||||
}}
|
||||
|
||||
input[type="submit"] {{
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
}}
|
||||
|
||||
input[type="submit"]:hover {{
|
||||
background-color: #45a049;
|
||||
}}
|
||||
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="number"],
|
||||
select {{
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
margin: 5px 0;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
box-sizing: border-box;
|
||||
}}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Growsystem Setup</h1>
|
||||
<form method="post" action="save">
|
||||
<label for="ssid">SSID:</label><br>
|
||||
<select name="ssid" id="ssid">
|
||||
{}
|
||||
</select><br>
|
||||
<label for="password">Password:</label><br>
|
||||
<input type="password" name="password" id="password"><br><br>
|
||||
<label for="user_id">ID:</label><br>
|
||||
<input type="number" name="user_id" id="user_id"><br>
|
||||
<label for="pin">PIN:</label><br>
|
||||
<input type="number" name="pin" id="pin" maxlength="4"><br>
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
"""
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
body = body.format(''.join(options))
|
||||
elif self.is_path_match(request, '/save', 'POST'):
|
||||
print("Save config path: ", request)
|
||||
|
|
@ -99,7 +168,6 @@ class LittleApache():
|
|||
body = f"""
|
||||
<div>Unknown page</div>
|
||||
"""
|
||||
|
||||
html = ''
|
||||
html_arr = [header, body, footer]
|
||||
html = html.join(html_arr)
|
||||
|
|
@ -109,3 +177,4 @@ class LittleApache():
|
|||
return path == request.path and method == request.method
|
||||
|
||||
|
||||
|
||||
|
|
@ -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()
|
||||
|
||||
|
||||
Loading…
Reference in New Issue