Poor man’s weather station

With all the money invested in our Loxone home automation project there currently is no room for a weather station. I need one to steer the heating system. The KNX OT Box of Theben I bought has a program which can take outdoor temperatures into account.

Currently Loxone has a weather service but it is limited to certain countries and the Netherlands is not included (yet). So I started thinking, can I not use weather services on the internet to tell me my local temperature, mold that into a PicoC program and have the service tell my heating the outdoor temperature?

The answer is “Yes you can!”. I’ve cooked up a little PicoC program which will do exactly that. Here’s how to do that:

A WARNING IS IN PLACE HERE! PicoC is not very strict in its syntax checking. A missing curly bracket will still run but gives unpredictable behavior. At one time I had to remove the SD card from the server, format it and reinsert it because my server did not respond to anything anymore. Be careful with what you program and check double check your code before committing it to the server!

You will need an account at a weather service. I used ‘aerisapi.com’. Go to their website and create an account. After you have created your account, register your application and you will get a UserID and UserSecret which will you will need in the code below.

Add a ‘Program’ module to a page in your Loxone Config program.

Loxone Config

Loxone Config

 

I use a lot of Memory flags which help me organize the programming. Here are the settings for the outdoor temperature memory flag. Uncheck the ‘Use as digital flag’. Now you can also change the ‘Unit’ value to reflect the value.

image

Doubleclick the module and paste the program below into the edit window and change the values of <your id> and <your secret> to the values obtained from the website mentioned above.

 

// This programm calls the aerisapi.com weather web service.
// The return value is a JSON string. Since PicoC does not support
// JSON I use scraping of the string to find the values.

enum OutputPorts
{
    Temperature,        // AQ1
    Humidity,            // AQ2
    windKPH             // AQ3
};

int GetIntValue(char *name, int def)
{
    int value = def;

    int pos = strfind(result, name, 0);

    if(pos > 0)
    {
        char *stemp = calloc(1, 10);
        int lenName = strlen(name);

        strncpy(stemp, result + pos + lenName, 5);

        value = atoi(stemp);

        setoutput(Temperature, temp);

        free(stemp);
        stemp = 0;
    }

    printf ("%s = %d", name, value);

    return value;
}

/// <Summary>
/// Main loop.
/// </Summary>
while(TRUE)
{
    char *host = "api.aerisapi.com";
    char *page = "/observations/apeldoorn,nl?client_id=<your id>&client_secret=<your secret>";

    char *result = httpget(host, page);

    if(result != 0)
    {
        int temp = GetIntValue("\"tempC\":", -100);

        if(temp != -100)
        {
            setoutput(Temperature, temp);
        }

        int humidity = GetIntValue("\"humidity\":", -100);

        if(temp != -100)
        {
            setoutput(Humidity, humidity);
        }

        int wind = GetIntValue("\"windKPH\":", -100);

        if(temp != -100)
        {
            setoutput(windKPH, wind);
        }

        free(result);
    }

    // Slow the loop down 10 minutes
    int sleepTime = 10 * 60 * 1000;
    sleep(sleepTime);
}

When you run the code in the server you will see the following in the Log. And the memory flags will show Temperature Celsius, Humidity and Wind velocity.

SNAGHTML8818c0

14 reacties op “Poor man’s weather station

  1. Hi Paul,

    Works well. I’ve been trying to adapt your script to call the setweatherdata() function but without success. Have you had any success with this?

    Cheers,
    Martin

    • Hi Martin,

      No I have not used that. As a matter of fact I did not know of it’s excistance. I’m a bit causious with PicoC programming at the moment since my debacle with the looping miniserver. Because my miniserver is build into a cabinet and I can not reach the SD card easily any mistake on my part will give the risk of crashing the whole system.

      Regards
      Paul

  2. hi there just buy a acurite at home depot my has a 3 in 1 sensore wind temputure humidity only cost $89 very cheap dose not reqier big area

      • We haven’t used Acurite. What I read from the AcuLink is that it work with WiFi. I have not found a WiFi connection to Loxone other then programming it myself in PicoC. I guess it would be possible but have no experience with it.

  3. Pingback: PicoC httpget no longer works

  4. Followed your guide: works like a charm!
    Thanks a lot, this is a nice start using PicoC programs on the Loxone. Now trying to write one that sends via RS232 a string to Velleman K8056 relayboards

    • Strange, I always get the weather observations for the city of vlissingen,nl instead of ledeberg,be. The gps coordinates are correct though: {“success”:true,”error”:null,”response”:{“id”:”EHFS”,”loc”:{“long”:3.6,”lat”:51.45},”place”:{“name”:”vlissingen”,”state”:””,”country”:”nl”},”profile”:{“tz”:”Europe\/Amsterdam”,”elevM”:32,”elevFT”:105},”obTimestamp”:1451692500,”obDateTime”:”2016-01-02T00:55:00+01:00″,”ob”:{“timestamp”:1451692500,”dateTimeISO”:”2016-01-02T00:55:00+01:00″,”tempC”:8,”tempF”:46,”dewpointC”:6,”dewpointF”:43,”humidity”:87,”pressureMB”:1020,”pressureIN”:30.12,”spressureMB”:1016,”spressureIN”:30,”altimeterMB”:null,”altimeterIN”:null,”windKTS”:16,”windKPH”:30,”windMPH”:18,”windSpeedKTS”:16,”windSpeedKPH”:30,”windSpeedMPH”:18,”windDirDEG”:210,”windDir”:”SSW”,”windGustKTS”:null,”windGustKPH”:null,”windGustMPH”:null,”flightRule”:”LIFR”,”visibilityKM”:7,”visibilityMI”:4.35,”weather”:”Mostly Clear”,”weatherShort”:”Mostly Clear”,”weatherCoded”:”::FW”,”weatherPrimary”:”Mostly Clear”,”weatherPrimaryCoded”:”::FW”,”cloudsCoded”:”FW”,”icon”:”pcloudyn.png”,”heatindexC”:8,”heatindexF”:46,”windchillC”:8,”windchillF”:46,”feelslikeC”:8,”feelslikeF”:46,”isDay”:false,”sunrise”:1451721040,”sunriseISO”:”2016-01-02T08:50:40+01:00″,”sunset”:1451749711,”sunsetISO”:”2016-01-02T16:48:31+01:00″,”snowDepthCM”:null,”snowDepthIN”:null,”precipMM”:null,”precipIN”:null,”solradWM2″:null,”sky”:19,”light”:0},”raw”:”EHFS 312355Z AUTO 21016KT 7000 FEW035\/\/\/ 08\/06 Q1020″,”relativeTo”:{“lat”:51.03859,”long”:3.74458,”bearing”:348,”bearingENG”:”NNW”,”distanceKM”:46.841,”distanceMI”:29.106}}}

      I found out this morning, because the Aerisweather windspeed indicated 30 km/h, whilst there was no wind at all around my house.

      The request I used was “/observations/Ledeberg,be?client_id=J4s4P7gg…….&client_secret=kAJuJJJmBiE…F0”;

      With “/Apeldoorn,nl” I also arrive in vlissingen.

      Any thoughts ?

  5. Tested for “Gent,Belgium” on Aeris website http://wx.aerisweather.com/?pands=gent
    This works ok for the webpage, but not as a JSON string: there I get “vlissingen,nl” again.
    I made a support ticket with Aeris, and while waiting if they solve it, the location “Brussels,Belgium” works.

    If Aeris does not come up with a solution, I can adapt the program for the WUnderground weather service, they also offer JSON output from their api, also with a free developer license.

  6. Hi thank you very much for sharing. I implemented the code and worked beautifully, I was just wondering you were able to get the reading to show the decimal point? Ie. 20.50, versus just 20?

    • Hi Inder,

      I was never bothered by that but you could write a more sophisticated conversion routine for the string to numeric value.

      I personally am not using this code anymore. We now use the Loxone Weather service. Is expensive but works very well.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *