Support different Sensor update types

This commit is contained in:
Carl Philipp Klemm 2026-04-21 16:31:13 +02:00
parent ff07551a59
commit 09f7e55b4e
20 changed files with 258 additions and 41 deletions

View file

@ -31,7 +31,7 @@ void PolynomalActor::getCoeffiancts( double& pow3, double& pow2, double& pow1, d
pow0=pow0_; pow0=pow0_;
} }
void PolynomalActor::sensorEvent(Sensor sensor) void PolynomalActor::sensorEvent(Sensor sensor, sensor_update_type_t type)
{ {
if(active && sensor == sensor_) if(active && sensor == sensor_)
{ {

View file

@ -18,7 +18,7 @@ private:
public slots: public slots:
void sensorEvent(Sensor sensor); void sensorEvent(Sensor sensor, sensor_update_type_t type);
public: public:

View file

@ -21,7 +21,7 @@ void Regulator::setSensor(const Sensor sensor)
sensor_ = sensor; sensor_ = sensor;
} }
void Regulator::sensorEvent(Sensor sensor) void Regulator::sensorEvent(Sensor sensor, sensor_update_type_t type)
{ {
if(active && sensor == sensor_) if(active && sensor == sensor_)
{ {

View file

@ -26,7 +26,7 @@ private slots:
public slots: public slots:
void sensorEvent(Sensor sensor); void sensorEvent(Sensor sensor, sensor_update_type_t type);
void setSensor(const Sensor sensor); void setSensor(const Sensor sensor);
void setPoint(float setPoint ); void setPoint(float setPoint );

View file

@ -17,7 +17,7 @@ void SensorActor::setSensor(const Sensor sensor)
sensor_ = sensor; sensor_ = sensor;
} }
void SensorActor::sensorEvent(Sensor sensor) void SensorActor::sensorEvent(Sensor sensor, sensor_update_type_t type)
{ {
if(sensor == sensor_) if(sensor == sensor_)
{ {

View file

@ -18,7 +18,7 @@ private:
public slots: public slots:
void sensorEvent(Sensor sensor); void sensorEvent(Sensor sensor, sensor_update_type_t type);
void setSloap(uint8_t sloap); void setSloap(uint8_t sloap);
void setSensor(const Sensor sensor); void setSensor(const Sensor sensor);

View file

@ -6,7 +6,7 @@
PowerItem::PowerItem(uint32_t itemIdIn, QString name, uint8_t value, QObject* parent): PowerItem::PowerItem(uint32_t itemIdIn, QString name, uint8_t value, QObject* parent):
Item(itemIdIn, name, value, parent) Item(itemIdIn, name, value, parent)
{ {
stateChanged(Sensor(Sensor::TYPE_SHUTDOWN_IMMINENT, 0, 0, "Shutdown Imminent", true)); stateChanged(Sensor(Sensor::TYPE_SHUTDOWN_IMMINENT, 0, 0, "Shutdown Imminent", true), SENSOR_UPDATE_BACKEND);
value_ = true; value_ = true;
hidden_ = true; hidden_ = true;
type_ = ITEM_VALUE_NO_VALUE; type_ = ITEM_VALUE_NO_VALUE;
@ -18,7 +18,7 @@ void PowerItem::enactValue(uint8_t value)
{ {
qDebug()<<"shutdown"; qDebug()<<"shutdown";
QTimer::singleShot(5000, this, &PowerItem::timeout); QTimer::singleShot(5000, this, &PowerItem::timeout);
stateChanged(Sensor(Sensor::TYPE_SHUTDOWN_IMMINENT, 0, 1, "Shutdown Imminent", true)); stateChanged(Sensor(Sensor::TYPE_SHUTDOWN_IMMINENT, 0, 1, "Shutdown Imminent", true), SENSOR_UPDATE_BACKEND);
} }
} }

View file

@ -13,7 +13,7 @@ private:
signals: signals:
void stateChanged(Sensor sensor); void stateChanged(Sensor sensor, sensor_update_type_t type = SENSOR_UPDATE_BACKEND);
private slots: private slots:
void timeout(); void timeout();

View file

@ -120,6 +120,7 @@ PrimaryMainObject::~PrimaryMainObject()
void PrimaryMainObject::store(QJsonObject &json) void PrimaryMainObject::store(QJsonObject &json)
{ {
globalItems.store(json); globalItems.store(json);
globalSensors.store(json);
QJsonObject mqttJson = json["Mqtt"].toObject(); QJsonObject mqttJson = json["Mqtt"].toObject();
mqttClient->store(mqttJson); mqttClient->store(mqttJson);
mqttSensorSource.store(mqttJson); mqttSensorSource.store(mqttJson);
@ -130,6 +131,7 @@ void PrimaryMainObject::load(const QJsonObject& json)
{ {
settings = json; settings = json;
itemLoader.updateJson(json); itemLoader.updateJson(json);
globalSensors.load(json);
globalItems.clear(); globalItems.clear();
globalItems.refresh(); globalItems.refresh();
} }

View file

@ -190,7 +190,7 @@ void Microcontroller::processSensorState(const QString& buffer)
{ {
Sensor sensor = Sensor::sensorFromString(buffer); Sensor sensor = Sensor::sensorFromString(buffer);
if(sensor.type != Sensor::TYPE_DUMMY) if(sensor.type != Sensor::TYPE_DUMMY)
gotSensorState(sensor); gotSensorState(sensor, SENSOR_UPDATE_BACKEND);
} }

View file

@ -78,7 +78,7 @@ private slots:
signals: signals:
void textRecived(const QString string); void textRecived(const QString string);
void gotSensorState(Sensor sensor); void gotSensorState(Sensor sensor, sensor_update_type_t type = SENSOR_UPDATE_BACKEND);
}; };
#endif // MICROCONTROLLER_H #endif // MICROCONTROLLER_H

View file

@ -39,6 +39,7 @@ MqttSensorSource::SensorSubscription& MqttSensorSource::findSubscription(const Q
return sensor; return sensor;
} }
assert(false); assert(false);
return sensors.front();
} }
void MqttSensorSource::onClientStateChanged(QMqttClient::ClientState state) void MqttSensorSource::onClientStateChanged(QMqttClient::ClientState state)
@ -81,7 +82,7 @@ void MqttSensorSource::onMessageReceived(const QMqttMessage& message)
sensor.name = baseName + " Temperature"; sensor.name = baseName + " Temperature";
sensor.type = Sensor::TYPE_TEMPERATURE; sensor.type = Sensor::TYPE_TEMPERATURE;
sensor.field = obj["temperature"].toDouble(0); sensor.field = obj["temperature"].toDouble(0);
stateChanged(sensor); stateChanged(sensor, SENSOR_UPDATE_BACKEND);
} }
if(obj.contains("local_temperature")) if(obj.contains("local_temperature"))
@ -89,7 +90,7 @@ void MqttSensorSource::onMessageReceived(const QMqttMessage& message)
sensor.name = baseName + " Temperature"; sensor.name = baseName + " Temperature";
sensor.type = Sensor::TYPE_TEMPERATURE; sensor.type = Sensor::TYPE_TEMPERATURE;
sensor.field = obj["local_temperature"].toDouble(0); sensor.field = obj["local_temperature"].toDouble(0);
stateChanged(sensor); stateChanged(sensor, SENSOR_UPDATE_BACKEND);
} }
if(obj.contains("humidity")) if(obj.contains("humidity"))
@ -97,7 +98,7 @@ void MqttSensorSource::onMessageReceived(const QMqttMessage& message)
sensor.name = baseName + " Humidity"; sensor.name = baseName + " Humidity";
sensor.type = Sensor::TYPE_HUMIDITY; sensor.type = Sensor::TYPE_HUMIDITY;
sensor.field = obj["humidity"].toDouble(0); sensor.field = obj["humidity"].toDouble(0);
stateChanged(sensor); stateChanged(sensor, SENSOR_UPDATE_BACKEND);
} }
if(obj.contains("illuminance")) if(obj.contains("illuminance"))
@ -105,7 +106,7 @@ void MqttSensorSource::onMessageReceived(const QMqttMessage& message)
sensor.name = baseName + " Illuminance"; sensor.name = baseName + " Illuminance";
sensor.type = Sensor::TYPE_BRIGHTNESS; sensor.type = Sensor::TYPE_BRIGHTNESS;
sensor.field = obj["illuminance"].toDouble(0); sensor.field = obj["illuminance"].toDouble(0);
stateChanged(sensor); stateChanged(sensor, SENSOR_UPDATE_BACKEND);
} }
if(obj.contains("presence")) if(obj.contains("presence"))
@ -113,7 +114,7 @@ void MqttSensorSource::onMessageReceived(const QMqttMessage& message)
sensor.name = baseName + " Presence"; sensor.name = baseName + " Presence";
sensor.type = Sensor::TYPE_OCUPANCY; sensor.type = Sensor::TYPE_OCUPANCY;
sensor.field = obj["presence"].toBool() ? 1 : 0; sensor.field = obj["presence"].toBool() ? 1 : 0;
stateChanged(sensor); stateChanged(sensor, SENSOR_UPDATE_BACKEND);
} }
if(obj.contains("co2")) if(obj.contains("co2"))
@ -121,7 +122,7 @@ void MqttSensorSource::onMessageReceived(const QMqttMessage& message)
sensor.name = baseName + " co2"; sensor.name = baseName + " co2";
sensor.type = Sensor::TYPE_CO2; sensor.type = Sensor::TYPE_CO2;
sensor.field = obj["co2"].toDouble(0); sensor.field = obj["co2"].toDouble(0);
stateChanged(sensor); stateChanged(sensor, SENSOR_UPDATE_BACKEND);
} }
if(obj.contains("formaldehyd")) if(obj.contains("formaldehyd"))
@ -129,7 +130,7 @@ void MqttSensorSource::onMessageReceived(const QMqttMessage& message)
sensor.name = baseName + " Formaldehyd"; sensor.name = baseName + " Formaldehyd";
sensor.type = Sensor::TYPE_FORMALDEHYD; sensor.type = Sensor::TYPE_FORMALDEHYD;
sensor.field = obj["formaldehyd"].toDouble(0); sensor.field = obj["formaldehyd"].toDouble(0);
stateChanged(sensor); stateChanged(sensor, SENSOR_UPDATE_BACKEND);
} }
if(obj.contains("pm25")) if(obj.contains("pm25"))
@ -137,7 +138,7 @@ void MqttSensorSource::onMessageReceived(const QMqttMessage& message)
sensor.name = baseName + " pm25"; sensor.name = baseName + " pm25";
sensor.type = Sensor::TYPE_PM25; sensor.type = Sensor::TYPE_PM25;
sensor.field = obj["pm25"].toDouble(0); sensor.field = obj["pm25"].toDouble(0);
stateChanged(sensor); stateChanged(sensor, SENSOR_UPDATE_BACKEND);
} }
if(obj.contains("voc")) if(obj.contains("voc"))
@ -145,7 +146,7 @@ void MqttSensorSource::onMessageReceived(const QMqttMessage& message)
sensor.name = baseName + " VOC"; sensor.name = baseName + " VOC";
sensor.type = Sensor::TYPE_TOTAL_VOC; sensor.type = Sensor::TYPE_TOTAL_VOC;
sensor.field = obj["voc"].toDouble(0); sensor.field = obj["voc"].toDouble(0);
stateChanged(sensor); stateChanged(sensor, SENSOR_UPDATE_BACKEND);
} }
if(obj.contains("power")) if(obj.contains("power"))
@ -153,7 +154,7 @@ void MqttSensorSource::onMessageReceived(const QMqttMessage& message)
sensor.name = baseName + " Power"; sensor.name = baseName + " Power";
sensor.type = Sensor::TYPE_POWER; sensor.type = Sensor::TYPE_POWER;
sensor.field = obj["power"].toDouble(0); sensor.field = obj["power"].toDouble(0);
stateChanged(sensor); stateChanged(sensor, SENSOR_UPDATE_BACKEND);
} }
if(obj.contains("energy")) if(obj.contains("energy"))
@ -161,7 +162,7 @@ void MqttSensorSource::onMessageReceived(const QMqttMessage& message)
sensor.name = baseName + " Energy"; sensor.name = baseName + " Energy";
sensor.type = Sensor::TYPE_ENERGY_USE; sensor.type = Sensor::TYPE_ENERGY_USE;
sensor.field = obj["energy"].toDouble(0); sensor.field = obj["energy"].toDouble(0);
stateChanged(sensor); stateChanged(sensor, SENSOR_UPDATE_BACKEND);
} }
if(obj.contains("voltage")) if(obj.contains("voltage"))
@ -169,7 +170,7 @@ void MqttSensorSource::onMessageReceived(const QMqttMessage& message)
sensor.name = baseName + " Voltage"; sensor.name = baseName + " Voltage";
sensor.type = Sensor::TYPE_VOLTAGE; sensor.type = Sensor::TYPE_VOLTAGE;
sensor.field = obj["voltage"].toDouble(0); sensor.field = obj["voltage"].toDouble(0);
stateChanged(sensor); stateChanged(sensor, SENSOR_UPDATE_BACKEND);
} }
} }
} }

View file

@ -38,7 +38,7 @@ public:
void store(QJsonObject& json); void store(QJsonObject& json);
signals: signals:
void stateChanged(Sensor sensor); void stateChanged(Sensor sensor, sensor_update_type_t type = SENSOR_UPDATE_BACKEND);
}; };
#endif // MQTTSENSORSOURCE_H #endif // MQTTSENSORSOURCE_H

View file

@ -1,6 +1,7 @@
#include "sensor.h" #include "sensor.h"
#include <QDebug> #include <QDebug>
#include <QJsonArray>
SensorStore globalSensors; SensorStore globalSensors;
@ -10,9 +11,31 @@ SensorStore::SensorStore(QObject *parent): QObject(parent)
sensors_.push_back(Sensor(Sensor::TYPE_DOOR,0,0,"Bedroom door")); sensors_.push_back(Sensor(Sensor::TYPE_DOOR,0,0,"Bedroom door"));
} }
void SensorStore::sensorGotState(const Sensor& sensor) void SensorStore::store(QJsonObject& json)
{ {
bool exsisting = false; QJsonArray sensorsArray;
for(const Sensor& sensor : sensors_)
{
QJsonObject sensorObject;
sensor.store(sensorObject);
sensorsArray.append(sensorObject);
}
json["Sensors"] = sensorsArray;
}
void SensorStore::load(const QJsonObject& json)
{
knownSensors_.clear();
QJsonArray sensorsArray = json["Sensors"].toArray();
for(const QJsonValue& value : sensorsArray)
{
knownSensors_.push_back(Sensor(value.toObject()));
}
}
void SensorStore::sensorGotState(const Sensor& sensor, sensor_update_type_t type)
{
bool inSensors = false;
for(unsigned i = 0; i < sensors_.size(); ++i) for(unsigned i = 0; i < sensors_.size(); ++i)
{ {
if(sensor.type == sensors_[i].type && sensor.id == sensors_[i].id) if(sensor.type == sensors_[i].type && sensor.id == sensors_[i].id)
@ -21,17 +44,43 @@ void SensorStore::sensorGotState(const Sensor& sensor)
if(sensors_[i].field != sensor.field) if(sensors_[i].field != sensor.field)
{ {
sensors_[i].field = sensor.field; sensors_[i].field = sensor.field;
sensorChangedState(sensor); if(type == SENSOR_UPDATE_USER)
stateChenged(sensors_); {
} sensors_[i].name = sensor.name;
exsisting = true; sensors_[i].hidden = sensor.hidden;
// Also update knownSensors_
for(Sensor& known : knownSensors_)
{
if(sensor.type == known.type && sensor.id == known.id)
{
known.name = sensor.name;
known.hidden = sensor.hidden;
break; break;
} }
} }
if(!exsisting) }
sensorChangedState(sensors_[i], type);
stateChenged(sensors_);
}
inSensors = true;
break;
}
}
if(!inSensors)
{ {
sensors_.push_back(sensor); Sensor newSensor = sensor;
sensorChangedState(sensor); // Check knownSensors_ for matching sensor to override name and hidden state
for(const Sensor& known : knownSensors_)
{
if(sensor.type == known.type && sensor.id == known.id)
{
newSensor.name = known.name;
newSensor.hidden = known.hidden;
break;
}
}
sensors_.push_back(newSensor);
sensorChangedState(newSensor, type);
stateChenged(sensors_); stateChenged(sensors_);
} }

View file

@ -98,7 +98,7 @@ public:
QString::number((type == Sensor::TYPE_HUMIDITY || type == Sensor::TYPE_TEMPERATURE) ? field*10 : field) + QString::number((type == Sensor::TYPE_HUMIDITY || type == Sensor::TYPE_TEMPERATURE) ? field*10 : field) +
" TIME: " + QString::number(lastSeen.toSecsSinceEpoch()); " TIME: " + QString::number(lastSeen.toSecsSinceEpoch());
} }
inline void store(QJsonObject& json) inline void store(QJsonObject& json) const
{ {
json["Type"] = "Sensor"; json["Type"] = "Sensor";
json["SensorType"] = static_cast<int>(type); json["SensorType"] = static_cast<int>(type);
@ -127,7 +127,7 @@ public:
name = "Shutdown Imminent"; name = "Shutdown Imminent";
else name = "Sensor Type " + QString::number(type) + " Id " + QString::number(id); else name = "Sensor Type " + QString::number(type) + " Id " + QString::number(id);
} }
QString getUnit() QString getUnit() const
{ {
switch(type) switch(type)
{ {
@ -160,11 +160,19 @@ public:
} }
}; };
typedef enum {
SENSOR_UPDATE_USER = 0,
SENSOR_UPDATE_BACKEND,
SENSOR_UPDATE_REMOTE,
SENSOR_UPDATE_INVALID
} sensor_update_type_t;
class SensorStore: public QObject class SensorStore: public QObject
{ {
Q_OBJECT Q_OBJECT
private: private:
std::vector<Sensor> sensors_; std::vector<Sensor> sensors_;
std::vector<Sensor> knownSensors_;
public: public:
@ -176,15 +184,17 @@ public:
return &sensors_; return &sensors_;
} }
void store(QJsonObject& json);
void load(const QJsonObject& json);
public slots: public slots:
void sensorGotState(const Sensor& sensor); void sensorGotState(const Sensor& sensor, sensor_update_type_t type = SENSOR_UPDATE_BACKEND);
signals: signals:
void stateChenged(std::vector<Sensor> sensors); void stateChenged(std::vector<Sensor> sensors);
void sensorChangedState(Sensor sensor); void sensorChangedState(Sensor sensor, sensor_update_type_t type);
void sensorDeleted(Sensor sensor); void sensorDeleted(Sensor sensor);
}; };

View file

@ -21,5 +21,5 @@ void SunSensorSource::abort()
void SunSensorSource::doTick() void SunSensorSource::doTick()
{ {
stateChanged(Sensor(Sensor::TYPE_SUN_ALTITUDE, 0, static_cast<float>(sun_.altitude()))); stateChanged(Sensor(Sensor::TYPE_SUN_ALTITUDE, 0, static_cast<float>(sun_.altitude())), SENSOR_UPDATE_BACKEND);
} }

View file

@ -22,7 +22,7 @@ public slots:
void abort(); void abort();
signals: signals:
void stateChanged(Sensor sensor); void stateChanged(Sensor sensor, sensor_update_type_t type = SENSOR_UPDATE_BACKEND);
private slots: private slots:
void doTick(); void doTick();

View file

@ -19,7 +19,7 @@ QJsonObject Service::createMessage(const QString& type, const QJsonArray& data)
return json; return json;
} }
void Service::sensorEvent(Sensor sensor) void Service::sensorEvent(Sensor sensor, sensor_update_type_t type)
{ {
QJsonArray sensors; QJsonArray sensors;
QJsonObject sensorjson; QJsonObject sensorjson;
@ -85,7 +85,7 @@ void Service::processIncomeingJson(const QByteArray& jsonbytes)
{ {
QJsonObject jsonobject = sensorjson.toObject(); QJsonObject jsonobject = sensorjson.toObject();
Sensor sensor(jsonobject); Sensor sensor(jsonobject);
gotSensor(sensor); gotSensor(sensor, SENSOR_UPDATE_REMOTE);
} }
} }
} }

View file

@ -20,10 +20,10 @@ protected:
} client_state_t; } client_state_t;
signals: signals:
void gotSensor(Sensor sensor); void gotSensor(Sensor sensor, sensor_update_type_t type = SENSOR_UPDATE_BACKEND);
public slots: public slots:
void sensorEvent(Sensor sensor); void sensorEvent(Sensor sensor, sensor_update_type_t type);
virtual void itemUpdated(ItemUpdateRequest update); virtual void itemUpdated(ItemUpdateRequest update);
virtual void refresh() override; virtual void refresh() override;

View file

@ -219,6 +219,161 @@ private slots:
QVERIFY(audio.type == Sensor::TYPE_AUDIO_OUTPUT); QVERIFY(audio.type == Sensor::TYPE_AUDIO_OUTPUT);
} }
void testSensorStoreUserUpdateUpdatesNameAndHidden()
{
// Create a SensorStore
SensorStore store;
store.getSensors()->clear();
// Add initial sensor
Sensor initialSensor(Sensor::TYPE_TEMPERATURE, 1, 20.0, "Initial Name", false);
store.sensorGotState(initialSensor, SENSOR_UPDATE_BACKEND);
// Verify initial state
std::vector<Sensor>* sensors = store.getSensors();
QVERIFY(sensors->size() == 1);
QVERIFY(sensors->at(0).name == "Initial Name");
QVERIFY(sensors->at(0).hidden == false);
// Send USER update with new name and hidden state
Sensor userUpdate(Sensor::TYPE_TEMPERATURE, 1, 25.0, "New Name", true);
store.sensorGotState(userUpdate, SENSOR_UPDATE_USER);
// Verify name and hidden were updated
QVERIFY(sensors->size() == 1);
QVERIFY(sensors->at(0).name == "New Name");
QVERIFY(sensors->at(0).hidden == true);
QVERIFY(sensors->at(0).field == 25.0);
}
void testSensorStoreNonUserUpdateIgnoresNameAndHidden()
{
// Create a SensorStore
SensorStore store;
store.getSensors()->clear();
// Add initial sensor
Sensor initialSensor(Sensor::TYPE_TEMPERATURE, 1, 20.0, "Initial Name", false);
store.sensorGotState(initialSensor, SENSOR_UPDATE_BACKEND);
// Verify initial state
std::vector<Sensor>* sensors = store.getSensors();
QVERIFY(sensors->size() == 1);
QVERIFY(sensors->at(0).name == "Initial Name");
QVERIFY(sensors->at(0).hidden == false);
// Send BACKEND update with new name and hidden state
Sensor backendUpdate(Sensor::TYPE_TEMPERATURE, 1, 25.0, "Backend Name", true);
store.sensorGotState(backendUpdate, SENSOR_UPDATE_BACKEND);
// Verify name and hidden were NOT updated
QVERIFY(sensors->size() == 1);
QVERIFY(sensors->at(0).name == "Initial Name");
QVERIFY(sensors->at(0).hidden == false);
QVERIFY(sensors->at(0).field == 25.0);
}
void testSensorStoreUserUpdateUpdatesKnownSensors()
{
// Create a SensorStore
SensorStore store;
store.getSensors()->clear();
// Add initial sensor
Sensor initialSensor(Sensor::TYPE_TEMPERATURE, 1, 20.0, "Initial Name", false);
store.sensorGotState(initialSensor, SENSOR_UPDATE_BACKEND);
// Send USER update with new name and hidden state
Sensor userUpdate(Sensor::TYPE_TEMPERATURE, 1, 25.0, "New Name", true);
store.sensorGotState(userUpdate, SENSOR_UPDATE_USER);
// Store to JSON and reload
QJsonObject json;
store.store(json);
SensorStore store2;
store2.getSensors()->clear();
store2.load(json);
// Add the sensor again - should use the updated name from knownSensors_
Sensor newSensor(Sensor::TYPE_TEMPERATURE, 1, 30.0, "Original Name", false);
store2.sensorGotState(newSensor, SENSOR_UPDATE_BACKEND);
// Verify the name was taken from knownSensors_
std::vector<Sensor>* sensors = store2.getSensors();
QVERIFY(sensors->size() == 1);
QVERIFY(sensors->at(0).name == "New Name");
QVERIFY(sensors->at(0).hidden == true);
}
void testSensorStoreNewSensorNotInKnownSensors()
{
// Create a SensorStore
SensorStore store;
store.getSensors()->clear();
// Add a new sensor (not in knownSensors_)
Sensor newSensor(Sensor::TYPE_TEMPERATURE, 99, 25.0, "New Sensor Name", true);
store.sensorGotState(newSensor, SENSOR_UPDATE_BACKEND);
// Verify sensor was added with its original name
std::vector<Sensor>* sensors = store.getSensors();
QVERIFY(sensors->size() == 1);
QVERIFY(sensors->at(0).name == "New Sensor Name");
QVERIFY(sensors->at(0).hidden == true);
}
void testSensorStoreNewSensorInKnownSensors()
{
// Create a SensorStore
SensorStore store;
store.getSensors()->clear();
// Load known sensors
QJsonObject json;
QJsonArray sensorsArray;
QJsonObject knownSensor;
knownSensor["SensorType"] = Sensor::TYPE_TEMPERATURE;
knownSensor["Id"] = 99;
knownSensor["Name"] = "Known Sensor Name";
knownSensor["Hidden"] = true;
sensorsArray.append(knownSensor);
json["Sensors"] = sensorsArray;
store.load(json);
// Add a new sensor that matches knownSensors_
Sensor newSensor(Sensor::TYPE_TEMPERATURE, 99, 25.0, "Original Name", false);
store.sensorGotState(newSensor, SENSOR_UPDATE_BACKEND);
// Verify name was overridden from knownSensors_
std::vector<Sensor>* sensors = store.getSensors();
QVERIFY(sensors->size() == 1);
QVERIFY(sensors->at(0).name == "Known Sensor Name");
QVERIFY(sensors->at(0).hidden == true);
}
void testSensorStoreRemoteUpdateIgnored()
{
// Create a SensorStore
SensorStore store;
store.getSensors()->clear();
// Add initial sensor
Sensor initialSensor(Sensor::TYPE_TEMPERATURE, 1, 20.0, "Initial Name", false);
store.sensorGotState(initialSensor, SENSOR_UPDATE_BACKEND);
// Send REMOTE update with new name and hidden state
Sensor remoteUpdate(Sensor::TYPE_TEMPERATURE, 1, 25.0, "Remote Name", true);
store.sensorGotState(remoteUpdate, SENSOR_UPDATE_REMOTE);
// Verify name and hidden were NOT updated
std::vector<Sensor>* sensors = store.getSensors();
QVERIFY(sensors->size() == 1);
QVERIFY(sensors->at(0).name == "Initial Name");
QVERIFY(sensors->at(0).hidden == false);
QVERIFY(sensors->at(0).field == 25.0);
}
void cleanupTestCase() void cleanupTestCase()
{ {
// Cleanup after all tests // Cleanup after all tests