What is required to create an IR Device compatible Interface
Posted: Tue Jan 06, 2009 1:15 pm
The following information is for anybody interested in developing a Hardware Interface that can send and receive IR codes. The details of the actual sending and receiving are specific to the particular hardware that you are interfacing to and are not covered at all here. The information here is really just general information regarding the required interface that the plugin needs to support to allow it to work with the existing HouseBot IRDevice plugin and examples of sending and receiving to/from the server. It does NOT cover IR learning from the interface.
The only interface that needs to be supported by the plugin is the SendIR interface.
Specifying the hfRequireIRConfiguration flag will enable the association tab for IR codes to be displayed for Devices that use the interface.
Make sure to export the function.
A function similar to the one below must can created and called from the main SendIR() export above. It is called with the InterfaceArgumentPack that contains the IR position and optional property value.
Receiving IR
If your interface can receive IR codes, here are a few tips on how to process and notify.
First you will need to get the IR Codes from the server so you have something to match incoming data against. I have not included every method in the code below, but it should give you the general idea.
Sending Notifications
To send a notification to the IRDevice when IR is detected, you must send the 'IR Response Received' notification message as shown below.
The only interface that needs to be supported by the plugin is the SendIR interface.
Code: Select all
InterfaceInfo g_InterfaceSendIR = {
0,
"SendIR( IRPosition, [Property Value] )",
"SendIR",
"This interface will send the IR command that corresponds to IR Position specified.",
hfRequireIRConfiguration,
};
Make sure to export the function.
Code: Select all
extern "C" HOUSEBOT_HARDWARE_API BOOL SendIR( HARDWARE_INSTANCE_HANDLE hInstanceHandle, InterfaceArgumentPack* pPack )
{
// Send the code here. Something like this can be used and is used as an example below.
return( m_mapInstances[ hInstanceHandle ]->SendIR( pPack ) );
}
A function similar to the one below must can created and called from the main SendIR() export above. It is called with the InterfaceArgumentPack that contains the IR position and optional property value.
Code: Select all
HARDWARE_RC YourClassHere::SendIR( InterfaceArgumentPack* pPack )
{
//
// Make sure we can handle the version of the struct.
if (pPack->m_nArgumentPackVersion != SUPPORTED_ARGUMENT_PACK_VERSION)
{
TraceMessage( ttError, "Unsupported Argument Pack Version [%s]. Must be version [%d]", pPack->m_nArgumentPackVersion, SUPPORTED_ARGUMENT_PACK_VERSION );
return( hrcFailureAbort );
}
//
// Make sure there are enough arguments.
if (pPack->m_nNumberOfArguments < 1)
{
TraceMessage( ttError, "Invalid number of arguments supplied to SendIR() interface. Expected 1. Received %d", pPack->m_nNumberOfArguments );
return( hrcFailureAbort );
}
if (!m_bEnabled)
{
return( hrcFailureAbort );
}
//
// Break out the arguments from the argument pack.
unsigned short usIRPosition = (unsigned short)IntFromInterfaceArgument( &(pPack->m_aArguments)[ 0 ] );
HARDWARE_RC rc = hrcSuccess;
//
// Get the specified IRCode from the server. Call the base class to get the info.
IRCode irCode;
if (!GetIRCodeFromPosition( usIRPosition, &irCode ))
{
TraceMessage( ttError, "Unable to retrieve IRCode from server for IR Position %d", usIRPosition );
rc = hrcFailureAbort;
}
else
{
// You now have the IRCode object with the information specific to the IR code.
// Send it to the physical interface and set rc = something appropriate.
}
return( rc );
}
If your interface can receive IR codes, here are a few tips on how to process and notify.
First you will need to get the IR Codes from the server so you have something to match incoming data against. I have not included every method in the code below, but it should give you the general idea.
Code: Select all
// We're using a member variable array 'm_aIRCodes' to hold the IR codes from the server.
// Clear the old array
ClearIRCodeArray();
//
// Check to see how large a buffer we need
DWORD dwBuffSize = 0;
if (GetIRCodes( NULL, &dwBuffSize ) &&
(dwBuffSize))
{
//
// Allocate the array memory
IRCode* pCodes = (IRCode*)malloc( dwBuffSize );
//
// Get fresh data from the server
if (GetIRCodes( pCodes, &dwBuffSize ))
{
for (int nLoop = 0; pCodes[ nLoop ].m_szDescription; nLoop++)
{
// CIRCode is just a simple class to encapsulate the IR code info received from the server.
// It has a constructor to convert from the basic IRCode object.
CIRCode* pCode = new CIRCode;
if (pCode->Init( pCodes+nLoop ))
{
//
// See if it is one of our IR Codes. Generally, there may be something specific
// that was stored in the 'interface specific data' portion of the IR data when the
// code was learned that can identify it as one of our codes.
if (pCode->IsOneOfOurCodes())
{
m_aIRCodes.Add( pCode );
}
else
{
delete pCode;
}
}
else
{
TraceMessage( ttError, "Unable to initialize IR Code [%s].", (IRCode*)(*pCodes+nLoop).m_szDescription );
}
}
}
//
// Delete the memory
free( pCodes );
}
To send a notification to the IRDevice when IR is detected, you must send the 'IR Response Received' notification message as shown below.
Code: Select all
CDataPack DataPack;
DataPack.AddData( "IR Number", [string with IR Number goes here] );
NotifySubscribedDevices( "IR Response Received", "", &DataPack );