How can I receive temperature messages from an Impinj reader over LLRP?

122 views Asked by At

I am attempting to monitor the temperature of a reader over an LLRP connection. In out_impinj_ltkcpp.h I see a class called CImpinjReaderTemperature that looks mostly boilerplate:

class CImpinjReaderTemperature : public CParameter
{
  public:
    CImpinjReaderTemperature (void);
    ~CImpinjReaderTemperature (void);

    static const CFieldDescriptor * const
    s_apFieldDescriptorTable[];

    static const CTypeDescriptor
    s_typeDescriptor;

    //... clipped for brevity
}

There is an enumeration that looks useful:

enum EImpinjRequestedDataType {
  ImpinjRequestedDataType_All_Configuration = 2000,  /**< All_Configuration */
  ImpinjRequestedDataType_Impinj_Sub_Regulatory_Region = 2001,  /**< Impinj_Sub_Regulatory_Region */
  ImpinjRequestedDataType_Impinj_GPI_Debounce_Configuration = 2003,  /**< Impinj_GPI_Debounce_Configuration */
  ImpinjRequestedDataType_Impinj_Reader_Temperature = 2004,  /**< Impinj_Reader_Temperature */
//...clipped for brevity
}

First, how are temperature messages received over LLRP, i.e. do reports need to be requested? Does the temperature need to be polled? Second, how do these parameters fit into LLRP? Which message is the correct one to send (CGET_READER_CONFIG, CUSTOM_MESSAGE, something else)?

1

There are 1 answers

0
adc On BEST ANSWER

The documentation on the LLRP protocol— and especially Impinj extensions— is somewhat lacking or locked behind doors whose keys were lost years ago. That said, I was able to find a document that referenced the Impinj:Temperature message and piece things together from there.

First, the temperature response comes as custom part of a CGET_READER_CONFIG_RESPONSE message. This means we need to send a CGET_READER_CONFIG message that requests the custom temperature extension:

  CGET_READER_CONFIG *pCmd;
  CMessage *pRspMsg;
  CGET_READER_CONFIG_RESPONSE *pRsp;

  // Compose the command message
  pCmd = new CGET_READER_CONFIG();
  pCmd->setRequestedData(GetReaderConfigRequestedData_Identification); // This is cheaper than the default of "all"
  
  CImpinjRequestedData * req = new CImpinjRequestedData();
  req->setRequestedData(ImpinjRequestedDataType_Impinj_Reader_Temperature);
  pCmd->addCustom(req);

Attached to that config request message is a CImpinjRequestData object that encodes a single integer 2004. This is the significance of the enumeration in my question above. After sending this message, the reader will respond with a response including the identifier we asked for. Without asking for the reader's identification, the value of the requestedData will be 0 which corresponds to "all information" and becomes quite a large message.

Along with the identifier is an <Impinj:Temperature> element containing the reader's internal temperature in Celsius. That can be accessed by enumerating the custom field responses (there is only one) and, after checking its type, reading its temperature field:

  std::list<CParameter *>::iterator it;
  for (it = pRsp->beginCustom(); it != pRsp->endCustom(); it++ )
  {
    if ((*it)->m_pType == &CImpinjReaderTemperature::s_typeDescriptor)
    {
      CImpinjReaderTemperature* temp = (CImpinjReaderTemperature*) *it;
      if (NULL != temperature_out)
        *temperature_out = temp->getTemperature();
    }
  }

While this may not be the most convenient interface to fetch this information, it is working reliably. It can also serve as an example for other fetching other LLRP extensions.