Sensors: Improve generic sensors

* Makes the main states of the sensors writable to ease up scripting
by not having to go through the scaling input state
* Adds min/max settings for all input states to ease up calibration
with various input devices
* For sensors that have a main state min/max setting, actually write
those min/max settings to the dynamic min/max values of the state
This commit is contained in:
Michael Zanetti 2023-01-01 19:39:43 +01:00
parent d159cdb332
commit cd09f19060
4 changed files with 487 additions and 116 deletions

View File

@ -51,6 +51,12 @@ void IntegrationPluginGenericHeatingCooling::setupThing(ThingSetupInfo *info)
if (paramTypeId == thermostatSettingsTemperatureDifferenceParamTypeId) { if (paramTypeId == thermostatSettingsTemperatureDifferenceParamTypeId) {
thermostatCheckPowerOutputState(thing); thermostatCheckPowerOutputState(thing);
} }
if (paramTypeId == thermostatSettingsMinTargetTemperatureParamTypeId) {
thing->setStateMinValue(thermostatTargetTemperatureStateTypeId, value);
}
if (paramTypeId == thermostatSettingsMaxTargetTemperatureParamTypeId) {
thing->setStateMaxValue(thermostatTargetTemperatureStateTypeId, value);
}
}); });
} else if (thing->thingClassId() == sgReadyThingClassId) { } else if (thing->thingClassId() == sgReadyThingClassId) {
bool relay1 = thing->stateValue(sgReadyRelay1StateTypeId).toBool(); bool relay1 = thing->stateValue(sgReadyRelay1StateTypeId).toBool();

View File

@ -4,13 +4,23 @@ This plugin allows to create generic sensors in nymea. Such things don't have an
functionality on their own, but allow to create a visually appealing experience when functionality on their own, but allow to create a visually appealing experience when
using general purpose input and outputs, such as GPIOs or MQTT. using general purpose input and outputs, such as GPIOs or MQTT.
## Set-up ## Set-up by connecting Generic inputs
First, set up a sensor with generic inputs or outputs. For instance from the GPIO plugin * Set up a sensor with generic inputs. For instance from a GPIO or an I2C device.
or the MQTT plugin. When done, set up the desired generic thing and use the things settings to connect * Set up the desired generc thing
the inputs and/or outputs or use nymea scripts to process MQTT messages and fill in the states accordingly. * Use the generic things settings to connect it to the device in the Generic Input/Outputs section.
* Use the min/max settings to calibrate the sensor.
### Example: A soil moisture sensor on an analog input GPIO ## Set-up by using scripting
* Set up a thing that obtains sensor data in one way or another. For example via the
mqtt client , the HTTP client or the Modbus commander plugin.
* Set up the desired generic thing.
* Create a script obtaining the input value and writing it to the generic sensor thing.
## Examples
### A soil moisture sensor on an analog input GPIO
First, set up the GPIO to receive the analog GPIO values from the sensor. Normally First, set up the GPIO to receive the analog GPIO values from the sensor. Normally
such an analog input GPIO will dispatch values from 0V to e.g. 3.3V, depending on the such an analog input GPIO will dispatch values from 0V to e.g. 3.3V, depending on the
@ -18,12 +28,48 @@ hardware. An input value of 0V normally refers to a soil moisture value of 0%, w
an input value of 3.3V would refer to the maximum, that is 100% soil moisture. Once an input value of 3.3V would refer to the maximum, that is 100% soil moisture. Once
those input values are received in nymea, set up a generic soil moisture thing and those input values are received in nymea, set up a generic soil moisture thing and
go to its settings. In there you'll find the Input/Output connections section which go to its settings. In there you'll find the Input/Output connections section which
allows to map this generic soil moisture sensure to the according GPIO input. Once allows to map this generic soil moisture sensor to the according GPIO input. Once
this connection has been made, the generic soil moisture thing will represent the this connection has been made, the generic soil moisture thing will represent the
input from the GPIO in a nice sensor view. input from the GPIO in a nice sensor view.
Some sensors might not support the full range from 0% to 100% and might output Some sensors might require calibration in order to display correct values. For instance
a sensor may not support the full range from 0% to 100% and might output
a value of 0V on a minimum soil moisture of e.g. 10% or might only be able to a value of 0V on a minimum soil moisture of e.g. 10% or might only be able to
measure the soil moisture up to, say, 90%. Normally the sensor hardware would give measure the soil moisture up to, say, 90%. Normally the sensor hardware would give
that information in the data sheet or user guide. If this is the case, the appropriate that information in the data sheet or user guide. If this is the case, the appropriate
input range can also be defined in the generic moisture sensor page. input range can also be defined in the generic moisture sensor page.
### A temperature sensor from MQTT
First decide on the MQTT broker to be used. The possibility is to use the nymea
integrated MQTT broker or an external one.
If using the nymea internal mqtt broker, make sure it is enabled in the System Settings
and, if authentication is enabled for the server, a valid client policy is in place.
Then configure the device to publish values to nymea. Then create an "Internal mqtt client"
thing and subscribe to an appropriate topic filter for the device's publishing topic.
If instead the device publishes values to another mqtt broker, create a new "MQTT client"
thing in nymea and provide connection information to the external MQTT broker.
Once a MQTT client thing is set up, create the desired generic sensor thing.
Then create a nymea script which parses the MQTT message and writes the value to the generic
sensor.
```
ThingEvent {
thingId: "..." // the mqtt client's id
eventName": "triggered"
onTriggered: {
console.log("Publish received from MQTT", JSON.stringify(params))
temperatureState.value = JSON.parse(params["data"])["temperature"]
}
}
ThingState {
id: temperatureState
thingId: "..." // the generic temperature sensor
stateName": "temperature"
}
```

View File

@ -44,6 +44,76 @@ void IntegrationPluginGenericSensors::setupThing(ThingSetupInfo *info)
{ {
Thing *thing = info->thing(); Thing *thing = info->thing();
if (thing->thingClassId() == temperatureSensorThingClassId) {
connect(thing, &Thing::settingChanged, thing, [thing](const ParamTypeId &settingTypeId, const QVariant &value){
if (settingTypeId == temperatureSensorSettingsMinTempParamTypeId) {
thing->setStateMinValue(temperatureSensorTemperatureStateTypeId, value);
}
if (settingTypeId == temperatureSensorSettingsMaxTempParamTypeId) {
thing->setStateMaxValue(temperatureSensorTemperatureStateTypeId, value);
}
});
}
if (thing->thingClassId() == orpSensorThingClassId) {
connect(thing, &Thing::settingChanged, thing, [thing](const ParamTypeId &settingTypeId, const QVariant &value){
if (settingTypeId == orpSensorSettingsMinORPParamTypeId) {
thing->setStateMinValue(orpSensorOrpStateTypeId, value);
}
if (settingTypeId == orpSensorSettingsMaxORPParamTypeId) {
thing->setStateMaxValue(orpSensorOrpStateTypeId, value);
}
});
}
if (thing->thingClassId() == pressureSensorThingClassId) {
connect(thing, &Thing::settingChanged, thing, [thing](const ParamTypeId &settingTypeId, const QVariant &value){
if (settingTypeId == pressureSensorSettingsMinPressureParamTypeId) {
thing->setStateMinValue(pressureSensorPressureStateTypeId, value);
}
if (settingTypeId == pressureSensorSettingsMaxPressureParamTypeId) {
thing->setStateMaxValue(pressureSensorPressureStateTypeId, value);
}
});
}
if (thing->thingClassId() == coSensorThingClassId) {
connect(thing, &Thing::settingChanged, thing, [thing](const ParamTypeId &settingTypeId, const QVariant &value){
if (settingTypeId == coSensorSettingsMinCOParamTypeId) {
thing->setStateMinValue(coSensorCoStateTypeId, value);
}
if (settingTypeId == coSensorSettingsMaxCOParamTypeId) {
thing->setStateMaxValue(coSensorCoStateTypeId, value);
}
});
}
if (thing->thingClassId() == co2SensorThingClassId) {
connect(thing, &Thing::settingChanged, thing, [thing](const ParamTypeId &settingTypeId, const QVariant &value){
if (settingTypeId == co2SensorSettingsMinCO2ParamTypeId) {
thing->setStateMinValue(co2SensorCo2StateTypeId, value);
}
if (settingTypeId == co2SensorSettingsMaxCO2ParamTypeId) {
thing->setStateMaxValue(co2SensorCo2StateTypeId, value);
}
});
}
if (thing->thingClassId() == gasSensorThingClassId) {
connect(thing, &Thing::settingChanged, thing, [thing](const ParamTypeId &settingTypeId, const QVariant &value){
if (settingTypeId == gasSensorSettingsMinValueParamTypeId) {
thing->setStateMinValue(gasSensorGasLevelStateTypeId, value);
}
if (settingTypeId == gasSensorSettingsMaxValueParamTypeId) {
thing->setStateMaxValue(gasSensorGasLevelStateTypeId, value);
}
});
}
if (thing->thingClassId() == lightSensorThingClassId) {
connect(thing, &Thing::settingChanged, thing, [thing](const ParamTypeId &settingTypeId, const QVariant &value){
if (settingTypeId == lightSensorSettingsMinLuxParamTypeId) {
thing->setStateMinValue(lightSensorLightIntensityStateTypeId, value);
}
if (settingTypeId == lightSensorSettingsMaxLuxParamTypeId) {
thing->setStateMaxValue(lightSensorLightIntensityStateTypeId, value);
}
});
}
if (thing->thingClassId() == waterLevelSensorThingClassId) { if (thing->thingClassId() == waterLevelSensorThingClassId) {
connect(thing, &Thing::settingChanged, thing, [ thing](const ParamTypeId &settingTypeId, const QVariant &value){ connect(thing, &Thing::settingChanged, thing, [ thing](const ParamTypeId &settingTypeId, const QVariant &value){
if (settingTypeId == waterLevelSensorSettingsCapacityParamTypeId) { if (settingTypeId == waterLevelSensorSettingsCapacityParamTypeId) {
@ -68,12 +138,19 @@ void IntegrationPluginGenericSensors::executeAction(ThingActionInfo *info)
Action action = info->action(); Action action = info->action();
if (thing->thingClassId() == temperatureSensorThingClassId) { if (thing->thingClassId() == temperatureSensorThingClassId) {
if (action.actionTypeId() == temperatureSensorInputActionTypeId) { if (action.actionTypeId() == temperatureSensorTemperatureActionTypeId) {
double value = info->action().param(temperatureSensorTemperatureActionTemperatureParamTypeId).value().toDouble();
thing->setStateValue(temperatureSensorTemperatureStateTypeId, value);
info->finish(Thing::ThingErrorNoError);
return;
} else if (action.actionTypeId() == temperatureSensorInputActionTypeId) {
double value = info->action().param(temperatureSensorInputActionInputParamTypeId).value().toDouble(); double value = info->action().param(temperatureSensorInputActionInputParamTypeId).value().toDouble();
thing->setStateValue(temperatureSensorInputStateTypeId, value); thing->setStateValue(temperatureSensorInputStateTypeId, value);
double min = info->thing()->setting(temperatureSensorSettingsMinTempParamTypeId).toDouble(); double inputMin = info->thing()->setting(temperatureSensorSettingsMinInputParamTypeId).toDouble();
double max = info->thing()->setting(temperatureSensorSettingsMaxTempParamTypeId).toDouble(); double inputMax = info->thing()->setting(temperatureSensorSettingsMaxInputParamTypeId).toDouble();
double newValue = mapDoubleValue(value, 0, 1, min, max); double tempMin = info->thing()->setting(temperatureSensorSettingsMinTempParamTypeId).toDouble();
double tempMax = info->thing()->setting(temperatureSensorSettingsMaxTempParamTypeId).toDouble();
double newValue = mapDoubleValue(value, inputMin, inputMax, tempMin, tempMax);
double roundingFactor = qPow(10, info->thing()->setting(temperatureSensorSettingsAccuracyParamTypeId).toInt()); double roundingFactor = qPow(10, info->thing()->setting(temperatureSensorSettingsAccuracyParamTypeId).toInt());
newValue = qRound(newValue * roundingFactor) / roundingFactor; newValue = qRound(newValue * roundingFactor) / roundingFactor;
thing->setStateValue(temperatureSensorTemperatureStateTypeId, newValue); thing->setStateValue(temperatureSensorTemperatureStateTypeId, newValue);
@ -83,12 +160,17 @@ void IntegrationPluginGenericSensors::executeAction(ThingActionInfo *info)
Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8()); Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8());
} }
} else if (thing->thingClassId() == humiditySensorThingClassId) { } else if (thing->thingClassId() == humiditySensorThingClassId) {
if (action.actionTypeId() == humiditySensorInputActionTypeId) { if (action.actionTypeId() == humiditySensorHumidityActionTypeId) {
double value = info->action().param(humiditySensorHumidityActionHumidityParamTypeId).value().toDouble();
thing->setStateValue(humiditySensorHumidityStateTypeId, value);
info->finish(Thing::ThingErrorNoError);
return;
} else if (action.actionTypeId() == humiditySensorInputActionTypeId) {
double value = info->action().param(humiditySensorInputActionInputParamTypeId).value().toDouble(); double value = info->action().param(humiditySensorInputActionInputParamTypeId).value().toDouble();
thing->setStateValue(humiditySensorInputStateTypeId, value); thing->setStateValue(humiditySensorInputStateTypeId, value);
double min = info->thing()->setting(humiditySensorSettingsMinHumidityParamTypeId).toDouble(); double inputMin = info->thing()->setting(humiditySensorSettingsMinInputParamTypeId).toDouble();
double max = info->thing()->setting(humiditySensorSettingsMaxHumidityParamTypeId).toDouble(); double inputMax = info->thing()->setting(humiditySensorSettingsMaxInputParamTypeId).toDouble();
double newValue = mapDoubleValue(value, 0, 100, min, max); double newValue = mapDoubleValue(value, inputMin, inputMax, 0, 100);
double roundingFactor = qPow(10, info->thing()->setting(humiditySensorSettingsAccuracyParamTypeId).toInt()); double roundingFactor = qPow(10, info->thing()->setting(humiditySensorSettingsAccuracyParamTypeId).toInt());
newValue = qRound(newValue * roundingFactor) / roundingFactor; newValue = qRound(newValue * roundingFactor) / roundingFactor;
thing->setStateValue(humiditySensorHumidityStateTypeId, newValue); thing->setStateValue(humiditySensorHumidityStateTypeId, newValue);
@ -98,12 +180,17 @@ void IntegrationPluginGenericSensors::executeAction(ThingActionInfo *info)
Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8()); Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8());
} }
} else if (thing->thingClassId() == moistureSensorThingClassId) { } else if (thing->thingClassId() == moistureSensorThingClassId) {
if (action.actionTypeId() == moistureSensorInputActionTypeId) { if (action.actionTypeId() == moistureSensorMoistureActionTypeId) {
double value = info->action().param(moistureSensorInputActionInputParamTypeId).value().toDouble();
thing->setStateValue(moistureSensorMoistureStateTypeId, value);
info->finish(Thing::ThingErrorNoError);
return;
} else if (action.actionTypeId() == moistureSensorInputActionTypeId) {
double value = info->action().param(moistureSensorInputActionInputParamTypeId).value().toDouble(); double value = info->action().param(moistureSensorInputActionInputParamTypeId).value().toDouble();
thing->setStateValue(moistureSensorInputStateTypeId, value); thing->setStateValue(moistureSensorInputStateTypeId, value);
double min = info->thing()->setting(moistureSensorSettingsMinMoistureParamTypeId).toDouble(); double inputMin = info->thing()->setting(moistureSensorSettingsMinInputParamTypeId).toDouble();
double max = info->thing()->setting(moistureSensorSettingsMaxMoistureParamTypeId).toDouble(); double inputMax = info->thing()->setting(moistureSensorSettingsMaxInputParamTypeId).toDouble();
double newValue = mapDoubleValue(value, 0, 100, min, max); double newValue = mapDoubleValue(value, inputMin, inputMax, 0, 100);
double roundingFactor = qPow(10, info->thing()->setting(moistureSensorSettingsAccuracyParamTypeId).toInt()); double roundingFactor = qPow(10, info->thing()->setting(moistureSensorSettingsAccuracyParamTypeId).toInt());
newValue = qRound(newValue * roundingFactor) / roundingFactor; newValue = qRound(newValue * roundingFactor) / roundingFactor;
thing->setStateValue(moistureSensorMoistureStateTypeId, newValue); thing->setStateValue(moistureSensorMoistureStateTypeId, newValue);
@ -113,7 +200,12 @@ void IntegrationPluginGenericSensors::executeAction(ThingActionInfo *info)
Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8()); Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8());
} }
} else if (thing->thingClassId() == phSensorThingClassId) { } else if (thing->thingClassId() == phSensorThingClassId) {
if (action.actionTypeId() == phSensorInputActionTypeId) { if (action.actionTypeId() == phSensorPhActionTypeId) {
double value = info->action().paramValue(phSensorInputActionInputParamTypeId).toDouble();
thing->setStateValue(phSensorPhStateTypeId, value);
info->finish(Thing::ThingErrorNoError);
return;
} else if (action.actionTypeId() == phSensorInputActionTypeId) {
double value = info->action().paramValue(phSensorInputActionInputParamTypeId).toDouble(); double value = info->action().paramValue(phSensorInputActionInputParamTypeId).toDouble();
thing->setStateValue(phSensorInputStateTypeId, value); thing->setStateValue(phSensorInputStateTypeId, value);
double min = info->thing()->setting(phSensorSettingsMinInputParamTypeId).toDouble(); double min = info->thing()->setting(phSensorSettingsMinInputParamTypeId).toDouble();
@ -125,13 +217,21 @@ void IntegrationPluginGenericSensors::executeAction(ThingActionInfo *info)
info->finish(Thing::ThingErrorNoError); info->finish(Thing::ThingErrorNoError);
return; return;
} }
} else if (thing->thingClassId() == orpSensorThingClassId) { } else if (thing->thingClassId() == orpSensorThingClassId) {
if (action.actionTypeId() == orpSensorInputActionTypeId) { if (action.actionTypeId() == orpSensorOrpActionTypeId) {
double value = info->action().paramValue(orpSensorInputActionInputParamTypeId).toDouble();
thing->setStateValue(orpSensorOrpStateTypeId, value);
info->finish(Thing::ThingErrorNoError);
return;
} else if (action.actionTypeId() == orpSensorInputActionTypeId) {
double value = info->action().paramValue(orpSensorInputActionInputParamTypeId).toDouble(); double value = info->action().paramValue(orpSensorInputActionInputParamTypeId).toDouble();
thing->setStateValue(orpSensorInputStateTypeId, value); thing->setStateValue(orpSensorInputStateTypeId, value);
double min = info->thing()->setting(orpSensorSettingsMinORPParamTypeId).toDouble(); double minInput = info->thing()->setting(orpSensorSettingsMinInputParamTypeId).toDouble();
double max = info->thing()->setting(orpSensorSettingsMaxORPParamTypeId).toDouble(); double maxInput = info->thing()->setting(orpSensorSettingsMaxInputParamTypeId).toDouble();
double newValue = mapDoubleValue(value, 0, 100, min, max); double minOrp = info->thing()->setting(orpSensorSettingsMinORPParamTypeId).toDouble();
double maxOrp = info->thing()->setting(orpSensorSettingsMaxORPParamTypeId).toDouble();
double newValue = mapDoubleValue(value, minInput, maxInput, minOrp, maxOrp);
double roundingFactor = qPow(10, info->thing()->setting(orpSensorSettingsAccuracyParamTypeId).toInt()); double roundingFactor = qPow(10, info->thing()->setting(orpSensorSettingsAccuracyParamTypeId).toInt());
newValue = qRound(newValue * roundingFactor) / roundingFactor; newValue = qRound(newValue * roundingFactor) / roundingFactor;
thing->setStateValue(orpSensorOrpStateTypeId, newValue); thing->setStateValue(orpSensorOrpStateTypeId, newValue);
@ -139,12 +239,17 @@ void IntegrationPluginGenericSensors::executeAction(ThingActionInfo *info)
return; return;
} }
} else if (thing->thingClassId() == o2SensorThingClassId) { } else if (thing->thingClassId() == o2SensorThingClassId) {
if (action.actionTypeId() == o2SensorInputActionTypeId) { if (action.actionTypeId() == o2SensorO2saturationActionTypeId) {
double value = info->action().paramValue(o2SensorO2saturationActionO2saturationParamTypeId).toDouble();
thing->setStateValue(o2SensorO2saturationStateTypeId, value);
info->finish(Thing::ThingErrorNoError);
return;
} else if (action.actionTypeId() == o2SensorInputActionTypeId) {
double value = info->action().paramValue(o2SensorInputActionInputParamTypeId).toDouble(); double value = info->action().paramValue(o2SensorInputActionInputParamTypeId).toDouble();
thing->setStateValue(o2SensorInputStateTypeId, value); thing->setStateValue(o2SensorInputStateTypeId, value);
double min = info->thing()->setting(o2SensorSettingsMinInputParamTypeId).toDouble(); double minInput = info->thing()->setting(o2SensorSettingsMinInputParamTypeId).toDouble();
double max = info->thing()->setting(o2SensorSettingsMaxInputParamTypeId).toDouble(); double maxInput = info->thing()->setting(o2SensorSettingsMaxInputParamTypeId).toDouble();
double newValue = mapDoubleValue(value, min, max, 0, 100); double newValue = mapDoubleValue(value, minInput, maxInput, 0, 100);
double roundingFactor = qPow(10, info->thing()->setting(o2SensorSettingsAccuracyParamTypeId).toInt()); double roundingFactor = qPow(10, info->thing()->setting(o2SensorSettingsAccuracyParamTypeId).toInt());
newValue = qRound(newValue * roundingFactor) / roundingFactor; newValue = qRound(newValue * roundingFactor) / roundingFactor;
thing->setStateValue(o2SensorO2saturationStateTypeId, newValue); thing->setStateValue(o2SensorO2saturationStateTypeId, newValue);
@ -152,12 +257,19 @@ void IntegrationPluginGenericSensors::executeAction(ThingActionInfo *info)
return; return;
} }
} else if (thing->thingClassId() == pressureSensorThingClassId) { } else if (thing->thingClassId() == pressureSensorThingClassId) {
if (action.actionTypeId() == pressureSensorInputActionTypeId) { if (action.actionTypeId() == pressureSensorPressureActionTypeId) {
double value = info->action().param(pressureSensorPressureActionPressureParamTypeId).value().toDouble();
thing->setStateValue(pressureSensorPressureStateTypeId, value);
info->finish(Thing::ThingErrorNoError);
return;
} else if (action.actionTypeId() == pressureSensorInputActionTypeId) {
double value = info->action().param(pressureSensorInputActionInputParamTypeId).value().toDouble(); double value = info->action().param(pressureSensorInputActionInputParamTypeId).value().toDouble();
thing->setStateValue(pressureSensorInputStateTypeId, value); thing->setStateValue(pressureSensorInputStateTypeId, value);
double min = info->thing()->setting(pressureSensorSettingsMinPressureParamTypeId).toDouble(); double minInput = info->thing()->setting(pressureSensorSettingsMinInputParamTypeId).toDouble();
double max = info->thing()->setting(pressureSensorSettingsMaxPressureParamTypeId).toDouble(); double maxInput = info->thing()->setting(pressureSensorSettingsMaxInputParamTypeId).toDouble();
double newValue = mapDoubleValue(value, 0, 100, min, max); double minPressure = info->thing()->setting(pressureSensorSettingsMinPressureParamTypeId).toDouble();
double maxPressure = info->thing()->setting(pressureSensorSettingsMaxPressureParamTypeId).toDouble();
double newValue = mapDoubleValue(value, minInput, maxInput, minPressure, maxPressure);
double roundingFactor = qPow(10, info->thing()->setting(pressureSensorSettingsAccuracyParamTypeId).toInt()); double roundingFactor = qPow(10, info->thing()->setting(pressureSensorSettingsAccuracyParamTypeId).toInt());
newValue = qRound(newValue * roundingFactor) / roundingFactor; newValue = qRound(newValue * roundingFactor) / roundingFactor;
thing->setStateValue(pressureSensorPressureStateTypeId, newValue); thing->setStateValue(pressureSensorPressureStateTypeId, newValue);
@ -167,12 +279,19 @@ void IntegrationPluginGenericSensors::executeAction(ThingActionInfo *info)
Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8()); Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8());
} }
} else if (thing->thingClassId() == coSensorThingClassId) { } else if (thing->thingClassId() == coSensorThingClassId) {
if (action.actionTypeId() == coSensorInputActionTypeId) { if (action.actionTypeId() == coSensorCoActionTypeId) {
double value = info->action().param(coSensorCoActionCoParamTypeId).value().toDouble();
thing->setStateValue(coSensorCoStateTypeId, value);
info->finish(Thing::ThingErrorNoError);
return;
} else if (action.actionTypeId() == coSensorInputActionTypeId) {
double value = info->action().param(coSensorInputActionInputParamTypeId).value().toDouble(); double value = info->action().param(coSensorInputActionInputParamTypeId).value().toDouble();
thing->setStateValue(coSensorInputStateTypeId, value); thing->setStateValue(coSensorInputStateTypeId, value);
double min = info->thing()->setting(coSensorSettingsMinCOParamTypeId).toDouble(); double minInput = info->thing()->setting(coSensorSettingsMinInputParamTypeId).toDouble();
double max = info->thing()->setting(coSensorSettingsMaxCOParamTypeId).toDouble(); double maxInput = info->thing()->setting(coSensorSettingsMaxInputParamTypeId).toDouble();
double newValue = mapDoubleValue(value, 0, 100, min, max); double minCo = info->thing()->setting(coSensorSettingsMinCOParamTypeId).toDouble();
double maxCo = info->thing()->setting(coSensorSettingsMaxCOParamTypeId).toDouble();
double newValue = mapDoubleValue(value, minInput, maxInput, minCo, maxCo);
double roundingFactor = qPow(10, info->thing()->setting(coSensorSettingsAccuracyParamTypeId).toInt()); double roundingFactor = qPow(10, info->thing()->setting(coSensorSettingsAccuracyParamTypeId).toInt());
newValue = qRound(newValue * roundingFactor) / roundingFactor; newValue = qRound(newValue * roundingFactor) / roundingFactor;
thing->setStateValue(coSensorCoStateTypeId, newValue); thing->setStateValue(coSensorCoStateTypeId, newValue);
@ -182,12 +301,19 @@ void IntegrationPluginGenericSensors::executeAction(ThingActionInfo *info)
Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8()); Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8());
} }
} else if (thing->thingClassId() == co2SensorThingClassId) { } else if (thing->thingClassId() == co2SensorThingClassId) {
if (action.actionTypeId() == co2SensorInputActionTypeId) { if (action.actionTypeId() == co2SensorCo2ActionTypeId) {
double value = info->action().param(co2SensorCo2ActionCo2ParamTypeId).value().toDouble();
thing->setStateValue(co2SensorCo2StateTypeId, value);
info->finish(Thing::ThingErrorNoError);
return;
} else if (action.actionTypeId() == co2SensorInputActionTypeId) {
double value = info->action().param(co2SensorInputActionInputParamTypeId).value().toDouble(); double value = info->action().param(co2SensorInputActionInputParamTypeId).value().toDouble();
thing->setStateValue(co2SensorInputStateTypeId, value); thing->setStateValue(co2SensorInputStateTypeId, value);
double min = info->thing()->setting(co2SensorSettingsMinCO2ParamTypeId).toDouble(); double minInput = info->thing()->setting(co2SensorSettingsMinInputParamTypeId).toDouble();
double max = info->thing()->setting(co2SensorSettingsMaxCO2ParamTypeId).toDouble(); double maxInput = info->thing()->setting(co2SensorSettingsMaxInputParamTypeId).toDouble();
double newValue = mapDoubleValue(value, 0, 100, min, max); double minCo2 = info->thing()->setting(co2SensorSettingsMinCO2ParamTypeId).toDouble();
double maxCo2 = info->thing()->setting(co2SensorSettingsMaxCO2ParamTypeId).toDouble();
double newValue = mapDoubleValue(value, minInput, maxInput, minCo2, maxCo2);
double roundingFactor = qPow(10, info->thing()->setting(co2SensorSettingsAccuracyParamTypeId).toInt()); double roundingFactor = qPow(10, info->thing()->setting(co2SensorSettingsAccuracyParamTypeId).toInt());
newValue = qRound(newValue * roundingFactor) / roundingFactor; newValue = qRound(newValue * roundingFactor) / roundingFactor;
thing->setStateValue(co2SensorCo2StateTypeId, newValue); thing->setStateValue(co2SensorCo2StateTypeId, newValue);
@ -197,12 +323,19 @@ void IntegrationPluginGenericSensors::executeAction(ThingActionInfo *info)
Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8()); Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8());
} }
} else if (thing->thingClassId() == gasSensorThingClassId) { } else if (thing->thingClassId() == gasSensorThingClassId) {
if (action.actionTypeId() == gasSensorInputActionTypeId) { if (action.actionTypeId() == gasSensorGasLevelActionTypeId) {
double value = info->action().param(gasSensorGasLevelActionGasLevelParamTypeId).value().toDouble();
thing->setStateValue(gasSensorGasLevelStateTypeId, value);
info->finish(Thing::ThingErrorNoError);
return;
} else if (action.actionTypeId() == gasSensorInputActionTypeId) {
double value = info->action().param(gasSensorInputActionInputParamTypeId).value().toDouble(); double value = info->action().param(gasSensorInputActionInputParamTypeId).value().toDouble();
thing->setStateValue(gasSensorInputStateTypeId, value); thing->setStateValue(gasSensorInputStateTypeId, value);
double min = info->thing()->setting(gasSensorSettingsMinValueParamTypeId).toDouble(); double minInput = info->thing()->setting(gasSensorSettingsMinInputParamTypeId).toDouble();
double max = info->thing()->setting(gasSensorSettingsMaxValueParamTypeId).toDouble(); double maxInput = info->thing()->setting(gasSensorSettingsMaxInputParamTypeId).toDouble();
double newValue = mapDoubleValue(value, 0, 100, min, max); double minValue = info->thing()->setting(gasSensorSettingsMinValueParamTypeId).toDouble();
double maxValue = info->thing()->setting(gasSensorSettingsMaxValueParamTypeId).toDouble();
double newValue = mapDoubleValue(value, minInput, maxInput, minValue, maxValue);
double roundingFactor = qPow(10, info->thing()->setting(gasSensorSettingsAccuracyParamTypeId).toInt()); double roundingFactor = qPow(10, info->thing()->setting(gasSensorSettingsAccuracyParamTypeId).toInt());
newValue = qRound(newValue * roundingFactor) / roundingFactor; newValue = qRound(newValue * roundingFactor) / roundingFactor;
thing->setStateValue(gasSensorGasLevelStateTypeId, newValue); thing->setStateValue(gasSensorGasLevelStateTypeId, newValue);
@ -212,12 +345,19 @@ void IntegrationPluginGenericSensors::executeAction(ThingActionInfo *info)
Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8()); Q_ASSERT_X(false, "executeAction", QString("Unhandled actionTypeId: %1").arg(action.actionTypeId().toString()).toUtf8());
} }
} else if (thing->thingClassId() == lightSensorThingClassId) { } else if (thing->thingClassId() == lightSensorThingClassId) {
if (action.actionTypeId() == lightSensorInputActionTypeId) { if (action.actionTypeId() == lightSensorLightIntensityStateTypeId) {
double value = info->action().param(lightSensorLightIntensityStateTypeId).value().toDouble();
thing->setStateValue(lightSensorLightIntensityStateTypeId, value);
info->finish(Thing::ThingErrorNoError);
return;
} else if (action.actionTypeId() == lightSensorInputActionTypeId) {
double value = info->action().param(lightSensorInputActionInputParamTypeId).value().toDouble(); double value = info->action().param(lightSensorInputActionInputParamTypeId).value().toDouble();
thing->setStateValue(lightSensorInputStateTypeId, value); thing->setStateValue(lightSensorInputStateTypeId, value);
double min = info->thing()->setting(lightSensorSettingsMinLuxParamTypeId).toDouble(); double minInput = info->thing()->setting(lightSensorSettingsMinInputParamTypeId).toDouble();
double max = info->thing()->setting(lightSensorSettingsMaxLuxParamTypeId).toDouble(); double maxInput = info->thing()->setting(lightSensorSettingsMaxInputParamTypeId).toDouble();
double newValue = mapDoubleValue(value, 0, 100, min, max); double minValue = info->thing()->setting(lightSensorSettingsMinLuxParamTypeId).toDouble();
double maxValue = info->thing()->setting(lightSensorSettingsMaxLuxParamTypeId).toDouble();
double newValue = mapDoubleValue(value, minInput, maxInput, minValue, maxValue);
double roundingFactor = qPow(10, info->thing()->setting(lightSensorSettingsAccuracyParamTypeId).toInt()); double roundingFactor = qPow(10, info->thing()->setting(lightSensorSettingsAccuracyParamTypeId).toInt());
newValue = qRound(newValue * roundingFactor) / roundingFactor; newValue = qRound(newValue * roundingFactor) / roundingFactor;
thing->setStateValue(lightSensorLightIntensityStateTypeId, newValue); thing->setStateValue(lightSensorLightIntensityStateTypeId, newValue);

View File

@ -20,16 +20,34 @@
"name": "minTemp", "name": "minTemp",
"displayName": "Minimum temperature", "displayName": "Minimum temperature",
"type": "double", "type": "double",
"defaultValue": -20, "unit": "DegreeCelsius",
"unit": "DegreeCelsius" "defaultValue": -20
}, },
{ {
"id": "8b5947ab-127f-4995-853b-eeeb628811e3", "id": "8b5947ab-127f-4995-853b-eeeb628811e3",
"name": "maxTemp", "name": "maxTemp",
"displayName": "Maximum temperature", "displayName": "Maximum temperature",
"type": "double", "type": "double",
"defaultValue": 50, "unit": "DegreeCelsius",
"unit": "DegreeCelsius" "defaultValue": 50
},
{
"id": "603e0c4e-4757-4ac0-8345-ba7a1aaf5503",
"name": "minInput",
"displayName": "Minimum input (0 - 1)",
"type": "double",
"minValue": -1,
"maxValue": 1,
"defaultValue": 0
},
{
"id": "1ea78589-f787-4aa5-bb1a-90cd73a14386",
"name": "maxInput",
"displayName": "Maximum input (0 - 1)",
"type": "double",
"minValue": 0,
"maxValue": 2,
"defaultValue": 1
}, },
{ {
"id": "3b543c3a-1fc0-45b5-8c07-600a6045f82e", "id": "3b543c3a-1fc0-45b5-8c07-600a6045f82e",
@ -46,16 +64,18 @@
"id": "d0b6c4be-339e-4b0f-a234-0611b7565395", "id": "d0b6c4be-339e-4b0f-a234-0611b7565395",
"name": "temperature", "name": "temperature",
"displayName": "Temperature", "displayName": "Temperature",
"displayNameEvent": "Temperature changed", "displayNameAction": "Set temperature",
"type": "double", "type": "double",
"unit": "DegreeCelsius", "unit": "DegreeCelsius",
"defaultValue": 0 "minValue": -20,
"maxValue": 50,
"defaultValue": 0,
"writable": true
}, },
{ {
"id": "fed37466-1264-4ac1-84fd-aff3a1f7ff04", "id": "fed37466-1264-4ac1-84fd-aff3a1f7ff04",
"name": "input", "name": "input",
"displayName": "Input value", "displayName": "Input value",
"displayNameEvent": "Input value changed",
"displayNameAction": "Set input value", "displayNameAction": "Set input value",
"type": "double", "type": "double",
"defaultValue": 0, "defaultValue": 0,
@ -75,19 +95,23 @@
"settingsTypes": [ "settingsTypes": [
{ {
"id": "0218ffa9-3d49-4b25-a59f-c8831f190432", "id": "0218ffa9-3d49-4b25-a59f-c8831f190432",
"name": "minHumidity", "name": "minInput",
"displayName": "Minimum humidity", "displayName": "Minimum input",
"type": "double", "type": "double",
"defaultValue": 0, "unit": "Percentage",
"unit": "Percentage" "minValue": -100,
"maxValue": 100,
"defaultValue": 0
}, },
{ {
"id": "10afc387-68d1-47ea-a816-0d1acad47b3c", "id": "10afc387-68d1-47ea-a816-0d1acad47b3c",
"name": "maxHumidity", "name": "maxInput",
"displayName": "Maximum humidity", "displayName": "Maximum input",
"type": "double", "type": "double",
"defaultValue": 100, "unit": "Percentage",
"unit": "Percentage" "minValue": 0,
"maxValue": 200,
"defaultValue": 100
}, },
{ {
"id": "38064841-6121-4862-a639-08fb0b778511", "id": "38064841-6121-4862-a639-08fb0b778511",
@ -104,18 +128,18 @@
"id": "925225d9-2965-444a-9c42-63c2873700fb", "id": "925225d9-2965-444a-9c42-63c2873700fb",
"name": "humidity", "name": "humidity",
"displayName": "Humidity", "displayName": "Humidity",
"displayNameEvent": "Humidity changed", "displayNameAction": "Set humidity",
"type": "double", "type": "double",
"unit": "Percentage", "unit": "Percentage",
"defaultValue": 0, "defaultValue": 0,
"minValue": 0, "minValue": 0,
"maxValue": 100 "maxValue": 100,
"writable": true
}, },
{ {
"id": "a8223e65-e704-4f84-9bbe-d8fc42597047", "id": "a8223e65-e704-4f84-9bbe-d8fc42597047",
"name": "input", "name": "input",
"displayName": "Input value", "displayName": "Input value",
"displayNameEvent": "Input value changed",
"displayNameAction": "Set input value", "displayNameAction": "Set input value",
"type": "double", "type": "double",
"defaultValue": 0, "defaultValue": 0,
@ -135,19 +159,23 @@
"settingsTypes": [ "settingsTypes": [
{ {
"id": "32153786-f1ae-4aa4-a84c-b9054102eb92", "id": "32153786-f1ae-4aa4-a84c-b9054102eb92",
"name": "minMoisture", "name": "minInput",
"displayName": "Minimum moisture", "displayName": "Minimum input",
"type": "double", "type": "double",
"defaultValue": 0, "unit": "Percentage",
"unit": "Percentage" "minValue": -100,
"maxValue": 100,
"defaultValue": 0
}, },
{ {
"id": "3426817d-065e-4cfc-aa21-bb434de684d6", "id": "3426817d-065e-4cfc-aa21-bb434de684d6",
"name": "maxMoisture", "name": "maxInput",
"displayName": "Maximum moisture", "displayName": "Maximum input",
"type": "double", "type": "double",
"defaultValue": 100, "unit": "Percentage",
"unit": "Percentage" "minValue": 0,
"maxValue": 200,
"defaultValue": 100
}, },
{ {
"id": "3c967a68-9951-4c9a-b019-79b913e762b6", "id": "3c967a68-9951-4c9a-b019-79b913e762b6",
@ -164,12 +192,13 @@
"id": "7a62e1d2-92f2-424c-876c-870478a4b2bd", "id": "7a62e1d2-92f2-424c-876c-870478a4b2bd",
"name": "moisture", "name": "moisture",
"displayName": "Soil moisture", "displayName": "Soil moisture",
"displayNameEvent": "Soil moisture changed", "displayNameAction": "Set soil moisture",
"type": "double", "type": "double",
"unit": "Percentage", "unit": "Percentage",
"minValue": 0, "minValue": 0,
"maxValue": 100, "maxValue": 100,
"defaultValue": 0 "defaultValue": 0,
"writable": true
}, },
{ {
"id": "ce64a425-d990-4fc1-966b-be6de445792b", "id": "ce64a425-d990-4fc1-966b-be6de445792b",
@ -196,15 +225,21 @@
{ {
"id": "a8ff2e16-e06c-4b1e-839a-a06691a12d64", "id": "a8ff2e16-e06c-4b1e-839a-a06691a12d64",
"name": "minInput", "name": "minInput",
"displayName": "Minimum input value", "displayName": "Minimum input",
"type": "double", "type": "double",
"unit": "Percentage",
"minValue": -100,
"maxValue": 100,
"defaultValue": 0 "defaultValue": 0
}, },
{ {
"id": "a8889e45-59e5-4cc4-b228-611f8f19f531", "id": "a8889e45-59e5-4cc4-b228-611f8f19f531",
"name": "maxInput", "name": "maxInput",
"displayName": "Maximum input value", "displayName": "Maximum input",
"type": "double", "type": "double",
"unit": "Percentage",
"minValue": 0,
"maxValue": 200,
"defaultValue": 100 "defaultValue": 100
}, },
{ {
@ -222,22 +257,23 @@
"id": "743514b1-8018-4525-b87a-c5f414146ff2", "id": "743514b1-8018-4525-b87a-c5f414146ff2",
"name": "ph", "name": "ph",
"displayName": "PH", "displayName": "PH",
"displayNameEvent": "PH changed", "displayNameAction": "Set PH",
"type": "double", "type": "double",
"defaultValue": 7, "defaultValue": 7,
"minValue": 0, "minValue": 0,
"maxValue": 14 "maxValue": 14,
"writable": true
}, },
{ {
"id": "614a039b-9ed9-4b62-9c74-01ba4ac42f16", "id": "614a039b-9ed9-4b62-9c74-01ba4ac42f16",
"name": "input", "name": "input",
"displayName": "Input value", "displayName": "Input value",
"displayNameEvent": "Input value changed",
"displayNameAction": "Set input value", "displayNameAction": "Set input value",
"type": "double", "type": "double",
"unit": "Percentage",
"minValue": 0, "minValue": 0,
"defaultValue": 50,
"maxValue": 100, "maxValue": 100,
"defaultValue": 50,
"ioType": "analogOutput", "ioType": "analogOutput",
"writable": true "writable": true
} }
@ -253,17 +289,37 @@
{ {
"id": "396bf3f9-a3fc-44c3-90f8-b316670116a7", "id": "396bf3f9-a3fc-44c3-90f8-b316670116a7",
"name": "minORP", "name": "minORP",
"displayName": "Minimum input value", "displayName": "Minimum ORP value",
"type": "double", "type": "double",
"defaultValue": -1500 "defaultValue": -1500
}, },
{ {
"id": "bd0774c9-1b89-49ce-b0f8-66ff26ca10db", "id": "bd0774c9-1b89-49ce-b0f8-66ff26ca10db",
"name": "maxORP", "name": "maxORP",
"displayName": "Maximum input ORP value", "displayName": "Maximum ORP value",
"type": "double", "type": "double",
"defaultValue": 1500 "defaultValue": 1500
}, },
{
"id": "a4776e88-80e1-4ab0-8140-2c00a79b406b",
"name": "minInput",
"displayName": "Minimum input",
"type": "double",
"minValue": -100,
"maxValue": 100,
"unit": "Percentage",
"defaultValue": 0
},
{
"id": "4a78f063-3b3a-423e-bd73-f3c85de1b511",
"name": "maxInput",
"displayName": "Maximum input",
"type": "double",
"minValue": 0,
"maxValue": 200,
"unit": "Percentage",
"defaultValue": 100
},
{ {
"id": "1f218ad8-652a-4bda-987d-3e183ff040b2", "id": "1f218ad8-652a-4bda-987d-3e183ff040b2",
"name": "accuracy", "name": "accuracy",
@ -279,18 +335,18 @@
"id": "e5ed3535-2e5d-412e-85f8-782cbccd7731", "id": "e5ed3535-2e5d-412e-85f8-782cbccd7731",
"name": "orp", "name": "orp",
"displayName": "ORP", "displayName": "ORP",
"displayNameEvent": "ORP changed", "displayNameAction": "Set ORP",
"type": "double", "type": "double",
"unit": "MilliVolt", "unit": "MilliVolt",
"defaultValue": 0, "defaultValue": 0,
"minValue": -1500, "minValue": -1500,
"maxValue": 1500 "maxValue": 1500,
"writable": true
}, },
{ {
"id": "020ff04f-a157-4925-9c55-2b45389208fc", "id": "020ff04f-a157-4925-9c55-2b45389208fc",
"name": "input", "name": "input",
"displayName": "Input value", "displayName": "Input value",
"displayNameEvent": "Input value changed",
"displayNameAction": "Set input value", "displayNameAction": "Set input value",
"type": "double", "type": "double",
"minValue": 0, "minValue": 0,
@ -311,15 +367,21 @@
{ {
"id": "58e84041-d451-44a2-972e-13a79b449b58", "id": "58e84041-d451-44a2-972e-13a79b449b58",
"name": "minInput", "name": "minInput",
"displayName": "Minimum input value", "displayName": "Minimum input",
"type": "double", "type": "double",
"minValue": -100,
"maxValue": 100,
"unit": "Percentage",
"defaultValue": 0 "defaultValue": 0
}, },
{ {
"id": "198847f6-a188-42b0-9e0b-15587eaabbed", "id": "198847f6-a188-42b0-9e0b-15587eaabbed",
"name": "maxInput", "name": "maxInput",
"displayName": "Maximum input value", "displayName": "Maximum input",
"type": "double", "type": "double",
"minValue": 0,
"maxValue": 200,
"unit": "Percentage",
"defaultValue": 100 "defaultValue": 100
}, },
{ {
@ -337,23 +399,24 @@
"id": "a3ff7641-87d9-4b07-b8e5-e6aa92b90088", "id": "a3ff7641-87d9-4b07-b8e5-e6aa92b90088",
"name": "o2saturation", "name": "o2saturation",
"displayName": "O2 saturation", "displayName": "O2 saturation",
"displayNameEvent": "O2 saturation changed", "displayNameAction": "Set O2 saturation",
"type": "double", "type": "double",
"unit": "Percentage", "unit": "Percentage",
"defaultValue": 0, "defaultValue": 0,
"minValue": 0, "minValue": 0,
"maxValue": 100 "maxValue": 100,
"writable": true
}, },
{ {
"id": "7e74fca7-84d0-4f3e-9f26-4232b7b9f507", "id": "7e74fca7-84d0-4f3e-9f26-4232b7b9f507",
"name": "input", "name": "input",
"displayName": "Input value", "displayName": "Input value",
"displayNameEvent": "Input value changed",
"displayNameAction": "Set input value", "displayNameAction": "Set input value",
"type": "double", "type": "double",
"minValue": 0, "minValue": 0,
"defaultValue": 0,
"maxValue": 100, "maxValue": 100,
"defaultValue": 0,
"unit": "Percentage",
"ioType": "analogOutput", "ioType": "analogOutput",
"writable": true "writable": true
} }
@ -371,16 +434,36 @@
"name": "minPressure", "name": "minPressure",
"displayName": "Minimum pressure", "displayName": "Minimum pressure",
"type": "double", "type": "double",
"defaultValue": 0, "unit": "MilliBar",
"unit": "MilliBar" "defaultValue": 0
}, },
{ {
"id": "06e21251-8b4f-44a1-8504-6b51f8526bd0", "id": "06e21251-8b4f-44a1-8504-6b51f8526bd0",
"name": "maxPressure", "name": "maxPressure",
"displayName": "Maximum pressure", "displayName": "Maximum pressure",
"type": "double", "type": "double",
"defaultValue": 2000, "unit": "MilliBar",
"unit": "MilliBar" "defaultValue": 2000
},
{
"id": "58487871-e128-4f09-9412-3433574fb62d",
"name": "minInput",
"displayName": "Minimum input",
"type": "double",
"unit": "Percentage",
"minValue": 0,
"maxValue": 100,
"defaultValue": 0
},
{
"id": "21109465-d53c-4c69-b9a8-7f1c41e823b2",
"name": "maxInput",
"displayName": "Maximum input",
"type": "double",
"unit": "Percentage",
"minValue": 0,
"maxValue": 100,
"defaultValue": 100
}, },
{ {
"id": "021a17d8-9e5e-4dd6-835d-1a3e1ffd6b23", "id": "021a17d8-9e5e-4dd6-835d-1a3e1ffd6b23",
@ -397,10 +480,13 @@
"id": "e645a979-1465-4592-b8b0-f4c123db0800", "id": "e645a979-1465-4592-b8b0-f4c123db0800",
"name": "pressure", "name": "pressure",
"displayName": "Pressure", "displayName": "Pressure",
"displayNameEvent": "Pressure changed", "displayNameAction": "Set pressure",
"type": "double", "type": "double",
"minValue": 0,
"maxValue": 2000,
"unit": "MilliBar", "unit": "MilliBar",
"defaultValue": 0 "defaultValue": 0,
"writable": true
}, },
{ {
"id": "c320577c-371a-442b-ac80-b692ff2064c9", "id": "c320577c-371a-442b-ac80-b692ff2064c9",
@ -430,16 +516,37 @@
"name": "minCO", "name": "minCO",
"displayName": "Minimum CO", "displayName": "Minimum CO",
"type": "double", "type": "double",
"defaultValue": 0, "unit": "PartsPerMillion",
"unit": "PartsPerMillion" "minValue": 0,
"defaultValue": 0
}, },
{ {
"id": "e9def195-1b67-4a1b-8030-cbbc6209d52e", "id": "e9def195-1b67-4a1b-8030-cbbc6209d52e",
"name": "maxCO", "name": "maxCO",
"displayName": "Maximum CO", "displayName": "Maximum CO",
"type": "double", "type": "double",
"defaultValue": 255, "unit": "PartsPerMillion",
"unit": "PartsPerMillion" "defaultValue": 255
},
{
"id": "d4784dde-aa9a-4be4-a16c-592373760dc8",
"name": "minInput",
"displayName": "Minimum input",
"type": "double",
"minValue": -100,
"maxValue": 100,
"unit": "Percentage",
"defaultValue": 0
},
{
"id": "c6d9d5f4-d3d0-4284-ab82-e93cc2c30e21",
"name": "maxInput",
"displayName": "Maximum input",
"type": "double",
"minValue": 0,
"maxValue": 200,
"unit": "Percentage",
"defaultValue": 100
}, },
{ {
"id": "9c8a9553-7b68-4b58-a8f1-3c6b591998c0", "id": "9c8a9553-7b68-4b58-a8f1-3c6b591998c0",
@ -456,20 +563,21 @@
"id": "9eebe9d2-b34b-4847-bc25-109e2b8cab24", "id": "9eebe9d2-b34b-4847-bc25-109e2b8cab24",
"name": "co", "name": "co",
"displayName": "CO level", "displayName": "CO level",
"displayNameEvent": "CO level changed", "displayNameAction": "Set CO level",
"type": "double", "type": "double",
"minValue": 0, "minValue": 0,
"maxValue": "255", "maxValue": "255",
"unit": "PartsPerMillion", "unit": "PartsPerMillion",
"defaultValue": 0 "defaultValue": 0,
"writable": true
}, },
{ {
"id": "cf3ec5ec-7098-47c5-9666-b3c52eba1b1d", "id": "cf3ec5ec-7098-47c5-9666-b3c52eba1b1d",
"name": "input", "name": "input",
"displayName": "Input value", "displayName": "Input value",
"displayNameEvent": "Input value changed",
"displayNameAction": "Set input value", "displayNameAction": "Set input value",
"type": "double", "type": "double",
"unit": "Percentage",
"defaultValue": 0, "defaultValue": 0,
"minValue": 0, "minValue": 0,
"maxValue": 100, "maxValue": 100,
@ -490,16 +598,36 @@
"name": "minCO2", "name": "minCO2",
"displayName": "Minimum CO2", "displayName": "Minimum CO2",
"type": "double", "type": "double",
"defaultValue": 0, "unit": "PartsPerMillion",
"unit": "PartsPerMillion" "defaultValue": 0
}, },
{ {
"id": "a3029bee-8b13-4aed-8ebd-eaceb603f8ef", "id": "a3029bee-8b13-4aed-8ebd-eaceb603f8ef",
"name": "maxCO2", "name": "maxCO2",
"displayName": "Maximum CO2", "displayName": "Maximum CO2",
"type": "double", "type": "double",
"defaultValue": 2000, "unit": "PartsPerMillion",
"unit": "PartsPerMillion" "defaultValue": 2000
},
{
"id": "67e6b107-826a-48bc-9bd9-144d9b73a778",
"name": "minInput",
"displayName": "Minimum input",
"type": "double",
"minValue": -100,
"maxValue": 100,
"unit": "Percentage",
"defaultValue": 0
},
{
"id": "b79dca8c-cd73-4429-8a01-c194b2c43ea2",
"name": "maxInput",
"displayName": "Maximum input",
"type": "double",
"minValue": 0,
"maxValue": 200,
"unit": "Percentage",
"defaultValue": 100
}, },
{ {
"id": "236831a8-a455-4e38-a9cd-eabbebaa3f67", "id": "236831a8-a455-4e38-a9cd-eabbebaa3f67",
@ -516,11 +644,13 @@
"id": "755c4c7f-093e-41dd-a38d-9ee18c9890d6", "id": "755c4c7f-093e-41dd-a38d-9ee18c9890d6",
"name": "co2", "name": "co2",
"displayName": "CO2", "displayName": "CO2",
"displayNameAction": "Set CO2",
"type": "double", "type": "double",
"unit": "PartsPerMillion", "unit": "PartsPerMillion",
"minValue": 0, "minValue": 0,
"maxValue": 2000, "maxValue": 2000,
"defaultValue": 0 "defaultValue": 0,
"writable": true
}, },
{ {
"id": "7dc765f8-fa9b-4199-8f21-49ed452f226d", "id": "7dc765f8-fa9b-4199-8f21-49ed452f226d",
@ -528,6 +658,7 @@
"displayName": "Input value", "displayName": "Input value",
"displayNameAction": "Set input value", "displayNameAction": "Set input value",
"type": "double", "type": "double",
"unit": "Percentage",
"defaultValue": 0, "defaultValue": 0,
"minValue": 0, "minValue": 0,
"maxValue": 100, "maxValue": 100,
@ -559,6 +690,26 @@
"defaultValue": 10000, "defaultValue": 10000,
"unit": "PartsPerMillion" "unit": "PartsPerMillion"
}, },
{
"id": "6fbb8fe6-4ac1-4ad5-9621-7a786b632225",
"name": "minInput",
"displayName": "Minimum input",
"type": "double",
"minValue": -100,
"maxValue": 100,
"unit": "Percentage",
"defaultValue": 0
},
{
"id": "93827b27-8dba-40d9-b3fa-dde42bfcbcbc",
"name": "maxInput",
"displayName": "Maximum input",
"type": "double",
"minValue": 0,
"maxValue": 200,
"unit": "Percentage",
"defaultValue": 100
},
{ {
"id": "1c7465b1-490d-43db-bb67-a179a6923a57", "id": "1c7465b1-490d-43db-bb67-a179a6923a57",
"name": "accuracy", "name": "accuracy",
@ -574,18 +725,21 @@
"id": "5135648f-57b7-44b0-b9d0-c5accad09356", "id": "5135648f-57b7-44b0-b9d0-c5accad09356",
"name": "gasLevel", "name": "gasLevel",
"displayName": "Gas level", "displayName": "Gas level",
"displayNameEvent": "Gas level changed", "displayNameAction": "Set gas level",
"type": "double", "type": "double",
"minValue": 0,
"maxValue": 10000,
"unit": "PartsPerMillion", "unit": "PartsPerMillion",
"defaultValue": 0 "defaultValue": 0,
"writable": true
}, },
{ {
"id": "e3eb500a-ac00-426c-932a-dee4fd6fbcf5", "id": "e3eb500a-ac00-426c-932a-dee4fd6fbcf5",
"name": "input", "name": "input",
"displayName": "Input value", "displayName": "Input value",
"displayNameEvent": "Input value changed",
"displayNameAction": "Set input value", "displayNameAction": "Set input value",
"type": "double", "type": "double",
"unit": "Percentage",
"defaultValue": 0, "defaultValue": 0,
"minValue": 0, "minValue": 0,
"maxValue": 100, "maxValue": 100,
@ -617,6 +771,26 @@
"defaultValue": 120000, "defaultValue": 120000,
"unit": "Lux" "unit": "Lux"
}, },
{
"id": "72e0244a-97e0-473b-94ac-94014c488c08",
"name": "minInput",
"displayName": "Minimum input",
"type": "double",
"minValue": -100,
"maxValue": 100,
"unit": "Percentage",
"defaultValue": 0
},
{
"id": "265bf736-7d60-4361-98fb-83b11c277d87",
"name": "maxInput",
"displayName": "Maximum input",
"type": "double",
"minValue": 0,
"maxValue": 200,
"unit": "Percentage",
"defaultValue": 100
},
{ {
"id": "f800988f-1ad5-4ffb-9aa8-70ef17614966", "id": "f800988f-1ad5-4ffb-9aa8-70ef17614966",
"name": "accuracy", "name": "accuracy",
@ -632,10 +806,11 @@
"id": "fe12ef32-9f2f-41cd-acb7-6b8e4acffa3b", "id": "fe12ef32-9f2f-41cd-acb7-6b8e4acffa3b",
"name": "lightIntensity", "name": "lightIntensity",
"displayName": "Light intensity", "displayName": "Light intensity",
"displayNameEvent": "Light intensity changed", "displayNameAction": "Set light intensity",
"type": "double", "type": "double",
"unit": "Lux", "unit": "Lux",
"defaultValue": 0 "defaultValue": 0,
"writable": true
}, },
{ {
"id": "520e5d27-7d15-4d79-94cf-5d01f5a09ea8", "id": "520e5d27-7d15-4d79-94cf-5d01f5a09ea8",
@ -714,6 +889,8 @@
"name": "minInputValue", "name": "minInputValue",
"displayName": "Minimum input value", "displayName": "Minimum input value",
"type": "double", "type": "double",
"minValue": -1,
"maxValue": 1,
"defaultValue": 0 "defaultValue": 0
}, },
{ {
@ -721,6 +898,8 @@
"name": "maxInputValue", "name": "maxInputValue",
"displayName": "Maximum input value", "displayName": "Maximum input value",
"type": "double", "type": "double",
"minValue": 0,
"maxValue": 2,
"defaultValue": 1 "defaultValue": 1
} }
], ],