/*! * \file CayenneLpp.c * * \brief Implements the Cayenne Low Power Protocol * * \copyright Revised BSD License, see section \ref LICENSE. * * \code * ______ _ * / _____) _ | | * ( (____ _____ ____ _| |_ _____ ____| |__ * \____ \| ___ | (_ _) ___ |/ ___) _ \ * _____) ) ____| | | || |_| ____( (___| | | | * (______/|_____)_|_|_| \__)_____)\____)_| |_| * (C)2013-2018 Semtech * * \endcode * * \author Miguel Luis ( Semtech ) */ #include #include "utilities.h" #include "CayenneLpp.h" #define CAYENNE_LPP_MAXBUFFER_SIZE 242 static uint8_t CayenneLppBuffer[CAYENNE_LPP_MAXBUFFER_SIZE]; static uint8_t CayenneLppCursor = 0; void CayenneLppInit( void ) { CayenneLppCursor = 0; } void CayenneLppReset( void ) { CayenneLppCursor = 0; } uint8_t CayenneLppGetSize( void ) { return CayenneLppCursor; } uint8_t* CayenneLppGetBuffer( void ) { return CayenneLppBuffer; } uint8_t CayenneLppCopy( uint8_t* dst ) { memcpy1( dst, CayenneLppBuffer, CayenneLppCursor ); return CayenneLppCursor; } uint8_t CayenneLppAddDigitalInput( uint8_t channel, uint8_t value ) { if( ( CayenneLppCursor + LPP_DIGITAL_INPUT_SIZE ) > CAYENNE_LPP_MAXBUFFER_SIZE ) { return 0; } CayenneLppBuffer[CayenneLppCursor++] = channel; CayenneLppBuffer[CayenneLppCursor++] = LPP_DIGITAL_INPUT; CayenneLppBuffer[CayenneLppCursor++] = value; return CayenneLppCursor; } uint8_t CayenneLppAddDigitalOutput( uint8_t channel, uint8_t value ) { if( ( CayenneLppCursor + LPP_DIGITAL_OUTPUT_SIZE ) > CAYENNE_LPP_MAXBUFFER_SIZE ) { return 0; } CayenneLppBuffer[CayenneLppCursor++] = channel; CayenneLppBuffer[CayenneLppCursor++] = LPP_DIGITAL_OUTPUT; CayenneLppBuffer[CayenneLppCursor++] = value; return CayenneLppCursor; } uint8_t CayenneLppAddAnalogInput( uint8_t channel, float value ) { if( ( CayenneLppCursor + LPP_ANALOG_INPUT_SIZE ) > CAYENNE_LPP_MAXBUFFER_SIZE ) { return 0; } int16_t val = ( int16_t ) ( value * 100 ); CayenneLppBuffer[CayenneLppCursor++] = channel; CayenneLppBuffer[CayenneLppCursor++] = LPP_ANALOG_INPUT; CayenneLppBuffer[CayenneLppCursor++] = val >> 8; CayenneLppBuffer[CayenneLppCursor++] = val; return CayenneLppCursor; } uint8_t CayenneLppAddAnalogOutput( uint8_t channel, float value ) { if( ( CayenneLppCursor + LPP_ANALOG_OUTPUT_SIZE ) > CAYENNE_LPP_MAXBUFFER_SIZE ) { return 0; } int16_t val = ( int16_t ) ( value * 100 ); CayenneLppBuffer[CayenneLppCursor++] = channel; CayenneLppBuffer[CayenneLppCursor++] = LPP_ANALOG_OUTPUT; CayenneLppBuffer[CayenneLppCursor++] = val >> 8; CayenneLppBuffer[CayenneLppCursor++] = val; return CayenneLppCursor; } uint8_t CayenneLppAddLuminosity( uint8_t channel, uint16_t lux ) { if( ( CayenneLppCursor + LPP_LUMINOSITY_SIZE ) > CAYENNE_LPP_MAXBUFFER_SIZE ) { return 0; } CayenneLppBuffer[CayenneLppCursor++] = channel; CayenneLppBuffer[CayenneLppCursor++] = LPP_LUMINOSITY; CayenneLppBuffer[CayenneLppCursor++] = lux >> 8; CayenneLppBuffer[CayenneLppCursor++] = lux; return CayenneLppCursor; } uint8_t CayenneLppAddPresence( uint8_t channel, uint8_t value ) { if( ( CayenneLppCursor + LPP_PRESENCE_SIZE ) > CAYENNE_LPP_MAXBUFFER_SIZE ) { return 0; } CayenneLppBuffer[CayenneLppCursor++] = channel; CayenneLppBuffer[CayenneLppCursor++] = LPP_PRESENCE; CayenneLppBuffer[CayenneLppCursor++] = value; return CayenneLppCursor; } uint8_t CayenneLppAddTemperature( uint8_t channel, float celsius ) { if( ( CayenneLppCursor + LPP_TEMPERATURE_SIZE ) > CAYENNE_LPP_MAXBUFFER_SIZE ) { return 0; } int16_t val = ( int16_t) ( celsius * 10 ); CayenneLppBuffer[CayenneLppCursor++] = channel; CayenneLppBuffer[CayenneLppCursor++] = LPP_TEMPERATURE; CayenneLppBuffer[CayenneLppCursor++] = val >> 8; CayenneLppBuffer[CayenneLppCursor++] = val; return CayenneLppCursor; } uint8_t CayenneLppAddRelativeHumidity( uint8_t channel, float rh ) { if( ( CayenneLppCursor + LPP_RELATIVE_HUMIDITY_SIZE ) > CAYENNE_LPP_MAXBUFFER_SIZE ) { return 0; } CayenneLppBuffer[CayenneLppCursor++] = channel; CayenneLppBuffer[CayenneLppCursor++] = LPP_RELATIVE_HUMIDITY; CayenneLppBuffer[CayenneLppCursor++] = (uint8_t ) ( rh * 2 ); return CayenneLppCursor; } uint8_t CayenneLppAddAccelerometer( uint8_t channel, float x, float y, float z ) { if( ( CayenneLppCursor + LPP_ACCELEROMETER_SIZE ) > CAYENNE_LPP_MAXBUFFER_SIZE ) { return 0; } int16_t vx = ( int16_t ) ( x * 1000 ); int16_t vy = ( int16_t ) ( y * 1000 ); int16_t vz = ( int16_t ) ( z * 1000 ); CayenneLppBuffer[CayenneLppCursor++] = channel; CayenneLppBuffer[CayenneLppCursor++] = LPP_ACCELEROMETER; CayenneLppBuffer[CayenneLppCursor++] = vx >> 8; CayenneLppBuffer[CayenneLppCursor++] = vx; CayenneLppBuffer[CayenneLppCursor++] = vy >> 8; CayenneLppBuffer[CayenneLppCursor++] = vy; CayenneLppBuffer[CayenneLppCursor++] = vz >> 8; CayenneLppBuffer[CayenneLppCursor++] = vz; return CayenneLppCursor; } uint8_t CayenneLppAddBarometricPressure( uint8_t channel, float hpa ) { if( ( CayenneLppCursor + LPP_BAROMETRIC_PRESSURE_SIZE ) > CAYENNE_LPP_MAXBUFFER_SIZE ) { return 0; } int16_t val = ( int16_t ) ( hpa * 10 ); CayenneLppBuffer[CayenneLppCursor++] = channel; CayenneLppBuffer[CayenneLppCursor++] = LPP_BAROMETRIC_PRESSURE; CayenneLppBuffer[CayenneLppCursor++] = val >> 8; CayenneLppBuffer[CayenneLppCursor++] = val; return CayenneLppCursor; } uint8_t CayenneLppAddGyrometer( uint8_t channel, float x, float y, float z ) { if( ( CayenneLppCursor + LPP_GYROMETER_SIZE ) > CAYENNE_LPP_MAXBUFFER_SIZE ) { return 0; } int16_t vx = ( int16_t ) ( x * 100 ); int16_t vy = ( int16_t ) ( y * 100 ); int16_t vz = ( int16_t ) ( z * 100 ); CayenneLppBuffer[CayenneLppCursor++] = channel; CayenneLppBuffer[CayenneLppCursor++] = LPP_GYROMETER; CayenneLppBuffer[CayenneLppCursor++] = vx >> 8; CayenneLppBuffer[CayenneLppCursor++] = vx; CayenneLppBuffer[CayenneLppCursor++] = vy >> 8; CayenneLppBuffer[CayenneLppCursor++] = vy; CayenneLppBuffer[CayenneLppCursor++] = vz >> 8; CayenneLppBuffer[CayenneLppCursor++] = vz; return CayenneLppCursor; } uint8_t CayenneLppAddGps( uint8_t channel, float latitude, float longitude, float meters ) { if( ( CayenneLppCursor + LPP_GPS_SIZE ) > CAYENNE_LPP_MAXBUFFER_SIZE ) { return 0; } int32_t lat = ( int32_t ) ( latitude * 10000 ); int32_t lon = ( int32_t ) ( longitude * 10000 ); int32_t alt = ( int32_t ) ( meters * 100 ); CayenneLppBuffer[CayenneLppCursor++] = channel; CayenneLppBuffer[CayenneLppCursor++] = LPP_GPS; CayenneLppBuffer[CayenneLppCursor++] = lat >> 16; CayenneLppBuffer[CayenneLppCursor++] = lat >> 8; CayenneLppBuffer[CayenneLppCursor++] = lat; CayenneLppBuffer[CayenneLppCursor++] = lon >> 16; CayenneLppBuffer[CayenneLppCursor++] = lon >> 8; CayenneLppBuffer[CayenneLppCursor++] = lon; CayenneLppBuffer[CayenneLppCursor++] = alt >> 16; CayenneLppBuffer[CayenneLppCursor++] = alt >> 8; CayenneLppBuffer[CayenneLppCursor++] = alt; return CayenneLppCursor; }