Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor logic for setting light state. #2553

Merged
merged 32 commits into from
Apr 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
144eb43
Update de_web_plugin.cpp
ebaauw Mar 8, 2020
803e9b2
Merge remote-tracking branch 'upstream/master'
ebaauw Mar 8, 2020
632dfd4
Update zcl_tasks.cpp
ebaauw Mar 8, 2020
61eab12
Update zcl_tasks.cpp
ebaauw Mar 8, 2020
290c68a
Merge remote-tracking branch 'upstream/master'
ebaauw Mar 8, 2020
d32c357
Update rest_lights.cpp
ebaauw Mar 8, 2020
543c9ca
Update rest_lights.cpp
ebaauw Mar 8, 2020
4576a44
Update rest_lights.cpp
ebaauw Mar 8, 2020
5582f7d
Update rest_lights.cpp
ebaauw Mar 8, 2020
80d6c6a
Merge remote-tracking branch 'upstream/master'
ebaauw Mar 8, 2020
bcb7e8a
Update zcl_tasks.cpp
ebaauw Mar 8, 2020
6697b88
Update rest_lights.cpp
ebaauw Mar 8, 2020
a493858
Update rest_lights.cpp
ebaauw Mar 8, 2020
07eda47
Merge remote-tracking branch 'upstream/master'
ebaauw Mar 10, 2020
22cda73
Update rest_lights.cpp
ebaauw Mar 13, 2020
28d3362
Update rest_node_base.cpp
ebaauw Mar 14, 2020
5ae403f
Update bindings.cpp
ebaauw Mar 14, 2020
23addf8
Update database.cpp
ebaauw Mar 14, 2020
a265877
Update de_web_plugin.cpp
ebaauw Mar 14, 2020
a3bb680
Update rest_lights.cpp
ebaauw Mar 15, 2020
2c2edb3
Update general.xml
ebaauw Mar 21, 2020
969f863
Long press for icasa Keypad Scene buttons.
ebaauw Mar 22, 2020
875e4ae
Update rest_groups.cpp
ebaauw Apr 3, 2020
0f94124
Update zcl_tasks.cpp
ebaauw Apr 3, 2020
5774d90
Update resource.cpp
ebaauw Apr 3, 2020
b224f4f
Update resource.h
ebaauw Apr 3, 2020
268c2cf
Update rest_lights.cpp
ebaauw Apr 3, 2020
b3cfeb5
Update sensor.cpp
ebaauw Apr 3, 2020
e1d2208
Update rest_sensors.cpp
ebaauw Apr 3, 2020
d537920
Merge remote-tracking branch 'upstream/master'
ebaauw Apr 3, 2020
9648c37
Update de_web_plugin.cpp
ebaauw Apr 3, 2020
12e6e86
Update sensor.cpp
ebaauw Apr 4, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 21 additions & 9 deletions bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -920,16 +920,28 @@ bool DeRestPluginPrivate::sendConfigureReportingRequest(BindingTask &bt)
{
bt.restNode->setZclValue(NodeValue::UpdateInvalid, bt.binding.srcEndpoint, bt.binding.clusterId, IAS_ZONE_CLUSTER_ATTR_ZONE_STATUS_ID, dummy);
}
rq.minInterval = 1;
rq.maxInterval = 300;

const Sensor *sensor = dynamic_cast<Sensor *>(bt.restNode);
const ResourceItem *item = sensor ? sensor->item(RConfigDuration) : nullptr;

if (item && item->toNumber() > 15 && item->toNumber() <= UINT16_MAX)
if (sensor->type() == QLatin1String("ZHAVibration") && sensor->modelId() == QLatin1String("multi")) // FIXME: check if this also applies to other Samjin sensors
// if (bt.restNode->node()->nodeDescriptor().manufacturerCode() == VENDOR_SAMJIN)
{
rq.maxInterval = static_cast<quint16>(item->toNumber());
rq.maxInterval -= 5; // report before going presence: false
// Only configure periodic reports, as events are already sent though zone status change notification commands
rq.minInterval = 300;
rq.maxInterval = 300;
}
else
{
rq.minInterval = 1;
rq.maxInterval = 300;

const ResourceItem *item = sensor ? sensor->item(RConfigDuration) : nullptr;

if (item && item->toNumber() > 15 && item->toNumber() <= UINT16_MAX)
{
rq.maxInterval = static_cast<quint16>(item->toNumber());
rq.maxInterval -= 5; // report before going presence: false
}
}

rq.dataType = deCONZ::Zcl16BitBitMap;
Expand Down Expand Up @@ -1431,23 +1443,23 @@ bool DeRestPluginPrivate::sendConfigureReportingRequest(BindingTask &bt)
rq.dataType = deCONZ::Zcl16BitInt;
rq.attributeId = 0x0012; // acceleration x
rq.minInterval = 1;
rq.maxInterval = 3600;
rq.maxInterval = 300;
rq.reportableChange16bit = 1;
rq.manufacturerCode = VENDOR_SAMJIN;

ConfigureReportingRequest rq2;
rq2.dataType = deCONZ::Zcl16BitInt;
rq2.attributeId = 0x0013; // acceleration y
rq2.minInterval = 1;
rq2.maxInterval = 3600;
rq2.maxInterval = 300;
rq2.reportableChange16bit = 1;
rq2.manufacturerCode = VENDOR_SAMJIN;

ConfigureReportingRequest rq3;
rq3.dataType = deCONZ::Zcl16BitInt;
rq3.attributeId = 0x0014; // acceleration z
rq3.minInterval = 1;
rq3.maxInterval = 3600;
rq3.maxInterval = 300;
rq3.reportableChange16bit = 1;
rq3.manufacturerCode = VENDOR_SAMJIN;

Expand Down
2 changes: 2 additions & 0 deletions database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3141,6 +3141,8 @@ static int sqliteLoadAllSensorsCallback(void *user, int ncols, char **colval , c
item = sensor.addItem(DataTypeInt16, RStateOrientationX);
item = sensor.addItem(DataTypeInt16, RStateOrientationY);
item = sensor.addItem(DataTypeInt16, RStateOrientationZ);
item = sensor.addItem(DataTypeUInt16, RConfigDuration);
item->setValue(0);
}
}
else if (sensor.type().endsWith(QLatin1String("Water")))
Expand Down
78 changes: 53 additions & 25 deletions de_web_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,8 @@ void DeRestPluginPrivate::gpProcessButtonEvent(const deCONZ::GpDataIndication &i
{
return;
}
sensor->rx();

quint32 btn = ind.gpdCommandId();
if (sensor->modelId() == QLatin1String("FOHSWITCH"))
{
Expand Down Expand Up @@ -3486,11 +3488,10 @@ void DeRestPluginPrivate::checkSensorButtonEvent(Sensor *sensor, const deCONZ::A
ok = true;
}
}
else if (ind.clusterId() == IAS_ZONE_CLUSTER_ID)
else if (ind.clusterId() == SCENE_CLUSTER_ID && zclFrame.commandId() == 0x04) // store scene
{
ok = false;
// following works for Samjin button
if (zclFrame.payload().size() == 6 && buttonMap->zclParam0 == zclFrame.payload().at(0))
ok = false; // payload: groupId, sceneId
if (zclFrame.payload().size() >= 3 && buttonMap->zclParam0 == zclFrame.payload().at(2))
{
ok = true;
}
Expand Down Expand Up @@ -3585,6 +3586,15 @@ void DeRestPluginPrivate::checkSensorButtonEvent(Sensor *sensor, const deCONZ::A
}
}
}
else if (ind.clusterId() == IAS_ZONE_CLUSTER_ID)
{
ok = false;
// following works for Samjin button
if (zclFrame.payload().size() == 6 && buttonMap->zclParam0 == zclFrame.payload().at(0))
{
ok = true;
}
}
else if (ind.clusterId() == COLOR_CLUSTER_ID &&
(zclFrame.commandId() == 0x4b && zclFrame.payload().size() >= 7) ) // move color temperature
{
Expand Down Expand Up @@ -5271,6 +5281,8 @@ void DeRestPluginPrivate::addSensorNode(const deCONZ::Node *node, const SensorFi
item = sensorNode.addItem(DataTypeInt16, RStateOrientationX);
item = sensorNode.addItem(DataTypeInt16, RStateOrientationY);
item = sensorNode.addItem(DataTypeInt16, RStateOrientationZ);
item = sensorNode.addItem(DataTypeUInt16, RConfigDuration);
item->setValue(0);
}

if (fingerPrint.hasInCluster(IAS_ZONE_CLUSTER_ID)) // POLL_CONTROL_CLUSTER_ID
Expand Down Expand Up @@ -6480,6 +6492,9 @@ void DeRestPluginPrivate::updateSensorNode(const deCONZ::NodeEvent &event)
}
else if (event.clusterId() == SAMJIN_CLUSTER_ID)
{
bool updated = false;
bool vibration = false;

for (;ia != enda; ++ia)
{
if (std::find(event.attributeIds().begin(),
Expand All @@ -6489,16 +6504,6 @@ void DeRestPluginPrivate::updateSensorNode(const deCONZ::NodeEvent &event)
continue;
}

if (ia->id() == 0x0012 || ia->id() == 0x0013 || ia->id() == 0x0014) // accelerate
{
ResourceItem *item = i->item(RStateVibration);
if (item)
{
item->setValue(true);
enqueueEvent(Event(RSensors, RStateVibration, i->id(), item));
i->durationDue = item->lastSet().addSecs(65);
}
}

if (ia->id() == 0x0012) // accelerate x
{
Expand All @@ -6513,15 +6518,14 @@ void DeRestPluginPrivate::updateSensorNode(const deCONZ::NodeEvent &event)
if (item)
{
item->setValue(ia->numericValue().s16);
updated = true;

if (item->lastSet() == item->lastChanged())
{
Event e(RSensors, item->descriptor().suffix, i->id(), item);
enqueueEvent(e);
vibration = true;
}
i->setNeedSaveDatabase(true);
i->updateStateTimestamp();
enqueueEvent(Event(RSensors, RStateLastUpdated, i->id()));
}
}
else if (ia->id() == 0x0013) // accelerate y
Expand All @@ -6537,15 +6541,14 @@ void DeRestPluginPrivate::updateSensorNode(const deCONZ::NodeEvent &event)
if (item)
{
item->setValue(ia->numericValue().s16);
updated = true;

if (item->lastSet() == item->lastChanged())
{
Event e(RSensors, item->descriptor().suffix, i->id(), item);
enqueueEvent(e);
vibration = true;
}
i->setNeedSaveDatabase(true);
i->updateStateTimestamp();
enqueueEvent(Event(RSensors, RStateLastUpdated, i->id()));
}
}
else if (ia->id() == 0x0014) // accelerate z
Expand All @@ -6561,18 +6564,42 @@ void DeRestPluginPrivate::updateSensorNode(const deCONZ::NodeEvent &event)
if (item)
{
item->setValue(ia->numericValue().s16);
updated = true;

if (item->lastSet() == item->lastChanged())
{
Event e(RSensors, item->descriptor().suffix, i->id(), item);
enqueueEvent(e);
vibration = true;
}
i->setNeedSaveDatabase(true);
i->updateStateTimestamp();
enqueueEvent(Event(RSensors, RStateLastUpdated, i->id()));
}
}
}

if (updated)
{
if (vibration)
{
{
ResourceItem *item = i->item(RStateVibration);
if (item)
{
item->setValue(true);
enqueueEvent(Event(RSensors, RStateVibration, i->id(), item));

// prepare to set vibration to false automatically
ResourceItem *item2 = i->item(RConfigDuration);
if (item2 && item2->toNumber() > 0)
{
i->durationDue = item->lastSet().addSecs(item2->toNumber());
}
}
}
}
i->setNeedSaveDatabase(true);
i->updateStateTimestamp();
enqueueEvent(Event(RSensors, RStateLastUpdated, i->id()));
}
}
else if (event.clusterId() == BASIC_CLUSTER_ID)
{
Expand Down Expand Up @@ -10640,7 +10667,8 @@ bool DeRestPluginPrivate::addTask(const TaskItem &task)
std::list<TaskItem>::iterator i = tasks.begin();
std::list<TaskItem>::iterator end = tasks.end();

if ((task.taskType != TaskGetSceneMembership) &&
if ((task.taskType != TaskSetLevel) &&
(task.taskType != TaskGetSceneMembership) &&
(task.taskType != TaskGetGroupMembership) &&
(task.taskType != TaskGetGroupIdentifiers) &&
(task.taskType != TaskStoreScene) &&
Expand All @@ -10664,7 +10692,7 @@ bool DeRestPluginPrivate::addTask(const TaskItem &task)
(i->req.asdu().size() == task.req.asdu().size()))

{
DBG_Printf(DBG_INFO, "Replace task %d type %d in queue cluster 0x%04X with newer task of same type. %u runnig tasks\n", task.taskId, task.taskType, task.req.clusterId(), runningTasks.size());
DBG_Printf(DBG_INFO, "Replace task %d type %d in queue cluster 0x%04X with newer task %d of same type. %u runnig tasks\n", i->taskId, task.taskType, task.req.clusterId(), task.taskId, runningTasks.size());
*i = task;
return true;
}
Expand Down
12 changes: 7 additions & 5 deletions general.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1076,7 +1076,9 @@ that measures a physical quantity that can take on one of a number of discrete s
<value name="Count down" value="4"></value>
<value name="Wait for more" value="5"></value>
</attribute>
<attribute id="0x0009" name="Min block request delay" type="u16" default="0" access="r" required="m"></attribute>
<attribute id="0x0007" name="Manufacturer ID" type="u16" access="r" required="o" showas="hex"></attribute>
<attribute id="0x0008" name="Image Type ID" type="u16" access="r" required="o" showas="hex"></attribute>
<attribute id="0x0009" name="Min block request delay" type="u16" default="0" access="r" required="m"></attribute>
<command id="0x01" dir="send" name="Query next image" required="m">
<description></description>
<payload>
Expand Down Expand Up @@ -2619,19 +2621,19 @@ devices can operate on either battery or mains power, and can have a wide variet
<attribute id="0x0000" type="u8" name="On" required="m" access="rw" default="0">
<description>Enable Sensor </description>
</attribute>

<attribute id="0x0001" name="X-Value" type="u16" default="0x0000" access="r" required="m" showas="dec">
<description>X-Value</description>
</attribute>

<attribute id="0x0002" name="Y-Value" type="u16" default="0x0000" access="r" required="m" showas="dec">
<description>Y-Value</description>
</attribute>

<attribute id="0x0003" name="Z-Value" type="u16" default="0x0000" access="r" required="m" showas="dec">
<description>Z-Value</description>
</attribute>

</server>
<client>
</client>
Expand Down
6 changes: 5 additions & 1 deletion resource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ const char *RAttrType = "attr/type";
const char *RAttrClass = "attr/class";
const char *RAttrUniqueId = "attr/uniqueid";
const char *RAttrSwVersion = "attr/swversion";
const char *RAttrLastAnnounce = "attr/lastannounced";
const char *RAttrLastSeen = "attr/lastseen";

const char *RActionScene = "action/scene";

Expand Down Expand Up @@ -164,6 +166,8 @@ void initResourceDescriptors()
rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeString, RAttrClass));
rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeString, RAttrUniqueId));
rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeString, RAttrSwVersion));
rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeTime, RAttrLastAnnounce));
rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeTime, RAttrLastSeen));

rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, RStateAlarm));
rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeString, RStateAlert));
Expand Down Expand Up @@ -373,7 +377,7 @@ const QString &ResourceItem::toString() const
QDateTime dt;
dt.setOffsetFromUtc(0);
dt.setMSecsSinceEpoch(m_num);
*m_str = dt.toString("yyyy-MM-ddTHH:mm:ss");
*m_str = dt.toString(m_rid.suffix == RStateLastUpdated ? "yyyy-MM-ddTHH:mm:ss.zzz" : "yyyy-MM-ddTHH:mm:ss");
}
else
{
Expand Down
2 changes: 2 additions & 0 deletions resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ extern const char *RAttrType;
extern const char *RAttrClass;
extern const char *RAttrUniqueId;
extern const char *RAttrSwVersion;
extern const char *RAttrLastAnnounce;
extern const char *RAttrLastSeen;

extern const char *RActionScene;

Expand Down
25 changes: 25 additions & 0 deletions rest_groups.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3025,11 +3025,13 @@ int DeRestPluginPrivate::modifyScene(const ApiRequest &req, ApiResponse &rsp)
uint tt = 0;
uint16_t xy_x;
uint16_t xy_y;
uint16_t ct = 0;

bool hasOn = false;
bool hasBri = false;
bool hasTt = false;
bool hasXy = false;
bool hasCt = false;

// on
if (map.contains("on"))
Expand Down Expand Up @@ -3084,6 +3086,23 @@ int DeRestPluginPrivate::modifyScene(const ApiRequest &req, ApiResponse &rsp)
}
}

if (map.contains("ct"))
{
bool ok;
ct = map["ct"].toUInt(&ok);

if (ok && map["ct"].type() == QVariant::Double && (ct < 1000))
{
hasCt = true;
}
else
{
rsp.list.append(errorToMap(ERR_INVALID_VALUE, QString("/groups/%1/scenes/%2/lights/%3/state/ct").arg(gid).arg(sid).arg(lid), QString("invalid value, %1, for parameter ct").arg(ct)));
rsp.httpStatus = HttpStatusBadRequest;
return REQ_READY_SEND;
}
}

// xy
if (map.contains("xy"))
{
Expand Down Expand Up @@ -3157,9 +3176,15 @@ int DeRestPluginPrivate::modifyScene(const ApiRequest &req, ApiResponse &rsp)
}
if (hasXy)
{
l->setColorMode(QLatin1String("xy"));
l->setX(xy_x);
l->setY(xy_y);
}
else if (hasCt)
{
l->setColorMode(QLatin1String("ct"));
l->setColorTemperature(ct);
}

if (!modifyScene(group, i->id))
{
Expand Down
Loading