Skip to content

Concepts

Mitra Ardron edited this page Jun 13, 2026 · 14 revisions

DRAFT

THIS IS A WORK IN PROGRESS - MUCH MORE TO BE ADDED THOUGH WHAT IS HERE SHOULD BE ACCURATE

Frugal IoT Concepts

This document is intended to give a high level overview of some of the concepts in Frugal IoT for developers, so its a good place to start and there should be links to more detailed versions.

Currently there is no particular order to these, I am just trying to bring documentation together on concepts that in many cases bridge nodes, logger/server and client.

To be covered below:

  • System Architecture
  • LoRa - how we'll handle longer range communications outside of WiFi range
  • Control - how parts are hooked together into control systems
  • Back Data / Logging - how we keep track of, and serve, old data
  • Interrupts
  • Power
  • Processors - including adding new ones
  • Local Ops - own server on RPi etc
  • UX (both its ugliness and composability)
  • Loops, periodic and infrequent
  • Data Structures on Client
  • Graphing
  • State retention - Node File System; MQTT broker, logger, RTC
  • multilingual

And in other documents

Loops, periodic and infrequent

Most of the time the sensor is running in a loop but things can happen on three different levels of frequency:

In each main.cpp we call e.g. frugal_iot.configure_power(Power_Deep, 600000, 30000)

This sets our "period" as 600000ms (10 minutes)

In the definition of the

  • loop() is run every time the loop goes round. This happens very frequently - around once every 10ms.
  • periodic() is run once for each period we define in the power setup so here it would be every 10 minutes. If we are sleeping, this is always once every time after we wake up
  • infrequent() is run every time the loop goes round but it should check a timer to see whether it should run. Generally avoid using the timers unless necessary. See System_Discovery::infrequently() for an example.

State retention - Node File System; MQTT broker, logger, RTC

State is stored in several places in the system. Wherever it's stored, it is conceptually following the message naming scheme /orgid/projectid/nodeid/moduleid/leaf[/parameter] for its hierarchy.

parameter is optional, and in structures that cannot handle a variable number of fields the special parameter value is used for the value of the leaf.

Node File System

  • Each node has its own file system in the LittleFS file format.
  • (We previously used SPIFFS, and you might still find references to this).
  • It's stored in a standard file hierarchy with the top level being the module, the next being the leaf, and the file name being the parameter or value.
  • There is an exception where the directory wifi has files, each of which is the SSID of a WiFi network, and the content is the password, e.g. /wifi/myhome = secret
  • This file system can be flashed if you're using platformio, and in particular I use this to store the Wi-Fi networks that I expect the node to encounter.
  • Each module uses readConfigFromFS() to read its directory during the setup() process.
  • Incoming set messages, are written to the file system with writeConfigToFS so the state is retained

Server

The server does not retain any state about nodes - though the Logger module it runs does. It does retain state about cookies for logged in users. Restarting the server clears this, so users have to login again.

MQTT broker

  • Most state change messages are sent using retain=true,
  • which means the broker will keep a mapping between topic and value.
  • The node doesn't see these echoed back because it only subscribes to set messages.
  • UX gets the full copy of the state from these messages, since it has subscribed to the .../node/#

Currently, set messages are also sent with retain=true, but this is likely to change. This currently means that on startup a node subscribes to .../node/set/# and gets these messages sent again, but since they should have previously been received and stored on disk, there is no impact on node state.

Restarting the broker does NOT clear state, as its stored in a database, to remove it ...

pushd /var/lib/mosquitto
service mosquitto stop. # Stop mosquitto first, so it writes out its status
sudo rm mosquitto.db.save; sudo mv mosquitto.db mosquitto.db.save # Save a copy, just in ccase
service mosquitto start # Start mosquitto, will recreate `.db` 
service frugaliot restart # Reconnect to this mosquitto

logger - see back data

  • The logger stores messages that are flagged in the schema/modules.yaml aslog=true into CSV files. See back data storage above.
  • The logger typically also stores the current state of each node, although there is currently no way to access this.
  • Restarting the logger loses that state, but it will reload when it connects to the MQTT server

RTC

  • During deep sleep, the RAM memory is cleared.
  • A few specific values that change frequently are stored in RTC memory, which survives deep sleep.
  • Currently, this includes just the timers and the total amount of time that sleep has happened for.
  • Power cycle clears this memory

Clone this wiki locally