parent
1a5d9ec2b9
commit
2c9d5ea4db
@ -36,7 +36,6 @@
|
|||||||
|
|
||||||
ThingGroup::ThingGroup(DeviceManager *deviceManager, DeviceClass *deviceClass, DevicesProxy *devices, QObject *parent):
|
ThingGroup::ThingGroup(DeviceManager *deviceManager, DeviceClass *deviceClass, DevicesProxy *devices, QObject *parent):
|
||||||
Device(deviceManager, deviceClass, QUuid::createUuid(), parent),
|
Device(deviceManager, deviceClass, QUuid::createUuid(), parent),
|
||||||
m_thingManager(deviceManager),
|
|
||||||
m_things(devices)
|
m_things(devices)
|
||||||
{
|
{
|
||||||
deviceClass->setParent(this);
|
deviceClass->setParent(this);
|
||||||
@ -45,7 +44,7 @@ ThingGroup::ThingGroup(DeviceManager *deviceManager, DeviceClass *deviceClass, D
|
|||||||
for (int i = 0; i < deviceClass->stateTypes()->rowCount(); i++) {
|
for (int i = 0; i < deviceClass->stateTypes()->rowCount(); i++) {
|
||||||
StateType *st = deviceClass->stateTypes()->get(i);
|
StateType *st = deviceClass->stateTypes()->get(i);
|
||||||
State *state = new State(id(), st->id(), QVariant(), this);
|
State *state = new State(id(), st->id(), QVariant(), this);
|
||||||
qDebug() << "Adding state" << st->name();
|
qDebug() << "Adding state" << st->name() << st->minValue() << st->maxValue();
|
||||||
states->addState(state);
|
states->addState(state);
|
||||||
}
|
}
|
||||||
setStates(states);
|
setStates(states);
|
||||||
@ -56,14 +55,15 @@ ThingGroup::ThingGroup(DeviceManager *deviceManager, DeviceClass *deviceClass, D
|
|||||||
syncStates();
|
syncStates();
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(m_thingManager, &DeviceManager::executeActionReply, this, [this](int commandId, const QVariantMap &/*params*/){
|
connect(m_thingManager, &DeviceManager::executeActionReply, this, [this](int commandId, const QVariantMap ¶ms){
|
||||||
// This should maybe check the params and only emit NoError if there is at least one thing that returned without error?
|
// This should maybe check the params and create a sensible group result instead of just forwarding the result of the last reply
|
||||||
foreach (int id, m_pendingActions.keys()) {
|
qDebug() << "action reply:" << commandId;
|
||||||
if (m_pendingActions.value(id).contains(commandId)) {
|
foreach (int id, m_pendingGroupActions.keys()) {
|
||||||
m_pendingActions[id].removeAll(commandId);
|
if (m_pendingGroupActions.value(id).contains(commandId)) {
|
||||||
if (m_pendingActions[id].isEmpty()) {
|
m_pendingGroupActions[id].removeAll(commandId);
|
||||||
m_pendingActions.remove(id);
|
if (m_pendingGroupActions[id].isEmpty()) {
|
||||||
emit actionExecutionFinished(id, "DeviceErrorNoError");
|
m_pendingGroupActions.remove(id);
|
||||||
|
emit executeActionReply(id, params);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -76,35 +76,51 @@ int ThingGroup::executeAction(const QString &actionName, const QVariantList &par
|
|||||||
{
|
{
|
||||||
QList<int> pendingIds;
|
QList<int> pendingIds;
|
||||||
|
|
||||||
|
ActionType *groupActionType = m_thingClass->actionTypes()->findByName(actionName);
|
||||||
|
if (!groupActionType) {
|
||||||
|
qWarning() << "Group has no action" << actionName;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
qDebug() << "Execute action for group:" << this;
|
qDebug() << "Execute action for group:" << this;
|
||||||
for (int i = 0; i < m_things->rowCount(); i++) {
|
for (int i = 0; i < m_things->rowCount(); i++) {
|
||||||
Device *device = m_things->get(i);
|
Device *thing = m_things->get(i);
|
||||||
if (device->setupStatus() != Device::ThingSetupStatusComplete) {
|
if (thing->setupStatus() != Device::ThingSetupStatusComplete) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ActionType *actionType = device->thingClass()->actionTypes()->findByName(actionName);
|
ActionType *actionType = thing->thingClass()->actionTypes()->findByName(actionName);
|
||||||
if (!actionType) {
|
if (!actionType) {
|
||||||
|
qWarning() << "Cannot send action to thing" << thing->name() << "because according action can't be found";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QVariantList finalParams;
|
QVariantList finalParams;
|
||||||
foreach (const QVariant ¶mVariant, params) {
|
foreach (const QVariant ¶mVariant, params) {
|
||||||
ParamType *paramType = actionType->paramTypes()->findByName(paramVariant.toMap().value("paramName").toString());
|
QString paramName = paramVariant.toMap().value("paramName").toString();
|
||||||
if (paramType) {
|
ParamType *groupParamType = groupActionType->paramTypes()->findByName(paramName);
|
||||||
QVariantMap finalParam;
|
if (!groupParamType) {
|
||||||
finalParam.insert("paramTypeId", paramType->id());
|
qWarning() << "Not adding param" << paramName << "to action" << actionName << "because group action param can't be found";
|
||||||
finalParam.insert("value", paramVariant.toMap().value("value"));
|
continue;
|
||||||
finalParams.append(finalParam);
|
|
||||||
}
|
}
|
||||||
|
ParamType *paramType = actionType->paramTypes()->findByName(paramName);
|
||||||
|
if (!paramType) {
|
||||||
|
qWarning() << "Not adding param" << paramName << "to action" << actionName << "because according action params can't be found";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantMap finalParam;
|
||||||
|
finalParam.insert("paramTypeId", paramType->id());
|
||||||
|
finalParam.insert("value", mapValue(paramVariant.toMap().value("value"), groupParamType, paramType));
|
||||||
|
finalParams.append(finalParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "Initial params" << params;
|
qDebug() << "Initial params" << params;
|
||||||
qDebug() << "Executing" << device->id() << actionType->name() << finalParams;
|
qDebug() << "Executing" << thing->id() << actionType->name() << finalParams;
|
||||||
int id = m_thingManager->executeAction(device->id(), actionType->id(), finalParams);
|
int id = m_thingManager->executeAction(thing->id(), actionType->id(), finalParams);
|
||||||
pendingIds.append(id);
|
pendingIds.append(id);
|
||||||
}
|
}
|
||||||
m_pendingActions.insert(++m_idCounter, pendingIds);
|
m_pendingGroupActions.insert(++m_idCounter, pendingIds);
|
||||||
return m_idCounter;
|
return m_idCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +130,7 @@ void ThingGroup::syncStates()
|
|||||||
StateType *stateType = thingClass()->stateTypes()->get(i);
|
StateType *stateType = thingClass()->stateTypes()->get(i);
|
||||||
State *state = states()->getState(stateType->id());
|
State *state = states()->getState(stateType->id());
|
||||||
|
|
||||||
qDebug() << "syncing state" << stateType->name();
|
qDebug() << "syncing state" << stateType->name() << stateType->type();
|
||||||
|
|
||||||
QVariant value;
|
QVariant value;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@ -142,6 +158,9 @@ void ThingGroup::syncStates()
|
|||||||
} else if (stateType->type().toLower() == "int") {
|
} else if (stateType->type().toLower() == "int") {
|
||||||
value = value.toInt() + d->stateValue(ds->id()).toInt();
|
value = value.toInt() + d->stateValue(ds->id()).toInt();
|
||||||
count++;
|
count++;
|
||||||
|
} else if (stateType->type().toLower() == "qcolor") {
|
||||||
|
value = d->stateValue(ds->id());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
@ -150,3 +169,23 @@ void ThingGroup::syncStates()
|
|||||||
state->setValue(value);
|
state->setValue(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariant ThingGroup::mapValue(const QVariant &value, ParamType *fromParamType, ParamType *toParamType) const
|
||||||
|
{
|
||||||
|
qDebug() << "Mapping:" << value << fromParamType->minValue() << fromParamType->maxValue() << toParamType->minValue() << toParamType->maxValue();
|
||||||
|
|
||||||
|
if (!fromParamType->minValue().isValid()
|
||||||
|
|| !fromParamType->maxValue().isValid()
|
||||||
|
|| !toParamType->minValue().isValid()
|
||||||
|
|| !toParamType->maxValue().isValid()) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
double fromMin = fromParamType->minValue().toDouble();
|
||||||
|
double fromMax = fromParamType->maxValue().toDouble();
|
||||||
|
double toMin = toParamType->minValue().toDouble();
|
||||||
|
double toMax = toParamType->maxValue().toDouble();
|
||||||
|
double fromValue = value.toDouble();
|
||||||
|
double fromPercent = (fromValue - fromMin) / (fromMax - fromMin);
|
||||||
|
double toValue = toMin + (toMax - toMin) * fromPercent;
|
||||||
|
return toValue;
|
||||||
|
}
|
||||||
|
|||||||
@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
class DevicesProxy;
|
class DevicesProxy;
|
||||||
class DeviceManager;
|
class DeviceManager;
|
||||||
|
class ParamType;
|
||||||
|
|
||||||
class ThingGroup : public Device
|
class ThingGroup : public Device
|
||||||
{
|
{
|
||||||
@ -49,15 +50,13 @@ public:
|
|||||||
private:
|
private:
|
||||||
void syncStates();
|
void syncStates();
|
||||||
|
|
||||||
signals:
|
QVariant mapValue(const QVariant &value, ParamType *fromParamType, ParamType *toParamType) const;
|
||||||
void actionExecutionFinished(int id, const QString &status);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DeviceManager* m_thingManager = nullptr;
|
|
||||||
DevicesProxy* m_things = nullptr;
|
DevicesProxy* m_things = nullptr;
|
||||||
|
|
||||||
int m_idCounter = 0;
|
int m_idCounter = 0;
|
||||||
QHash<int, QList<int>> m_pendingActions;
|
QHash<int, QList<int>> m_pendingGroupActions;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // THINGGROUP_H
|
#endif // THINGGROUP_H
|
||||||
|
|||||||
@ -40,6 +40,12 @@ Device::Device(DeviceManager *thingManager, DeviceClass *thingClass, const QUuid
|
|||||||
m_parentId(parentId),
|
m_parentId(parentId),
|
||||||
m_thingClass(thingClass)
|
m_thingClass(thingClass)
|
||||||
{
|
{
|
||||||
|
connect(thingManager, &DeviceManager::executeActionReply, this, [=](int commandId, const QVariantMap ¶ms){
|
||||||
|
if (m_pendingActions.contains(commandId)) {
|
||||||
|
m_pendingActions.removeAll(commandId);
|
||||||
|
emit executeActionReply(commandId, params);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Device::name() const
|
QString Device::name() const
|
||||||
@ -229,7 +235,9 @@ int Device::executeAction(const QString &actionName, const QVariantList ¶ms)
|
|||||||
}
|
}
|
||||||
finalParams.append(param);
|
finalParams.append(param);
|
||||||
}
|
}
|
||||||
return m_thingManager->executeAction(m_id, actionType->id(), finalParams);
|
int commandId = m_thingManager->executeAction(m_id, actionType->id(), finalParams);
|
||||||
|
m_pendingActions.append(commandId);
|
||||||
|
return commandId;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDebug operator<<(QDebug &dbg, Device *thing)
|
QDebug operator<<(QDebug &dbg, Device *thing)
|
||||||
|
|||||||
@ -114,6 +114,9 @@ signals:
|
|||||||
void statesChanged();
|
void statesChanged();
|
||||||
void eventTriggered(const QUuid &eventTypeId, const QVariantMap ¶ms);
|
void eventTriggered(const QUuid &eventTypeId, const QVariantMap ¶ms);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void executeActionReply(int commandId, const QVariantMap ¶ms);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DeviceManager *m_thingManager = nullptr;
|
DeviceManager *m_thingManager = nullptr;
|
||||||
QString m_name;
|
QString m_name;
|
||||||
@ -125,6 +128,8 @@ protected:
|
|||||||
Params *m_settings = nullptr;
|
Params *m_settings = nullptr;
|
||||||
States *m_states = nullptr;
|
States *m_states = nullptr;
|
||||||
DeviceClass *m_thingClass = nullptr;
|
DeviceClass *m_thingClass = nullptr;
|
||||||
|
|
||||||
|
QList<int> m_pendingActions;
|
||||||
};
|
};
|
||||||
|
|
||||||
QDebug operator<<(QDebug &dbg, Device* thing);
|
QDebug operator<<(QDebug &dbg, Device* thing);
|
||||||
|
|||||||
@ -417,7 +417,7 @@ void Interfaces::addStateType(const QString &interfaceName, const QString &name,
|
|||||||
st->setMinValue(min);
|
st->setMinValue(min);
|
||||||
st->setMaxValue(max);
|
st->setMaxValue(max);
|
||||||
iface->stateTypes()->addStateType(st);
|
iface->stateTypes()->addStateType(st);
|
||||||
ParamTypes *pts = createParamTypes(name, displayName, type);
|
ParamTypes *pts = createParamTypes(name, displayName, type, QVariant(), min, max);
|
||||||
addEventType(interfaceName, name, displayNameEvent, pts);
|
addEventType(interfaceName, name, displayNameEvent, pts);
|
||||||
if (writable) {
|
if (writable) {
|
||||||
addActionType(interfaceName, name, displayNameAction, pts);
|
addActionType(interfaceName, name, displayNameAction, pts);
|
||||||
|
|||||||
@ -200,11 +200,10 @@ MainPageTile {
|
|||||||
onClicked: {
|
onClicked: {
|
||||||
switch (iface.name) {
|
switch (iface.name) {
|
||||||
case "light":
|
case "light":
|
||||||
var group = engine.deviceManager.createGroup(Interfaces.findByName("colorlight"), devicesProxy);
|
var group = engine.thingManager.createGroup(Interfaces.findByName("colorlight"), devicesProxy);
|
||||||
print("opening lights page for group", group)
|
print("opening lights page for group", group)
|
||||||
pageStack.push("../devicepages/LightDevicePage.qml", {device: group})
|
pageStack.push("../devicepages/LightDevicePage.qml", {thing: group})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -118,16 +118,16 @@ DevicePageBase {
|
|||||||
var absoluteCtValue = (model.ct * (root.ctStateType.maxValue - root.ctStateType.minValue) / 100) + root.ctStateType.minValue
|
var absoluteCtValue = (model.ct * (root.ctStateType.maxValue - root.ctStateType.minValue) / 100) + root.ctStateType.minValue
|
||||||
var params = [];
|
var params = [];
|
||||||
var param1 = {};
|
var param1 = {};
|
||||||
param1["paramTypeId"] = root.ctActionType.paramTypes.get(0).id;
|
param1["paramName"] = root.ctActionType.paramTypes.get(0).name;
|
||||||
param1["value"] = absoluteCtValue;
|
param1["value"] = absoluteCtValue;
|
||||||
params.push(param1)
|
params.push(param1)
|
||||||
engine.deviceManager.executeAction(root.device.id, root.ctActionType.id, params)
|
root.thing.executeAction(root.ctActionType.name, params)
|
||||||
params = [];
|
params = [];
|
||||||
param1 = {};
|
param1 = {};
|
||||||
param1["paramTypeId"] = root.brightnessActionType.paramTypes.get(0).id;
|
param1["paramName"] = root.brightnessActionType.paramTypes.get(0).name;
|
||||||
param1["value"] = model.bri;
|
param1["value"] = model.bri;
|
||||||
params.push(param1)
|
params.push(param1)
|
||||||
engine.deviceManager.executeAction(root.device.id, root.brightnessActionType.id, params)
|
root.thing.executeAction(root.brightnessActionType.name, params)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -176,7 +176,7 @@ DevicePageBase {
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
engine.thingManager.executeAction(root.thing.id, root.powerStateType.id, [{paramTypeId: root.powerStateType.id, value: !root.powerState.value}])
|
root.thing.executeAction("power", [{paramName: "power", value: !root.powerState.value}])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,10 +16,9 @@ Item {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
d.pendingValue = value;
|
d.pendingValue = value;
|
||||||
d.pendingCommand = engine.thingManager.executeAction(root.thing.id,
|
d.pendingCommand = root.thing.executeAction(root.stateType.name,
|
||||||
root.stateType.id,
|
|
||||||
[{
|
[{
|
||||||
paramTypeId: root.stateType.id,
|
paramName: root.stateType.name,
|
||||||
value: value
|
value: value
|
||||||
}])
|
}])
|
||||||
d.queuedValue = null
|
d.queuedValue = null
|
||||||
@ -33,7 +32,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: engine.thingManager
|
target: root.thing
|
||||||
onExecuteActionReply: {
|
onExecuteActionReply: {
|
||||||
if (d.pendingCommand == commandId) {
|
if (d.pendingCommand == commandId) {
|
||||||
d.pendingCommand = -1;
|
d.pendingCommand = -1;
|
||||||
|
|||||||
Reference in New Issue
Block a user