-
Notifications
You must be signed in to change notification settings - Fork 5
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.
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.
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.
The power of the controls is that they can be wired to other devices.
Expand the Now and you'll see it is wired to this devices Temperature
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.
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.
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.
TODO - write this
TODO - write this
TODO - relationship to Deep Sleep TODO - relationship to time