diff options
26 files changed, 404 insertions, 97 deletions
@@ -124,6 +124,8 @@ id INT PRIMARY KEY AUTO_INCREMENT, registration BIT NOT NULL, map VARCHAR(128), + bingKey VARCHAR(128), + mapUrl VARCHAR(128), language VARCHAR(128), distanceUnit VARCHAR(128), speedUnit VARCHAR(128), @@ -150,6 +152,8 @@ UPDATE server SET registration = :registration, map = :map, + bingKey = :bingKey, + mapUrl = :mapUrl, language = :language, distanceUnit = :distanceUnit, speedUnit = :speedUnit, @@ -230,7 +234,7 @@ </entry> <entry key='database.selectPositions'> - SELECT * FROM position WHERE deviceId = :deviceId AND fixTime BETWEEN :from AND :to; + SELECT * FROM position WHERE deviceId = :deviceId AND fixTime BETWEEN :from AND :to ORDER BY fixTime; </entry> <entry key='database.insertPosition'> diff --git a/src/org/traccar/BasePipelineFactory.java b/src/org/traccar/BasePipelineFactory.java index 216e48709..0dc0bbb47 100644 --- a/src/org/traccar/BasePipelineFactory.java +++ b/src/org/traccar/BasePipelineFactory.java @@ -34,7 +34,7 @@ import org.traccar.helper.Log; public abstract class BasePipelineFactory implements ChannelPipelineFactory { private final TrackerServer server; - private int resetDelay; + private final int resetDelay; private FilterHandler filterHandler; private DistanceHandler distanceHandler; @@ -54,9 +54,6 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory { } } - /** - * Logging using global logger - */ protected class StandardLoggingHandler extends LoggingHandler { @Override diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index d50a0c626..f818368d0 100644 --- a/src/org/traccar/Context.java +++ b/src/org/traccar/Context.java @@ -15,6 +15,7 @@ */ package org.traccar; +import com.ning.http.client.AsyncHttpClient; import org.traccar.database.ConnectionManager; import org.traccar.database.DataManager; import org.traccar.database.IdentityManager; @@ -81,6 +82,12 @@ public class Context { public static ServerManager getServerManager() { return serverManager; } + + private static final AsyncHttpClient asyncHttpClient = new AsyncHttpClient(); + + public static AsyncHttpClient getAsyncHttpClient() { + return asyncHttpClient; + } public static void init(String[] arguments) throws Exception { diff --git a/src/org/traccar/WebDataHandler.java b/src/org/traccar/WebDataHandler.java index 5e3626022..5f12b9c93 100644 --- a/src/org/traccar/WebDataHandler.java +++ b/src/org/traccar/WebDataHandler.java @@ -15,7 +15,6 @@ */ package org.traccar; -import com.ning.http.client.AsyncHttpClient; import java.util.Calendar; import java.util.Formatter; import java.util.Locale; @@ -62,16 +61,16 @@ public class WebDataHandler extends BaseDataHandler { Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); - String request = url. - replace("{uniqueId}", device.getUniqueId()). - replace("{deviceId}", String.valueOf(device.getId())). - replace("{fixTime}", String.valueOf(position.getFixTime().getTime())). - replace("{latitude}", String.valueOf(position.getLatitude())). - replace("{longitude}", String.valueOf(position.getLongitude())). - replace("{gprmc}", formatSentence(position)); + String request = url + .replace("{uniqueId}", device.getUniqueId()) + .replace("{deviceId}", String.valueOf(device.getId())) + .replace("{fixTime}", String.valueOf(position.getFixTime().getTime())) + .replace("{latitude}", String.valueOf(position.getLatitude())) + .replace("{longitude}", String.valueOf(position.getLongitude())) + .replace("{gprmc}", formatSentence(position)) + .replace("{statusCode}", position.getSpeed() < 1.0 ? "0xF020" : "0xF11C"); - AsyncHttpClient asyncHttpClient = new AsyncHttpClient(); - asyncHttpClient.prepareGet(request).execute(); + Context.getAsyncHttpClient().prepareGet(request).execute(); return position; } diff --git a/src/org/traccar/model/Server.java b/src/org/traccar/model/Server.java index f5ad4887c..b910e30ec 100644 --- a/src/org/traccar/model/Server.java +++ b/src/org/traccar/model/Server.java @@ -34,6 +34,14 @@ public class Server implements Factory { public String getMap() { return map; } public void setMap(String map) { this.map = map; } + private String bingKey; + public String getBingKey() { return bingKey; } + public void setBingKey(String bingKey) { this.bingKey = bingKey; } + + private String mapUrl; + public String getMapUrl() { return mapUrl; } + public void setMapUrl(String mapUrl) { this.mapUrl = mapUrl; } + private String language; public String getLanguage() { return language; } public void setLanguage(String language) { this.language = language; } diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java index 3628730e3..38b1df1a6 100644 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -44,7 +44,30 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { "(?:\\x00?\\x04,\\p{XDigit}{4},[01],))" + "GT...," + "(?:[0-9A-Z]{2}\\p{XDigit}{4})?," + // Protocol version - "([^,]+),.*," + // IMEI + "([^,]+)," + // IMEI + + "(?:[0-9A-Z]{17}," + // VIN + "[^,]{0,20}," + // Device name + "[01]," + // Report type + "\\p{XDigit}{1,8}," + // Report mask + "[0-9A-Z]{17}," + // VIN + "[01]," + // ODB connect + "\\d{1,5}," + // ODB voltage + "\\p{XDigit}{8}," + // Support PIDs + "\\d{1,5}," + // Engine RPM + "\\d{1,3}," + // Speed + "-?\\d{1,3}," + // Coolant temp + "(\\d+\\.?\\d*|Inf|NaN)?," + // Fuel consumption + "\\d{1,5}," + // Odometer + "\\d{1,5}," + + "[01]," + // ODB connect + "\\d{1,3}," + // Number of DTCs + "\\p{XDigit}*," + // DTCs + "\\d{1,3}," + // Throttle + "\\d{1,3}," + // Engine load + "(\\d{1,3})?,"+ // Fuel level + "\\d+|.*)," + // Odometer + "(\\d*)," + // GPS accuracy "(\\d+.\\d)?," + // Speed "(\\d+)?," + // Course @@ -58,7 +81,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { "(\\p{XDigit}{4}|\\p{XDigit}{8})?," + // LAC "(\\p{XDigit}{4})?," + // Cell "(?:(\\d+\\.\\d)?," + // Odometer - "(\\d{1,3})?,)?" + // Battery + "(\\d{1,3})?,)?" + // Battery*/ ".*," + "(\\p{XDigit}{4})\\$?"); @@ -96,6 +119,10 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { } position.setDeviceId(getDeviceId()); + // Fuel + position.set("fuel-consumption", parser.group(index++)); + position.set(Event.KEY_FUEL, parser.group(index++)); + // Validity position.setValid(Integer.valueOf(parser.group(index++)) < 20); diff --git a/src/org/traccar/protocol/MegastekProtocolDecoder.java b/src/org/traccar/protocol/MegastekProtocolDecoder.java index 019bb69de..c07e73533 100644 --- a/src/org/traccar/protocol/MegastekProtocolDecoder.java +++ b/src/org/traccar/protocol/MegastekProtocolDecoder.java @@ -20,9 +20,7 @@ import java.util.Calendar; import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; - import org.jboss.netty.channel.Channel; - import org.traccar.BaseProtocolDecoder; import org.traccar.model.Event; import org.traccar.model.Position; @@ -44,7 +42,7 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder { "(\\d+\\.\\d+)?," + // Speed "(\\d+\\.\\d+)?," + // Course "(\\d{2})(\\d{2})(\\d{2})" + // Date (DDMMYY) - "[^\\*]+\\*[0-9a-fA-F]{2}"); // Checksum + ".*"); // Checksum private static final Pattern patternSimple = Pattern.compile( "[FL]," + // Flag @@ -143,10 +141,18 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder { id = sentence.substring(beginIndex, endIndex); beginIndex = endIndex + 1; - endIndex = sentence.indexOf('*', beginIndex) + 3; + endIndex = sentence.indexOf('*', beginIndex); + if (endIndex != -1) { + endIndex += 3; + } else { + endIndex = sentence.length(); + } gprmc = sentence.substring(beginIndex, endIndex); beginIndex = endIndex + 1; + if (beginIndex > sentence.length()) { + beginIndex = endIndex; + } status = sentence.substring(beginIndex); } else { @@ -175,78 +181,75 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder { if (simple) { - // Parse status Matcher parser = patternSimple.matcher(status); - if (!parser.matches()) { - return null; - } + if (parser.matches()) { - int index = 1; + int index = 1; - // Alarm - position.set(Event.KEY_ALARM, parser.group(index++)); + position.set(Event.KEY_ALARM, parser.group(index++)); - // IMEI - if (!identify(parser.group(index++), channel, null, false)) { - if (!identify(id, channel)) { - return null; + // IMEI + if (!identify(parser.group(index++), channel, null, false)) { + if (!identify(id, channel)) { + return null; + } } - } - position.setDeviceId(getDeviceId()); + position.setDeviceId(getDeviceId()); - // Satellites - position.set(Event.KEY_SATELLITES, parser.group(index++)); + position.set(Event.KEY_SATELLITES, parser.group(index++)); - // Altitude - String altitude = parser.group(index++); - if (altitude != null) { - position.setAltitude(Double.valueOf(altitude)); - } + String altitude = parser.group(index++); + if (altitude != null) { + position.setAltitude(Double.valueOf(altitude)); + } - // Battery - position.set(Event.KEY_POWER, Double.valueOf(parser.group(index++))); + position.set(Event.KEY_POWER, Double.valueOf(parser.group(index++))); - // Charger - String charger = parser.group(index++); - if (charger != null) { - position.set(Event.KEY_CHARGE, Integer.valueOf(charger) == 1); - } + String charger = parser.group(index++); + if (charger != null) { + position.set(Event.KEY_CHARGE, Integer.valueOf(charger) == 1); + } - position.set(Event.KEY_MCC, parser.group(index++)); - position.set(Event.KEY_MNC, parser.group(index++)); - position.set(Event.KEY_LAC, parser.group(index++)); + position.set(Event.KEY_MCC, parser.group(index++)); + position.set(Event.KEY_MNC, parser.group(index++)); + position.set(Event.KEY_LAC, parser.group(index++)); + + } else { + + if (!identify(id, channel)) { + return null; + } + position.setDeviceId(getDeviceId()); + + } } else { - // Parse status Matcher parser = patternAlternative.matcher(status); if (!parser.matches()) { - return null; - } - int index = 1; + int index = 1; - if (!identify(id, channel)) { - return null; + if (!identify(id, channel)) { + return null; + } + position.setDeviceId(getDeviceId()); + + position.set(Event.KEY_MCC, parser.group(index++)); + position.set(Event.KEY_MNC, parser.group(index++)); + position.set(Event.KEY_LAC, parser.group(index++)); + position.set(Event.KEY_GSM, parser.group(index++)); + + position.set(Event.KEY_BATTERY, Double.valueOf(parser.group(index++))); + + position.set(Event.KEY_FLAGS, parser.group(index++)); + position.set(Event.KEY_INPUT, parser.group(index++)); + position.set(Event.KEY_OUTPUT, parser.group(index++)); + position.set(Event.PREFIX_ADC + 1, parser.group(index++)); + position.set(Event.PREFIX_ADC + 2, parser.group(index++)); + position.set(Event.PREFIX_ADC + 3, parser.group(index++)); + position.set(Event.KEY_ALARM, parser.group(index++)); } - position.setDeviceId(getDeviceId()); - - position.set(Event.KEY_MCC, parser.group(index++)); - position.set(Event.KEY_MNC, parser.group(index++)); - position.set(Event.KEY_LAC, parser.group(index++)); - position.set(Event.KEY_GSM, parser.group(index++)); - - // Battery - position.set(Event.KEY_BATTERY, Double.valueOf(parser.group(index++))); - - position.set(Event.KEY_FLAGS, parser.group(index++)); - position.set(Event.KEY_INPUT, parser.group(index++)); - position.set(Event.KEY_OUTPUT, parser.group(index++)); - position.set(Event.PREFIX_ADC + 1, parser.group(index++)); - position.set(Event.PREFIX_ADC + 2, parser.group(index++)); - position.set(Event.PREFIX_ADC + 3, parser.group(index++)); - position.set(Event.KEY_ALARM, parser.group(index++)); - } return position; diff --git a/src/org/traccar/protocol/MeiligaoProtocol.java b/src/org/traccar/protocol/MeiligaoProtocol.java index 70c9a87ec..9e8da7dc2 100644 --- a/src/org/traccar/protocol/MeiligaoProtocol.java +++ b/src/org/traccar/protocol/MeiligaoProtocol.java @@ -15,16 +15,13 @@ */ package org.traccar.protocol; +import java.util.List; import org.jboss.netty.bootstrap.ConnectionlessBootstrap; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.string.StringDecoder; -import org.jboss.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.TrackerServer; -import java.util.List; - public class MeiligaoProtocol extends BaseProtocol { public MeiligaoProtocol() { diff --git a/src/org/traccar/protocol/MeitrackProtocol.java b/src/org/traccar/protocol/MeitrackProtocol.java index bcc224a94..6f452aa33 100644 --- a/src/org/traccar/protocol/MeitrackProtocol.java +++ b/src/org/traccar/protocol/MeitrackProtocol.java @@ -15,19 +15,24 @@ */ package org.traccar.protocol; +import java.nio.ByteOrder; +import java.util.List; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.TrackerServer; - -import java.nio.ByteOrder; -import java.util.List; +import org.traccar.model.Command; public class MeitrackProtocol extends BaseProtocol { public MeitrackProtocol() { super("meitrack"); + setSupportedCommands( + Command.TYPE_ENGINE_STOP, + Command.TYPE_ENGINE_RESUME, + Command.TYPE_ALARM_ARM, + Command.TYPE_ALARM_DISARM); } @Override diff --git a/src/org/traccar/protocol/MeitrackProtocolEncoder.java b/src/org/traccar/protocol/MeitrackProtocolEncoder.java new file mode 100644 index 000000000..73f3d01e4 --- /dev/null +++ b/src/org/traccar/protocol/MeitrackProtocolEncoder.java @@ -0,0 +1,40 @@ +/* + * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.traccar.StringProtocolEncoder; +import org.traccar.model.Command; + +public class MeitrackProtocolEncoder extends StringProtocolEncoder { + + @Override + protected Object encodeCommand(Command command) { + + switch (command.getType()) { + case Command.TYPE_ENGINE_STOP: + return formatCommand(command, "@@M33,{%s},C01,0,12222*18\r\n", Command.KEY_UNIQUE_ID); + case Command.TYPE_ENGINE_RESUME: + return formatCommand(command, "@@M33,{%s},C01,0,02222*18\r\n", Command.KEY_UNIQUE_ID); + case Command.TYPE_ALARM_ARM: + return formatCommand(command, "@@M33,{%s},C01,0,22122*18\r\n", Command.KEY_UNIQUE_ID); + case Command.TYPE_ALARM_DISARM: + return formatCommand(command, "@@M33,{%s},C01,0,22022*18\r\n", Command.KEY_UNIQUE_ID); + } + + return null; + } + +} diff --git a/src/org/traccar/protocol/TotemProtocolDecoder.java b/src/org/traccar/protocol/TotemProtocolDecoder.java index a22bbf71e..358c5cb67 100644 --- a/src/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/org/traccar/protocol/TotemProtocolDecoder.java @@ -20,10 +20,7 @@ import java.util.Calendar; import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; - import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; - import org.traccar.BaseProtocolDecoder; import org.traccar.model.Event; import org.traccar.model.Position; @@ -59,7 +56,7 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { "(\\d{3})" + // Battery "(\\d{4})\\|" + // External Power "(?:(\\d+)\\|)?" + // ADC - "(\\p{XDigit}{8})\\|" + // Location Code + "(\\p{XDigit}+)\\|" + // Location Code "(\\d+)\\|" + // Temperature "(\\d+.\\d+)\\|" + // Odometer "\\d+\\|" + // Serial Number @@ -315,6 +312,10 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { position.setLongitude(longitude); } + + if (channel != null) { + channel.write("ACK OK\r\n"); + } return position; } diff --git a/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java index 6eeb9c13b..1a816554f 100644 --- a/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java @@ -12,6 +12,12 @@ public class Gl200ProtocolDecoderTest extends ProtocolDecoderTest { Gl200ProtocolDecoder decoder = new Gl200ProtocolDecoder(new Gl200Protocol()); verify(decoder.decode(null, null, + "+RESP:GTOBD,1F0109,864251020135483,,gv500,0,78FFFF,,1,12613,,,,,,,,,,,,,,1286,0,0.0,0,17.1,3.379630,6.529701,20150813074639,0621,0030,51C0,A2B3,00,0.0,20150813074641,A7E6$")); + + verify(decoder.decode(null, null, + "+RESP:GTOBD,1F0109,864251020135483,4T1BE46KX7U018210,gv500,0,78FFFF,4T1BE46KX7U018210,1,13411,981B81C0,787,3,43,,921,463,1,10,0300030103030304001200310351035203530354,20,55,,1286,0,6.5,74,21.6,3.379710,6.529714,20150813074824,0621,0030,51C0,A2B3,00,0.0,20150813074828,A7E9$")); + + verify(decoder.decode(null, null, "+RESP:GTSTT,1A0401,860599000508846,,41,0,0.0,84,107.5,-76.657998,39.497203,20150623160622,0310,0260,B435,3B81,,20150623160622,0F54$")); verify(decoder.decode(null, null, diff --git a/test/org/traccar/protocol/GoSafeProtocolDecoderTest.java b/test/org/traccar/protocol/GoSafeProtocolDecoderTest.java index c1a204b3c..7148a0ab3 100644 --- a/test/org/traccar/protocol/GoSafeProtocolDecoderTest.java +++ b/test/org/traccar/protocol/GoSafeProtocolDecoderTest.java @@ -16,6 +16,12 @@ public class GoSafeProtocolDecoderTest extends ProtocolDecoderTest { verify(decoder.decode(null, null, "*GS16,351535058709775,100356130215,,SYS:G79W;V1.06;V1.0.2,GPS:A;6;N24.802700;E46.616828;0;0;684;1.35,COT:60,ADC:4.31;0.10,DTT:20000;;0;0;0;1")); + + verify(decoder.decode(null, null, + "*GS16,351535059439208,155750220815,,SYS:G79;V1.10;V1.0.2,GPS:A;4;N31.944198;E35.846644;0;0;923;9.47;1.00,COT:155133,ADC:12.21;0.10,DTT:20002;;0;0;0;1#")); + + verify(decoder.decode(null, null, + "*GS16,351535059439208,070034220815,,SYS:G79;V1.10;V1.0.2,GPS:A;8;N31.945970;E35.859848;29;65;922;1.14;1.68,COT:147528,ADC:14.07;0.11,DTT:27006;;0;0;0;3,OBD:04410C1ECD03410D2D03411C010341057A037F011203411107$070035220815,,SYS:G79;V1.10;V1.0.2,GPS:A;8;N31.945934;E35.859908;29;86;922;1.14;1.68,COT:147528,ADC:13.94;0.15,DTT:27006;;0;0;0;3,OBD:04410C1ECD03410D2D03411C010341057A037F011203411107$070037220815,,SYS:G79;V1.10;V1.0.2,GPS:A;8;N31.945844;E35.859952;29;123;922;1.14;1.68,COT:147625,ADC:13.75;0.11,DTT:27006;;0;0;0;3,OBD:04410C0FE803410D1803411C010341057C037F011203411100$070038220815,,SYS:G79;V1.10;V1.0.2,GPS:A;8;N31.945808;E35.859940;29;145;923;1.14;1.68,COT:147625,ADC:14.00;0.11,DTT:27006;;0;0;0;3,OBD:04410C0FE803410D1803411C010341057C037F011203411100#")); } diff --git a/test/org/traccar/protocol/KhdProtocolDecoderTest.java b/test/org/traccar/protocol/KhdProtocolDecoderTest.java index 2a92e3f6c..7bab7b2e8 100644 --- a/test/org/traccar/protocol/KhdProtocolDecoderTest.java +++ b/test/org/traccar/protocol/KhdProtocolDecoderTest.java @@ -38,6 +38,9 @@ public class KhdProtocolDecoderTest extends ProtocolDecoderTest { verify(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ChannelBufferTools.convertHexString( "292980002822836665140825142037045343770193879200000050ffff000082fc000004b0780b170000002a0d")))); + verify(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ChannelBufferTools.convertHexString( + "292980002802425349120811032137022373011140211100000334FFFF000082FC0000001E780913000034DF0D")))); + } } diff --git a/test/org/traccar/protocol/MegastekProtocolDecoderTest.java b/test/org/traccar/protocol/MegastekProtocolDecoderTest.java index a9b7c4f0a..21a2d46b4 100644 --- a/test/org/traccar/protocol/MegastekProtocolDecoderTest.java +++ b/test/org/traccar/protocol/MegastekProtocolDecoderTest.java @@ -12,6 +12,9 @@ public class MegastekProtocolDecoderTest extends ProtocolDecoderTest { MegastekProtocolDecoder decoder = new MegastekProtocolDecoder(new MegastekProtocol()); verify(decoder.decode(null, null, + "STX,865067020439090,$GPRMC,171013.000,A,5919.1411,N,01804.1681,E,0.000,294.41,140815,,,A")); + + verify(decoder.decode(null, null, "$MGV002,013777007536434,,R,010114,000057,V,0000.0000,N,00000.0000,E,00,00,00,99.9,0.000,0.00,0.0,80.263,510,89,2342,030B,,0000,0000,200,96,0, , ,,,,Timer;!")); verify(decoder.decode(null, null, diff --git a/test/org/traccar/protocol/TotemProtocolDecoderTest.java b/test/org/traccar/protocol/TotemProtocolDecoderTest.java index cdb6be355..c01640241 100644 --- a/test/org/traccar/protocol/TotemProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TotemProtocolDecoderTest.java @@ -11,7 +11,10 @@ public class TotemProtocolDecoderTest extends ProtocolDecoderTest { public void testDecode() throws Exception { TotemProtocolDecoder decoder = new TotemProtocolDecoder(new TotemProtocol()); - + + verify(decoder.decode(null, null, + "$$BE863771024392112|AA$GPRMC,044704.000,A,1439.3334,N,12059.1417,E,0.00,0.00,200815,,,A*67|01.7|00.8|01.4|000000000000|20150820044704|14291265|00000000|4EECBF8B31|0000|0.0000|0002|00000|56E7")); + verify(decoder.decode(null, null, "$$AE860990002922822|AA$GPRMC,051002.00,A,0439.26245,N,10108.94448,E,0.023,,140315,,,A*71|02.98|01.95|02.26|000000000000|20150314051003|13841157|105A3B1C|0000|0.0000|0005|5324")); diff --git a/web/app/model/Server.js b/web/app/model/Server.js index 9e4ab1eec..b21f28299 100644 --- a/web/app/model/Server.js +++ b/web/app/model/Server.js @@ -22,6 +22,8 @@ Ext.define('Traccar.model.Server', { { name: 'id', type: 'int' }, { name: 'registration', type: 'boolean' }, { name: 'map', type: 'string' }, + { name: 'bingKey', type: 'string' }, + { name: 'mapUrl', type: 'string' }, { name: 'language', type: 'string' }, { name: 'distanceUnit', type: 'string' }, { name: 'speedUnit', type: 'string' }, diff --git a/web/app/store/MapTypes.js b/web/app/store/MapTypes.js index ebc45cc8d..fbdc49acc 100644 --- a/web/app/store/MapTypes.js +++ b/web/app/store/MapTypes.js @@ -20,6 +20,7 @@ Ext.define('Traccar.store.MapTypes', { data: [ {'key': 'osm', 'name': strings.mapOsm}, {'key': 'bingRoad', 'name': strings.mapBingRoad}, - {'key': 'bingAerial', 'name': strings.mapBingAerial} + {'key': 'bingAerial', 'name': strings.mapBingAerial}, + {'key': 'custom', 'name': strings.mapCustom}, ] }); diff --git a/web/app/view/admin/ServerDialog.js b/web/app/view/admin/ServerDialog.js index 37bb498a0..080e2fcc4 100644 --- a/web/app/view/admin/ServerDialog.js +++ b/web/app/view/admin/ServerDialog.js @@ -43,6 +43,14 @@ Ext.define('Traccar.view.admin.ServerDialog', { displayField: 'name', valueField: 'key' }, { + xtype: 'textfield', + name: 'bingKey', + fieldLabel: strings.mapBingKey + }, { + xtype: 'textfield', + name: 'mapUrl', + fieldLabel: strings.mapCustom + }, { xtype: 'combobox', name: 'distanceUnit', fieldLabel: strings.settingsDistanceUnit, diff --git a/web/app/view/map/Map.js b/web/app/view/map/Map.js index 9d9a92886..cdb46342b 100644 --- a/web/app/view/map/Map.js +++ b/web/app/view/map/Map.js @@ -36,16 +36,20 @@ Ext.define('Traccar.view.map.Map', { var layer; var mapLayer = user.get('map') || server.get('map'); - var bindKey = 'AseEs0DLJhLlTNoxbNXu7DGsnnH4UoWuGue7-irwKkE3fffaClwc9q_Mr6AyHY8F'; + var bingKey = server.get('bingKey'); - if (mapLayer === 'bingRoad') { + if (mapLayer === 'custom') { + layer = new ol.layer.Tile({ source: new ol.source.XYZ({ + url: server.get('mapUrl') + })}); + } else if (mapLayer === 'bingRoad') { layer = new ol.layer.Tile({ source: new ol.source.BingMaps({ - key: bindKey, + key: bingKey, imagerySet: 'Road' })}); } else if (mapLayer === 'bingAerial') { layer = new ol.layer.Tile({ source: new ol.source.BingMaps({ - key: bindKey, + key: bingKey, imagerySet: 'Aerial' })}); } else { diff --git a/web/app/view/map/MapController.js b/web/app/view/map/MapController.js index 98922a307..0aab71725 100644 --- a/web/app/view/map/MapController.js +++ b/web/app/view/map/MapController.js @@ -128,9 +128,8 @@ Ext.define('Traccar.view.map.MapController', { var vectorSource = this.getView().vectorSource; - var data = Ext.getStore('Positions').getData().clone(); - data.sort('fixTime'); - + var data = Ext.getStore('Positions').getData(); + var index; var positions = []; this.reportRoutePoints = {}; diff --git a/web/app/view/state/StateController.js b/web/app/view/state/StateController.js index 58bc5c55c..73dc28b50 100644 --- a/web/app/view/state/StateController.js +++ b/web/app/view/state/StateController.js @@ -73,6 +73,14 @@ Ext.define('Traccar.view.state.StateController', { } }, + formatValue: function(value) { + if (typeof(id) === 'number') { + return +value.toFixed(2); + } else { + return value; + } + }, + updatePosition: function(position) { var other; @@ -93,7 +101,7 @@ Ext.define('Traccar.view.state.StateController', { store.add(Ext.create('Traccar.model.Parameter', { priority: this.keys[key].priority, name: this.keys[key].name, - value: value + value: this.formatValue(value) })); } } @@ -119,7 +127,7 @@ Ext.define('Traccar.view.state.StateController', { name: key.replace(/^./, function (match) { return match.toUpperCase(); }), - value: value + value: this.formatValue(value) })); } } diff --git a/web/l10n/en.js b/web/l10n/en.js index 33c494a54..4c1e0f233 100644 --- a/web/l10n/en.js +++ b/web/l10n/en.js @@ -66,7 +66,9 @@ var strings = { mapTitle: 'Map', mapLayer: 'Map Layer', + mapCustom: 'Custom Map', mapOsm: 'Open Street Map', + mapBingKey: 'Bing Maps Key', mapBingRoad: 'Bing Maps Road', mapBingAerial: 'Bing Maps Aerial', diff --git a/web/l10n/sk.js b/web/l10n/sk.js new file mode 100644 index 000000000..0c0fa77c3 --- /dev/null +++ b/web/l10n/sk.js @@ -0,0 +1,86 @@ +var strings = { + sharedLoading: 'Načítava...', + sharedSave: 'Uloženie', + sharedCancel: 'Zrušenie', + sharedAdd: 'Pridať', + sharedEdit: 'Úprava', + sharedRemove: 'Odstrániť', + sharedRemoveConfirm: 'Odstrániť položku?', + sharedKm: 'Km', + sharedMi: 'mi', + sharedKmh: 'Km/h', + sharedMph: 'mph', + sharedHour: 'Hodina', + sharedMinute: 'Minúta', + sharedSecond: 'Druhý', + + errorTitle: 'Chyba', + errorUnknown: 'Neznáma chyba', + + userName: 'Meno', + userEmail: 'E-mail', + userPassword: 'Heslo', + userAdmin: 'Admin', + + loginTitle: 'Prihlásenie', + loginLanguage: 'Jazyk', + loginRegister: 'Registrovať', + loginLogin: 'Prihlásenie', + loginFailed: 'Nesprávna e-mailová adresa alebo heslo', + loginCreated: 'Nový užívateľ sa zaregistroval', + loginLogout: 'Odhlásiť', + + deviceDialog: 'Zariadenie', + deviceTitle: 'Zariadena', + deviceName: 'Meno', + deviceIdentifier: 'Identifikátor', + deviceCommand: 'Príkaz', + + settingsTitle: 'Nastavenia', + settingsUser: 'Účet', + settingsServer: 'Server', + settingsUsers: 'Užívatelia', + settingsDistanceUnit: 'Vzdialenosť', + settingsSpeedUnit: 'Rýchlosť jazdy', + + reportTitle: 'Správy', + reportDevice: 'Zariadenie', + reportFrom: 'Z', + reportTo: 'do', + reportShow: 'Zobraziť', + reportClear: 'Vyčistiť', + + positionTime: 'Čas', + positionValid: 'Platný', + positionLatitude: 'Šírka', + positionLongitude: 'Dĺžka', + positionAltitude: 'Výška', + positionSpeed: 'Rýchlosť jazdy', + positionCourse: 'Kurz', + positionAddress: 'Adresa', + positionProtocol: 'Protokol', + + serverTitle: 'Nastavenie servera', + serverZoom: 'Zoom', + serverRegistration: 'Registrácia', + + mapTitle: 'Mapa', + mapLayer: 'Mapové vrstvy', + mapOsm: 'Open Street Map', + mapBingRoad: 'Bing Maps Road', + mapBingAerial: 'Bing Maps Arial', + + stateTitle: 'Štát', + stateName: 'Parameter', + stateValue: 'Hodnota', + + commandTitle: 'Príkaz', + commandSend: 'Odoslať', + commandType: 'Typ', + commandPositionPeriodic: 'Pravidelné podávanie správ', + commandPositionStop: 'Zastavte podávanie správ', + commandEngineStop: 'Zastavenie motora', + commandEngineResume: 'Spustenie motora', + commandFrequency: 'Frekvencia', + commandUnit: 'Unit' +}; diff --git a/web/l10n/sr.js b/web/l10n/sr.js new file mode 100644 index 000000000..8bfe6f104 --- /dev/null +++ b/web/l10n/sr.js @@ -0,0 +1,86 @@ +var strings = { + sharedLoading: 'Učitava...', + sharedSave: 'Sačuvaj', + sharedCancel: 'Odustani', + sharedAdd: 'Dodaj', + sharedEdit: 'Podesi', + sharedRemove: 'Ukloni', + sharedRemoveConfirm: 'Ukloniti jedinicu?', + sharedKm: 'km', + sharedMi: 'mi', + sharedKmh: 'km/h', + sharedMph: 'mph', + sharedHour: 'Čas', + sharedMinute: 'Minut', + sharedSecond: 'Sekunda', + + errorTitle: 'Greška', + errorUnknown: 'Nepoznata greška', + + userName: 'Ime', + userEmail: 'Email', + userPassword: 'Lozinka', + userAdmin: 'Admin', + + loginTitle: 'Prijava', + loginLanguage: 'Jezik', + loginRegister: 'Registruj se', + loginLogin: 'Prijava', + loginFailed: 'Neispravna email adresa ili lozinka', + loginCreated: 'Novi korisnik je registrovan', + loginLogout: 'Odjava', + + deviceDialog: 'Uređaj', + deviceTitle: 'Uređaji', + deviceName: 'Ime', + deviceIdentifier: 'Identifikator', + deviceCommand: 'Komanda', + + settingsTitle: 'Podešavanja', + settingsUser: 'Nalog', + settingsServer: 'Server', + settingsUsers: 'Korisnici', + settingsDistanceUnit: 'Udaljenost', + settingsSpeedUnit: 'Brzina', + + reportTitle: 'Izveštaji', + reportDevice: 'Uređaj', + reportFrom: 'Od', + reportTo: 'Do', + reportShow: 'Prikaži', + reportClear: 'Izbriši', + + positionTime: 'Vreme', + positionValid: 'Ispravno', + positionLatitude: 'Geografska širina', + positionLongitude: 'Geografska dužina', + positionAltitude: 'Visina', + positionSpeed: 'Brzina', + positionCourse: 'Pravac', + positionAddress: 'Adresa', + positionProtocol: 'Protokol', + + serverTitle: 'Podešavanja Servera', + serverZoom: 'Zumiranje', + serverRegistration: 'Registracija', + + mapTitle: 'Mapa', + mapLayer: 'Vrsta Mape', + mapOsm: 'Open Street Map', + mapBingRoad: 'Bing Maps Road', + mapBingAerial: 'Bing Maps Aerial', + + stateTitle: 'Stanje', + stateName: 'Parametar', + stateValue: 'Vrednost', + + commandTitle: 'Komanda', + commandSend: 'Pošalji', + commandType: 'Tip', + commandPositionPeriodic: 'Periodično izveštavanje', + commandPositionStop: 'Prekini izveštavanja', + commandEngineStop: 'Zaustavi motor', + commandEngineResume: 'Pokreni motor', + commandFrequency: 'Frekvencija', + commandUnit: 'Jedinica' +}; diff --git a/web/locale.js b/web/locale.js index 497b6ab2e..c5aca40cd 100644 --- a/web/locale.js +++ b/web/locale.js @@ -28,6 +28,8 @@ var availableLanguages = { 'pl': { name: 'Polski', code: 'pl' }, 'pt': { name: 'Português', code: 'pt' }, 'ru': { name: 'Русский', code: 'ru' }, + 'sk': { name: 'Slovenčina', code: 'sk' }, + 'sr': { name: 'Srpski', code: 'sr' }, 'th': { name: 'ไทย', code: 'th' }, 'zh': { name: '中文', code: 'zh_CN' }, 'lt': { name: 'Lietuvių', code: 'lt' } |