Skip to content

Controls

Mitra Ardron edited this page Feb 18, 2026 · 2 revisions

WORK IN PROGRESS

Frugal IoT - Controls

Frugal IoT intrinsically deals with the idea of a Control, an module that has inputs, wired to sensors, performs some calculations, and sets its outputs which are wired to actuators.

There are different levels of engagement with Controls.

Using a Control

image

Some of the examples have Controls built in. For example if you have a Sonoff, or a SHT then examples/sonoff and examples/sht boith include a Control_Hysterisis (yes, this is miss-spelled, and awaiting a global fix across multiple repos! TODO)

To use this control, you can adjust the settings, so that for example when the value Now is greater than 25 then the Output turns on.

Hysteresis (or Hysterisis)

A switch than turns on above 25, and off below 25, is not very useful, it can flicker on and off at the transition value. This is particularly true if for example, the output turns on a fan, that immediately drops the temperature below 57 and turns off.

In practice, you want Hysteresis, e.g. a switch that turns on at 27, and off at 23, which is how room thermostats etc work.

Wiring a Control

The power of the controls is that they can be wired to other devices.

image

Expand the Now and you'll see it is wired to this devices Temperature


image

Click on the current value, and you'll be offered a list of compatible sensors to connect to.


You can connect to other devices, so for example if you have both a SHT and a Sonoff in the same project, you can connect the Out, to for example the Relay on the Sonoff.

Including an existing Control in an application

To include an existing control in an app, see examples/sht/sht.ino or examples/sonoff/sonoff.ino

// Create a new Control_Hysterisis, set its value, number of decimal points, min and max
Control_Hysterisis* cb = new Control_Hysterisis("Control_Hysterisis", "Control", 50, 1, 0, 100);

// Add it to the `controls` so it will get messages etc
frugal_iot.controls->add(cb);

// Wire its output to the LED
cb->outputs[0]->wireTo(frugal_iot.messages->setPath("ledbuiltin/on"));

It can either be wired to inputs or outputs at this stage, or left to change in the UI.

Note that the wired connections are remembered in the SPIFFS file system, and reloaded at boot, and also remembered on the MQTT server.

Developing your own Control Class

Lets say you want to build your own climate control system. With a bunch of sensors, and actuators (e.g. relay controlled fans & heaters). Including a number of Control_Hysteresis, and wiring them together, might not be sufficient or might add unwanted complexity. What is typically wanted is the ability to make decisions based on current, and possibly prior, data and then set outputs on this device on other.

Adding a custom Control class is the way to do this.
examples/climate gives the basics.

In your main.cpp or climate.ino you'll see where the custom control is created, and wired to sensors and actuators.

Then in climate.cpp(https://github.com/mitra42/frugal-iot/blob/main/examples/climate/control_climate.cpp) you find the constructor

Control_Climate::Control_Climate(const char* const id, const char* const name,
  float temp_setpoint, float temp_hysteresis,
  float humidity_setpoint, float humidity_hysteresis)

which takes some standardized parameters (id, name) and custom parameters.

It then creates the inputs e.g.

new INfloat(id, "temperature_now", "Temperature", temp_setpoint, 1, -40, 80, "black", true),

and outputs e.g.

new OUTbool(id, "temperature_out", "Heating", false, "black", true),

The key function needed is act().

This function is called whenever any of the inputs have changed. This is where any calculations are made, and can be as simple, or complex, as needed.

Adding to UX

TODO - write this

Controls and buttons (as in examples/sonoff)

TODO - write this

Time and Deep sleep for Controls

TODO - relationship to Deep Sleep TODO - relationship to time

Clone this wiki locally