Fieldcimate

Developing Your Own Applications

 

PIKernel Data Interface makes it easy to develop

·       Customized Back-End applications

·       Disease and Forecast Modules

·       Data Conversion Modules

·       Database Replication Modules

·       Interfaces to 3rd party software

 

 

Get instant access to your iMetos weather data programmatically

·        From any device connected to internet

·        Without database

·        Without web hosting

·        Using any development tool

Table of Content

Introduction 

More on SOAP 

Why Not Simple XML? 

Foreword For Windows Developers 

General Description of Data Structures 

PHP Class Library 

Reading the List of Stations 

Getting Configuration of Station 

Getting Sensors Info 

Getting Weather Data 

Diesease Models and Weather Forecast

Versions of PHP 

Putting all together 

Introduction

PIKernel Data Interface is a SOAP based interface to access the climate data of the weather stations. Developers can access it directly through WSDL (see SOAP description). This assumes some familiarity with SOAP Protocol. The interface covers all aspects of iMetos data. It includes list of stations, its parameters and, of course, weather data. Weather data can be read in any portion in different format from any date. It can be grouped by hour, day or month. Page-like navigation is very easy as interface provides possibility to read previous and next block relatively to the last block read.

As of March 2007 the data interface is read-only. It is not possible to set parameters of the weather station or store any data.

For PHP developers, Pessl Instruments offers a library of classes that greatly simplifies the development process. Using this library you don't need to learn anything about underlying protocols and can access fieldclimate data as if it were located on the same computer with your application. All calls are internally translated to SOAP and dispatched to the fieldclimate web site. The classes are arranged in a very convenient way and PHP developers will feel comfortable working with them. Those, who are eager to start digging the source code, please refer to a sample application at index.php

Pessl Instruments is planning to develop similar libraries for VB, Delphi and Java developers. If you want to participate in this work, you are very welcome. We will be happy to receive your proposals at software@metos.at . Specially, we need Java specialists with SOAP experience.

More on SOAP

If you never heard of SOAP here are some highlights

SOAP

·        Is a [simple?] XML-based protocol to let applications exchange information

·        Is a web consortium standard

·        Supported by many popular development tools like Delphi, Visual Basic, PHP, .NET, Java etc.

·        Used by many industrial web services and well understood by web development community

·        Microsoft .NET framework mainly relies on SOAP for remote procedure calls and natively supports it

For more information you can have a look at

http://en.wikipedia.org/wiki/SOAP - Short description of SOAP features

http://www.w3.org/TR/soap12-part0/ - SOAP specification from WWW consortium

 

 

The WSDL file is located at http://metos.at/cidiwsdl.php

It is implemented with the freeware PHP library NUSOAP. If you open this URL in your browser you will see something like this

This is the list of functions exposed by iMetosSOAP interface. If you click on any function, the list of parameters will be shown at the right side. Clicking on the WSDL link will open WSDL file. Detailed description of WSDL of PIKernel data interface is out of scope of this document. For more information read the comments in the WSDL.

Why Not Simple XML?

What is bad with simple XML format? It looks very easy to make an XML interface, put all data of the station in one document and let other application access it. There are plenty of XML tools available for every platform and OS.

The problem is that parsing of XML document is relatively complex. It is difficult to divide the interface into different functions. For example, if we need to implement a function that delivers the list of stations and another function that delivers data for a particular station we have to define two different xml formats. Furthermore we need to parameterise the data request to define the date and amount of weather data. Parameterisation can be done by sending an xml file to the server. This would be one more xml format. With complex interface and many different data structures we would end up with tens of different xml specifications that are not possible to manage.

SOAP solves all of those problems by defining the rules to implement remote procedure calls. At the very high level it looks like normal functions with parameters.

For those who still want to user a pure XML, we support XML data interface. For details refer to http://fieldclimate.com/pikernel/download/imetos.zip

Foreword For Windows Developers

If you are going to develop a windows application using Fieldcliamte weather data you can consider one more, probably easier way to get to the data - Synchronization Module. Synchronization module is a small application that synchronizes Fieldcliamte data with a local MSACCESS database on customers PC. It is available as a windows executable or ActiveX module. This can give you some advantages against using the data interface directly. The most notable is that internet traffic is considerably reduced because the data is replicated only once. Another advantage is that many development tools offer easy ways to work with the database. If you prefer to work with MSACCESS database refer to

http://www.metos.at/pikernel/download/windows_sync/index.htm

 

General Description of Data Structures

Basically, there are tree main data structures - list of stations, list of sensors of a station and data of a station.

List of stations returns all stations to which the user has access. It includes name, serial number and some other parameters.

Having received this list one can query weather data of a particular station. Weather data is transferred in small portions, normally up to 1000 records, in order not to overload the server and communication channel.

Depending on programming language, data can be represented as a 2-dimensional array where every row is an associative array (PHP) or as a recordset object (VB, Delphi, Java ).

 

PHP Class Library

If you work with PHP you can use the class library provided by Pessl Instruments. It wrappers all SOAP calls in a nice classes so that you don't need to deal with SOAP at all.

 

Reading the List of Stations

You start from reading out the list of available station. First create a new instance of the class PesslSOAPStationList

  $soap_stations = & new PesslSOAPStationList();

Then you need to provide the user name and password

  $soap_stations ->username = 'soap';

  $soap_stations ->password = 'test';

That's all. Now we can read a list of stations from fieldclimate

$stations = & $soap_stations->PesslSOAPStationListAll() or die($soap_stations->error);

The function PesslSOAPStationListAll returns a list of stations or false in case of error. Error message is saved in the error variable

If stations have been read successfully variable $stations is a 2-dimensional array representing a table with rows. Every row is an associative array. The rows are very similar to those which are returned by the mysql_fetch_array() functions where keys are the names of fields.

Try to execute this script. Live demo is available here station_list.php

 

<?php

   require_once('class.pessl_soap.php');

$soap_stations = & new PesslSOAPStationList();

$soap_stations ->username = 'soap';

$soap_stations ->password = 'test';

$stations = & $soap_stations->PesslSOAPStationListAll() or

    die("error reading station list: ".$soap_stations->error);

  if(!count($stations)){

    die("there are no stations available");

  }

  $fields=array_keys($stations[0]);

  echo "<table border=\"1\">";

  echo "<tr>";

  foreach($fields as $f){

    echo "<th> $f <th/>";

  }

  echo "<tr/>";

  foreach($stations as $row){

    echo "<tr>";

    foreach($row as $value){

      echo "<td> $value <td/>";

    }

    echo "<tr>";

  }

  echo "<table/>";

 

?>

 

Getting Configuration of Station

Now we need to learn more about the stations. To request data of a particular station, instantiate class PesslSOAPStation

$soap_station = & New PesslSOAPStation();

$soap_station->station_name = $stations[0]['f_name'];

By assigning variable station_name we identify the station we are interested in.

Again, we need the user name and password to access data

$soap_station->username   = 'soap';

$soap_station->password   = 'test';

Now we can read out configuration of the station using function PesslSOAPStation::PesslSOAPStationConfig()

$station_config = & $soap_station->PesslSOAPStationConfig() or die($soap_station->error);

 

It returns 2-dimensional array. This array contains only 1 row that is an associative array with the following fields

f_station_code

Ignore

f_date

Date of registration in database

f_dev_id

Code of device

f_name

Name of station

f_descr

Textual description of station

f_info

Extended textual description of the station

f_uid

Ignore

F_create_time

Ignore

F_measure_int

Measure interval (0 - default)

f_data_int

Logging interval (0 - default)

F_webserv_dom

Ignore

F_webserv_url

Ignore

F_webserv_port

Ignore

f_emergency_sms

Ignore

f_timezone

Time zone in minutes (60=+1H -60 = -1H)

f_latitude

Latitude

f_longitude

Longitude

F_hw_ver_major

Major number of hardware version

F_hw_ver_minor

Minor number of hardware version

F_sw_ver_major

Major number of software version

F_sw_ver_minor

Minor number of software version

f_sms_warn_numbers

Maximum number of telephone numbers for SMS warnings

f_sms_warn_values

Maximum number of conditions for SMS warnings

f_gsm_mcc

MCC code of GSM operator

f_gsm_mnc

MNC code of GSM operator

f_gprs_apn

APN of GRPS connection

f_gprs_user_id

User name of GPRS connection

F_gprs_passw

Password for GPRS connection

 

The following code is an example of reading station configuration

It is also available here

station_config.php

 

<?php

  require_once('class.pessl_soap.php');

  $soap_stations = & new PesslSOAPStationList();

  $soap_stations ->username = 'soap';

  $soap_stations ->password = 'test';

  $stations = & $soap_stations->PesslSOAPStationListAll() or

    die("error reading station list: ".$soap_stations->error);

  if(!count($stations)){

    die("there are no stations available");

  }

  $soap_station = & New PesslSOAPStation();

  $soap_station->station_name = $stations[0]['f_name'];

  $soap_station->username   = 'soap';

  $soap_station->password   = 'test';

  $station_config = & $soap_station->PesslSOAPStationConfig() or die($soap_station->error);

  echo "<h1> Configuration of station ".$soap_station->station_name."</h1>";

 

  echo "<table border=\"1\">";

  $fields=array_keys($stations[0]);

  $station_config=$station_config[0];

  foreach($station_config as $k=>$v){

    echo "<tr>";

    echo "<th> $k </th>";

    echo "<td> $v </td>";

    echo "</tr>";

  }

  echo "</table>";

 

?>

 

Getting Sensors Info

Next step is to read the list of sensors connected to this station

$sensors = & $soap_station->PesslSOAPStationSensors() or die($soap_station->error);

Again, the returned value is a 2-dimensional array

Each row has the following fields

 

Field

Meaning

f_station_code

Ignore

f_sensor_ch

Channel of the sensor. Every sensor connected to the station has a unique channel number

f_sensor_code

Global code of the sensor. Every model of sensor has its own code. Don't confuse with the channel. More then one sensors with the same code can be connected to the same station, but their channels will be different. For example, two air temperature sensors with code 0 connected to the same station may have channels 0 and 1 respectively

f_chain_code

Code of chain is sensors are chained. Some of sensors may be chained through a special cable. One chain may have tens of different sensors. Through channel code one may group sensors by chain to display or do some specific calculations

f_group_code

Code of group to which the sensor belongs. Every model of sensor belongs to a globally defined group. For example, all different air temperature sensors belong to one group, wind speed sensors belong to another group, etc. Group allows recognising of different sensors and unifying their parameters.

f_unit_code

Ignore

f_name

Original name of the sensor. Human readable name of the sensor, assigned by Pessl Instruments

f_unit f_div

Ignore

f_mul

Ingnore

f_val_neg

Sensor may have negative values

f_val_log

Ignore

f_val_last

Last measured value is available

f_val_sum

Sum is available

f_val_aver

Average is available

f_val_min

Minimum value is available

f_val_max

Maximum value is available

f_val_time

Value is time interval

f_val_user

Ignore

f_create_time

Ignore

f_group_name

Name of group to which this sensor belongs

f_color

HTML colour assigned to this sensor in fieldclimate web site

f_sensor_user_name

User defined name for this sensor

f_user_unit_code

Ignore

 

This script will show the list of sensors of the first station from the station list.

Live demo is available here

station_sensors.php

 

<?php

  require_once('class.pessl_soap.php');

  $soap_stations = & new PesslSOAPStationList();

  $soap_stations ->username = 'soap';

  $soap_stations ->password = 'test';

  $stations = & $soap_stations->PesslSOAPStationListAll() or

    die("error reading station list: ".$soap_stations->error);

  if(!count($stations)){

    die("there are no stations available");

  }

  $fields=array_keys($stations[0]);

  echo "<h1> List of stations </h1>";

  echo "<table border=\"1\">";

  echo "<tr>";

  foreach($fields as $f){

    echo "<th> $f </th>";

  }

  echo "</tr>";

  foreach($stations as $row){

    echo "<tr>";

    foreach($row as $value){

      echo "<td> $value </td>";

    }

    echo "</tr>";

  }

  echo "</table>";

 

  $soap_station = & New PesslSOAPStation();

  $soap_station->station_name = $stations[0]['f_name'];

  $soap_station->username   = 'soap';

  $soap_station->password   = 'test';

  $sensors = & $soap_station->PesslSOAPStationSensors() or

    die("error reading sensors: ".$soap_station->error);

 

  if(!count($sensors)){

    die("there are no sensors available");

  }

  $fields=array_keys($sensors[0]);

  echo "<h1> Sensors of station ".$stations[0]['f_name']."</h1>";

  echo "<table border=\"1\">";

  echo "<tr>";

  foreach($fields as $f){

    echo "<th> $f </th>";

  }

  echo "</tr>";

  foreach($sensors as $row){

    echo "<tr>";

    foreach($row as $value){

      echo "<td> $value </td>";

    }

    echo "</tr>";

  }

  echo "</table>";

 

?>

 

Getting Weather Data

Finally, as a reward for all our efforts and patience we read the main value of the weather station - weather data. Class PesslSOAPStation has the following functions to randomly access weather data

Function

Description

PesslSOAPStationDataGetFirst

Reads first block of data

PesslSOAPStationDataGetNext

Reads next block of data

PesslSOAPStationDataGetPrev

Reads previous block of data

PesslSOAPStationDataGetLast

Reads last block of data

PesslSOAPStationDataGetFromDate

Reads block of data starting from a specified date

 

Variable row_count defines how many data records one block should contain

Next and previous blocks are always calculated relatively to the previous call using variable dt_from. This variable also serves as a status of the object. To keep track between different http sessions it is enough to recreate the PesslSOAPStation object and set dt_from.

Before calling PesslSOAPStationDataGetFromDate dt_from should be implicitly set.

Like all previously mentioned interfaces, weather data functions return a 2-dimensional array.

The number of columns and their names depend on what sensors are connected to the station in question.

It is possible to read data grouped by hour, day, and month or not grouped. To define the group function assign PesslSOAPStation::group_code to

0

no group (default)

1

hour

2

day

3

month

First column always contains the date of the measurement and is called f_date

Other column names are built according to the scheme explained below

sens_aggr_ch_code

where aggr can be

aver

Average value

min

Minimum value

max

Maximum value

last

Last value

time

Time

 

ch   channel of the sensor

Code  code of the sensor

Example of data array

f_date

sens_aver_0_16

sens_min_0_16

sens_max_0_16

sens_aver_3_1

sens_aver_4_0

sens_min_4_0

sens_max_4_0

sens_sum_5_6

sens_last_7_7

sens_time_8_4

sens_aver_20_21

sens_min_20_21

2006-04-07 15:00:00

26

26

26

28

27.4

27.4

27.4

 

6328

 

7.3

7.3

2006-04-07 16:00:00

26.2

25.4

27.2

21

25.1

19.4

27.1

 

6386

 

1.5

-5.4

 

sens_aver_0_16 means average value of sensor with code 16 (soil temperature) connected to channel 0. This sensor also has minimum and maximum values - sens_min_0_16 and sens_max_0_16. Next is sensor with code 1 (Relative humidity) on channel 3. This sensor has only average value.

 

To see the real weather data of a demo station, execute this script.

It is also available here

station_data.php

 

<?php

  require_once('class.pessl_soap.php');

  $soap_stations = & new PesslSOAPStationList();

  $soap_stations ->username = 'soap';

  $soap_stations ->password = 'test';

  $stations = & $soap_stations->PesslSOAPStationListAll() or

    die("error reading station list: ".$soap_stations->error);

  if(!count($stations)){

    die("there are no stations available");

  }

  $fields=array_keys($stations[0]);

  echo "<h1> List of stations </h1>";

  echo "<table border=\"1\">";

  echo "<tr>";

  foreach($fields as $f){

    echo "<th> $f </th>";

  }

  echo "</tr>";

  foreach($stations as $row){

    echo "<tr>";

    foreach($row as $value){

      echo "<td> $value </td>";

    }

    echo "</tr>";

  }

  echo "</table>";

 

  $soap_station = & New PesslSOAPStation();

  $soap_station->station_name = $stations[0]['f_name'];

  $soap_station->username   = 'soap';

  $soap_station->password   = 'test';

 

  $station_data = & $soap_station->PesslSOAPStationDataGetFirst() or

    die("error reading weather data: ".$soap_station->error);

 

  if(!count($station_data)){

    die("there is no data available");

  }

  $fields=array_keys($station_data[0]);

  echo "<h1> First block of weather data of station ".$stations[0]['f_name']."</h1>";

  echo "<table border=\"1\">";

  echo "<tr>";

  foreach($fields as $f){

    echo "<th> $f </th>";

  }

  echo "</tr>";

  foreach($station_data as $row){

    echo "<tr>";

    foreach($row as $value){

      echo "<td>";

      if($value){

        echo $value;

      }else{

        echo "&nbsp;";

      }

      echo "</td>";

    }

    echo "</tr>";

  }

  echo "</table>";

 

 

?>

 

The names of columns are not very descriptive in this example. To relate the columns to sensor information function PesslSOAPStation::PesslSOAPGetInfoSensors has been designed.

This function accepts a name of column of weather data and returns an array with information about the sensor related to this column. The structure is same as in sensor array returned by PesslSOAPStationSensors with one additional element with name f_aggr. This element contains the name of aggregate function. It can be aver, max, min, last or time depending on values of the sensor. Below is an example of using this function to display the name of sensor and measurement unit in the header of weather data table.

<?php

  require_once('class.pessl_soap.php');

  $soap_stations = & new PesslSOAPStationList();

  $soap_stations ->username = 'soap';

  $soap_stations ->password = 'test';

  $stations = & $soap_stations->PesslSOAPStationListAll() or

    die("error reading station list: ".$soap_stations->error);

  if(!count($stations)){

    die("there are no stations available");

  }

  $fields=array_keys($stations[0]);

  echo "<h1> List of stations </h1>";

  echo "<table border=\"1\">";

  echo "<tr>";

  foreach($fields as $f){

    echo "<th> $f </th>";

  }

  echo "</tr>";

  foreach($stations as $row){

    echo "<tr>";

    foreach($row as $value){

      echo "<td> $value </td>";

    }

    echo "</tr>";

  }

  echo "</table>";

 

  $soap_station = & New PesslSOAPStation();

  $soap_station->station_name = $stations[0]['f_name'];

  $soap_station->username   = 'soap';

  $soap_station->password   = 'test';

 

  $station_data = & $soap_station->PesslSOAPStationDataGetFirst() or

    die("error reading weather data: ".$soap_station->error);

 

  if(!count($station_data)){

    die("there is no data available");

  }

  $fields=array_keys($station_data[0]);

  echo "<h1> First block of weather data of station ".$stations[0]['f_name']."</h1>";

  echo "<table border=\"1\">";

  echo "<tr>";

  foreach($fields as $f){

    echo "<th>";

    if($f=="f_date"){

      echo "Date/Time";

    }else{

      $sens_info=$soap_station->PesslSOAPGetInfoSensors($f);

      echo $sens_info["f_name"]." ".$sens_info["f_aggr"]."<br/>[".$sens_info["f_unit"]."]";

    }

   

    echo "</th>";

  }

  echo "</tr>";

  foreach($station_data as $row){

    echo "<tr>";

    foreach($row as $value){

      echo "<td>";

      if($value){

        echo $value;

      }else{

        echo "&nbsp;";

      }

      echo "</td>";

    }

    echo "</tr>";

  }

  echo "</table>";

 

 

?>

 

It is also available here

station_data_header.php

 

Disease Models and Weather Forecast

Except weather data, there can be additional data, generated by fieldclimate modules, like diesase modules, forecast, etc. This data has the same structure as weather data and is represented in a form of additional sensors of the station. It means that it can be read with SOAP interface without any modifications. You simply read sensors and data of the station.

Try this script.

<?php

            require_once('class.pessl_soap.php');

            $soap_stations = & new PesslsoapStationList();

            $soap_stations ->username = 'soap';

            $soap_stations ->password = 'test';

            $stations = & $soap_stations->PesslSoapStationListAll() or

                        die("error reading station list: ".$soap_stations->error);

            if(!count($stations)){

                        die("there are no stations available");

            }

           

            $soap_station = & New PesslsoapStation();

            $soap_station->station_name = $stations[0]['f_name'];

            $soap_station->username      = 'soap';

            $soap_station->password      = 'test';

            $soap_station->show_user_app=true;

 

            $station_data = & $soap_station->PesslsoapStationDataGetLast() or

                        die("error reading weather data: ".$soap_station->error);

            if(!count($station_data)){

                        die("there is no data available");

            }

            $fields=array_keys($station_data[0]);

            echo "<h1> Last block of weather data with additional sensors of station ".$stations[0]['f_name']."</h1>";

            echo "<table border=\"1\">";

            echo "<tr>";

            foreach($fields as $f){

                        echo "<th>";

                        if($f=="f_date"){

                                   echo "Date/Time";

                        }else{

                                  

                                   $sens_info=$soap_station->PesslsoapGetInfoSensors($f);

                                   if(!$sens_info){

                                               continue;

                                   }

                                   echo $sens_info["f_name"]." ".$sens_info["f_aggr"]."<br/>[".$sens_info["f_unit"]."]";

                        }

                       

                        echo "</th>";

            }

            echo "</tr>";

            foreach($station_data as $row){

                        echo "<tr>";

                        foreach($row as $value){

                                   echo "<td>";

                                   if($value){

                                               echo $value;

                                   }else{

                                               echo "&nbsp;";

                                   }

                                   echo "</td>";

                        }

                        echo "</tr>";

            }

            echo "</table>";

?>

This script is also available here station_data_user_app.php

You can see that that now station has much more sensors than in previous examples. This is because we have requested not only the weather data but also sensors generated by additional modules. This is done by setting property show_user_app of soap_station class to true.

$soap_station->show_user_app=true;

What additional sensors the station has depends on what modules are activated by the user. To activate/deactivate modules log in into fieldclimate, go to user settings and click on “Activate disease modules and forecast”. In you version it may have different text depending on the language. In this example there are 2 additional modules: apple disease and weather forecast, so the list of sensors looks like this

Last block of weather data with additional sensors of station 00000264

Date/Time

Soil temperature aver
[C]

Soil temperature min
[C]

Soil temperature max
[C]

Relative humidity aver
[%]

Air temperature aver
[C]

Air temperature min
[C]

Air temperature max
[C]

Precipitation sum
[mm]

Battery voltage last
[V]

Leaf Wetness time
[Min]

Dew Point aver
[C]

Dew Point min
[C]

Asco max
[]

Asco Reif max
[%]

Asco Frei max
[%]

Asco Light Infection max
[%]

Asco Medium Infection max
[%]

Asco Strong Infection max
[%]

Conidia Light Infection max
[%]

Conidia Medium Infection max
[%]

Conidia Strong Infection max
[%]

Fireblight DIV aver
[]

Temp Sum aver
[]

Blossomblight aver
[]

temperature aver
[C]

temperature min
[C]

temperature max
[C]

Total Precip. sum
[mm]

convective Precip sum
[mm]

Snow Fraction aver
[%]

Snow Fraction max
[%]

Low Clouds aver
[%]

Low Clouds max
[%]

Mid Clouds aver
[%]

Mid Clouds max
[%]

High Clouds aver
[%]

High Clouds max
[%]

Probability of Precipitation aver
[%]

Probability of Precipitation max
[%]

GUST aver
[m/s]

GUST max
[m/s]

wind speed aver
[m/s]

wind speed max
[m/s]

wind direction aver
[deg]

wind direction max
[deg]

relative humidity aver
[%]

relative humidity max
[%]

The only problem here is that the data is only available until last weather data record, though weather forecast should go in the future. This is because all additional data is synchronized with the weather data. To change this behavior, so called “master user application” has been introduced. It is stored in the master_user_app property of soap_station class. This property defines, data of which module has the highest priority. By default, it is weather data and data of other applications is merged according to date/time of the weather data. It also defines the behaviour of GetMinMaxDate() function. If a name of user application is assigned to master_user_app, data generated by this application is read first and  data of other applications is merged with it. Following values are defined for master_user_app

1.     false = weather data

2.     ‘weather_data’ = weather data

3.     ‘forecast’ = weather forecast

Now let’s try the same script but with

$soap_station->master_user_app=’forecast’;

Script is also available here station_data_forecast.php

You can see that the data goes one week beyond the last record of weather data thus allowing reading weather forecast. Please note that normal sensors have null-values in the future. Care should be taken for implementing replication solutions.

Versions of PHP

The library has been developed for PHP 4.x. It may not work with PHP 5 due to name conflicts. Release of PHP 5 compatible version is scheduled for April 2008.

 

Putting all together

After learning the basics of data interface you can start developing your own applications. Here you will find a complete example similar to fieldclimate web site working solely through data interface described in this manual index.php .

You can download the source code and use it as a skeleton for your development.

We hope you will find this interface useful. Although it is read-only it opens up possibility to implement many different applications without big efforts and expenses.

 

Please send error reports, suggestions, requests for support and examples of your applications to software@metos.at