192 lines
4.4 KiB
C++
192 lines
4.4 KiB
C++
#pragma once
|
|
#include <stdint.h>
|
|
#include<QString>
|
|
#include<QDateTime>
|
|
#include<QObject>
|
|
#include<vector>
|
|
#include<QJsonObject>
|
|
|
|
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<sensor_type_t>(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<sensor_type_t>(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<int>(type);
|
|
json["Id"] = static_cast<int>(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<Sensor> sensors_;
|
|
|
|
public:
|
|
|
|
SensorStore(QObject *parent = nullptr);
|
|
virtual ~SensorStore() {}
|
|
|
|
inline std::vector<Sensor>* getSensors()
|
|
{
|
|
return &sensors_;
|
|
}
|
|
|
|
|
|
public slots:
|
|
|
|
void sensorGotState(const Sensor& sensor);
|
|
|
|
signals:
|
|
|
|
void stateChenged(std::vector<Sensor> sensors);
|
|
void sensorChangedState(Sensor sensor);
|
|
void sensorDeleted(Sensor sensor);
|
|
|
|
};
|
|
|
|
extern SensorStore globalSensors;
|