security-system / pages / index.js
index.js
Raw
import {useState, useRef, useEffect} from 'react'
import useMqtt from '../lib/useMqtt'
import 'bootstrap/dist/css/bootstrap.min.css';
import {Accordion, Button, Card, Col, Row} from "react-bootstrap";

export default function Home() {
    const [currentDevices, setCurrentDevices] = useState([])

    const addDevice = (message) => {
        console.log("adding " + message.payload.type)
        setCurrentDevices((currentDevices) => {
            const device = message.payload
            device.topic = message.topic
            let newDevices = []
            let found = false;
            for(let i = 0; i < currentDevices.length; i++) {
                let oldDevice = currentDevices[i]
                if(oldDevice) {
                    if(device.id === oldDevice.id) {
                        oldDevice.time = device.time
                        oldDevice.live = device.live
                        found = true
                    }
                    newDevices.push(oldDevice)
                }
            }
            if(!found) {
                newDevices.push(device)
            }
            return newDevices
        })
    }


    const removeDevice = (device) => {
        setCurrentDevices((currentDevices) => currentDevices.filter((oldDevice) => {
            return oldDevice.id !== device.id
        }))
    }

    useEffect(() => {
        const interval = setInterval(() => {
            let devicesToRemove = currentDevices.filter((oldDevice) => {
                return (Date.now() / 1000) - oldDevice.time > 60
            })
            devicesToRemove.forEach((device) => {
                console.log("removing " + device.type)
                removeDevice(device)
            })
        }, 10000)
        return () => clearInterval(interval);
    }, [currentDevices]);



    const incomingMessageHandlers = useRef([
        {
        topic: "login",
        handler: (msg) => {
            addDevice(msg)
        }
    }])

    const mqttClientRef = useRef(null)
    const setMqttClient = (client) => {
        mqttClientRef.current = client
        client.publish("admin", "online")
    }

    useMqtt({
        uri: process.env.NEXT_PUBLIC_MQTT_URI,
        options: {
            username: process.env.NEXT_PUBLIC_MQTT_USERNAME,
            password: process.env.NEXT_PUBLIC_MQTT_PASSWORD,
            clientId: process.env.NEXT_PUBLIC_MQTT_CLIENTID,
        },
        topicHandlers: incomingMessageHandlers.current,
        onConnectedHandler: (client) => setMqttClient(client),
    })


    const publishMessage = (client, topic, message) => {
        console.log("publishing")
        if (!client) {
            console.log('(publishMessages) Cannot publish, mqttClient: ', client)
            return
        }
        client.publish(topic, message)
    }

    let currentlyActive = currentDevices.filter((i) => i.live).map((i) => String(i.ip + i.port))
    return (
        <div className={"main"}>
            <div className={"title"}>
                <h2>SUPER SAFE "SECURITY" SYSTEM</h2>
            </div>

            <h3>Transmitters:</h3>
            <Row>
                {currentDevices.map((i) => i.type === "transmitter" && (
                    <Col key={i.ip + i.port} style={{margin: "2vh"}}>
                        <Card className={"transmitterCard"} style={{display: "inline-block", margin: "auto" }}>
                            <Card.Body>
                                <Card.Title>
                                    <h4>{i.id + " - " + (i.live ? "LIVE" : "INACTIVE")}</h4>
                                </Card.Title>
                                {i.live && (
                                    <iframe height={480} width={640} src={"http://pi:raspberry@" + i.ip.toString() + ":" + i.port.toString() + "/stream_simple.html"} />
                                )}
                                <h5>Type: {i.subtype}</h5>
                                <h5>Location: {i.location}</h5>
                                <h5>Address: {i.ip + ":" + i.port}</h5>
                                {!i.live && (
                                    <div>
                                        <Button onClick={() => {
                                            console.log("clicked")
                                            publishMessage(mqttClientRef.current, "home/" + i.location + "/" + i.type, "activate")
                                        }}>
                                            Activate
                                        </Button>
                                    </div>

                                )}
                            </Card.Body>
                        </Card>
                    </Col>
                ))}
            </Row>
            <h3>Sensors:</h3>
            <Row>
                {currentDevices.map((i) => i.type === "sensor" && (
                    <Col key={i.id}>
                        <Card style={{display: "inline-block", margin: "auto", padding: "1vh" }}>
                            <Card.Title>
                                {i.id + " - " + (i.live ? "ACTIVE" : "INACTIVE")}
                            </Card.Title>
                            <h5>Type: {i.type}</h5>
                            <h5>Location: {i.location}</h5>
                            <h5>Activates: {i.targets.join(", ")}</h5>

                        </Card>

                    </Col>
                ))}
            </Row>
        </div>
    )
}