// ----------------------------------------------------------------------------- // Abstract sensor class (other sensor classes extend this class) // Copyright (C) 2017-2019 by Xose PĂ©rez // ----------------------------------------------------------------------------- #pragma once #include #include #include #include "../sensor.h" using TSensorCallback = std::function; class BaseSensor { public: // Constructor BaseSensor() {} // Destructor virtual ~BaseSensor() {} // Initialization method, must be idempotent virtual void begin() {} // Loop-like method, call it in your main loop virtual void tick() {} // Pre-read hook (usually to populate registers with up-to-date data) virtual void pre() {} // Post-read hook (usually to reset things) virtual void post() {} // Descriptive name of the sensor virtual String description() = 0; // Descriptive name of the slot # index virtual String description(unsigned char index) = 0; // Address of the sensor (it could be the GPIO or I2C address) virtual String address(unsigned char index) = 0; // Type of sensor virtual unsigned char type() { return sensor::type::Base; } // Type for slot # index virtual unsigned char type(unsigned char index) = 0; // Number of decimals for a unit (or -1 for default) virtual signed char decimals(sensor::Unit) { return -1; } // Current value for slot # index virtual double value(unsigned char index) = 0; // Generic calibration virtual void calibrate() {}; // Retrieve current instance configuration virtual void getConfig(JsonObject& root) {}; // Save current instance configuration virtual void setConfig(JsonObject& root) {}; // Load the configuration manifest static void manifest(JsonArray& root) {}; // Sensor ID unsigned char getID() { return _sensor_id; }; // Return status (true if no errors) bool status() { return 0 == _error; } // Return ready status (true for ready) bool ready() { return _ready; } // Return sensor last internal error int error() { return _error; } // Number of available slots unsigned char count() { return _count; } // Convert slot # index to a magnitude # index virtual unsigned char local(unsigned char slot) { return 0; } // Hook for event callback void onEvent(TSensorCallback fn) { _callback = fn; }; // Specify units attached to magnitudes virtual sensor::Unit units(unsigned char index) { switch (type(index)) { case MAGNITUDE_TEMPERATURE: return sensor::Unit::Celcius; case MAGNITUDE_HUMIDITY: case MAGNITUDE_POWER_FACTOR: return sensor::Unit::Percentage; case MAGNITUDE_PRESSURE: return sensor::Unit::Hectopascal; case MAGNITUDE_CURRENT: return sensor::Unit::Ampere; case MAGNITUDE_VOLTAGE: return sensor::Unit::Volt; case MAGNITUDE_POWER_ACTIVE: return sensor::Unit::Watt; case MAGNITUDE_POWER_APPARENT: return sensor::Unit::Voltampere; case MAGNITUDE_POWER_REACTIVE: return sensor::Unit::VoltampereReactive; case MAGNITUDE_ENERGY_DELTA: return sensor::Unit::Joule; case MAGNITUDE_ENERGY: return sensor::Unit::KilowattHour; case MAGNITUDE_PM1dot0: case MAGNITUDE_PM2dot5: return sensor::Unit::MicrogrammPerCubicMeter; case MAGNITUDE_CO: case MAGNITUDE_CO2: case MAGNITUDE_NO2: case MAGNITUDE_VOC: return sensor::Unit::PartsPerMillion; case MAGNITUDE_LUX: return sensor::Unit::Lux; case MAGNITUDE_RESISTANCE: return sensor::Unit::Ohm; case MAGNITUDE_HCHO: return sensor::Unit::MilligrammPerCubicMeter; case MAGNITUDE_GEIGER_CPM: return sensor::Unit::CountsPerMinute; case MAGNITUDE_GEIGER_SIEVERT: return sensor::Unit::MicrosievertPerHour; case MAGNITUDE_DISTANCE: return sensor::Unit::Meter; case MAGNITUDE_FREQUENCY: return sensor::Unit::Hertz; case MAGNITUDE_PH: return sensor::Unit::Ph; default: return sensor::Unit::None; } } protected: TSensorCallback _callback = NULL; unsigned char _sensor_id = 0x00; int _error = 0; bool _dirty = true; unsigned char _count = 0; bool _ready = false; };