TURNING INFORMATION INTO PROFITS
Sync Module for Windows Description
Table of contentsSee also: Sync Module for Windows Code Documentation Fieldclimate Sensor Groups Sync Module for Windows Mobile Screenshots |
|
Introduction
Fieldclimate platform provides SOAP interface with a set of functions allowing reading all data related to the user account. This includes the list of station, configuration for every station, weather data and calculated data, such as disease models and weather forecast. Detailed description and tutorial of the interface is found here.
To eliminate the need of programming the SOAP web services and speed up development of Windows applications, Synchronization module for Windows has been developed.This is a cross-platform compatible .Net application for Windows and Windows Mobile operating systems. Written in a form of ActiveX object, it allows seamless and transparent synchronization of Fieldclimate data with a local database on demand. It also provides a data interface to abstract the user application from the underlying database. Both versions, Windows and Windows Mobile use the same set of source files and therefor provide the same interface. Compiled for .Net2 and .Net2 Compact framework, it is compatible with Windows XP and upwards and with Windows Mobile 5 and upwards. You may use complied version as well as the source code.
Following databases are supported:
- Windows: MS access, SQLCE, SQLite
- Windows Mobile: SQLCE, SQLite
Although this software is free and open source, modification is not recommended unless you are missing some important functionality. Pessl Instruments continuously develops the module to reflect the ongoing changes of the fieldclimate platform. You may any time upgrade to the latest version without the need of redeveloping your user application because backward compatibility is always maintained.
Concept
The data is read from fieldclimate and saved in a local database for future use. Every portion of data is read only once.
- List of station of user account
- Configuration of every station
- Sensors of every station
- Weather data and other calculated data
- User-station-sensors rights
All information is user related, which implies that multiple users can use the application on the same device.
The module consists of two parts.
Synchronization with fieldclimate
Data interface for user application
Download Source Code
Download the latest official source code release
It includes a Visual Studio solution with following projects
Common | common source file for all platforms. It should be always unloaded | ||||||||
WindowsMobileSyncNet2.0 | ActiveX module for windows mobile OS | ||||||||
WindowsMobilePesslSyncExample | Demo application for windows mobile OS | ||||||||
WindowsXPSync | ActiveX module for windows OS | ||||||||
WindowsPesslSyncExample | Demo application for windows OS | ||||||||
WindowsMobilePesslSync | Installation project for Windows Mobile OS. This projects produces CAB installation for windows mobile |
Two modes of operation
Depending on application goal, network availability and user preference, one of 2 synchronization modes can be chosen
Manual synchronization mode
In this mode user application is responsible for calling synchronization functions provided by the module
To activate this mode set AutoSync property to false
Auto synchronization mode
In this mode data is synchronized automatically when user application reads data through data interface. If network is not available error message will be displayed, unless it is suppressed (see error handling).
To activate this mode set AutoSync property to true
Typical behavior of user application
Login
Before the user application can do anything with the module it should provide the user credential.
Public Sub Login(ByVal userName As String, ByVal userPwd As String)
The module will save this information and use it for authentication at fieldclimate.com and for supplying data to the user application.
Manual synchronization mode: Optionally call DoSyncStationList(). This will assure that all stations (not the data) are present in the local database. Because it is very seldom that the user adds, removes or renames a station, this function may be called on users request only.
Read station list
Public Sub GetStationList(ByRef ds As DataSet)
This is the starting point for any application, because for all other data station name should be provided.
It creates or updates table 'stationlist' in the dataset with the following fields
Name | Type | Size | Comment | ||||||
f_station_code | Long Integer | 4 | Unique code of station; this field i used to link to other tables of the database | ||||||
f_date | Date/Time | 8 | Date of registration | ||||||
f_dev_id | Long Integer | 4 | device ID | ||||||
f_name | Text | 50 | name of the station, normally same as serial number | ||||||
f_descr | Text | 50 | short description | ||||||
f_info | Text | 255 | information about the device | ||||||
f_uid | Decimal | 16 | hardware ID |
Read station sensors
Public Sub GetStationSensors(ByVal station_name As String, ByRef ds As DataSet)
Manual synchronization mode: Optionally call DoSyncOneStation()
This function creates of updates the "stationsensors" table in ther recordset. The table has following fields
Name | Type | Size | Comment | ||||||
f_station_code | Long Integer | 4 | this field is used to link to the stations table | ||||||
f_sensor_ch | Long Integer | 4 | sensor channel. Sensor channel is unique in the scope of station. If station has more then one sensor of the same type with same code they can be differentiated by the sensor channel. Detailed explanation of this approach is here. | ||||||
f_sensor_code | Long Integer | 4 | Code of sensor. Every sensor has its own code that identifies the sensor type characteristics | ||||||
f_chain_code | Long Integer | 4 | If sensor is a member of the sensor-chain this field contains the number of the chain. More information about chains is here. | ||||||
f_group_code | Long Integer | 4 | Group of sensors. All sensors are grouped by the type and measurement unit. Knowing the group allows you to use the sensor in different calculations. You can tell that sensor belongs to soil temperature sensors or global radiation and so on. Please look for the Fieldclimate Sensor Groups for more information. | ||||||
f_unit_code | Long Integer | 4 | not used | ||||||
f_name | Text | 50 | Original name of the sensor given by Pessl Instruments. | ||||||
f_unit | Text | 50 | Textual description of the measurement unit of the sensor given by Pessl Instruments. Normally it match to International System of Units or SI![]() | ||||||
f_div | Long Integer | 4 | not used | ||||||
f_mul | Long Integer | 4 | not used | ||||||
f_val_neg | Long Integer | 4 | if > 0 value can be negative | ||||||
f_val_log | Long Integer | 4 | if > 0 sensor is logical rather then Physical. It means that this value is not measured directly but calculated. This can be duty point, Evaprotranspitaion, etc. | ||||||
f_val_last | Long Integer | 4 | if > 0 This sensor has aggregation function "last" (f_val_last field in table download_data has value) | ||||||
f_val_sum | Long Integer | 4 | if > 0 This sensor has aggregation function "sum" (f_val_sum field in table download_data has value). This is applied to sensors like precipitation for which sum is calculated | ||||||
f_val_aver | Long Integer | 4 | if > 0 This sensor has aggregation function "average" (f_val_aver field in table download_data has value). This is applied to sensors like temperature, global radiation for which average is calculated | ||||||
f_val_min | Long Integer | 4 | if > 0 This sensor has aggregation function "min" (f_val_min field in table download_data has value). This is applied to sensors like temperature, relative humidity for which minimum is calculated | ||||||
f_val_max | Long Integer | 4 | if > 0 This sensor has aggregation function "max" (f_val_max field in table download_data has value). This is applied to sensors like temperature, relative humidity for which maximum is calculated | ||||||
f_val_time | Long Integer | 4 | if > 0 This sensor has aggregation function "time" (f_val_time field in table download_data has value). This is applied to sensors like leaf wetness for which time of status is calculated. In case of leaf wetness it says how long the leaf was wet during the logging interval of the station | ||||||
f_val_user | Long Integer | 4 | not used | ||||||
f_user_sensor_name | Text | 50 | user defined name | ||||||
f_color | Text | 50 | user defined color in HTML notation |
Read station data
Call one of GetStationData* functions
GetStationDataFirst, GetStationDataNext, GetStationDataLast, GetStationDataFromDAte
For description see Data Interface
Manual synchronization mode: Optionally call DoSyncOneStation()
These functions create or update table "stationdata" in the dataset. This table has following format
f_date | sens_aggr1_ch1_code1 | sens_aggr2_ch2_code2 | sens_aggr3_ch3_code3 | sens_aggrN_chN_codeN | |||||
date1 | value1 | value2 | value3 | valueN | |||||
date2 | value1 | value2 | value3 | valueN | |||||
date3 | value1 | value2 | value3 | valueN |
Where
sens: literal string "sens"
aggr: aggregate functions. can be "min", "max", "aver", "sum", "last", "time"
chX: the channel number of sensor
codeX: the code of sensor
Real exapmle of dataset returned by the fucntion call GetStationDataFirst("00000A85"):
f_date | sens_sum_5_6 | sens_last_7_7 | sens_time_8_4 | sens_min_22_506 | sens_max_22_506 | sens_aver_22_506 | sens_aver_23_507 | sens_min_26_21 | sens_aver_26_21 |
17.08.2009 01:00:00 | 0 | 6562 | 0 | 17,82 | 18,3 | 18,015 | 98,1566666666667 | 17,5 | 17,7833333333333 |
17.08.2009 02:00:00 | 0 | 6552 | 0 | 17,4 | 18,23 | 17,8416666666667 | 97,9433333333333 | 17 | 17,55 |
17.08.2009 03:00:00 | 0 | 6552 | 0 | 17,09 | 17,4 | 17,255 | 99,6566666666667 | 16,8 | 17,2333333333333 |
17.08.2009 04:00:00 | 0 | 6552 | 0 | 17,2 | 17,59 | 17,4 | 99,6166666666667 | 17 | 17,35 |
17.08.2009 05:00:00 | 0 | 6582 | 0 | 17,06 | 17,82 | 17,4333333333333 | 98,5283333333333 | 16,9 | 17,3833333333333 |
Column names have following meaning
f_date date or record
sens_sum_5_6 sum of sensor data with code 6 on channel 5. If you look to the dataset returned by function GetStationSensors() you will find that this is precipitation sensor and it has only sum (f_val_sum is equal to 1)
sens_last_7_7 is last value of sensor with code 7 on channel 7, that is battery
sens_time_8_4 is a leaf wetness sensor with code 4 on channel 8. It has only 'time' function. Value shows how many minutes the sensor was wet during the hour. If you request daily data it will be wet minutes per day and so on.
sens_min_22_506 minumim value of sensor with code 506 on channel 22. This is air temperature sensor and according to the sensors table it has minimum, average and maximum aggregate values
sens_max_22_506 maximum of temperature sensor on channel 22
sens_max_22_506 average value os temperature sensor on channel 22
Following the same principle, you can describe the other sensors
Thus having 2 tables, stationsensors and stationdata you can always link column from stationdata table to a row from stationsensors.
You only need to break out the field name of stationdata table into 3 components and find a match in stationsensors table.
In the next release of the module we will provide helper functions to automatize this.
Demo Application - Getting started
The fastest way to start development using synchronization module is to extend the demo application included in the solution. This application makes use of all functions provided by the module.
It has for tabs
Login tab allows the user to log into the system.
Sync tab demonstrates all synchronization functions.
Data tab demonstrates the data interface
Settings tab allows changing settings of the module and select different databases; database must exist before it can be selected
Params tab allows changing different parameters of the module. among them AtutoSync, raiseException, isSilent. This parameters are not persistent and will be reset when application is restarted
Tools tab contains database utility functions.
Error handling and user interface
Error handling is one of the most important aspect of such application. Network availability, limited data storage, complex environment inevitably lead to different errors. Synchronization module provide two possibilities for the user application to handle erroneous situations.
Catching exception
If you prefer try catch paradigm and prepare to deal with different exceptions set the raiseException property to true. In this case all calls should be wrapped in try-catch block.
Checking error code. Other, more relaxed possibility to handle errors is to check the result code of the methods. If raiseException is set to false the module will catch all exceptions by itself and not pass them to the user application. The user application should check the isError property to see if there were any errors. If error is set to true, sException property will hold the latest exception object with detailed information about the error. When error occurs, the module shows a message box with error description. I you handle errors yourself and don't need the message box set isSilent property to true. This may be useful for background or batch operations.
A small progress window is always displayed during synchronization. It has 2 text fields "X" button and progress bar to show the action being performed and progress indicator. Clicking on "X" button aborts the synchronization function being executed. Another purpose of this window is to allow the user application to redraw it's forms during execution of synchronization functions. If If you don't want to display this window set property showProgress to false. In this case the current thread will be blocked during execution of synchronization functions and the active forms of the application will not be redrawn in case they are overlapped by other windows. Also, if the progress window is not displayed, aborting of synchronization process is not possible.
limitations
Due to the fact that disease models, weather forecast and other data is saved in the form of sensors like weather data, different users have different set of sensors for the same station.
But synchronization is always ongoing. Once a record of data is saved it will never be updated. If data has been synchronized for one station of one user it will not be resynchronized for the same station for another user even if that user has different set of sensors. To overcome this limitation all available data of station is synchronized thus creating data transfer and storage overhead.
This limitation will be addressed in next versions of the module
It is still possible to overcome this limitation by deleting the data of the station and synchronising again.
To delete data call DBdeleteStation(ByVal station_name As String)
To delete data and synchronise in one go call DoReSyncOneStation(ByVal stationName As String)
Because of ongoing synchronization all calculated data for a particular date must be available at the time of reading. If some data is still being calculated, synchronization is aborted. Normally this is not a problem because calculations take few seconds as a rule. But if a user has just activated a new disease module for big amount of data, initial calculation may take hours to complete.
Created by system. Last Modification: Wednesday 24 of March, 2010 15:08:43 GMT by Vitaly.