Client for the DeviceHubNet gateway. (You need the gateway SW as well!)

Dependents:   DeviceHubNet_DEMO

DeviceHubNet.h

Committer:
gume
Date:
2017-04-04
Revision:
1:5dca66437dd1
Parent:
0:093f1cb20c52

File content as of revision 1:5dca66437dd1:

/**
 * @file DeviceHubNet.h
 *
 * Class declaration for DeviceHubNet
 */

#ifndef __DEVICEHUBNET_H__
#define __DEVICEHUBNET_H__

#include <mbed.h>
#include "RF24.h"
#include <list>
#include <map>
#include <string>

#define BROADCAST_ADDRESS_LL 0x3333333333LL
#define NETWORK_PREFIX 0x424D45L    // All network node has a common 3 byte address prefix

#define PACKET_PING 1
#define PACKET_PONG 2
#define PACKET_DATA 3
#define PACKET_REGISTER 4
#define PACKET_UNREGISTER 5
#define PACKET_REGISTERERROR 6
#define PACKET_ERROR 15


struct __attribute__((__packed__)) Message {
    uint16_t sourceAddress;
    uint8_t type;
    uint8_t counter;
    uint8_t payload[28];
};

struct __attribute__((__packed__)) MsgRegister {
    uint8_t rType;  // 1: Project, 2: Device, 3: Sensor, 4: Actuator
    uint8_t id[27];
};

struct __attribute__((__packed__)) MsgData {
    uint16_t sensorId;
    uint8_t dType;  // 0: Digital, 1: Analog
    union {
        uint8_t ddata;
        float adata;
    } data;
};

/**
 * Driver for DeviceHubNet
 */

class DeviceHubNet
{
private:
    uint32_t projectId;
    uint8_t apiKey[16];
    uint8_t deviceId[16];
    uint16_t nextSId;       // Increasing sensor IDs

    map<uint16_t, string> sensors;
    map<uint16_t, string> actuators;
    map<uint16_t, void*> actuator_cbs;
    map<uint16_t, uint8_t> actuator_types;

    RF24 *radio;
    uint16_t nodeAddress;
    uint8_t msgCounter;

    int readHex(char *hexStr, uint8_t *hex);
    bool sendData(uint8_t type, uint8_t *data, uint8_t len);
    uint64_t getFullAddress();
    uint64_t getGWAddress();

    void registerProject();
    void registerDevice();

protected:

    void reRegisterSensor(uint16_t sensorId);
    void reRegisterActuator(uint16_t actuatorId);

public:

    /**
     * @name DeviceHubNet public interface
     *
     *  These are the main function in order to send/receive data to the gateway
     *  The gateway will handle the communication to devicehub.net
     *
     *  The code does not work without the running gateway!
     */
    /**@{*/

    /**
     * DeviceHubNet Constructor
     *
     * Creates a new instance of this driver. At the moment only 1 device per driver
     * The device might have multiple sensors and actuators
     *
     * @param projectId The projectId on the devicehub.net site
     * @param apikey The 16 byte long APIkey on the devicehub.net site
     * @param apikey The 16 byte long deviceID on the devicehub.net site
     */
    DeviceHubNet(uint32_t projectId, uint8_t* apiKey, uint8_t* deviceId);

    /**
     * DeviceHubNet Constructor
     *
     * Creates a new instance of this driver. At the moment only 1 device per driver.
     * The device might have multiple sensors and actuators.
     *
     * @param projectId The projectId on the devicehub.net site
     * @param apikey The string representation of the APIkey on the devicehub.net site
     * @param apikey The string representation of the deviceID on the devicehub.net site
     *
     * @code DeviceHubNet DHN(4275, "bbbb950b-ad0c-4fcd-8f0a-546e154a1c35", "40854b01-0ff4-407f-bc63-fa75f6604ec4"); @endcode
     */
    DeviceHubNet(uint32_t projectId, char* apiKeyStr, char* deviceIdStr);
    
    virtual ~DeviceHubNet() {};

    /**
     * Set pins for the radio communication
     *
     * This should be called before radioConfig() !
     *
     * @param mosi The pin attached to SPI MOSI (Master Output)
     * @param miso The pin attached to SPI MISO (Slave Input)
     * @param sck The pin attached to SPI CLK (Clock)
     * @param cs The pin attached to Chip Select
     * @param ce The pin attached to Chip Enable
     */
    bool radioPinConfig(PinName mosi, PinName miso, PinName sck, PinName cs, PinName ce);
    
    /**
     * Set node address and channel for the radio communication and
     * initialize the radio interface
     *
     * radioPinConfig() should be callled first!
     * This module and the gateway should be on the same channel!
     *
     * @param address Unique 2 byte address (0-65525)
     * @param channel Radio channel (0-127)
     */    
    bool radioConfig(uint16_t address, uint8_t channel);

    /**
     * Dump radio modul configuration paramters using the stdout
     *
     */    
    void radioDump();
    
    /**
     * Process incoming messages and activates callbacks
     *
     * This function should be called frequently from the main code.
     */    
    void processMsgs();

    /**
     * Register a sensor on the device
     *
     * Sensor name should be the same as the one registered on devicehub.net
     *
     * @param sensorName name of the sensor
     * @return sensor ID, which can be used to send data to devicehub.net
     *
     * @code
     * uint16_t sid = DHN.registerSensor("LightSense");
     * DHN.sendDigitalData(sid, 1);
     * @endcode
     */    
    uint16_t registerSensor(char* sensorName);

    /**
     * Register an actuator on the device
     *
     * Actuator name should be the same as the one registered on devicehub.net
     * Digital actuators get 0 or 1, Analog actuators get a float value
     
     * @param actuatorName name of the actuator
     * @param type type of the actuator. 0: Digital,1: Analog
     * @param onReceive callback function for incoming messages
     * @return actuator ID, which is not used at the moment
     *
     * @code
     * void onLightSwitchMsg(uint8_t type, uint8_t ddata, float adata)
     * {
     *   pc.printf("Data received.");
     * }
     *     
     * uint16_t aid = DHN.registerActuator("LightSwitch", 0, &onLightSwitchMsg);
     * @endcode
     */    
    uint16_t registerActuator(char *actuatorName, uint8_t type, void (*onReceive)(uint8_t, uint8_t, float));


    /**
     * Send digital data to a virtual sensor on devicehub.net
     *
     * @param sensorId sensor ID, coming from the registerSensor() function
     * @param data sensor data. Should be 0 or 1 for digital devices
     *
     */    
    bool sendDigitalData(uint16_t sensorId, uint8_t data);

    /**
     * Send analog data to a virtual sensor on devicehub.net
     *
     * @param sensorId sensor ID, coming from the registerSensor() function
     * @param data sensor data. Should be a float value for analog devices
     *
     */    
    bool sendAnalogData(uint16_t sensorId, float data);

    /**@}*/

};

#endif