Monday, 30 April 2012

Temporary wifi solution

While I'm waiting for the parts to arrive for me to build the real wifi controller board, I found this temporary solution in the local computer shop today.
Vonets VAP11G
It's a wifi ethernet bridge, and at around $25 I thought it was worth a shot. Sadly I can't put it to use tonight as the little CD only has software to configure it from a windows machine and frankly, I don't have any of those laying around..


I'll sort it out tomorrow, until then have a look at what Simon has been doing with google calendar.
http://simonslinuxworld.blogspot.se/2012/04/google-command-line-tools-google.html

Wednesday, 25 April 2012

mBed - Google API source code

A few people have asked me to post the source code. Here it is. Even though I have been programming for years in various database and IBM mainframe languages, I've never done much C, so feel free to send me a few tips. I'm not sure why, for example, it works only when ctTime and buffer[21] are declared outside of the subroutine they're used in??


All the libraries used can all be found on the mbed website.


#include "mbed.h"
#include "DS18B20.h"
#include "DS18S20.h"
#include "OneWireDefs.h"
#include "EthernetNetIf.h"
#include "HTTPClient.h"
#include "NTPClient.h"

#define THERMOMETER DS18S20
#define HOSTNAME "mbed"
string calendar = "<<< YOUR CALENDAR PRIVATE ADDRESS >>>";

EthernetNetIf eth(HOSTNAME);
HTTPClient http;
NTPClient ntp;
THERMOMETER device(true, false, false, p21);

DigitalOut led1(LED1, "led1");
DigitalOut led2(LED2, "led2");
DigitalOut led3(LED3, "led3");
DigitalOut led4(LED4, "led4");

DigitalOut heater(p10);
time_t ctTime;
char buffer[21];
int targetTemp = 0;

string getURL() {
    char url[256];
    char endTime[21];
    char startTime[21];
    ctTime = time(NULL);
    strftime(buffer, 20, "%Y-%m-%dT%H:%M:00Z", localtime(&ctTime));
    strcpy(startTime,buffer);
    ctTime = time(NULL)+60;
    strftime(buffer, 20, "%Y-%m-%dT%H:%M:00Z", localtime(&ctTime));
    strcpy(endTime,buffer);      
    //printf("start %s\n",startTime);
    //printf("end   %s\n",endTime);
    sprintf(url, "%s?start-min=%s&start-max=%s", calendar, startTime, endTime);
    //printf("url   %s\n",url);
    return url;
}

string getPage(char url[256]) {
    printf("\nQuery Google API... \n");
    HTTPText txt("text/html",5000);
    HTTPResult r = http.get(url, &txt);
  
    if (r==HTTP_OK) {
       printf("Result Ok\n");
       led2 = 0;
       return txt.gets();
    } else {
       printf("Error %d\n",r);
       led2 = 1;
       return "FAIL";
    }
}

void getAPI() {
    string testres;
    string results;
    char to[3];
    char url[256];
    strcpy(url,(char*)getURL().c_str());
    results = getPage(url);
    //printf("results API %s\n",results);
   
    if (results == "FAIL") {
       printf("%s\n","Bad Result");
       // Make no changes to the target temperature
    } else {
       testres = strstr(results.c_str(),"<title type='html'>");
       //printf("\n\n\n%s\n",testres);
       if (testres == "") {
          // no temperature set for this time
          printf("%s\n","No calendar entry for this time");
          targetTemp = 0;
          led3 = 0;
       } else {
          // grab the temperature (this assumes I've entered a 2 digit int in the event title)
          strncpy(to, testres.c_str()+19, 2);
          printf("result: %s\n", to);
          targetTemp = atoi(to);
          led3 = 1;
       }
    }
}

void getNTP() {
    ctTime = time(NULL);
    printf("Current time is (UTC): %d %s\n", ctTime, ctime(&ctTime));
    printf("NTP setTime...\n");
    Host server(IpAddr(), 123, "pool.ntp.org");
    printf("Result : %d\n", ntp.setTime(server));
    ctTime = time(NULL);
    printf("Time is now (UTC): %d %s\n", ctTime, ctime(&ctTime));
}

void checkTemperature() {
    float temp = device.readTemperature();
    if (temp > (targetTemp+0.5)) {
       heater = 0;
       led4 = 0;
    }
    if (temp < targetTemp) {
       heater = 1;
       led4 = 1;
    }
}

int main() {
    EthernetErr ethErr;
    int count = 0;
    do {
        printf("Setting up %d...\n", ++count);
        ethErr = eth.setup();
        if (ethErr) printf("Timeout\n", ethErr);
    } while (ethErr != ETH_OK);

    printf("Connected OK\n");
    const char* hwAddr = eth.getHwAddr();
    printf("HW address : %02x:%02x:%02x:%02x:%02x:%02x\n",
           hwAddr[0], hwAddr[1], hwAddr[2],
           hwAddr[3], hwAddr[4], hwAddr[5]);

    IpAddr ethIp = eth.getIp();
    printf("IP address : %d.%d.%d.%d\n", ethIp[0], ethIp[1], ethIp[2], ethIp[3]);
    printf("Check router DHCP table for name : %s\n", eth.getHostname());

    getNTP();
    getAPI();
   
    Timer pollTemp;
    pollTemp.start();
    Timer pollAPI;
    pollAPI.start();
    Timer pollNTP;
    pollNTP.start();
    Timer lookAlive;
    lookAlive.start();
   
    while (true) {
        if (lookAlive.read() > 1) {
           led1 = !led1;
           lookAlive.start();
        }
        if (pollTemp.read() > 10) {
            checkTemperature();
            pollTemp.start();
        }
        if (pollAPI.read() > 30) {
            getAPI();
            printf("Target Temp: %i\n",targetTemp);
            pollAPI.start();
        }
        if (pollNTP.read() > 21000) {
            pollNTP.start();
            getNTP();
        }
    }
}

Tuesday, 24 April 2012

The Google API and smartphone features

The Google API developers guide is a scary read at first if you're about to program in C and you're not a C programmer, but I discovered a much easier way to play with this.

https://developers.google.com/google-apps/calendar/v2/developers_guide_protocol

It talks about oAuth and fun things like this, but I discovered that you don't have to authenticate if you use the xml private address found on your calendar settings page.

Getting the Private address
Now you can use any of the read-only API features as GET requests from google calendar. On the mBed I set the realtime clock using NTP and then format the time in RFC 3339, then the time plus one minute. It will return an XML of a event that is current.

https://developers.google.com/google-apps/calendar/v2/reference#Parameters

example:
?start-min=2012-04-21T18:30:00%2b10:00&start-max=2012-04-21T18:31:00%2b10:00



So far so good. The final feature I wanted was the ability to enter events using my smart phone. Here's the time where I'm going to have to mention that I don't have an Android or open source smart phone, I carry an iPhone... *hides*

There were a few websites that I found useful getting multiple google calendars to sync with my phone's calendar. Have a read and you'll work it out.


Setting up google sync on iOS:
http://support.google.com/mobile/bin/answer.py?hl=en&answer=138740

Using google sync with multiple calendars:
http://support.google.com/mobile/bin/answer.py?hl=en&answer=139206


Finally, I've ordered some more bits to make the mBed connect via my wireless network as I don't currently have a wired one. Right now I'm using a computer as a wireless bridge and connecting the mBed using a crossover cable. These parts should arrive early next week.

Wiring it up - Heater Automation

In the video posted below, I was controlling the heater by simply cutting the power supply to it. This was good because it meant that I hadn't played around with the built in safety features, but bad because it beeped every time the power cycled. Time to break out the screwdrivers!

The built in controller
The built in controller is fairly simple and I quickly figured out which was the signal between the two boards that caused the relay to switch. I then had a think about if it was safe to drive that relay myself, or should I be putting a second on in series with it, meaning I've got a fail safe with the on board temperature controller if my controller forgot to switch it off. I can wind the on board one up to a temperature at the highest level that I'll ever want, and that is as hot as the room will get in the event of a failure.

40A Solid State relay
I discovered when I went to my local electronics shop that they had some rather grunty solid state relays available for around $45 each. I grabbed a handful of 40A AC ones and one 100A DC for another project.

It fits in the space!! :)
As I said, I wired it in series with the existing controller for safety reasons. I'm not much of a C programmer so I figured this was the best option.

Wired up, taped up, stuck in

Ready to play

Google Calendar Automation - part 1

I've been thinking about what automated features I'd like in my new house which I hope to build in the coming year. This is the first of many ideas, programming the schedule and temperature of my heating using Google Calendar!

I'm using an mBed in this video, but I've also got another board which is being designed by my friend Stu. Watch this space


I'll post some photos soon, tomorrow I'll be pulling the heater apart to wire it up properly. In the video you'll notice a 'beep' when it cuts in and out. This is not a desirable feature which is about to get fixed.