void EnoceanDevice::handleRadioPacket(Esp3PacketPtr aEsp3PacketPtr) { ALOG(LOG_INFO, "now starts processing EnOcean packet:\n%s", aEsp3PacketPtr->description().c_str()); lastPacketTime = MainLoop::now(); lastRSSI = aEsp3PacketPtr->radioDBm(); lastRepeaterCount = aEsp3PacketPtr->radioRepeaterCount(); // pass to every channel for (EnoceanChannelHandlerVector::iterator pos = channels.begin(); pos!=channels.end(); ++pos) { (*pos)->handleRadioPacket(aEsp3PacketPtr); } // if device cannot be updated whenever output value change is requested, send updates after receiving a message if (pendingDeviceUpdate || updateAtEveryReceive) { // send updates, if any pendingDeviceUpdate = true; // set it in case of updateAtEveryReceive (so message goes out even if no changes pending) ALOG(LOG_NOTICE, "pending output update is now sent to device"); sendOutgoingUpdate(); } }
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); } } }