Creating a OPC/UA server for a virtual weather station.
update on 26/06/2016 for node-opcua 0.0.55.
In my quest of exploring the “Internet of Things” world,
I decided to create a simple weather station with 3 sensors mounted on my Raspberry computer.
I needed to buy some equipment to build the prototype. After studying different type of sensors (1-Wire,Analog,I2C),
I finally opted for I2C sensors. (I used I2C chips a long time ago, in a Junior Enterprise Project).
I ordered a breadboard
and I2C temperature and humidity sensor.
While waiting for the equipment to be delivered, I though it was time to start coding the Server Application.
I got the idea of using a free Web-Service to get some realtime temperature and pressure information that I need to simulate the data.
retrieving Weather data using a REST API.
The virtual weather station need to extract the weather data from a web service.
worldweatheronline provides a free API.
The Free API comes with some
restrictions, though, and only allows each user to make up to a maximum of 250 requests per day, a.k.a 1 request every 6 minutes)
getting a key at worldweatheronline
You will need to register to worldweatheronline to obtain
your API key. Store you API key in a file name worldweatheronline.key, in your project folder.
Our purpose is to create a getCityWeather asynchronous function that pass to a callback function
an object containing the temperature and pressure of a city. This function will be used this way:
get city weather
Let’s write the method that reads the weather of a city.
extract useful data
reading data periodically
The Weather Station Server will have to query the weather data of a city on a regular basis. However, we have to be careful not to send too many queries to the web-server, as any exceeding requests will get rejected and will lead to a error:
In NodeJs, the setInterval function can be used to perform a action periodically.
Why not make our server expose the weather variables of more than one city ?
Supposing we hold an array containing the city we want to monitor, our periodic call to the REST API will have to query the data for each city in turn. We will store the most up to date weather data inside a map city_data_map .
I chose 10 cities spread in different continents and hemisphere.
The server address space will be made of a Cities folder containing one folder for each city.
extracting a DataValue
Let’s write a helper function (extract_value) to extract a city weather variable as DataValue.
Since the city weather data are read asynchronously at a very low rate, it is possible that the data doesn’t exist
yet when the client will send its request. We have to be careful to handle this case appropriately.
In the absence of city data, I have chose to send a BadUncertainInitalValue status code.
construct city weather variables
Each city node exposes 3 read-only variables that can be instantiated this way:
testing the server
It is now time to start the server for testing.
Putting everything together, the weather.js script looks like this