Aquariums rely on numerous peripheral devices, resulting in high overall power demand and burdensome maintenance.
From a user perspective, it is difficult to access consolidated environmental information—such as water temperature
Many routine tasks still require manual intervention (e.g., water changes and feeding), creating a significant operational burden.
So we persue a Fully-automated smart aquarium
Improving Manual Operations in AquariumsPain Points of Typical Aquariums
Each peripheral device requires a separate power source
Key environmental parameters are not easily accessible
Routine tasks (e.g., water changes and feeding) create a continual manual workload.
Proposed Improvements
Centralize power distribution and control
Collect data and provide a user-facing monitoring system.
Automate manual maintenance tasks
Core Implementation Ideas - SensorsWe structured the code to exchange HTTP requests with preconfigured endpoints on the Mobius4 server, and the above snippet is the core implementation that sends only the value field of the sensor data to the corresponding endpoint.
Core Implementation Ideas - ControlJust like the sensors send HTTP requests, the actuators continuously poll the endpoint where control commands are received. When an "on" or "off" control command is detected, the corresponding relay on the mapped pin is activated, enabling the automatic control of the aquarium's environment.
Core Implementation Ideas - ServerThe AE-Logic server automatically creates subscriptions on Mobius at startup using the check_and_create_subscription function.
- It iterates through every individual container in the
SUBSCRIPTION_RESOURCE_URLSlist (e.g.,/temp,/light). "enc": {"net":[3]}is the critical setting that tells Mobius to send a notification only upon the Creation of a Child Resource (cin)."nct": 1ensures that the notification includes the fullm2m:cindata object, which solved our earlierno m2m:cinerror.- A unique
X-M2M-RIheader is generated for each request to prevent therqi is required400 error.
All notifications from Mobius are received at the /notification endpoint. This endpoint immediately delegates the job to a background thread, _process_notification_worker, allowing it to instantly send a 200 OK response back to Mobius.
- Path Resolution: When Mobius sends a short Resource ID (
ri) in thepifield, theresolve_resource_pathfunction uses theg_ri_cachemap to translate it into a full, human-readable path like/Mobius/AE-Sensor/light. This is a crucial feature. - Routing: The code parses the
aeandcntfrom the path and usesif ae == AE_SENSOR:statements to route the data to the correct handler function. - Debouncing: Sensor/threshold alerts are passed to
schedule_debounceto bundle rapid-fire events together, preventing server overload.
This function, called by the sensor_debounce_handler, is the core automation logic for the server.
- Stateful: It safely reads the latest thresholds (e.g.,
temp-threshold) set by the app from theg_statevariable. This state is persistent, meaning it survives server restarts thanks tostate_persistent.json. - Independent Execution: It checks that both the sensor value (
temp) and the threshold (t_thresh) are notNoneand are valid numbers (isinstance) before comparing them. This allows the logic for the heater to run even if thelightsensor hasn't reported data. - Compound Logic: Based on the comparison, it either controls actuators by calling
send_mobius_command(for the heater/LED) or triggers external APIs likesend_fcm_push(for water level warnings).
The scheduler_thread_fn is a "heartbeat" that runs in a separate thread (started by start_server), checking the time every 60 seconds.
- It reads the
feeding_times(e.g.,[9, 17]) from the globalg_state. - It checks if the current time is on the hour (
minute == 0) and if thehouris in the schedule. - If conditions are met, it sends an
"on"command to thefeedactuator. - Crucially, after a successful
"on"command, it pauses for 1 second (time.sleep(1.0)) before sending an"off"command. This ensures the feed motor runs for a precise, controlled duration.
This screenshot shows the top-level (root) view of our Mobius resource tree. This structure represents all the "participants" and "rules" of our project at a glance.
This screenshot shows the details of AE and CNT to which each ACP is applied. This design clarifies the flow of data and, most importantly, allows us to enforce strict ACPs (Access Control Policies) to control who can access what.
AEs (Application Entities):
AE-Sensor: The ESP32 sensor device.AE-Rapi: The Raspberry Pi responsible for AI analysis.AE-App: The user's mobile application.AE-Actuator: The physical actuators (heater, LED, etc.).AE-Logic: The Python server (logic_server.py)
ACPs (Access Control Policies):
acp-sensor,acp-app, etc., are the "security rules" linked to each CNT and AE.- These ACP files define "who (Originator) can do what (Operation)."
This is the internal structure of AE-Sensor.
- CNTs (Containers): It consists of containers for "raw data" physically measured by the ESP32, such as
light,temp, andwlevel. - Data Flow: The ESP32's only job is to
POST(write) new data to these CNTs. - Security: Governed by the
acp-sensorpolicy, the ESP32 (S-Sensor) can only write to its own CNTs. It is strictly forbidden from accessing sensitive information in other AEs, likeAE-ActuatororAE-App'sfcm-token.
This is the internal structure of AE-Actuator.
- CNTs (Containers): It consists of containers that receive control commands, such as
feed,heater, andLED. - Data Flow: The
AE-Logic(Python server)POSTs control commands (like"on"or"off") to these CNTs. - Security (Critical): Based on its
acp-actuatorpolicy, onlyS-Logic(the server) has permission to write (POST) to these CNTs. This means that even if the mobile app (S-App) or a sensor (S-Sensor) is compromised, it is impossible for them to turn on the heater or run the feeder.
While oneM2M's ACP (Application Layer Security) determines who can control the data, our Nginx setup provides Transport Layer Security to encrypt the channel the data travels through.
This project implements a Multi-Layered Security model that uses both.
No external device (ESP32, mobile app, Freeboard dashboard) ever accesses the Mobius server (running on http://localhost:7599) directly. Instead, all traffic is routed through an Nginx Reverse Proxy.
- Single Point of Entry: Nginx listens externally on port
443(HTTPS) and securely forwards requests to the correct internal service, whether it'shttp://localhost:7599(Mobius). The Mobius and logic servers themselves are never directly exposed to the network. - Encrypted Data Transfer (SSL/TLS):All of these data payloads and their headers (like
X-M2M-Origin) are encrypted with SSL/TLS (HTTPS) during transit. This fundamentally blocks Man-in-the-Middle (MITM) attacks, preventing an attacker on the same Wi-Fi network from sniffing packets to read or tamper with the data.
This model is designed to classify the health condition of a Betta fish into three categories: Normal, Fin Rot, and White Spot.It follows a typical CNN (Convolutional Neural Network) pipeline, similar to a lightweight ResNet structure.
To make it easy to understand, we can break the model into four major stages:
1️⃣ Input — The Image Enters the ModelThe model receives a 224 × 224 RGB image of a Betta fish.This ensures a consistent size and format before processing.
2️⃣ Stem — Extracting the Basic ShapeThe Stem block uses 7×7 Convolution + BatchNorm + ReLU + MaxPool.
Its purpose is to quickly capture large-scale features from the image, such as:
overall body shape
- overall body shape
major color areas
- major color areas
coarse patterns
- coarse patterns
You can think of this as a rough first scan that grabs the big picture before focusing on details.
3️⃣ Feature Extraction (Layer1–Layer4) — Understanding Deeper PatternsThese layers consist of ResNet BasicBlocks, and each stage extracts increasingly complex features.
Layer
Output Size
What It Learns
Layer1
64 channels, 56×56
Edges, simple textures
Layer2
128 channels, 28×28
Fins, color transitions, basic patterns
Layer3
256 channels, 14×14
Disease-related structures, abnormal shapes
Layer4
512 channels, 7×7
High-level features like white spots, fin damage
As we go deeper, the model transitions from:pixels → edges → patterns → meaningful disease cues.
📱 S m art Fish Tank App Development – Structure & Role OverviewIn this project, I was responsible for developing the Android application (9P-App) used to manage and interact with the smart aquarium.
The app allows users to monitor the aquarium in real time, control actuators such as the water pump and heater, and receive immediate alerts when abnormal conditions occur.
Within the overall system, the app serves as the main interface connecting the user to the IoT platform (Mobius).
To make the workflow easy to understand, the app can be described in four intuitive stages.
1️⃣ Input Stage — Reading Aquarium StatusThe app retrieves sensor data from the Mobius (oneM2M) platform, including:
- Water temperature
- Water level
- Ambient light
- Pump status
These values are uploaded by the hardware system (ESP32 / Raspberry Pi) and the app fetches the latest data periodically or upon user request.
In this stage, the app acts as a window that displays the aquarium’s current condition.
2️⃣ Data Processing Stage — Communicating with MobiusThe app communicates with Mobius using REST API calls, performing two key operations:
■ Fetching Sensor Data (GET)- Requests the latest ContentInstance (cin) from Mobius
- Parses the JSON response using Gson
- Updates the UI with real-time values
When the user presses a control button (e.g., Pump ON), the app sends a command like:
{ "m2m:cin": { "con": { "Pump": "on" } } }The Raspberry Pi, subscribed to this container, receives the command and operates the physical device accordingly.
At this stage, the app becomes the bridge that converts user actions into actual device operations.
3️⃣ Function Processing Stage — User-Centered FeaturesThe app provides several key screens:
- Dashboard: Real-time sensor monitoring
- Device Control: Remote actuator control
- Notification Log: Viewing received alert messages
Each screen is connected to Mobius through the Retrofit2 network layer.
ViewBinding is used for stable and clean UI rendering.
Especially, the Notification Log uses Firebase Cloud Messaging (FCM) to deliver immediate alerts whenever the system detects abnormal conditions.
4️⃣ User Interface Stage — Connecting Monitoring to ControlThe app is designed to enhance user experience by enabling:
- Real-time monitoring from anywhere
- Instant control of devices such as pumps
- Immediate notification through FCM when something unusual occurs
Therefore, the 9P-App does more than simple monitoring—it functions as a mobile dashboard that allows the user to operate the entire IoT system conveniently.
#DemoVideo















Comments