commit
fca6aa31de
14 changed files with 870 additions and 0 deletions
Binary file not shown.
Binary file not shown.
@ -0,0 +1,34 @@ |
|||
import connexion |
|||
import sqlite3 |
|||
|
|||
|
|||
|
|||
app = connexion.FlaskApp(__name__, specification_dir='./') |
|||
app.add_api('cloud.yml') |
|||
|
|||
|
|||
|
|||
@app.route('/') |
|||
def index(): |
|||
|
|||
conn = sqlite3.connect('light.db') |
|||
|
|||
c = conn.cursor() |
|||
c.execute('SELECT id, devicename, light, timestamp FROM light ORDER BY id DESC') |
|||
results = c.fetchall() |
|||
|
|||
html = '<html><head><title>Cloud Server</title><meta http-equiv="refresh" content="5" /></head><body><h1>Global Lights</h1><table cellspacing="1" cellpadding="3" border="1"><tr><th>ID</th><th>Device Name</th><th>Light</th><th>Timestamp</th></tr>' |
|||
for result in results: |
|||
|
|||
html += '<tr><td>' + str(result[0]) + '</td><td>' + str(result[1]) + '</td><td>' + str(result[2]) + '</td><td>' + str(result[3]) + '</td></tr>' |
|||
|
|||
html += '</body></html>' |
|||
|
|||
conn.close() |
|||
|
|||
return html |
|||
|
|||
# If we're running in stand alone mode, run the application |
|||
if __name__ == '__main__': |
|||
# app.run(host='0.0.0.0', port=5000, debug=True) |
|||
app.run(host='0.0.0.0', port=5000) |
|||
@ -0,0 +1,77 @@ |
|||
swagger: "2.0" |
|||
info: |
|||
description: This is the swagger file that goes with our server code |
|||
version: "1.0.0" |
|||
title: Swagger REST Article |
|||
consumes: |
|||
- "application/json" |
|||
produces: |
|||
- "application/json" |
|||
|
|||
basePath: "/api" |
|||
|
|||
# Paths supported by the server application |
|||
paths: |
|||
/globallight: |
|||
get: |
|||
operationId: "globallight.read" |
|||
tags: |
|||
- "Global Light" |
|||
summary: "The light data structure supported by the server application" |
|||
description: "Read the list of light" |
|||
responses: |
|||
200: |
|||
description: "Successful read light list operation" |
|||
schema: |
|||
type: "array" |
|||
items: |
|||
properties: |
|||
id: |
|||
type: "number" |
|||
devicename: |
|||
type: "string" |
|||
light: |
|||
type: "number" |
|||
timestamp: |
|||
type: "string" |
|||
put: |
|||
operationId: "globallight.create" |
|||
tags: |
|||
- Global Light |
|||
summary: Create a light record in the database |
|||
description: Create a new light in the database |
|||
parameters: |
|||
- name: globallight |
|||
in: body |
|||
description: Light record to create |
|||
required: True |
|||
schema: |
|||
type: object |
|||
properties: |
|||
devicename: |
|||
type: "string" |
|||
light: |
|||
type: "number" |
|||
timestamp: |
|||
type: "string" |
|||
responses: |
|||
200: |
|||
description: Successfully created light record in database |
|||
|
|||
/lightcluster: |
|||
get: |
|||
operationId: "globallight.cluster" |
|||
tags: |
|||
- Get cluster label of light |
|||
summary: "Get cluster label of light" |
|||
description: "Get cluster label of light" |
|||
parameters: |
|||
- name: light |
|||
in: query |
|||
description: Light |
|||
required: true |
|||
type: number |
|||
|
|||
responses: |
|||
200: |
|||
description: "Successful prediction" |
|||
@ -0,0 +1,213 @@ |
|||
{ |
|||
"cells": [ |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": 8, |
|||
"metadata": {}, |
|||
"outputs": [ |
|||
{ |
|||
"ename": "OperationalError", |
|||
"evalue": "unable to open database file", |
|||
"output_type": "error", |
|||
"traceback": [ |
|||
"\u001b[31m---------------------------------------------------------------------------\u001b[39m", |
|||
"\u001b[31mOperationalError\u001b[39m Traceback (most recent call last)", |
|||
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[8]\u001b[39m\u001b[32m, line 40\u001b[39m\n\u001b[32m 37\u001b[39m conn.close()\n\u001b[32m 38\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m (\u001b[33m\"\u001b[39m\u001b[33mTable \u001b[39m\u001b[33m'\u001b[39m\u001b[33mlight\u001b[39m\u001b[33m'\u001b[39m\u001b[33m does NOT exist.\u001b[39m\u001b[33m\"\u001b[39m, [])\n\u001b[32m---> \u001b[39m\u001b[32m40\u001b[39m init_message = \u001b[43minit_db\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 41\u001b[39m check_message, schema_info = check_db()\n\u001b[32m 43\u001b[39m init_message, check_message, schema_info\n", |
|||
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[8]\u001b[39m\u001b[32m, line 5\u001b[39m, in \u001b[36minit_db\u001b[39m\u001b[34m()\u001b[39m\n\u001b[32m 4\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34minit_db\u001b[39m():\n\u001b[32m----> \u001b[39m\u001b[32m5\u001b[39m conn = \u001b[43msqlite3\u001b[49m\u001b[43m.\u001b[49m\u001b[43mconnect\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43msrc\u001b[39;49m\u001b[38;5;130;43;01m\\\\\u001b[39;49;00m\u001b[33;43mlight.db\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 6\u001b[39m c = conn.cursor()\n\u001b[32m 8\u001b[39m \u001b[38;5;66;03m# Create the 'light' table if it doesn't already exist\u001b[39;00m\n", |
|||
"\u001b[31mOperationalError\u001b[39m: unable to open database file" |
|||
] |
|||
} |
|||
], |
|||
"source": [ |
|||
"import sqlite3\n", |
|||
"\n", |
|||
"# Initialize the database and table\n", |
|||
"def init_db():\n", |
|||
" conn = sqlite3.connect('src\\\\light.db')\n", |
|||
" c = conn.cursor()\n", |
|||
"\n", |
|||
" # Create the 'light' table if it doesn't already exist\n", |
|||
" c.execute('''\n", |
|||
" CREATE TABLE IF NOT EXISTS light (\n", |
|||
" id INTEGER PRIMARY KEY AUTOINCREMENT,\n", |
|||
" devicename CHARACTER(5) NOT NULL,\n", |
|||
" light INTEGER NOT NULL,\n", |
|||
" timestamp DATETIME NOT NULL,\n", |
|||
" tocloud BOOLEAN DEFAULT 0 NOT NULL\n", |
|||
" )\n", |
|||
" ''')\n", |
|||
"\n", |
|||
" conn.commit()\n", |
|||
" conn.close()\n", |
|||
" return \"Database initialized and table 'light' is ready.\"\n", |
|||
"\n", |
|||
"# Check if the table exists and print the schema\n", |
|||
"def check_db():\n", |
|||
" conn = sqlite3.connect('src\\\\light.db')\n", |
|||
" c = conn.cursor()\n", |
|||
"\n", |
|||
" c.execute(\"SELECT name FROM sqlite_master WHERE type='table' AND name='light';\")\n", |
|||
" table_exists = c.fetchone()\n", |
|||
"\n", |
|||
" if table_exists:\n", |
|||
" c.execute(\"PRAGMA table_info(light);\")\n", |
|||
" columns = c.fetchall()\n", |
|||
" conn.close()\n", |
|||
" return (\"Table 'light' exists.\", columns)\n", |
|||
" else:\n", |
|||
" conn.close()\n", |
|||
" return (\"Table 'light' does NOT exist.\", [])\n", |
|||
"\n", |
|||
"init_message = init_db()\n", |
|||
"check_message, schema_info = check_db()\n", |
|||
"\n", |
|||
"init_message, check_message, schema_info\n" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": 4, |
|||
"metadata": {}, |
|||
"outputs": [ |
|||
{ |
|||
"name": "stderr", |
|||
"output_type": "stream", |
|||
"text": [ |
|||
"<>:3: SyntaxWarning: invalid escape sequence '\\l'\n", |
|||
"<>:3: SyntaxWarning: invalid escape sequence '\\l'\n", |
|||
"C:\\Users\\LittleLishu\\AppData\\Local\\Temp\\ipykernel_22052\\2500929216.py:3: SyntaxWarning: invalid escape sequence '\\l'\n", |
|||
" conn = sqlite3.connect('src\\light.db')\n" |
|||
] |
|||
}, |
|||
{ |
|||
"ename": "OperationalError", |
|||
"evalue": "unable to open database file", |
|||
"output_type": "error", |
|||
"traceback": [ |
|||
"\u001b[31m---------------------------------------------------------------------------\u001b[39m", |
|||
"\u001b[31mOperationalError\u001b[39m Traceback (most recent call last)", |
|||
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[4]\u001b[39m\u001b[32m, line 18\u001b[39m\n\u001b[32m 15\u001b[39m conn.close()\n\u001b[32m 16\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m (\u001b[33m\"\u001b[39m\u001b[33mTable \u001b[39m\u001b[33m'\u001b[39m\u001b[33mlight\u001b[39m\u001b[33m'\u001b[39m\u001b[33m does NOT exist.\u001b[39m\u001b[33m\"\u001b[39m, [])\n\u001b[32m---> \u001b[39m\u001b[32m18\u001b[39m check_message, schema_info = \u001b[43mcheck_db\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 19\u001b[39m check_message, schema_info\n", |
|||
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[4]\u001b[39m\u001b[32m, line 3\u001b[39m, in \u001b[36mcheck_db\u001b[39m\u001b[34m()\u001b[39m\n\u001b[32m 2\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mcheck_db\u001b[39m():\n\u001b[32m----> \u001b[39m\u001b[32m3\u001b[39m conn = \u001b[43msqlite3\u001b[49m\u001b[43m.\u001b[49m\u001b[43mconnect\u001b[49m\u001b[43m(\u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43msrc\u001b[39;49m\u001b[33;43m\\\u001b[39;49m\u001b[33;43mlight.db\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 4\u001b[39m c = conn.cursor()\n\u001b[32m 6\u001b[39m c.execute(\u001b[33m\"\u001b[39m\u001b[33mSELECT name FROM sqlite_master WHERE type=\u001b[39m\u001b[33m'\u001b[39m\u001b[33mtable\u001b[39m\u001b[33m'\u001b[39m\u001b[33m AND name=\u001b[39m\u001b[33m'\u001b[39m\u001b[33mlight\u001b[39m\u001b[33m'\u001b[39m\u001b[33m;\u001b[39m\u001b[33m\"\u001b[39m)\n", |
|||
"\u001b[31mOperationalError\u001b[39m: unable to open database file" |
|||
] |
|||
} |
|||
], |
|||
"source": [ |
|||
"import sqlite3\n", |
|||
"def check_db():\n", |
|||
" conn = sqlite3.connect('src\\light.db')\n", |
|||
" c = conn.cursor()\n", |
|||
"\n", |
|||
" c.execute(\"SELECT name FROM sqlite_master WHERE type='table' AND name='light';\")\n", |
|||
" table_exists = c.fetchone()\n", |
|||
"\n", |
|||
" if table_exists:\n", |
|||
" c.execute(\"PRAGMA table_info(light);\")\n", |
|||
" columns = c.fetchall()\n", |
|||
" conn.close()\n", |
|||
" return (\"Table 'light' exists.\", columns)\n", |
|||
" else:\n", |
|||
" conn.close()\n", |
|||
" return (\"Table 'light' does NOT exist.\", [])\n", |
|||
"\n", |
|||
"check_message, schema_info = check_db()\n", |
|||
"check_message, schema_info" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": 5, |
|||
"metadata": {}, |
|||
"outputs": [ |
|||
{ |
|||
"name": "stdout", |
|||
"output_type": "stream", |
|||
"text": [ |
|||
"Tables in the database:\n", |
|||
"light\n", |
|||
"sqlite_sequence\n", |
|||
"Empty DataFrame\n", |
|||
"Columns: [id, devicename, light, timestamp, tocloud]\n", |
|||
"Index: []\n" |
|||
] |
|||
} |
|||
], |
|||
"source": [ |
|||
"import sqlite3\n", |
|||
"import pandas as pd\n", |
|||
"\n", |
|||
"db_path = r\"D:\\OneDrive - National University of Singapore\\Document\\NUSCourses\\Semester 2\\IS5451 AloT Solutions and Development\\Mock\\src\\lighttest.db\"\n", |
|||
"\n", |
|||
"conn = sqlite3.connect(db_path)\n", |
|||
"\n", |
|||
"cursor = conn.cursor()\n", |
|||
"\n", |
|||
"# 获取所有表名\n", |
|||
"cursor.execute(\"SELECT name FROM sqlite_master WHERE type='table';\")\n", |
|||
"tables = cursor.fetchall()\n", |
|||
"\n", |
|||
"print(\"Tables in the database:\")\n", |
|||
"for table in tables:\n", |
|||
" print(table[0])\n", |
|||
"\n", |
|||
"df = pd.read_sql_query(\"SELECT * FROM light\", conn)\n", |
|||
"\n", |
|||
"print(df)\n", |
|||
"\n", |
|||
"conn.close()\n" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": 14, |
|||
"metadata": {}, |
|||
"outputs": [ |
|||
{ |
|||
"data": { |
|||
"text/plain": [ |
|||
"'d:\\\\OneDrive - National University of Singapore\\\\Document\\\\NUSCourses\\\\Semester 2\\\\IS5451 AloT Solutions and Development\\\\Mock\\\\src'" |
|||
] |
|||
}, |
|||
"execution_count": 14, |
|||
"metadata": {}, |
|||
"output_type": "execute_result" |
|||
} |
|||
], |
|||
"source": [ |
|||
"import os\n", |
|||
"os.getcwd()" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"# 将txt的command写入light.db,在树莓派上运行\n", |
|||
"sqlite3 light.db < sqlite.txt" |
|||
] |
|||
} |
|||
], |
|||
"metadata": { |
|||
"kernelspec": { |
|||
"display_name": "is5451", |
|||
"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.13.2" |
|||
} |
|||
}, |
|||
"nbformat": 4, |
|||
"nbformat_minor": 2 |
|||
} |
|||
@ -0,0 +1,71 @@ |
|||
import sqlite3 |
|||
from flask import make_response, abort |
|||
|
|||
from joblib import dump, load |
|||
|
|||
|
|||
|
|||
def read(): |
|||
|
|||
lights = [] |
|||
|
|||
conn = sqlite3.connect('light.db') |
|||
|
|||
c = conn.cursor() |
|||
c.execute('SELECT id, devicename, light, timestamp FROM light ORDER BY id ASC') |
|||
results = c.fetchall() |
|||
|
|||
for result in results: |
|||
|
|||
lights.append({'id':result[0],'devicename':result[1],'light':result[2],'timestamp':result[3]}) |
|||
|
|||
conn.close() |
|||
|
|||
return lights |
|||
|
|||
|
|||
|
|||
def create(globallight): |
|||
''' |
|||
This function creates a new light record in the database |
|||
based on the passed in light data |
|||
:param globallight: Global light record to create in the database |
|||
:return: 200 on success |
|||
''' |
|||
devicename = globallight.get('devicename', None) |
|||
light = globallight.get('light', None) |
|||
timestamp = globallight.get('timestamp', None) |
|||
|
|||
conn = sqlite3.connect('light.db') |
|||
|
|||
c = conn.cursor() |
|||
sql = "INSERT INTO light (devicename, light, timestamp) VALUES('" + devicename + "', " + str(light) + ", '" + timestamp + "')" |
|||
print(sql) |
|||
c.execute(sql) |
|||
conn.commit() |
|||
conn.close() |
|||
|
|||
return make_response('Global light record successfully created', 200) |
|||
|
|||
|
|||
|
|||
def cluster(light): |
|||
|
|||
try: |
|||
|
|||
# predict new temperature and humidity observation |
|||
kmeans = load('lightcluster.joblib') |
|||
|
|||
# temperature, humidity |
|||
newX = [[light]] |
|||
result = kmeans.predict(newX) |
|||
|
|||
print('Cluster Light: light={}; cluster={}'.format(light, result[0])) |
|||
|
|||
return str(result[0]) |
|||
|
|||
except Exception as error: |
|||
|
|||
print('Error: {}'.format(error.args[0])) |
|||
|
|||
return 'Unknown' |
|||
@ -0,0 +1,233 @@ |
|||
import time |
|||
import random |
|||
|
|||
import serial |
|||
import RPi.GPIO as GPIO |
|||
|
|||
import sqlite3 |
|||
import requests |
|||
import json |
|||
|
|||
import paho.mqtt.client as mqtt |
|||
|
|||
import _thread as thread |
|||
|
|||
|
|||
|
|||
def sendCommand(command): |
|||
|
|||
command = command + '\n' |
|||
ser.write(str.encode(command)) |
|||
|
|||
|
|||
|
|||
def waitResponse(): |
|||
|
|||
response = ser.readline() |
|||
response = response.decode('utf-8').strip() |
|||
|
|||
return response |
|||
|
|||
|
|||
|
|||
def saveData(lights): |
|||
|
|||
conn = sqlite3.connect('light.db') |
|||
c = conn.cursor() |
|||
|
|||
for light in lights: |
|||
|
|||
data = light.split('=') |
|||
|
|||
sql = "INSERT INTO light (devicename, light, timestamp) VALUES('" + data[0] + "', " + data[1] + ", datetime('now', 'localtime'))" |
|||
c.execute(sql) |
|||
|
|||
conn.commit() |
|||
conn.close() |
|||
|
|||
lights.clear() |
|||
|
|||
|
|||
|
|||
def rhub(): |
|||
|
|||
global ser |
|||
ser = serial.Serial(port='/dev/ttyACM0', baudrate=115200, timeout=1) |
|||
print('rhub: Listening on /dev/ttyACM0... Press CTRL+C to exit') |
|||
|
|||
# Handshaking |
|||
sendCommand('handshake') |
|||
|
|||
strMicrobitDevices = '' |
|||
|
|||
while strMicrobitDevices == None or len(strMicrobitDevices) <= 0: |
|||
|
|||
strMicrobitDevices = waitResponse() |
|||
|
|||
print('rhub handshake: ' + strMicrobitDevices) |
|||
|
|||
time.sleep(0.1) |
|||
|
|||
strMicrobitDevices = strMicrobitDevices.split('=') |
|||
|
|||
if len(strMicrobitDevices[1]) > 0: |
|||
|
|||
listMicrobitDevices = strMicrobitDevices[1].split(',') |
|||
|
|||
if len(listMicrobitDevices) > 0: |
|||
|
|||
for mb in listMicrobitDevices: |
|||
|
|||
print('rhub: Connected to micro:bit device {}...'.format(mb)) |
|||
|
|||
while True: |
|||
|
|||
time.sleep(1) |
|||
|
|||
commandToTx = 'sensor=light' |
|||
sendCommand('cmd:' + commandToTx) |
|||
|
|||
if commandToTx.startswith('sensor='): |
|||
|
|||
strSensorValues = '' |
|||
|
|||
while strSensorValues == None or len(strSensorValues) <= 0: |
|||
|
|||
strSensorValues = waitResponse() |
|||
time.sleep(0.1) |
|||
|
|||
listSensorValues = strSensorValues.split(',') |
|||
|
|||
for sensorValue in listSensorValues: |
|||
|
|||
print('rhub: {}'.format(sensorValue)) |
|||
|
|||
saveData(listSensorValues) |
|||
|
|||
|
|||
|
|||
def cloudrelay(): |
|||
|
|||
conn = sqlite3.connect('light.db') |
|||
|
|||
base_uri = 'http://169.254.53.99:5000/' |
|||
globallight_uri = base_uri + 'api/globallight' |
|||
headers = {'content-type': 'application/json'} |
|||
|
|||
|
|||
|
|||
while True: |
|||
|
|||
time.sleep(10) |
|||
|
|||
print('Relaying data to cloud server...') |
|||
|
|||
c = conn.cursor() |
|||
c.execute('SELECT id, devicename, light, timestamp FROM light WHERE tocloud = 0') |
|||
results = c.fetchall() |
|||
c = conn.cursor() |
|||
|
|||
for result in results: |
|||
|
|||
print('Relaying id={}; devicename={}; light={}; timestamp={}'.format(result[0], result[1], result[2], result[3])) |
|||
|
|||
glight = { |
|||
'devicename':result[1], |
|||
'light':result[2], |
|||
'timestamp':result[3] |
|||
} |
|||
req = requests.put(globallight_uri, headers = headers, data = json.dumps(glight)) |
|||
|
|||
c.execute('UPDATE light SET tocloud = 1 WHERE id = ' + str(result[0])) |
|||
|
|||
conn.commit() |
|||
|
|||
|
|||
|
|||
def on_message(client, userdata, msg): |
|||
|
|||
smartlight = str(msg.payload.decode()) |
|||
print('Smartlight command subscribed: ' + smartlight) |
|||
|
|||
if smartlight == 'on': |
|||
|
|||
GPIO.output(redLedPin, True) |
|||
|
|||
else: |
|||
|
|||
GPIO.output(redLedPin, False) |
|||
|
|||
|
|||
|
|||
def smartlight(): |
|||
|
|||
broker = 'broker.emqx.io' |
|||
port = 1883 |
|||
topic = "/is4151-is5451/mockpe/smartlight" |
|||
client_id = f'python-mqtt-{random.randint(0, 10000)}' |
|||
username = 'emqx' |
|||
password = 'public' |
|||
client = mqtt.Client(client_id) |
|||
client.username_pw_set(username, password) |
|||
client.connect(broker, port) |
|||
client.subscribe(topic) |
|||
client.on_message = on_message |
|||
client.loop_forever() |
|||
|
|||
|
|||
|
|||
def init(): |
|||
|
|||
GPIO.setmode(GPIO.BOARD) |
|||
|
|||
global redLedPin |
|||
redLedPin = 11 |
|||
GPIO.setup(redLedPin, GPIO.OUT) |
|||
GPIO.output(redLedPin, False) |
|||
|
|||
|
|||
|
|||
def main(): |
|||
|
|||
init() |
|||
|
|||
thread.start_new_thread(rhub, ()) |
|||
thread.start_new_thread(cloudrelay, ()) |
|||
thread.start_new_thread(smartlight, ()) |
|||
|
|||
print('Program running... Press CTRL+C to exit') |
|||
|
|||
while True: |
|||
|
|||
try: |
|||
|
|||
time.sleep(0.1) |
|||
|
|||
except RuntimeError as error: |
|||
|
|||
print('Error: {}'.format(error.args[0])) |
|||
|
|||
except Exception as error: |
|||
|
|||
print('Error: {}'.format(error.args[0])) |
|||
|
|||
except KeyboardInterrupt: |
|||
|
|||
if ser.is_open: |
|||
|
|||
ser.close() |
|||
|
|||
GPIO.cleanup() |
|||
|
|||
print('Program terminating...') |
|||
|
|||
break |
|||
|
|||
|
|||
print('Program exited...') |
|||
|
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
|
|||
main() |
|||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,71 @@ |
|||
import time |
|||
|
|||
import sqlite3 |
|||
|
|||
import numpy as np |
|||
import pandas as pd |
|||
from sklearn.cluster import KMeans |
|||
|
|||
from joblib import dump, load |
|||
|
|||
|
|||
|
|||
def main(): |
|||
|
|||
print('Starting light cluster training process') |
|||
|
|||
np.random.seed(int(round(time.time()))) |
|||
|
|||
while True: |
|||
|
|||
try: |
|||
|
|||
conn = sqlite3.connect('light.db') |
|||
|
|||
c = conn.cursor() |
|||
c.execute('SELECT id, devicename, light, timestamp FROM light ORDER BY id ASC') |
|||
results = c.fetchall() |
|||
|
|||
df = pd.DataFrame(columns=['id', 'devicename', 'light', 'timestamp']) |
|||
# print(df) |
|||
|
|||
for result in results: |
|||
|
|||
df = pd.concat([df, pd.DataFrame({'id': [result[0]], 'devicename': [str(result[1])], 'light': [result[2]], 'timestamp': [str(result[3])]})], ignore_index=True) |
|||
|
|||
# print(df) |
|||
|
|||
X = df['light'].values.reshape(-1,1) |
|||
|
|||
# print(X) |
|||
|
|||
kmeans = KMeans(n_clusters=2, random_state=0) |
|||
kmeans = kmeans.fit(X) |
|||
result = pd.concat([df['light'], pd.DataFrame({'cluster':kmeans.labels_})], axis=1) |
|||
|
|||
# print(result) |
|||
|
|||
for cluster in result.cluster.unique(): |
|||
print('{:d}\t{:.3f} ({:.3f})'.format(cluster, result[result.cluster==cluster].light.mean(), result[result.cluster==cluster].light.std())) |
|||
|
|||
|
|||
dump(kmeans, 'lightcluster.joblib') |
|||
|
|||
time.sleep(10) |
|||
|
|||
|
|||
except Exception as error: |
|||
|
|||
print('Error: {}'.format(error.args[0])) |
|||
continue |
|||
|
|||
except KeyboardInterrupt: |
|||
|
|||
print('Program terminating...') |
|||
break |
|||
|
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
|
|||
main() |
|||
@ -0,0 +1,80 @@ |
|||
serial.onDataReceived(serial.delimiters(Delimiters.NewLine), function () { |
|||
data = serial.readLine() |
|||
if (data == "handshake") { |
|||
basic.showString("H") |
|||
|
|||
if (state == 0) { |
|||
state = 1 |
|||
radio.sendString("handshake") |
|||
handshakeStartTime = input.runningTime() |
|||
} |
|||
} else if (data.includes('cmd:')) { |
|||
basic.showString("S") |
|||
if (state == 2) { |
|||
if (data.includes('cmd:sensor=')) { |
|||
state = 3 |
|||
commandStartTime = input.runningTime() |
|||
sensorValues = [] |
|||
} |
|||
buffer = data.split(':') |
|||
radio.sendString("" + buffer[1]) |
|||
} |
|||
} |
|||
}) |
|||
radio.onReceivedString(function (receivedString) { |
|||
basic.showString("R") |
|||
if (receivedString.includes('enrol=')) { |
|||
if (state == 1) { |
|||
buffer = receivedString.split('=') |
|||
microbitDevices.push(buffer[1]) |
|||
} |
|||
} else if (receivedString.includes('=')) { |
|||
if (state == 3) { |
|||
sensorValues.push(receivedString) |
|||
} |
|||
} |
|||
}) |
|||
let response = "" |
|||
let microbitDevices: string[] = [] |
|||
let sensorValues: string[] = [] |
|||
let state = 0 |
|||
let commandStartTime = 0 |
|||
let handshakeStartTime = 0 |
|||
let data = "" |
|||
let buffer: string[] = [] |
|||
handshakeStartTime = 0 |
|||
commandStartTime = 0 |
|||
radio.setGroup(8) |
|||
radio.setTransmitSerialNumber(true) |
|||
radio.setTransmitPower(7) |
|||
serial.redirectToUSB() |
|||
basic.showIcon(IconNames.Yes) |
|||
basic.forever(function () { |
|||
if (state == 1) { |
|||
if (input.runningTime() - handshakeStartTime > 3 * 1000) { |
|||
state = 2 |
|||
response = "" |
|||
for (let microbitDevice of microbitDevices) { |
|||
if (response.length > 0) { |
|||
response = "" + response + "," + microbitDevice |
|||
} else { |
|||
response = microbitDevice |
|||
} |
|||
} |
|||
serial.writeLine("enrol=" + response) |
|||
} |
|||
} else if (state == 3) { |
|||
if (input.runningTime() - commandStartTime > 3 * 1000) { |
|||
response = "" |
|||
for (let sensorValue of sensorValues) { |
|||
if (response.length > 0) { |
|||
response = "" + response + "," + sensorValue |
|||
} else { |
|||
response = sensorValue |
|||
} |
|||
} |
|||
serial.writeLine("" + response) |
|||
state = 2 |
|||
} |
|||
} |
|||
}) |
|||
@ -0,0 +1,35 @@ |
|||
radio.onReceivedString(function (receivedString) { |
|||
if (receivedString == "handshake") { |
|||
//basic.showString("H")
|
|||
if (state == 0) { |
|||
state = 1 |
|||
radio.sendString("enrol=" + control.deviceName()) |
|||
} |
|||
} else { |
|||
if (state == 1) { |
|||
buffer = receivedString.split("=") |
|||
commandKey = buffer[0] |
|||
commandValue = buffer[1] |
|||
if (commandKey == "sensor") { |
|||
//basic.showString("S")
|
|||
if (commandValue == "light") { |
|||
radio.sendString("" + control.deviceName() + "=" + pins.analogReadPin(AnalogPin.P0)) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
}) |
|||
let commandValue = "" |
|||
let commandKey = "" |
|||
let buffer: string[] = [] |
|||
let state = 0 |
|||
radio.setGroup(8) |
|||
radio.setTransmitPower(7) |
|||
radio.setTransmitSerialNumber(true) |
|||
basic.showIcon(IconNames.Yes) |
|||
basic.forever(function () { |
|||
led.plotBarGraph( |
|||
pins.analogReadPin(AnalogPin.P0), |
|||
650 |
|||
) |
|||
}) |
|||
@ -0,0 +1,49 @@ |
|||
import sys |
|||
import random |
|||
import time |
|||
|
|||
import requests |
|||
|
|||
import paho.mqtt.client as mqtt |
|||
|
|||
def main(): |
|||
|
|||
n = len(sys.argv) |
|||
|
|||
if n > 1: |
|||
|
|||
arg = sys.argv[1] |
|||
print('Light to cluster: ' + arg) |
|||
|
|||
base_uri = 'http://localhost:5000/' |
|||
lightcluster_uri = base_uri + 'api/lightcluster' |
|||
req = requests.get(lightcluster_uri, params={'light': arg}) |
|||
cluster_label = str(req.text).replace('"', '') |
|||
cluster_label = cluster_label.strip() |
|||
print('Cluster Label: ' + cluster_label) |
|||
|
|||
smartlight = 'off' |
|||
|
|||
if cluster_label == '0': |
|||
|
|||
smartlight = 'on' |
|||
|
|||
broker = 'broker.emqx.io' |
|||
port = 1883 |
|||
topic = "/is4151-is5451/mockpe/smartlight" |
|||
client_id = f'python-mqtt-{random.randint(0, 10000)}' |
|||
username = 'emqx' |
|||
password = 'public' |
|||
# client = mqtt.Client(client_id) |
|||
client = mqtt.Client(client_id=client_id, protocol=mqtt.MQTTv311) |
|||
client.username_pw_set(username, password) |
|||
client.connect(broker, port) |
|||
client.publish(topic, smartlight) |
|||
client.disconnect() |
|||
|
|||
print('Smartlight command published: ' + smartlight) |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
|
|||
main() |
|||
@ -0,0 +1,7 @@ |
|||
sudo apt-get install sqlite3 |
|||
|
|||
sqlite3 light.db |
|||
|
|||
BEGIN; |
|||
CREATE TABLE `light` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `devicename` CHARACTER(5) NOT NULL, `light` INTEGER NOT NULL, `timestamp` DATETIME NOT NULL, `tocloud` BOOLEAN DEFAULT 0 NOT NULL); |
|||
COMMIT; |
|||
Loading…
Reference in new issue