Skip to content

Commit

Permalink
Add an actual group address for "group 0" instead of special-casing i…
Browse files Browse the repository at this point in the history
…t and use that for group 0/All.

- a group address of 0 actually works for Ikea and Osram lights, but not for Philips
- finds a free group-address from 65520 downwards, 65535 does not work for Osram
- add all lights when found after database load or after light search
- remove all special cases and use "regular" groupcast
  • Loading branch information
KodeCR authored and manup committed Jun 10, 2019
1 parent c6cf447 commit 590a8f1
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 40 deletions.
13 changes: 13 additions & 0 deletions database.cpp
Expand Up @@ -1040,6 +1040,18 @@ static int sqliteLoadConfigCallback(void *user, int ncols, char **colval , char
}
}
}
else if (strcmp(colval[0], "group0") == 0)
{
if (!val.isEmpty())
{
uint group0 = val.toUInt(&ok);
if (ok && (group0 <= 65535))
{
d->gwGroup0 = group0;
d->gwConfig["group0"] = (uint16_t)group0;
}
}
}
else if (strcmp(colval[0], "updatechannel") == 0)
{
if ((val == "stable") || (val == "alpha") || (val == "beta"))
Expand Down Expand Up @@ -3993,6 +4005,7 @@ void DeRestPluginPrivate::saveDb()
gwConfig["announceurl"] = gwAnnounceUrl;
gwConfig["groupdelay"] = gwGroupSendDelay;
gwConfig["zigbeechannel"] = gwZigbeeChannel;
gwConfig["group0"] = gwGroup0;
gwConfig["gwusername"] = gwAdminUserName;
gwConfig["gwpassword"] = gwAdminPasswordHash;
gwConfig["homebridge"] = gwHomebridge;
Expand Down
70 changes: 44 additions & 26 deletions de_web_plugin.cpp
Expand Up @@ -336,10 +336,31 @@ DeRestPluginPrivate::DeRestPluginPrivate(QObject *parent) :
}

// create default group
Group group;
group.setAddress(0);
group.setName("All");
groups.push_back(group);
if (gwGroup0 == 0) { // get new id and replace old group0 and get new id
for (uint16_t i = 0xFFF0; i > 0; i--) // 0 and larger than 0xfff7 is not valid for Osram Lightify
{
Group* group = getGroupForId(i);
if (!group) {
gwGroup0 = i;
// delete old group 0
Group* group = getGroupForId(0);
if (group)
{
group->setState(Group::StateDeleted);
}
queSaveDb(DB_CONFIG | DB_GROUPS, DB_LONG_SAVE_DELAY);
break;
}
}
}
Group* group = getGroupForId(gwGroup0);
if (!group) { // new default group
Group group;
group.setAddress(gwGroup0);
group.setName("All");
groups.push_back(group);
queSaveDb(DB_GROUPS, DB_LONG_SAVE_DELAY);
}

connect(apsCtrl, SIGNAL(apsdeDataConfirm(const deCONZ::ApsDataConfirm&)),
this, SLOT(apsdeDataConfirm(const deCONZ::ApsDataConfirm&)));
Expand Down Expand Up @@ -1697,6 +1718,16 @@ void DeRestPluginPrivate::addLightNode(const deCONZ::Node *node)
{ q->nodeUpdated(lightNode.address().ext(), QLatin1String("modelid"), lightNode.modelId()); }
}

// add light node to default group
GroupInfo *groupInfo = getGroupInfo(&lightNode, gwGroup0);
if (!groupInfo)
{
groupInfo = createGroupInfo(&lightNode, gwGroup0);
lightNode.setNeedSaveDatabase(true);
groupInfo->actions &= ~GroupInfo::ActionRemoveFromGroup; // sanity
groupInfo->actions |= GroupInfo::ActionAddToGroup;
}

// force reading attributes
lightNode.enableRead(READ_VENDOR_NAME |
READ_MODEL_ID |
Expand Down Expand Up @@ -6763,12 +6794,14 @@ Sensor *DeRestPluginPrivate::getSensorNodeForId(const QString &id)
*/
Group *DeRestPluginPrivate::getGroupForId(uint16_t id)
{
uint16_t gid = id ? id : gwGroup0;

std::vector<Group>::iterator i = groups.begin();
std::vector<Group>::iterator end = groups.end();

for (; i != end; ++i)
{
if (i->address() == id)
if (i->address() == gid)
{
return &(*i);
}
Expand Down Expand Up @@ -6842,13 +6875,17 @@ Group *DeRestPluginPrivate::getGroupForId(const QString &id)
DBG_Printf(DBG_INFO, "Get group for id error: invalid group id %s\n", qPrintable(id));
return 0;
}
if (gid == 0)
{
gid = gwGroup0;
}

std::vector<Group>::iterator i = groups.begin();
std::vector<Group>::iterator end = groups.end();

for (; i != end; ++i)
{
if (i->id() == id)
if (i->address() == gid)
{
return &(*i);
}
Expand Down Expand Up @@ -8071,10 +8108,6 @@ bool DeRestPluginPrivate::isLightNodeInGroup(const LightNode *lightNode, uint16_

if (lightNode)
{
if (groupId == 0)
{
return true; // global group
}
std::vector<GroupInfo>::const_iterator i = lightNode->groups().begin();
std::vector<GroupInfo>::const_iterator end = lightNode->groups().end();

Expand Down Expand Up @@ -12228,7 +12261,7 @@ void DeRestPluginPrivate::taskToLocalData(const TaskItem &task)
for (; i != end; ++i)
{
LightNode *lightNode = &(*i);
if (isLightNodeInGroup(lightNode, task.req.dstAddress().group()) || group->id() == "0")
if (isLightNodeInGroup(lightNode, task.req.dstAddress().group()))
{
pushNodes.push_back(lightNode);
}
Expand Down Expand Up @@ -12262,21 +12295,6 @@ void DeRestPluginPrivate::taskToLocalData(const TaskItem &task)
updateEtag(group->etag);
group->setIsOn(task.onOff);

if (!task.lightNode && group->id() == "0")
{
std::vector<Group>::iterator g = groups.begin();
std::vector<Group>::iterator gend = groups.end();

for (; g != gend; ++g)
{
if (g->state() != Group::StateDeleted && g->state() != Group::StateDeleteFromDB)
{
updateEtag(g->etag);
g->setIsOn(task.onOff);
}
}
}

break;

case TaskSetLevel:
Expand Down
1 change: 1 addition & 0 deletions de_web_plugin_private.h
Expand Up @@ -1441,6 +1441,7 @@ public Q_SLOTS:
QString gwUpdateChannel;
int gwGroupSendDelay;
uint gwZigbeeChannel;
uint16_t gwGroup0;
QVariantMap gwConfig;
QString gwSensorsEtag;
QString gwLightsEtag;
Expand Down
1 change: 1 addition & 0 deletions rest_configuration.cpp
Expand Up @@ -79,6 +79,7 @@ void DeRestPluginPrivate::initConfig()
gwRgbwDisplay = "1";
gwTimeFormat = "12h";
gwZigbeeChannel = 0;
gwGroup0 = 0;
gwName = GW_DEFAULT_NAME;
gwUpdateVersion = GW_SW_VERSION; // will be replaced by discovery handler
{
Expand Down
18 changes: 4 additions & 14 deletions rest_groups.cpp
Expand Up @@ -137,7 +137,7 @@ int DeRestPluginPrivate::getAllGroups(const ApiRequest &req, ApiResponse &rsp)
continue;
}

if (i->address() != 0) // don't return special group 0
if (i->address() != gwGroup0) // don't return special group 0
{
QVariantMap mnode;
groupToMap(req, &(*i), mnode);
Expand Down Expand Up @@ -750,18 +750,8 @@ int DeRestPluginPrivate::setGroupState(const ApiRequest &req, ApiResponse &rsp)
rsp.httpStatus = HttpStatusOk;

// set destination parameters
if (id == "0")
{
// use a broadcast
taskRef.req.dstAddress().setNwk(deCONZ::BroadcastRouters);
taskRef.req.dstAddress().setGroup(0); // taskToLocal() needs this
taskRef.req.setDstAddressMode(deCONZ::ApsNwkAddress);
}
else
{
taskRef.req.dstAddress().setGroup(group->address());
taskRef.req.setDstAddressMode(deCONZ::ApsGroupAddress);
}
taskRef.req.dstAddress().setGroup(group->address());
taskRef.req.setDstAddressMode(deCONZ::ApsGroupAddress);
taskRef.req.setDstEndpoint(0xFF); // broadcast endpoint
taskRef.req.setSrcEndpoint(getSrcEndpoint(0, taskRef.req));

Expand Down Expand Up @@ -1729,7 +1719,7 @@ int DeRestPluginPrivate::deleteGroup(const ApiRequest &req, ApiResponse &rsp)

userActivity();

if (!group || (group->state() == Group::StateDeleted))
if (!group || (group->state() == Group::StateDeleted) || (group->address() == gwGroup0))
{
rsp.httpStatus = HttpStatusNotFound;
rsp.list.append(errorToMap(ERR_RESOURCE_NOT_AVAILABLE, QString("/groups/%1").arg(id), QString("resource, /groups/%1, not available").arg(id)));
Expand Down

0 comments on commit 590a8f1

Please sign in to comment.