I was running Traccar 3.10 with a custom protocol. I upgraded to Traccar 4.8 and again added my custom protocol. However, the custom protocol is not working and nothing is getting logged by Traccar. I can't figure out what is wrong with it. Essentially I have another program which talks to the trackers and then that program sends the data to Traccar in a simple text string format.
Right now I am stumped on what the problem could be as this protocol has been working for 2 years on Traccar 3.10. Please help!
This is the NavisysProtocol.java:
package org.traccar.protocol;
import org.traccar.BaseProtocol;
import org.traccar.PipelineBuilder;
import org.traccar.TrackerServer;
public class NavisysProtocol extends BaseProtocol {
public NavisysProtocol() {
addServer(new TrackerServer(false, getName()) {
@Override
protected void addProtocolHandlers(PipelineBuilder pipeline) {
pipeline.addLast(new NavisysProtocolDecoder(NavisysProtocol.this));
}
});
}
}
This is the NavisysProtocolDecoder.jave:
package org.traccar.protocol;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
import org.traccar.DeviceSession;
import org.traccar.helper.DateBuilder;
import org.traccar.model.Position;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.Date;
public class NavisysProtocolDecoder extends BaseProtocolDecoder {
public NavisysProtocolDecoder(NavisysProtocol protocol) {
super(protocol);
}
private Object processEvent(Channel channel, SocketAddress remoteAddress, String sentence) {
Position position = new Position();
position.setProtocol(getProtocolName());
String[] parts = sentence.split(",");
String imei = parts[1];
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei);
if (deviceSession == null) {
return null;
}
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
.setDate(Integer.parseInt(parts[3].substring(0, 4)),
Integer.parseInt(parts[3].substring(5, 7)),
Integer.parseInt(parts[3].substring(8, 10)));
dateBuilder.setTime(Integer.parseInt(parts[3].substring(11, 13)),
Integer.parseInt(parts[3].substring(14, 16)),
Integer.parseInt(parts[3].substring(17, 19)));
position.setTime(dateBuilder.getDate());
switch (parts[2]) {
case "BATTERY":
Date time2 = new Date();
long diff = time2.getTime() - position.getDeviceTime().getTime();
if (diff < 7200000) {
position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY);
}
break;
case "MOVE":
position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT);
break;
case "CONNECT":
position.set(Position.KEY_ALARM, Position.ALARM_NAVISYS_CONNECT);
break;
case "DISCONNECT":
position.set(Position.KEY_ALARM, Position.ALARM_NAVISYS_DISCONNECT);
break;
default:
break;
}
position.set(Position.KEY_EVENT, parts[2]);
switch (parts[2]) {
case "CONNECT":
case "DISCONNECT":
break;
default:
position.setLatitude(Double.parseDouble(parts[4]));
position.setLongitude(Double.parseDouble(parts[5]));
position.setAccuracy(Double.parseDouble(parts[8]));
position.set(Position.KEY_STATUS, parts[7]);
Double pct = Double.parseDouble(parts[6]);
Long val = Math.round(pct * 100);
position.set(Position.KEY_BATTERY, val + "%");
break;
}
position.setValid(parts[7].equals("GPS_FIXED"));
return position;
}
private Object processPosition(Channel channel, SocketAddress remoteAddress, String sentence) {
Position position = new Position();
position.setProtocol(getProtocolName());
String[] parts = sentence.split(",");
String imei = parts[1];
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei);
if (deviceSession == null) {
return null;
}
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
.setDate(Integer.parseInt(parts[2].substring(0, 4)),
Integer.parseInt(parts[2].substring(5, 7)),
Integer.parseInt(parts[2].substring(8, 10)));
dateBuilder.setTime(Integer.parseInt(parts[2].substring(11, 13)),
Integer.parseInt(parts[2].substring(14, 16)),
Integer.parseInt(parts[2].substring(17, 19)));
Boolean valid = false;
if (parts[6].equals("GPS_FIXED")) {
valid = true;
} else if (!parts[11].startsWith("0:0;")) {
valid = true;
}
position.setValid(valid);
position.setTime(dateBuilder.getDate());
position.setLatitude(Double.parseDouble(parts[3]));
position.setLongitude(Double.parseDouble(parts[4]));
position.setSpeed(Double.parseDouble(parts[9]));
position.setAltitude(Double.parseDouble(parts[8]));
position.setAccuracy(Double.parseDouble(parts[10]));
position.set(Position.KEY_STATUS, parts[6]);
position.set(Position.KEY_SATELLITES, parts[11]);
Double pct = Double.parseDouble(parts[5]);
Long val = Math.round(pct * 100);
position.set(Position.KEY_BATTERY, val + "%");
return position;
}
@Override
protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
ByteBuf buf = (ByteBuf) msg;
String sentence = buf.toString(StandardCharsets.US_ASCII).trim();
if (sentence.contains("$POS,")) {
return processPosition(channel, remoteAddress, sentence);
} else if (sentence.contains("$EVENT,")) {
return processEvent(channel, remoteAddress, sentence);
} else {
return null;
}
}
}
I was running Traccar 3.10 with a custom protocol. I upgraded to Traccar 4.8 and again added my custom protocol. However, the custom protocol is not working and nothing is getting logged by Traccar. I can't figure out what is wrong with it. Essentially I have another program which talks to the trackers and then that program sends the data to Traccar in a simple text string format.
Right now I am stumped on what the problem could be as this protocol has been working for 2 years on Traccar 3.10. Please help!
This is the NavisysProtocol.java:
package org.traccar.protocol; import org.traccar.BaseProtocol; import org.traccar.PipelineBuilder; import org.traccar.TrackerServer; public class NavisysProtocol extends BaseProtocol { public NavisysProtocol() { addServer(new TrackerServer(false, getName()) { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new NavisysProtocolDecoder(NavisysProtocol.this)); } }); } }
This is the NavisysProtocolDecoder.jave:
package org.traccar.protocol; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.DateBuilder; import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.Date; public class NavisysProtocolDecoder extends BaseProtocolDecoder { public NavisysProtocolDecoder(NavisysProtocol protocol) { super(protocol); } private Object processEvent(Channel channel, SocketAddress remoteAddress, String sentence) { Position position = new Position(); position.setProtocol(getProtocolName()); String[] parts = sentence.split(","); String imei = parts[1]; DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession == null) { return null; } position.setDeviceId(deviceSession.getDeviceId()); DateBuilder dateBuilder = new DateBuilder() .setDate(Integer.parseInt(parts[3].substring(0, 4)), Integer.parseInt(parts[3].substring(5, 7)), Integer.parseInt(parts[3].substring(8, 10))); dateBuilder.setTime(Integer.parseInt(parts[3].substring(11, 13)), Integer.parseInt(parts[3].substring(14, 16)), Integer.parseInt(parts[3].substring(17, 19))); position.setTime(dateBuilder.getDate()); switch (parts[2]) { case "BATTERY": // only report battery event if it is in the last 2 hours, prevents BS backlogged reports. Date time2 = new Date(); long diff = time2.getTime() - position.getDeviceTime().getTime(); if (diff < 7200000) { position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); } break; case "MOVE": position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); break; case "CONNECT": position.set(Position.KEY_ALARM, Position.ALARM_NAVISYS_CONNECT); break; case "DISCONNECT": position.set(Position.KEY_ALARM, Position.ALARM_NAVISYS_DISCONNECT); break; default: break; } position.set(Position.KEY_EVENT, parts[2]); switch (parts[2]) { case "CONNECT": case "DISCONNECT": break; default: position.setLatitude(Double.parseDouble(parts[4])); position.setLongitude(Double.parseDouble(parts[5])); position.setAccuracy(Double.parseDouble(parts[8])); position.set(Position.KEY_STATUS, parts[7]); Double pct = Double.parseDouble(parts[6]); Long val = Math.round(pct * 100); position.set(Position.KEY_BATTERY, val + "%"); break; } position.setValid(parts[7].equals("GPS_FIXED")); return position; } private Object processPosition(Channel channel, SocketAddress remoteAddress, String sentence) { Position position = new Position(); position.setProtocol(getProtocolName()); String[] parts = sentence.split(","); String imei = parts[1]; DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession == null) { return null; } position.setDeviceId(deviceSession.getDeviceId()); DateBuilder dateBuilder = new DateBuilder() .setDate(Integer.parseInt(parts[2].substring(0, 4)), Integer.parseInt(parts[2].substring(5, 7)), Integer.parseInt(parts[2].substring(8, 10))); dateBuilder.setTime(Integer.parseInt(parts[2].substring(11, 13)), Integer.parseInt(parts[2].substring(14, 16)), Integer.parseInt(parts[2].substring(17, 19))); Boolean valid = false; if (parts[6].equals("GPS_FIXED")) { valid = true; } else if (!parts[11].startsWith("0:0;")) { valid = true; } position.setValid(valid); position.setTime(dateBuilder.getDate()); position.setLatitude(Double.parseDouble(parts[3])); position.setLongitude(Double.parseDouble(parts[4])); position.setSpeed(Double.parseDouble(parts[9])); position.setAltitude(Double.parseDouble(parts[8])); position.setAccuracy(Double.parseDouble(parts[10])); position.set(Position.KEY_STATUS, parts[6]); position.set(Position.KEY_SATELLITES, parts[11]); Double pct = Double.parseDouble(parts[5]); Long val = Math.round(pct * 100); position.set(Position.KEY_BATTERY, val + "%"); return position; } @Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ByteBuf buf = (ByteBuf) msg; String sentence = buf.toString(StandardCharsets.US_ASCII).trim(); if (sentence.contains("$POS,")) { return processPosition(channel, remoteAddress, sentence); } else if (sentence.contains("$EVENT,")) { return processEvent(channel, remoteAddress, sentence); } else { return null; } } }