diff --git a/database.cpp b/database.cpp index ddffb7ef13..4b6cffebb9 100644 --- a/database.cpp +++ b/database.cpp @@ -2979,8 +2979,8 @@ static int sqliteLoadAllSensorsCallback(void *user, int ncols, char **colval , c item->setValue(0); item = sensor.addItem(DataTypeInt16, RConfigOffset); item->setValue(0); - sensor.addItem(DataTypeInt16, RStateHeating); // Heating set point - sensor.addItem(DataTypeBool, RStateSchedulerOn); // Scheduler state on/off + sensor.addItem(DataTypeInt16, RConfigHeating); // Heating set point + sensor.addItem(DataTypeBool, RConfigSchedulerOn); // Scheduler state on/off sensor.addItem(DataTypeBool, RStateOn); // Heating on/off sensor.addItem(DataTypeString, RConfigScheduler); // Scheduler setting } diff --git a/de_web_plugin.cpp b/de_web_plugin.cpp index 37d211e72d..9bcdb9b6c5 100644 --- a/de_web_plugin.cpp +++ b/de_web_plugin.cpp @@ -3978,8 +3978,8 @@ void DeRestPluginPrivate::addSensorNode(const deCONZ::Node *node, const SensorFi sensorNode.addItem(DataTypeInt16, RStateTemperature); item = sensorNode.addItem(DataTypeInt16, RConfigOffset); item->setValue(0); - sensorNode.addItem(DataTypeInt16, RStateHeating); // Heating set point - sensorNode.addItem(DataTypeBool, RStateSchedulerOn); // Scheduler state on/off + sensorNode.addItem(DataTypeInt16, RConfigHeating); // Heating set point + sensorNode.addItem(DataTypeBool, RConfigSchedulerOn); // Scheduler state on/off sensorNode.addItem(DataTypeBool, RStateOn); // Heating on/off sensorNode.addItem(DataTypeString, RConfigScheduler); // Scheduler setting } diff --git a/resource.cpp b/resource.cpp index f58db9efeb..ed925f7bb2 100644 --- a/resource.cpp +++ b/resource.cpp @@ -50,7 +50,6 @@ const char *RStateDaylight = "state/daylight"; const char *RStateEffect = "state/effect"; const char *RStateFire = "state/fire"; const char *RStateFlag = "state/flag"; -const char *RStateHeating = "state/heatsetpoint"; const char *RStateHue = "state/hue"; const char *RStateHumidity = "state/humidity"; const char *RStateLastUpdated = "state/lastupdated"; @@ -64,7 +63,6 @@ const char *RStatePressure = "state/pressure"; const char *RStatePower = "state/power"; const char *RStateReachable = "state/reachable"; const char *RStateSat = "state/sat"; -const char *RStateSchedulerOn = "state/scheduleron"; const char *RStateStatus = "state/status"; const char *RStateTampered = "state/tampered"; const char *RStateTemperature = "state/temperature"; @@ -89,6 +87,7 @@ const char *RConfigLedIndication = "config/ledindication"; const char *RConfigLocalTime = "config/localtime"; const char *RConfigLong = "config/long"; const char *RConfigLevelMin = "config/levelmin"; +const char *RConfigHeating = "config/heatsetpoint"; const char *RConfigMode = "config/mode"; const char *RConfigOffset = "config/offset"; const char *RConfigOn = "config/on"; @@ -98,6 +97,7 @@ const char *RConfigPowerOnCt = "config/poweronct"; const char *RConfigPowerOnLevel = "config/poweronlevel"; const char *RConfigReachable = "config/reachable"; const char *RConfigScheduler = "config/scheduler"; +const char *RConfigSchedulerOn = "config/scheduleron"; const char *RConfigSensitivity = "config/sensitivity"; const char *RConfigSensitivityMax = "config/sensitivitymax"; const char *RConfigSunriseOffset = "config/sunriseoffset"; @@ -156,7 +156,6 @@ void initResourceDescriptors() rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeString, RStateEffect)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, RStateFire)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, RStateFlag)); - rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeInt16, RStateHeating)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeUInt16, RStateHue)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeUInt16, RStateHumidity, 0, 10000)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeTime, RStateLastUpdated)); @@ -170,7 +169,6 @@ void initResourceDescriptors() rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeInt16, RStatePower)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, RStateReachable)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeUInt8, RStateSat)); - rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, RStateSchedulerOn)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeString, RActionScene)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeInt32, RStateStatus)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, RStateTampered)); @@ -190,6 +188,7 @@ void initResourceDescriptors() rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeUInt16, RConfigDelay)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeUInt16, RConfigDuration)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeString, RConfigGroup)); + rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeInt16, RConfigHeating)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeUInt32, RConfigId)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeString, RConfigLat)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, RConfigLedIndication)); @@ -205,6 +204,7 @@ void initResourceDescriptors() rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeUInt16, RConfigPowerOnCt)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, RConfigReachable)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeString, RConfigScheduler)); + rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeBool, RConfigSchedulerOn)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeUInt8, RConfigSensitivity)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeUInt8, RConfigSensitivityMax)); rItemDescriptors.emplace_back(ResourceItemDescriptor(DataTypeInt8, RConfigSunriseOffset, -120, 120)); diff --git a/resource.h b/resource.h index 3e71e83e21..7fe4e26059 100644 --- a/resource.h +++ b/resource.h @@ -65,7 +65,6 @@ extern const char *RStateDaylight; extern const char *RStateEffect; extern const char *RStateFire; extern const char *RStateFlag; -extern const char *RStateHeating; extern const char *RStateHue; extern const char *RStateHumidity; extern const char *RStateLastUpdated; @@ -79,7 +78,6 @@ extern const char *RStatePressure; extern const char *RStatePower; extern const char *RStateReachable; extern const char *RStateSat; -extern const char *RStateSchedulerOn; extern const char *RStateStatus; extern const char *RStateTampered; extern const char *RStateTemperature; @@ -98,6 +96,7 @@ extern const char *RConfigConfigured; extern const char *RConfigDelay; extern const char *RConfigDuration; extern const char *RConfigGroup; +extern const char *RConfigHeating; extern const char *RConfigId; extern const char *RConfigLat; extern const char *RConfigLedIndication; @@ -113,6 +112,7 @@ extern const char *RConfigPowerOnCt; extern const char *RConfigPowerOnLevel; extern const char *RConfigReachable; extern const char *RConfigScheduler; +extern const char *RConfigSchedulerOn; extern const char *RConfigSensitivity; extern const char *RConfigSensitivityMax; extern const char *RConfigSunriseOffset; diff --git a/rest_sensors.cpp b/rest_sensors.cpp index e1c0c4b5aa..035183d3d7 100644 --- a/rest_sensors.cpp +++ b/rest_sensors.cpp @@ -1340,6 +1340,40 @@ int DeRestPluginPrivate::changeSensorConfig(const ApiRequest &req, ApiResponse & return REQ_READY_SEND; } } + if (rid.suffix == RConfigSchedulerOn) + { + bool onoff = map[pi.key()].toBool(); + uint8_t onoffAttr = onoff ? 0x01 : 0x00; + + if (addTaskThermostatReadWriteAttribute(task, deCONZ::ZclWriteAttributesId, 0x0025, deCONZ::Zcl8BitBitMap, onoffAttr)) + { + updated = true; + } + else + { + rsp.list.append(errorToMap(ERR_INVALID_VALUE, QString("/sensors/%1/%2").arg(id).arg(rid.suffix), QString("could not set attribute"))); + rsp.httpStatus = HttpStatusBadRequest; + return REQ_READY_SEND; + } + } + else if (rid.suffix == RConfigHeating) + { + bool ok; + int16_t heatsetpoint =map[pi.key()].toUInt(&ok); + + if (ok && addTaskThermostatReadWriteAttribute(task, deCONZ::ZclWriteAttributesId, 0x0012, deCONZ::Zcl16BitInt, heatsetpoint)) + { + updated = true; + } + else + { + rsp.list.append(errorToMap(ERR_INVALID_VALUE, + QString("/sensors/%1/%2").arg(id).arg(rid.suffix), + QString("could not set attribute value=%1").arg(map[pi.key()].toString()))); + rsp.httpStatus = HttpStatusBadRequest; + return REQ_READY_SEND; + } + } } } @@ -1487,11 +1521,6 @@ int DeRestPluginPrivate::changeSensorState(const ApiRequest &req, ApiResponse &r bool isClip = sensor->type().startsWith(QLatin1String("CLIP")); - if (sensor->type() == "ZHAThermostat") - { - isClip = true; // ZHAThermostat allow PUT on state - } - if (req.sock) { userActivity(); @@ -1622,58 +1651,6 @@ int DeRestPluginPrivate::changeSensorState(const ApiRequest &req, ApiResponse &r sensor->durationDue = QDateTime::currentDateTime().addSecs(item2->toNumber()).addMSecs(-500); } } - else if (sensor->type() == "ZHAThermostat") - { - TaskItem task; - // set destination parameters - task.req.dstAddress() = sensor->address(); - task.req.setTxOptions(deCONZ::ApsTxAcknowledgedTransmission); - task.req.setDstEndpoint(sensor->fingerPrint().endpoint); - task.req.setSrcEndpoint(getSrcEndpoint(sensor, task.req)); - task.req.setDstAddressMode(deCONZ::ApsExtAddress); - - if (rid.suffix == RStateSchedulerOn) - { - bool onoff = val.toBool(); - uint8_t onoffAttr = onoff ? 0x01 : 0x00; - - if (addTaskThermostatReadWriteAttribute(task, deCONZ::ZclWriteAttributesId, 0x0025, deCONZ::Zcl8BitBitMap, onoffAttr)) - { - updated = true; - } - else - { - rsp.list.append(errorToMap(ERR_INVALID_VALUE, QString("/sensors/%1/%2").arg(id).arg(rid.suffix), QString("could not set attribute"))); - rsp.httpStatus = HttpStatusBadRequest; - - } - } - else if (rid.suffix == RStateHeating) - { - bool ok; - int16_t heatsetpoint =val.toUInt(&ok); - - if (ok && addTaskThermostatReadWriteAttribute(task, deCONZ::ZclWriteAttributesId, 0x0012, deCONZ::Zcl16BitInt, heatsetpoint)) - { - updated = true; - } - else - { - rsp.list.append(errorToMap(ERR_INVALID_VALUE, - QString("/sensors/%1/%2").arg(id).arg(rid.suffix), - QString("could not set attribute value=%1").arg(val.toString()))); - rsp.httpStatus = HttpStatusBadRequest; - } - } - else - { - rsp.list.append(errorToMap(ERR_INVALID_VALUE, - QString("/sensors/%1/state/%2").arg(id).arg(pi.key()), - QString("thermostat invalid value, %1, for parameter %2").arg(rid.suffix).arg(pi.key()))); - rsp.httpStatus = HttpStatusBadRequest; - return REQ_READY_SEND; - } - } } else // invalid { diff --git a/thermostat.cpp b/thermostat.cpp index e895aa9a72..adf2e26044 100644 --- a/thermostat.cpp +++ b/thermostat.cpp @@ -8,26 +8,26 @@ * option | read/write | attribute | description * -------------------|------------|-----------|--------------------- * state.on | read only | 0x0029 | running state on/off - * state.heatsetpoint | read write | 0x0012 | heating setpoint - * state.scheduleron | read write | 0x0025 | scheduler on/off - * state.temperature | read only | 0x0000 | meassured temperature + * state.temperature | read only | 0x0000 | measured temperature + * config.heatsetpoint| read write | 0x0012 | heating setpoint + * config.scheduleron | read write | 0x0025 | scheduler on/off * config.offset | read write | 0x0010 | temperature offset * config.scheduler | read write | (command) | scheduled setpoints * * * Example sensor: * - * /api//sensors// + * /api//sensors// * { * config: { + * "heatsetpoint": 2200, * "offset": 0, - * "scheduler": "Monday,Tuesday,Wednesday,Thursday,Friday 05:00 2200 19:00 1800;Saturday,Sunday 06:00 2100 19:00 1800;" + * "scheduler": "Monday,Tuesday,Wednesday,Thursday,Friday 05:00 2200 19:00 1800;Saturday,Sunday 06:00 2100 19:00 1800;" + * "scheduleron": true * }, * state: { - * "heatsetpoint": 1800, - * "on": false, - * "scheduleron": true, - * "temperature": 2190 + * "on": true, + * "temperature": 2150 * }, * "ep": 1, * "manufacturername": "Bitron Home", @@ -37,8 +37,8 @@ * } * * Rest API example commands: - * -X PUT /api//sensors//state -d '{ "heatsetpoint": 1800 }' - * -X PUT /api//sensors//state -d '{ "scheduleron": true }' + * -X PUT /api//sensors//config -d '{ "heatsetpoint": 1800 }' + * -X PUT /api//sensors//config -d '{ "scheduleron": true }' * -X PUT /api//sensors//config -d '{ "offset": 0 }' * -X PUT /api//sensors//config -d '{ "scheduler": "Monday 05:00 2200 19:00 1800;" }' * -d '{ "scheduler": "" }' (send get scheduler command) @@ -207,22 +207,22 @@ void DeRestPluginPrivate::handleThermostatClusterIndication(const deCONZ::ApsDat break; case 0x0012: // Occupied Heating Setpoint - item = sensor->item(RStateHeating); + item = sensor->item(RConfigHeating); if (item) { item->setValue(attrValue); - Event e(RSensors, RStateHeating, sensor->id(), item); + Event e(RSensors, RConfigHeating, sensor->id(), item); enqueueEvent(e); } break; case 0x0025: // Thermostat Programming Operation Mode, default 0 (bit#0 = disable/enable Scheduler) - item = sensor->item(RStateSchedulerOn); + item = sensor->item(RConfigSchedulerOn); if (item) { bool onoff = attrValue & 0x01 ? true : false; item->setValue(onoff); - Event e(RSensors, RStateSchedulerOn, sensor->id(), item); + Event e(RSensors, RConfigSchedulerOn, sensor->id(), item); enqueueEvent(e); } break;