void EnoceanDeviceContainer::handleRadioPacket(Esp3PacketPtr aEsp3PacketPtr, ErrorPtr aError) { if (aError) { LOG(LOG_INFO, "Radio packet error: %s\n", aError->description().c_str()); return; } // check learning mode if (learningMode) { // no learn/unlearn actions detected so far // - check if we know that device address already. If so, it is a learn-out bool learnIn = enoceanDevices.find(aEsp3PacketPtr->radioSender())==enoceanDevices.end(); // now add/remove the device (if the action is a valid learn/unlearn) // detect implicit (RPS) learn in only with sufficient radio strength (or explicit override of that check), // explicit ones are always recognized if (aEsp3PacketPtr->eepHasTeachInfo(disableProximityCheck ? 0 : MIN_LEARN_DBM, false)) { LOG(LOG_NOTICE, "Received EnOcean learn packet while learn mode enabled: %s\n", aEsp3PacketPtr->description().c_str()); // This is actually a valid learn action ErrorPtr learnStatus; if (learnIn) { // new device learned in, add logical devices for it int numNewDevices = EnoceanDevice::createDevicesFromEEP(this, aEsp3PacketPtr->radioSender(), aEsp3PacketPtr->eepProfile(), aEsp3PacketPtr->eepManufacturer()); if (numNewDevices>0) { // successfully learned at least one device // - update learn status (device learned) getDeviceContainer().reportLearnEvent(true, ErrorPtr()); } } else { // device learned out, un-pair all logical dS devices it has represented // but keep dS level config in case it is reconnected unpairDevicesByAddress(aEsp3PacketPtr->radioSender(), false); getDeviceContainer().reportLearnEvent(false, ErrorPtr()); } // - only allow one learn action (to prevent learning out device when // button is released or other repetition of radio packet) learningMode = false; } // learn action } else { // not learning mode, dispatch packet to all devices known for that address for (EnoceanDeviceMap::iterator pos = enoceanDevices.lower_bound(aEsp3PacketPtr->radioSender()); pos!=enoceanDevices.upper_bound(aEsp3PacketPtr->radioSender()); ++pos) { if (aEsp3PacketPtr->eepHasTeachInfo(MIN_LEARN_DBM, false) && aEsp3PacketPtr->eepRorg()!=rorg_RPS) { // learning packet in non-learn mode -> report as non-regular user action, may be attempt to identify a device // Note: RPS devices are excluded because for these all telegrams are regular regular user actions. signalDeviceUserAction() will be called // from button if (getDeviceContainer().signalDeviceUserAction(*(pos->second), false)) { // consumed for device identification purposes, suppress further processing break; } } // handle regularily (might be RPS switch which does not have separate learn/action packets pos->second->handleRadioPacket(aEsp3PacketPtr); } } }
void EnoceanDeviceContainer::handleTestRadioPacket(CompletedCB aCompletedCB, Esp3PacketPtr aEsp3PacketPtr, ErrorPtr aError) { // ignore packets with error if (Error::isOK(aError)) { if (aEsp3PacketPtr->eepRorg()==rorg_RPS && aEsp3PacketPtr->radioDBm()>MIN_LEARN_DBM && enoceanComm.modemAppVersion()>0) { // uninstall handler enoceanComm.setRadioPacketHandler(NULL); // seen both watchdog response (modem works) and independent RPS telegram (RF is ok) LOG(LOG_NOTICE, "- enocean modem info: appVersion=0x%08X, apiVersion=0x%08X, modemAddress=0x%08X\n", enoceanComm.modemAppVersion(), enoceanComm.modemApiVersion(), enoceanComm.modemAddress()); aCompletedCB(ErrorPtr()); // done return; } } // - still waiting LOG(LOG_NOTICE, "- enocean test: still waiting for RPS telegram in learn distance\n"); }