This shows you the differences between two versions of the page.
iothings:proiecte:2025sric:homemonitoringsystemwithalerts [2025/05/24 13:25] andrei.buhnici [Context] |
iothings:proiecte:2025sric:homemonitoringsystemwithalerts [2025/05/24 14:37] (current) andrei.buhnici [References] |
||
---|---|---|---|
Line 15: | Line 15: | ||
PIR threshold set by me: 5 (configurable from Thingsboard) | PIR threshold set by me: 5 (configurable from Thingsboard) | ||
PIR count of 1s: 0 (when the board starts and count is reset) | PIR count of 1s: 0 (when the board starts and count is reset) | ||
- | Timer until count reset: 5 seconds (resets count to 1 if threshold is not reached) | + | Timer until count reset: 5 seconds (resets count to 1 if threshold is not reached in time) |
PIR alarm: 0 | PIR alarm: 0 | ||
| | ||
- | Now we receive: 1,1,1,1,1 for under 5 seconds then count will be 5 and PIR alarm is set to 1. If the readings of 1 take more than 5 seconds to reach the set threshold then the count will be reset and the alarm won't be triggered. Once the alarm is triggered, it won't be set to 1 again until we turn it off first. This is to avoid SMS spam. | + | Now if we receive a stream of 1s in under 5 seconds then count will be 5 and PIR alarm is set to 1. If the readings of 1 take more than 5 seconds to reach the set threshold then the count will be reset and the alarm won't be triggered. Once the alarm is triggered, it won't be set to 1 again until we turn it off first. This is to avoid SMS spam. |
The above explanation is valid for PIR and sound sensors. The gas sensor alarm functions almost the same. It only lacks the count and timer variables, because the values are analog and once the threshold value is reached it means it was progressively reached (not spiked, at least usually). | The above explanation is valid for PIR and sound sensors. The gas sensor alarm functions almost the same. It only lacks the count and timer variables, because the values are analog and once the threshold value is reached it means it was progressively reached (not spiked, at least usually). | ||
Line 28: | Line 28: | ||
{{:iothings:proiecte:2025sric:tb_rule_chain.png?700|}} | {{:iothings:proiecte:2025sric:tb_rule_chain.png?700|}} | ||
- | And this pretty much should've summed up the project, but it seemed to me that it wasn't quite enough so i also added an esp32 cam to send a photo instead of a "Motion detected!" message. So i decided to connect to my main ESP32 an [[https://www.emag.ro/placa-dezvoltare-esp32-cam-wifi-bluetooth-cu-modul-camera-ov2640-2mp-ai934/pd/D83Q4HMBM/?ref=history-shopping_422734184_112784_1|ESP32 cam module with a programmer]]. The programmer is needed to upload code to the esp32 cam module. The module is configured as a server and when a GET request to home (default path /) is received then it will begin to capture an image save the encoded image in it's main memory. Then the photo will eventually be saved to Google Cloud. By using Google Cloud scripts the image is saved in my personal drive in a designated folder. After the image is uploaded an URL is returned. The cam module extracts the URL and sends it to the client that made the GET request. The client in our case will be the main ESP32 which will connect through Wi-Fi to the cam module and it will receive the url to the image. When motion alarm is triggered it will first take a photo and then it will upload the image URL along with the motion alarm status to Thingsboard. And now when the alarm is triggered an URL to the photo will be send through SMS to the configured phone number. | + | And this pretty much should've summed up the project, but it seemed to me that it wasn't quite enough so i also added an esp32 cam to send a photo instead of a "Motion detected!" message. So i decided to connect to my main ESP32 an [[https://www.emag.ro/placa-dezvoltare-esp32-cam-wifi-bluetooth-cu-modul-camera-ov2640-2mp-ai934/pd/D83Q4HMBM/?ref=history-shopping_422734184_112784_1|ESP32 cam module with a programmer]]. The programmer is needed to upload code to the esp32 cam module. The module is configured as a server and when a GET request to home (default path /) is received then it will begin to capture an image and save the encoded image in it's main memory. Then the photo will eventually be saved to Google Cloud. By using Google Cloud scripts the image is saved in my personal drive in a designated folder. After the image is uploaded an URL is returned. The cam module extracts the URL and sends it to the client that made the GET request. The client in our case will be the main ESP32 which will connect through Wi-Fi to the cam module and it will receive the url to the image. When motion alarm is triggered it will first take a photo and then it will upload the image URL along with the motion alarm status to Thingsboard. And now when the alarm is triggered an URL to the photo will be send through SMS to the configured phone number. |
| | ||
- | {{:iothings:proiecte:2025sric:esp32_cam_flow.png?600|}} | + | {{:iothings:proiecte:2025sric:esp32_cam_flow.png?800|}} |
+ | |||
+ | {{:iothings:proiecte:2025sric:whatsapp_image_2025-05-24_at_13.43.11.jpeg?200|}} | ||
====== Hardware ====== | ====== Hardware ====== | ||
+ | - [[https://www.emag.ro/placa-esp32-cu-esp-wroom-32-38-pini-cu-cip-cp2102-multicolor-esp32-cp2102/pd/D7R798MBM/?ref=history-shopping_416710871_112784_1|ESP32]]; | ||
+ | |||
+ | - [[https://www.emag.ro/kit-16-senzori-compatibili-arduino-rpi-oky1212/pd/D8JNKRMBM/?ref=history-shopping_416710871_2895_1|PIR sensor, Sound sensor, Gas sensor]]; | ||
+ | |||
+ | - [[https://www.emag.ro/placa-dezvoltare-esp32-cam-wifi-bluetooth-cu-modul-camera-ov2640-2mp-ai934/pd/D83Q4HMBM/?ref=history-shopping_422734184_112784_1|ESP32-CAM with programmer and camera]]; | ||
+ | |||
+ | - Breadboard; | ||
+ | |||
+ | - Wires; | ||
+ | |||
+ | - USB - micro USB cables; | ||
+ | {{:iothings:proiecte:2025sric:whatsapp_image_2025-05-24_at_13.55.30.jpeg?400|}} | ||
====== Software ====== | ====== Software ====== | ||
- | === Code Snippets === | + | === Arduino Code === |
I have 2 ino files, 1 for the base ESP32 which controls the sensors and sends the data, and the other is for the esp32 cam module to take the picture and save it to my google drive. The base ESP32 code is the Thingsboard example modified to fit my needs and the esp32 cam module contains different examples combined (http server example, take photo example and google drive data upload example). | I have 2 ino files, 1 for the base ESP32 which controls the sensors and sends the data, and the other is for the esp32 cam module to take the picture and save it to my google drive. The base ESP32 code is the Thingsboard example modified to fit my needs and the esp32 cam module contains different examples combined (http server example, take photo example and google drive data upload example). | ||
Line 999: | Line 1013: | ||
Besides these 2 ino files i have 3 javascript rule nodes in Thingsboard's rule chain which just filter for the correct telemetry (motion, sound, gas) and convert the message from "gasAlarm = 1" to a string like "[Telemetry_Name] detected! [photo_url]". Then this message is sent to Twilio and is routed to the configured mobile phone number. | Besides these 2 ino files i have 3 javascript rule nodes in Thingsboard's rule chain which just filter for the correct telemetry (motion, sound, gas) and convert the message from "gasAlarm = 1" to a string like "[Telemetry_Name] detected! [photo_url]". Then this message is sent to Twilio and is routed to the configured mobile phone number. | ||
- | ==== Firebase ==== | + | ==== Google Drive ==== |
+ | As i said previously i am also using a google script to actually store the photo taken by the esp32 cam module to my google drive. The script is needed to handle the image upload and return the actual url to the image. The script is at https://script.google.com. | ||
+ | |||
+ | <code> | ||
+ | function doPost(e) { | ||
+ | var data = Utilities.base64Decode(e.parameters.data); | ||
+ | var nombreArchivo = Utilities.formatDate(new Date(), "GMT-3", "yyyyMMdd_HHmmss") + ".jpg"; | ||
+ | var blob = Utilities.newBlob(data, e.parameters.mimetype, nombreArchivo); | ||
+ | |||
+ | var folder = DriveApp.getFoldersByName("ESP32-CAM").hasNext() | ||
+ | ? DriveApp.getFoldersByName("ESP32-CAM").next() | ||
+ | : DriveApp.createFolder("ESP32-CAM"); | ||
+ | |||
+ | var file = folder.createFile(blob); | ||
+ | file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW); | ||
+ | |||
+ | var publicLink = "https://drive.google.com/uc?id=" + file.getId(); | ||
+ | |||
+ | PropertiesService.getScriptProperties().setProperty("latestImageLink", publicLink); | ||
+ | |||
+ | return ContentService.createTextOutput(publicLink); | ||
+ | } | ||
+ | |||
+ | |||
+ | function doGet(e) { | ||
+ | var link = PropertiesService.getScriptProperties().getProperty("latestImageLink"); | ||
+ | if (link) { | ||
+ | return ContentService | ||
+ | .createTextOutput(link) | ||
+ | .setMimeType(ContentService.MimeType.TEXT); | ||
+ | } else { | ||
+ | return ContentService | ||
+ | .createTextOutput("No image link available.") | ||
+ | .setMimeType(ContentService.MimeType.TEXT); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ==== Thingsboard ==== | ||
+ | In Thingsboard there is not much coding going on, i just configured some buttons which connect to the RPC methods from the ESP32 code. I also wrote some filter and transform functions in JS for the Thingsboard rule chain. It was needed in order to choose a path based on the alarm triggered and configure a message. Example: | ||
+ | <code> | ||
+ | Filter: | ||
+ | return msg.soundAlarm == 1; | ||
+ | |||
+ | Transform: | ||
+ | msg.body = "Sound was detected"; | ||
+ | delete msg.soundAlarm; | ||
+ | return {msg: msg, ...}; | ||
+ | </code> | ||
+ | |||
+ | And also there is the telemetry data and the dashboard shown in the context section. | ||
+ | |||
+ | {{:iothings:proiecte:2025sric:tb_ss.png?600|}} | ||
+ | |||
+ | {{:iothings:proiecte:2025sric:tb_dashboard.png?600|}} | ||
====== Challenges ====== | ====== Challenges ====== | ||
+ | The most challenging thing was to actually take the photo, because it needed a bit more setup with the google cloud and the actual taking of the photo. And also i really struggled with the google script because it was returning a redirect response and i had to figure out how to follow the redirect link in order to get the image URL. It took me a lot of time to realise i can just extract the url from the body of the redirect message and just make another request. Also i first wanted to send the image url through BLE to the main ESP32 and it took me a while to realise that BLE and Wi-Fi don't really work simultaneously, because there is interference and communication ordering and stuff. So i had to give that up and find another way, because i really didn't want to connect wires since i was skeptical about how to connect them. So i eventually came up with a web server and then it went smoothly. | ||
+ | |||
+ | Another big challenge was how to send SMS only once and not every time an "alarm" is triggered. And to achieve what i have now i reached the limit of free sms messages sent in 3 different days. I first tried to keep count of alarms in Thingsboard but it didn't went well and i just figured that i can manage the alarm stuff locally and just set them off from the cloud and that's exactly what i did. Now an alarm triggers once until it's turned off. | ||
+ | |||
+ | And the last challenge i encountered was setting the right values for potentiometers and the thresholds set by me. | ||
+ | |||
+ | There was a lot of trial and error during this project but thankfully nothing was fried :D. | ||
====== References ====== | ====== References ====== | ||
+ | - https://thingsboard.io/docs/devices-library/esp32-dev-kit-v1/ | ||
+ | |||
+ | - https://docs.sunfounder.com/projects/umsk/en/latest/03_esp32/esp32_lesson04_mq2.html | ||
+ | |||
+ | - https://www.electronicwings.com/esp32/pir-sensor-interfacing-with-esp32 | ||
+ | |||
+ | - https://circuitdigest.com/microcontroller-projects/interface-ky038-sound-sensor-with-esp32 | ||
+ | |||
+ | - https://randomnerdtutorials.com/esp32-cam-take-photo-save-microsd-card/ | ||
+ | |||
+ | - https://www.niraltek.com/blog/how-to-take-photos-and-upload-it-to-google-drive-using-esp32-cam/ | ||
+ | |||
+ | - https://ocw.cs.pub.ro/courses/iothings/laboratoare/2022/lab3 | ||
+ | |||
+ | - https://thingsboard.io/docs/user-guide/ui/rule-chains/ | ||