Skip to content
Snippets Groups Projects
Landing.js 7.31 KiB
import React, {useState, useEffect} from 'react';
import useWebSocket, { ReadyState } from 'react-use-websocket';
import './Landing.css';
import MyModal from './Modal';
import WarnModal from './WarnModal';


function Landing() {
    const [plants,setPlants] = useState([]);
    const [modalIsOpen, setModalIsOpen] = useState(false)
    const [maxWaterUsage, setMaxWaterUsage] = useState(0);
    var [dataFromModal, setDataFromModal] = useState({});

    // station: '192.168.4.1'  localWiFi(AP): 172.16.107.184
    const ESP32_IP_ADDRESS = '172.16.107.184';  
    const { sendMessage, lastMessage, readyState } = useWebSocket(`ws://${ESP32_IP_ADDRESS}/ws`);
    // For Data Transmission testing purposes

    const handleClickSendMessage = () => {
        const jsonMsg = JSON.stringify(plants)
        sendMessage(jsonMsg);    
      };

    const connectionStatus = {
        [ReadyState.CONNECTING]: 'Connecting',
        [ReadyState.OPEN]: 'Open',
        [ReadyState.CLOSING]: 'Closing',
        [ReadyState.CLOSED]: 'Closed',
        [ReadyState.UNINSTANTIATED]: 'Uninstantiated',
      }[readyState];


    const loadPlant = (newPlantData) => {
        setPlants(prevPlants => [...prevPlants, newPlantData]);
    };
      

    const openModal = () => {
        setModalIsOpen(true);
    }

    const closeModal = () => {
        setModalIsOpen(false);
    }

    const receiveData = (data) => {
        const newPlantData = {
            name: data['plantName'],
            // maxWaterUsage: data['maxWaterUsage'],
            minMoistureLevel: data['minMoistureLevel'],
            wateringHours: data['wateringHours'],
            wateringDays: data['wateringDays'],
        };

        // Ensure the new plant data is valid before adding
        if (newPlantData.name && newPlantData.minMoistureLevel && newPlantData.wateringHours && newPlantData.wateringDays) {
            loadPlant(newPlantData);
            closeModal();
        } else {
            console.error('Some fields are undefined or empty');
        }
    };

    
    
    
    // Gonna send plants: [{name, maxWaterUsage, minMoistureLevel, wateringHours}] to ESP32
    // hardcoded data on ESP32 for now
    const [dataObjects, setDataObjects] = useState([]);
    useEffect(() => {
        if (lastMessage !== null) {
          try {
            // Parse the message data as JSON and update the state
            const data = JSON.parse(lastMessage.data);
            console.log(data)
            setDataObjects(data);
          } catch (e) {
            console.error("Failed to parse JSON:", e);
          }
        }
      }, [lastMessage]);

    useEffect(() => {
    // Log the updated 'plants' state whenever it changes
    console.log(JSON.stringify(plants));
    console.log(plants)
    }, [plants]);
   

    const [warnModalIsOpen, setWarnModalIsOpen] = useState(false);
    const [warnedPlants, setWarnedPlants] = useState([]);

    useEffect(() => {
        if (lastMessage !== null) {
        try {
            const data = JSON.parse(lastMessage.data);
            console.log(data);
            setDataObjects(data);
            // Check for plants with flags -1 or 1 and set warned plants
            const flaggedPlants = data.plant_data.filter((plant) => plant.flag === -1 || plant.flag === 1);
            if (flaggedPlants.length > 0) {
            setWarnedPlants(flaggedPlants);
            setWarnModalIsOpen(true); // Open the warning modal
            } else {
            setWarnModalIsOpen(false);
            }
        } catch (e) {
            console.error("Failed to parse JSON:", e);
        }
        }
    }, [lastMessage]);


    return (
        <div className='bg'>
            <div className='container'>
                <div className='param-wrap'>
                    <div className='title'>
                        <p>Green Your World</p>
                        <p>One Drop at a Time!</p>

                        <div className='sensor-data-display'>
                            <div>
                                <button onClick={handleClickSendMessage} disabled={readyState !== ReadyState.OPEN}>
                                Send Message to ESP32
                                </button>
                            </div>
                            <div>
                                <p>Max Water Usage: {dataObjects.usage}</p>
                            </div>
                            <div>
                                {lastMessage ? <p>Last message from server: {lastMessage.data}</p> : "Waiting for message"}
                            </div>
                            <div>
                                <span>The WebSocket is currently {connectionStatus}</span>
                            </div>
                        </div>
                        <WarnModal isOpen={warnModalIsOpen} warnedPlants={warnedPlants} closeModal={() => setWarnModalIsOpen(false)} />

                        
                    </div>
                    <div className='split-container'>
                        <div className='options-bg'>
                            <div className='options-container'>
                                <div className='options'>
                                    <button className='add-plant-btn' onClick={ () => {openModal();}}>Add Plant</button>
                                    <p className='options-text'>Min Moisture Level</p>
                                    <p className='options-text'>Watering Hours</p>
                                    <p className='options-text'>Watering Days</p>
                                </div>
                            </div>
                            <div className='plant-container'>
                                {plants.length > 0 ? (plants.map((plant, index) => (
                                    <div className='new-plant' key={index}>
                                        <p className='new-plant-text'>Plant {index}: {plant.name}</p>
                                        <p className='new-plant-text'>{plant.minMoistureLevel}</p>
                                        <p className='new-plant-text'>{plant.wateringHours}</p>
                                        <p className='new-plant-text'>{plant.wateringDays}</p>
                                    </div>
                                ))
                                ) : (<p>No Plants added yet.</p>
                                )}
                            </div>
                            <MyModal isOpen = {modalIsOpen} closeModal={closeModal} sendDataToParent={receiveData} />

                        </div>

                        <div className='health-wrap'>
                            <p className='health-header'>Plant Health</p>
                            <div className='adjust'>
                                <div className='health-container'>
                                    {dataObjects.plant_data.map((item, index) => (
                                        <p key={index} className='health-text'> Address: {item.address} <br /> Health: {item.health} <br/> Moisture: {item.moisture}</p>
                                    ))}
                                </div>
                            </div>
                        </div>
                                        
                    </div>

                    
                </div>
                
            </div>
                
        </div>
    )
}

export default Landing;