Compare commits

..

2 commits

10 changed files with 78 additions and 15 deletions

View file

@ -67,6 +67,8 @@ void ItemData::storeWithChanges(QJsonObject& json, const ItemFieldChanges& chang
valueNamesArray.append(name);
json["ValueNames"] = valueNamesArray;
}
if(changes.override)
json["override"] = override_;
}
void ItemData::load(const QJsonObject &json, const bool preserve)
@ -107,6 +109,11 @@ ItemFieldChanges ItemData::loadWithChanges(const QJsonObject& json, const bool p
valueNames_.push_back(valueNamesArray[i].toString());
changes.valueNames = true;
}
if(json.contains("override"))
{
override_ = json["override"].toBool(false);
changes.override = true;
}
itemId_ = static_cast<uint32_t>(json["ItemId"].toDouble(0));
}
return changes;
@ -142,6 +149,8 @@ bool ItemData::hasChanged(const ItemData& other, const ItemFieldChanges& changes
return true;
if(changes.valueNames && other.getValueNames() != getValueNames())
return true;
if(changes.override && other.getOverride() != getOverride())
return true;
return false;
}
@ -197,6 +206,16 @@ QString ItemData::indexToValueName(int index) const
return QString();
}
bool ItemData::getOverride() const
{
return override_;
}
void ItemData::setOverride(bool overrideVal)
{
override_ = overrideVal;
}
//item
Item::Item(uint32_t itemIdIn, QString name, uint8_t value, QObject *parent): QObject(parent), ItemData (itemIdIn, name,
@ -217,7 +236,6 @@ Item::~Item()
void Item::store(QJsonObject &json)
{
ItemData::store(json);
json["override"] = override_;
if(!actors_.empty())
{
QJsonArray actorsArray;
@ -237,7 +255,6 @@ void Item::store(QJsonObject &json)
void Item::load(const QJsonObject &json, const bool preserve)
{
ItemData::load(json, preserve);
override_ = json["override"].toBool(false);
if(json.contains("Actors"))
{
const QJsonArray actorsArray(json["Actors"].toArray(QJsonArray()));
@ -306,6 +323,8 @@ void Item::requestUpdate(ItemUpdateRequest update)
}
if(update.changes.valueNames)
valueNames_ = update.payload.getValueNames();
if(update.changes.override)
override_ = update.payload.getOverride();
update.payload = *this;
updated(update);
}
@ -351,12 +370,12 @@ bool Item::removeActor(std::shared_ptr<Actor> actor)
void Item::setOverride(const bool in)
{
override_ = in;
ItemData::setOverride(in);
}
bool Item::getOverride()
{
return override_;
return ItemData::getOverride();
}
void Item::removeAllActors()

View file

@ -38,6 +38,7 @@ protected:
item_value_type_t type_;
QString groupName_;
std::vector<QString> valueNames_;
bool override_ = false;
public:
ItemData(uint32_t itemIdIn = QRandomGenerator::global()->generate(),
@ -78,6 +79,8 @@ public:
void storeWithChanges(QJsonObject& json, const ItemFieldChanges& changes);
ItemFieldChanges loadWithChanges(const QJsonObject& json, const bool preserve = false);
virtual QString getName() const;
bool getOverride() const;
void setOverride(bool overrideVal);
virtual void store(QJsonObject& json);
virtual void load(const QJsonObject& json, const bool preserve = false);
};
@ -87,7 +90,6 @@ class Item: public QObject, public ItemData
Q_OBJECT
private:
std::vector< std::shared_ptr<Actor> > actors_;
bool override_ = false;
signals:
void updated(ItemUpdateRequest update);
@ -135,6 +137,7 @@ struct ItemFieldChanges
bool groupName :1;
bool actors :1;
bool valueNames :1;
bool override :1;
ItemFieldChanges(bool defaultVal = false)
{
name = defaultVal;
@ -144,10 +147,11 @@ struct ItemFieldChanges
groupName = defaultVal;
actors = false;
valueNames = defaultVal;
override = defaultVal;
}
inline bool isNone() const
{
return !name && !value && !hidden && !type && !groupName && !actors && !valueNames;
return !name && !value && !hidden && !type && !groupName && !actors && !valueNames && !override;
}
};

View file

@ -165,6 +165,7 @@ SecondaryMainObject::SecondaryMainObject(QString host, int port, QObject *parent
{
connect(tcpClient, &TcpClient::gotSensor, &globalSensors, &SensorStore::sensorGotState);
globalItems.registerItemSource(tcpClient);
connect(&globalSensors, &SensorStore::sensorChangedState, tcpClient, &TcpClient::sensorEvent);
if(!tcpClient->launch(QHostAddress(host), port))
{

View file

@ -89,6 +89,31 @@ void SensorStore::sensorGotState(const Sensor& sensor, sensor_update_type_t type
needsUpdate = true;
}
}
else if(type == SENSOR_UPDATE_REMOTE)
{
if(sensors_[i].name != sensor.name || sensors_[i].hidden != sensor.hidden || sensors_[i].groupName != sensor.groupName)
{
sensors_[i].name = sensor.name;
sensors_[i].hidden = sensor.hidden;
sensors_[i].groupName = sensor.groupName;
for(Sensor& known : knownSensors_)
{
if(sensor.type == known.type && sensor.id == known.id)
{
known.name = sensor.name;
known.hidden = sensor.hidden;
known.groupName = sensor.groupName;
break;
}
}
needsUpdate = true;
}
if(sensors_[i].field != sensor.field)
{
needsUpdate = true;
sensors_[i].field = sensor.field;
}
}
else if(sensors_[i].field != sensor.field)
{
needsUpdate = true;

View file

@ -24,7 +24,7 @@ signals:
void sensorAdded(Sensor sensor, Sensor::sensor_backend_type_t backend, QJsonObject payload);
public slots:
void sensorEvent(Sensor sensor, sensor_update_type_t type);
virtual void sensorEvent(Sensor sensor, sensor_update_type_t type);
virtual void itemUpdated(ItemUpdateRequest update);
virtual void refresh() override;
virtual void addSensor(Sensor sensor, Sensor::sensor_backend_type_t backend, QJsonObject payload = {});

View file

@ -128,6 +128,16 @@ void TcpClient::itemUpdated(ItemUpdateRequest update)
}
}
void TcpClient::sensorEvent(Sensor sensor, sensor_update_type_t type)
{
// Only forward user-initiated sensor updates to the server
// to prevent feedback loops with backend/remote updates
if(type == SENSOR_UPDATE_USER)
{
Service::sensorEvent(sensor, type);
}
}
TcpClient::~TcpClient()
{
delete socket;

View file

@ -18,6 +18,7 @@ class TcpClient : public Service
public slots:
virtual void itemUpdated(ItemUpdateRequest update) override;
virtual void sensorEvent(Sensor sensor, sensor_update_type_t type) override;
public:
TcpClient(QObject* parent = nullptr);

View file

@ -96,7 +96,10 @@ void ItemSettingsDialog::changeGroup()
void ItemSettingsDialog::changeOverride()
{
item_->setOverride(ui->checkBox_Override->isChecked());
ItemUpdateRequest update = item_->createValueUpdateRequest(ITEM_UPDATE_USER);
update.payload.setOverride(ui->checkBox_Override->isChecked());
update.changes.override = true;
item_->requestUpdate(update);
}
void ItemSettingsDialog::loadActorList()

View file

@ -37,7 +37,7 @@ void SensorListWidget::onDoubleClick(QTreeWidgetItem *item, int column)
{
if(item && item->type() == 1001)
{
const Sensor& sensor = getSensorForIndex(currentIndex());
const Sensor& sensor = static_cast<SensorListItem*>(item)->getSensor();
SensorSettingsDialog diag(sensor, this);
if(diag.exec())
{

View file

@ -362,16 +362,16 @@ private slots:
// 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
// Send REMOTE update with new name and hidden state (e.g., from secondary instance)
Sensor remoteUpdate(Sensor::TYPE_TEMPERATURE, 1, 25.0, "Remote Name", true);
store.sensorGotState(remoteUpdate, SENSOR_UPDATE_REMOTE);
// Verify name and hidden were NOT updated
// Verify name, hidden and field were updated (remote updates should sync user-configurable fields)
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).name == "Remote Name");
QVERIFY(sensors->at(0).hidden == true);
QVERIFY(sensors->at(0).field == 25.0);
}