From 7db5c2501c80a5ed9b146093e69e09585d55a6c3 Mon Sep 17 00:00:00 2001 From: mseng10 Date: Mon, 17 Feb 2025 13:33:56 -0600 Subject: [PATCH 1/6] WIP --- client/Dockerfile | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/client/Dockerfile b/client/Dockerfile index 8a0e726..18b0bd0 100644 --- a/client/Dockerfile +++ b/client/Dockerfile @@ -1,13 +1,25 @@ -FROM node:14 +# Build stage +FROM node:14 as build WORKDIR /app COPY package*.json ./ - RUN npm install COPY . . +ARG NODE_ENV +ENV NODE_ENV=$NODE_ENV + +RUN if [ "$NODE_ENV" = "production" ]; then npm run build; fi + +# Development or Production stage +FROM node:14 + +WORKDIR /app + +COPY --from=build /app . + EXPOSE 3000 CMD ["npm", "start"] \ No newline at end of file From b01b4c825a5b7bbe6a7d3dd94f39edacbd8a598b Mon Sep 17 00:00:00 2001 From: mseng10 Date: Mon, 17 Feb 2025 14:04:59 -0600 Subject: [PATCH 2/6] Display system lights to end user --- client/src/pages/system/Systems.js | 24 +++++++++++++++++++++--- server/app/routes/system_routes.py | 25 +++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/client/src/pages/system/Systems.js b/client/src/pages/system/Systems.js index 39bb9c5..0930770 100644 --- a/client/src/pages/system/Systems.js +++ b/client/src/pages/system/Systems.js @@ -8,6 +8,10 @@ import InvertColorsSharpIcon from '@mui/icons-material/InvertColorsSharp'; import TungstenSharpIcon from '@mui/icons-material/TungstenSharp'; import Card from '@mui/material/Card'; import CardContent from '@mui/material/CardContent'; +import List from '@mui/material/List'; +import ListItem from '@mui/material/ListItem'; +import ListItemText from '@mui/material/ListItemText'; +import Divider from '@mui/material/Divider'; import { CardActionArea, CardHeader } from '@mui/material'; import Avatar from '@mui/material/Avatar'; import GrassOutlinedIcon from '@mui/icons-material/GrassOutlined'; @@ -17,14 +21,14 @@ import CardActions from '@mui/material/CardActions'; import PointOfSaleIcon from '@mui/icons-material/PointOfSale'; import SystemPlants from '../../modals/system/SystemPlants'; import SystemAlerts from '../../modals/system/SystemAlerts'; -import { useSystems } from '../../hooks/useSystems'; +import { useSystems, useLights } from '../../hooks/useSystems'; import { CARD_STYLE, AVATAR_STYLE, CIRCULAR_PROGRESS_STYLE, ICON_STYLE } from '../../constants'; import { EditSharp } from '@mui/icons-material'; import { useNavigate } from 'react-router-dom'; import DeleteOutlineSharpIcon from '@mui/icons-material/DeleteOutlineSharp'; import { NoData, ServerError, Loading } from '../../elements/Page'; -const SystemCard = ({ system, deprecateSystem }) => { +const SystemCard = ({ system, lights, deprecateSystem }) => { const navigate = useNavigate(); const [isSystemsPlanetsOpen, setIsSystemsPlanetsOpen] = useState(false); const [isSystemAlertsOpen, setIsSystemsAlertsOpen] = useState(false); @@ -71,6 +75,19 @@ const SystemCard = ({ system, deprecateSystem }) => { /> + + + {lights && lights.map((light) => ( +
+ + + + +
+ ))} +
@@ -109,6 +126,7 @@ const SystemCard = ({ system, deprecateSystem }) => { const Systems = () => { const { systems, isLoading, error, deprecateSystem } = useSystems(); + const {lights } = useLights(); if (isLoading) return ; if (error) return ; @@ -118,7 +136,7 @@ const Systems = () => { {systems.map((system) => ( - + light.system_id === system.id)} deprecateSystem={deprecateSystem}/> ))} diff --git a/server/app/routes/system_routes.py b/server/app/routes/system_routes.py index fb1ef41..d42559e 100644 --- a/server/app/routes/system_routes.py +++ b/server/app/routes/system_routes.py @@ -40,6 +40,31 @@ def get_systems_alerts(id): return jsonify([Schema.ALERT.read(alert) for alert in alerts]) +@APIBuilder.register_custom_route( + system_bp, "/systems//lights/", methods=["GET"] +) +def get_systems_lights(id): + """ + Get system's lights. + """ + logger.info("Received request to get a system's alerts") + + lights = Table.LIGHT.get_many({"system_id": ObjectId(id)}) + + return jsonify([Schema.LIGHT.read(light) for light in lights]) + +# @APIBuilder.register_custom_route( +# system_bp, "/systems//lights//", methods=["POST"] +# ) +# def resync_light(id, light_id): +# """ +# Get system's lights. +# """ +# logger.info("Received request to get a system's alerts") + +# light = Table.LIGHT.get_one(light_id) + +# return jsonify([Schema.LIGHT.read(light) for light in lights]) # @APIBuilder.register_custom_route(system_bp, "/systems//video_feed/", ["GET"]) # def get_video_feed(system_id): From d9986451f7f629ba666f311d1c5935240d57a18a Mon Sep 17 00:00:00 2001 From: mseng10 Date: Mon, 17 Feb 2025 15:15:06 -0600 Subject: [PATCH 3/6] Initial docker fixes, still need to address import issue --- docker-compose.yml | 10 +++++----- server/app/Dockerfile | 23 ++++++++++------------- server/app/__init__.py | 0 server/app/entrypoint.sh | 33 ++++++++++++++++++++++++++------- 4 files changed, 41 insertions(+), 25 deletions(-) delete mode 100644 server/app/__init__.py diff --git a/docker-compose.yml b/docker-compose.yml index c50919f..fad3add 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,7 +8,7 @@ services: - "8002:5000" environment: - MONGODB_URL=mongodb://mongo1:27017 - - MONGODB_URL_HIST=mongodb://mongo1:27018 + - MONGODB_URL_HIST=mongodb://mongo2:27018 - USE_LOCAL_HARDWARE=true - ENVIRONMENT=docker volumes: @@ -30,7 +30,7 @@ services: - "8003:5000" environment: - ENVIRONMENT=docker - - MONGODB_URL=mongodb://mongo2:27017/plnts + - MONGODB_URL=mongodb://mongo1:27017/plnts volumes: - ./server/shared:/app/shared - ./server/adaptor:/app/adaptor @@ -56,7 +56,7 @@ services: volumes: - mongo_data_2:/data/db ports: - - "27018:27017" + - "27018:27018" healthcheck: test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"] interval: 5s @@ -69,8 +69,8 @@ services: build: context: ./client dockerfile: Dockerfile - args: - - NODE_ENV=${NODE_ENV:-development} + args: + NODE_ENV: ${NODE_ENV:-development} ports: - "3000:3000" environment: diff --git a/server/app/Dockerfile b/server/app/Dockerfile index dc14f6b..a5e810f 100755 --- a/server/app/Dockerfile +++ b/server/app/Dockerfile @@ -1,24 +1,21 @@ FROM python:3.9 -WORKDIR /app +# Install MongoDB client tools +RUN apt-get update && apt-get install -y gnupg curl +RUN curl -fsSL https://pgp.mongodb.com/server-6.0.asc | \ + gpg -o /usr/share/keyrings/mongodb-server-6.0.gpg \ + --dearmor +RUN echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-6.0.gpg] http://repo.mongodb.org/apt/debian bullseye/mongodb-org/6.0 main" | \ + tee /etc/apt/sources.list.d/mongodb-org-6.0.list +RUN apt-get update && apt-get install -y mongodb-mongosh + +WORKDIR /app COPY ../requirements.txt . RUN pip install -r requirements.txt - -# Remove PostgreSQL client and install MongoDB tools instead -RUN apt-get update && apt-get install -y \ - wget gnupg \ - && wget -qO - https://www.mongodb.org/static/pgp/server-7.0.asc | apt-key add - \ - && echo "deb http://repo.mongodb.org/apt/debian bullseye/mongodb-org/7.0 main" | tee /etc/apt/sources.list.d/mongodb-org-7.0.list \ - && apt-get update \ - && apt-get install -y mongodb-mongosh mongodb-database-tools \ - && rm -rf /var/lib/apt/lists/* - COPY . . COPY ../shared . RUN chmod -R 755 /app - COPY app/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh - EXPOSE 5000 ENTRYPOINT ["/entrypoint.sh"] \ No newline at end of file diff --git a/server/app/__init__.py b/server/app/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/server/app/entrypoint.sh b/server/app/entrypoint.sh index de87da1..c77553f 100755 --- a/server/app/entrypoint.sh +++ b/server/app/entrypoint.sh @@ -5,22 +5,41 @@ echo "Debugging information:" cd ../ cd app/ -# Wait for the database to be ready -until PGPASSWORD=$POSTGRES_PASSWORD psql -h "db" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c '\q'; do - >&2 echo "Postgres is unavailable - sleeping" +# Print working directory and structure +echo "==== CURRENT DIRECTORY ====" +pwd +# echo "\n==== DIRECTORY STRUCTURE FROM ROOT ====" +# ls -R / +echo "\n==== DIRECTORY STRUCTURE FROM /server ====" +ls -R /server +echo "\n==== DIRECTORY STRUCTURE FROM /app ====" +ls -R /app +echo "\n==== PYTHON PATH ====" +echo $PYTHONPATH +echo "\n==== ENVIRONMENT VARIABLES ====" +env + +# Wait for MongoDB connections +echo "\n==== CHECKING MONGODB CONNECTIONS ====" +until mongosh --host mongo1 --port 27017 --eval "db.adminCommand('ping')" > /dev/null 2>&1; do + >&2 echo "Main MongoDB (mongo1:27017) is unavailable - sleeping" + sleep 1 +done + +until mongosh --host mongo2 --port 27017 --eval "db.adminCommand('ping')" > /dev/null 2>&1; do + >&2 echo "Historical MongoDB (mongo2:27017) is unavailable - sleeping" sleep 1 done ->&2 echo "Postgres is up - executing command" # Check if the install flag exists if [ ! -f ".installed" ]; then - echo "Running install script..." + echo "\n==== RUNNING INSTALL SCRIPT ====" python install.py touch .installed else - echo "Install script already run, skipping..." + echo "\n==== INSTALL SCRIPT ALREADY RUN ====" fi +echo "\n==== STARTING FLASK APP ====" # Start the Flask application -echo "Starting Flask app..." exec gunicorn -b 0.0.0.0:5000 app.app:app \ No newline at end of file From 3942348f7dfe97c6fa5239a7609dee8f207b0c7d Mon Sep 17 00:00:00 2001 From: mseng10 Date: Mon, 17 Feb 2025 15:21:33 -0600 Subject: [PATCH 4/6] Fix docker git status --- server/app/__init__.py | 0 server/app/entrypoint.sh | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 server/app/__init__.py diff --git a/server/app/__init__.py b/server/app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/server/app/entrypoint.sh b/server/app/entrypoint.sh index c77553f..84a66c6 100755 --- a/server/app/entrypoint.sh +++ b/server/app/entrypoint.sh @@ -42,4 +42,5 @@ fi echo "\n==== STARTING FLASK APP ====" # Start the Flask application -exec gunicorn -b 0.0.0.0:5000 app.app:app \ No newline at end of file +cd app/ # This is here because I had a hilariously bad time starting app +exec gunicorn -b 0.0.0.0:5000 app:app \ No newline at end of file From f31d4993b3531b3f8b470f4df66ae823af8956f8 Mon Sep 17 00:00:00 2001 From: mseng10 Date: Mon, 17 Feb 2025 16:04:00 -0600 Subject: [PATCH 5/6] Fix adaptor (what I can) --- docker-compose.yml | 2 +- server/adaptor/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index fad3add..56ddcd4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -27,7 +27,7 @@ services: context: ./server dockerfile: adaptor/Dockerfile ports: - - "8003:5000" + - "8003:5001" environment: - ENVIRONMENT=docker - MONGODB_URL=mongodb://mongo1:27017/plnts diff --git a/server/adaptor/Dockerfile b/server/adaptor/Dockerfile index 274579e..fa377e0 100755 --- a/server/adaptor/Dockerfile +++ b/server/adaptor/Dockerfile @@ -10,4 +10,4 @@ COPY adaptor ./adaptor ENV PYTHONPATH="/app:${PYTHONPATH}" -CMD ["gunicorn", "--bind", "0.0.0.0:5000", "adaptor.adaptor:app"] \ No newline at end of file +CMD ["gunicorn", "--bind", "0.0.0.0:5001", "adaptor.adaptor:app"] \ No newline at end of file From bb5bad02aab99a8b9fc6fe66884dc88d5a650d99 Mon Sep 17 00:00:00 2001 From: mseng10 Date: Mon, 17 Feb 2025 16:04:19 -0600 Subject: [PATCH 6/6] Black formatting --- model/identify_plants_model.py | 4 ++-- server/app/routes/system_routes.py | 2 ++ server/models/__init__.py | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/model/identify_plants_model.py b/model/identify_plants_model.py index 429868c..83f43d1 100644 --- a/model/identify_plants_model.py +++ b/model/identify_plants_model.py @@ -3,7 +3,7 @@ from tflite_model_maker.image_classifier import DataLoader # Load input data specific to an on-device ML app. -data = DataLoader.from_folder('data/test') +data = DataLoader.from_folder("data/test") train_data, test_data = data.split(0.9) # Customize the TensorFlow model. @@ -13,4 +13,4 @@ loss, accuracy = model.evaluate(test_data) # Export to Tensorflow Lite model and label file in `export_dir`. -model.export(export_dir='/tmp/') \ No newline at end of file +model.export(export_dir="/tmp/") diff --git a/server/app/routes/system_routes.py b/server/app/routes/system_routes.py index d42559e..7fa848b 100644 --- a/server/app/routes/system_routes.py +++ b/server/app/routes/system_routes.py @@ -40,6 +40,7 @@ def get_systems_alerts(id): return jsonify([Schema.ALERT.read(alert) for alert in alerts]) + @APIBuilder.register_custom_route( system_bp, "/systems//lights/", methods=["GET"] ) @@ -53,6 +54,7 @@ def get_systems_lights(id): return jsonify([Schema.LIGHT.read(light) for light in lights]) + # @APIBuilder.register_custom_route( # system_bp, "/systems//lights//", methods=["POST"] # ) diff --git a/server/models/__init__.py b/server/models/__init__.py index ca647a5..2996e32 100644 --- a/server/models/__init__.py +++ b/server/models/__init__.py @@ -74,7 +74,7 @@ def __init__(self, **kwargs): self.banished_on = kwargs.get("banished_on") self.banished_cause = kwargs.get("banished_cause") - def banish(self, cause: Optional[str]=None): + def banish(self, cause: Optional[str] = None): self.banished = True self.banished_on = datetime.now() self.banished_cause = cause