60 lines
2.2 KiB
C++
60 lines
2.2 KiB
C++
#pragma once
|
|
|
|
#include "fgc/IEnvSensor.h"
|
|
#include "fgc/Logger.h"
|
|
|
|
#include <chrono>
|
|
#include <cmath>
|
|
|
|
namespace fgc {
|
|
|
|
// Simulated ambient sensor for development without hardware: synthesizes a
|
|
// slowly varying, plausible temp/humidity reading so the Sensors panel
|
|
// animates without an SHT41 attached.
|
|
//
|
|
// It holds each reading for `period`, exactly as the real driver does (which
|
|
// only refreshes latest/timestamp_ms once per [Env] period_ms). Stamping a new
|
|
// timestamp on every sample() call would make every ~10 ms control tick look
|
|
// like a fresh reading, and Application's "publish once per fresh sample" check
|
|
// keys on that timestamp - so the mock would publish Env hundreds of times a
|
|
// second where the real sensor publishes once every two seconds.
|
|
class MockEnvSensor : public IEnvSensor {
|
|
public:
|
|
explicit MockEnvSensor(std::chrono::milliseconds period = std::chrono::milliseconds(2000))
|
|
: period_(period) {}
|
|
|
|
void start() override {
|
|
start_ = clock::now();
|
|
LOG_INFO << "[mock] env sensor started";
|
|
}
|
|
void stop() override { LOG_INFO << "[mock] env sensor stopped"; }
|
|
|
|
bool connected() const override { return true; }
|
|
|
|
std::optional<EnvSample> sample() override {
|
|
const auto now = clock::now();
|
|
if (latest_.valid && (now - taken_) < period_) return latest_; // same reading as before
|
|
|
|
const double t = std::chrono::duration<double>(now - start_).count();
|
|
latest_.valid = true;
|
|
latest_.temp_c = static_cast<float>(22.0 + 3.0 * std::sin(t * 0.02));
|
|
latest_.humidity_pct = static_cast<float>(45.0 + 10.0 * std::sin(t * 0.013 + 1.0));
|
|
latest_.timestamp_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
std::chrono::system_clock::now().time_since_epoch())
|
|
.count();
|
|
taken_ = now;
|
|
return latest_;
|
|
}
|
|
|
|
std::string name() const override { return "SHT41 (mock)"; }
|
|
|
|
private:
|
|
using clock = std::chrono::steady_clock;
|
|
clock::time_point start_ = clock::now();
|
|
std::chrono::milliseconds period_;
|
|
EnvSample latest_;
|
|
clock::time_point taken_{};
|
|
};
|
|
|
|
} // namespace fgc
|