Commit 16e564bd authored by luz's avatar luz

EnOcean: added x-p44-addProfile method to add EnOcean devices which cannot be...

EnOcean: added x-p44-addProfile method to add EnOcean devices which cannot be learned in via example telegram from device (such as remote control type devices)
parent f6f4c928
......@@ -266,6 +266,9 @@ namespace p44 {
/// @note will be called via UI for devices that need to be learned into remote actors
virtual void sendTeachInBeacon() { /* NOP in base class */ };
/// mark base offsets in use by this device
/// @param aUsedOffsetsMap must be passed a string with 128 chars of '0' or '1'.
virtual void markUsedBaseOffsets(string &aUsedOffsetsMap) { /* NOP in base class */ };
/// description of object, mainly for debug and logging
/// @return textual description of object
......
......@@ -237,15 +237,82 @@ void EnoceanDeviceContainer::unpairDevicesByAddress(EnoceanAddress aEnoceanAddre
}
#pragma mark - learn and unlearn devices
#pragma mark - EnOcean specific methods
ErrorPtr EnoceanDeviceContainer::handleMethod(VdcApiRequestPtr aRequest, const string &aMethod, ApiValuePtr aParams)
{
ErrorPtr respErr;
if (aMethod=="x-p44-addProfile") {
// create a composite device out of existing single-channel ones
respErr = addProfile(aRequest, aParams);
}
else {
respErr = inherited::handleMethod(aRequest, aMethod, aParams);
}
return respErr;
}
//#ifdef DEBUG
//#define MIN_LEARN_DBM -255 // any signal strength
//#warning "DEBUG Learning with weak signal enabled!"
//#else
//#define MIN_LEARN_DBM -50 // within approx one meter of the TCM310 (experimental luz v1 patched bridge)
//#endif
ErrorPtr EnoceanDeviceContainer::addProfile(VdcApiRequestPtr aRequest, ApiValuePtr aParams)
{
// add an EnOcean profile
ErrorPtr respErr;
ApiValuePtr o;
respErr = checkParam(aParams, "eep", o); // EEP with variant in MSB
if (Error::isOK(respErr)) {
EnoceanProfile eep = o->uint32Value();
respErr = checkParam(aParams, "address", o);
if (Error::isOK(respErr)) {
// remote device address
// if 0xFF800000..0xFF80007F : bit0..6 = ID base offset to ID base of modem
// if 0xFF8000FF : automatically take next unused ID base offset
EnoceanAddress addr = o->uint32Value();
if ((addr & 0xFFFFFF00)==0xFF800000) {
// relative to ID base
// - get map of already used offsets
string usedOffsetMap;
usedOffsetMap.assign(128,'0');
for (EnoceanDeviceMap::iterator pos = enoceanDevices.begin(); pos!=enoceanDevices.end(); ++pos) {
pos->second->markUsedBaseOffsets(usedOffsetMap);
}
addr &= 0xFF; // extract offset
if (addr==0xFF) {
// auto-determine offset
for (addr=0; addr<128; addr++) {
if (usedOffsetMap[addr]=='0') break; // free offset here
}
if (addr>128) {
respErr = ErrorPtr(new WebError(400, "no more free base ID offsets"));
}
}
else {
if (usedOffsetMap[addr]!='0') {
respErr = ErrorPtr(new WebError(400, "invalid or already used base ID offset specifier"));
}
}
// add-in my own ID base
addr += enoceanComm.idBase();
}
// now create device(s)
if (Error::isOK(respErr)) {
// create devices as if this was a learn-in
if (EnoceanDevice::createDevicesFromEEP(this, addr, eep, manufacturer_unknown)<1) {
respErr = ErrorPtr(new WebError(400, "Unknown EEP specification, no device(s) created"));
}
}
}
}
return respErr;
}
#pragma mark - learn and unlearn devices
#define MIN_LEARN_DBM -50
// -50 = for experimental luz v1 patched bridge: within approx one meter of the TCM310
......
......@@ -110,6 +110,9 @@ namespace p44 {
/// collect and add devices to the container
virtual void collectDevices(StatusCB aCompletedCB, bool aIncremental, bool aExhaustive, bool aClearSettings);
/// vdc level methods (p44 specific, JSON only, for configuring multichannel RGB(W) devices)
virtual ErrorPtr handleMethod(VdcApiRequestPtr aRequest, const string &aMethod, ApiValuePtr aParams);
/// @param aForget if set, all parameters stored for the device (if any) will be deleted. Note however that
/// the devices are not disconnected (=unlearned) by this.
virtual void removeDevices(bool aForget);
......@@ -163,6 +166,8 @@ namespace p44 {
void handleRadioPacket(Esp3PacketPtr aEsp3PacketPtr, ErrorPtr aError);
void handleTestRadioPacket(StatusCB aCompletedCB, Esp3PacketPtr aEsp3PacketPtr, ErrorPtr aError);
ErrorPtr addProfile(VdcApiRequestPtr aRequest, ApiValuePtr aParams);
};
} // namespace p44
......
......@@ -71,6 +71,15 @@ void EnoceanRemoteControlDevice::sendSwitchBeaconRelease()
}
void EnoceanRemoteControlDevice::markUsedBaseOffsets(string &aUsedOffsetsMap)
{
int offs = getAddress() & 0x7F;
if (offs<aUsedOffsetsMap.size()) {
aUsedOffsetsMap[offs]='1';
}
}
// insert into knowndevices (enoceanAddress, subdevice, eeProfile, eeManufacturer) values (0xFFDC0D00, 0, 0xFFF6FF, 0xFFFF);
// insert into knowndevices (enoceanAddress, subdevice, eeProfile, eeManufacturer) values (4292611328, 0, 16774911, 65535);
......
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