This repository contains code to push dilution fridge system data (both BlueFors and Oxford Systems) to a Firebase Realtime Database and a Streamlit web application to visualize the data.
- Real-Time Monitoring: Continuously updates Firebase with the latest log data.
- Data Upload: Supports both continuous monitoring (
log_to_db.py) and historical data upload (upload_all_logs.py,upload_single_day_data.py). - Fridge Type Support: Handles both BlueFors and Oxford (Triton) log file formats.
- Streamlit Web App: Provides a user-friendly interface to view the data, with interactive Plotly charts.
- Firebase Integration: Uses Firebase Realtime Database for data storage and retrieval.
- Python 3.7+
- A Google Cloud Platform (GCP) project with Firebase enabled.
- A Firebase Realtime Database instance.
-
Create a GCP Project: If you don't have one, create a project in the Google Cloud Console.
-
Enable Firebase: In your GCP project, navigate to Firebase and enable it.
-
Create a Realtime Database: Within Firebase, create a Realtime Database instance. Note the database URL (e.g.,
https://<your-project-id>.firebaseio.com/). -
Create a Service Account:
- Go to "Project settings" (gear icon) in the Firebase console.
- Select the "Service accounts" tab.
- Click "Generate new private key". This downloads a JSON file (e.g.,
sneezy.json). Keep this file secure! Place it in the project's root directory.
-
Set Firebase Rules: In the Firebase console, go to "Realtime Database" -> "Rules". Replace the existing rules with the following JSON:
{ "rules": { "$pcName": { "$logDate": { ".indexOn": ["timestamp"], "temperature": { "$channel": { ".indexOn": ["timestamp"] } }, "pressure": { "$channel": { ".indexOn": ["timestamp"] } }, "resistance": { "$channel": { ".indexOn": ["timestamp"] } }, "flow_rate": { ".indexOn": ["timestamp"] }, "status": { ".indexOn": ["timestamp"] } } }, ".read": "true", // Replace with appropriate security rules ".write": "true" // Replace with appropriate security rules } }Important: This rule set uses wildcards (
$pcName,$logDate,$channel) to apply to all your fridges and dates. It includes indexes on thetimestampfield for efficient querying. You must replace.read: trueand.write: truewith appropriate security rules for production use. See the "Security" section below. This rule set supports both BlueFors and Oxford data structures. The Oxford-specific write rule (preventing zero values) is no longer needed, as the filtering is now done in the Python code.
-
Clone the repository:
git clone <repository_url> cd <repository_name>
-
Create and activate a virtual environment:
conda create -n fridge_env python=3.9 -y # Or your preferred method conda activate fridge_env -
Install dependencies:
pip install -r requirements.txt
(
requirements.txtshould contain:firebase-admin,pandas,python-dotenv,plotly,streamlit)
-
Create a
.envfile in the project's root directory:DB_URL=https://<YOUR_DATABASE_URL>[.firebaseio.com/](https://www.google.com/search?q=https://.firebaseio.com/) PC_NAME=sneezy # Change to dopey, bashful, or test, as appropriate for each machine. CRED_FILE=sneezy.json # Path to your service account key file. FRIDGE_TYPE=BlueFors # Oxford or BlueFors. Set per-machine. LOGFILE_DIR=logs # Optional. Defaults to "logs". Path to log files.Replace placeholders with your actual values.
PC_NAMEandFRIDGE_TYPEshould be set appropriately for each machine running thelog_to_db.pyscript. -
Ensure your log files are in the directory specified by
LOGFILE_DIR(defaults tologs):- BlueFors: Organized by date (e.g.,
logs/22-07-20/CH1 T 22-07-20.log). - Oxford/Triton:
.vclfiles directly in thelogsdirectory (e.g.,logs/log 240119 141920.vcl).
- BlueFors: Organized by date (e.g.,
For Webapp Deployment:
-
Store Firebase Credentials Securely
Streamlit usessecrets.tomlfor storing private keys. Create asecrets.tomlfile in the.streamlit/directory:.streamlit/secrets.tomlExample:
[firebase] FIREBASE_TYPE = "service_account" FIREBASE_PROJECT_ID = "your-project-id" FIREBASE_PRIVATE_KEY_ID = "your-private-key-id" FIREBASE_PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\nABC123...\n-----END PRIVATE KEY-----" FIREBASE_CLIENT_EMAIL = "your-client-email@your-project.iam.gserviceaccount.com" FIREBASE_CLIENT_ID = "your-client-id" FIREBASE_AUTH_URI = "https://accounts.google.com/o/oauth2/auth" FIREBASE_TOKEN_URI = "https://oauth2.googleapis.com/token" FIREBASE_AUTH_PROVIDER_X509_CERT_URL = "https://www.googleapis.com/oauth2/v1/certs" FIREBASE_CLIENT_X509_CERT_URL = "https://www.googleapis.com/robot/v1/metadata/x509/your-client-email@your-project.iam.gserviceaccount.com" DB_URL = "https://your-database.firebaseio.com/"
Ensure:
- The private key is formatted correctly, preserving
\nfor line breaks. - The
.streamlit/secrets.tomlfile is never committed to Git. Add it to.gitignore:.streamlit/secrets.toml
- The private key is formatted correctly, preserving
This replaces .env files and ensures secure storage for Firebase credentials.
This update ensures better security and seamless integration with Streamlit. Let me know if you need further refinements! 🚀
Purpose: Continuously monitors log files and uploads new data to Firebase in real-time.
Usage:
python log_to_db.pyTo Run as Background Process:
nohup python log_to_db.py &Description:
- Detects the fridge type (BlueFors or Oxford) based on the
FRIDGE_TYPEenvironment variable. - BlueFors: Monitors the
logsdirectory for new date directories and files within those directories. - Oxford: Monitors the
logsdirectory for new.vclfiles. - Uploads the latest data to Firebase, using the appropriate data structure for each fridge type.
- Avoids uploading duplicate data.
- Runs continuously, checking for updates every 60 seconds.
Purpose: Uploads all historical log data from a specified parent directory to Firebase, or uploads data for a single day (BlueFors) or a single file (Oxford). Useful for initial data population or re-uploading specific data.
Usage:
python upload_all_logs.pyDescription:
- Processes all log files (BlueFors or Oxford) within the directory specified by
LOGS_PARENT_DIRECTORYin.env(or the default 'logs'). - For BlueFors, you can select option 2 to upload data for a specific date.
- For Oxford, select option 3 to upload a specific file by entering the filename (including the .vcl).
Purpose: Provides a web-based interface to view the data stored in Firebase.
Usage:
streamlit run app.pyDescription:
- Fridge Selection: Select the fridge you want to view data for.
- Date Selection: Select the date (or log file, for Oxford) you want to view.
- Data Type Selection (BlueFors): Choose the data type (temperature, pressure, resistance, flow rate, status). All channels are plotted on a single interactive chart.
- Data Field Selection (Oxford): Choose which data field to display from the available data.
- Interactive Plots: Uses Plotly for interactive charts.
- Data Table: Displays the raw data in a table format.
- BlueFors:
- Temperature:
CHX T YY-MM-DD.log - Pressure:
CHX P YY-MM-DD.log - Resistance:
CHX R YY-MM-DD.log - Status:
Channels YY-MM-DD.log - Flow Rate:
Flowmeter YY-MM-DD.log
- Temperature:
- Oxford/Triton:
.vclfiles (e.g.,log 240119 141920.vcl). Place these directly in thelogsdirectory.
Implement Firebase Authentication: The provided Firebase rules are placeholders only. You must implement Firebase Authentication to properly secure your database. This involves:
-
Setting up Authentication: Enable authentication methods in your Firebase project (e.g., email/password, Google Sign-In).
-
Modifying Rules: Change the
.readand.writerules to useauth.uidto restrict access based on user authentication. Refer to the Firebase documentation for details on how to write secure rules. For example:".read": "auth != null", ".write": "auth.uid === 'your_admin_uid'" // Or a more complex rule