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