Docs/quickstart rewrite - #43
Conversation
…adings and backend communication, with Kconfig configuration and project setup.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: baf5ef3a85
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| config GRIDSHIELD_DEMO_MODE | ||
| bool "Enable Demo Mode (no sensors, simulated data)" | ||
| default y |
There was a problem hiding this comment.
Keep QEMU mode as default for simulation workflows
Setting CONFIG_GRIDSHIELD_DEMO_MODE to default y makes the default firmware entrypoint switch from app_main.cpp (QEMU path) to demo_main.cpp because GS_QEMU_BUILD is now only defined when demo mode is off (firmware/main/CMakeLists.txt:52-55). I checked the existing simulation path in scripts/script.ps1 (idf.py qemu monitor at line 55) and the quickstart QEMU flow, and neither toggles this config, so the default --run path now boots WiFi demo code and waits for connection (demo_main.cpp waits on event bits), which can stall/break QEMU simulation out of the box.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Pull request overview
Reworks the project quickstart documentation to cover backend + frontend + firmware end-to-end, and adds an ESP32 “demo mode” firmware entry point that simulates readings/alerts/anomalies and POSTs them to the FastAPI backend.
Changes:
- Rewrite
docs/QUICKSTART.mdinto a full-system, step-by-step guide (backend, frontend, QEMU/ESP32). - Add ESP32 demo firmware (
demo_main.cpp) plus Kconfig/CMake build-mode selection. - Add new documentation artifacts (
docs/RAB.md) and repository ownership config (.github/CODEOWNERS), and commit a SQLite DB file.
Reviewed changes
Copilot reviewed 6 out of 12 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| gridshield.db | Adds a committed SQLite database artifact containing schema + demo data. |
| firmware/main/demo_main.cpp | New ESP32 demo firmware that connects to WiFi and POSTs simulated JSON events to the backend. |
| firmware/main/Kconfig.projbuild | Adds “GridShield Demo Config” menu and GRIDSHIELD_DEMO_MODE option. |
| firmware/main/CMakeLists.txt | Includes both entry points and toggles GS_QEMU_BUILD based on CONFIG_GRIDSHIELD_DEMO_MODE; adds WiFi/HTTP/json deps. |
| docs/RAB.md | Adds a project budget (RAB) document. |
| docs/QUICKSTART.md | Full rewrite of quickstart guide (Indonesian), including backend/frontend steps and firmware run modes. |
| .github/CODEOWNERS | Adds CODEOWNERS coverage for repo areas. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| config GRIDSHIELD_DEMO_MODE | ||
| bool "Enable Demo Mode (no sensors, simulated data)" | ||
| default y |
There was a problem hiding this comment.
CONFIG_GRIDSHIELD_DEMO_MODE defaults to y, which flips the project into Demo (WiFi/HTTP) mode by default. Existing tooling/docs for QEMU (scripts/script.ps1 --build/--run runs idf.py qemu monitor) don't set this config, so QEMU runs will now build/run the demo firmware instead of the QEMU simulation entry point. Consider defaulting this to n (keep QEMU as the default), or update the scripts/docs to explicitly toggle this Kconfig option before QEMU builds.
| default y | |
| default n |
| cJSON* json = cJSON_CreateObject(); | ||
| // cJSON doesn't support uint64, so use double for meter_id | ||
| cJSON_AddNumberToObject(json, "meter_id", (double)meter_id); |
There was a problem hiding this comment.
meter_id is serialized as a JSON number via double. That will lose precision for 64-bit IDs above 2^53 (and the QEMU config uses a 64-bit hex meter_id). To avoid silent rounding, encode meter_id as a string (or a pair of hi/lo integers) and accept it accordingly on the backend.
| cJSON* json = cJSON_CreateObject(); | |
| // cJSON doesn't support uint64, so use double for meter_id | |
| cJSON_AddNumberToObject(json, "meter_id", (double)meter_id); | |
| char meter_id_str[32]; | |
| snprintf(meter_id_str, sizeof(meter_id_str), "%llu", | |
| (unsigned long long) meter_id); | |
| cJSON* json = cJSON_CreateObject(); | |
| // Serialize meter_id as a string to avoid precision loss for 64-bit IDs | |
| cJSON_AddStringToObject(json, "meter_id", meter_id_str); |
| char* str = cJSON_PrintUnformatted(json); | ||
| ESP_LOGI(TAG, "[READING] energy=%d Wh, voltage=%.1f V, current=%d mA", | ||
| energy_wh, voltage_mv / 1000.0f, current_ma); | ||
| http_post_json("/api/meter-data", str); | ||
| free(str); |
There was a problem hiding this comment.
cJSON_PrintUnformatted() can return NULL on allocation failure. In that case http_post_json() will call strlen(json_str) and crash. Please check str != nullptr before logging/posting, and handle the error path (e.g., log OOM and skip this cycle).
| char* str = cJSON_PrintUnformatted(json); | ||
| ESP_LOGW(TAG, "[ALERT] 🚨 %s (severity=%d)", tamper_types[idx], severity); | ||
| http_post_json("/api/tamper-alert", str); | ||
| free(str); |
There was a problem hiding this comment.
cJSON_PrintUnformatted() can return NULL on allocation failure. If that happens, http_post_json() will call strlen(json_str) and crash. Please guard against str == nullptr before posting/logging and handle the failure path.
| char* str = cJSON_PrintUnformatted(json); | ||
| ESP_LOGW(TAG, "[ANOMALY] ⚠️ %s deviation=%.1f%% confidence=%d%%", | ||
| anomaly_types[type_idx], deviation_pct, confidence); | ||
| http_post_json("/api/anomalies", str); | ||
| free(str); |
There was a problem hiding this comment.
cJSON_PrintUnformatted() can return NULL on allocation failure. If that happens, http_post_json() will call strlen(json_str) and crash. Please guard against str == nullptr before posting/logging and handle the failure path.
| ### 2.2. Seed Database (Pertama Kali) | ||
|
|
||
| Database sudah terisi data contoh (`gridshield.db`). Jika ingin reset: | ||
|
|
||
| # Or manually | ||
| python $IDF_PATH/tools/idf_tools.py install qemu-xtensa qemu-riscv32 | ||
| ```powershell | ||
| py seed.py | ||
| ``` |
There was a problem hiding this comment.
This section implies the DB already contains sample data (gridshield.db), but in the current repo the seed script generates backend/gridshield.db (and .gitignore ignores that path). If you intend users to have demo data, either (a) instruct them to run seed.py to create/populate the DB, or (b) ship the DB in the expected location and align the backend DB URL + .gitignore accordingly.
No description provided.