Commit a35ef85d authored by luz's avatar luz

EnOcean profile variants - enhanced mechanism and made it generic at...

EnOcean profile variants - enhanced mechanism and made it generic at EnoceanDevice level, now mutiple profile groups can be defined, no longer only for RPS.
parent e93e2a46
......@@ -172,18 +172,6 @@ void EnoceanDevice::disconnect(bool aForgetParams, DisconnectCB aDisconnectResul
}
void EnoceanDevice::switchToProfile(EnoceanProfile aProfile)
{
// make sure object is retained locally
EnoceanDevicePtr keepMeAlive(this); // make sure this object lives until routine terminates
// have devices related to current profile deleted, including settings
// Note: this removes myself from container, and deletes the config (which is valid for the previous profile, i.e. a different type of device)
getEnoceanDeviceContainer().unpairDevicesByAddress(getAddress(), true);
// - create new ones, with same address and manufacturer, but new profile
EnoceanDevice::createDevicesFromEEP(&getEnoceanDeviceContainer(), getAddress(), aProfile, getEEManufacturer());
}
void EnoceanDevice::addChannelHandler(EnoceanChannelHandlerPtr aChannelHandler)
{
......@@ -323,6 +311,75 @@ string EnoceanDevice::description()
}
#pragma mark - profile variants
bool EnoceanDevice::getProfileVariants(ApiValuePtr aApiObjectValue)
{
// check if current profile is one of the interchangeable ones
const profileVariantEntry *currentVariant = profileVariantsTable();
while (currentVariant && currentVariant->profileGroup!=0) {
// look for current EEP in the list of variants
if (getEEProfile()==currentVariant->eep) {
// create string from all other variants (same profileGroup), if any
bool anyVariants = false;
const profileVariantEntry *variant = profileVariantsTable();
while (variant->profileGroup!=0) {
if (variant->profileGroup==currentVariant->profileGroup) {
if (variant->eep!=getEEProfile()) anyVariants = true; // another variant than just myself
aApiObjectValue->add(string_format("%d",variant->eep), aApiObjectValue->newString(variant->description));
}
variant++;
}
// there are variants
return anyVariants;
}
currentVariant++;
}
return false; // no variants
}
bool EnoceanDevice::setProfileVariant(EnoceanProfile aProfile)
{
// verify if changeable profile code requested
// - check for already having that profile
if (aProfile==getEEProfile()) return true; // we already have that profile -> NOP
// - find my profileGroup
const profileVariantEntry *currentVariant = profileVariantsTable();
while (currentVariant && currentVariant->profileGroup!=0) {
if (getEEProfile()==currentVariant->eep) {
// this is my profile group, now check if requested profile is in my profile group as well
const profileVariantEntry *variant = profileVariantsTable();
while (variant && variant->profileGroup!=0) {
if (variant->profileGroup==currentVariant->profileGroup && variant->eep==aProfile) {
// requested profile is in my group, change now
switchToProfile(aProfile); // will delete this device, so return immediately afterwards
return true; // changed profile
}
variant++;
}
}
currentVariant++;
}
return false; // invalid profile
}
void EnoceanDevice::switchToProfile(EnoceanProfile aProfile)
{
// make sure object is retained locally
EnoceanDevicePtr keepMeAlive(this); // make sure this object lives until routine terminates
// have devices related to current profile deleted, including settings
// Note: this removes myself from container, and deletes the config (which is valid for the previous profile, i.e. a different type of device)
getEnoceanDeviceContainer().unpairDevicesByAddress(getAddress(), true);
// - create new ones, with same address and manufacturer, but new profile
EnoceanDevice::createDevicesFromEEP(&getEnoceanDeviceContainer(), getAddress(), aProfile, getEEManufacturer());
}
#pragma mark - property access
......
......@@ -84,6 +84,12 @@ namespace p44 {
};
/// profile variant entry
typedef struct {
int profileGroup; // zero to terminate list or group number (interchangeable profiles must have same group number)
EnoceanProfile eep;
const char *description;
} profileVariantEntry;
typedef vector<EnoceanChannelHandlerPtr> EnoceanChannelHandlerVector;
......@@ -257,11 +263,11 @@ namespace p44 {
/// get profile variants this device can have
/// @param aApiObjectValue must be an object typed API value, will receive profile variants as EEP/description key/values
/// @return true if device has variants
virtual bool getProfileVariants(ApiValuePtr aApiObjectValue) { return false; /* none in base class */ };
bool getProfileVariants(ApiValuePtr aApiObjectValue);
/// @param aProfile must be an EEP profile code
/// @return true if profile variant is valid and can be set
virtual bool setProfileVariant(EnoceanProfile aProfile) { return false; /* profile not changeable in base class */ };
bool setProfileVariant(EnoceanProfile aProfile);
/// @name identification of the addressable entity
......@@ -300,9 +306,15 @@ namespace p44 {
/// derive dSUID from hardware address
void deriveDsUid();
/// switch EEP profile
/// switch EEP profile (or interpretation VARIANT thereof)
/// @param aProfile enocean profile to switch this device to
/// @note aProfile is not checked for being suitable for this type of device, this is done in setProfileVariant()
void switchToProfile(EnoceanProfile aProfile);
/// get table of profile variants
/// @return NULL or pointer to a list of profile variants
virtual const profileVariantEntry *profileVariantsTable() { return NULL; /* none in base class */ };
private:
/// get handler associated with a behaviour
......
......@@ -560,53 +560,28 @@ string EnoceanRpsLeakageDetectorHandler::shortDesc()
#pragma mark - EnoceanRPSDevice
typedef struct {
EnoceanProfile eep;
const char *description;
} profileVariantEntry;
static const int numRPSprofileVariants = 7;
static const profileVariantEntry RPSprofileVariants[numRPSprofileVariants] = {
{ 0x00F602FF, "dual rocker switch (as 2-way rockers)" },
{ 0x01F602FF, "dual rocker switch (as 4 separate buttons)" },
{ 0x00F60401, "key card activated switch ERP1" },
{ 0x00F60402, "key card activated switch ERP2" },
{ 0x00F604C0, "key card switch FKC/FKF" },
{ 0x00F60501, "Liquid Leakage detector" },
{ 0x00F605C0, "Smoke detector FRW/GUARD" }
#pragma mark - EnoceanRPSDevice profile variants
static const profileVariantEntry RPSprofileVariants[] = {
// dual rocker RPS button alternatives
{ 1, 0x00F602FF, "dual rocker switch (as 2-way rockers)" },
{ 1, 0x01F602FF, "dual rocker switch (as 4 separate buttons)" },
{ 1, 0x00F60401, "key card activated switch ERP1" },
{ 1, 0x00F60402, "key card activated switch ERP2" },
{ 1, 0x00F604C0, "key card activated switch FKC/FKF" },
{ 1, 0x00F60501, "Liquid Leakage detector" },
{ 1, 0x00F605C0, "Smoke detector FRW/GUARD" },
// quad rocker RPS button alternatives
{ 2, 0x00F603FF, "quad rocker switch (as 2-way rockers)" },
{ 2, 0x01F603FF, "quad rocker switch (as 8 separate buttons)" },
{ 0, 0, NULL } // terminator
};
bool EnoceanRPSDevice::getProfileVariants(ApiValuePtr aApiObjectValue)
const profileVariantEntry *EnoceanRPSDevice::profileVariantsTable()
{
// check if current profile is one of the interchangeable ones
for (int i=0; i<numRPSprofileVariants; i++) {
if (getEEProfile()==RPSprofileVariants[i].eep) {
// create string
for (int j=0; j<numRPSprofileVariants; j++) {
aApiObjectValue->add(string_format("%d",RPSprofileVariants[j].eep), aApiObjectValue->newString(RPSprofileVariants[j].description));
}
// there are variants
return true;
}
}
return false; // no variants
return RPSprofileVariants;
}
bool EnoceanRPSDevice::setProfileVariant(EnoceanProfile aProfile)
{
// check if changeable profile code
for (int i=0; i<numRPSprofileVariants; i++) {
if (aProfile==RPSprofileVariants[i].eep) {
// is one of the interchangeable ones
if (aProfile==getEEProfile()) return true; // we already have that profile -> NOP
// change profile now
switchToProfile(aProfile);
return true;
}
}
return false; // invalid profile
}
......@@ -208,14 +208,9 @@ namespace p44 {
/// @return constant identifier for this type of device (one container might contain more than one type)
virtual const char *deviceTypeIdentifier() { return "enocean_rps"; };
/// get profile variants this device can have
/// @param aApiObjectValue must be an object typed API value, will receive profile variants as EEP/description key/values
/// @return true if device has variants
virtual bool getProfileVariants(ApiValuePtr aApiObjectValue);
/// @param aProfile must be an EEP profile code
/// @return true if profile variant is valid and can be set
virtual bool setProfileVariant(EnoceanProfile aProfile);
/// get table of profile variants
/// @return NULL or pointer to a list of profile variants
virtual const profileVariantEntry *profileVariantsTable();
/// @return step between dSUID subdevice indices
virtual uint8_t dsUIDIndexStep() { return dsuidIndexStep; };
......
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