Renesas GR-Peach integrated with dweet.io

Dependencies:   EthernetInterfaceprivate HTTPClient PubNub mbed-rtos mbed picojson spxml

main.cpp

Committer:
nikhilchaturtvedi
Date:
2015-10-23
Revision:
0:675ae62a5261

File content as of revision 0:675ae62a5261:

#include "HTTPClient.h"
#include "picojson.h"
#include "spdomparser.hpp"
#include "spxmlnode.hpp"
#include "spxmlhandle.hpp"
#include "PubNub.h"
#include "mbed.h"
#include "EthernetInterface.h"

/*****Function defs*****/
void read_temp();
char* get_time();
void get_weather();
void parseWeather(SP_XmlElementNode *node);
void read_and_execute_message(PubNub &pn, const char *jsonmsg);
void publish_to_pubnub(PubNub &pn);
int pubnub_main();
/***********************/

/********Change these values accordingly********/
const char* ip_address = "143.103.6.188"; //change to your ip address
const char* subnet     = "255.255.255.0"; 
const char* gateway    = "143.103.6.254"; //change this
/***********************************************/

/*********Keys for PubNub************/
const char pubkey[] = "pub-c-0fee6373-fae0-4aa9-9fe9-b9b48605a82f"; //fill from the pubnub application
const char subkey[] = "sub-c-62761692-404d-11e5-976c-02ee2ddab7fe"; //fill from the pubnub application
const char channel[] = "peach-channel"; //name given to your channel
/************************************/

Serial pc_console(USBTX, USBRX);
EthernetInterface ethernet;

/*Temp sensor ; for this example, used a MAX31723 sensor interfaced through SPI*/
SPI temp_sensor(P4_6, P4_7, P4_4);
DigitalOut chip_select(P4_5);

PubNub pubnub(pubkey, subkey);


int main()
{
    pc_console.baud(115200); //set the serial com baud rate

    ethernet.init(ip_address, subnet, gateway);
    pc_console.printf("Init eth\n");

    ethernet.connect();
    pc_console.printf("Connected eth\n");
    
    pubnub_main(); //start the PubNub main loop

}

/*Publish a message to PubNub*/
void publish_to_pubnub(PubNub &pubnub)
{
    char message[128];
    PubNubRes ret = pubnub.publish(channel, message);
    if (ret != PNR_OK) {}

}

/*Read message from PubNub and perform an operation*/
void read_and_execute_message(PubNub &pubnub, const char *message)
{
    picojson::value msg;
    std::string err = picojson::parse(msg, message, message + strlen(message));
    if (!err.empty()) {
        return;
    }

    /*Use this message to read temp sensor value and send it to PubNub*/
    if (msg.get("send_temperature").get<bool>()) 
    {
        publish_to_pubnub(pubnub);
    }
    /*Use this message to read the weather from openweather service and send the values to dweet.io
     The message sent from PubNub console is { "weather": "get" }*/
    if(msg.get("weather").is<std::string>())
    {
        get_weather();
    }
}

/*The main PubNub loop function*/
int pubnub_main()
{

    publish_to_pubnub(pubnub);
    pc_console.printf("publish done\n");

    while (1) 
    {

        pc_console.printf("Subscribing\n");

        char *reply = NULL;
        PubNubRes result = pubnub.subscribe(channel, &reply);
        if (result != PNR_OK) {

            pc_console.printf("Error %d \n", result);
            wait(1.0);
            continue; //try again
        }

        if (reply) 
        {
            read_and_execute_message(pubnub, reply);
        }

        wait(2); // just to avoid unnecessary busy loops
    }
}

void get_weather()
{
    HTTPClient weather_client;
    char weather_message[128] = "";
    char weather_response[812];
    picojson::value msg;
    
    sprintf(weather_message,"http://api.openweathermap.org/data/2.5/weather?q=%s,%s&mode=xml", "London", "uk");
    pc_console.printf("URL %s\n", weather_message);
    HTTPResult result;
    
    result = weather_client.get(weather_message, weather_response, sizeof(weather_response));
    
    pc_console.printf("Resp %s %d\n", weather_response, strlen(weather_response));
   
    if(!result)
    {
        pc_console.printf("Weather response %s \n", weather_response);
    }
    else
    {
        pc_console.printf("Error code %d - %d - %s \n", result, weather_client.getHTTPResponseCode(), weather_response);
    }
    
    /*Parse the XML from openweather service
    * Parsing is done here just for simplicity's sake*/
    SP_XmlDomParser parser;
    parser.append(weather_response, strlen(weather_response));
    
    SP_XmlHandle rootHandle(parser.getDocument()->getRootElement());
    
    SP_XmlElementNode *city_child = rootHandle.getChild("city").toElement();
    SP_XmlElementNode *city_coord_child = rootHandle.getChild("city").getChild("coord").toElement();
    
    SP_XmlElementNode *temperature_child;
    
    temperature_child = rootHandle.getChild("temperature").toElement();    
    pc_console.printf("Child %s\n", temperature_child->getAttrValue("value"));
    pc_console.printf("Temp unit %d\n", temperature_child->getAttrValue("unit"));
    
    SP_XmlElementNode *humidity_child = rootHandle.getChild("humidity").toElement();
    
    SP_XmlElementNode *wind_child = rootHandle.getChild("wind").getChild("speed").toElement();
    pc_console.printf("Wind speed %s\n", wind_child->getAttrValue("value"));
    pc_console.printf("Wind name %s\n", wind_child->getAttrValue("name"));
    
    SP_XmlElementNode *wind_direction_child = rootHandle.getChild("wind").getChild("direction").toElement();
    pc_console.printf("Wind direction %s\n", wind_direction_child->getAttrValue("name"));
    
    SP_XmlElementNode *sky_child = rootHandle.getChild("weather").toElement();
    pc_console.printf("Weather type %s\n", sky_child->getAttrValue("value"));
    
    char dweet_resp[512];
    char message_to_dweet[128] = "";
    char thing_name[] = "Peach"; //name of the "thing" on dweet; change this for your own "thing name"
    
    /*Uploading only the city name, temperature and its unit; can upload many more parsed values in the same format as below
    Also, time stamp for the update can be posted by using the get_time() function*/
    sprintf(message_to_dweet,"http://dweet.io/dweet/for/%s?City=%s&Temperature=%s&TempUnit=%s", 
            thing_name, city_child->getAttrValue("name"),
            temperature_child->getAttrValue("value"), 
            temperature_child->getAttrValue("unit"));
    
    pc_console.printf("Sending to dweet %s\n",message_to_dweet);
    HTTPClient http;
    int response = http.get(message_to_dweet, dweet_resp, sizeof(dweet_resp));

    if(!response) 
    {
        pc_console.printf("Response from dweet %s \n", dweet_resp);
    } else 
    {
        pc_console.printf("Error %d - HTTP response code = %d\n", response, http.getHTTPResponseCode());
    }
    
    wait(2);
}

/*Simple helper function for getting a child node*/
char* get_child_value(SP_XmlElementNode *node, char *value)
{
    return (char*)node->getAttrValue(value);
}


/*Get the time for having a timestamp for dweet.io updates*/
char* get_time()
{
    time_t seconds = time(NULL);
    pc_console.printf("Seconds %d", seconds);
    pc_console.printf("Time %s"  ,ctime(&seconds));
    
    char time_buf[32];
    strftime(time_buf, sizeof(time_buf), "%I %M %p \n", localtime(&seconds));
    pc_console.printf("Formatted time %s \n", time_buf);
    
    return ctime(&seconds);
}

/*Unimplemented temp sensor read function; use it for your own sensor device*/
void read_temp()
{}