Commit c440305b authored by luz's avatar luz

Modelfeatures: Removed output settings for climate control outputs. Refactored...

Modelfeatures: Removed output settings for climate control outputs. Refactored to move feature decisions closer to actual objects having them, less assumptions at device level. Converted to tristate to allow explicit NOs (so far only YES was explicit).
parent a058dc0b
......@@ -53,19 +53,26 @@ void ClimateControlBehaviour::processControlValue(const string &aName, double aV
}
bool ClimateControlBehaviour::hasModelFeature(DsModelFeatures aFeatureIndex)
Tristate ClimateControlBehaviour::hasModelFeature(DsModelFeatures aFeatureIndex)
{
// now check for climate control behaviour level features
switch (aFeatureIndex) {
case modelFeature_blink:
// heating outputs can't blink
return no;
case modelFeature_heatinggroup:
// Assumption: virtual heating control devices (valves) do have group and mode setting...
return true;
return yes;
case modelFeature_heatingoutmode:
// ...but not the more specific PWM and heating props
return false;
return no;
case modelFeature_valvetype:
// for now, all climate control devices are heating valves
return true;
return yes;
case modelFeature_outmodeswitch:
case modelFeature_outmode:
// suppress output mode settings
return no;
default:
// not available at this level, ask base class
return inherited::hasModelFeature(aFeatureIndex);
......
......@@ -104,8 +104,8 @@ namespace p44 {
/// check for presence of model feature (flag in dSS visibility matrix)
/// @param aFeatureIndex the feature to check for
/// @return true if this output behaviour has the feature (which means dSS Configurator must provide UI for it)
virtual bool hasModelFeature(DsModelFeatures aFeatureIndex);
/// @return yes if this output behaviour has the feature, no if (explicitly) not, undefined if asked entity does not know
virtual Tristate hasModelFeature(DsModelFeatures aFeatureIndex);
/// Process a named control value. The type, color and settings of the output determine if at all,
/// and if, how the value affects the output
......
......@@ -211,13 +211,13 @@ ColorLightBehaviour::ColorLightBehaviour(Device &aDevice) :
}
bool ColorLightBehaviour::hasModelFeature(DsModelFeatures aFeatureIndex)
Tristate ColorLightBehaviour::hasModelFeature(DsModelFeatures aFeatureIndex)
{
// now check for light behaviour level features
switch (aFeatureIndex) {
case modelFeature_outputchannels:
// Assumption: all color light output devices need the multi-channel color lamp UI
return true;
return yes;
default:
// not available at this level, ask base class
return inherited::hasModelFeature(aFeatureIndex);
......
......@@ -246,8 +246,8 @@ namespace p44 {
/// check for presence of model feature (flag in dSS visibility matrix)
/// @param aFeatureIndex the feature to check for
/// @return true if this output behaviour has the feature (which means dSS Configurator must provide UI for it)
virtual bool hasModelFeature(DsModelFeatures aFeatureIndex);
/// @return yes if this output behaviour has the feature, no if (explicitly) not, undefined if asked entity does not know
virtual Tristate hasModelFeature(DsModelFeatures aFeatureIndex);
/// description of object, mainly for debug and logging
/// @return textual description of object, may contain LFs
......
......@@ -78,13 +78,13 @@ LightBehaviour::LightBehaviour(Device &aDevice) :
}
bool LightBehaviour::hasModelFeature(DsModelFeatures aFeatureIndex)
Tristate LightBehaviour::hasModelFeature(DsModelFeatures aFeatureIndex)
{
// now check for light behaviour level features
switch (aFeatureIndex) {
case modelFeature_transt:
// Assumption: all light output devices have transition times
return true;
return yes;
default:
// not available at this level, ask base class
return inherited::hasModelFeature(aFeatureIndex);
......
......@@ -176,8 +176,8 @@ namespace p44 {
/// check for presence of model feature (flag in dSS visibility matrix)
/// @param aFeatureIndex the feature to check for
/// @return true if this output behaviour has the feature (which means dSS Configurator must provide UI for it)
virtual bool hasModelFeature(DsModelFeatures aFeatureIndex);
/// @return yes if this output behaviour has the feature, no if (explicitly) not, undefined if asked entity does not know
virtual Tristate hasModelFeature(DsModelFeatures aFeatureIndex);
/// apply scene to output channels
/// @param aScene the scene to apply to output channels
......
......@@ -166,13 +166,13 @@ MovingLightBehaviour::MovingLightBehaviour(Device &aDevice) :
}
bool MovingLightBehaviour::hasModelFeature(DsModelFeatures aFeatureIndex)
Tristate MovingLightBehaviour::hasModelFeature(DsModelFeatures aFeatureIndex)
{
// now check for light behaviour level features
switch (aFeatureIndex) {
// case modelFeature_positionControls: //%%% does not exist yet...
// // Assumption: all moving light output devices need a UI for position
// return true;
// return yes;
default:
// not available at this level, ask base class
return inherited::hasModelFeature(aFeatureIndex);
......
......@@ -136,8 +136,8 @@ namespace p44 {
/// check for presence of model feature (flag in dSS visibility matrix)
/// @param aFeatureIndex the feature to check for
/// @return true if this output behaviour has the feature (which means dSS Configurator must provide UI for it)
virtual bool hasModelFeature(DsModelFeatures aFeatureIndex);
/// @return yes if this output behaviour has the feature, no if (explicitly) not, undefined if asked entity does not know
virtual Tristate hasModelFeature(DsModelFeatures aFeatureIndex);
/// short (text without LFs!) description of object, mainly for referencing it in log messages
/// @return textual description of object
......
......@@ -178,13 +178,16 @@ ShadowBehaviour::ShadowBehaviour(Device &aDevice) :
}
bool ShadowBehaviour::hasModelFeature(DsModelFeatures aFeatureIndex)
Tristate ShadowBehaviour::hasModelFeature(DsModelFeatures aFeatureIndex)
{
// now check for light behaviour level features
switch (aFeatureIndex) {
case modelFeature_transt:
// Assumption: all shadow output devices don't transition times
return false;
return no;
case modelFeature_shadeposition:
// Assumption: Shade outputs should be 16bit resolution and be labelled "Position", not "Value"
return yes;
default:
// not available at this level, ask base class
return inherited::hasModelFeature(aFeatureIndex);
......
......@@ -200,8 +200,8 @@ namespace p44 {
/// check for presence of model feature (flag in dSS visibility matrix)
/// @param aFeatureIndex the feature to check for
/// @return true if this output behaviour has the feature (which means dSS Configurator must provide UI for it)
virtual bool hasModelFeature(DsModelFeatures aFeatureIndex);
/// @return yes if this output behaviour has the feature, no if (explicitly) not, undefined if asked entity does not know
virtual Tristate hasModelFeature(DsModelFeatures aFeatureIndex);
/// apply scene to output channels
/// @param aScene the scene to apply to output channels
......
......@@ -30,6 +30,14 @@ using namespace std;
namespace p44 {
/// tristate type
typedef enum {
yes = 1,
no = 0,
undefined = -1
} Tristate;
/// printf-style format into std::string
/// @param aFormat printf-style format string
/// @return formatted string
......
......@@ -71,7 +71,7 @@ string Device::modelUID()
if (output) s += output->behaviourTypeIdentifier();
// model features
for (int f=0; f<numModelFeatures; f++) {
s += hasModelFeature((DsModelFeatures)f) ? 'T' : 'F';
s += hasModelFeature((DsModelFeatures)f)==yes ? 'T' : 'F';
}
// now make UUIDv5 type dSUID out of it
DsUid modelUID;
......@@ -244,74 +244,59 @@ static const char *modelFeatureNames[numModelFeatures] = {
};
bool Device::hasModelFeature(DsModelFeatures aFeatureIndex)
Tristate Device::hasModelFeature(DsModelFeatures aFeatureIndex)
{
// ask output first, might have more specific info
if (output) {
bool hasFeature = output->hasModelFeature(aFeatureIndex);
if (hasFeature) return true; // output has the feature, no need to check at device level
Tristate hasFeature = output->hasModelFeature(aFeatureIndex);
if (hasFeature!=undefined) return hasFeature; // output has a say about the feature, no need to check at device level
}
// now check for device level features
switch (aFeatureIndex) {
case modelFeature_dontcare:
// Generic: all devices with scene table have the ability to set scene's don't care flag
return boost::dynamic_pointer_cast<SceneDeviceSettings>(deviceSettings)!=NULL;
case modelFeature_blink:
// Assumption: all devices with an output have this, except heating
return output && primaryGroup!=group_blue_heating;
return boost::dynamic_pointer_cast<SceneDeviceSettings>(deviceSettings)!=NULL ? yes : no;
case modelFeature_ledauto:
case modelFeature_leddark:
// Virtual devices do not have the standard dS LED at all
return false;
case modelFeature_outmode:
// Assumption: All devices with an output that is gradual (not only switched) should have this
return (output && output->getOutputFunction()!=outputFunction_switch);
case modelFeature_outmodeswitch:
// Assumption: All devices with a switch-only output (not dimmable) should have this
return (output && output->getOutputFunction()==outputFunction_switch);
case modelFeature_outvalue8:
// Assumption: All normal 8-bit outputs should have this. Exception so far are shade outputs
return (output && !output->isMember(group_grey_shadow));
case modelFeature_shadeposition:
// Assumption: Shade outputs should be 16bit resolution and be labelled "Position", not "Value"
return (output && output->isMember(group_grey_shadow));
return no;
case modelFeature_pushbutton:
case modelFeature_pushbarea:
case modelFeature_pushbadvanced:
case modelFeature_pushbsensor:
// Assumption: any device with a buttonInputBehaviour has these props
return buttons.size()>0;
return buttons.size()>0 ? yes : no;
case modelFeature_pushbdevice:
// Assumption: virtual devices don't have a local button
return false;
return no;
case modelFeature_pushbcombined:
case modelFeature_twowayconfig:
// Assumption: devices with more than single button input are combined up/down (or even 4-way and more) buttons, and need two-way config
return buttons.size()>1;
return buttons.size()>1 ? yes : no;
case modelFeature_highlevel:
// Assumption: only black joker devices can have a high-level (app) functionality
return primaryGroup==group_black_joker;
return primaryGroup==group_black_joker ? yes : no;
case modelFeature_jokerconfig:
// Assumption: black joker devices need joker config (setting color) only if there are buttons or an output.
// Pure sensors or binary inputs don't need color config
return primaryGroup==group_black_joker && (output || buttons.size()>0);
return primaryGroup==group_black_joker && (output || buttons.size()>0) ? yes : no;
case modelFeature_akmsensor:
// Assumption: only devices with binaryinputs that do not have a predefined type need akmsensor
for (BehaviourVector::iterator pos = binaryInputs.begin(); pos!=binaryInputs.end(); ++pos) {
BinaryInputBehaviourPtr b = boost::dynamic_pointer_cast<BinaryInputBehaviour>(*pos);
if (b && b->getHardwareInputType()==binInpType_none) {
return true; // input with no predefined functionality, need to be able to configure sensor
return yes; // input with no predefined functionality, need to be able to configure sensor
}
}
// no inputs or all inputs have predefined functionality
return false;
return no;
case modelFeature_akminput:
case modelFeature_akmdelay:
// TODO: once binaryInputs support the AKM binary input settings (polarity, delays), this should be enabled
// for configurable inputs (most likely those that already have modelFeature_akmsensor)
return false; // %%% for now
return no; // %%% for now
default:
return false; // not known
return undefined; // not known
}
}
......@@ -1662,7 +1647,7 @@ bool Device::accessField(PropertyAccessMode aMode, ApiValuePtr aPropValue, Prope
else if (aPropertyDescriptor->hasObjectKey(device_modelFeatures_key)) {
// model features
if (aMode==access_read) {
if (hasModelFeature((DsModelFeatures)aPropertyDescriptor->fieldKey())) {
if (hasModelFeature((DsModelFeatures)aPropertyDescriptor->fieldKey())==yes) {
aPropValue->setBoolValue(true);
return true;
}
......
......@@ -128,8 +128,8 @@ namespace p44 {
/// check for presence of model feature (flag in dSS visibility matrix)
/// @param aFeatureIndex the feature to check for
/// @return true if this device has the feature (which means dSS Configurator must provide UI for it)
virtual bool hasModelFeature(DsModelFeatures aFeatureIndex);
/// @return yes if this output behaviour has the feature, no if (explicitly) not, undefined if asked entity does not know
virtual Tristate hasModelFeature(DsModelFeatures aFeatureIndex);
/// @}
......
......@@ -44,6 +44,29 @@ OutputBehaviour::OutputBehaviour(Device &aDevice) :
}
Tristate OutputBehaviour::hasModelFeature(DsModelFeatures aFeatureIndex)
{
// now check for light behaviour level features
switch (aFeatureIndex) {
case modelFeature_outmode:
// Assumption: outputs that are gradual (not only switched) should have this
return getOutputFunction()!=outputFunction_switch ? yes : no;
case modelFeature_outmodeswitch:
// Assumption: All devices with a switch-only output (not dimmable) should have this
return getOutputFunction()==outputFunction_switch ? yes : no;
case modelFeature_outvalue8:
// Assumption: All normal 8-bit outputs should have this. Exception so far are shade outputs
return yes;
case modelFeature_blink:
// Assumption: devices with an output have this
return yes;
default:
// not available at output level
return undefined;
}
}
void OutputBehaviour::setHardwareOutputConfig(DsOutputFunction aOutputFunction, DsUsageHint aUsage, bool aVariableRamp, double aMaxPower)
{
outputFunction = aOutputFunction;
......
......@@ -133,8 +133,8 @@ namespace p44 {
/// check for presence of model feature (flag in dSS visibility matrix)
/// @param aFeatureIndex the feature to check for
/// @return true if this output behaviour has the feature (which means dSS Configurator must provide UI for it)
virtual bool hasModelFeature(DsModelFeatures aFeatureIndex) { return false; /* base class does not have any specific feature */ };
/// @return yes if this output behaviour has the feature, no if (explicitly) not, undefined if asked entity does not know
virtual Tristate hasModelFeature(DsModelFeatures aFeatureIndex);
/// apply scene to output channels
/// @param aScene the scene to apply to output channels
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment