#pragma once #include #include #include #include #include #include class Sensor { public: typedef enum { TYPE_DOOR = 0, TYPE_TEMPERATURE, TYPE_HUMIDITY, TYPE_PRESSURE, TYPE_BRIGHTNESS, TYPE_BUTTON, TYPE_ADC, TYPE_CO2, TYPE_FORMALDEHYD, TYPE_PM25, TYPE_TOTAL_VOC, TYPE_ENERGY_USE, TYPE_POWER, TYPE_VOLTAGE, TYPE_LOWBATTERY = 128, TYPE_SHUTDOWN_IMMINENT = 251, TYPE_OCUPANCY, TYPE_SUN_ALTITUDE, TYPE_AUDIO_OUTPUT, TYPE_DUMMY, } sensor_type_t; sensor_type_t type; uint64_t id; float field; QString name; QDateTime lastSeen; bool hidden; Sensor(sensor_type_t typeIn, uint64_t idIn, float fieldIn = 0, QString nameIn = "", bool hiddenIn = false): type(typeIn), id(idIn), field(fieldIn), name(nameIn), hidden(hiddenIn) { lastSeen = QDateTime::currentDateTime(); if(nameIn == "") generateName(); } Sensor(QString nameIn = "dummy"): type(TYPE_DUMMY), id(0), field(0), name(nameIn), hidden(false) { lastSeen = QDateTime::currentDateTime(); } Sensor(const QJsonObject& json) { type = static_cast(json["SensorType"].toInt(0)); id = json["Id"].toInt(0); field = json["Field"].toDouble(0); lastSeen = QDateTime::fromString(json["LastSeen"].toString("")); hidden = json["Hidden"].toBool(false); name = json["Name"].toString(); if(name == "") generateName(); } inline bool operator==(const Sensor& in) const { return type==in.type && id == in.id; } inline bool operator!=(const Sensor& in) const { return !(*this==in); } inline void updateSeen() { lastSeen = QDateTime::currentDateTime(); } static Sensor sensorFromString(const QString& str) { QStringList bufferList = str.split(' '); if(bufferList.size() >= 7) { Sensor sensor(static_cast(bufferList[2].toUInt()), bufferList[4].toUInt(), bufferList[6].toUInt()); if(sensor.type == Sensor::TYPE_HUMIDITY || sensor.type == Sensor::TYPE_TEMPERATURE) sensor.field = sensor.field/10; if(bufferList.size() >= 9) sensor.lastSeen = QDateTime::fromSecsSinceEpoch(bufferList[8].toLongLong()); return sensor; } else { return Sensor(TYPE_DUMMY, 0, 0, "", true); } } QString toString() { return QString("SENSOR TYPE: ")+QString::number(type)+" ID: "+QString::number(id)+" FIELD: "+ QString::number((type == Sensor::TYPE_HUMIDITY || type == Sensor::TYPE_TEMPERATURE) ? field*10 : field) + " TIME: " + QString::number(lastSeen.toSecsSinceEpoch()); } inline void store(QJsonObject& json) { json["Type"] = "Sensor"; json["SensorType"] = static_cast(type); json["Id"] = static_cast(id); json["Field"] = field; json["Name"] = name; json["LastSeen"] = lastSeen.toString(); json["Hidden"] = hidden; json["Unit"] = getUnit(); } inline void generateName() { if(type == TYPE_TEMPERATURE) name = "Temperature " + QString::number(id); else if(type == TYPE_DOOR) name = "Door " + QString::number(id); else if(type == TYPE_BUTTON) name = "Button " + QString::number(id); else if(type == TYPE_AUDIO_OUTPUT) name = "Speakers " + QString::number(id); else if(type == TYPE_HUMIDITY) name = "Humidity " + QString::number(id); else if(type == TYPE_SUN_ALTITUDE) name = "Solar Altitude"; else if(type == TYPE_SHUTDOWN_IMMINENT) name = "Shutdown Imminent"; else name = "Sensor Type " + QString::number(type) + " Id " + QString::number(id); } QString getUnit() { switch(type) { case TYPE_TEMPERATURE: return "°C"; case TYPE_HUMIDITY: return "%"; case TYPE_PRESSURE: return "hPa"; case TYPE_BRIGHTNESS: return "lx"; case TYPE_CO2: return "ppm"; case TYPE_FORMALDEHYD: case TYPE_PM25: return "µg/m³"; case TYPE_TOTAL_VOC: return "ppb"; case TYPE_SUN_ALTITUDE: return "°"; case TYPE_POWER: return "W"; case TYPE_ENERGY_USE: return "kWh"; case TYPE_VOLTAGE: return "V"; default: return ""; } } }; class SensorStore: public QObject { Q_OBJECT private: std::vector sensors_; public: SensorStore(QObject *parent = nullptr); virtual ~SensorStore() {} inline std::vector* getSensors() { return &sensors_; } public slots: void sensorGotState(const Sensor& sensor); signals: void stateChenged(std::vector sensors); void sensorChangedState(Sensor sensor); void sensorDeleted(Sensor sensor); }; extern SensorStore globalSensors;