Skip to content

Commit

Permalink
Merge pull request #661 from mestafin/constant_sensor
Browse files Browse the repository at this point in the history
added constant_sensor class
  • Loading branch information
mairas authored Jul 3, 2023
2 parents 9b0888a + a3b2add commit d8d87fa
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ jobs:
- examples/repeat_sensor_analog_input.cpp
- examples/freertos_tasks.cpp
- examples/raw_json.cpp
- examples/constant_sensor.cpp
target_device:
- esp32dev
steps:
Expand Down
45 changes: 45 additions & 0 deletions examples/constant_sensor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* @file constant_sensor.cpp
* @brief Example of a ConstantSensor that outputs a constant value at given
* time intervals.
*
* ConstantSensor is a "sensor" that outputs a constant value at given time
* intervals. The interval, output value and the path can be set in the
* user interface.
*
* This example outputs a fresh water tank capacity of 100 litres (0.1 m3) every
* 10 seconds.
*/

#include "sensesp/sensors/constant_sensor.h"
#include "sensesp_app_builder.h"

using namespace sensesp;

reactesp::ReactESP app;

void setup() {
// Some initialization boilerplate when in debug mode...
#ifndef SERIAL_DEBUG_DISABLED
SetupSerialDebug(115200);
#endif

// Create the builder object
SensESPAppBuilder builder;
sensesp_app = builder.get_app();

// Create the ConstantSensor object
auto* constant_sensor =
new FloatConstantSensor(0.1, 10, "/Sensors/Frash Water Tank Capacity");

// create and connect the output object

constant_sensor->connect_to(
new SKOutputFloat("tanks.freshWater.capacity", "",
new SKMetadata("m3", "Fresh Water Tank Capacity")));

// Start the SensESP application running
sensesp_app->start();
}

void loop() { app.tick(); }
102 changes: 102 additions & 0 deletions src/sensesp/sensors/constant_sensor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#ifndef CONSTANT_SENSOR_H_
#define CONSTANT_SENSOR_H_

#include "Arduino.h"
#include "sensesp/sensors/sensor.h"

namespace sensesp {

/**
* @brief ConstantSensor is the base class for virtual sensors that periodically
* emit a constant value.
*
* The virtual sensors are typically used to send a constant value to SignalK.
* Typical example is the capacity of a tank or the length of an anchor rode;
*
* The sensors can be connected to all the standard SKOutput consumers.
*
* The sensor value and send delay can be configured via the web ui.
*
* The sensor has a get_value() and a set_value() method to interact with the
* sensor from normal code.
*
* Example: send the water tank capacity every 30 seconds to SignalK:
*
* int send_delay = 30;
* const char* config_path = "/tanks.water_capacity";
* auto *capacity = new ConstantFloatSensor(send_delay,config_path);
* capacity->connect_to(new SKOutputFloat(sk_path, sk_config_path, sk_metadata));
*
* To set or get the the value of the virtual sensor for use in your code:
*
* capacity->set_value(value);
*
* value = capacity->get_value();
*
* @param send_interval[in] Time interval in seconds between consecutive
* emissions of the sensor value.
*
* @param[in] config_path Configuration path for the sensor.
*/

static const char SCHEMA_CONSTANT_SENSOR[] PROGMEM = R"###({
"type": "object",
"properties": {
"value": { "title": "Constant Value", "type": "number", "description": "Constant value" }
}
})###";

/**
* @brief Base class for constant value sensors.
*/
template <class T>
class ConstantSensor : public SensorT<T> {
public:
ConstantSensor(T value, int send_interval = 30, String config_path = "")
: SensorT<T>(config_path), value_{value}, send_interval_{send_interval} {
this->load_configuration();
}
void start() override {
ReactESP::app->onRepeat(send_interval_ * 1000,
[this]() { this->emit(value_); });
}

void set_value(T value) { value_ = value; }
T get_value() { return value_; }

protected:
virtual void get_configuration(JsonObject &doc) override {
doc["value"] = value_;
doc["interval"] = send_interval_;
}
virtual bool set_configuration(const JsonObject &config) override {
// Neither of the configuration parameters are mandatory
if (config.containsKey("value")) {
value_ = config["value"];
}
if (config.containsKey("interval")) {
send_interval_ = config["interval"];
}
return true;
}
virtual String get_config_schema() override {
return FPSTR(SCHEMA_CONSTANT_SENSOR);
}
void update() { this->emit(value_); }

T value_;
int send_interval_; // seconds
};

// ..........................................
// constant value sensors
// ..........................................

typedef ConstantSensor<float> FloatConstantSensor;
typedef ConstantSensor<int> IntConstantSensor;
typedef ConstantSensor<bool> BoolConstantSensor;
typedef ConstantSensor<String> StringConstantSensor;

} // namespace sensesp

#endif

0 comments on commit d8d87fa

Please sign in to comment.