#pragma once #include "fgc/IEnvSensor.h" #include "fgc/IMotorController.h" #include namespace fgc { // A fan driven at half speed or more whose tach reads nothing: dead, jammed or // unplugged. Only meaningful where a tach is wired - without one rpm is always 0. inline bool fanLooksStalled(const McuEnvReading& r) { return r.fan_duty >= 128 && r.fan_rpm == 0; } // An ambient DHT11 wired to the motor MCU ([Hardware] env = dht11) - the legacy // towers' sensor. The firmware reads it every 10 s and prints an ENV line; this // serves the latest one through the ordinary IEnvSensor interface, so the // sensors panel, the log and `test hardware env` treat it like any other. // // No reading when the firmware's last read failed its checksum, or when no ENV // line has arrived for 2.5 read periods - a firmware built without the sensor, // or a link that has gone quiet. class McuEnvSensor : public IEnvSensor { public: static constexpr long long kStaleMs = 25000; explicit McuEnvSensor(IMotorController& motor, std::function now_ms = {}); void start() override {} void stop() override {} bool connected() const override; std::optional sample() override; std::string name() const override { return "DHT11"; } private: std::optional current() const; IMotorController& motor_; std::function now_ms_; }; } // namespace fgc