Where Am I? Collecting GPS Data With Apache Camel
In this article I will tell you how Apache Camel can turn a full-stack Linux microcomputer (like Raspberry Pi) into a device collecting the GPS coordinates.
Join the DZone community and get the full member experience.
Join For FreeOne of the most popular requirements for the field devices used in IoT systems is to provide the current GPS location of that device and send this information to the data center. In this article I will tell you how Apache Camel can turn a full-stack Linux microcomputer (like Raspberry Pi) into a device collecting the GPS coordinates.
Which GPS Unit Should I Choose?
There is a myriad of GPS receivers available on the market. The BU353 is one of the cheapest and the most popular GPS units. It can be connected to a computer via the USB port. If you are looking for a good and cheap GPS receiver for your IoT solution, you should definitely consider purchasing this unit.
The picture below presents the BU353 connected to the Raspberry Pi device via the USB port.
You can optionally equip your Pi into an external mobile battery, like GOODRAM Power Bank P661. Equipped with the external power supply, you can take your mobile GPS system in car or outdoors. A battery significantly simplifies the testing in the field part of your solution.
How Can Camel Help Me?
Camel GPS BU353 component can be used to read the current GPS information from that device. With Camel GPS BU353 you can just connect the receiver to your computer's USB port and read the GPS data - the component will make sure that GPS daemon is up, running, and switched to the NMEA mode. The component also takes care of parsing the NMEA data read from the serial port, so you can enjoy the GPS data wrapped into the com.github.camellabs.iot.component.gps.bu353.ClientGpsCoordinates POJO objects (which in turn are forwarded to your Camel routes).
Show Me the Code
In order to take advantage of the Camel GPS BU353 you have to add the following dependency to your Maven project:
<dependency>
<groupId>com.github.camel-labs</groupId>
<artifactId>camel-gps-bu353</artifactId>
<version>0.1.1</version>
</dependency>
The BU353 component supports only consumer endpoints - it makes sense as GPS component is used to read, not write, GPS data. The BU353 consumer is the polling one, i.e. it periodically asks the GPS device for the current coordinates. The Camel endpoint URI format for the BU353 consumer is as follows:
gps-bu353:label
Where label can be replaced with any text label:
from("gps-bu353:current-position").
to("file:///var/gps-coordinates");
The Camel route presented above reads the current GPS coordinates every 5 seconds and saves these into the /var/gps-coordinates directory. Each GPS coordinates pair is saved into a dedicated file. The complete runnable example of the route above is presented in the code snippet below. I use Camel Spring Boot support to start the Camel context and load the route definition:
@SpringBootApplication
public class GpsReader extends FatJarRouter {
public void configure() throws Exception {
from("gps-bu353:current-position").
to("file:///var/gps-coordinates");
}
}
BU353 consumer receives the com.github.camellabs.iot.component.gps.bu353.ClientGpsCoordinates instances. ClientGpsCoordinates class is a convenient POJO wrapper around the GPS data:
ConsumerTemplate consumerTemplate = camelContext.createConsumerTemplate();
ClientGpsCoordinates currentPosition =
consumerTemplate.receiveBody("gps-bu353:current-position", ClientGpsCoordinates.class);
String deviceId = currentPosition.clientId();
Date taken = currentPosition.timestamp();
double latitude = currentPosition.lat();
double longitude = currentPosition.lng();
ClientGpsCoordinates class name is prefixed with the Client keyword to indicate that these coordinates have been created on the device, not on the server side of the IoT solution.
Process Manager
Process manager is used by the BU353 component to execute Linux commands responsible for starting GPSD daemon and configuring the GPS receiver to provide GPS coordinates in the NMEA mode. If for some reason you would like to change the default implementation of the process manager used by Camel (i.e. com.github.camellabs.iot.utils.process.DefaultProcessManager), you can set it on the component level:
GpsBu353Component bu353 = new GpsBu353Component();
bu353.setProcessManager(new CustomProcessManager());
camelContext.addComponent("gps-bu353", bu353);
If the custom process manager is not set on the component, Camel will try to find the manager instance in the registry. So for example for the Spring application, you can just configure the manager as the bean:
@Bean
ProcessManager myProcessManager() {
new CustomProcessManager();
}
The custom process manager may be useful if for some reasons your Linux distribution requires executing some unusual commands in order to make the GPSD up and running.
What's Next?
Do geographical capabilities of the Camel seem compelling to you? Then you should also Camel Geocoder component which can be used to easily convert GPS coordinates collected via Camel into the human readable street address. Also stay tuned for the geofencing features coming soon to the Camel IoT Labs project.
Opinions expressed by DZone contributors are their own.
Comments