1
0
mirror of https://github.com/xg590/IoT.git synced 2024-11-17 00:37:38 +03:00
This commit is contained in:
Xiaokang Guo
2022-10-29 23:39:01 -04:00
parent ef917412a9
commit f5229ac913
8 changed files with 733 additions and 52 deletions

46
Board/Arduino_CLI.md Normal file
View File

@@ -0,0 +1,46 @@
### <a name="Arduino-CLI">Arduino-CLI:</a> Program Arduino board in CLI
* Blink
```
wget arduino-cli_0.18.3_Linux_64bit.tar.gz && tar zxvf # https://github.com/arduino/arduino-cli/releases
sudo mv arduino-cli /usr/local/bin/
arduino-cli core install arduino:avr # Install compile platform of Arduino board family
arduino-cli core update-index --additional-urls https://arduino.esp8266.com/stable/package_esp8266com_index.json
arduino-cli core install esp8266:esp8266 --additional-urls https://arduino.esp8266.com/stable/package_esp8266com_index.json
arduino-cli core update-index --additional-urls https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
arduino-cli core install esp32:esp32 --additional-urls https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
arduino-cli core update-index --additional-urls https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json
arduino-cli core install seeeduino:samd --additional-urls https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json
arduino-cli core update-index --additional-urls https://sandeepmistry.github.io/arduino-nRF5/package_nRF5_boards_index.json
arduino-cli core install sandeepmistry:nRF5 --additional-urls https://sandeepmistry.github.io/arduino-nRF5/package_nRF5_boards_index.json
arduino-cli board listall # You will see FQBN. What kind of board we can program now?
mkdir /tmp/blink
cd /tmp/blink
cat << EOF > blink.ino
int count = 0;
void setup() { pinMode(LED_BUILTIN, OUTPUT); Serial.begin(9600);}
void loop() {
count++; Serial.println(count);
digitalWrite(LED_BUILTIN, HIGH); delay(1000);
digitalWrite(LED_BUILTIN, LOW); delay(1000);
}
EOF
arduino-cli compile . --fqbn arduino:avr:nano # Compile the blink test
sudo usermod -aG dialout $USER # Give /dev/ttyUSB0 access permission to arduino-cli
newgrp dialout
arduino-cli upload . --fqbn arduino:avr:nano -p /dev/ttyUSB0
```
* Install library
```
arduino-cli lib search SHT4x
arduino-cli lib install "Adafruit SHT4x Library"
```
* More
```
cat << EOF >> ~/.bashrc
export PATH=\$PATH:~/bin
alias xiao='arduino-cli compile . --fqbn Seeeduino:samd:seeed_XIAO_m0 && arduino-cli upload . --fqbn Seeeduino:samd:seeed_XIAO_m0 -p'
alias d1_mini='arduino-cli compile . --fqbn esp8266:esp8266:d1_mini && arduino-cli upload . --fqbn esp8266:esp8266:d1_mini -p'
alias bbc='arduino-cli compile . --fqbn sandeepmistry:nRF5:BBCmicrobit && arduino-cli upload . --fqbn sandeepmistry:nRF5:BBCmicrobit -p'
EOF
```

View File

@@ -0,0 +1,26 @@
* Enable WSL in PowerShell
```
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
```
* Virtual Com Port in WSL (COM34 -> /dev/ttyS34)
* Binary data can be written to the ESPs flash chip via the serial <i><b>write_flash</b></i> command:
* Multiple flash addresses and file names can be given on the same command line:
```
idf.py -p (PORT) flash
```
Or:
```
esptool.py
-p (PORT)
-b 460800
--before default_reset
--after hard_reset
--chip esp32
write_flash
--flash_mode dio
--flash_size detect
--flash_freq 40m
0x1000 build/bootloader/bootloader.bin
0x8000 build/partition_table/partition-table.bin
0x10000 build/blink.bin
```

View File

@@ -1,61 +1,15 @@
### Pin convention
* For ESP8266, Digital Pin 4 (D4) is GPIO2
* In Arduino IDE, pin is specified by on-board printed name like A0, A2, D1, or D3. Meanwhile, GPIO number is recommended for MicroPython (ESP8266) or Python (Raspberry Pi).
* Following C code will light up built-in LED on ESP8266 dev board
### Pin convention
* For MCU D1 mini, D4 (digital pin 4) is GPIO2.
* In Arduino IDE, pin is specified by on-board printed name like A0 (analog pin 0) and D4. Following C code will light up built-in LED on D1 mini.
```C
void setup() { pinMode(D4, OUTPUT); digitalWrite(D4, 0); }
void loop () {}
```
* Following MicroPython code also light up built-in LED on ESP8266 dev board
```
* Meanwhile, MicroPython (ESP8266) or Python (Raspberry Pi) recommends GPIO number. Following MicroPython code also lights up built-in LED on D1 mini.
```Python
from machine import Pin
Pin( 2, Pin.OUT, value=0)
```
### <a name="Arduino-CLI">Arduino-CLI:</a> Program Arduino board on Raspberry Pi
* Blink
```
wget arduino-cli_0.18.3_Linux_64bit.tar.gz && tar zxvf # https://github.com/arduino/arduino-cli/releases
sudo mv arduino-cli /usr/local/bin/
arduino-cli core install arduino:avr # Install compile platform of Arduino board family
arduino-cli core update-index --additional-urls https://arduino.esp8266.com/stable/package_esp8266com_index.json
arduino-cli core install esp8266:esp8266 --additional-urls https://arduino.esp8266.com/stable/package_esp8266com_index.json
arduino-cli core update-index --additional-urls https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
arduino-cli core install esp32:esp32 --additional-urls https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
arduino-cli core update-index --additional-urls https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json
arduino-cli core install seeeduino:samd --additional-urls https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json
arduino-cli core update-index --additional-urls https://sandeepmistry.github.io/arduino-nRF5/package_nRF5_boards_index.json
arduino-cli core install sandeepmistry:nRF5 --additional-urls https://sandeepmistry.github.io/arduino-nRF5/package_nRF5_boards_index.json
arduino-cli board listall # You will see FQBN. What kind of board we can program now?
mkdir /tmp/blink
cd /tmp/blink
cat << EOF > blink.ino
int count = 0;
void setup() { pinMode(LED_BUILTIN, OUTPUT); Serial.begin(9600);}
void loop() {
count++; Serial.println(count);
digitalWrite(LED_BUILTIN, HIGH); delay(1000);
digitalWrite(LED_BUILTIN, LOW); delay(1000);
}
EOF
arduino-cli compile . --fqbn arduino:avr:nano # Compile the blink test
sudo usermod -aG dialout $USER # Give /dev/ttyUSB0 access permission to arduino-cli
newgrp dialout
arduino-cli upload . --fqbn arduino:avr:nano -p /dev/ttyUSB0
```
* Install library
```
arduino-cli lib search SHT4x
arduino-cli lib install "Adafruit SHT4x Library"
```
* More
```
cat << EOF >> ~/.bashrc
export PATH=\$PATH:~/bin
alias xiao='arduino-cli compile . --fqbn Seeeduino:samd:seeed_XIAO_m0 && arduino-cli upload . --fqbn Seeeduino:samd:seeed_XIAO_m0 -p'
alias d1_mini='arduino-cli compile . --fqbn esp8266:esp8266:d1_mini && arduino-cli upload . --fqbn esp8266:esp8266:d1_mini -p'
alias bbc='arduino-cli compile . --fqbn sandeepmistry:nRF5:BBCmicrobit && arduino-cli upload . --fqbn sandeepmistry:nRF5:BBCmicrobit -p'
EOF
```
### Trouble shooting
* error while loading shared libraries: libfl.so.2
```

View File

@@ -189,7 +189,7 @@ Device Boot Start End Sectors Size Id
mkdir /tmp/raspbian_os_boot
sudo mount -o offset=$((8192*512)),umask=0002,uid=$UID $img /tmp/raspbian_os_boot
```
* Add / Change files
* [Add / Change files](https://www.raspberrypi.com/news/raspberry-pi-bullseye-update-april-2022/)
```
touch /tmp/raspbian_os_boot/ssh # Enable ssh server at first boot
cat << EOF > /tmp/raspbian_os_boot/wpa_supplicant.conf # Join WiFi network
@@ -202,6 +202,9 @@ Device Boot Start End Sectors Size Id
key_mgmt=WPA-PSK
}
EOF
cat << EOF > /tmp/raspbian_os_boot/userconf.txt
pi:$(echo 'raspberry' | openssl passwd -6 -stdin)
EOF
umount /tmp/raspbian_os_boot
```
* Mount system partition (Second partition is EXT4 format)

54
Misc/mqtt.md Normal file
View File

@@ -0,0 +1,54 @@
### Broker
* Mosquitto from Eclipse, written in C
```
sudo apt install -y mosquitto mosquitto-clients
mosquitto -v
sudo tee -a /etc/mosquitto/mosquitto.conf << EOF >/dev/null
listener 1883
allow_anonymous true
EOF
sudo systemctl restart mosquitto.service
```
### Client
* Install
```
sudo apt install -y mosquitto-clients
```
* Subscribe
```
mosquitto_sub -d -t testTopic
```
* Push
```
mosquitto_pub -h 192.168.xxx.xxx -t testTopic -m "Hello world!"
```
### Python
```
pip install paho-mqtt
import paho.mqtt.client as mqtt
client = mqtt.Client()
client.connect("192.168.xxx.xxx", 1883, 60)
client.publish("testTopic", payload="Hello World From Python", qos=0, retain=False)
```
### MicroPython
[MQTT Lib](https://raw.githubusercontent.com/micropython/micropython-lib/master/micropython/umqtt.simple/umqtt/simple.py)
```
import time
from umqtt.simple import MQTTClient
def sub_cb(topic, msg):
print((topic, msg))
c = MQTTClient("client_id", "server_ip")
c.set_callback(sub_cb)
c.connect()
c.subscribe(b"foo_topic")
try:
while 1:
c.wait_msg()
finally:
c.disconnect()
```

119
Project/SHT4x/SHT4x.ino Normal file
View File

@@ -0,0 +1,119 @@
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include "Adafruit_SHT4x.h"
#include "env.h"
/*
cat << EOF > env.h
#define STASSID "wifi_ssid"
#define STAPSK "wifi_passwd"
#define LOG_URL "http://192.168.x.x:x/log"
EOF
*/
const int sensorPin = A0, OLED_SDA = D2, OLED_SCL = D1;
WiFiClient client;
HTTPClient http;
Adafruit_SHT4x sht4 = Adafruit_SHT4x();
void initWIFI() {
WiFi.begin(STASSID, STAPSK);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.print("\nConnected! IP address: ");
Serial.println(WiFi.localIP());
delay(3000);
http.begin(client, LOG_URL); //HTTP
}
void initSHT4x() {
Serial.println("Adafruit SHT4x test");
if (! sht4.begin()) {
Serial.println("Couldn't find SHT4x");
while (1) delay(1);
}
Serial.println("Found SHT4x sensor");
Serial.print("Serial number 0x");
Serial.println(sht4.readSerial(), HEX);
// You can have 3 different precisions, higher precision takes longer
sht4.setPrecision(SHT4X_HIGH_PRECISION);
switch (sht4.getPrecision()) {
case SHT4X_HIGH_PRECISION:
Serial.println("High precision");
break;
case SHT4X_MED_PRECISION:
Serial.println("Med precision");
break;
case SHT4X_LOW_PRECISION:
Serial.println("Low precision");
break;
}
// You can have 6 different heater settings
// higher heat and longer times uses more power
// and reads will take longer too!
sht4.setHeater(SHT4X_NO_HEATER);
switch (sht4.getHeater()) {
case SHT4X_NO_HEATER:
Serial.println("No heater");
break;
case SHT4X_HIGH_HEATER_1S:
Serial.println("High heat for 1 second");
break;
case SHT4X_HIGH_HEATER_100MS:
Serial.println("High heat for 0.1 second");
break;
case SHT4X_MED_HEATER_1S:
Serial.println("Medium heat for 1 second");
break;
case SHT4X_MED_HEATER_100MS:
Serial.println("Medium heat for 0.1 second");
break;
case SHT4X_LOW_HEATER_1S:
Serial.println("Low heat for 1 second");
break;
case SHT4X_LOW_HEATER_100MS:
Serial.println("Low heat for 0.1 second");
break;
}
}
void setup() {
Serial.begin(115200);
while (!Serial)
delay(10); // will pause Zero, Leonardo, etc until serial console opens
Serial.print("\n\n\n");
pinMode(sensorPin, INPUT);
initWIFI();
initSHT4x();
}
float T, H; int P;
void loop() {
// wait for WiFi connection
if ((WiFi.status() == WL_CONNECTED)) {
sensors_event_t humidity, temp;
sht4.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
T = temp.temperature;
H = humidity.relative_humidity;
P = analogRead(sensorPin);
char json[96];
sprintf(json,"{\"Temperature (C)\":%f,\"Humidity (%% rH)\":%f,\"Photoresistor\":%d}", T, H, P);
Serial.println("[HTTP] POSTing "+String(json));
http.addHeader("Content-Type", "application/json");
int httpCode = http.POST(json);
if (httpCode == HTTP_CODE_OK) {
// const String& payload = http.getString();
Serial.print("[HTTP] Payload received~\n\n");
} else {
Serial.printf("[HTTP] Problematic returncode: %s\n\n", http.errorToString(httpCode).c_str());
}
}
delay(3000);
}
// http.end();

71
Project/SHT4x/plot.ipynb Normal file

File diff suppressed because one or more lines are too long

408
Project/SHT4x/server.ipynb Normal file
View File

@@ -0,0 +1,408 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "7ab5ee43",
"metadata": {
"ExecuteTime": {
"end_time": "2022-08-31T07:49:25.947790Z",
"start_time": "2022-08-31T07:49:25.929995Z"
}
},
"outputs": [],
"source": [
"#pip install python-kasa flask requests picamera"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "72ac21ad",
"metadata": {
"ExecuteTime": {
"end_time": "2022-08-31T07:49:27.011462Z",
"start_time": "2022-08-31T07:49:25.963467Z"
}
},
"outputs": [],
"source": [
"import sqlite3, datetime, time, queue, threading, sys, os, asyncio, kasa, pathlib, json, dateutil, requests, flask, logging # dhcp-lease-list\n",
"\n",
"'''\n",
"with open('secret.json','w') as fw: \n",
" sec = {'bedroom_bulb_ip':\"192.168.x.x\",\n",
" 'bedroom_ac_ip' :\"192.168.x.x\" } \n",
" json.dump(sec, fw)\n",
"'''\n",
"with open('secret.json') as fr: sec = json.load(fr) "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1e2ccf4a",
"metadata": {
"ExecuteTime": {
"end_time": "2022-08-31T07:49:27.075754Z",
"start_time": "2022-08-31T07:49:27.022444Z"
}
},
"outputs": [],
"source": [
"pathlib.Path('log').mkdir(parents=True, exist_ok=True)\n",
"new_db = f'log/SHT40.{datetime.datetime.fromtimestamp(time.time()).strftime(\"%Y-%m-%dT%H:%M:%S\")}.db' \n",
"\n",
"def database(): \n",
" con = sqlite3.connect(new_db) \n",
" cur = con.cursor() \n",
" cur.execute('CREATE TABLE IF NOT EXISTS log (Temperature REAL, Humidity REAL, Photoresistor INTEGER, timestamp REAL);')\n",
" cur = con.cursor() \n",
" while True: \n",
" opt, foo = q_in.get() # q.get() = opt_foo\n",
" bar = False # opt is a placeholder \n",
" try:\n",
" if opt == 'insert':\n",
" cur.execute('INSERT INTO log VALUES (?, ?, ?, ?);', \n",
" (foo['Temperature (C)'], foo['Humidity (% rH)'], foo['Photoresistor'], time.time(),)) \n",
" elif opt == 'sql':\n",
" cur.execute(foo['sql']) \n",
" bar = cur.fetchall()\n",
" elif opt == 'commit': \n",
" con.commit() \n",
" bar = 'Database commited'\n",
" print('Database commited')\n",
" elif opt == 'close': \n",
" con.commit()\n",
" con.close()\n",
" bar = 'Database commited and closed'\n",
" print('Database commited and closed')\n",
" except Exception as e:\n",
" print('sql_exception', e, opt, foo)\n",
" pass\n",
" q_out.put(bar) \n",
" q_out.join()\n",
" q_in.task_done()\n",
"\n",
"q_in, q_out = queue.Queue(), queue.Queue() \n",
"threading.Thread(target=database, name='thread-1', daemon=True).start() \n",
"\n",
"def database_operator(opt_foo): \n",
" q_in.join() \n",
" q_in.put(opt_foo) \n",
" bar = q_out.get() \n",
" q_out.task_done() \n",
" return bar"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e4f22b09",
"metadata": {
"ExecuteTime": {
"end_time": "2022-08-31T07:49:30.202015Z",
"start_time": "2022-08-31T07:49:27.088256Z"
}
},
"outputs": [],
"source": [
"UTC = dateutil.tz.gettz('UTC') \n",
"class HUB:\n",
" def __init__(self, temp_ceil = 28.5, lumi_ceil = 650):\n",
" self.kasa_ac = kasa.SmartPlug(sec['bedroom_ac_ip']) \n",
" self.kasa_bulb = kasa.SmartBulb(sec['bedroom_bulb_ip']) \n",
" self.kasa_queue = queue.Queue()\n",
" self.params = { 'temp_ceil':temp_ceil,\n",
" 'lumi_ceil':lumi_ceil, \n",
" 'night_mode':False,\n",
" 'manual_mode':False,\n",
" 'sunrise_dt':None,\n",
" 'sunset_dt' :None, \n",
" 'bulb_timer':False # most of the time, bulb_timer is True. \n",
" # It is false upon update and test begin. \n",
" } \n",
" time.sleep(3)\n",
" threading.Thread(target=self.kasa_thread).start()\n",
" threading.Thread(target=self.update).start() \n",
" \n",
" async def kasa_worker(self):\n",
" while True: \n",
" device_name, method_name = self.kasa_queue.get() \n",
" device = getattr( self, device_name)\n",
" method = getattr(device, method_name)\n",
" await method()\n",
" self.kasa_queue.task_done()\n",
" \n",
" def kasa_thread(self):\n",
" asyncio.run(self.kasa_worker()) \n",
"\n",
" def kasa_director(self, device_name, method_name):\n",
" #kasa_queue.join()\n",
" self.kasa_queue.put((device_name, method_name)) \n",
" \n",
" def update(self):\n",
" lat, lng = (40.7063311, -73.9971931)\n",
" onehour = datetime.timedelta(hours=1) \n",
" while 1:\n",
" print('[Daily Sunrise & Sunset Update]')\n",
" date = datetime.datetime.now().strftime('%Y-%m-%d')\n",
" r = requests.get(f'https://api.sunrise-sunset.org/json?lat={lat}&lng={lng}&date={date}&formatted=0')\n",
" if r.json()['status'] != 'OK': raise\n",
" self.params['sunrise_dt'] = datetime.datetime.fromisoformat(r.json()['results']['sunrise'])\n",
" self.params['sunset_dt'] = datetime.datetime.fromisoformat(r.json()['results']['sunset']) \n",
" while 1: \n",
" if self.params['sunrise_dt'].day != datetime.datetime.now().day: \n",
" print('A New Day Has Come')\n",
" break\n",
" self.kasa_director( 'kasa_ac', 'update')\n",
" self.kasa_director('kasa_bulb', 'update') \n",
" if datetime.datetime.now().astimezone(UTC) < self.params['sunrise_dt'] + onehour or \\\n",
" datetime.datetime.now().astimezone(UTC) > self.params['sunset_dt'] - onehour: # Daylight\n",
" self.params['night_mode'] = True \n",
" else: # At night\n",
" self.params['night_mode'] = False\n",
" time.sleep(60)\n",
" if self.params['bulb_timer']: self.params.update({'bulb_timer':False})\n",
"\n",
"hub = HUB()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b3ff53b8",
"metadata": {
"ExecuteTime": {
"start_time": "2022-08-31T07:49:24.905Z"
}
},
"outputs": [],
"source": [
"index_html_string = ''' <!DOCTYPE html>\n",
"<html>\n",
" <head>\n",
" <meta charset=\"utf-8\">\n",
" <title> hub </title>\n",
" <style>\n",
" .inp {height: 100px; width: 100px} \n",
" \n",
" #slider {\n",
" -webkit-appearance: none;\n",
" width: 100%;\n",
" height: 25px;\n",
" background: #d3d3d3;\n",
" outline: none;\n",
" opacity: 0.7;\n",
" -webkit-transition: .2s;\n",
" transition: opacity .2s;\n",
" }\n",
" \n",
" #slider:hover {\n",
" opacity: 1;\n",
" } \n",
" \n",
" #slider::-webkit-slider-thumb {\n",
" -webkit-appearance: none;\n",
" appearance: none;\n",
" width: 100px;\n",
" height: 100px;\n",
" background: #04AA6D;\n",
" cursor: pointer;\n",
" }\n",
" \n",
" #slider::-moz-range-thumb {\n",
" width: 100px;\n",
" height: 100px;\n",
" background: #04AA6D;\n",
" cursor: pointer;\n",
" } \n",
" \n",
" td {text-align: center; }\n",
" </style>\n",
" </head>\n",
" <body> \n",
" <form method=\"POST\" action=\"/\" enctype=\"multipart/form-data\"> \n",
" <table style=\"width: 500px;\" > \n",
" <tr>\n",
" <td class=\"inp\">Light Mode:</td> \n",
" <td style=\"position: relative;\">\n",
" <input type=\"radio\" name=\"manual_mode\" value=\"1\" {{'checked' if hub.params['manual_mode'] else ''}} class=\"inp\">\n",
" <span style=\"position: absolute;\">Manu</span> \n",
" </td> \n",
" <td style=\"position: relative;\">\n",
" <input type=\"radio\" name=\"manual_mode\" value='0' {{'' if hub.params['manual_mode'] else 'checked'}} class=\"inp\"> \n",
" <span style=\"position: absolute; top: 0px; left: 0px; \">Auto</span> \n",
" </td> \n",
" </tr> \n",
" <tr>\n",
" <td>Max Celsius Degress:</td>\n",
" <td><input type=\"text\" name=\"temp_ceil\" value=\"{{hub.params['temp_ceil']}}\" style=\"font-size: 40px;\" class=\"inp\" id=\"output\"/></td>\n",
" <td><input type=\"submit\" value=\"Submit\" class=\"inp\"></td>\n",
" </tr> \n",
" <tr >\n",
" <td colspan=\"3\"><input type=\"range\" min=\"1\" max=\"100\" value=\"{{ 10*hub.params['temp_ceil']-200}}\" style=\"height:100px; width:100%\" class=\"inp\" id=\"slider\"></td>\n",
" <script>\n",
" var output = document.getElementById(\"output\");\n",
" var slider = document.getElementById(\"slider\"); \n",
" slider.oninput = function() {\n",
" output.setAttribute(\"value\", 20+slider.value/10); \n",
" }\n",
" </script> \n",
" </tr>\n",
" <tr> \n",
" </tr> \n",
" <tr> \n",
" <td> <button type=\"button\" onclick=\"light()\" class=\"inp\">Light</button> </td>\n",
" <td> <button type=\"button\" class=\"inp\">Placeholder</button> </td>\n",
" <td> <button type=\"button\" class=\"inp\">Placeholder</button> </td> \n",
" <script>\n",
" function light() { \n",
" var xmlHttp = new XMLHttpRequest();\n",
" xmlHttp.open( \"GET\", \"/remote?pin=15\", false ); \n",
" xmlHttp.send( null );\n",
" }; \n",
" \n",
" </script> \n",
" </tr> \n",
" <tr >\n",
" <td colspan=\"3\"> <img src=\"{{sec.cam_1_url}}\"></img> </td> \n",
" </tr>\n",
" <tr >\n",
" <td colspan=\"3\"> <img src=\"{{sec.cam_2_url}}\"></img> </td> \n",
" </tr>\n",
" \n",
" <tr >\n",
" <td>EA:DB:84:98:31:F4 </td> <td>MicroPython-9831f4 </td> <td> Controller</td> \n",
" </tr>\n",
" <tr >\n",
" <td>EA:DB:84:9C:54:9E </td> <td>MicroPython-9c549e </td> <td>unknown </td> \n",
" </tr>\n",
" <tr >\n",
" <td>EA:DB:84:9B:90:48 </td> <td>MicroPython-9b9048 </td> <td>HDMI Relay </td> \n",
" </tr>\n",
" \t\t \n",
" \t\t \n",
" \t\t \n",
" \n",
" </table> \n",
" <br/> \n",
" </form> \n",
" </body>\n",
"</html> \n",
"'''\n",
"\n",
"\n",
"log = logging.getLogger('werkzeug') \n",
"log.setLevel(logging.ERROR) \n",
"\n",
"app = flask.Flask(__name__) \n",
"\n",
"@app.route(\"/\", methods=['GET', 'POST'])\n",
"def index(): \n",
" req = flask.request \n",
" if req.method == 'GET':\n",
" return flask.render_template_string(index_html_string, hub=hub, sec=sec) \n",
" elif req.method == 'POST': \n",
" hub.params['temp_ceil'] = float(req.form['temp_ceil']) \n",
" hub.params['manual_mode'] = int(req.form['manual_mode']) \n",
" return flask.redirect(\"/\", code=302)\n",
" \n",
"@app.route(\"/remote\", methods=['GET'])\n",
"def remote(): \n",
" pin = flask.request.args.get('pin', -1) \n",
" if pin == '13' : \n",
" if hub.kasa_ac.is_on: \n",
" hub.kasa_director('kasa_ac', 'turn_off')\n",
" hub.kasa_director('kasa_ac', 'update')\n",
" d = 'A/C Off' \n",
" else: \n",
" hub.kasa_director('kasa_ac', 'turn_on')\n",
" hub.kasa_director('kasa_ac', 'update')\n",
" d = 'A/C On' \n",
" elif pin == '15' : # \n",
" if hub.kasa_bulb.is_on: \n",
" hub.kasa_director('kasa_bulb', 'turn_off')\n",
" hub.kasa_director('kasa_bulb', 'update')\n",
" hub.params['manual_mode'] = True\n",
" d = 'Light Off'\n",
" else: \n",
" hub.kasa_director('kasa_bulb', 'turn_on')\n",
" hub.kasa_director('kasa_bulb', 'update') \n",
" hub.params['manual_mode'] = False\n",
" d = 'Light ON'\n",
" return flask.jsonify({'response':d})\n",
"\n",
"@app.route(\"/log\", methods=['POST'])\n",
"def log():\n",
" T = flask.request.json['Temperature (C)']\n",
" P = flask.request.json['Photoresistor'] \n",
" if T > hub.params['temp_ceil'] and hub.kasa_ac.is_on == False: \n",
" hub.kasa_director('kasa_ac', 'turn_on')\n",
" hub.kasa_director('kasa_ac', 'update') \n",
" elif T < hub.params['temp_ceil'] - 1 and hub.kasa_ac.is_on == True: \n",
" hub.kasa_director('kasa_ac', 'turn_off')\n",
" hub.kasa_director('kasa_ac', 'update') \n",
" \n",
" if hub.params['manual_mode'] or hub.params['bulb_timer']:\n",
" pass \n",
" else:\n",
" hub.params.update({'bulb_timer':True})\n",
" if hub.params['night_mode']: \n",
" if P < hub.params['lumi_ceil']: \n",
" hub.kasa_director('kasa_bulb', 'turn_on')\n",
" hub.kasa_director('kasa_bulb', 'update') \n",
" elif hub.kasa_bulb.is_on: \n",
" hub.kasa_director('kasa_bulb', 'turn_off')\n",
" hub.kasa_director('kasa_bulb', 'update') \n",
" else: \n",
" hub.kasa_director('kasa_bulb', 'turn_off')\n",
" hub.kasa_director('kasa_bulb', 'update') \n",
" print(flask.request.json)\n",
" database_operator(('insert', flask.request.json)) \n",
" return 'OK' \n",
"\n",
"@app.route(\"/sql\", methods=['POST'])\n",
"def sql(): \n",
" return {'result':database_operator(('sql', flask.request.json)).__repr__() }\n",
" \n",
"@app.route(\"/params\", methods=['GET', 'POST'])\n",
"def params(): \n",
" req = flask.request \n",
" if req.method == 'GET':\n",
" return hub.params\n",
" elif req.method == 'POST': # \n",
" hub.params.update(req.json) \n",
" return {'return_code':100}\n",
"\n",
"@app.route('/heartbeat', methods=['GET']) \n",
"def heartbeat():\n",
" database_operator(('commit', None)) \n",
" return 'Cheers!'\n",
" \n",
"app.run('0.0.0.0','8080')"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}