commit fca6aa31de7342d4b7ffba93f86dbef2815821d1 Author: LittleLishu Date: Fri Apr 18 18:00:52 2025 +0800 init diff --git a/__pycache__/globallight.cpython-313.pyc b/__pycache__/globallight.cpython-313.pyc new file mode 100644 index 0000000..592ce5b Binary files /dev/null and b/__pycache__/globallight.cpython-313.pyc differ diff --git a/__pycache__/globallight.cpython-38.pyc b/__pycache__/globallight.cpython-38.pyc new file mode 100644 index 0000000..08630c9 Binary files /dev/null and b/__pycache__/globallight.cpython-38.pyc differ diff --git a/cloud.py b/cloud.py new file mode 100644 index 0000000..3895f91 --- /dev/null +++ b/cloud.py @@ -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 = 'Cloud Server

Global Lights

' + for result in results: + + html += '' + + 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) diff --git a/cloud.yml b/cloud.yml new file mode 100644 index 0000000..916f200 --- /dev/null +++ b/cloud.yml @@ -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" \ No newline at end of file diff --git a/createdb.ipynb b/createdb.ipynb new file mode 100644 index 0000000..c62e96a --- /dev/null +++ b/createdb.ipynb @@ -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 +} diff --git a/globallight.py b/globallight.py new file mode 100644 index 0000000..c752a6f --- /dev/null +++ b/globallight.py @@ -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' diff --git a/ihub.py b/ihub.py new file mode 100644 index 0000000..b8529bd --- /dev/null +++ b/ihub.py @@ -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() diff --git a/light.db b/light.db new file mode 100644 index 0000000..aeb5bf2 Binary files /dev/null and b/light.db differ diff --git a/lightcluster.joblib b/lightcluster.joblib new file mode 100644 index 0000000..a0e9cc5 Binary files /dev/null and b/lightcluster.joblib differ diff --git a/lightcluster.py b/lightcluster.py new file mode 100644 index 0000000..b5113e1 --- /dev/null +++ b/lightcluster.py @@ -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() diff --git a/rcontroller.js b/rcontroller.js new file mode 100644 index 0000000..72df0cc --- /dev/null +++ b/rcontroller.js @@ -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 + } + } +}) diff --git a/rnode.js b/rnode.js new file mode 100644 index 0000000..d06a8a5 --- /dev/null +++ b/rnode.js @@ -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 + ) +}) diff --git a/smartcontrol.py b/smartcontrol.py new file mode 100644 index 0000000..be3e46b --- /dev/null +++ b/smartcontrol.py @@ -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() \ No newline at end of file diff --git a/sqlite.txt b/sqlite.txt new file mode 100644 index 0000000..13f4035 --- /dev/null +++ b/sqlite.txt @@ -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;
IDDevice NameLightTimestamp
' + str(result[0]) + '' + str(result[1]) + '' + str(result[2]) + '' + str(result[3]) + '