Skip to content

Commit

Permalink
v1.2.0.0 - WebSocket Implementation
Browse files Browse the repository at this point in the history
- Firmware:
-- Expanded SmartHome library
-- Added new websocket fucntions to main

- Webapp:
-- Changed ws tester page
-- Added DeviceBox component to tester page
  • Loading branch information
martinvichnal committed Dec 4, 2023
1 parent 3930497 commit d4679e7
Show file tree
Hide file tree
Showing 7 changed files with 553 additions and 174 deletions.
9 changes: 5 additions & 4 deletions smart-home-app/src/app/devices/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ export default function Devices() {

const fetchDevices = async () => {
const newDevices = await getDevice(user.uid)
console.log(newDevices)
setDevices(newDevices)
}

useEffect(() => {
// fetchDevices()
const intervalId = setInterval(fetchDevices, 1000) // Fetch every 5 seconds
fetchDevices()
// const intervalId = setInterval(fetchDevices, 1000) // Fetch every 5 seconds

// Clean up the interval on unmount
return () => clearInterval(intervalId)
// // Clean up the interval on unmount
// return () => clearInterval(intervalId)
}, [])

const handleDeviceChange = (deviceID) => {
Expand Down
182 changes: 182 additions & 0 deletions smart-home-app/src/app/testing/components/DeviceBox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
"use client"

import React, { useState, useEffect } from "react"
import setDeviceData from "@/lib/setDeviceData"
import axios from "axios"

/*
got device prop:
{
"DID": "05b31779-14ee-4233-8c9a-2749e81d3ccb",
"DN": "Thermostat",
"DD": "temperature-n-0-100-34--humidity-n-0-100-61--state-b-0-0-0--",
"UID": "80ff2b60-bf4b-42fe-8de4-d21734a393c8"
}
properties:
[
"temperature-n-0-100-34",
"humidity-n-0-100-61",
"state-b-0-0-0",
""
]
*/

function parseDeviceDataString(deviceDataString) {
const properties = deviceDataString
.split("--")
.filter((property) => property)

let deviceData = {}
properties.forEach((property) => {
const [name, type, min, max, value] = property.split("-")
let v
if (type === "b") {
if (value === "0" || value.toLowerCase() === "false") {
v = false
} else if (value === "1" || value.toLowerCase() === "true") {
v = true
}
} else if (type === "n") {
v = Number(value)
}

deviceData[name] = {
type,
min: Number(min),
max: Number(max),
value: v,
}
})
return deviceData
}

function stringifyDeviceData(deviceData) {
let properties = []
Object.keys(deviceData).forEach((name) => {
let { type, min, max, value } = deviceData[name]
let propertyString = [name, type, min, max, value].join("-")
properties.push(propertyString)
})
return properties.join("--")
}

export default function DeviceBox({ device, onDeviceChange }) {
const [values, setValues] = useState(parseDeviceDataString(device.DD))

useEffect(() => {
const initialValues = parseDeviceDataString(device.DD)
setValues(initialValues)
console.log("Initial Values:", initialValues)
}, [device.dd])

useEffect(() => {
const updateDeviceData = async () => {
const deviceDataString = stringifyDeviceData(values)
try {
const response = await axios.put(
`${process.env.API_SERVER_NAME}/api/devices/deviceDID`,
{
did: device.did,
dd: deviceDataString + "--",
}
)
console.log("Data fetched... ", response)
// Notify the parent component that the device data has been updated
if (onDeviceChange) {
onDeviceChange(device.did)
}
} catch (error) {
console.log("ERROR - ", error)
setValues(parseDeviceDataString(device.dd))
alert("Failed to update device data")
}
}

updateDeviceData()
}, [values])

// Updating the values object
const handleInputChange = (variableName, variableNewValue) => {
setValues((prevValues) => ({
...prevValues,
[variableName]: {
...prevValues[variableName],
value: variableNewValue,
},
}))
}

// Rendering out the corresponding component based on the variable type
const renderComponents = (name, type, min, max, value) => {
switch (type) {
case "n":
return (
<div key={name} className="mb-4">
<label className="text-sm font-medium">{name}</label>
<input
type="number"
name={name}
value={values[name].value || ""}
min={min}
max={max}
disabled={name === "battery"}
onChange={(e) =>
handleInputChange(name, e.target.value)
}
className="border p-2 rounded-md w-full"
/>
</div>
)
case "b":
return (
<div key={name} className="mb-4">
<h1 className="text-sm font-medium">
{values[name].value}
</h1>
<label className="text-sm font-medium m-4">
{name}
</label>
{values[name].value ? (
<button
className="text-white bg-green-700 hover:bg-green-800 focus:ring-4 focus:ring-green-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-green-600 dark:hover:bg-green-700 focus:outline-none dark:focus:ring-green-800"
onClick={() =>
handleInputChange(name, !values[name].value)
}
>
{name}
</button>
) : (
<button
className="text-white bg-red-700 hover:bg-red-800 focus:ring-4 focus:ring-red-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-red-600 dark:hover:bg-red-700 focus:outline-none dark:focus:ring-red-800"
onClick={() =>
handleInputChange(name, !values[name].value)
}
>
{name}
</button>
)}
</div>
)
default:
return null
}
}

return (
<div className="m-6 p-6 bg-white border border-gray-200 rounded-lg shadow-lg">
<h2 className="pb-8 text-2xl font-bold tracking-tight text-gray-900">
{device.DN}
</h2>
<div className="grid grid-cols-2 gap-8 justify-start">
{device.DD.split("--").map((item) => {
if (item) {
const [name, type, min, max, value] = item.split("-")
return renderComponents(name, type, min, max, value)
}
return null
})}
</div>
</div>
)
}
44 changes: 22 additions & 22 deletions smart-home-app/src/app/testing/page.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
"use client"
import { useEffect, useState } from "react"

import { io } from "socket.io-client"
import DeviceBox from "@/app/devices/components/DeviceBox"
import { Suspense, useEffect, useState } from "react"

export default function Testing() {
const [socket, setSocket] = useState(null)
const [devices, setDevices] = useState([])

useEffect(() => {
const socketIO = io("ws://158.220.110.116:5000")
Expand All @@ -16,38 +19,35 @@ export default function Testing() {
console.log("disconnected")
})
socketIO.on("webMessage", (message) => {
console.log("A message appeared on deviceMessage: " + message)
setDevices(message)
console.log(message)
})
socketIO.on("deviceMessage", (message) => {
console.log("A message appeared on deviceMessage: " + message)
})
}, [])

const sendMessage = (messageType, message) => {
if (socket) {
socket.emit(messageType, message)
}
}
const handleDeviceChange = (deviceID) => {
if (socket) {
console.log("sending ")
// socket.emit("webMessage", deviceID)
}
}

return (
<div>
<div>
<button
id="sendWebMessage"
onClick={() => sendMessage("webMessage", "web data")}
>
Send Web Message
</button>
</div>
<br />
<div>
<button
id="sendDeviceMessage"
onClick={() => sendMessage("deviceMessage", "device data")}
>
Send Device Message
</button>
<div className="" id="devices">
<div className="flex flex-wrap lg:justify-evenly md:justify-evenly sm:justify-center">
<Suspense fallback={<div>Loading...</div>}>
{devices.map((device) => (
<DeviceBox
device={device}
key={device.DID}
onDeviceChange={handleDeviceChange}
/>
))}
</Suspense>
</div>
</div>
)
Expand Down
41 changes: 40 additions & 1 deletion smart-home-firmware/.vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,45 @@
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"algorithm": "cpp"
"algorithm": "cpp",
"atomic": "cpp",
"*.tcc": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"exception": "cpp",
"functional": "cpp",
"iterator": "cpp",
"map": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"fstream": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"new": "cpp",
"ostream": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"cinttypes": "cpp",
"typeinfo": "cpp"
}
}
Loading

0 comments on commit d4679e7

Please sign in to comment.