Remote Health Care Monitoring System Based on Arduino Nano33 IOt and Raspberry Pi
by sananh2004 in Circuits > Arduino
1656 Views, 2 Favorites, 0 Comments
Remote Health Care Monitoring System Based on Arduino Nano33 IOt and Raspberry Pi
In today's rapidly evolving world, healthcare has reached a pivotal turning point. The critical need for precise and constant health monitoring is driving innovation like never before. Smart IoT devices are becoming indispensable tools, bridging the gap between patients and healthcare professionals. These devices empower us to keep a vigilant eye on our health, allowing for timely interventions and better care.
Now, let's delve into our project – the IoT-based Remote Health Care Monitoring System.
Welcome to our project! We've created something amazing to help improve healthcare, especially for elderly people. We've harnessed the power of technology to create a remote health monitoring system that's changing the way we take care of our health. Our project makes it easy to keep track of important health information without leaving your home. We built this system to simplify healthcare, reduce hospital visits, and improve the quality of care. With our step-by-step guide, you'll discover how it works and how it can empower you to take control of your health. It allows for the convenient and secure collection of vital health data, like heart rate, SpO2 and temperature, using sensors and a user-friendly interface(GUI). This project is more than wires, sensors, and data – it's about transforming healthcare.
Supplies
- Arduino nano 33 IOT https://robu.in/product/arduino-nano-33-iot/?
- Raspberry Pi 4 https://robu.in/product/raspberry-pi-4-model-b-with-2-gb-ram/?
- MAX30100 Pulse-Oximeter-Heart-Rate-Sensor https://robocraze.com/products/max30100-pulse-oximeter-heart-rate-sensor-module?
- MLX90614 Temperature Sensor https://robu.in/product/mlx90614-esf-non-contact-human-body-infrared-temperature-measurement-module/?
- AD8232 ECG Sensor https://www.electronicscomp.com/ad8232-ecg-monitor-sensor-module-india?
- PCB https://componentstree.com/product/general-purpose-pcb-5cm-x-6cm/?
Block Diagram
This is a simple block diagram demonstrating the IoT Based Remote Health Care Monitoring System with Arduino nano 33 IOT and Raspberry pi. We have used 3 sensors MAX30100 Sensor for measuring the Heart rate and SpO2 levels of a person, MLX90614 Sensor for measuring the temperature of a person, and ECG sensor for measuring the ECG (electrocardiogram) of a person. All the data from the sensors is collected from the arduino nano and then the data from the cloud is collected from the Raspberry pi and displayed on the GUI. And now the data can be seen by anyone in the world.
Sensors Description
MAX30100 Pulse Oximeter Sensor:
Pulse Oximetry is a test used to measure the oxygen level i.e. oxygen saturation of the blood. It is an easy, painless measure of how well oxygen is being sent to parts of your body furthest from your heart, such as the arms and legs. What to study more about the health care visit “https://www.hopkinsmedicine.org/”.
No doubt the Max30100 Pulse Oximeter is an amazing sensor, still it has some disadvantages it may generate incorrect readings if the finger is not properly placed. The ambient light falling on the sensor can affect the final reading. While using the Max30100 Oximeter, make sure your finger is not moving because it can result in an incorrect reading.
Max30100 Pulse Oximeter Sensor Technical Specification:
The MAX30100 operates from 1.8V and 3.3V power supplies.
Applications
- Wearable Devices
- Fitness Assistant Devices
- Medical Monitoring Devices
Pinouts:
As you can see clearly the Max30100 Pulse Oximeter has a total of 5 male headers which are clearly labeled as VIN, GND, SCL, SDA, and INT. This is an i2c supported sensor and communicates with the Arduino board through i2c communication bus.
MLX90614 Temperature Sensor:
The MLX90614 is a Contactless Infrared (IR) Digital Temperature Sensor that can be used to measure the temperature of a particular object ranging from -70° C to 382.2°C. The sensor uses IR rays to measure the temperature of the object without any physical contact and communicates to the microcontroller using the I2C protocol.
MLX90614 Temperature Sensor Specifications
- Operating Voltage: 3.6V to 5V (available in 3V and 5V version)
- Supply Current: 1.5mA
- Object Temperature Range: -70° C to 382.2°C
- Ambient Temperature Range: -40° C to 125°C
- Accuracy: 0.02°C
- Field of View: 80°
- Distance between object and sensor: 2cm-5cm (approx.).
Pinouts:
As you can see clearly the MLX90614 temperature Sensor has a total of 4 male headers which are clearly labeled as VIN, GND, SCL and SDA.
ECG Sensor:
The AD8232 ECG sensor is a commercial board used to calculate the electrical movement of the human heart. This action can be chart like an Electrocardiogram and the output of this is an analog reading.
Pinouts:
The heart rate monitoring sensor like AD8232 includes the pins like SDN pin, LO+ pin, LO- pin, OUTPUT pin, 3.3V pin, and GND pin. So that we can connect this IC to development boards like Arduino by soldering pins.
ECG Sensor Specifications
The features of this sensor mainly include the following.
- Operation of single supply ranges from 2V to 3.5V
- The front end is integrated fully with only lead ECG
- The virtual ground can be generated through integrated reference
- RFI filter is used internally
- The current supply is low like 170 µA
- The output is rail to rail
- Shutdown pin
- CMRR is 80 dB
- Incorporated RLD amplifier (right leg drive
- Electrode configurations are 2 or 3
- The operational amplifier is uncommitted
- It accepts half cell potential up to ±300 mV
- Three-pole adaptable LPF with adaptable gain
- The signal gain is high using DC blocking capacity
- Filter settling can be improved by quick restore
- Two-pole adaptable HPF
- 4 mm × 4 mm and 20-lead LFCSP package
Circuit Diagram
The circuit diagram of IOT based IoT Based Remote Health Care Monitoring System is shown in the figure below. If you are doing the same project then assemble the circuit as shown in the figure below:
Circuit Diagram Of Patient Health Monitoring Based On IOT:
- Connect MLX90614 Scl pin to A5 of Arduino, Sda pin to A4 of Arduino and the other 2 pins to Gnd and Vcc.
- Connect MAX30100 Scl pin to A5 of Arduino, Sda pin to A4 of Arduino and the other 2 pins to Gnd and Vcc.
- Connect ECG Output pin to A0, Lo- pin to D11 of Arduino, Lo+ pin to D10 of Arduino and the other 2 pins to Gnd and Vcc.
Below is the individual connections of the Sensors with Arduino nano:
Setting Up Firebase
Firebase has served as a backbone of my project that ensures secure, efficient, and accessible management of health data. It acts as the central repository where all patient health metrics, including heart rate, temperature, and ECG data, are securely stored in real-time and firestore. This cloud-based platform not only provides a seamless connection between our IoT devices and the user interface but also empowers patients and healthcare providers with instantaneous access to critical information. Furthermore, Firebase guarantees data security and privacy, ensuring that sensitive patient data is protected from unauthorized access.
Steps to follow for setting up Firebase:
- Open firebase, then Go to Console.
- After going to console add a new project and name it.
- After that setup both the Realtime and firestore databases.
- And now you are good to go.
Now when you click on Real-time you can see real time data of the sensors and when you click on firestore you can view the historical data of the sensors.
Source Code of Sensors With Arduino
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#include <Adafruit_MLX90614.h>
#define REPORTING_PERIOD_MS 1000
PulseOximeter pox;
uint32_t tsLastReport = 0;
Adafruit_MLX90614 mlx;
void onBeatDetected() {
Serial.println("Beat!");
}
void setup() {
Serial.begin(9600);
Serial.print("Initializing pulse oximeter..");
// Initialize the PulseOximeter instance
// Failures are generally due to an improper I2C wiring, missing power supply
// or wrong target chip
if (!pox.begin()) {
Serial.println("FAILED");
for(;;);
} else {
Serial.println("SUCCESS");
}
pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
mlx.begin();
pinMode(10, INPUT); // Setup for leads off detection LO +
pinMode(11, INPUT); // Setup for leads off detection LO -
}
void loop() {
// Make sure to call update as fast as possible
pox.update();
if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
Serial.print("Heart rate:");
Serial.print(pox.getHeartRate());
Serial.print(" bpm / SpO2:");
Serial.print(pox.getSpO2());
Serial.println("%");
float ambientTemp = mlx.readAmbientTempC();
float objectTemp = mlx.readObjectTempC();
Serial.print("Ambient Temperature: ");
Serial.print(ambientTemp);
Serial.println(" °C");
Serial.print("Object Temperature: ");
Serial.print(objectTemp);
Serial.println(" °C");
if ((digitalRead(10) == 1) || (digitalRead(11) == 1)) {
Serial.println('!');
} else {
// send the value of analog input 0:
Serial.print("ECG Value: ");
Serial.println(analogRead(A0));
}
tsLastReport = millis();
}
// Wait for a bit to keep serial data from saturating
// Adjust the delay as needed
}
Setting Up GUI
Now we would develop the GUI (Graphical user interface)
The GUI serves as a crucial bridge between the users (patients, healthcare providers, and families) and the complex data collected by the remote health monitoring system. The GUI presents real-time and historical data, of heart rate, temperature, and ECG sensor. Patients can view their health metrics, trends, and history, which can empower them to actively manage their health. They can also initiate actions like sharing data with doctors.
Steps to setup the GUI on raspberry pi:
- First open the raspberry pi desktop.
- Then open the terminal to install some of libraries:
- pip install firebase-admin
- python3 -m pip3 install
- sudo apt install python3-pip3
- Now open the Thony editor for writting the code.
Below is the code for the GUI:
Login.py code:
from tkinter import *
from tkinter import Tk, ttk
from tkinter import messagebox
import os # You need to import this module to launch another script
# Colors
co1 = "#525561"
co2 = "#FFFFFF"
co3 = "#1D90F5"
root = Tk()
root.title("Login")
root.geometry('400x450')
root.resizable(width=False, height=False)
root.configure(bg=co1)
frame_up = Frame(root, width=310, height=50, bg=co1)
frame_up.grid(row=0, column=0)
frame_down = Frame(root, width=310, height=400, bg=co1)
frame_down.grid(row=1, column=0)
heading = Label(frame_up, text="LOGIN", bg=co1, font=('yu gothic ui Bold', 23), fg=co2)
heading.place(x=80, y=5)
line = Label(frame_up, width=40, text="", height=1, bg=co3, anchor=NW)
line.place(x=10, y=45)
label_style = {"font": ('yu gothic ui Regular', 15), "fg": co2, "bg": co1, "anchor": NW}
username = Label(frame_down, text="username *", height=1, **label_style)
username.place(x=10, y=10)
e_name = Entry(frame_down, width=25, justify='left', font=("", 15), highlightthickness=1)
e_name.place(x=14, y=48)
password = Label(frame_down, text="password *", height=1, **label_style)
password.place(x=10, y=95)
e_password = Entry(frame_down, width=25, justify='left', show='*', font=("", 15), highlightthickness=1)
e_password.place(x=14, y=130)
email = Label(frame_down, text="email *", height=1, **label_style)
email.place(x=10, y=175)
e_email = Entry(frame_down, width=25, justify='left', font=("", 15), highlightthickness=1)
e_email.place(x=14, y=210)
email_password = Label(frame_down, text="email password *", height=1, **label_style)
email_password.place(x=10, y=255)
e_email_password = Entry(frame_down, width=25, justify='left', show='*', font=("", 15), highlightthickness=1)
e_email_password.place(x=14, y=290)
# Button
button_confirm = Button(frame_down, text="Login", bg=co3, fg=co1, width=39, height=2, font=("Ivy 9 bold"))
button_confirm.place(x=35, y=400)
# Credentials
credentials = [
['harshita', 'harshita', 'harshita.sanan@gmail.com', 'harshita20'],
['jhanvi', 'jhanvi', 'jhanvi@gmail.com', 'jhanvi']
]
def check_password():
name = e_name.get()
password = str(e_password.get())
email = e_email.get()
email_password = e_email_password.get()
for user in credentials:
if name == user[0] and password == user[1] and email == user[2] and email_password == user[3]:
messagebox.showinfo('Login', f'Welcome, {name}!')
# Launch the my_firebase.py script
os.system('python my_firebase.py')
return # Exit the loop if a matching user is found
messagebox.showwarning('Error', 'Invalid username, password, email, or email password')
button_confirm = Button(frame_down, text="Login", bg=co3, fg=co1, width=39, height=2, font=("Ivy 9 bold"), command=check_password)
button_confirm.place(x=15, y=335)
root.mainloop()
Data extraction code:
import tkinter as tk
from tkinter import *
from tkinter import ttk
from tkcalendar import Calendar
import firebase_admin
from firebase_admin import credentials, firestore
from datetime import datetime
import pyrebase
import os
import requests
# Initialize Firebase Admin SDK with your JSON key file
cred = credentials.Certificate("/home/harshita_sanan/Desktop/firestore/sensordata-5b22b-firebase-adminsdk-4978y-469cc2463e.json")
firebase_admin.initialize_app(cred)
# Create a Firestore client
db = firestore.client()
def retrieve_historical_data():
selected_date_str = date_picker.get_date()
selected_time = time_entry.get()
# Parse the selected date string to a datetime object
selected_datetime_str = f"{selected_date_str} {selected_time}"
# Parse the combined date and time string to a datetime object
selected_datetime = datetime.strptime(selected_datetime_str, "%m/%d/%Y %I:%M%p")
# Format the selected date to match the Firestore timestamp format
formatted_date = selected_datetime.strftime("%B %d, %Y at %I:%M%p")
# Access a Firestore collection and retrieve data from documents with a specific timestamp
collection_ref = db.collection("patientData")
# Define a query to filter documents by the timestamp field
query = collection_ref.where("timestamp", "==", formatted_date)
# Retrieve matching documents
docs = query.stream()
data_str = ""
for doc in docs:
data = doc.to_dict()
data_str += f"Data: {data}\n"
if data_str:
result_label.config(text=data_str)
else:
result_label.config(text=f"No documents found for {formatted_date}")
def SubmitData():
config = {
"apiKey": "AIz*************",
"authDomain": "senso***********",
"databaseURL": "https*****************",
"storageBucket": "se*******************"
}
firebase = pyrebase.initialize_app(config)
db_realtime = firebase.database()
data = db_realtime.child("Patient Data").get().val()
if data:
HeartRate = data.get("Heart")
SPO2 = data.get("Spo2")
Temperature = data.get("Temp")
webhook_url = "https://maker.ifttt.com/trigge*******************"
data_to_send = {
"value1": HeartRate,
"value2": SPO2,
"value3": Temperature
}
response = requests.post(webhook_url, json=data_to_send)
if response.status_code == 200:
print("Request Sent")
else:
print("Request Not Sent")
else:
print("Real-time data not found in the Realtime Database.")
def retrieve_realtime_data():
def update_realtime_data():
config = {
"apiKey": "AIzaSyBeA6*************",
"authDomain": "sensorda****************",
"databaseURL": "https://sensordata-******************",
"storageBucket": "sensorda****************"
}
firebase = pyrebase.initialize_app(config)
db_realtime = firebase.database()
data = db_realtime.child("Patient Data").get().val()
if data is not None:
ECG = data.get("ECG")
HeartRate = data.get("Heart")
SPO2 = data.get("Spo2")
Temperature = data.get("Temp")
# Update your Tkinter UI with the new data
data_str = f"Real-time Data:\nHeart Rate: {HeartRate}\nSPO2: {SPO2}\nTemperature: {Temperature}\nECG: {ECG}"
realtime_label.config(text=data_str, font=("Helvetica", 30), bg="black", fg="white")
# Schedule the next update in milliseconds (e.g., every 1000ms for 1 second)
root.after(1000, update_realtime_data)
realtime_window = tk.Toplevel()
realtime_window.title("Real-Time Data")
window_width = 800
window_height = 400
screen_width = realtime_window.winfo_screenwidth()
screen_height = realtime_window.winfo_screenheight()
x = (screen_width - window_width) // 2
y = (screen_height - window_height) // 2
realtime_window.geometry(f"{window_width}x{window_height}+{x}+{y}")
realtime_label = tk.Label(realtime_window, text="", font=("Helvetica", 30), bg="black", fg="white")
#realtime_label.pack()
realtime_label.grid(row=0, column=0, sticky="nsew")
# Use grid layout and sticky to fill the window
submit_button = tk.Button(realtime_window, text="Submit Data", command=SubmitData, font=("Helvetica", 16))
submit_button.grid(row=1, column=0, padx=20, pady=10)
# Configure the grid to expand and fill the available space
realtime_window.grid_rowconfigure(0, weight=1)
realtime_window.grid_columnconfigure(0, weight=1)
update_realtime_data()
root = tk.Tk()
root.title("Firestore Data Retrieval")
#root.attributes('-fullscreen', True)
# Create a date picker widget
style = ttk.Style()
style.configure("TButton", background="black", foreground="white")
style.configure("TLabel", background="black", foreground="white")
style.layout("TButton", [("Button.focus", {"children": [("Button.padding", {"children": [("Button.label", {"side": "left", "expand": 1})]})]})])
# Configure the Calendar widget
date_picker = Calendar(root, date_pattern="mm/dd/yyyy", background="black", foreground="white", headersbackground="black", headersforeground="white", bordercolor="black", normalbackground="black", normalforeground="white", othermonthbackground="black", othermonthforeground="grey")
date_picker.pack(fill='both', expand=True)
date_picker.config(font=('Helvetica', 20))
# Create a time entry field
time_label = tk.Label(root, text="Select a Time (e.g., 12:00AM):", font=('Helvetica', 16))
time_label.pack()
time_entry = tk.Entry(root, font=('Helvetica', 16))
time_entry.pack()
# Create buttons for switching between historical and real-time data
historical_button = tk.Button(root, text="Historical Data", command=retrieve_historical_data, font=('Helvetica', 16))
historical_button.pack()
realtime_button = tk.Button(root, text="Real-Time Data", command=retrieve_realtime_data , font=('Helvetica', 16))
realtime_button.pack()
# Create buttons to show login and signup windows
result_label = tk.Label(root, text="", font=('Helvetica', 16))
result_label.pack()
root.mainloop()
Sending Data to Firebase
Code for Sending the data to the Firebase Real Time and Excel sheet:
#include <WiFiNINA.h>
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#include <Adafruit_MLX90614.h>
#include "Firebase_Arduino_WiFiNINA.h"
#define DATABASE_URL "sensordata-****************" //<databaseName>.firebaseio.com or <databaseName>.<region>.firebasedatabase.app
#define DATABASE_SECRET "ytCfLvAQ******************"
#define WIFI_SSID ""
#define WIFI_PASSWORD ""
// Define Firebase data object
FirebaseData fbdo;
#define REPORTING_PERIOD_MS 1000
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
PulseOximeter pox;
uint32_t tsLastReport = 0;
const char* ssid = "vivo Y35";
const char* password = "jeetasha17022004";
void onBeatDetected() {
Serial.println("Beat!");
}
// Ifttt settings
const char* server = "maker.ifttt.com";
String eventName = "Savedata";
String IFTTT_Key = "lS4Qfe5jLcxQwrl****************";
float value1 = 0.0;
float value2 = 0.0;
float value3 = 0.0;
String path = "/Patient Data";
void setup() {
Serial.begin(9600);
Serial.print("Connecting to Wi-Fi");
int status = WL_IDLE_STATUS;
while (status != WL_CONNECTED) {
status = WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print(".");
delay(100);
}
Serial.println();
Serial.print("Connected with IP: ");
Serial.println(WiFi.localIP());
Serial.println();
// Provide the authentication data
Firebase.begin(DATABASE_URL, DATABASE_SECRET, WIFI_SSID, WIFI_PASSWORD);
Firebase.reconnectWiFi(true);
Serial.println("Setting Sensor Data");
// Initializing Pulse Oximeter sensor
Serial.println();
Serial.print("Initializing pulse oximeter..");
// Initialize the PulseOximeter instance
// Failures are generally due to an improper I2C wiring, missing power supply
// or wrong target chip
if (!pox.begin()) {
Serial.println("FAILED");
for (;;) {
}
} else {
Serial.println("SUCCESS");
}
pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
// Initializing the MLX90614 temperature sensor
Wire.begin();
mlx.begin();
pinMode(10, INPUT); // Setup for leads off detection LO +
pinMode(11, INPUT); // Setup for leads off detection LO -
}
void sendDataToIFTTT() {
// Prepare the URL with event name and values
String url = "/trigger/" + eventName + "/with/key/" + IFTTT_Key +
"?value1=" + String(value1) + "&value2=" + String(value2) +
"&value3=" + String(value3);
Serial.println("Sending data to IFTTT: " + url);
// Create a WiFiClient object
WiFiClient client;
// Connect to the server
if (client.connect(server, 80)) {
// Send an HTTP request
client.print("GET " + url + " HTTP/1.1\r\n");
client.print("Host: " + String(server) + "\r\n");
client.print("Connection: close\r\n\r\n");
// Read and print the response
while (client.connected()) {
if (client.available()) {
String line = client.readStringUntil('\n');
Serial.println(line);
}
}
// Disconnect from the server
client.stop();
} else {
Serial.println("Failed to connect to the server");
}
}
void loop() {
// Read sensor values
// Make sure to call update as fast as possible
pox.update();
if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
// Read heart rate and SpO2 values
float heartRate = pox.getHeartRate();
float SpO2Value = pox.getSpO2();
float ecg=analogRead(A0);
if (heartRate > 0 && SpO2Value > 0) {
Serial.print("Heart rate: ");
Serial.print(heartRate);
Serial.print(" bpm / SpO2: ");
Serial.print(SpO2Value);
Serial.println("%");
value2 = static_cast<float>(heartRate);
value3 = static_cast<float>(SpO2Value);
//Measuring Temp
value1=static_cast<double>(mlx.readAmbientTempC());
// Send data to IFTTT
sendDataToIFTTT();
// Sending data to Firebase
if (Firebase.setFloat(fbdo, path + "/Heart", value2)) {
Serial.println("Heart rate uploaded to Firebase");
} else {
Serial.println("Error uploading Heart rate to Firebase: " + fbdo.errorReason());
}
if (Firebase.setFloat(fbdo, path + "/Spo2", value3)) {
Serial.println("SpO2 uploaded to Firebase");
} else {
Serial.println("Error uploading SpO2 to Firebase: " + fbdo.errorReason());
}
if (Firebase.setDouble(fbdo, path + "/Temp", value1)) {
Serial.println("Temp uploaded to Firebase");
} else {
Serial.println("Error uploading SpO2 to Firebase: " + fbdo.errorReason());
}
if (Firebase.setDouble(fbdo, path + "/ECG", ecg)) {
Serial.println("ECG uploaded to Firebase");
} else {
Serial.println("Error uploading ecg to Firebase: " + fbdo.errorReason());
}
} else {
Serial.println("Invalid Heart rate or SpO2 values");
}
tsLastReport = millis();
}
// Continue with other code...
}
Code for sending the data of excel sheet to the Firebase Firestore database:
// function doGet(e) {
// Logger.log( JSON.stringify(e) ); // view parameters
// var result = 'Ok'; // assume success
// if (e.parameter == 'undefined') {
// result = 'No Parameters';
// }
// else {
// var sheet_id = '1JlVv88__0C_ttk5-dTRs6ZnaOfrdXzfGtWI-Dcw1AFk'; // Spreadsheet ID
// var sheet = SpreadsheetApp.openById(sheet_id).getActiveSheet(); // get Active sheet
// var newRow = sheet.getLastRow() + 1;
// var rowData = [];
// for (var param in e.parameter) {
// Logger.log('In for loop, param=' + param);
// var value = stripQuotes(e.parameter[param]);
// Logger.log(param + ':' + e.parameter[param]);
// switch (param) {
// case 'Temperature': //Parameter
// rowData[0] = value; //Value in column A
// result = 'Written on column A';
// break;
// case 'Humidity': //Parameter
// rowData[1] = value; //Value in column B
// result += ' ,Written on column B';
// break;
// default:
// result = "unsupported parameter";
// }
// }
// Logger.log(JSON.stringify(rowData));
// // Write new row below
// var newRange = sheet.getRange(newRow, 1, 1, rowData.length);
// newRange.setValues([rowData]);
// }
// // Return result of operation
// firestore();
// return ContentService.createTextOutput(result);
// }
// /**
// * Remove leading and trailing single or double quotes
// */
// function stripQuotes( value ) {
// return value.replace(/^["']|['"]$/g, "");
// }
// function firestore(){
// //add firebase library to script before running the code
// //get firebase project credentials from GCP and add data from the created json key below
// const email = "firebase-adminsd****************";
// const key = "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC+8XY18yTkKP6a\n1iSvF2R6FD7209nOj7iLAfQ3bSwxJEFbC0en45H7hR0L7UEt6xCxsRycms0K9xqx\nD/5iSuxioa/ItA20HF3xwymD8g93d2lurLj4xskJFkkBrqAWgRCxTwUebCpiV2zb\nfao/LnSG/mhEiLiJGI7vrn4D5e6ojJ7jkRFHV6WLJrBQVC0l7hY6D8gf8MkxdAqD\n/svlvxyP2spmojJmfPbaIxVVJwNJrX3GS9+A51Hx7bSaE3LMNWuGKcjCADEqTope\n9uAtn7mx8nAQhzr9neJ0b4rqWIX/3zk5yZAXiefN8PySthx8gEEobuzbdgFZp+e6\nl3TVr2y/AgMBAAECggEAXLDOl6XutKuJ3RQzPqP2bKTDZAK3auStyx0ptnZSy5A0\nAcRaBpAcX6Lg1NdZmrbPpdK6dvNWsgn+dRG0hXalhcPDl4SAWnyixifdUWYCSBY5\nojZKnMmy8axVyHFC2WnR9qDLdVdAw/h4qZw5Nu6QNq/tYceU/Uhkqslj9vR5hGvX\n6vJCVQhacpSM6XfxkTSMNtI4T/68oXXDbb45GIiNmtBSdw5iKwcuP9/xBAB*******************";
// const projectId = "sensordata-5b22b";
// var firestore = FirestoreApp.getFirestore (email, key, projectId);
// // get document data from ther spreadsheet
// var ss = SpreadsheetApp.getActiveSpreadsheet();
// //Give the sheetname of your spreadsheet
// var sheetname = "IFTTT_Maker_Webhooks_Events";
// var sheet = ss.getSheetByName(sheetname);
// // get the last row and column in order to define range
// var sheetLR = sheet.getLastRow(); // get the last row
// var sheetLC = sheet.getLastColumn(); // get the last column
// var dataSR = 2; // the first row of data
// // define the data range
// var sourceRange = sheet.getRange(2,1,sheetLR-dataSR+1,sheetLC);
// // get the data
// var sourceData = sourceRange.getValues();
// // get the number of length of the object in order to establish a loop value
// var sourceLen = sourceData.length;
// // Loop through the rows
// for (var i= sourceLen-1;i<sourceLen;i++){
// if (sourceData[i][1] !=='') {
// var data = {};
// data.timestamp = sourceData[i][0];
// data.heartrate=sourceData[i][1];
// firestore.createDocument("datalog",data);
// }
// }
// }
//Adding all rows
function doGet(e) {
Logger.log( JSON.stringify(e) ); // view parameters
var result = 'Ok'; // assume success
if (e.parameter == 'undefined') {
result = 'No Parameters';
}
else {
var sheet_id = '1JlVv88__0C_ttk5-dTRs6ZnaOfrdXzfGtWI-Dcw1AFk'; // Spreadsheet ID
var sheet = SpreadsheetApp.openById(sheet_id).getActiveSheet(); // get Active sheet
var newRow = sheet.getLastRow() + 1;
var rowData = [];
for (var param in e.parameter) {
Logger.log('In for loop, param=' + param);
var value = stripQuotes(e.parameter[param]);
Logger.log(param + ':' + e.parameter[param]);
switch (param) {
case 'Temperature': //Parameter
rowData[0] = value; //Value in column A
result = 'Written on column A';
break;
case 'Humidity': //Parameter
rowData[1] = value; //Value in column B
result += ' ,Written on column B';
break;
default:
result = "unsupported parameter";
}
}
Logger.log(JSON.stringify(rowData));
// Write new row below
var newRange = sheet.getRange(newRow, 1, 1, rowData.length);
newRange.setValues([rowData]);
}
// Return result of operation
firestore();
return ContentService.createTextOutput(result);
}
/**
* Remove leading and trailing single or double quotes
*/
function stripQuotes( value ) {
return value.replace(/^["']|['"]$/g, "");
}
function firestore(){
//add firebase library to script before running the code
//get firebase project credentials from GCP and add data from the created json key below
const email = "firebase-adm****************************";
const key = "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC+8XY18yTkKP6a\n1iSvF2R6FD7209nOj7iLAfQ3bSwxJEFbC0en45H7hR0L7UEt6xCxsRycms0K9xqx\nD/5iSuxioa/ItA20HF3xwymD8g93d2lurLj4xskJFkkBrqAWgRCxTwUebCpiV2zb\nfao/LnSG/mhEiLiJGI7vrn4D5e6ojJ7jkRFHV6WLJrBQVC0l7hY6D8gf8MkxdAqD\n/svlvxyP2spmojJmfPbaIxVVJwNJrX3GS9+A51Hx7bSaE3LMNWuGKcjCADEqTope\n9uAtn7mx8nAQhzr9neJ0b4rqWIX/3zk5yZAXiefN8PySthx8gEEobuzbdgFZp+e6\nl3TVr2y/AgMBAAECggEAXLDOl6XutKuJ3RQzPqP2bKTDZAK3auStyx0ptnZSy5A0\nAcRaBpAc***********************************";
const projectId = "sensordata-5b22b";
var firestore = FirestoreApp.getFirestore (email, key, projectId);
// get document data from ther spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
//Give the sheetname of your spreadsheet
var sheetname = "IFTTT_Maker_Webhooks_Events";
var sheet = ss.getSheetByName(sheetname);
// get the last row and column in order to define range
var sheetLR = sheet.getLastRow(); // get the last row
var sheetLC = sheet.getLastColumn(); // get the last column
var dataSR = 2; // the first row of data
// define the data range
var sourceRange = sheet.getRange(2,1,sheetLR-dataSR+1,sheetLC);
// get the data
var sourceData = sourceRange.getValues();
// get the number of length of the object in order to establish a loop value
var sourceLen = sourceData.length;
// Loop through the rows
for (var i= sourceLen-1;i<sourceLen;i++){
if (sourceData[i][1] !=='') {
var data = {};
data.timestamp = sourceData[i][0];
data.temperature=sourceData[i][1];
data.spo2 = sourceData[i][2];
data.heartrate=sourceData[i][3];
firestore.createDocument("patientData",data);
}
}
}App script
For sending the sensor data to firebase Firestore using google app script you can take reference from this link:
Working Video
Below is the working video of my project: