diff options
236 files changed, 3907 insertions, 6393 deletions
diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 8bc638a65..61d527e5a 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -16,6 +16,6 @@ jobs: - uses: actions/setup-java@v4 with: distribution: temurin - java-version: 11 + java-version: 17 cache: gradle - run: ./gradlew build --no-daemon diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 26695dbac..79ea35262 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -42,9 +42,9 @@ jobs: working-directory: ./setup run: | wget -q http://files.jrsoftware.org/is/5/isetup-5.5.6.exe - wget -q https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.2+13/OpenJDK21U-jdk_x64_windows_hotspot_21.0.2_13.zip - wget -q https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.2+13/OpenJDK21U-jdk_x64_linux_hotspot_21.0.2_13.tar.gz - wget -q https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.2+13/OpenJDK21U-jdk_aarch64_linux_hotspot_21.0.2_13.tar.gz + wget -q https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.4+7/OpenJDK21U-jdk_x64_windows_hotspot_21.0.4_7.zip + wget -q https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.4+7/OpenJDK21U-jdk_x64_linux_hotspot_21.0.4_7.tar.gz + wget -q https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.4+7/OpenJDK21U-jdk_aarch64_linux_hotspot_21.0.4_7.tar.gz ./package.sh ${{ github.event.inputs.version }} - name: Upload installers working-directory: ./setup diff --git a/build.gradle b/build.gradle index 029c4ae6d..9786c8458 100644 --- a/build.gradle +++ b/build.gradle @@ -10,8 +10,8 @@ repositories { } java { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } compileJava.options.encoding = "UTF-8" @@ -24,8 +24,9 @@ checkstyle { } enforce { + // noinspection UnnecessaryQualifiedReference rule(enforcer.rules.EnforceBytecodeVersion) { r -> - r.maxJdkVersion = "11" + r.maxJdkVersion = "17" } } @@ -33,10 +34,10 @@ ext { guiceVersion = "7.0.0" jettyVersion = "11.0.21" jerseyVersion = "3.1.7" - jacksonVersion = "2.17.1" // same version as jersey-media-json-jackson dependency - protobufVersion = "4.27.0" - jxlsVersion = "2.14.0" // version 3 requires java 17 - junitVersion = "5.10.2" + jacksonVersion = "2.17.2" // same version as jersey-media-json-jackson dependency + protobufVersion = "4.27.2" + jxlsVersion = "2.14.0" // version 3 has breaking changes + junitVersion = "5.10.3" } protobuf { @@ -46,14 +47,14 @@ protobuf { } dependencies { - implementation "commons-codec:commons-codec:1.17.0" - implementation "com.h2database:h2:2.2.224" - implementation "com.mysql:mysql-connector-j:8.4.0" - implementation "org.mariadb.jdbc:mariadb-java-client:3.4.0" + implementation "commons-codec:commons-codec:1.17.1" + implementation "com.h2database:h2:2.3.230" + implementation "com.mysql:mysql-connector-j:9.0.0" + implementation "org.mariadb.jdbc:mariadb-java-client:3.4.1" implementation "org.postgresql:postgresql:42.7.3" - implementation "com.microsoft.sqlserver:mssql-jdbc:12.6.2.jre11" + implementation "com.microsoft.sqlserver:mssql-jdbc:12.6.3.jre11" implementation "com.zaxxer:HikariCP:5.1.0" - implementation "io.netty:netty-all:4.1.110.Final" + implementation "io.netty:netty-all:4.1.112.Final" implementation "org.slf4j:slf4j-jdk14:2.0.13" implementation "com.google.inject:guice:$guiceVersion" implementation "com.google.inject.extensions:guice-servlet:$guiceVersion" @@ -73,24 +74,24 @@ dependencies { implementation "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:$jacksonVersion" implementation "com.fasterxml.jackson.datatype:jackson-datatype-jakarta-jsonp:$jacksonVersion" implementation "org.liquibase:liquibase-core:4.23.2" // upgrade has issues - implementation "org.apache.commons:commons-jexl3:3.3" + implementation "org.apache.commons:commons-jexl3:3.4.0" implementation "org.jxls:jxls:$jxlsVersion" implementation "org.jxls:jxls-poi:$jxlsVersion" implementation "org.apache.velocity:velocity-engine-core:2.3" implementation "org.apache.velocity.tools:velocity-tools-generic:3.1" implementation "org.apache.commons:commons-collections4:4.4" - implementation "org.mnode.ical4j:ical4j:3.2.18" + implementation "org.mnode.ical4j:ical4j:4.0.2" implementation "org.locationtech.spatial4j:spatial4j:0.8" implementation "org.locationtech.jts:jts-core:1.19.0" implementation "net.java.dev.jna:jna-platform:5.14.0" implementation "com.github.jnr:jnr-posix:3.1.19" implementation "com.google.protobuf:protobuf-java:$protobufVersion" - implementation "com.amazonaws:aws-java-sdk-sns:1.12.733" - implementation "org.apache.kafka:kafka-clients:3.7.0" + implementation "com.amazonaws:aws-java-sdk-sns:1.12.765" + implementation "org.apache.kafka:kafka-clients:3.8.0" implementation "com.hivemq:hivemq-mqtt-client:1.3.3" implementation "redis.clients:jedis:5.1.3" implementation "com.google.firebase:firebase-admin:9.3.0" - implementation "com.nimbusds:oauth2-oidc-sdk:11.12" + implementation "com.nimbusds:oauth2-oidc-sdk:11.13" implementation "com.rabbitmq:amqp-client:5.21.0" implementation "com.warrenstrange:googleauth:1.5.0" implementation "com.google.openlocationcode:openlocationcode:1.0.4" @@ -113,7 +114,7 @@ jar { manifest { attributes( "Main-Class": "org.traccar.Main", - "Implementation-Version": "6.2", + "Implementation-Version": "6.3", "Class-Path": configurations.runtimeClasspath.files.collect { "lib/$it.name" }.join(" ")) } } @@ -1,4 +1,4 @@ -<?xml version='1.0' encoding='UTF-8'?> +<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE properties SYSTEM 'http://java.sun.com/dtd/properties.dtd'> <properties> diff --git a/gradle/checkstyle.xml b/gradle/checkstyle.xml index bb89450d6..fc016c6f6 100644 --- a/gradle/checkstyle.xml +++ b/gradle/checkstyle.xml @@ -115,7 +115,7 @@ <module name="EqualsHashCode"/> <module name="IllegalInstantiation"/> <!--<module name="InnerAssignment"/>--> - <module name="MissingSwitchDefault"/> + <!--<module name="MissingSwitchDefault"/>--> <module name="SimplifyBooleanExpression"/> <module name="SimplifyBooleanReturn"/> diff --git a/schema/changelog-6.3.xml b/schema/changelog-6.3.xml new file mode 100644 index 000000000..c987a7315 --- /dev/null +++ b/schema/changelog-6.3.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<databaseChangeLog + xmlns="http://www.liquibase.org/xml/ns/dbchangelog" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog + http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd" + logicalFilePath="changelog-6.3"> + + <changeSet author="author" id="changelog-6.3-old"> + + <preConditions onFail="MARK_RAN"> + <foreignKeyConstraintExists foreignKeyTableName="tc_events" foreignKeyName="fk_event_deviceid" /> + </preConditions> + + <dropForeignKeyConstraint baseTableName="tc_events" constraintName="fk_event_deviceid" /> + <dropForeignKeyConstraint baseTableName="tc_positions" constraintName="fk_position_deviceid" /> + + </changeSet> + + <changeSet author="author" id="changelog-6.3-new"> + + <preConditions onFail="MARK_RAN"> + <foreignKeyConstraintExists foreignKeyTableName="tc_events" foreignKeyName="fk_events_deviceid" /> + </preConditions> + + <dropForeignKeyConstraint baseTableName="tc_events" constraintName="fk_events_deviceid" /> + <dropForeignKeyConstraint baseTableName="tc_positions" constraintName="fk_positions_deviceid" /> + + </changeSet> + +</databaseChangeLog> diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml index e9ae52569..3ce4b43e6 100644 --- a/schema/changelog-master.xml +++ b/schema/changelog-master.xml @@ -44,5 +44,6 @@ <include file="changelog-5.11.xml" relativeToChangelogFile="true" /> <include file="changelog-6.2.xml" relativeToChangelogFile="true" /> + <include file="changelog-6.3.xml" relativeToChangelogFile="true" /> </databaseChangeLog> diff --git a/setup/cloud-init.yaml b/setup/cloud-init.yaml index 3d55f5f6f..734f8e370 100644 --- a/setup/cloud-init.yaml +++ b/setup/cloud-init.yaml @@ -2,7 +2,7 @@ write_files: - content: | - <?xml version='1.0' encoding='UTF-8'?> + <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE properties SYSTEM 'http://java.sun.com/dtd/properties.dtd'> <properties> <entry key='database.driver'>com.mysql.jdbc.Driver</entry> diff --git a/setup/traccar.iss b/setup/traccar.iss index ad8e2552b..b86c6012d 100644 --- a/setup/traccar.iss +++ b/setup/traccar.iss @@ -1,6 +1,6 @@ [Setup] AppName=Traccar -AppVersion=6.2 +AppVersion=6.3 DefaultDirName={pf}\Traccar OutputBaseFilename=traccar-setup ArchitecturesInstallIn64BitMode=x64 diff --git a/setup/traccar.xml b/setup/traccar.xml index d5bd87e9c..2b4518307 100644 --- a/setup/traccar.xml +++ b/setup/traccar.xml @@ -1,4 +1,4 @@ -<?xml version='1.0' encoding='UTF-8'?> +<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE properties SYSTEM 'http://java.sun.com/dtd/properties.dtd'> <properties> diff --git a/src/main/java/org/traccar/BaseMqttProtocolDecoder.java b/src/main/java/org/traccar/BaseMqttProtocolDecoder.java index 0388563f5..5a55eee74 100644 --- a/src/main/java/org/traccar/BaseMqttProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseMqttProtocolDecoder.java @@ -38,9 +38,7 @@ public abstract class BaseMqttProtocolDecoder extends BaseProtocolDecoder { protected final Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - if (msg instanceof MqttConnectMessage) { - - MqttConnectMessage message = (MqttConnectMessage) msg; + if (msg instanceof MqttConnectMessage message) { DeviceSession deviceSession = getDeviceSession( channel, remoteAddress, message.payload().clientIdentifier()); @@ -55,9 +53,7 @@ public abstract class BaseMqttProtocolDecoder extends BaseProtocolDecoder { channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } - } else if (msg instanceof MqttSubscribeMessage) { - - MqttSubscribeMessage message = (MqttSubscribeMessage) msg; + } else if (msg instanceof MqttSubscribeMessage message) { MqttMessage response = MqttMessageBuilders.subAck() .packetId(message.variableHeader().messageId()) @@ -67,15 +63,13 @@ public abstract class BaseMqttProtocolDecoder extends BaseProtocolDecoder { channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } - } else if (msg instanceof MqttPublishMessage) { + } else if (msg instanceof MqttPublishMessage message) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { return null; } - MqttPublishMessage message = (MqttPublishMessage) msg; - Object result = decode(deviceSession, message); MqttMessage response = MqttMessageBuilders.pubAck() diff --git a/src/main/java/org/traccar/BasePipelineFactory.java b/src/main/java/org/traccar/BasePipelineFactory.java index 40360cca7..92b9759c1 100644 --- a/src/main/java/org/traccar/BasePipelineFactory.java +++ b/src/main/java/org/traccar/BasePipelineFactory.java @@ -64,10 +64,10 @@ public abstract class BasePipelineFactory extends ChannelInitializer<Channel> { public static <T extends ChannelHandler> T getHandler(ChannelPipeline pipeline, Class<T> clazz) { for (Map.Entry<String, ChannelHandler> handlerEntry : pipeline) { ChannelHandler handler = handlerEntry.getValue(); - if (handler instanceof WrapperInboundHandler) { - handler = ((WrapperInboundHandler) handler).getWrappedHandler(); - } else if (handler instanceof WrapperOutboundHandler) { - handler = ((WrapperOutboundHandler) handler).getWrappedHandler(); + if (handler instanceof WrapperInboundHandler wrapperHandler) { + handler = wrapperHandler.getWrappedHandler(); + } else if (handler instanceof WrapperOutboundHandler wrapperHandler) { + handler = wrapperHandler.getWrappedHandler(); } if (clazz.isAssignableFrom(handler.getClass())) { return (T) handler; @@ -106,10 +106,10 @@ public abstract class BasePipelineFactory extends ChannelInitializer<Channel> { if (handler instanceof BaseProtocolDecoder || handler instanceof BaseProtocolEncoder) { injectMembers(handler); } else { - if (handler instanceof ChannelInboundHandler) { - handler = new WrapperInboundHandler((ChannelInboundHandler) handler); - } else { - handler = new WrapperOutboundHandler((ChannelOutboundHandler) handler); + if (handler instanceof ChannelInboundHandler channelHandler) { + handler = new WrapperInboundHandler(channelHandler); + } else if (handler instanceof ChannelOutboundHandler channelHandler) { + handler = new WrapperOutboundHandler(channelHandler); } } pipeline.addLast(handler); diff --git a/src/main/java/org/traccar/BaseProtocolDecoder.java b/src/main/java/org/traccar/BaseProtocolDecoder.java index b764e5cdf..5e3f668ed 100644 --- a/src/main/java/org/traccar/BaseProtocolDecoder.java +++ b/src/main/java/org/traccar/BaseProtocolDecoder.java @@ -108,17 +108,12 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { } protected double convertSpeed(double value, String defaultUnits) { - switch (getConfig().getString(getProtocolName() + ".speed", defaultUnits)) { - case "kmh": - return UnitsConverter.knotsFromKph(value); - case "mps": - return UnitsConverter.knotsFromMps(value); - case "mph": - return UnitsConverter.knotsFromMph(value); - case "kn": - default: - return value; - } + return switch (getConfig().getString(getProtocolName() + ".speed", defaultUnits)) { + case "kmh" -> UnitsConverter.knotsFromKph(value); + case "mps" -> UnitsConverter.knotsFromMps(value); + case "mph" -> UnitsConverter.knotsFromMph(value); + default -> value; + }; } protected TimeZone getTimeZone(long deviceId) { @@ -168,8 +163,8 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { } Set<Long> deviceIds = new HashSet<>(); if (decodedMessage != null) { - if (decodedMessage instanceof Position) { - deviceIds.add(((Position) decodedMessage).getDeviceId()); + if (decodedMessage instanceof Position position) { + deviceIds.add(position.getDeviceId()); } else if (decodedMessage instanceof Collection) { Collection<Position> positions = (Collection) decodedMessage; for (Position position : positions) { diff --git a/src/main/java/org/traccar/BaseProtocolEncoder.java b/src/main/java/org/traccar/BaseProtocolEncoder.java index e357c27dc..2724a59b1 100644 --- a/src/main/java/org/traccar/BaseProtocolEncoder.java +++ b/src/main/java/org/traccar/BaseProtocolEncoder.java @@ -82,11 +82,9 @@ public abstract class BaseProtocolEncoder extends ChannelOutboundHandlerAdapter @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - if (msg instanceof NetworkMessage) { - NetworkMessage networkMessage = (NetworkMessage) msg; - if (networkMessage.getMessage() instanceof Command) { + if (msg instanceof NetworkMessage networkMessage) { + if (networkMessage.getMessage() instanceof Command command) { - Command command = (Command) networkMessage.getMessage(); Object encodedCommand = encodeCommand(ctx.channel(), command); StringBuilder s = new StringBuilder(); diff --git a/src/main/java/org/traccar/ExtendedObjectDecoder.java b/src/main/java/org/traccar/ExtendedObjectDecoder.java index 9468e2fff..8d693c7cf 100644 --- a/src/main/java/org/traccar/ExtendedObjectDecoder.java +++ b/src/main/java/org/traccar/ExtendedObjectDecoder.java @@ -54,14 +54,12 @@ public abstract class ExtendedObjectDecoder extends ChannelInboundHandlerAdapter } private void saveOriginal(Object decodedMessage, Object originalMessage) { - if (getConfig().getBoolean(Keys.DATABASE_SAVE_ORIGINAL) && decodedMessage instanceof Position) { - Position position = (Position) decodedMessage; - if (originalMessage instanceof ByteBuf) { - ByteBuf buf = (ByteBuf) originalMessage; + if (getConfig().getBoolean(Keys.DATABASE_SAVE_ORIGINAL) && decodedMessage instanceof Position position) { + if (originalMessage instanceof ByteBuf buf) { position.set(Position.KEY_ORIGINAL, ByteBufUtil.hexDump(buf, 0, buf.writerIndex())); - } else if (originalMessage instanceof String) { + } else if (originalMessage instanceof String stringMessage) { position.set(Position.KEY_ORIGINAL, DataConverter.printHex( - ((String) originalMessage).getBytes(StandardCharsets.US_ASCII))); + stringMessage.getBytes(StandardCharsets.US_ASCII))); } } } @@ -78,8 +76,7 @@ public abstract class ExtendedObjectDecoder extends ChannelInboundHandlerAdapter decodedMessage = handleEmptyMessage(ctx.channel(), networkMessage.getRemoteAddress(), originalMessage); } if (decodedMessage != null) { - if (decodedMessage instanceof Collection) { - var collection = (Collection) decodedMessage; + if (decodedMessage instanceof Collection collection) { ctx.writeAndFlush(new AcknowledgementHandler.EventDecoded(collection)); for (Object o : collection) { saveOriginal(o, originalMessage); diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index 66238ab44..945bb8bc2 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -68,6 +68,7 @@ import org.traccar.geocoder.OpenCageGeocoder; import org.traccar.geocoder.PositionStackGeocoder; import org.traccar.geocoder.PlusCodesGeocoder; import org.traccar.geocoder.TomTomGeocoder; +import org.traccar.geocoder.GeocodeJsonGeocoder; import org.traccar.geolocation.GeolocationProvider; import org.traccar.geolocation.GoogleGeolocationProvider; import org.traccar.geolocation.OpenCellIdGeolocationProvider; @@ -205,66 +206,28 @@ public class MainModule extends AbstractModule { AddressFormat addressFormat = formatString != null ? new AddressFormat(formatString) : new AddressFormat(); int cacheSize = config.getInteger(Keys.GEOCODER_CACHE_SIZE); - Geocoder geocoder; - switch (type) { - case "pluscodes": - geocoder = new PlusCodesGeocoder(); - break; - case "nominatim": - geocoder = new NominatimGeocoder(client, url, key, language, cacheSize, addressFormat); - break; - case "locationiq": - geocoder = new LocationIqGeocoder(client, url, key, language, cacheSize, addressFormat); - break; - case "gisgraphy": - geocoder = new GisgraphyGeocoder(client, url, cacheSize, addressFormat); - break; - case "mapquest": - geocoder = new MapQuestGeocoder(client, url, key, cacheSize, addressFormat); - break; - case "opencage": - geocoder = new OpenCageGeocoder(client, url, key, language, cacheSize, addressFormat); - break; - case "bingmaps": - geocoder = new BingMapsGeocoder(client, url, key, cacheSize, addressFormat); - break; - case "factual": - geocoder = new FactualGeocoder(client, url, key, cacheSize, addressFormat); - break; - case "geocodefarm": - geocoder = new GeocodeFarmGeocoder(client, key, language, cacheSize, addressFormat); - break; - case "geocodexyz": - geocoder = new GeocodeXyzGeocoder(client, key, cacheSize, addressFormat); - break; - case "ban": - geocoder = new BanGeocoder(client, cacheSize, addressFormat); - break; - case "here": - geocoder = new HereGeocoder(client, url, key, language, cacheSize, addressFormat); - break; - case "mapmyindia": - geocoder = new MapmyIndiaGeocoder(client, url, key, cacheSize, addressFormat); - break; - case "tomtom": - geocoder = new TomTomGeocoder(client, url, key, cacheSize, addressFormat); - break; - case "positionstack": - geocoder = new PositionStackGeocoder(client, key, cacheSize, addressFormat); - break; - case "mapbox": - geocoder = new MapboxGeocoder(client, key, cacheSize, addressFormat); - break; - case "maptiler": - geocoder = new MapTilerGeocoder(client, key, cacheSize, addressFormat); - break; - case "geoapify": - geocoder = new GeoapifyGeocoder(client, key, language, cacheSize, addressFormat); - break; - default: - geocoder = new GoogleGeocoder(client, key, language, cacheSize, addressFormat); - break; - } + Geocoder geocoder = switch (type) { + case "pluscodes" -> new PlusCodesGeocoder(); + case "nominatim" -> new NominatimGeocoder(client, url, key, language, cacheSize, addressFormat); + case "locationiq" -> new LocationIqGeocoder(client, url, key, language, cacheSize, addressFormat); + case "gisgraphy" -> new GisgraphyGeocoder(client, url, cacheSize, addressFormat); + case "mapquest" -> new MapQuestGeocoder(client, url, key, cacheSize, addressFormat); + case "opencage" -> new OpenCageGeocoder(client, url, key, language, cacheSize, addressFormat); + case "bingmaps" -> new BingMapsGeocoder(client, url, key, cacheSize, addressFormat); + case "factual" -> new FactualGeocoder(client, url, key, cacheSize, addressFormat); + case "geocodefarm" -> new GeocodeFarmGeocoder(client, key, language, cacheSize, addressFormat); + case "geocodexyz" -> new GeocodeXyzGeocoder(client, key, cacheSize, addressFormat); + case "ban" -> new BanGeocoder(client, cacheSize, addressFormat); + case "here" -> new HereGeocoder(client, url, key, language, cacheSize, addressFormat); + case "mapmyindia" -> new MapmyIndiaGeocoder(client, url, key, cacheSize, addressFormat); + case "tomtom" -> new TomTomGeocoder(client, url, key, cacheSize, addressFormat); + case "positionstack" -> new PositionStackGeocoder(client, key, cacheSize, addressFormat); + case "mapbox" -> new MapboxGeocoder(client, key, cacheSize, addressFormat); + case "maptiler" -> new MapTilerGeocoder(client, key, cacheSize, addressFormat); + case "geoapify" -> new GeoapifyGeocoder(client, key, language, cacheSize, addressFormat); + case "geocodejson" -> new GeocodeJsonGeocoder(client, url, key, language, cacheSize, addressFormat); + default -> new GoogleGeocoder(client, url, key, language, cacheSize, addressFormat); + }; geocoder.setStatisticsManager(statisticsManager); return geocoder; } @@ -278,14 +241,11 @@ public class MainModule extends AbstractModule { String type = config.getString(Keys.GEOLOCATION_TYPE, "google"); String url = config.getString(Keys.GEOLOCATION_URL); String key = config.getString(Keys.GEOLOCATION_KEY); - switch (type) { - case "opencellid": - return new OpenCellIdGeolocationProvider(client, url, key); - case "unwired": - return new UnwiredGeolocationProvider(client, url, key); - default: - return new GoogleGeolocationProvider(client, key); - } + return switch (type) { + case "opencellid" -> new OpenCellIdGeolocationProvider(client, url, key); + case "unwired" -> new UnwiredGeolocationProvider(client, url, key); + default -> new GoogleGeolocationProvider(client, key); + }; } return null; } @@ -296,11 +256,10 @@ public class MainModule extends AbstractModule { if (config.getBoolean(Keys.SPEED_LIMIT_ENABLE)) { String type = config.getString(Keys.SPEED_LIMIT_TYPE, "overpass"); String url = config.getString(Keys.SPEED_LIMIT_URL); - switch (type) { - case "overpass": - default: - return new OverpassSpeedLimitProvider(config, client, url); - } + return switch (type) { + case "overpass" -> new OverpassSpeedLimitProvider(config, client, url); + default -> throw new IllegalArgumentException("Unknown speed limit provider"); + }; } return null; } @@ -368,14 +327,11 @@ public class MainModule extends AbstractModule { public static BroadcastService provideBroadcastService( Config config, ObjectMapper objectMapper) throws IOException { if (config.hasKey(Keys.BROADCAST_TYPE)) { - switch (config.getString(Keys.BROADCAST_TYPE)) { - case "multicast": - return new MulticastBroadcastService(config, objectMapper); - case "redis": - return new RedisBroadcastService(config, objectMapper); - default: - break; - } + return switch (config.getString(Keys.BROADCAST_TYPE)) { + case "multicast" -> new MulticastBroadcastService(config, objectMapper); + case "redis" -> new RedisBroadcastService(config, objectMapper); + default -> new NullBroadcastService(); + }; } return new NullBroadcastService(); } @@ -385,17 +341,12 @@ public class MainModule extends AbstractModule { public static EventForwarder provideEventForwarder(Config config, Client client, ObjectMapper objectMapper) { if (config.hasKey(Keys.EVENT_FORWARD_URL)) { String forwardType = config.getString(Keys.EVENT_FORWARD_TYPE); - switch (forwardType) { - case "amqp": - return new EventForwarderAmqp(config, objectMapper); - case "kafka": - return new EventForwarderKafka(config, objectMapper); - case "mqtt": - return new EventForwarderMqtt(config, objectMapper); - case "json": - default: - return new EventForwarderJson(config, client); - } + return switch (forwardType) { + case "amqp" -> new EventForwarderAmqp(config, objectMapper); + case "kafka" -> new EventForwarderKafka(config, objectMapper); + case "mqtt" -> new EventForwarderMqtt(config, objectMapper); + default -> new EventForwarderJson(config, client); + }; } return null; } @@ -404,21 +355,14 @@ public class MainModule extends AbstractModule { @Provides public static PositionForwarder providePositionForwarder(Config config, Client client, ObjectMapper objectMapper) { if (config.hasKey(Keys.FORWARD_URL)) { - switch (config.getString(Keys.FORWARD_TYPE)) { - case "json": - return new PositionForwarderJson(config, client, objectMapper); - case "amqp": - return new PositionForwarderAmqp(config, objectMapper); - case "kafka": - return new PositionForwarderKafka(config, objectMapper); - case "mqtt": - return new PositionForwarderMqtt(config, objectMapper); - case "redis": - return new PositionForwarderRedis(config, objectMapper); - case "url": - default: - return new PositionForwarderUrl(config, client, objectMapper); - } + return switch (config.getString(Keys.FORWARD_TYPE)) { + case "json" -> new PositionForwarderJson(config, client, objectMapper); + case "amqp" -> new PositionForwarderAmqp(config, objectMapper); + case "kafka" -> new PositionForwarderKafka(config, objectMapper); + case "mqtt" -> new PositionForwarderMqtt(config, objectMapper); + case "redis" -> new PositionForwarderRedis(config, objectMapper); + default -> new PositionForwarderUrl(config, client, objectMapper); + }; } return null; } diff --git a/src/main/java/org/traccar/ProcessingHandler.java b/src/main/java/org/traccar/ProcessingHandler.java index bb040bfff..76442d402 100644 --- a/src/main/java/org/traccar/ProcessingHandler.java +++ b/src/main/java/org/traccar/ProcessingHandler.java @@ -131,8 +131,8 @@ public class ProcessingHandler extends ChannelInboundHandlerAdapter implements B @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - if (msg instanceof Position) { - bufferingManager.accept(ctx, (Position) msg); + if (msg instanceof Position position) { + bufferingManager.accept(ctx, position); } else { super.channelRead(ctx, msg); } diff --git a/src/main/java/org/traccar/WindowsService.java b/src/main/java/org/traccar/WindowsService.java index 08eba25a6..61606c5be 100644 --- a/src/main/java/org/traccar/WindowsService.java +++ b/src/main/java/org/traccar/WindowsService.java @@ -206,16 +206,11 @@ public abstract class WindowsService { private final class ServiceControl implements HandlerEx { public int callback(int dwControl, int dwEventType, Pointer lpEventData, Pointer lpContext) { - switch (dwControl) { - case Winsvc.SERVICE_CONTROL_STOP: - case Winsvc.SERVICE_CONTROL_SHUTDOWN: - reportStatus(Winsvc.SERVICE_STOP_PENDING, WinError.NO_ERROR, 5000); - synchronized (waitObject) { - waitObject.notifyAll(); - } - break; - default: - break; + if (dwControl == Winsvc.SERVICE_CONTROL_STOP || dwControl == Winsvc.SERVICE_CONTROL_SHUTDOWN) { + reportStatus(Winsvc.SERVICE_STOP_PENDING, WinError.NO_ERROR, 5000); + synchronized (waitObject) { + waitObject.notifyAll(); + } } return WinError.NO_ERROR; } diff --git a/src/main/java/org/traccar/WrapperInboundHandler.java b/src/main/java/org/traccar/WrapperInboundHandler.java index 5e2b1d304..7acca9c50 100644 --- a/src/main/java/org/traccar/WrapperInboundHandler.java +++ b/src/main/java/org/traccar/WrapperInboundHandler.java @@ -52,8 +52,7 @@ public class WrapperInboundHandler implements ChannelInboundHandler { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - if (msg instanceof NetworkMessage) { - NetworkMessage nm = (NetworkMessage) msg; + if (msg instanceof NetworkMessage nm) { handler.channelRead(new WrapperContext(ctx, nm.getRemoteAddress()), nm.getMessage()); } else { handler.channelRead(ctx, msg); @@ -85,7 +84,6 @@ public class WrapperInboundHandler implements ChannelInboundHandler { handler.handlerRemoved(ctx); } - @SuppressWarnings("deprecation") @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { handler.exceptionCaught(ctx, cause); diff --git a/src/main/java/org/traccar/WrapperOutboundHandler.java b/src/main/java/org/traccar/WrapperOutboundHandler.java index ae2b06ad2..8b9c01405 100644 --- a/src/main/java/org/traccar/WrapperOutboundHandler.java +++ b/src/main/java/org/traccar/WrapperOutboundHandler.java @@ -67,8 +67,7 @@ public class WrapperOutboundHandler implements ChannelOutboundHandler { @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { - if (msg instanceof NetworkMessage) { - NetworkMessage nm = (NetworkMessage) msg; + if (msg instanceof NetworkMessage nm) { handler.write(new WrapperContext(ctx, nm.getRemoteAddress()), nm.getMessage(), promise); } else { handler.write(ctx, msg, promise); diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index 2a801221b..e35850e1f 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -68,7 +68,7 @@ public abstract class BaseObjectResource<T extends BaseModel> extends BaseResour @POST public Response add(T entity) throws Exception { - permissionsService.checkEdit(getUserId(), entity, true); + permissionsService.checkEdit(getUserId(), entity, true, false); entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id")))); LogAction.create(getUserId(), entity); @@ -86,25 +86,27 @@ public abstract class BaseObjectResource<T extends BaseModel> extends BaseResour @Path("{id}") @PUT public Response update(T entity) throws Exception { - permissionsService.checkEdit(getUserId(), entity, false); permissionsService.checkPermission(baseClass, getUserId(), entity.getId()); - if (entity instanceof User) { + boolean skipReadonly = false; + if (entity instanceof User after) { User before = storage.getObject(User.class, new Request( new Columns.All(), new Condition.Equals("id", entity.getId()))); permissionsService.checkUserUpdate(getUserId(), before, (User) entity); - } else if (entity instanceof Group) { - Group group = (Group) entity; + skipReadonly = permissionsService.getUser(getUserId()) + .compare(after, "notificationTokens", "termsAccepted"); + } else if (entity instanceof Group group) { if (group.getId() == group.getGroupId()) { throw new IllegalArgumentException("Cycle in group hierarchy"); } } + permissionsService.checkEdit(getUserId(), entity, false, skipReadonly); + storage.updateObject(entity, new Request( new Columns.Exclude("id"), new Condition.Equals("id", entity.getId()))); - if (entity instanceof User) { - User user = (User) entity; + if (entity instanceof User user) { if (user.getHashedPassword() != null) { storage.updateObject(entity, new Request( new Columns.Include("hashedPassword", "salt"), @@ -120,8 +122,8 @@ public abstract class BaseObjectResource<T extends BaseModel> extends BaseResour @Path("{id}") @DELETE public Response remove(@PathParam("id") long id) throws Exception { - permissionsService.checkEdit(getUserId(), baseClass, false); permissionsService.checkPermission(baseClass, getUserId(), id); + permissionsService.checkEdit(getUserId(), baseClass, false, false); storage.removeObject(baseClass, new Request(new Condition.Equals("id", id))); cacheManager.invalidateObject(true, baseClass, id, ObjectOperation.DELETE); diff --git a/src/main/java/org/traccar/api/ResourceErrorHandler.java b/src/main/java/org/traccar/api/ResourceErrorHandler.java index 387f3db6a..5f5e70632 100644 --- a/src/main/java/org/traccar/api/ResourceErrorHandler.java +++ b/src/main/java/org/traccar/api/ResourceErrorHandler.java @@ -25,8 +25,7 @@ public class ResourceErrorHandler implements ExceptionMapper<Exception> { @Override public Response toResponse(Exception e) { - if (e instanceof WebApplicationException) { - WebApplicationException webException = (WebApplicationException) e; + if (e instanceof WebApplicationException webException) { return Response.fromResponse(webException.getResponse()).entity(Log.exceptionStack(webException)).build(); } else { return Response.status(Response.Status.BAD_REQUEST).entity(Log.exceptionStack(e)).build(); diff --git a/src/main/java/org/traccar/api/resource/AttributeResource.java b/src/main/java/org/traccar/api/resource/AttributeResource.java index 52c4d6324..8debb2e50 100644 --- a/src/main/java/org/traccar/api/resource/AttributeResource.java +++ b/src/main/java/org/traccar/api/resource/AttributeResource.java @@ -62,16 +62,10 @@ public class AttributeResource extends ExtendedObjectResource<Attribute> { Object result = computedAttributesHandler.computeAttribute(entity, position); if (result != null) { - switch (entity.getType()) { - case "number": - Number numberValue = (Number) result; - return Response.ok(numberValue).build(); - case "boolean": - Boolean booleanValue = (Boolean) result; - return Response.ok(booleanValue).build(); - default: - return Response.ok(result.toString()).build(); - } + return switch (entity.getType()) { + case "number", "boolean" -> Response.ok(result).build(); + default -> Response.ok(result.toString()).build(); + }; } else { return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/api/resource/DeviceResource.java b/src/main/java/org/traccar/api/resource/DeviceResource.java index 971c29c60..4be8dbb12 100644 --- a/src/main/java/org/traccar/api/resource/DeviceResource.java +++ b/src/main/java/org/traccar/api/resource/DeviceResource.java @@ -137,8 +137,8 @@ public class DeviceResource extends BaseObjectResource<Device> { @Path("{id}/accumulators") @PUT public Response updateAccumulators(DeviceAccumulators entity) throws Exception { - permissionsService.checkEdit(getUserId(), Device.class, false); permissionsService.checkPermission(Device.class, getUserId(), entity.getDeviceId()); + permissionsService.checkEdit(getUserId(), Device.class, false, false); Position position = storage.getObject(Position.class, new Request( new Columns.All(), new Condition.LatestPositions(entity.getDeviceId()))); @@ -174,20 +174,14 @@ public class DeviceResource extends BaseObjectResource<Device> { } private String imageExtension(String type) { - switch (type) { - case "image/jpeg": - return "jpg"; - case "image/png": - return "png"; - case "image/gif": - return "gif"; - case "image/webp": - return "webp"; - case "image/svg+xml": - return "svg"; - default: - throw new IllegalArgumentException("Unsupported image type"); - } + return switch (type) { + case "image/jpeg" -> "jpg"; + case "image/png" -> "png"; + case "image/gif" -> "gif"; + case "image/webp" -> "webp"; + case "image/svg+xml" -> "svg"; + default -> throw new IllegalArgumentException("Unsupported image type"); + }; } @Path("{id}/image") diff --git a/src/main/java/org/traccar/api/resource/NotificationResource.java b/src/main/java/org/traccar/api/resource/NotificationResource.java index a41d00cf3..8bc81a3a4 100644 --- a/src/main/java/org/traccar/api/resource/NotificationResource.java +++ b/src/main/java/org/traccar/api/resource/NotificationResource.java @@ -85,7 +85,7 @@ public class NotificationResource extends ExtendedObjectResource<Notification> { public Collection<Typed> getNotificators(@QueryParam("announcement") boolean announcement) { Set<String> announcementsUnsupported = Set.of("command", "web"); return notificatorManager.getAllNotificatorTypes().stream() - .filter(typed -> !announcement || !announcementsUnsupported.contains(typed.getType())) + .filter(typed -> !announcement || !announcementsUnsupported.contains(typed.type())) .collect(Collectors.toUnmodifiableSet()); } @@ -94,7 +94,7 @@ public class NotificationResource extends ExtendedObjectResource<Notification> { public Response testMessage() throws MessageException, StorageException { User user = permissionsService.getUser(getUserId()); for (Typed method : notificatorManager.getAllNotificatorTypes()) { - notificatorManager.getNotificator(method.getType()).send(null, user, new Event("test", 0), null); + notificatorManager.getNotificator(method.type()).send(null, user, new Event("test", 0), null); } return Response.noContent().build(); } diff --git a/src/main/java/org/traccar/api/resource/UserResource.java b/src/main/java/org/traccar/api/resource/UserResource.java index fbc31e46a..65ca2c883 100644 --- a/src/main/java/org/traccar/api/resource/UserResource.java +++ b/src/main/java/org/traccar/api/resource/UserResource.java @@ -25,6 +25,7 @@ import org.traccar.config.Config; import org.traccar.config.Keys; import org.traccar.helper.LogAction; import org.traccar.helper.model.UserUtil; +import org.traccar.model.Device; import org.traccar.model.ManagedUser; import org.traccar.model.Permission; import org.traccar.model.User; @@ -61,12 +62,18 @@ public class UserResource extends BaseObjectResource<User> { } @GET - public Collection<User> get(@QueryParam("userId") long userId) throws StorageException { + public Collection<User> get( + @QueryParam("userId") long userId, @QueryParam("deviceId") long deviceId) throws StorageException { if (userId > 0) { permissionsService.checkUser(getUserId(), userId); return storage.getObjects(baseClass, new Request( new Columns.All(), new Condition.Permission(User.class, userId, ManagedUser.class).excludeGroups())); + } else if (deviceId > 0) { + permissionsService.checkAdmin(getUserId()); + return storage.getObjects(baseClass, new Request( + new Columns.All(), + new Condition.Permission(User.class, Device.class, deviceId).excludeGroups())); } else if (permissionsService.notAdmin(getUserId())) { return storage.getObjects(baseClass, new Request( new Columns.All(), diff --git a/src/main/java/org/traccar/api/security/PermissionsService.java b/src/main/java/org/traccar/api/security/PermissionsService.java index d60bbafb8..721793c2f 100644 --- a/src/main/java/org/traccar/api/security/PermissionsService.java +++ b/src/main/java/org/traccar/api/security/PermissionsService.java @@ -98,10 +98,12 @@ public class PermissionsService { } } - public void checkEdit(long userId, Class<?> clazz, boolean addition) throws StorageException, SecurityException { + public void checkEdit( + long userId, Class<?> clazz, boolean addition, boolean skipReadonly) + throws StorageException, SecurityException { if (!getUser(userId).getAdministrator()) { boolean denied = false; - if (getServer().getReadonly() || getUser(userId).getReadonly()) { + if (!skipReadonly && (getServer().getReadonly() || getUser(userId).getReadonly())) { denied = true; } else if (clazz.equals(Device.class)) { denied = getServer().getDeviceReadonly() || getUser(userId).getDeviceReadonly() @@ -121,11 +123,12 @@ public class PermissionsService { } } - public void checkEdit(long userId, BaseModel object, boolean addition) throws StorageException, SecurityException { + public void checkEdit( + long userId, BaseModel object, boolean addition, boolean skipReadonly) + throws StorageException, SecurityException { if (!getUser(userId).getAdministrator()) { - checkEdit(userId, object.getClass(), addition); - if (object instanceof GroupedModel) { - GroupedModel after = ((GroupedModel) object); + checkEdit(userId, object.getClass(), addition, skipReadonly); + if (object instanceof GroupedModel after) { if (after.getGroupId() > 0) { GroupedModel before = null; if (!addition) { @@ -137,8 +140,7 @@ public class PermissionsService { } } } - if (object instanceof Schedulable) { - Schedulable after = ((Schedulable) object); + if (object instanceof Schedulable after) { if (after.getCalendarId() > 0) { Schedulable before = null; if (!addition) { @@ -150,8 +152,7 @@ public class PermissionsService { } } } - if (object instanceof Notification) { - Notification after = ((Notification) object); + if (object instanceof Notification after) { if (after.getCommandId() > 0) { Notification before = null; if (!addition) { diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java index 91d5dac5d..dcd9aaa28 100644 --- a/src/main/java/org/traccar/config/Keys.java +++ b/src/main/java/org/traccar/config/Keys.java @@ -1811,6 +1811,15 @@ public final class Keys { List.of(KeyType.CONFIG)); /** + * If this parameter is set, Traccar will monitor drops in the number of stored messages. If it drops more than + * the threshold, it will mark service as failing for systemd. Threshold is a value from 0.0 to 1.0. For example, + * value 0.7 means that the number of messages in the last period is only 70% of what it was in the previous. + */ + public static final ConfigKey<Double> WEB_HEALTH_CHECK_DROP_THRESHOLD = new DoubleConfigKey( + "web.healthCheck.dropThreshold", + List.of(KeyType.CONFIG)); + + /** * Sets SameSite cookie attribute value. * Supported options: Lax, Strict, None. */ @@ -1902,6 +1911,14 @@ public final class Keys { true); /** + * If all bytes are printable characters, log network data as text instead of HEX. + */ + public static final ConfigKey<Boolean> LOGGER_TEXT_PROTOCOL = new BooleanConfigKey( + "logger.decodeTextData", + List.of(KeyType.CONFIG), + true); + + /** * Log file rotation interval, the default rotation interval is once a day. * This option is ignored if 'logger.rotate' = false * Available options: day, hour @@ -1920,8 +1937,8 @@ public final class Keys { "time,position,speed,course,accuracy,result"); /** - * Broadcast method. Available options are "multicast" and "redis". By default (if the value is not - * specified or does not matches available options) server disables broadcast. + * Broadcast method. Available options are "multicast" and "redis". By default, (if the value is not + * specified or does not match available options) server disables broadcast. */ public static final ConfigKey<String> BROADCAST_TYPE = new StringConfigKey( "broadcast.type", @@ -1948,4 +1965,11 @@ public final class Keys { "broadcast.port", List.of(KeyType.CONFIG)); + /** + * Flag to mark secondary servers. Some tasks, like scheduled reports, will be executed on the main server only. + */ + public static final ConfigKey<Boolean> BROADCAST_SECONDARY = new BooleanConfigKey( + "broadcast.secondary", + List.of(KeyType.CONFIG)); + } diff --git a/src/main/java/org/traccar/database/LdapProvider.java b/src/main/java/org/traccar/database/LdapProvider.java index d517294b8..549b68e6c 100644 --- a/src/main/java/org/traccar/database/LdapProvider.java +++ b/src/main/java/org/traccar/database/LdapProvider.java @@ -189,23 +189,12 @@ public class LdapProvider { for (int i = 0; i < input.length(); i++) { char c = input.charAt(i); switch (c) { - case '\\': - sb.append("\\5c"); - break; - case '*': - sb.append("\\2a"); - break; - case '(': - sb.append("\\28"); - break; - case ')': - sb.append("\\29"); - break; - case '\0': - sb.append("\\00"); - break; - default: - sb.append(c); + case '\\' -> sb.append("\\5c"); + case '*' -> sb.append("\\2a"); + case '(' -> sb.append("\\28"); + case ')' -> sb.append("\\29"); + case '\0' -> sb.append("\\00"); + default -> sb.append(c); } } return sb.toString(); diff --git a/src/main/java/org/traccar/database/StatisticsManager.java b/src/main/java/org/traccar/database/StatisticsManager.java index 8711289a0..5f4d97263 100644 --- a/src/main/java/org/traccar/database/StatisticsManager.java +++ b/src/main/java/org/traccar/database/StatisticsManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2024 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -100,8 +100,6 @@ public class StatisticsManager { statistics.setProtocols(protocols); } - statistics.set("modern", config.getString(Keys.WEB_PATH).contains("modern")); - users.clear(); deviceProtocols.clear(); deviceMessages.clear(); @@ -178,6 +176,10 @@ public class StatisticsManager { } } + public synchronized int messageStoredCount() { + return messagesStored; + } + public synchronized int messageStoredCount(long deviceId) { return deviceMessages.getOrDefault(deviceId, 0); } diff --git a/src/main/java/org/traccar/forward/PositionForwarderMqtt.java b/src/main/java/org/traccar/forward/PositionForwarderMqtt.java index 53f0ced19..3a3600073 100644 --- a/src/main/java/org/traccar/forward/PositionForwarderMqtt.java +++ b/src/main/java/org/traccar/forward/PositionForwarderMqtt.java @@ -37,7 +37,7 @@ public class PositionForwarderMqtt implements PositionForwarder { @Override public void forward(PositionData positionData, ResultHandler resultHandler) { try { - String payload = objectMapper.writeValueAsString(topic); + String payload = objectMapper.writeValueAsString(positionData); mqttClient.publish(topic, payload, (message, e) -> resultHandler.onResult(e == null, e)); } catch (JsonProcessingException e) { resultHandler.onResult(false, e); diff --git a/src/main/java/org/traccar/geocoder/BanGeocoder.java b/src/main/java/org/traccar/geocoder/BanGeocoder.java index e2ff72311..128ef4b84 100644 --- a/src/main/java/org/traccar/geocoder/BanGeocoder.java +++ b/src/main/java/org/traccar/geocoder/BanGeocoder.java @@ -20,45 +20,22 @@ package org.traccar.geocoder; * API documentation: https://adresse.data.gouv.fr/api */ -import jakarta.json.JsonArray; import jakarta.json.JsonObject; import jakarta.ws.rs.client.Client; -public class BanGeocoder extends JsonGeocoder { +public class BanGeocoder extends GeocodeJsonGeocoder { public BanGeocoder(Client client, int cacheSize, AddressFormat addressFormat) { - super(client, "https://api-adresse.data.gouv.fr/reverse/?lat=%f&lon=%f", cacheSize, addressFormat); + super(client, "https://api-adresse.data.gouv.fr/reverse/", null, null, cacheSize, addressFormat); } @Override public Address parseAddress(JsonObject json) { - JsonArray result = json.getJsonArray("features"); + Address geodecoded = super.parseAddress(json); + if (geodecoded != null) { + geodecoded.setCountry("FR"); - if (result != null && !result.isEmpty()) { - JsonObject location = result.getJsonObject(0).getJsonObject("properties"); - Address address = new Address(); - - address.setCountry("FR"); - if (location.containsKey("postcode")) { - address.setPostcode(location.getString("postcode")); - } - if (location.containsKey("context")) { - address.setDistrict(location.getString("context")); - } - if (location.containsKey("name")) { - address.setStreet(location.getString("name")); - } - if (location.containsKey("city")) { - address.setSettlement(location.getString("city")); - } - if (location.containsKey("housenumber")) { - address.setHouse(location.getString("housenumber")); - } - if (location.containsKey("label")) { - address.setFormattedAddress(location.getString("label")); - } - - return address; + return geodecoded; } return null; diff --git a/src/main/java/org/traccar/geocoder/GeocodeJsonGeocoder.java b/src/main/java/org/traccar/geocoder/GeocodeJsonGeocoder.java new file mode 100644 index 000000000..da4688423 --- /dev/null +++ b/src/main/java/org/traccar/geocoder/GeocodeJsonGeocoder.java @@ -0,0 +1,81 @@ +/* + * Copyright 2014 - 2024 Anton Tananaev (anton@traccar.org) + * Copyright 2024 - 2024 Matjaž Črnko (m.crnko@txt.i) + * + * 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.geocoder; + +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; + +public class GeocodeJsonGeocoder extends JsonGeocoder { + + private static String formatUrl(String url, String key, String language) { + if (url == null) { + url = "https://photon.komoot.io/reverse"; + } + url += "?lat=%f&lon=%f"; + if (key != null) { + url += "&key=" + key; + } + if (language != null) { + url += "&lang=" + language; + } + return url; + } + + public GeocodeJsonGeocoder( + Client client, String url, String key, String language, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(url, key, language), cacheSize, addressFormat); + } + + @Override + public Address parseAddress(JsonObject json) { + JsonArray features = json.getJsonArray("features"); + if (!features.isEmpty()) { + Address address = new Address(); + JsonObject properties = features.getJsonObject(0).getJsonObject("properties"); + + if (properties.containsKey("label")) { + address.setFormattedAddress(properties.getString("label")); + } + if (properties.containsKey("housenumber")) { + address.setHouse(properties.getString("housenumber")); + } + if (properties.containsKey("street")) { + address.setStreet(properties.getString("street")); + } + if (properties.containsKey("city")) { + address.setSettlement(properties.getString("city")); + } + if (properties.containsKey("district")) { + address.setDistrict(properties.getString("district")); + } + if (properties.containsKey("state")) { + address.setState(properties.getString("state")); + } + if (properties.containsKey("countrycode")) { + address.setCountry(properties.getString("countrycode").toUpperCase()); + } + if (properties.containsKey("postcode")) { + address.setPostcode(properties.getString("postcode")); + } + + return address; + } + return null; + } + +} diff --git a/src/main/java/org/traccar/geocoder/GoogleGeocoder.java b/src/main/java/org/traccar/geocoder/GoogleGeocoder.java index 93f128b46..174ef66c8 100644 --- a/src/main/java/org/traccar/geocoder/GoogleGeocoder.java +++ b/src/main/java/org/traccar/geocoder/GoogleGeocoder.java @@ -22,8 +22,10 @@ import jakarta.ws.rs.client.Client; public class GoogleGeocoder extends JsonGeocoder { - private static String formatUrl(String key, String language) { - String url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f"; + private static String formatUrl(String url, String key, String language) { + if (url == null) { + url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f"; + } if (key != null) { url += "&key=" + key; } @@ -33,8 +35,9 @@ public class GoogleGeocoder extends JsonGeocoder { return url; } - public GoogleGeocoder(Client client, String key, String language, int cacheSize, AddressFormat addressFormat) { - super(client, formatUrl(key, language), cacheSize, addressFormat); + public GoogleGeocoder( + Client client, String url, String key, String language, int cacheSize, AddressFormat addressFormat) { + super(client, formatUrl(url, key, language), cacheSize, addressFormat); } @Override diff --git a/src/main/java/org/traccar/geocoder/MapTilerGeocoder.java b/src/main/java/org/traccar/geocoder/MapTilerGeocoder.java index 24c9da2ad..11394339a 100644 --- a/src/main/java/org/traccar/geocoder/MapTilerGeocoder.java +++ b/src/main/java/org/traccar/geocoder/MapTilerGeocoder.java @@ -66,9 +66,4 @@ public class MapTilerGeocoder extends JsonGeocoder { return null; } - @Override - protected String parseError(JsonObject json) { - return null; - } - } diff --git a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java index d286866a5..f4079f127 100644 --- a/src/main/java/org/traccar/handler/ComputedAttributesHandler.java +++ b/src/main/java/org/traccar/handler/ComputedAttributesHandler.java @@ -146,57 +146,41 @@ public class ComputedAttributesHandler extends BasePositionHandler { .collect(Collectors.toUnmodifiableList()); for (Attribute attribute : attributes) { if (attribute.getAttribute() != null) { - Object result = null; try { - result = computeAttribute(attribute, position); - } catch (JexlException error) { - LOGGER.warn("Attribute computation error", error); - } - if (result != null) { - try { + Object result = computeAttribute(attribute, position); + if (result != null) { switch (attribute.getAttribute()) { - case "valid": - position.setValid((Boolean) result); - break; - case "latitude": - position.setLatitude(((Number) result).doubleValue()); - break; - case "longitude": - position.setLongitude(((Number) result).doubleValue()); - break; - case "altitude": - position.setAltitude(((Number) result).doubleValue()); - break; - case "speed": - position.setSpeed(((Number) result).doubleValue()); - break; - case "course": - position.setCourse(((Number) result).doubleValue()); - break; - case "address": - position.setAddress((String) result); - break; - case "accuracy": - position.setAccuracy(((Number) result).doubleValue()); - break; - default: + case "valid" -> position.setValid((Boolean) result); + case "latitude" -> position.setLatitude(((Number) result).doubleValue()); + case "longitude" -> position.setLongitude(((Number) result).doubleValue()); + case "altitude" -> position.setAltitude(((Number) result).doubleValue()); + case "speed" -> position.setSpeed(((Number) result).doubleValue()); + case "course" -> position.setCourse(((Number) result).doubleValue()); + case "address" -> position.setAddress((String) result); + case "accuracy" -> position.setAccuracy(((Number) result).doubleValue()); + default -> { switch (attribute.getType()) { - case "number": + case "number" -> { Number numberValue = (Number) result; position.getAttributes().put(attribute.getAttribute(), numberValue); - break; - case "boolean": + } + case "boolean" -> { Boolean booleanValue = (Boolean) result; position.getAttributes().put(attribute.getAttribute(), booleanValue); - break; - default: + } + default -> { position.getAttributes().put(attribute.getAttribute(), result.toString()); + } } - break; + } } - } catch (ClassCastException error) { - LOGGER.warn("Attribute cast error", error); + } else { + position.getAttributes().remove(attribute.getAttribute()); } + } catch (JexlException error) { + LOGGER.warn("Attribute computation error", error); + } catch (ClassCastException error) { + LOGGER.warn("Attribute cast error", error); } } } diff --git a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java index 573ad4ad6..7fc6086aa 100644 --- a/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java +++ b/src/main/java/org/traccar/handler/events/MaintenanceEventHandler.java @@ -57,16 +57,12 @@ public class MaintenanceEventHandler extends BaseEventHandler { } private double getValue(Position position, String type) { - switch (type) { - case "serverTime": - return position.getServerTime().getTime(); - case "deviceTime": - return position.getDeviceTime().getTime(); - case "fixTime": - return position.getFixTime().getTime(); - default: - return position.getDouble(type); - } + return switch (type) { + case "serverTime" -> position.getServerTime().getTime(); + case "deviceTime" -> position.getDeviceTime().getTime(); + case "fixTime" -> position.getFixTime().getTime(); + default -> position.getDouble(type); + }; } } diff --git a/src/main/java/org/traccar/handler/network/AcknowledgementHandler.java b/src/main/java/org/traccar/handler/network/AcknowledgementHandler.java index e87f5d34c..7ba625e00 100644 --- a/src/main/java/org/traccar/handler/network/AcknowledgementHandler.java +++ b/src/main/java/org/traccar/handler/network/AcknowledgementHandler.java @@ -92,12 +92,10 @@ public class AcknowledgementHandler extends ChannelOutboundHandlerAdapter { if (queue == null) { queue = new LinkedList<>(); } - } else if (msg instanceof EventDecoded) { - EventDecoded event = (EventDecoded) msg; + } else if (msg instanceof EventDecoded event) { LOGGER.debug("Event decoded {}", event.getObjects().size()); waiting.addAll(event.getObjects()); - } else if (msg instanceof EventHandled) { - EventHandled event = (EventHandled) msg; + } else if (msg instanceof EventHandled event) { LOGGER.debug("Event handled"); waiting.remove(event.getObject()); } diff --git a/src/main/java/org/traccar/handler/network/NetworkMessageHandler.java b/src/main/java/org/traccar/handler/network/NetworkMessageHandler.java index c2fb9016a..f151c91a9 100644 --- a/src/main/java/org/traccar/handler/network/NetworkMessageHandler.java +++ b/src/main/java/org/traccar/handler/network/NetworkMessageHandler.java @@ -32,16 +32,14 @@ public class NetworkMessageHandler extends ChannelDuplexHandler { if (ctx.channel() instanceof DatagramChannel) { DatagramPacket packet = (DatagramPacket) msg; ctx.fireChannelRead(new NetworkMessage(packet.content(), packet.sender())); - } else if (msg instanceof ByteBuf) { - ByteBuf buffer = (ByteBuf) msg; + } else if (msg instanceof ByteBuf buffer) { ctx.fireChannelRead(new NetworkMessage(buffer, ctx.channel().remoteAddress())); } } @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) { - if (msg instanceof NetworkMessage) { - NetworkMessage message = (NetworkMessage) msg; + if (msg instanceof NetworkMessage message) { if (ctx.channel() instanceof DatagramChannel) { InetSocketAddress recipient = (InetSocketAddress) message.getRemoteAddress(); InetSocketAddress sender = (InetSocketAddress) ctx.channel().localAddress(); diff --git a/src/main/java/org/traccar/handler/network/RemoteAddressHandler.java b/src/main/java/org/traccar/handler/network/RemoteAddressHandler.java index c52bb2be1..9d5504ce1 100644 --- a/src/main/java/org/traccar/handler/network/RemoteAddressHandler.java +++ b/src/main/java/org/traccar/handler/network/RemoteAddressHandler.java @@ -44,8 +44,7 @@ public class RemoteAddressHandler extends ChannelInboundHandlerAdapter { InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress(); String hostAddress = remoteAddress != null ? remoteAddress.getAddress().getHostAddress() : null; - if (msg instanceof Position) { - Position position = (Position) msg; + if (msg instanceof Position position) { position.set(Position.KEY_IP, hostAddress); } } diff --git a/src/main/java/org/traccar/handler/network/StandardLoggingHandler.java b/src/main/java/org/traccar/handler/network/StandardLoggingHandler.java index dae93655d..8e63cae4d 100644 --- a/src/main/java/org/traccar/handler/network/StandardLoggingHandler.java +++ b/src/main/java/org/traccar/handler/network/StandardLoggingHandler.java @@ -24,22 +24,33 @@ import jakarta.inject.Inject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.NetworkMessage; +import org.traccar.config.Config; +import org.traccar.config.Keys; +import org.traccar.helper.BufferUtil; import org.traccar.helper.NetworkUtil; import org.traccar.model.LogRecord; import org.traccar.session.ConnectionManager; +import java.nio.charset.StandardCharsets; + public class StandardLoggingHandler extends ChannelDuplexHandler { private static final Logger LOGGER = LoggerFactory.getLogger(StandardLoggingHandler.class); private final String protocol; private ConnectionManager connectionManager; + private boolean decodeTextData; public StandardLoggingHandler(String protocol) { this.protocol = protocol; } @Inject + public void setConfig(Config config) { + decodeTextData = config.getBoolean(Keys.LOGGER_TEXT_PROTOCOL); + } + + @Inject public void setConnectionManager(ConnectionManager connectionManager) { this.connectionManager = connectionManager; } @@ -61,12 +72,17 @@ public class StandardLoggingHandler extends ChannelDuplexHandler { } private LogRecord createLogRecord(ChannelHandlerContext ctx, Object msg) { - if (msg instanceof NetworkMessage) { - NetworkMessage networkMessage = (NetworkMessage) msg; - if (networkMessage.getMessage() instanceof ByteBuf) { + if (msg instanceof NetworkMessage networkMessage) { + if (networkMessage.getMessage() instanceof ByteBuf data) { LogRecord record = new LogRecord(ctx.channel().localAddress(), networkMessage.getRemoteAddress()); record.setProtocol(protocol); - record.setData(ByteBufUtil.hexDump((ByteBuf) networkMessage.getMessage())); + if (decodeTextData && BufferUtil.isPrintable(data, data.readableBytes())) { + record.setData(data.getCharSequence( + data.readerIndex(), data.readableBytes(), StandardCharsets.US_ASCII).toString() + .replace("\r", "\\r").replace("\n", "\\n")); + } else { + record.setData(ByteBufUtil.hexDump(data)); + } return record; } } diff --git a/src/main/java/org/traccar/helper/Log.java b/src/main/java/org/traccar/helper/Log.java index 9aaf1cfd3..d01d70559 100644 --- a/src/main/java/org/traccar/helper/Log.java +++ b/src/main/java/org/traccar/helper/Log.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2024 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.traccar.helper; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.model.Pair; import java.io.BufferedWriter; import java.io.File; @@ -30,9 +31,9 @@ import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.FileStore; import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Comparator; import java.util.Date; import java.util.logging.ConsoleHandler; import java.util.logging.Formatter; @@ -40,6 +41,7 @@ import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; +import java.util.stream.Stream; public final class Log { @@ -124,21 +126,13 @@ public final class Log { } private static String formatLevel(Level level) { - switch (level.getName()) { - case "FINEST": - return "TRACE"; - case "FINER": - case "FINE": - case "CONFIG": - return "DEBUG"; - case "INFO": - return "INFO"; - case "WARNING": - return "WARN"; - case "SEVERE": - default: - return "ERROR"; - } + return switch (level.getName()) { + case "FINEST" -> "TRACE"; + case "FINER", "FINE", "CONFIG" -> "DEBUG"; + case "INFO" -> "INFO"; + case "WARNING" -> "WARN"; + default -> "ERROR"; + }; } @Override @@ -150,7 +144,7 @@ public final class Log { } if (record.getThrown() != null) { - if (message.length() > 0) { + if (!message.isEmpty()) { message.append(" - "); } if (fullStackTraces) { @@ -278,17 +272,22 @@ public final class Log { } public static long[] getStorageSpace() { - long usable = 0; - long total = 0; - for (Path root : FileSystems.getDefault().getRootDirectories()) { + var stores = new ArrayList<Pair<Long, Long>>(); + for (FileStore store : FileSystems.getDefault().getFileStores()) { try { - FileStore store = Files.getFileStore(root); - usable += store.getUsableSpace(); - total += store.getTotalSpace(); + long usableSpace = store.getUsableSpace(); + long totalSpace = store.getTotalSpace(); + if (totalSpace > 1_000_000_000) { + stores.add(new Pair<>(usableSpace, totalSpace)); + } } catch (IOException ignored) { } } - return new long[]{usable, total}; + return stores.stream() + .sorted(Comparator.comparingDouble(p -> p.first() / (double) p.second())) + .flatMap(p -> Stream.of(p.first(), p.second())) + .mapToLong(Long::longValue) + .toArray(); } } diff --git a/src/main/java/org/traccar/helper/ObdDecoder.java b/src/main/java/org/traccar/helper/ObdDecoder.java index 3cbae334a..091747225 100644 --- a/src/main/java/org/traccar/helper/ObdDecoder.java +++ b/src/main/java/org/traccar/helper/ObdDecoder.java @@ -30,17 +30,13 @@ public final class ObdDecoder { private static final int MODE_CODES = 0x03; public static Map.Entry<String, Object> decode(int mode, String value) { - switch (mode) { - case MODE_CURRENT: - case MODE_FREEZE_FRAME: - return decodeData( - Integer.parseInt(value.substring(0, 2), 16), - Long.parseLong(value.substring(2), 16), true); - case MODE_CODES: - return decodeCodes(value); - default: - return null; - } + return switch (mode) { + case MODE_CURRENT, MODE_FREEZE_FRAME -> decodeData( + Integer.parseInt(value.substring(0, 2), 16), + Long.parseLong(value.substring(2), 16), true); + case MODE_CODES -> decodeCodes(value); + default -> null; + }; } private static Map.Entry<String, Object> createEntry(String key, Object value) { @@ -53,7 +49,7 @@ public final class ObdDecoder { int numValue = Integer.parseInt(value.substring(i * 4, (i + 1) * 4), 16); codes.append(' ').append(decodeCode(numValue)); } - if (codes.length() > 0) { + if (!codes.isEmpty()) { return createEntry(Position.KEY_DTCS, codes.toString().trim()); } else { return null; @@ -61,49 +57,29 @@ public final class ObdDecoder { } public static String decodeCode(int value) { - char prefix; - switch (value >> 14) { - case 1: - prefix = 'C'; - break; - case 2: - prefix = 'B'; - break; - case 3: - prefix = 'U'; - break; - default: - prefix = 'P'; - break; - } + char prefix = switch (value >> 14) { + case 1 -> 'C'; + case 2 -> 'B'; + case 3 -> 'U'; + default -> 'P'; + }; return String.format("%c%04X", prefix, value & 0x3FFF); } public static Map.Entry<String, Object> decodeData(int pid, long value, boolean convert) { - switch (pid) { - case 0x04: - return createEntry(Position.KEY_ENGINE_LOAD, convert ? value * 100 / 255 : value); - case 0x05: - return createEntry(Position.KEY_COOLANT_TEMP, convert ? value - 40 : value); - case 0x0B: - return createEntry("mapIntake", value); - case 0x0C: - return createEntry(Position.KEY_RPM, convert ? value / 4 : value); - case 0x0D: - return createEntry(Position.KEY_OBD_SPEED, value); - case 0x0F: - return createEntry("intakeTemp", convert ? value - 40 : value); - case 0x11: - return createEntry(Position.KEY_THROTTLE, convert ? value * 100 / 255 : value); - case 0x21: - return createEntry("milDistance", value); - case 0x2F: - return createEntry(Position.KEY_FUEL_LEVEL, convert ? value * 100 / 255 : value); - case 0x31: - return createEntry("clearedDistance", value); - default: - return null; - } + return switch (pid) { + case 0x04 -> createEntry(Position.KEY_ENGINE_LOAD, convert ? value * 100 / 255 : value); + case 0x05 -> createEntry(Position.KEY_COOLANT_TEMP, convert ? value - 40 : value); + case 0x0B -> createEntry("mapIntake", value); + case 0x0C -> createEntry(Position.KEY_RPM, convert ? value / 4 : value); + case 0x0D -> createEntry(Position.KEY_OBD_SPEED, value); + case 0x0F -> createEntry("intakeTemp", convert ? value - 40 : value); + case 0x11 -> createEntry(Position.KEY_THROTTLE, convert ? value * 100 / 255 : value); + case 0x21 -> createEntry("milDistance", value); + case 0x2F -> createEntry(Position.KEY_FUEL_LEVEL, convert ? value * 100 / 255 : value); + case 0x31 -> createEntry("clearedDistance", value); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/helper/model/AttributeUtil.java b/src/main/java/org/traccar/helper/model/AttributeUtil.java index 2630f64f0..0e3d91766 100644 --- a/src/main/java/org/traccar/helper/model/AttributeUtil.java +++ b/src/main/java/org/traccar/helper/model/AttributeUtil.java @@ -70,20 +70,20 @@ public final class AttributeUtil { if (result != null) { Class<T> valueClass = key.getValueClass(); if (valueClass.equals(Boolean.class)) { - return (T) (result instanceof String - ? Boolean.parseBoolean((String) result) + return (T) (result instanceof String stringResult + ? Boolean.parseBoolean(stringResult) : result); } else if (valueClass.equals(Integer.class)) { - return (T) (Object) (result instanceof String - ? Integer.parseInt((String) result) + return (T) (Object) (result instanceof String stringResult + ? Integer.parseInt(stringResult) : ((Number) result).intValue()); } else if (valueClass.equals(Long.class)) { - return (T) (Object) (result instanceof String - ? Long.parseLong((String) result) + return (T) (Object) (result instanceof String stringResult + ? Long.parseLong(stringResult) : ((Number) result).longValue()); } else if (valueClass.equals(Double.class)) { - return (T) (Object) (result instanceof String - ? Double.parseDouble((String) result) + return (T) (Object) (result instanceof String stringResult + ? Double.parseDouble(stringResult) : ((Number) result).doubleValue()); } else { return (T) result; diff --git a/src/main/java/org/traccar/model/Calendar.java b/src/main/java/org/traccar/model/Calendar.java index 76c9a2cc1..c1a570037 100644 --- a/src/main/java/org/traccar/model/Calendar.java +++ b/src/main/java/org/traccar/model/Calendar.java @@ -19,9 +19,6 @@ package org.traccar.model; import com.fasterxml.jackson.annotation.JsonIgnore; import net.fortuna.ical4j.data.CalendarBuilder; import net.fortuna.ical4j.data.ParserException; -import net.fortuna.ical4j.filter.Filter; -import net.fortuna.ical4j.filter.predicate.PeriodRule; -import net.fortuna.ical4j.model.DateTime; import net.fortuna.ical4j.model.Period; import net.fortuna.ical4j.model.component.CalendarComponent; import net.fortuna.ical4j.model.component.VEvent; @@ -31,9 +28,8 @@ import org.traccar.storage.StorageName; import java.io.ByteArrayInputStream; import java.io.IOException; import java.time.Duration; -import java.util.Collection; +import java.time.Instant; import java.util.Date; -import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -70,23 +66,19 @@ public class Calendar extends ExtendedModel { return calendar; } - private Collection<VEvent> findEvents(Date date) { + public Set<Period<Instant>> findPeriods(Date date) { if (calendar != null) { - var filter = new Filter<VEvent>(new PeriodRule<>(new Period(new DateTime(date), Duration.ZERO))); - return filter.filter(calendar.getComponents(CalendarComponent.VEVENT)); + var period = new Period<>(date.toInstant(), Duration.ZERO); + return calendar.<VEvent>getComponents(CalendarComponent.VEVENT).stream() + .flatMap(c -> c.<Instant>calculateRecurrenceSet(period).stream()) + .collect(Collectors.toUnmodifiableSet()); } else { - return List.of(); + return Set.of(); } } - public Set<Period> findPeriods(Date date) { - return findEvents(date).stream() - .flatMap((e) -> e.calculateRecurrenceSet(new Period(new DateTime(date), Duration.ZERO)).stream()) - .collect(Collectors.toSet()); - } - public boolean checkMoment(Date date) { - return !findEvents(date).isEmpty(); + return !findPeriods(date).isEmpty(); } } diff --git a/src/main/java/org/traccar/model/ExtendedModel.java b/src/main/java/org/traccar/model/ExtendedModel.java index d5cd094da..f1183e11a 100644 --- a/src/main/java/org/traccar/model/ExtendedModel.java +++ b/src/main/java/org/traccar/model/ExtendedModel.java @@ -105,8 +105,8 @@ public class ExtendedModel extends BaseModel { public double getDouble(String key) { if (attributes.containsKey(key)) { Object value = attributes.get(key); - if (value instanceof Number) { - return ((Number) attributes.get(key)).doubleValue(); + if (value instanceof Number numberValue) { + return numberValue.doubleValue(); } else { return Double.parseDouble(value.toString()); } @@ -118,8 +118,8 @@ public class ExtendedModel extends BaseModel { public boolean getBoolean(String key) { if (attributes.containsKey(key)) { Object value = attributes.get(key); - if (value instanceof Boolean) { - return (Boolean) attributes.get(key); + if (value instanceof Boolean booleanValue) { + return booleanValue; } else { return Boolean.parseBoolean(value.toString()); } @@ -131,8 +131,8 @@ public class ExtendedModel extends BaseModel { public int getInteger(String key) { if (attributes.containsKey(key)) { Object value = attributes.get(key); - if (value instanceof Number) { - return ((Number) attributes.get(key)).intValue(); + if (value instanceof Number numberValue) { + return numberValue.intValue(); } else { return Integer.parseInt(value.toString()); } @@ -144,8 +144,8 @@ public class ExtendedModel extends BaseModel { public long getLong(String key) { if (attributes.containsKey(key)) { Object value = attributes.get(key); - if (value instanceof Number) { - return ((Number) attributes.get(key)).longValue(); + if (value instanceof Number numberValue) { + return numberValue.longValue(); } else { return Long.parseLong(value.toString()); } diff --git a/src/main/java/org/traccar/model/Pair.java b/src/main/java/org/traccar/model/Pair.java index b679de57b..90b82d577 100644 --- a/src/main/java/org/traccar/model/Pair.java +++ b/src/main/java/org/traccar/model/Pair.java @@ -1,43 +1,19 @@ +/* + * Copyright 2024 Anton Tananaev (anton@traccar.org) + * + * 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.model; -import java.util.Objects; - -public class Pair<K, V> { - - private final K first; - private final V second; - - public Pair(K first, V second) { - this.first = first; - this.second = second; - } - - public K getFirst() { - return first; - } - - public V getSecond() { - return second; - } - - @SuppressWarnings("rawtypes") - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - Pair pair = (Pair) o; - - return Objects.equals(first, pair.first) && Objects.equals(second, pair.second); - } - - @Override - public int hashCode() { - return Objects.hash(first, second); - } - +public record Pair<K, V>(K first, V second) { } diff --git a/src/main/java/org/traccar/model/Typed.java b/src/main/java/org/traccar/model/Typed.java index fc671ac70..0476fdc4b 100644 --- a/src/main/java/org/traccar/model/Typed.java +++ b/src/main/java/org/traccar/model/Typed.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Anton Tananaev (anton@traccar.org) + * Copyright 2020 - 2024 Anton Tananaev (anton@traccar.org) * Copyright 2016 Gabor Somogyi (gabor.g.somogyi@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,37 +16,5 @@ */ package org.traccar.model; -import java.util.Objects; - -public class Typed { - - private String type; - - public Typed(String type) { - this.type = type; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - return Objects.equals(type, ((Typed) o).type); - } - - @Override - public int hashCode() { - return Objects.hash(type); - } +public record Typed(String type) { } diff --git a/src/main/java/org/traccar/model/User.java b/src/main/java/org/traccar/model/User.java index 9b8ee3e53..7cf8c25a6 100644 --- a/src/main/java/org/traccar/model/User.java +++ b/src/main/java/org/traccar/model/User.java @@ -17,11 +17,13 @@ package org.traccar.model; import com.fasterxml.jackson.annotation.JsonIgnore; +import org.apache.commons.lang3.builder.EqualsBuilder; import org.traccar.storage.QueryIgnore; import org.traccar.helper.Hashing; import org.traccar.storage.StorageName; import java.util.Date; +import java.util.HashMap; @StorageName("tc_users") public class User extends ExtendedModel implements UserRestrictions, Disableable { @@ -305,4 +307,17 @@ public class User extends ExtendedModel implements UserRestrictions, Disableable return Hashing.validatePassword(password, hashedPassword, salt); } + public boolean compare(User other, String... exclusions) { + if (!EqualsBuilder.reflectionEquals(this, other, "attributes", "hashedPassword", "salt")) { + return false; + } + var thisAttributes = new HashMap<>(getAttributes()); + var otherAttributes = new HashMap<>(other.getAttributes()); + for (String exclusion : exclusions) { + thisAttributes.remove(exclusion); + otherAttributes.remove(exclusion); + } + return thisAttributes.equals(otherAttributes); + } + } diff --git a/src/main/java/org/traccar/notification/PropertiesProvider.java b/src/main/java/org/traccar/notification/PropertiesProvider.java index 91887b5d4..5178b9a9e 100644 --- a/src/main/java/org/traccar/notification/PropertiesProvider.java +++ b/src/main/java/org/traccar/notification/PropertiesProvider.java @@ -48,7 +48,7 @@ public class PropertiesProvider { } else { Object result = extendedModel.getAttributes().get(key.getKey()); if (result != null) { - return result instanceof String ? Integer.parseInt((String) result) : (Integer) result; + return result instanceof String stringResult ? Integer.parseInt(stringResult) : (Integer) result; } else { return key.getDefaultValue(); } @@ -65,7 +65,7 @@ public class PropertiesProvider { } else { Object result = extendedModel.getAttributes().get(key.getKey()); if (result != null) { - return result instanceof String ? Boolean.valueOf((String) result) : (Boolean) result; + return result instanceof String stringResult ? Boolean.valueOf(stringResult) : (Boolean) result; } else { return null; } diff --git a/src/main/java/org/traccar/protocol/AdmProtocolDecoder.java b/src/main/java/org/traccar/protocol/AdmProtocolDecoder.java index 1f940f7e2..3eab90988 100644 --- a/src/main/java/org/traccar/protocol/AdmProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AdmProtocolDecoder.java @@ -108,38 +108,19 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder { int endIndex = buf.readerIndex() + buf.readUnsignedByte(); while (buf.readerIndex() < endIndex) { int mask = buf.readUnsignedByte(); - long value; - switch (BitUtil.from(mask, 6)) { - case 3: - value = buf.readLongLE(); - break; - case 2: - value = buf.readUnsignedIntLE(); - break; - case 1: - value = buf.readUnsignedShortLE(); - break; - default: - value = buf.readUnsignedByte(); - break; - } + long value = switch (BitUtil.from(mask, 6)) { + case 3 -> buf.readLongLE(); + case 2 -> buf.readUnsignedIntLE(); + case 1 -> buf.readUnsignedShortLE(); + default -> buf.readUnsignedByte(); + }; int index = BitUtil.to(mask, 6); switch (index) { - case 1: - position.set(Position.PREFIX_TEMP + 1, value); - break; - case 2: - position.set("humidity", value); - break; - case 3: - position.set("illumination", value); - break; - case 4: - position.set(Position.KEY_BATTERY, value); - break; - default: - position.set("can" + index, value); - break; + case 1 -> position.set(Position.PREFIX_TEMP + 1, value); + case 2 -> position.set("humidity", value); + case 3 -> position.set("illumination", value); + case 4 -> position.set(Position.KEY_BATTERY, value); + default -> position.set("can" + index, value); } } } diff --git a/src/main/java/org/traccar/protocol/AdmProtocolEncoder.java b/src/main/java/org/traccar/protocol/AdmProtocolEncoder.java index c02fa4112..9bd0e7909 100644 --- a/src/main/java/org/traccar/protocol/AdmProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/AdmProtocolEncoder.java @@ -29,16 +29,11 @@ public class AdmProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_GET_DEVICE_STATUS: - return formatCommand(command, "STATUS\r\n"); - - case Command.TYPE_CUSTOM: - return formatCommand(command, "%s\r\n", Command.KEY_DATA); - - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_GET_DEVICE_STATUS -> formatCommand(command, "STATUS\r\n"); + case Command.TYPE_CUSTOM -> formatCommand(command, "%s\r\n", Command.KEY_DATA); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java b/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java index 0cd8ca37e..d560620b7 100644 --- a/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AplicomProtocolDecoder.java @@ -88,40 +88,19 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { private void decodeEventData(Position position, ByteBuf buf, int event) { switch (event) { - case 2: - case 40: - buf.readUnsignedByte(); - break; - case 9: - buf.readUnsignedMedium(); - break; - case 31: - case 32: - buf.readUnsignedShort(); - break; - case 38: - buf.skipBytes(4 * 9); - break; - case 113: + case 2, 40 -> buf.readUnsignedByte(); + case 9 -> buf.readUnsignedMedium(); + case 31, 32 -> buf.readUnsignedShort(); + case 38 -> buf.skipBytes(4 * 9); + case 113 -> { buf.readUnsignedInt(); buf.readUnsignedByte(); - break; - case 119: - position.set("eventData", ByteBufUtil.hexDump( - buf, buf.readerIndex(), Math.min(buf.readableBytes(), 1024))); - break; - case 121: - case 142: - buf.readLong(); - break; - case 130: - buf.readUnsignedInt(); // incorrect - break; - case 188: - decodeEB(position, buf); - break; - default: - break; + } + case 119 -> position.set("eventData", ByteBufUtil.hexDump( + buf, buf.readerIndex(), Math.min(buf.readableBytes(), 1024))); + case 121, 142 -> buf.readLong(); + case 130 -> buf.readUnsignedInt(); // incorrect + case 188 -> decodeEB(position, buf); } } @@ -145,62 +124,42 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { for (int i = 0; i < count; i++) { ByteBuf value = values.get(i); switch (buf.readInt()) { - case 0x20D: + case 0x20D -> { position.set(Position.KEY_RPM, value.readShortLE()); position.set("dieselTemperature", value.readShortLE() * 0.1); position.set("batteryVoltage", value.readShortLE() * 0.01); position.set("supplyAirTempDep1", value.readShortLE() * 0.1); - break; - case 0x30D: - position.set("activeAlarm", ByteBufUtil.hexDump(value)); - break; - case 0x40C: + } + case 0x30D -> position.set("activeAlarm", ByteBufUtil.hexDump(value)); + case 0x40C -> { position.set("airTempDep1", value.readShortLE() * 0.1); position.set("airTempDep2", value.readShortLE() * 0.1); - break; - case 0x40D: - position.set("coldUnitState", ByteBufUtil.hexDump(value)); - break; - case 0x50C: + } + case 0x40D -> position.set("coldUnitState", ByteBufUtil.hexDump(value)); + case 0x50C -> { position.set("defrostTempDep1", value.readShortLE() * 0.1); position.set("defrostTempDep2", value.readShortLE() * 0.1); - break; - case 0x50D: + } + case 0x50D -> { position.set("condenserPressure", value.readShortLE() * 0.1); position.set("suctionPressure", value.readShortLE() * 0.1); - break; - case 0x58C: + } + case 0x58C -> { value.readByte(); value.readShort(); // index switch (value.readByte()) { - case 0x01: - position.set("setpointZone1", value.readIntLE() * 0.1); - break; - case 0x02: - position.set("setpointZone2", value.readIntLE() * 0.1); - break; - case 0x05: - position.set("unitType", value.readIntLE()); - break; - case 0x13: - position.set("dieselHours", value.readIntLE() / 60 / 60); - break; - case 0x14: - position.set("electricHours", value.readIntLE() / 60 / 60); - break; - case 0x17: - position.set("serviceIndicator", value.readIntLE()); - break; - case 0x18: - position.set("softwareVersion", value.readIntLE() * 0.01); - break; - default: - break; + case 0x01 -> position.set("setpointZone1", value.readIntLE() * 0.1); + case 0x02 -> position.set("setpointZone2", value.readIntLE() * 0.1); + case 0x05 -> position.set("unitType", value.readIntLE()); + case 0x13 -> position.set("dieselHours", value.readIntLE() / 60 / 60); + case 0x14 -> position.set("electricHours", value.readIntLE() / 60 / 60); + case 0x17 -> position.set("serviceIndicator", value.readIntLE()); + case 0x18 -> position.set("softwareVersion", value.readIntLE() * 0.01); + default -> { + } } - break; - default: - LOGGER.warn("Aplicom CAN decoding error", new UnsupportedOperationException()); - break; + } + default -> LOGGER.warn("Aplicom CAN decoding error", new UnsupportedOperationException()); } } } @@ -487,50 +446,39 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { int end = buf.readerIndex() + length; switch (type) { - case 0x01: - position.set("brakeFlags", ByteBufUtil.hexDump(buf.readSlice(length))); - break; - case 0x02: + case 0x01 -> position.set("brakeFlags", ByteBufUtil.hexDump(buf.readSlice(length))); + case 0x02 -> { position.set("wheelSpeed", buf.readUnsignedShort() / 256.0); position.set("wheelSpeedDifference", buf.readUnsignedShort() / 256.0 - 125.0); position.set("lateralAcceleration", buf.readUnsignedByte() / 10.0 - 12.5); position.set("vehicleSpeed", buf.readUnsignedShort() / 256.0); - break; - case 0x03: - position.set(Position.KEY_AXLE_WEIGHT, buf.readUnsignedShort() * 2); - break; - case 0x04: + } + case 0x03 -> position.set(Position.KEY_AXLE_WEIGHT, buf.readUnsignedShort() * 2); + case 0x04 -> { position.set("tirePressure", buf.readUnsignedByte() * 10); position.set("pneumaticPressure", buf.readUnsignedByte() * 5); - break; - case 0x05: + } + case 0x05 -> { position.set("brakeLining", buf.readUnsignedByte() * 0.4); position.set("brakeTemperature", buf.readUnsignedByte() * 10); - break; - case 0x06: + } + case 0x06 -> { position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 5L); position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedInt() * 5L); position.set(Position.KEY_ODOMETER_SERVICE, (buf.readUnsignedInt() - 2105540607) * 5L); - break; - case 0x0A: + } + case 0x0A -> { position.set("absStatusCounter", buf.readUnsignedShort()); position.set("atvbStatusCounter", buf.readUnsignedShort()); position.set("vdcActiveCounter", buf.readUnsignedShort()); - break; - case 0x0B: - position.set("brakeMinMaxData", ByteBufUtil.hexDump(buf.readSlice(length))); - break; - case 0x0C: - position.set("missingPgn", ByteBufUtil.hexDump(buf.readSlice(length))); - break; - case 0x0D: + } + case 0x0B -> position.set("brakeMinMaxData", ByteBufUtil.hexDump(buf.readSlice(length))); + case 0x0C -> position.set("missingPgn", ByteBufUtil.hexDump(buf.readSlice(length))); + case 0x0D -> { buf.readUnsignedByte(); position.set("towedDetectionStatus", buf.readUnsignedInt()); buf.skipBytes(17); // vin - break; - case 0x0E: - default: - break; + } } buf.readerIndex(end); diff --git a/src/main/java/org/traccar/protocol/ArknavX8ProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArknavX8ProtocolDecoder.java index 22c0344d6..ac32abb93 100644 --- a/src/main/java/org/traccar/protocol/ArknavX8ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArknavX8ProtocolDecoder.java @@ -67,16 +67,11 @@ public class ArknavX8ProtocolDecoder extends BaseProtocolDecoder { return null; } - switch (sentence.substring(0, 2)) { - case "1G": - case "1R": - case "1M": - return decode1G(channel, remoteAddress, sentence); - case "2G": - return decode2G(channel, remoteAddress, sentence); - default: - return null; - } + return switch (sentence.substring(0, 2)) { + case "1G", "1R", "1M" -> decode1G(channel, remoteAddress, sentence); + case "2G" -> decode2G(channel, remoteAddress, sentence); + default -> null; + }; } private Position decode1G(Channel channel, SocketAddress remoteAddress, String sentence) { diff --git a/src/main/java/org/traccar/protocol/ArnaviBinaryProtocolDecoder.java b/src/main/java/org/traccar/protocol/ArnaviBinaryProtocolDecoder.java index 0f6b7a33f..7735d8ff4 100644 --- a/src/main/java/org/traccar/protocol/ArnaviBinaryProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ArnaviBinaryProtocolDecoder.java @@ -147,11 +147,7 @@ public class ArnaviBinaryProtocolDecoder extends BaseProtocolDecoder { byte recordType = buf.readByte(); while (buf.readableBytes() > 0) { switch (recordType) { - case RECORD_PING: - case RECORD_DATA: - case RECORD_TEXT: - case RECORD_FILE: - case RECORD_BINARY: + case RECORD_PING, RECORD_DATA, RECORD_TEXT, RECORD_FILE, RECORD_BINARY -> { int length = buf.readUnsignedShortLE(); Date time = new Date(buf.readUnsignedIntLE() * 1000); @@ -162,10 +158,10 @@ public class ArnaviBinaryProtocolDecoder extends BaseProtocolDecoder { } buf.readUnsignedByte(); // checksum - break; - - default: + } + default -> { return null; + } } recordType = buf.readByte(); diff --git a/src/main/java/org/traccar/protocol/AstraProtocolDecoder.java b/src/main/java/org/traccar/protocol/AstraProtocolDecoder.java index 366bf9e8b..a1e133c23 100644 --- a/src/main/java/org/traccar/protocol/AstraProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AstraProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2024 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.traccar.protocol; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.slf4j.Logger; @@ -31,6 +32,7 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.util.Date; import java.util.LinkedList; import java.util.List; @@ -51,15 +53,33 @@ public class AstraProtocolDecoder extends BaseProtocolDecoder { ByteBuf buf = (ByteBuf) msg; + byte protocol = buf.readByte(); + buf.readUnsignedShort(); // length + if (channel != null) { channel.writeAndFlush(new NetworkMessage(Unpooled.wrappedBuffer(new byte[] {0x06}), remoteAddress)); } - buf.readUnsignedByte(); // protocol - buf.readUnsignedShort(); // length + return switch (protocol) { + case 'K' -> decodeK(channel, remoteAddress, buf); + case 'X' -> decodeX(channel, remoteAddress, buf); + default -> null; + }; + } + + private String readImei(ByteBuf buf) { + return String.format("%08d", buf.readUnsignedInt()) + String.format("%07d", buf.readUnsignedMedium()); + } + + private Date readTime(ByteBuf buf) { + DateBuilder dateBuilder = new DateBuilder() + .setDate(1980, 1, 6).addMillis(buf.readUnsignedInt() * 1000L); + return dateBuilder.getDate(); + } - String imei = String.format("%08d", buf.readUnsignedInt()) + String.format("%07d", buf.readUnsignedMedium()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); + private Object decodeK(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, readImei(buf)); if (deviceSession == null) { return null; } @@ -76,11 +96,7 @@ public class AstraProtocolDecoder extends BaseProtocolDecoder { position.setValid(true); position.setLatitude(buf.readInt() * 0.000001); position.setLongitude(buf.readInt() * 0.000001); - - DateBuilder dateBuilder = new DateBuilder() - .setDate(1980, 1, 6).addMillis(buf.readUnsignedInt() * 1000L); - position.setTime(dateBuilder.getDate()); - + position.setTime(readTime(buf)); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte() * 2)); position.setCourse(buf.readUnsignedByte() * 2); @@ -126,4 +142,193 @@ public class AstraProtocolDecoder extends BaseProtocolDecoder { return positions; } + private Object decodeX(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { + + int count = buf.readUnsignedByte(); + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, readImei(buf)); + if (deviceSession == null) { + return null; + } + + List<Position> positions = new LinkedList<>(); + for (int i = 0; i < count; i++) { + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.set(Position.KEY_INDEX, buf.readUnsignedByte()); + long mask = (long) buf.readUnsignedShort() << 32 + buf.readUnsignedInt(); + position.setDeviceTime(readTime(buf)); + position.set(Position.KEY_EVENT, buf.readUnsignedInt()); + position.set(Position.KEY_STATUS, buf.readUnsignedShort()); + + if ((mask & 1L) > 0) { + position.set(Position.KEY_POWER, buf.readUnsignedByte() * 0.2); + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + } + + if ((mask & 2L) > 0) { + position.setValid(true); + position.setFixTime(readTime(buf)); + position.setLatitude(buf.readInt() * 0.000001); + position.setLongitude(buf.readInt() * 0.000001); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte() * 2)); + buf.readUnsignedByte(); // max speed since last report + position.setCourse(buf.readUnsignedByte() * 2); + position.setAltitude(buf.readUnsignedByte() * 20); + position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedShort() * 100); + } else { + getLastLocation(position, position.getDeviceTime()); + } + + if ((mask & 4L) > 0) { + buf.readUnsignedShort(); // states + buf.readUnsignedShort(); // changes mask + } + + if ((mask & 8L) > 0) { + buf.readUnsignedShort(); // adc1 + buf.readUnsignedShort(); // adc2 + } + + if ((mask & 16L) > 0) { + position.set("xMax", buf.readByte()); + position.set("xMin", buf.readByte()); + position.set("yMax", buf.readByte()); + position.set("yMin", buf.readByte()); + position.set("zMax", buf.readByte()); + position.set("zMin", buf.readByte()); + position.set("idleHours", buf.readUnsignedShort()); + } + + if ((mask & 32L) > 0) { + int value = buf.readUnsignedByte(); + position.set(Position.KEY_SATELLITES, BitUtil.to(value, 4)); + position.set(Position.KEY_RSSI, BitUtil.from(value, 4)); + } + + if ((mask & 64L) > 0) { + buf.readUnsignedShort(); // mcc + buf.readUnsignedShort(); // mnc + } + + if ((mask & 128L) > 0) { + buf.readUnsignedByte(); // geofences + } + + if ((mask & 256L) > 0) { + buf.readUnsignedByte(); // source + buf.readLong(); // driver id + } + + if ((mask & 512L) > 0) { + buf.readUnsignedByte(); // source + buf.skipBytes(10); // trailer id + buf.readUnsignedByte(); // status + } + + if ((mask & 1024L) > 0) { + position.set("axleWeight", buf.readUnsignedShort()); + } + + if ((mask & 2048L) > 0) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium() * 1000); + position.set(Position.KEY_HOURS, buf.readUnsignedShort() * 3_600_000); + } + + if ((mask & 4096L) > 0) { + position.set("wheelSpeedMax", buf.readUnsignedByte()); + position.set("wheelSpeedAvg", buf.readUnsignedByte()); + position.set("rpmMax", buf.readUnsignedByte() * 32); + position.set("rpmAvg", buf.readUnsignedByte() * 32); + position.set("acceleratorMax", buf.readUnsignedByte()); + position.set("acceleratorAvg", buf.readUnsignedByte()); + position.set("engineLoadMax", buf.readUnsignedByte()); + position.set("engineLoadAvg", buf.readUnsignedByte()); + position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedShort() * 100); + position.set(Position.KEY_COOLANT_TEMP, buf.readByte() + 40); + position.set("fmsStatus", buf.readUnsignedShort()); + position.set("fmsEvents", buf.readUnsignedShort()); + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); + position.set(Position.KEY_FUEL_USED, buf.readUnsignedInt() * 0.5); + } + + if ((mask & 8192L) > 0) { + position.set("wheelSpeedMax", buf.readUnsignedByte()); + position.set("wheelSpeedAvg", buf.readUnsignedByte()); + position.set("rpmMax", buf.readUnsignedByte() * 32); + position.set("rpmAvg", buf.readUnsignedByte() * 32); + position.set("acceleratorMax", buf.readUnsignedByte()); + position.set("acceleratorAvg", buf.readUnsignedByte()); + position.set("engineLoadMax", buf.readUnsignedByte()); + position.set("engineLoadAvg", buf.readUnsignedByte()); + position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedShort() * 100); + position.set(Position.KEY_COOLANT_TEMP, buf.readByte() + 40); + position.set("obdStatus", buf.readUnsignedShort()); + position.set("obdEvents", buf.readUnsignedShort()); + position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); + position.set(Position.KEY_FUEL_USED, buf.readUnsignedShort() * 0.1); + } + + if ((mask & 16384L) > 0) { + for (int j = 1; j <= 5; j++) { + position.set("dtc" + j, buf.readCharSequence(5, StandardCharsets.US_ASCII).toString()); + } + } + + if ((mask & 32768L) > 0) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium() * 1000); + position.set(Position.KEY_HOURS, buf.readUnsignedShort() * 3_600_000); + position.set("axleWeight", buf.readUnsignedShort()); + position.set("tripFuelUsed", buf.readUnsignedShort() * 0.1); + position.set("tripCruise", buf.readUnsignedShort()); + position.set(Position.KEY_ODOMETER_SERVICE, buf.readUnsignedShort() * 5); + } + + if ((mask & 65536L) > 0) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium() * 1000); + position.set(Position.KEY_HOURS, buf.readUnsignedShort() * 3_600_000); + buf.readUnsignedShort(); // time with mil on + buf.readUnsignedShort(); // distance with mil on + } + + if ((mask & 131072L) > 0) { + for (int j = 1; j <= 6; j++) { + position.set(Position.PREFIX_TEMP + j, buf.readShort() * 0.1); + } + for (int j = 1; j <= 3; j++) { + position.set("setpoint" + j, buf.readByte() * 0.5); + } + buf.readUnsignedByte(); // refrigerator fuel level + buf.readUnsignedShort(); // refrigerator total engine hours + buf.readUnsignedShort(); // refrigerator total standby hours + buf.readUnsignedShort(); // refrigerator status + buf.readUnsignedMedium(); // alarm flags + } + + if ((mask & 262144L) > 0) { + for (int j = 1; j <= 4; j++) { + position.set(Position.PREFIX_TEMP + j, (buf.readUnsignedShort() - 550) * 0.1); + } + } + + if ((mask & 524288L) > 0) { + position.set("alarmCount", buf.readUnsignedByte()); + position.set("alarmQueue", ByteBufUtil.hexDump(buf.readSlice(16))); + } + + if ((mask & 4294967296L) > 0) { + for (int j = 1; j <= 6; j++) { + position.set("sensor" + j, buf.readUnsignedMedium()); + } + } + + positions.add(position); + + } + + return positions; + } + } diff --git a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java index 834f4f16c..0ef977e53 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocolDecoder.java @@ -127,7 +127,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { position.set("tag" + i + "Id", ByteBufUtil.hexDump(data.readSlice(6))); } switch (mode) { - case 1: + case 1 -> { if (BitUtil.check(mask, 6)) { data.readUnsignedShort(); // major } @@ -140,8 +140,8 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(mask, 3)) { position.set("tag" + i + "Rssi", data.readUnsignedByte()); } - break; - case 2: + } + case 2 -> { if (BitUtil.check(mask, 6)) { data.readUnsignedShort(); // battery voltage } @@ -154,8 +154,8 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(mask, 3)) { position.set("tag" + i + "Rssi", data.readUnsignedByte()); } - break; - case 3: + } + case 3 -> { if (BitUtil.check(mask, 6)) { position.set("tag" + i + "Humidity", data.readUnsignedShort()); } @@ -168,36 +168,23 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(mask, 2)) { data.readUnsignedShort(); } - break; - case 4: + } + case 4 -> { if (BitUtil.check(mask, 6)) { int hardwareId = data.readUnsignedByte(); if (BitUtil.check(mask, 5)) { switch (hardwareId) { - case 1: - case 4: - data.skipBytes(11); // fuel - break; - case 2: - data.skipBytes(2); // temperature - break; - case 3: - data.skipBytes(6); // temperature and luminosity - break; - case 5: - data.skipBytes(10); // temperature, humidity, luminosity and pressure - break; - default: - break; + case 1, 4 -> data.skipBytes(11); // fuel + case 2 -> data.skipBytes(2); // temperature + case 3 -> data.skipBytes(6); // temperature and luminosity + case 5 -> data.skipBytes(10); // temperature, humidity, luminosity and pressure } } } if (BitUtil.check(mask, 4)) { data.skipBytes(9); // name } - break; - default: - break; + } } i += 1; } @@ -209,101 +196,58 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { String[] values = data.split(",|\r\n"); for (int i = 0; i < Math.min(keys.length, values.length); i++) { switch (keys[i]) { - case "SA": - position.set(Position.KEY_SATELLITES, Integer.parseInt(values[i])); - break; - case "MV": - position.set(Position.KEY_POWER, Integer.parseInt(values[i]) * 0.1); - break; - case "BV": - position.set(Position.KEY_BATTERY, Integer.parseInt(values[i]) * 0.1); - break; - case "GQ": - cellTower.setSignalStrength(Integer.parseInt(values[i])); - break; - case "CE": - cellTower.setCellId(Long.parseLong(values[i])); - break; - case "LC": - cellTower.setLocationAreaCode(Integer.parseInt(values[i])); - break; - case "CN": + case "SA" -> position.set(Position.KEY_SATELLITES, Integer.parseInt(values[i])); + case "MV" -> position.set(Position.KEY_POWER, Integer.parseInt(values[i]) * 0.1); + case "BV" -> position.set(Position.KEY_BATTERY, Integer.parseInt(values[i]) * 0.1); + case "GQ" -> cellTower.setSignalStrength(Integer.parseInt(values[i])); + case "CE" -> cellTower.setCellId(Long.parseLong(values[i])); + case "LC" -> cellTower.setLocationAreaCode(Integer.parseInt(values[i])); + case "CN" -> { if (values[i].length() > 3) { cellTower.setMobileCountryCode(Integer.parseInt(values[i].substring(0, 3))); cellTower.setMobileNetworkCode(Integer.parseInt(values[i].substring(3))); } - break; - case "PC": - position.set(Position.PREFIX_COUNT + 1, Integer.parseInt(values[i])); - break; - case "AT": - position.setAltitude(Integer.parseInt(values[i])); - break; - case "RP": - position.set(Position.KEY_RPM, Integer.parseInt(values[i])); - break; - case "GS": - position.set(Position.KEY_RSSI, Integer.parseInt(values[i])); - break; - case "DT": - position.set(Position.KEY_ARCHIVE, Integer.parseInt(values[i]) == 1); - break; - case "VN": - position.set(Position.KEY_VIN, values[i]); - break; - case "TR": - position.set(Position.KEY_THROTTLE, Integer.parseInt(values[i])); - break; - case "ET": - position.set(Position.KEY_COOLANT_TEMP, Integer.parseInt(values[i])); - break; - case "FL": - position.set(Position.KEY_FUEL_LEVEL, Integer.parseInt(values[i])); - break; - case "FC": - position.set(Position.KEY_FUEL_CONSUMPTION, Integer.parseInt(values[i])); - break; - case "AV1": - position.set(Position.PREFIX_ADC + 1, Integer.parseInt(values[i])); - break; - case "CD": - position.set(Position.KEY_ICCID, values[i]); - break; - case "EH": - position.set(Position.KEY_HOURS, UnitsConverter.msFromHours(Integer.parseInt(values[i]) * 0.1)); - break; - case "IA": - position.set("intakeTemp", Integer.parseInt(values[i])); - break; - case "EL": - position.set(Position.KEY_ENGINE_LOAD, Integer.parseInt(values[i])); - break; - case "HA": + } + case "PC" -> position.set(Position.PREFIX_COUNT + 1, Integer.parseInt(values[i])); + case "AT" -> position.setAltitude(Integer.parseInt(values[i])); + case "RP" -> position.set(Position.KEY_RPM, Integer.parseInt(values[i])); + case "GS" -> position.set(Position.KEY_RSSI, Integer.parseInt(values[i])); + case "DT" -> position.set(Position.KEY_ARCHIVE, Integer.parseInt(values[i]) == 1); + case "VN" -> position.set(Position.KEY_VIN, values[i]); + case "TR" -> position.set(Position.KEY_THROTTLE, Integer.parseInt(values[i])); + case "ET" -> position.set(Position.KEY_COOLANT_TEMP, Integer.parseInt(values[i])); + case "FL" -> position.set(Position.KEY_FUEL_LEVEL, Integer.parseInt(values[i])); + case "FC" -> position.set(Position.KEY_FUEL_CONSUMPTION, Integer.parseInt(values[i])); + case "AV1" -> position.set(Position.PREFIX_ADC + 1, Integer.parseInt(values[i])); + case "CD" -> position.set(Position.KEY_ICCID, values[i]); + case "EH" -> + position.set(Position.KEY_HOURS, UnitsConverter.msFromHours(Integer.parseInt(values[i]) * 0.1)); + case "IA" -> position.set("intakeTemp", Integer.parseInt(values[i])); + case "EL" -> position.set(Position.KEY_ENGINE_LOAD, Integer.parseInt(values[i])); + case "HA" -> { if (Integer.parseInt(values[i]) > 0) { position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); } - break; - case "HB": + } + case "HB" -> { if (Integer.parseInt(values[i]) > 0) { position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); } - break; - case "HC": + } + case "HC" -> { if (Integer.parseInt(values[i]) > 0) { position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); } - break; - case "MT": - position.set(Position.KEY_MOTION, Integer.parseInt(values[i]) > 0); - break; - case "BC": + } + case "MT" -> position.set(Position.KEY_MOTION, Integer.parseInt(values[i]) > 0); + case "BC" -> { String[] beaconValues = values[i].split(":"); decodeBeaconData( position, Integer.parseInt(beaconValues[0]), Integer.parseInt(beaconValues[1]), Unpooled.wrappedBuffer(DataConverter.parseHex(beaconValues[2]))); - break; - default: - break; + } + default -> { + } } } @@ -322,320 +266,122 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { String[] keys = form.substring(1).split("%"); for (String key : keys) { switch (key) { - case "SA": - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - break; - case "MT": - position.set(Position.KEY_MOTION, buf.readUnsignedByte() > 0); - break; - case "MV": - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.1); - break; - case "BV": - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.1); - break; - case "GQ": - cellTower.setSignalStrength((int) buf.readUnsignedByte()); - break; - case "CE": - cellTower.setCellId(buf.readUnsignedInt()); - break; - case "LC": - cellTower.setLocationAreaCode(buf.readUnsignedShort()); - break; - case "CN": + case "SA" -> position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + case "MT" -> position.set(Position.KEY_MOTION, buf.readUnsignedByte() > 0); + case "MV" -> position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.1); + case "BV" -> position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.1); + case "GQ" -> cellTower.setSignalStrength((int) buf.readUnsignedByte()); + case "CE" -> cellTower.setCellId(buf.readUnsignedInt()); + case "LC" -> cellTower.setLocationAreaCode(buf.readUnsignedShort()); + case "CN" -> { int combinedMobileCodes = (int) (buf.readUnsignedInt() % 100000); // cccnn cellTower.setMobileCountryCode(combinedMobileCodes / 100); cellTower.setMobileNetworkCode(combinedMobileCodes % 100); - break; - case "RL": - buf.readUnsignedByte(); // rxlev - break; - case "PC": - position.set(Position.PREFIX_COUNT + 1, buf.readUnsignedInt()); - break; - case "AT": - position.setAltitude(buf.readUnsignedInt()); - break; - case "RP": - position.set(Position.KEY_RPM, buf.readUnsignedShort()); - break; - case "GS": - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - break; - case "DT": - position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() == 1); - break; - case "VN": - position.set(Position.KEY_VIN, readString(buf)); - break; - case "MF": - buf.readUnsignedShort(); // mass air flow rate - break; - case "EL": - buf.readUnsignedByte(); // engine load - break; - case "TR": - position.set(Position.KEY_THROTTLE, buf.readUnsignedByte()); - break; - case "ET": - position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedShort()); - break; - case "FL": - position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); - break; - case "ML": - buf.readUnsignedByte(); // mil status - break; - case "FC": - position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedInt()); - break; - case "CI": - readString(buf); // format string - break; - case "AV1": - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); - break; - case "NC": - readString(buf); // gsm neighbor cell info - break; - case "SM": - buf.readUnsignedShort(); // max speed between reports - break; - case "GL": - readString(buf); // google link - break; - case "MA": - readString(buf); // mac address - break; - case "PD": - buf.readUnsignedByte(); // pending code status - break; - case "CD": - position.set(Position.KEY_ICCID, readString(buf)); - break; - case "CM": - buf.readLong(); // imsi - break; - case "GN": - buf.skipBytes(60); // g sensor data - break; - case "GV": - buf.skipBytes(6); // maximum g force - break; - case "ME": - buf.readLong(); // imei - break; - case "IA": - buf.readUnsignedByte(); // intake air temperature - break; - case "MP": - buf.readUnsignedByte(); // manifold absolute pressure - break; - case "EO": - position.set(Position.KEY_ODOMETER, UnitsConverter.metersFromMiles(buf.readUnsignedInt())); - break; - case "EH": - position.set(Position.KEY_HOURS, buf.readUnsignedInt() * 360000); - break; - case "ZO1": - buf.readUnsignedByte(); // brake stroke status - break; - case "ZO2": - buf.readUnsignedByte(); // warning indicator status - break; - case "ZO3": - buf.readUnsignedByte(); // abs control status - break; - case "ZO4": - position.set(Position.KEY_THROTTLE, buf.readUnsignedByte() * 0.4); - break; - case "ZO5": - buf.readUnsignedByte(); // parking brake status - break; - case "ZO6": - position.set(Position.KEY_OBD_SPEED, buf.readUnsignedByte() * 0.805); - break; - case "ZO7": - buf.readUnsignedByte(); // cruise control status - break; - case "ZO8": - buf.readUnsignedByte(); // accelector pedal position - break; - case "ZO9": - position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedByte() * 0.5); - break; - case "ZO10": - position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte() * 0.5); - break; - case "ZO11": - buf.readUnsignedByte(); // engine oil pressure - break; - case "ZO12": - buf.readUnsignedByte(); // boost pressure - break; - case "ZO13": - buf.readUnsignedByte(); // intake temperature - break; - case "ZO14": - position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte()); - break; - case "ZO15": - buf.readUnsignedByte(); // brake application pressure - break; - case "ZO16": - buf.readUnsignedByte(); // brake primary pressure - break; - case "ZO17": - buf.readUnsignedByte(); // brake secondary pressure - break; - case "ZH1": - buf.readUnsignedShort(); // cargo weight - break; - case "ZH2": - position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 16.428 / 3600); - break; - case "ZH3": - position.set(Position.KEY_RPM, buf.readUnsignedShort() * 0.25); - break; - case "ZL1": - buf.readUnsignedInt(); // fuel used (natural gas) - break; - case "ZL2": - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 161); - break; - case "ZL3": - buf.readUnsignedInt(); // vehicle hours - break; - case "ZL4": - position.set(Position.KEY_HOURS, buf.readUnsignedInt() * 5 * 36000); - break; - case "ZS1": - position.set(Position.KEY_VIN, readString(buf)); - break; - case "JO1": - buf.readUnsignedByte(); // pedals - break; - case "JO2": - buf.readUnsignedByte(); // power takeoff device - break; - case "JO3": - buf.readUnsignedByte(); // accelector pedal position - break; - case "JO4": - position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedByte()); - break; - case "JO5": - position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte() * 0.4); - break; - case "JO6": - buf.readUnsignedByte(); // fms vehicle interface - break; - case "JO7": - buf.readUnsignedByte(); // driver 2 - break; - case "JO8": - buf.readUnsignedByte(); // driver 1 - break; - case "JO9": - buf.readUnsignedByte(); // drivers - break; - case "JO10": - buf.readUnsignedByte(); // system information - break; - case "JO11": - position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte() - 40); - break; - case "JO12": - buf.readUnsignedByte(); // pto engaged - break; - case "JH1": - position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort() / 256.0); - break; - case "JH2": - position.set(Position.KEY_RPM, buf.readUnsignedShort() * 0.125); - break; - case "JH3": - case "JH4": - case "JH5": - case "JH6": - case "JH7": + } + case "RL" -> buf.readUnsignedByte(); // rxlev + case "PC" -> position.set(Position.PREFIX_COUNT + 1, buf.readUnsignedInt()); + case "AT" -> position.setAltitude(buf.readUnsignedInt()); + case "RP" -> position.set(Position.KEY_RPM, buf.readUnsignedShort()); + case "GS" -> position.set(Position.KEY_RSSI, buf.readUnsignedByte()); + case "DT" -> position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() == 1); + case "VN" -> position.set(Position.KEY_VIN, readString(buf)); + case "MF" -> buf.readUnsignedShort(); // mass air flow rate + case "EL" -> buf.readUnsignedByte(); // engine load + case "TR" -> position.set(Position.KEY_THROTTLE, buf.readUnsignedByte()); + case "ET" -> position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedShort()); + case "FL" -> position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); + case "ML" -> buf.readUnsignedByte(); // mil status + case "FC" -> position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedInt()); + case "CI" -> readString(buf); // format string + case "AV1" -> position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); + case "NC" -> readString(buf); // gsm neighbor cell info + case "SM" -> buf.readUnsignedShort(); // max speed between reports + case "GL" -> readString(buf); // google link + case "MA" -> readString(buf); // mac address + case "PD" -> buf.readUnsignedByte(); // pending code status + case "CD" -> position.set(Position.KEY_ICCID, readString(buf)); + case "CM" -> buf.readLong(); // imsi + case "GN" -> buf.skipBytes(60); // g sensor data + case "GV" -> buf.skipBytes(6); // maximum g force + case "ME" -> buf.readLong(); // imei + case "IA" -> buf.readUnsignedByte(); // intake air temperature + case "MP" -> buf.readUnsignedByte(); // manifold absolute pressure + case "EO" -> position.set(Position.KEY_ODOMETER, UnitsConverter.metersFromMiles(buf.readUnsignedInt())); + case "EH" -> position.set(Position.KEY_HOURS, buf.readUnsignedInt() * 360000); + case "ZO1" -> buf.readUnsignedByte(); // brake stroke status + case "ZO2" -> buf.readUnsignedByte(); // warning indicator status + case "ZO3" -> buf.readUnsignedByte(); // abs control status + case "ZO4" -> position.set(Position.KEY_THROTTLE, buf.readUnsignedByte() * 0.4); + case "ZO5" -> buf.readUnsignedByte(); // parking brake status + case "ZO6" -> position.set(Position.KEY_OBD_SPEED, buf.readUnsignedByte() * 0.805); + case "ZO7" -> buf.readUnsignedByte(); // cruise control status + case "ZO8" -> buf.readUnsignedByte(); // accelector pedal position + case "ZO9" -> position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedByte() * 0.5); + case "ZO10" -> position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte() * 0.5); + case "ZO11" -> buf.readUnsignedByte(); // engine oil pressure + case "ZO12" -> buf.readUnsignedByte(); // boost pressure + case "ZO13" -> buf.readUnsignedByte(); // intake temperature + case "ZO14" -> position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte()); + case "ZO15" -> buf.readUnsignedByte(); // brake application pressure + case "ZO16" -> buf.readUnsignedByte(); // brake primary pressure + case "ZO17" -> buf.readUnsignedByte(); // brake secondary pressure + case "ZH1" -> buf.readUnsignedShort(); // cargo weight + case "ZH2" -> position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 16.428 / 3600); + case "ZH3" -> position.set(Position.KEY_RPM, buf.readUnsignedShort() * 0.25); + case "ZL1" -> buf.readUnsignedInt(); // fuel used (natural gas) + case "ZL2" -> position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 161); + case "ZL3" -> buf.readUnsignedInt(); // vehicle hours + case "ZL4" -> position.set(Position.KEY_HOURS, buf.readUnsignedInt() * 5 * 36000); + case "ZS1" -> position.set(Position.KEY_VIN, readString(buf)); + case "JO1" -> buf.readUnsignedByte(); // pedals + case "JO2" -> buf.readUnsignedByte(); // power takeoff device + case "JO3" -> buf.readUnsignedByte(); // accelector pedal position + case "JO4" -> position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedByte()); + case "JO5" -> position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte() * 0.4); + case "JO6" -> buf.readUnsignedByte(); // fms vehicle interface + case "JO7" -> buf.readUnsignedByte(); // driver 2 + case "JO8" -> buf.readUnsignedByte(); // driver 1 + case "JO9" -> buf.readUnsignedByte(); // drivers + case "JO10" -> buf.readUnsignedByte(); // system information + case "JO11" -> position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte() - 40); + case "JO12" -> buf.readUnsignedByte(); // pto engaged + case "JH1" -> position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort() / 256.0); + case "JH2" -> position.set(Position.KEY_RPM, buf.readUnsignedShort() * 0.125); + case "JH3", "JH4", "JH5", "JH6", "JH7" -> { int index = Integer.parseInt(key.substring(2)) - 2; position.set("axleWeight" + index, buf.readUnsignedShort() * 0.5); - break; - case "JH8": - position.set(Position.KEY_ODOMETER_SERVICE, buf.readUnsignedShort() * 5); - break; - case "JH9": - buf.readUnsignedShort(); // tachograph speed - break; - case "JH10": - buf.readUnsignedShort(); // ambient air temperature - break; - case "JH11": - position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 0.05); - break; - case "JH12": - buf.readUnsignedShort(); // fuel economy - break; - case "JL1": - position.set(Position.KEY_FUEL_USED, buf.readUnsignedInt() * 0.5); - break; - case "JL2": - position.set(Position.KEY_HOURS, buf.readUnsignedInt() * 5 * 36000); - break; - case "JL3": - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 1000); - break; - case "JL4": - position.set(Position.KEY_FUEL_USED, buf.readUnsignedInt() * 0.001); - break; - case "JS1": - position.set(Position.KEY_VIN, readString(buf)); - break; - case "JS2": - readString(buf); // fms version supported - break; - case "JS3": - position.set("driver1", readString(buf)); - break; - case "JS4": - position.set("driver2", readString(buf)); - break; - case "JN1": - buf.readUnsignedInt(); // cruise control distance - break; - case "JN2": - buf.readUnsignedInt(); // excessive idling time - break; - case "JN3": - buf.readUnsignedInt(); // excessive idling fuel - break; - case "JN4": - buf.readUnsignedInt(); // pto time - break; - case "JN5": - buf.readUnsignedInt(); // pto fuel - break; - case "IN0": - position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); - break; - case "IN1": - case "IN2": - case "IN3": + } + case "JH8" -> position.set(Position.KEY_ODOMETER_SERVICE, buf.readUnsignedShort() * 5); + case "JH9" -> buf.readUnsignedShort(); // tachograph speed + case "JH10" -> buf.readUnsignedShort(); // ambient air temperature + case "JH11" -> position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 0.05); + case "JH12" -> buf.readUnsignedShort(); // fuel economy + case "JL1" -> position.set(Position.KEY_FUEL_USED, buf.readUnsignedInt() * 0.5); + case "JL2" -> position.set(Position.KEY_HOURS, buf.readUnsignedInt() * 5 * 36000); + case "JL3" -> position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 1000); + case "JL4" -> position.set(Position.KEY_FUEL_USED, buf.readUnsignedInt() * 0.001); + case "JS1" -> position.set(Position.KEY_VIN, readString(buf)); + case "JS2" -> readString(buf); // fms version supported + case "JS3" -> position.set("driver1", readString(buf)); + case "JS4" -> position.set("driver2", readString(buf)); + case "JN1" -> buf.readUnsignedInt(); // cruise control distance + case "JN2" -> buf.readUnsignedInt(); // excessive idling time + case "JN3" -> buf.readUnsignedInt(); // excessive idling fuel + case "JN4" -> buf.readUnsignedInt(); // pto time + case "JN5" -> buf.readUnsignedInt(); // pto fuel + case "IN0" -> position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); + case "IN1", "IN2", "IN3" -> { position.set(Position.PREFIX_IN + key.charAt(2), buf.readUnsignedByte() > 0); - break; - case "HA": + } + case "HA" -> { position.set(Position.KEY_ALARM, buf.readUnsignedByte() > 0 ? Position.ALARM_ACCELERATION : null); - break; - case "HB": + } + case "HB" -> { position.set(Position.KEY_ALARM, buf.readUnsignedByte() > 0 ? Position.ALARM_BRAKING : null); - break; - case "HC": + } + case "HC" -> { position.set(Position.KEY_ALARM, buf.readUnsignedByte() > 0 ? Position.ALARM_CORNERING : null); - break; - default: - break; + } } } diff --git a/src/main/java/org/traccar/protocol/AtrackProtocolEncoder.java b/src/main/java/org/traccar/protocol/AtrackProtocolEncoder.java index d803ae391..00752dbc6 100644 --- a/src/main/java/org/traccar/protocol/AtrackProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/AtrackProtocolEncoder.java @@ -31,13 +31,11 @@ public class AtrackProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return Unpooled.copiedBuffer( - command.getString(Command.KEY_DATA) + "\r\n", StandardCharsets.US_ASCII); - default: - return null; + if (command.getType().equals(Command.TYPE_CUSTOM)) { + return Unpooled.copiedBuffer( + command.getString(Command.KEY_DATA) + "\r\n", StandardCharsets.US_ASCII); } + return null; } } diff --git a/src/main/java/org/traccar/protocol/AutoFonFrameDecoder.java b/src/main/java/org/traccar/protocol/AutoFonFrameDecoder.java index 69f28133f..f0545279a 100644 --- a/src/main/java/org/traccar/protocol/AutoFonFrameDecoder.java +++ b/src/main/java/org/traccar/protocol/AutoFonFrameDecoder.java @@ -32,27 +32,14 @@ public class AutoFonFrameDecoder extends BaseFrameDecoder { return null; } - int length; - switch (buf.getUnsignedByte(buf.readerIndex())) { - case AutoFonProtocolDecoder.MSG_LOGIN: - length = 12; - break; - case AutoFonProtocolDecoder.MSG_LOCATION: - length = 78; - break; - case AutoFonProtocolDecoder.MSG_HISTORY: - length = 257; - break; - case AutoFonProtocolDecoder.MSG_45_LOGIN: - length = 19; - break; - case AutoFonProtocolDecoder.MSG_45_LOCATION: - length = 34; - break; - default: - length = 0; - break; - } + int length = switch (buf.getUnsignedByte(buf.readerIndex())) { + case AutoFonProtocolDecoder.MSG_LOGIN -> 12; + case AutoFonProtocolDecoder.MSG_LOCATION -> 78; + case AutoFonProtocolDecoder.MSG_HISTORY -> 257; + case AutoFonProtocolDecoder.MSG_45_LOGIN -> 19; + case AutoFonProtocolDecoder.MSG_45_LOCATION -> 34; + default -> 0; + }; // Check length and return buffer if (length != 0 && buf.readableBytes() >= length) { diff --git a/src/main/java/org/traccar/protocol/AutoTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/AutoTrackProtocolDecoder.java index 938d170e6..78243b76a 100644 --- a/src/main/java/org/traccar/protocol/AutoTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/AutoTrackProtocolDecoder.java @@ -103,7 +103,7 @@ public class AutoTrackProtocolDecoder extends BaseProtocolDecoder { DeviceSession deviceSession; switch (type) { - case MSG_LOGIN_REQUEST: + case MSG_LOGIN_REQUEST -> { String imei = ByteBufUtil.hexDump(buf.readSlice(8)); deviceSession = getDeviceSession(channel, remoteAddress, imei); if (deviceSession == null) { @@ -123,16 +123,17 @@ public class AutoTrackProtocolDecoder extends BaseProtocolDecoder { channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } return null; - case MSG_TELEMETRY_1: - case MSG_TELEMETRY_2: - case MSG_TELEMETRY_3: + } + case MSG_TELEMETRY_1, MSG_TELEMETRY_2, MSG_TELEMETRY_3 -> { deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { return null; } return decodeTelemetry(channel, remoteAddress, deviceSession, buf); - default: + } + default -> { return null; + } } } diff --git a/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java b/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java index b0a5411f7..a0c059898 100644 --- a/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/B2316ProtocolDecoder.java @@ -40,35 +40,24 @@ public class B2316ProtocolDecoder extends BaseProtocolDecoder { } private String decodeAlarm(int value) { - switch (value) { - case 1: - return Position.ALARM_LOW_BATTERY; - case 2: - return Position.ALARM_SOS; - case 3: - return Position.ALARM_POWER_OFF; - case 4: - return Position.ALARM_REMOVING; - default: - return null; - } + return switch (value) { + case 1 -> Position.ALARM_LOW_BATTERY; + case 2 -> Position.ALARM_SOS; + case 3 -> Position.ALARM_POWER_OFF; + case 4 -> Position.ALARM_REMOVING; + default -> null; + }; } private Integer decodeBattery(int value) { - switch (value) { - case 0: - return 10; - case 1: - return 30; - case 2: - return 60; - case 3: - return 80; - case 4: - return 100; - default: - return null; - } + return switch (value) { + case 0 -> 10; + case 1 -> 30; + case 2 -> 60; + case 3 -> 80; + case 4 -> 100; + default -> null; + }; } @Override diff --git a/src/main/java/org/traccar/protocol/BlueProtocolDecoder.java b/src/main/java/org/traccar/protocol/BlueProtocolDecoder.java index db59c564d..c3fbddbeb 100644 --- a/src/main/java/org/traccar/protocol/BlueProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/BlueProtocolDecoder.java @@ -67,16 +67,12 @@ public class BlueProtocolDecoder extends BaseProtocolDecoder { } private String decodeAlarm(int value) { - switch (value) { - case 1: - return Position.ALARM_SOS; - case 8: - return Position.ALARM_OVERSPEED; - case 19: - return Position.ALARM_LOW_POWER; - default: - return null; - } + return switch (value) { + case 1 -> Position.ALARM_SOS; + case 8 -> Position.ALARM_OVERSPEED; + case 19 -> Position.ALARM_LOW_POWER; + default -> null; + }; } @Override diff --git a/src/main/java/org/traccar/protocol/BstplProtocolDecoder.java b/src/main/java/org/traccar/protocol/BstplProtocolDecoder.java index 15c114642..5dee16cba 100644 --- a/src/main/java/org/traccar/protocol/BstplProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/BstplProtocolDecoder.java @@ -61,20 +61,14 @@ public class BstplProtocolDecoder extends BaseProtocolDecoder { .compile(); private String decodeAlarm(int value) { - switch (value) { - case 4: - return Position.ALARM_LOW_BATTERY; - case 5: - return Position.ALARM_ACCELERATION; - case 6: - return Position.ALARM_BRAKING; - case 7: - return Position.ALARM_OVERSPEED; - case 9: - return Position.ALARM_SOS; - default: - return null; - } + return switch (value) { + case 4 -> Position.ALARM_LOW_BATTERY; + case 5 -> Position.ALARM_ACCELERATION; + case 6 -> Position.ALARM_BRAKING; + case 7 -> Position.ALARM_OVERSPEED; + case 9 -> Position.ALARM_SOS; + default -> null; + }; } @Override protected Object decode( diff --git a/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java b/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java index aef158fc7..908f5d0f3 100644 --- a/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/C2stekProtocolDecoder.java @@ -60,24 +60,16 @@ public class C2stekProtocolDecoder extends BaseProtocolDecoder { .compile(); private String decodeAlarm(int alarm) { - switch (alarm) { - case 0x2: - return Position.ALARM_VIBRATION; - case 0x3: - return Position.ALARM_POWER_CUT; - case 0x4: - return Position.ALARM_OVERSPEED; - case 0x5: - return Position.ALARM_SOS; - case 0x6: - return Position.ALARM_DOOR; - case 0xA: - return Position.ALARM_LOW_BATTERY; - case 0xB: - return Position.ALARM_FAULT; - default: - return null; - } + return switch (alarm) { + case 0x2 -> Position.ALARM_VIBRATION; + case 0x3 -> Position.ALARM_POWER_CUT; + case 0x4 -> Position.ALARM_OVERSPEED; + case 0x5 -> Position.ALARM_SOS; + case 0x6 -> Position.ALARM_DOOR; + case 0xA -> Position.ALARM_LOW_BATTERY; + case 0xB -> Position.ALARM_FAULT; + default -> null; + }; } @Override diff --git a/src/main/java/org/traccar/protocol/CarcellProtocolEncoder.java b/src/main/java/org/traccar/protocol/CarcellProtocolEncoder.java index 78dbe7e91..7a460b7c4 100644 --- a/src/main/java/org/traccar/protocol/CarcellProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/CarcellProtocolEncoder.java @@ -28,14 +28,11 @@ public class CarcellProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_ENGINE_STOP: - return formatCommand(command, "$SRVCMD,%s,BA#\r\n", Command.KEY_UNIQUE_ID); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "$SRVCMD,%s,BD#\r\n", Command.KEY_UNIQUE_ID); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_ENGINE_STOP -> formatCommand(command, "$SRVCMD,%s,BA#\r\n", Command.KEY_UNIQUE_ID); + case Command.TYPE_ENGINE_RESUME -> formatCommand(command, "$SRVCMD,%s,BD#\r\n", Command.KEY_UNIQUE_ID); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java index b076b9f66..5cabeb5a4 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CastelProtocolDecoder.java @@ -162,20 +162,12 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { if (!PID_LENGTH_MAP.containsKey(pids[i])) { throw new RuntimeException(String.format("Unknown PID 0x%02x", pids[i])); } - switch (PID_LENGTH_MAP.get(pids[i])) { - case 1: - value = buf.readUnsignedByte(); - break; - case 2: - value = buf.readUnsignedShortLE(); - break; - case 4: - value = buf.readIntLE(); - break; - default: - value = 0; - break; - } + value = switch (PID_LENGTH_MAP.get(pids[i])) { + case 1 -> buf.readUnsignedByte(); + case 2 -> buf.readUnsignedShortLE(); + case 4 -> buf.readIntLE(); + default -> 0; + }; position.add(ObdDecoder.decodeData(pids[i], value, false)); } } @@ -250,62 +242,24 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { private void decodeAlarm(Position position, int alarm) { switch (alarm) { - case 0x01: - position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); - break; - case 0x02: - position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); - break; - case 0x03: - position.set(Position.KEY_ALARM, Position.ALARM_TEMPERATURE); - break; - case 0x04: - position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - break; - case 0x05: - position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); - break; - case 0x06: - position.set(Position.KEY_ALARM, Position.ALARM_IDLE); - break; - case 0x07: - position.set(Position.KEY_ALARM, Position.ALARM_TOW); - break; - case 0x08: - position.set(Position.KEY_ALARM, Position.ALARM_HIGH_RPM); - break; - case 0x09: - position.set(Position.KEY_ALARM, Position.ALARM_POWER_ON); - break; - case 0x0B: - position.set(Position.KEY_ALARM, Position.ALARM_LANE_CHANGE); - break; - case 0x0C: - position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); - break; - case 0x0D: - position.set(Position.KEY_ALARM, Position.ALARM_FATIGUE_DRIVING); - break; - case 0x0E: - position.set(Position.KEY_ALARM, Position.ALARM_POWER_OFF); - break; - case 0x11: - position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); - break; - case 0x12: - position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); - break; - case 0x16: - position.set(Position.KEY_IGNITION, true); - break; - case 0x17: - position.set(Position.KEY_IGNITION, false); - break; - case 0x1C: - position.set(Position.KEY_ALARM, Position.ALARM_VIBRATION); - break; - default: - break; + case 0x01 -> position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); + case 0x02 -> position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); + case 0x03 -> position.set(Position.KEY_ALARM, Position.ALARM_TEMPERATURE); + case 0x04 -> position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + case 0x05 -> position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + case 0x06 -> position.set(Position.KEY_ALARM, Position.ALARM_IDLE); + case 0x07 -> position.set(Position.KEY_ALARM, Position.ALARM_TOW); + case 0x08 -> position.set(Position.KEY_ALARM, Position.ALARM_HIGH_RPM); + case 0x09 -> position.set(Position.KEY_ALARM, Position.ALARM_POWER_ON); + case 0x0B -> position.set(Position.KEY_ALARM, Position.ALARM_LANE_CHANGE); + case 0x0C -> position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + case 0x0D -> position.set(Position.KEY_ALARM, Position.ALARM_FATIGUE_DRIVING); + case 0x0E -> position.set(Position.KEY_ALARM, Position.ALARM_POWER_OFF); + case 0x11 -> position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); + case 0x12 -> position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); + case 0x16 -> position.set(Position.KEY_IGNITION, true); + case 0x17 -> position.set(Position.KEY_IGNITION, false); + case 0x1C -> position.set(Position.KEY_ALARM, Position.ALARM_VIBRATION); } } @@ -623,15 +577,11 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { return null; } - switch (version) { - case -1: - return decodeMpip(channel, remoteAddress, buf, version, id, type, deviceSession); - case 3: - case 4: - return decodeSc(channel, remoteAddress, buf, version, id, type, deviceSession); - default: - return decodeCc(channel, remoteAddress, buf, version, id, type, deviceSession); - } + return switch (version) { + case -1 -> decodeMpip(channel, remoteAddress, buf, version, id, type, deviceSession); + case 3, 4 -> decodeSc(channel, remoteAddress, buf, version, id, type, deviceSession); + default -> decodeCc(channel, remoteAddress, buf, version, id, type, deviceSession); + }; } } diff --git a/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java b/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java index 61dde3e80..867db7a09 100644 --- a/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/CastelProtocolEncoder.java @@ -59,16 +59,17 @@ public class CastelProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { ByteBuf content = Unpooled.buffer(0); - switch (command.getType()) { - case Command.TYPE_ENGINE_STOP: + return switch (command.getType()) { + case Command.TYPE_ENGINE_STOP -> { content.writeByte(1); - return encodeContent(command.getDeviceId(), CastelProtocolDecoder.MSG_CC_PETROL_CONTROL, content); - case Command.TYPE_ENGINE_RESUME: + yield encodeContent(command.getDeviceId(), CastelProtocolDecoder.MSG_CC_PETROL_CONTROL, content); + } + case Command.TYPE_ENGINE_RESUME -> { content.writeByte(0); - return encodeContent(command.getDeviceId(), CastelProtocolDecoder.MSG_CC_PETROL_CONTROL, content); - default: - return null; - } + yield encodeContent(command.getDeviceId(), CastelProtocolDecoder.MSG_CC_PETROL_CONTROL, content); + } + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/CellocatorFrameDecoder.java b/src/main/java/org/traccar/protocol/CellocatorFrameDecoder.java index ee2adde6d..6dc299c7a 100644 --- a/src/main/java/org/traccar/protocol/CellocatorFrameDecoder.java +++ b/src/main/java/org/traccar/protocol/CellocatorFrameDecoder.java @@ -35,28 +35,20 @@ public class CellocatorFrameDecoder extends BaseFrameDecoder { int length = 0; int type = buf.getUnsignedByte(4); switch (type) { - case CellocatorProtocolDecoder.MSG_CLIENT_STATUS: - length = 70; - break; - case CellocatorProtocolDecoder.MSG_CLIENT_PROGRAMMING: - length = 31; - break; - case CellocatorProtocolDecoder.MSG_CLIENT_SERIAL_LOG: - length = 70; - break; - case CellocatorProtocolDecoder.MSG_CLIENT_SERIAL: + case CellocatorProtocolDecoder.MSG_CLIENT_STATUS -> length = 70; + case CellocatorProtocolDecoder.MSG_CLIENT_PROGRAMMING -> length = 31; + case CellocatorProtocolDecoder.MSG_CLIENT_SERIAL_LOG -> length = 70; + case CellocatorProtocolDecoder.MSG_CLIENT_SERIAL -> { if (buf.readableBytes() >= 19) { length = 19 + buf.getUnsignedShortLE(buf.readerIndex() + 16); } - break; - case CellocatorProtocolDecoder.MSG_CLIENT_MODULAR: + } + case CellocatorProtocolDecoder.MSG_CLIENT_MODULAR -> { length = 15 + buf.getUnsignedByte(buf.readerIndex() + 13); - break; - case CellocatorProtocolDecoder.MSG_CLIENT_MODULAR_EXT: + } + case CellocatorProtocolDecoder.MSG_CLIENT_MODULAR_EXT -> { length = 16 + buf.getUnsignedShortLE(buf.readerIndex() + 13); - break; - default: - break; + } } if (length > 0 && buf.readableBytes() >= length) { diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java index 3573a95ca..27fc8452c 100644 --- a/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CellocatorProtocolDecoder.java @@ -95,16 +95,12 @@ public class CellocatorProtocolDecoder extends BaseProtocolDecoder { } private String decodeAlarm(short reason) { - switch (reason) { - case 70: - return Position.ALARM_SOS; - case 80: - return Position.ALARM_POWER_CUT; - case 81: - return Position.ALARM_LOW_POWER; - default: - return null; - } + return switch (reason) { + case 70 -> Position.ALARM_SOS; + case 80 -> Position.ALARM_POWER_CUT; + case 81 -> Position.ALARM_LOW_POWER; + default -> null; + }; } private Position decodeStatus(ByteBuf buf, DeviceSession deviceSession, boolean alternative) { diff --git a/src/main/java/org/traccar/protocol/CellocatorProtocolEncoder.java b/src/main/java/org/traccar/protocol/CellocatorProtocolEncoder.java index 76fa67686..738eabbb2 100644 --- a/src/main/java/org/traccar/protocol/CellocatorProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/CellocatorProtocolEncoder.java @@ -69,14 +69,12 @@ public class CellocatorProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_OUTPUT_CONTROL: - int data = Integer.parseInt(command.getString(Command.KEY_DATA)) << 4 - + command.getInteger(Command.KEY_INDEX); - return encodeCommand(command.getDeviceId(), 0x03, data, 0); - default: - return null; + if (command.getType().equals(Command.TYPE_OUTPUT_CONTROL)) { + int data = Integer.parseInt(command.getString(Command.KEY_DATA)) << 4 + + command.getInteger(Command.KEY_INDEX); + return encodeCommand(command.getDeviceId(), 0x03, data, 0); } + return null; } } diff --git a/src/main/java/org/traccar/protocol/CguardProtocolDecoder.java b/src/main/java/org/traccar/protocol/CguardProtocolDecoder.java index 90f8e0caf..fef90dbb5 100644 --- a/src/main/java/org/traccar/protocol/CguardProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/CguardProtocolDecoder.java @@ -94,25 +94,17 @@ public class CguardProtocolDecoder extends BaseProtocolDecoder { String key = data[i * 2]; String value = data[i * 2 + 1]; switch (key) { - case "CSQ1": - position.set(Position.KEY_RSSI, Integer.parseInt(value)); - break; - case "NSQ1": - position.set(Position.KEY_SATELLITES, Integer.parseInt(value)); - break; - case "BAT1": + case "CSQ1" -> position.set(Position.KEY_RSSI, Integer.parseInt(value)); + case "NSQ1" -> position.set(Position.KEY_SATELLITES, Integer.parseInt(value)); + case "BAT1" -> { if (value.contains(".")) { position.set(Position.KEY_BATTERY, Double.parseDouble(value)); } else { position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(value)); } - break; - case "PWR1": - position.set(Position.KEY_POWER, Double.parseDouble(value)); - break; - default: - position.set(key.toLowerCase(), value); - break; + } + case "PWR1" -> position.set(Position.KEY_POWER, Double.parseDouble(value)); + default -> position.set(key.toLowerCase(), value); } } diff --git a/src/main/java/org/traccar/protocol/CityeasyProtocolEncoder.java b/src/main/java/org/traccar/protocol/CityeasyProtocolEncoder.java index 934105862..563d13206 100644 --- a/src/main/java/org/traccar/protocol/CityeasyProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/CityeasyProtocolEncoder.java @@ -53,15 +53,18 @@ public class CityeasyProtocolEncoder extends BaseProtocolEncoder { ByteBuf content = Unpooled.buffer(); switch (command.getType()) { - case Command.TYPE_POSITION_SINGLE: + case Command.TYPE_POSITION_SINGLE -> { return encodeContent(CityeasyProtocolDecoder.MSG_LOCATION_REQUEST, content); - case Command.TYPE_POSITION_PERIODIC: + } + case Command.TYPE_POSITION_PERIODIC -> { content.writeShort(command.getInteger(Command.KEY_FREQUENCY)); return encodeContent(CityeasyProtocolDecoder.MSG_LOCATION_INTERVAL, content); - case Command.TYPE_POSITION_STOP: + } + case Command.TYPE_POSITION_STOP -> { content.writeShort(0); return encodeContent(CityeasyProtocolDecoder.MSG_LOCATION_INTERVAL, content); - case Command.TYPE_SET_TIMEZONE: + } + case Command.TYPE_SET_TIMEZONE -> { int timezone = TimeZone.getTimeZone(command.getString(Command.KEY_TIMEZONE)).getRawOffset() / 60000; if (timezone < 0) { content.writeByte(1); @@ -70,8 +73,10 @@ public class CityeasyProtocolEncoder extends BaseProtocolEncoder { } content.writeShort(Math.abs(timezone)); return encodeContent(CityeasyProtocolDecoder.MSG_TIMEZONE, content); - default: + } + default -> { return null; + } } } diff --git a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java index c2e617a2a..672848174 100644 --- a/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DmtHttpProtocolDecoder.java @@ -199,15 +199,9 @@ public class DmtHttpProtocolDecoder extends BaseHttpProtocolDecoder { for (int i = 0; i < counters.size(); i++) { JsonObject counter = counters.getJsonObject(i); switch (counter.getInt("id")) { - case 0: - position.set(Position.KEY_BATTERY, counter.getInt("val") * 0.001); - break; - case 1: - position.set(Position.KEY_BATTERY_LEVEL, counter.getInt("val") * 0.01); - break; - default: - position.set("counter" + counter.getInt("id"), counter.getInt("val")); - break; + case 0 -> position.set(Position.KEY_BATTERY, counter.getInt("val") * 0.001); + case 1 -> position.set(Position.KEY_BATTERY_LEVEL, counter.getInt("val") * 0.01); + default -> position.set("counter" + counter.getInt("id"), counter.getInt("val")); } } diff --git a/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java b/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java index 320aa1b60..a18e8bc53 100644 --- a/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DmtProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 - 2021 Anton Tananaev (anton@traccar.org) + * Copyright 2017 - 2024 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -151,7 +151,9 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { position.setDeviceTime(new Date(1356998400000L + buf.readUnsignedIntLE() * 1000)); // since 1 Jan 2013 - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); + int event = buf.readUnsignedByte(); + position.set(Position.KEY_ALARM, decodeAlarm(event)); + position.set(Position.KEY_EVENT, event); while (buf.readerIndex() < recordEnd) { @@ -199,24 +201,12 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { while (buf.readerIndex() < fieldEnd) { int number = buf.readUnsignedByte(); switch (number) { - case 1: - position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.001); - break; - case 2: - position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.01); - break; - case 3: - position.set(Position.KEY_DEVICE_TEMP, buf.readShortLE() * 0.01); - break; - case 4: - position.set(Position.KEY_RSSI, buf.readUnsignedShortLE()); - break; - case 5: - position.set("solarPower", buf.readUnsignedShortLE() * 0.001); - break; - default: - position.set(Position.PREFIX_IO + number, buf.readUnsignedShortLE()); - break; + case 1 -> position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.001); + case 2 -> position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.01); + case 3 -> position.set(Position.KEY_DEVICE_TEMP, buf.readShortLE() * 0.01); + case 4 -> position.set(Position.KEY_RSSI, buf.readUnsignedShortLE()); + case 5 -> position.set("solarPower", buf.readUnsignedShortLE() * 0.001); + default -> position.set(Position.PREFIX_IO + number, buf.readUnsignedShortLE()); } } @@ -246,6 +236,21 @@ public class DmtProtocolDecoder extends BaseProtocolDecoder { return positions; } + private String decodeAlarm(int value) { + return switch (value) { + case 12 -> Position.ALARM_BRAKING; + case 13 -> Position.ALARM_ACCELERATION; + case 14 -> Position.ALARM_CORNERING; + case 18 -> Position.ALARM_OVERSPEED; + case 20 -> Position.ALARM_TOW; + case 23 -> Position.ALARM_ACCIDENT; + case 29 -> Position.ALARM_TAMPERING; + case 44 -> Position.ALARM_GEOFENCE_ENTER; + case 45 -> Position.ALARM_GEOFENCE_EXIT; + default -> null; + }; + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { diff --git a/src/main/java/org/traccar/protocol/EasyTrackProtocolEncoder.java b/src/main/java/org/traccar/protocol/EasyTrackProtocolEncoder.java index 3f2a142d6..124c3e0a3 100644 --- a/src/main/java/org/traccar/protocol/EasyTrackProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/EasyTrackProtocolEncoder.java @@ -28,18 +28,13 @@ public class EasyTrackProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_ENGINE_STOP: - return formatCommand(command, "*ET,%s,FD,Y1#", Command.KEY_UNIQUE_ID); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "*ET,%s,FD,Y2#", Command.KEY_UNIQUE_ID); - case Command.TYPE_ALARM_ARM: - return formatCommand(command, "*ET,%s,FD,F1#", Command.KEY_UNIQUE_ID); - case Command.TYPE_ALARM_DISARM: - return formatCommand(command, "*ET,%s,FD,F2#", Command.KEY_UNIQUE_ID); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_ENGINE_STOP -> formatCommand(command, "*ET,%s,FD,Y1#", Command.KEY_UNIQUE_ID); + case Command.TYPE_ENGINE_RESUME -> formatCommand(command, "*ET,%s,FD,Y2#", Command.KEY_UNIQUE_ID); + case Command.TYPE_ALARM_ARM -> formatCommand(command, "*ET,%s,FD,F1#", Command.KEY_UNIQUE_ID); + case Command.TYPE_ALARM_DISARM -> formatCommand(command, "*ET,%s,FD,F2#", Command.KEY_UNIQUE_ID); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java index db1b365c3..f1cc43394 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocolDecoder.java @@ -67,35 +67,21 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_CAMERA_DATA = 0x1F; private String decodeAlarm(Short value) { - switch (value) { - case 0x01: - return Position.ALARM_POWER_OFF; - case 0x02: - return Position.ALARM_SOS; - case 0x03: - return Position.ALARM_LOW_BATTERY; - case 0x04: - return Position.ALARM_VIBRATION; - case 0x08: - case 0x09: - return Position.ALARM_GPS_ANTENNA_CUT; - case 0x25: - return Position.ALARM_REMOVING; - case 0x81: - return Position.ALARM_LOW_SPEED; - case 0x82: - return Position.ALARM_OVERSPEED; - case 0x83: - return Position.ALARM_GEOFENCE_ENTER; - case 0x84: - return Position.ALARM_GEOFENCE_EXIT; - case 0x85: - return Position.ALARM_ACCIDENT; - case 0x86: - return Position.ALARM_FALL_DOWN; - default: - return null; - } + return switch (value) { + case 0x01 -> Position.ALARM_POWER_OFF; + case 0x02 -> Position.ALARM_SOS; + case 0x03 -> Position.ALARM_LOW_BATTERY; + case 0x04 -> Position.ALARM_VIBRATION; + case 0x08, 0x09 -> Position.ALARM_GPS_ANTENNA_CUT; + case 0x25 -> Position.ALARM_REMOVING; + case 0x81 -> Position.ALARM_LOW_SPEED; + case 0x82 -> Position.ALARM_OVERSPEED; + case 0x83 -> Position.ALARM_GEOFENCE_ENTER; + case 0x84 -> Position.ALARM_GEOFENCE_EXIT; + case 0x85 -> Position.ALARM_ACCIDENT; + case 0x86 -> Position.ALARM_FALL_DOWN; + default -> null; + }; } private void decodeStatus(Position position, int status) { @@ -407,17 +393,9 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { int pid = buf.readUnsignedByte(); int value = buf.readInt(); switch (pid) { - case 0x89: - position.set(Position.KEY_FUEL_CONSUMPTION, value); - break; - case 0x8a: - position.set(Position.KEY_ODOMETER, value * 1000L); - break; - case 0x8b: - position.set(Position.KEY_FUEL_LEVEL, value / 10); - break; - default: - break; + case 0x89 -> position.set(Position.KEY_FUEL_CONSUMPTION, value); + case 0x8a -> position.set(Position.KEY_ODOMETER, value * 1000L); + case 0x8b -> position.set(Position.KEY_FUEL_LEVEL, value / 10); } } diff --git a/src/main/java/org/traccar/protocol/EelinkProtocolEncoder.java b/src/main/java/org/traccar/protocol/EelinkProtocolEncoder.java index 3673c35b3..d3f7aa30b 100644 --- a/src/main/java/org/traccar/protocol/EelinkProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/EelinkProtocolEncoder.java @@ -90,20 +90,14 @@ public class EelinkProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return encodeContent(command.getDeviceId(), command.getString(Command.KEY_DATA)); - case Command.TYPE_POSITION_SINGLE: - return encodeContent(command.getDeviceId(), "WHERE#"); - case Command.TYPE_ENGINE_STOP: - return encodeContent(command.getDeviceId(), "RELAY,1#"); - case Command.TYPE_ENGINE_RESUME: - return encodeContent(command.getDeviceId(), "RELAY,0#"); - case Command.TYPE_REBOOT_DEVICE: - return encodeContent(command.getDeviceId(), "RESET#"); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_CUSTOM -> encodeContent(command.getDeviceId(), command.getString(Command.KEY_DATA)); + case Command.TYPE_POSITION_SINGLE -> encodeContent(command.getDeviceId(), "WHERE#"); + case Command.TYPE_ENGINE_STOP -> encodeContent(command.getDeviceId(), "RELAY,1#"); + case Command.TYPE_ENGINE_RESUME -> encodeContent(command.getDeviceId(), "RELAY,0#"); + case Command.TYPE_REBOOT_DEVICE -> encodeContent(command.getDeviceId(), "RESET#"); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/EnforaProtocolEncoder.java b/src/main/java/org/traccar/protocol/EnforaProtocolEncoder.java index 8cc24dc0f..7cd10a2ed 100644 --- a/src/main/java/org/traccar/protocol/EnforaProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/EnforaProtocolEncoder.java @@ -45,16 +45,12 @@ public class EnforaProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return encodeContent(command.getString(Command.KEY_DATA)); - case Command.TYPE_ENGINE_STOP: - return encodeContent("AT$IOGP3=1"); - case Command.TYPE_ENGINE_RESUME: - return encodeContent("AT$IOGP3=0"); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_CUSTOM -> encodeContent(command.getString(Command.KEY_DATA)); + case Command.TYPE_ENGINE_STOP -> encodeContent("AT$IOGP3=1"); + case Command.TYPE_ENGINE_RESUME -> encodeContent("AT$IOGP3=0"); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java index 750ff2bda..f4d1f5747 100644 --- a/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EnvotechProtocolDecoder.java @@ -75,14 +75,8 @@ public class EnvotechProtocolDecoder extends BaseProtocolDecoder { int event = parser.nextHexInt(); switch (event) { - case 0x60: - position.set(Position.KEY_ALARM, Position.ALARM_LOCK); - break; - case 0x61: - position.set(Position.KEY_ALARM, Position.ALARM_UNLOCK); - break; - default: - break; + case 0x60 -> position.set(Position.KEY_ALARM, Position.ALARM_LOCK); + case 0x61 -> position.set(Position.KEY_ALARM, Position.ALARM_UNLOCK); } position.set(Position.KEY_EVENT, event); diff --git a/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java b/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java index dd15c4276..7958265c3 100644 --- a/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/EsealProtocolDecoder.java @@ -74,20 +74,14 @@ public class EsealProtocolDecoder extends BaseProtocolDecoder { } private String decodeAlarm(String type) { - switch (type) { - case "Event-Door": - return Position.ALARM_DOOR; - case "Event-Shock": - return Position.ALARM_VIBRATION; - case "Event-Drop": - return Position.ALARM_FALL_DOWN; - case "Event-Lock": - return Position.ALARM_LOCK; - case "Event-RC-Unlock": - return Position.ALARM_UNLOCK; - default: - return null; - } + return switch (type) { + case "Event-Door" -> Position.ALARM_DOOR; + case "Event-Shock" -> Position.ALARM_VIBRATION; + case "Event-Drop" -> Position.ALARM_FALL_DOWN; + case "Event-Lock" -> Position.ALARM_LOCK; + case "Event-RC-Unlock" -> Position.ALARM_UNLOCK; + default -> null; + }; } @Override @@ -141,14 +135,8 @@ public class EsealProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt())); switch (parser.next()) { - case "Open": - position.set(Position.KEY_DOOR, true); - break; - case "Close": - position.set(Position.KEY_DOOR, false); - break; - default: - break; + case "Open" -> position.set(Position.KEY_DOOR, true); + case "Close" -> position.set(Position.KEY_DOOR, false); } position.set(Position.KEY_ACCELERATION, parser.nextDouble()); diff --git a/src/main/java/org/traccar/protocol/EsealProtocolEncoder.java b/src/main/java/org/traccar/protocol/EsealProtocolEncoder.java index 74f9e22ab..4af36b245 100644 --- a/src/main/java/org/traccar/protocol/EsealProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/EsealProtocolEncoder.java @@ -28,19 +28,15 @@ public class EsealProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return formatCommand( - command, "##S,eSeal,%s,256,3.0.8,%s,E##", Command.KEY_UNIQUE_ID, Command.KEY_DATA); - case Command.TYPE_ALARM_ARM: - return formatCommand( - command, "##S,eSeal,%s,256,3.0.8,RC-Power Control,Power OFF,E##", Command.KEY_UNIQUE_ID); - case Command.TYPE_ALARM_DISARM: - return formatCommand( - command, "##S,eSeal,%s,256,3.0.8,RC-Unlock,E##", Command.KEY_UNIQUE_ID); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_CUSTOM -> formatCommand( + command, "##S,eSeal,%s,256,3.0.8,%s,E##", Command.KEY_UNIQUE_ID, Command.KEY_DATA); + case Command.TYPE_ALARM_ARM -> formatCommand( + command, "##S,eSeal,%s,256,3.0.8,RC-Power Control,Power OFF,E##", Command.KEY_UNIQUE_ID); + case Command.TYPE_ALARM_DISARM -> formatCommand( + command, "##S,eSeal,%s,256,3.0.8,RC-Unlock,E##", Command.KEY_UNIQUE_ID); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java index 59019830f..0a0392acd 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocolDecoder.java @@ -157,50 +157,28 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { private String decodeAlarm(Integer alarm) { if (alarm != null) { - switch (alarm) { - case 2: - return Position.ALARM_SOS; - case 14: - return Position.ALARM_LOW_POWER; - case 15: - return Position.ALARM_POWER_CUT; - case 16: - return Position.ALARM_POWER_RESTORED; - case 17: - return Position.ALARM_LOW_BATTERY; - case 18: - return Position.ALARM_OVERSPEED; - case 20: - return Position.ALARM_GPS_ANTENNA_CUT; - case 21: - return Position.ALARM_VIBRATION; - case 23: - return Position.ALARM_ACCELERATION; - case 24: - return Position.ALARM_BRAKING; - case 27: - return Position.ALARM_FATIGUE_DRIVING; - case 30: - case 32: - return Position.ALARM_JAMMING; - case 31: - return Position.ALARM_FALL_DOWN; - case 33: - return Position.ALARM_GEOFENCE_EXIT; - case 34: - return Position.ALARM_GEOFENCE_ENTER; - case 35: - return Position.ALARM_IDLE; - case 40: - case 41: - return Position.ALARM_TEMPERATURE; - case 53: - return Position.ALARM_POWER_ON; - case 54: - return Position.ALARM_POWER_OFF; - default: - return null; - } + return switch (alarm) { + case 2 -> Position.ALARM_SOS; + case 14 -> Position.ALARM_LOW_POWER; + case 15 -> Position.ALARM_POWER_CUT; + case 16 -> Position.ALARM_POWER_RESTORED; + case 17 -> Position.ALARM_LOW_BATTERY; + case 18 -> Position.ALARM_OVERSPEED; + case 20 -> Position.ALARM_GPS_ANTENNA_CUT; + case 21 -> Position.ALARM_VIBRATION; + case 23 -> Position.ALARM_ACCELERATION; + case 24 -> Position.ALARM_BRAKING; + case 27 -> Position.ALARM_FATIGUE_DRIVING; + case 30, 32 -> Position.ALARM_JAMMING; + case 31 -> Position.ALARM_FALL_DOWN; + case 33 -> Position.ALARM_GEOFENCE_EXIT; + case 34 -> Position.ALARM_GEOFENCE_ENTER; + case 35 -> Position.ALARM_IDLE; + case 40, 41 -> Position.ALARM_TEMPERATURE; + case 53 -> Position.ALARM_POWER_ON; + case 54 -> Position.ALARM_POWER_OFF; + default -> null; + }; } return null; } diff --git a/src/main/java/org/traccar/protocol/FifotrackProtocolEncoder.java b/src/main/java/org/traccar/protocol/FifotrackProtocolEncoder.java index a4e69b47b..2c01fc691 100644 --- a/src/main/java/org/traccar/protocol/FifotrackProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/FifotrackProtocolEncoder.java @@ -37,14 +37,11 @@ public class FifotrackProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return formatCommand(command, command.getString(Command.KEY_DATA)); - case Command.TYPE_REQUEST_PHOTO: - return formatCommand(command, "D05,3"); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_CUSTOM -> formatCommand(command, command.getString(Command.KEY_DATA)); + case Command.TYPE_REQUEST_PHOTO -> formatCommand(command, "D05,3"); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/FleetGuideProtocolDecoder.java b/src/main/java/org/traccar/protocol/FleetGuideProtocolDecoder.java index 8f679525b..6163a24c8 100644 --- a/src/main/java/org/traccar/protocol/FleetGuideProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FleetGuideProtocolDecoder.java @@ -205,17 +205,9 @@ public class FleetGuideProtocolDecoder extends BaseProtocolDecoder { case 18: int sensorIndex = data.readUnsignedByte(); switch (recordLength - 1) { - case 1: - position.set("sensor" + sensorIndex, data.readUnsignedByte()); - break; - case 2: - position.set("sensor" + sensorIndex, data.readUnsignedShortLE()); - break; - case 4: - position.set("sensor" + sensorIndex, data.readUnsignedIntLE()); - break; - default: - break; + case 1 -> position.set("sensor" + sensorIndex, data.readUnsignedByte()); + case 2 -> position.set("sensor" + sensorIndex, data.readUnsignedShortLE()); + case 4 -> position.set("sensor" + sensorIndex, data.readUnsignedIntLE()); } break; default: diff --git a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java index ea076afd8..e6ea994df 100644 --- a/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlespiProtocolDecoder.java @@ -93,169 +93,205 @@ public class FlespiProtocolDecoder extends BaseHttpProtocolDecoder { } private boolean decodeParam(String name, int index, JsonValue value, Position position) { - switch (name) { - case "timestamp": + return switch (name) { + case "timestamp" -> { position.setTime(new Date(((JsonNumber) value).longValue() * 1000)); - return true; - case "position.latitude": + yield true; + } + case "position.latitude" -> { position.setLatitude(((JsonNumber) value).doubleValue()); - return true; - case "position.longitude": + yield true; + } + case "position.longitude" -> { position.setLongitude(((JsonNumber) value).doubleValue()); - return true; - case "position.speed": + yield true; + } + case "position.speed" -> { position.setSpeed(UnitsConverter.knotsFromKph(((JsonNumber) value).doubleValue())); - return true; - case "position.direction": + yield true; + } + case "position.direction" -> { position.setCourse(((JsonNumber) value).doubleValue()); - return true; - case "position.altitude": + yield true; + } + case "position.altitude" -> { position.setAltitude(((JsonNumber) value).doubleValue()); - return true; - case "position.satellites": + yield true; + } + case "position.satellites" -> { position.set(Position.KEY_SATELLITES, ((JsonNumber) value).intValue()); - return true; - case "position.valid": + yield true; + } + case "position.valid" -> { position.setValid(value == JsonValue.TRUE); - return true; - case "position.hdop": + yield true; + } + case "position.hdop" -> { position.set(Position.KEY_HDOP, ((JsonNumber) value).doubleValue()); - return true; - case "position.pdop": + yield true; + } + case "position.pdop" -> { position.set(Position.KEY_PDOP, ((JsonNumber) value).doubleValue()); - return true; - case "din": + yield true; + } + case "din" -> { position.set(Position.KEY_INPUT, ((JsonNumber) value).intValue()); - return true; - case "dout": + yield true; + } + case "dout" -> { position.set(Position.KEY_OUTPUT, ((JsonNumber) value).intValue()); - return true; - case "report.reason": + yield true; + } + case "report.reason" -> { position.set(Position.KEY_EVENT, ((JsonNumber) value).intValue()); - return true; - case "gps.vehicle.mileage": + yield true; + } + case "gps.vehicle.mileage" -> { position.set(Position.KEY_ODOMETER, ((JsonNumber) value).doubleValue()); - return true; - case "external.powersource.voltage": + yield true; + } + case "external.powersource.voltage" -> { position.set(Position.KEY_POWER, ((JsonNumber) value).doubleValue()); - return true; - case "battery.voltage": + yield true; + } + case "battery.voltage" -> { position.set(Position.KEY_BATTERY, ((JsonNumber) value).doubleValue()); - return true; - case "battery.level": + yield true; + } + case "battery.level" -> { position.set(Position.KEY_BATTERY_LEVEL, ((JsonNumber) value).intValue()); - return true; - case "fuel.level": - case "can.fuel.level": + yield true; + } + case "fuel.level", "can.fuel.level" -> { position.set(Position.KEY_FUEL_LEVEL, ((JsonNumber) value).doubleValue()); - return true; - case "engine.rpm": - case "can.engine.rpm": + yield true; + } + case "engine.rpm", "can.engine.rpm" -> { position.set(Position.KEY_RPM, ((JsonNumber) value).doubleValue()); - return true; - case "can.engine.temperature": + yield true; + } + case "can.engine.temperature" -> { position.set(Position.PREFIX_TEMP + Math.max(index, 0), ((JsonNumber) value).doubleValue()); - return true; - case "engine.ignition.status": + yield true; + } + case "engine.ignition.status" -> { position.set(Position.KEY_IGNITION, value == JsonValue.TRUE); - return true; - case "movement.status": + yield true; + } + case "movement.status" -> { position.set(Position.KEY_MOTION, value == JsonValue.TRUE); - return true; - case "device.temperature": + yield true; + } + case "device.temperature" -> { position.set(Position.KEY_DEVICE_TEMP, ((JsonNumber) value).doubleValue()); - return true; - case "ibutton.code": + yield true; + } + case "ibutton.code" -> { position.set(Position.KEY_DRIVER_UNIQUE_ID, ((JsonString) value).getString()); - return true; - case "vehicle.vin": + yield true; + } + case "vehicle.vin" -> { position.set(Position.KEY_VIN, ((JsonString) value).getString()); - return true; - case "alarm.event.trigger": + yield true; + } + case "alarm.event.trigger" -> { if (value == JsonValue.TRUE) { position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); } - return true; - case "towing.event.trigger": - case "towing.alarm.status": + yield true; + } + case "towing.event.trigger", "towing.alarm.status" -> { if (value == JsonValue.TRUE) { position.set(Position.KEY_ALARM, Position.ALARM_TOW); } - return true; - case "geofence.event.enter": + yield true; + } + case "geofence.event.enter" -> { if (value == JsonValue.TRUE) { position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE_ENTER); } - return true; - case "geofence.event.exit": + yield true; + } + case "geofence.event.exit" -> { if (value == JsonValue.TRUE) { position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE_EXIT); } - return true; - case "shock.event.trigger": + yield true; + } + case "shock.event.trigger" -> { if (value == JsonValue.TRUE) { position.set(Position.KEY_ALARM, Position.ALARM_VIBRATION); } - return true; - case "overspeeding.event.trigger": + yield true; + } + case "overspeeding.event.trigger" -> { if (value == JsonValue.TRUE) { position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); } - return true; - case "harsh.acceleration.event.trigger": + yield true; + } + case "harsh.acceleration.event.trigger" -> { if (value == JsonValue.TRUE) { position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); } - return true; - case "harsh.braking.event.trigger": + yield true; + } + case "harsh.braking.event.trigger" -> { if (value == JsonValue.TRUE) { position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); } - return true; - case "harsh.cornering.event.trigger": + yield true; + } + case "harsh.cornering.event.trigger" -> { if (value == JsonValue.TRUE) { position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); } - return true; - case "gnss.antenna.cut.status": + yield true; + } + case "gnss.antenna.cut.status" -> { if (value == JsonValue.TRUE) { position.set(Position.KEY_ALARM, Position.ALARM_GPS_ANTENNA_CUT); } - return true; - case "gsm.jamming.event.trigger": + yield true; + } + case "gsm.jamming.event.trigger" -> { if (value == JsonValue.TRUE) { position.set(Position.KEY_ALARM, Position.ALARM_JAMMING); } - return true; - case "hood.open.status": + yield true; + } + case "hood.open.status" -> { if (value == JsonValue.TRUE) { position.set(Position.KEY_ALARM, Position.ALARM_BONNET); } - return true; - case "custom.wln_accel_max": + yield true; + } + case "custom.wln_accel_max" -> { position.set("maxAcceleration", ((JsonNumber) value).doubleValue()); - return true; - case "custom.wln_brk_max": + yield true; + } + case "custom.wln_brk_max" -> { position.set("maxBraking", ((JsonNumber) value).doubleValue()); - return true; - case "custom.wln_crn_max": + yield true; + } + case "custom.wln_crn_max" -> { position.set("maxCornering", ((JsonNumber) value).doubleValue()); - return true; - default: - return false; - } + yield true; + } + default -> false; + }; } private void decodeUnknownParam(String name, JsonValue value, Position position) { - if (value instanceof JsonNumber) { - if (((JsonNumber) value).isIntegral()) { - position.set(name, ((JsonNumber) value).longValue()); + if (value instanceof JsonNumber jsonNumber) { + if (jsonNumber.isIntegral()) { + position.set(name, jsonNumber.longValue()); } else { - position.set(name, ((JsonNumber) value).doubleValue()); + position.set(name, jsonNumber.doubleValue()); } - position.set(name, ((JsonNumber) value).doubleValue()); - } else if (value instanceof JsonString) { - position.set(name, ((JsonString) value).getString()); + position.set(name, jsonNumber.doubleValue()); + } else if (value instanceof JsonString jsonString) { + position.set(name, jsonString.getString()); } else if (value == JsonValue.TRUE || value == JsonValue.FALSE) { position.set(name, value == JsonValue.TRUE); } diff --git a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java index fb76673ca..c39f774b7 100644 --- a/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FlexApiProtocolDecoder.java @@ -93,17 +93,9 @@ public class FlexApiProtocolDecoder extends BaseProtocolDecoder { Integer.parseInt(payload.getString("modem1.cell_id"), 16), payload.getInt("modem1.rssi")); switch (payload.getInt("modem1.network")) { - case 1: - cellTower.setRadioType("gsm"); - break; - case 2: - cellTower.setRadioType("wcdma"); - break; - case 3: - cellTower.setRadioType("lte"); - break; - default: - break; + case 1 -> cellTower.setRadioType("gsm"); + case 2 -> cellTower.setRadioType("wcdma"); + case 3 -> cellTower.setRadioType("lte"); } position.setNetwork(new Network(cellTower)); } diff --git a/src/main/java/org/traccar/protocol/FreematicsProtocolDecoder.java b/src/main/java/org/traccar/protocol/FreematicsProtocolDecoder.java index d0402cc94..d7d9d62ed 100644 --- a/src/main/java/org/traccar/protocol/FreematicsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/FreematicsProtocolDecoder.java @@ -48,20 +48,13 @@ public class FreematicsProtocolDecoder extends BaseProtocolDecoder { String key = data[0]; String value = data[1]; switch (key) { - case "ID": - case "VIN": + case "ID", "VIN" -> { if (deviceSession == null) { deviceSession = getDeviceSession(channel, remoteAddress, value); } - break; - case "EV": - event = value; - break; - case "TS": - time = value; - break; - default: - break; + } + case "EV" -> event = value; + case "TS" -> time = value; } } @@ -105,74 +98,44 @@ public class FreematicsProtocolDecoder extends BaseProtocolDecoder { dateBuilder = new DateBuilder(new Date()); } else if (position != null) { switch (key) { - case 0x11: + case 0x11 -> { value = ("000000" + value).substring(value.length()); dateBuilder.setDateReverse( Integer.parseInt(value.substring(0, 2)), Integer.parseInt(value.substring(2, 4)), Integer.parseInt(value.substring(4))); - break; - case 0x10: + } + case 0x10 -> { value = ("00000000" + value).substring(value.length()); dateBuilder.setTime( Integer.parseInt(value.substring(0, 2)), Integer.parseInt(value.substring(2, 4)), Integer.parseInt(value.substring(4, 6)), Integer.parseInt(value.substring(6)) * 10); - break; - case 0xA: + } + case 0xA -> { position.setValid(true); position.setLatitude(Double.parseDouble(value)); - break; - case 0xB: + } + case 0xB -> { position.setValid(true); position.setLongitude(Double.parseDouble(value)); - break; - case 0xC: - position.setAltitude(Double.parseDouble(value)); - break; - case 0xD: - position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(value))); - break; - case 0xE: - position.setCourse(Integer.parseInt(value)); - break; - case 0xF: - position.set(Position.KEY_SATELLITES, Integer.parseInt(value)); - break; - case 0x12: - position.set(Position.KEY_HDOP, Integer.parseInt(value)); - break; - case 0x20: - position.set(Position.KEY_ACCELERATION, value); - break; - case 0x24: - position.set(Position.KEY_BATTERY, Integer.parseInt(value) * 0.01); - break; - case 0x81: - position.set(Position.KEY_RSSI, Integer.parseInt(value)); - break; - case 0x82: - position.set(Position.KEY_DEVICE_TEMP, Double.parseDouble(value) * 0.1); - break; - case 0x104: - position.set(Position.KEY_ENGINE_LOAD, Integer.parseInt(value)); - break; - case 0x105: - position.set(Position.KEY_COOLANT_TEMP, Integer.parseInt(value)); - break; - case 0x10c: - position.set(Position.KEY_RPM, Integer.parseInt(value)); - break; - case 0x10d: - position.set(Position.KEY_OBD_SPEED, Integer.parseInt(value)); - break; - case 0x111: - position.set(Position.KEY_THROTTLE, Integer.parseInt(value)); - break; - default: - position.set(Position.PREFIX_IO + key, value); - break; + } + case 0xC -> position.setAltitude(Double.parseDouble(value)); + case 0xD -> position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(value))); + case 0xE -> position.setCourse(Integer.parseInt(value)); + case 0xF -> position.set(Position.KEY_SATELLITES, Integer.parseInt(value)); + case 0x12 -> position.set(Position.KEY_HDOP, Integer.parseInt(value)); + case 0x20 -> position.set(Position.KEY_ACCELERATION, value); + case 0x24 -> position.set(Position.KEY_BATTERY, Integer.parseInt(value) * 0.01); + case 0x81 -> position.set(Position.KEY_RSSI, Integer.parseInt(value)); + case 0x82 -> position.set(Position.KEY_DEVICE_TEMP, Double.parseDouble(value) * 0.1); + case 0x104 -> position.set(Position.KEY_ENGINE_LOAD, Integer.parseInt(value)); + case 0x105 -> position.set(Position.KEY_COOLANT_TEMP, Integer.parseInt(value)); + case 0x10c -> position.set(Position.KEY_RPM, Integer.parseInt(value)); + case 0x10d -> position.set(Position.KEY_OBD_SPEED, Integer.parseInt(value)); + case 0x111 -> position.set(Position.KEY_THROTTLE, Integer.parseInt(value)); + default -> position.set(Position.PREFIX_IO + key, value); } } } diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java index 44baa94ea..1ac735407 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolDecoder.java @@ -149,94 +149,42 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { private void decodeTagOther(Position position, ByteBuf buf, int tag) { switch (tag) { - case 0x01: - position.set(Position.KEY_VERSION_HW, buf.readUnsignedByte()); - break; - case 0x02: - position.set(Position.KEY_VERSION_FW, buf.readUnsignedByte()); - break; - case 0x04: - position.set("deviceId", buf.readUnsignedShortLE()); - break; - case 0x10: - position.set(Position.KEY_INDEX, buf.readUnsignedShortLE()); - break; - case 0x20: - position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); - break; - case 0x33: + case 0x01 -> position.set(Position.KEY_VERSION_HW, buf.readUnsignedByte()); + case 0x02 -> position.set(Position.KEY_VERSION_FW, buf.readUnsignedByte()); + case 0x04 -> position.set("deviceId", buf.readUnsignedShortLE()); + case 0x10 -> position.set(Position.KEY_INDEX, buf.readUnsignedShortLE()); + case 0x20 -> position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); + case 0x33 -> { position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE() * 0.1)); position.setCourse(buf.readUnsignedShortLE() * 0.1); - break; - case 0x34: - position.setAltitude(buf.readShortLE()); - break; - case 0x35: - position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); - break; - case 0x40: - position.set(Position.KEY_STATUS, buf.readUnsignedShortLE()); - break; - case 0x41: - position.set(Position.KEY_POWER, buf.readUnsignedShortLE() / 1000.0); - break; - case 0x42: - position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() / 1000.0); - break; - case 0x43: - position.set(Position.KEY_DEVICE_TEMP, buf.readByte()); - break; - case 0x44: - position.set(Position.KEY_ACCELERATION, buf.readUnsignedIntLE()); - break; - case 0x45: - position.set(Position.KEY_OUTPUT, buf.readUnsignedShortLE()); - break; - case 0x46: - position.set(Position.KEY_INPUT, buf.readUnsignedShortLE()); - break; - case 0x48: - position.set("statusExtended", buf.readUnsignedShortLE()); - break; - case 0x58: - position.set("rs2320", buf.readUnsignedShortLE()); - break; - case 0x59: - position.set("rs2321", buf.readUnsignedShortLE()); - break; - case 0x90: - position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(buf.readUnsignedIntLE())); - break; - case 0xc0: - position.set("fuelTotal", buf.readUnsignedIntLE() * 0.5); - break; - case 0xc1: + } + case 0x34 -> position.setAltitude(buf.readShortLE()); + case 0x35 -> position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); + case 0x40 -> position.set(Position.KEY_STATUS, buf.readUnsignedShortLE()); + case 0x41 -> position.set(Position.KEY_POWER, buf.readUnsignedShortLE() / 1000.0); + case 0x42 -> position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() / 1000.0); + case 0x43 -> position.set(Position.KEY_DEVICE_TEMP, buf.readByte()); + case 0x44 -> position.set(Position.KEY_ACCELERATION, buf.readUnsignedIntLE()); + case 0x45 -> position.set(Position.KEY_OUTPUT, buf.readUnsignedShortLE()); + case 0x46 -> position.set(Position.KEY_INPUT, buf.readUnsignedShortLE()); + case 0x48 -> position.set("statusExtended", buf.readUnsignedShortLE()); + case 0x58 -> position.set("rs2320", buf.readUnsignedShortLE()); + case 0x59 -> position.set("rs2321", buf.readUnsignedShortLE()); + case 0x90 -> position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(buf.readUnsignedIntLE())); + case 0xc0 -> position.set("fuelTotal", buf.readUnsignedIntLE() * 0.5); + case 0xc1 -> { position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte() * 0.4); position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedByte() - 40); position.set(Position.KEY_RPM, buf.readUnsignedShortLE() * 0.125); - break; - case 0xc2: - position.set("canB0", buf.readUnsignedIntLE()); - break; - case 0xc3: - position.set("canB1", buf.readUnsignedIntLE()); - break; - case 0xd4: - position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); - break; - case 0xe0: - position.set(Position.KEY_INDEX, buf.readUnsignedIntLE()); - break; - case 0xe1: - position.set(Position.KEY_RESULT, - buf.readSlice(buf.readUnsignedByte()).toString(StandardCharsets.US_ASCII)); - break; - case 0xea: - position.set("userDataArray", ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte()))); - break; - default: - buf.skipBytes(getTagLength(tag)); - break; + } + case 0xc2 -> position.set("canB0", buf.readUnsignedIntLE()); + case 0xc3 -> position.set("canB1", buf.readUnsignedIntLE()); + case 0xd4 -> position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); + case 0xe0 -> position.set(Position.KEY_INDEX, buf.readUnsignedIntLE()); + case 0xe1 -> position.set(Position.KEY_RESULT, + buf.readSlice(buf.readUnsignedByte()).toString(StandardCharsets.US_ASCII)); + case 0xea -> position.set("userDataArray", ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte()))); + default -> buf.skipBytes(getTagLength(tag)); } } diff --git a/src/main/java/org/traccar/protocol/GalileoProtocolEncoder.java b/src/main/java/org/traccar/protocol/GalileoProtocolEncoder.java index cd068b251..b0033a2ba 100644 --- a/src/main/java/org/traccar/protocol/GalileoProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/GalileoProtocolEncoder.java @@ -58,15 +58,13 @@ public class GalileoProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return encodeText(getUniqueId(command.getDeviceId()), command.getString(Command.KEY_DATA)); - case Command.TYPE_OUTPUT_CONTROL: - return encodeText(getUniqueId(command.getDeviceId()), - "Out " + command.getInteger(Command.KEY_INDEX) + "," + command.getString(Command.KEY_DATA)); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_CUSTOM -> encodeText(getUniqueId(command.getDeviceId()), + command.getString(Command.KEY_DATA)); + case Command.TYPE_OUTPUT_CONTROL -> encodeText(getUniqueId(command.getDeviceId()), + "Out " + command.getInteger(Command.KEY_INDEX) + "," + command.getString(Command.KEY_DATA)); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java b/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java index 6c6b9a54a..2bd56592b 100644 --- a/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/GatorProtocolEncoder.java @@ -73,21 +73,22 @@ public class GatorProtocolEncoder extends BaseProtocolEncoder { ByteBuf content = Unpooled.buffer(); - switch (command.getType()) { - case Command.TYPE_POSITION_SINGLE: - return encodeContent(command.getDeviceId(), GatorProtocolDecoder.MSG_POSITION_REQUEST, null); - case Command.TYPE_ENGINE_STOP: - return encodeContent(command.getDeviceId(), GatorProtocolDecoder.MSG_CLOSE_OIL_DUCT, null); - case Command.TYPE_ENGINE_RESUME: - return encodeContent(command.getDeviceId(), GatorProtocolDecoder.MSG_RESTORE_OIL_DUCT, null); - case Command.TYPE_SET_SPEED_LIMIT: + return switch (command.getType()) { + case Command.TYPE_POSITION_SINGLE -> + encodeContent(command.getDeviceId(), GatorProtocolDecoder.MSG_POSITION_REQUEST, null); + case Command.TYPE_ENGINE_STOP -> + encodeContent(command.getDeviceId(), GatorProtocolDecoder.MSG_CLOSE_OIL_DUCT, null); + case Command.TYPE_ENGINE_RESUME -> + encodeContent(command.getDeviceId(), GatorProtocolDecoder.MSG_RESTORE_OIL_DUCT, null); + case Command.TYPE_SET_SPEED_LIMIT -> { content.writeByte(command.getInteger(Command.KEY_DATA)); - return encodeContent(command.getDeviceId(), GatorProtocolDecoder.MSG_RESET_MILEAGE, content); - case Command.TYPE_SET_ODOMETER: + yield encodeContent(command.getDeviceId(), GatorProtocolDecoder.MSG_RESET_MILEAGE, content); + } + case Command.TYPE_SET_ODOMETER -> { content.writeShort(command.getInteger(Command.KEY_DATA)); - return encodeContent(command.getDeviceId(), GatorProtocolDecoder.MSG_OVERSPEED_ALARM, content); - default: - return null; - } + yield encodeContent(command.getDeviceId(), GatorProtocolDecoder.MSG_OVERSPEED_ALARM, content); + } + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java b/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java index 6448b6a5a..30416a07b 100644 --- a/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GenxProtocolDecoder.java @@ -57,42 +57,21 @@ public class GenxProtocolDecoder extends BaseProtocolDecoder { for (int i = 0; i < Math.min(values.length, reportColumns.length); i++) { switch (reportColumns[i]) { - case 1: - case 28: + case 1, 28 -> { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[i]); if (deviceSession != null) { position.setDeviceId(deviceSession.getDeviceId()); } - break; - case 2: - position.setTime(new SimpleDateFormat("MM/dd/yy HH:mm:ss").parse(values[i])); - break; - case 3: - position.setLatitude(Double.parseDouble(values[i])); - break; - case 4: - position.setLongitude(Double.parseDouble(values[i])); - break; - case 11: - position.set(Position.KEY_IGNITION, values[i].equals("ON")); - break; - case 13: - position.setSpeed(UnitsConverter.knotsFromKph(Integer.parseInt(values[i]))); - break; - case 17: - position.setCourse(Integer.parseInt(values[i])); - break; - case 23: - position.set(Position.KEY_ODOMETER, Double.parseDouble(values[i]) * 1000); - break; - case 27: - position.setAltitude(UnitsConverter.metersFromFeet(Integer.parseInt(values[i]))); - break; - case 46: - position.set(Position.KEY_SATELLITES, Integer.parseInt(values[i])); - break; - default: - break; + } + case 2 -> position.setTime(new SimpleDateFormat("MM/dd/yy HH:mm:ss").parse(values[i])); + case 3 -> position.setLatitude(Double.parseDouble(values[i])); + case 4 -> position.setLongitude(Double.parseDouble(values[i])); + case 11 -> position.set(Position.KEY_IGNITION, values[i].equals("ON")); + case 13 -> position.setSpeed(UnitsConverter.knotsFromKph(Integer.parseInt(values[i]))); + case 17 -> position.setCourse(Integer.parseInt(values[i])); + case 23 -> position.set(Position.KEY_ODOMETER, Double.parseDouble(values[i]) * 1000); + case 27 -> position.setAltitude(UnitsConverter.metersFromFeet(Integer.parseInt(values[i]))); + case 46 -> position.set(Position.KEY_SATELLITES, Integer.parseInt(values[i])); } } diff --git a/src/main/java/org/traccar/protocol/Gl200BinaryProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200BinaryProtocolDecoder.java index ecd1f5bfa..359af8e5a 100644 --- a/src/main/java/org/traccar/protocol/Gl200BinaryProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200BinaryProtocolDecoder.java @@ -230,52 +230,39 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); switch (type) { - case MSG_EVT_BPL: - buf.readUnsignedShort(); // backup battery voltage - break; - case MSG_EVT_VGN: - case MSG_EVT_VGF: + case MSG_EVT_BPL -> buf.readUnsignedShort(); // backup battery voltage + case MSG_EVT_VGN, MSG_EVT_VGF -> { buf.readUnsignedShort(); // reserved buf.readUnsignedByte(); // report type buf.readUnsignedInt(); // ignition duration - break; - case MSG_EVT_UPD: + } + case MSG_EVT_UPD -> { buf.readUnsignedShort(); // code buf.readUnsignedByte(); // retry - break; - case MSG_EVT_IDF: - buf.readUnsignedInt(); // idling duration - break; - case MSG_EVT_GSS: + } + case MSG_EVT_IDF -> buf.readUnsignedInt(); // idling duration + case MSG_EVT_GSS -> { buf.readUnsignedByte(); // gps signal status buf.readUnsignedInt(); // reserved - break; - case MSG_EVT_GES: + } + case MSG_EVT_GES -> { buf.readUnsignedShort(); // trigger geo id buf.readUnsignedByte(); // trigger geo enable buf.readUnsignedByte(); // trigger mode buf.readUnsignedInt(); // radius buf.readUnsignedInt(); // check interval - break; - case MSG_EVT_GPJ: + } + case MSG_EVT_GPJ -> { buf.readUnsignedByte(); // cw jamming value buf.readUnsignedByte(); // gps jamming state - break; - case MSG_EVT_RMD: - buf.readUnsignedByte(); // roaming state - break; - case MSG_EVT_JDS: - buf.readUnsignedByte(); // jamming state - break; - case MSG_EVT_CRA: - buf.readUnsignedByte(); // crash counter - break; - case MSG_EVT_UPC: + } + case MSG_EVT_RMD -> buf.readUnsignedByte(); // roaming state + case MSG_EVT_JDS -> buf.readUnsignedByte(); // jamming state + case MSG_EVT_CRA -> buf.readUnsignedByte(); // crash counter + case MSG_EVT_UPC -> { buf.readUnsignedByte(); // command id buf.readUnsignedShort(); // result - break; - default: - break; + } } buf.readUnsignedByte(); // count @@ -388,16 +375,12 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { ByteBuf buf = (ByteBuf) msg; - switch (buf.readSlice(4).toString(StandardCharsets.US_ASCII)) { - case "+RSP": - return decodeLocation(channel, remoteAddress, buf); - case "+INF": - return decodeInformation(channel, remoteAddress, buf); - case "+EVT": - return decodeEvent(channel, remoteAddress, buf); - default: - return null; - } + return switch (buf.readSlice(4).toString(StandardCharsets.US_ASCII)) { + case "+RSP" -> decodeLocation(channel, remoteAddress, buf); + case "+INF" -> decodeInformation(channel, remoteAddress, buf); + case "+EVT" -> decodeEvent(channel, remoteAddress, buf); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/Gl200FrameDecoder.java b/src/main/java/org/traccar/protocol/Gl200FrameDecoder.java index 4ce243425..b011ede8b 100644 --- a/src/main/java/org/traccar/protocol/Gl200FrameDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200FrameDecoder.java @@ -52,27 +52,13 @@ public class Gl200FrameDecoder extends BaseFrameDecoder { if (isBinary(buf)) { - int length; - switch (buf.toString(buf.readerIndex(), 4, StandardCharsets.US_ASCII)) { - case "+ACK": - length = buf.getUnsignedByte(buf.readerIndex() + 6); - break; - case "+INF": - case "+BNF": - length = buf.getUnsignedShort(buf.readerIndex() + 7); - break; - case "+HBD": - length = buf.getUnsignedByte(buf.readerIndex() + 5); - break; - case "+CRD": - case "+BRD": - case "+LGN": - length = buf.getUnsignedShort(buf.readerIndex() + 6); - break; - default: - length = buf.getUnsignedShort(buf.readerIndex() + 9); - break; - } + int length = switch (buf.toString(buf.readerIndex(), 4, StandardCharsets.US_ASCII)) { + case "+ACK" -> buf.getUnsignedByte(buf.readerIndex() + 6); + case "+INF", "+BNF" -> buf.getUnsignedShort(buf.readerIndex() + 7); + case "+HBD" -> buf.getUnsignedByte(buf.readerIndex() + 5); + case "+CRD", "+BRD", "+LGN" -> buf.getUnsignedShort(buf.readerIndex() + 6); + default -> buf.getUnsignedShort(buf.readerIndex() + 9); + }; if (buf.readableBytes() >= length) { return buf.readRetainedSlice(length); diff --git a/src/main/java/org/traccar/protocol/Gl200ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gl200ProtocolEncoder.java index dd0672c23..1d48db623 100644 --- a/src/main/java/org/traccar/protocol/Gl200ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Gl200ProtocolEncoder.java @@ -30,22 +30,19 @@ public class Gl200ProtocolEncoder extends StringProtocolEncoder { initDevicePassword(command, ""); - switch (command.getType()) { - case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, "AT+GTRTO=%s,1,,,,,,FFFF$", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_ENGINE_STOP: - return formatCommand(command, "AT+GTOUT=%s,1,,,0,0,0,0,0,0,0,,,,,,,FFFF$", - Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "AT+GTOUT=%s,0,,,0,0,0,0,0,0,0,,,,,,,FFFF$", - Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_IDENTIFICATION: - return formatCommand(command, "AT+GTRTO=%s,8,,,,,,FFFF$", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_REBOOT_DEVICE: - return formatCommand(command, "AT+GTRTO=%s,3,,,,,,FFFF$", Command.KEY_DEVICE_PASSWORD); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_POSITION_SINGLE -> formatCommand( + command, "AT+GTRTO=%s,1,,,,,,FFFF$", Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_ENGINE_STOP -> formatCommand( + command, "AT+GTOUT=%s,1,,,0,0,0,0,0,0,0,,,,,,,FFFF$", Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_ENGINE_RESUME -> formatCommand( + command, "AT+GTOUT=%s,0,,,0,0,0,0,0,0,0,,,,,,,FFFF$", Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_IDENTIFICATION -> formatCommand( + command, "AT+GTRTO=%s,8,,,,,,FFFF$", Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_REBOOT_DEVICE -> formatCommand( + command, "AT+GTRTO=%s,3,,,,,,FFFF$", Command.KEY_DEVICE_PASSWORD); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java index 8edce9346..edcd0fa8b 100644 --- a/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -229,32 +229,24 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); switch (parser.nextHexInt()) { - case 0x16: - case 0x1A: - case 0x12: + case 0x16, 0x1A, 0x12 -> { position.set(Position.KEY_IGNITION, false); position.set(Position.KEY_MOTION, true); - break; - case 0x11: + } + case 0x11 -> { position.set(Position.KEY_IGNITION, false); position.set(Position.KEY_MOTION, false); - break; - case 0x21: + } + case 0x21 -> { position.set(Position.KEY_IGNITION, true); position.set(Position.KEY_MOTION, false); - break; - case 0x22: + } + case 0x22 -> { position.set(Position.KEY_IGNITION, true); position.set(Position.KEY_MOTION, true); - break; - case 0x41: - position.set(Position.KEY_MOTION, false); - break; - case 0x42: - position.set(Position.KEY_MOTION, true); - break; - default: - break; + } + case 0x41 -> position.set(Position.KEY_MOTION, false); + case 0x42 -> position.set(Position.KEY_MOTION, true); } position.set(Position.KEY_ICCID, parser.next()); @@ -278,6 +270,8 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_ADC + 2, parser.next()); if (model.equals("GV310LAU")) { position.set(Position.PREFIX_ADC + 3, parser.next()); + } else { + parser.next(); // skip for other devices } position.set(Position.KEY_INPUT, parser.next()); @@ -1033,36 +1027,34 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return positions; } - private static final Pattern PATTERN_IGN = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GT[IV]G[NF],") - .expression("(?:.{6}|.{10})?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .number("d+,") // ignition off duration - .expression(PATTERN_LOCATION.pattern()) - .number("(d{5}:dd:dd)?,") // hour meter - .number("(d{1,7}.d)?,") // odometer - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private Object decodeIgn(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_IGN, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { + private Object decodeIgn( + Channel channel, SocketAddress remoteAddress, String[] v, String type) throws ParseException { + int index = 0; + index += 1; // header + String protocolVersion = v[index++]; // protocol version + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, v[index++]); + if (deviceSession == null) { return null; } + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); - decodeLocation(position, parser); + String model = getDeviceModel(deviceSession, protocolVersion); + index += 1; // device name + index += 1; // duration of ignition on/off - position.set(Position.KEY_IGNITION, sentence.contains("GN")); - position.set(Position.KEY_HOURS, parseHours(parser.next())); - position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000); + decodeLocation(position, model, v, index); - decodeDeviceTime(position, parser); + position.set(Position.KEY_IGNITION, type.contains("GN")); + position.set(Position.KEY_HOURS, parseHours(v[index++])); + position.set(Position.KEY_ODOMETER, Double.parseDouble(v[index]) * 1000); + + Date time = dateFormat.parse(v[v.length - 2]); + if (ignoreFixTime) { + position.setTime(time); + } else { + position.setDeviceTime(time); + } return position; } @@ -1495,19 +1487,9 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_IGNITION, reportType % 0x10 == 1); } else if (type.equals("HBM")) { switch (reportType % 0x10) { - case 0: - case 3: - position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); - break; - case 1: - case 4: - position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - break; - case 2: - position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); - break; - default: - break; + case 0, 3 -> position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + case 1, 4 -> position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + case 2 -> position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); } } @@ -1595,45 +1577,17 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { decodeDeviceTime(position, parser); switch (type) { - case "TOW": - position.set(Position.KEY_ALARM, Position.ALARM_TOW); - break; - case "IDL": - position.set(Position.KEY_ALARM, Position.ALARM_IDLE); - break; - case "PNA": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_ON); - break; - case "PFA": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_OFF); - break; - case "EPN": - case "MPN": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED); - break; - case "EPF": - case "MPF": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); - break; - case "BPL": - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - case "STT": - position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); - break; - case "SWG": - position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE); - break; - case "TMP": - case "TEM": - position.set(Position.KEY_ALARM, Position.ALARM_TEMPERATURE); - break; - case "JDR": - case "JDS": - position.set(Position.KEY_ALARM, Position.ALARM_JAMMING); - break; - default: - break; + case "TOW" -> position.set(Position.KEY_ALARM, Position.ALARM_TOW); + case "IDL" -> position.set(Position.KEY_ALARM, Position.ALARM_IDLE); + case "PNA" -> position.set(Position.KEY_ALARM, Position.ALARM_POWER_ON); + case "PFA" -> position.set(Position.KEY_ALARM, Position.ALARM_POWER_OFF); + case "EPN", "MPN" -> position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED); + case "EPF", "MPF" -> position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); + case "BPL" -> position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + case "STT" -> position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); + case "SWG" -> position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE); + case "TMP", "TEM" -> position.set(Position.KEY_ALARM, Position.ALARM_TEMPERATURE); + case "JDR", "JDS" -> position.set(Position.KEY_ALARM, Position.ALARM_JAMMING); } return position; @@ -1657,80 +1611,34 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { if (sentence.startsWith("+ACK")) { result = decodeAck(channel, remoteAddress, values); } else { - switch (type) { - case "INF": - result = decodeInf(channel, remoteAddress, sentence); - break; - case "OBD": - result = decodeObd(channel, remoteAddress, sentence); - break; - case "CAN": - result = decodeCan(channel, remoteAddress, values); - break; - case "CTN": - case "FRI": - case "GEO": - case "RTL": - case "DOG": - case "STR": - result = decodeFri(channel, remoteAddress, sentence); - break; - case "ERI": - result = decodeEri(channel, remoteAddress, values); - break; - case "IGN": - case "IGF": - case "VGN": - case "VGF": - result = decodeIgn(channel, remoteAddress, sentence); - break; - case "LSW": - case "TSW": - result = decodeLsw(channel, remoteAddress, sentence); - break; - case "IDA": - result = decodeIda(channel, remoteAddress, sentence); - break; - case "WIF": - result = decodeWif(channel, remoteAddress, sentence); - break; - case "GSM": - result = decodeGsm(channel, remoteAddress, sentence); - break; - case "VER": - result = decodeVer(channel, remoteAddress, sentence); - break; - case "PNA": - case "PFA": - result = decodePna(channel, remoteAddress, sentence); - break; - case "DAR": - result = decodeDar(channel, remoteAddress, sentence); - break; - case "DTT": - result = decodeDtt(channel, remoteAddress, sentence); - break; - case "BAA": - result = decodeBaa(channel, remoteAddress, sentence); - break; - case "BID": - result = decodeBid(channel, remoteAddress, sentence); - break; - case "LSA": - result = decodeLsa(channel, remoteAddress, sentence); - break; - default: - result = decodeOther(channel, remoteAddress, sentence, type); - break; - } + result = switch (type) { + case "INF" -> decodeInf(channel, remoteAddress, sentence); + case "OBD" -> decodeObd(channel, remoteAddress, sentence); + case "CAN" -> decodeCan(channel, remoteAddress, values); + case "CTN", "FRI", "GEO", "RTL", "DOG", "STR" -> decodeFri(channel, remoteAddress, sentence); + case "ERI" -> decodeEri(channel, remoteAddress, values); + case "IGN", "IGF", "VGN", "VGF" -> decodeIgn(channel, remoteAddress, values, type); + case "LSW", "TSW" -> decodeLsw(channel, remoteAddress, sentence); + case "IDA" -> decodeIda(channel, remoteAddress, sentence); + case "WIF" -> decodeWif(channel, remoteAddress, sentence); + case "GSM" -> decodeGsm(channel, remoteAddress, sentence); + case "VER" -> decodeVer(channel, remoteAddress, sentence); + case "PNA", "PFA" -> decodePna(channel, remoteAddress, sentence); + case "DAR" -> decodeDar(channel, remoteAddress, sentence); + case "DTT" -> decodeDtt(channel, remoteAddress, sentence); + case "BAA" -> decodeBaa(channel, remoteAddress, sentence); + case "BID" -> decodeBid(channel, remoteAddress, sentence); + case "LSA" -> decodeLsa(channel, remoteAddress, sentence); + default -> decodeOther(channel, remoteAddress, sentence, type); + }; if (result == null) { result = decodeBasic(channel, remoteAddress, sentence, type); } if (result != null) { - if (result instanceof Position) { - ((Position) result).set(Position.KEY_TYPE, type); + if (result instanceof Position position) { + position.set(Position.KEY_TYPE, type); } else { for (Position p : (List<Position>) result) { p.set(Position.KEY_TYPE, type); diff --git a/src/main/java/org/traccar/protocol/GlobalSatProtocolEncoder.java b/src/main/java/org/traccar/protocol/GlobalSatProtocolEncoder.java index 4f56274da..c39410371 100644 --- a/src/main/java/org/traccar/protocol/GlobalSatProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/GlobalSatProtocolEncoder.java @@ -32,20 +32,12 @@ public class GlobalSatProtocolEncoder extends StringProtocolEncoder { String formattedCommand = null; switch (command.getType()) { - case Command.TYPE_CUSTOM: - formattedCommand = formatCommand( - command, "GSC,%s,%s", Command.KEY_UNIQUE_ID, Command.KEY_DATA); - break; - case Command.TYPE_ALARM_DISMISS: - formattedCommand = formatCommand( - command, "GSC,%s,Na", Command.KEY_UNIQUE_ID); - break; - case Command.TYPE_OUTPUT_CONTROL: - formattedCommand = formatCommand( - command, "GSC,%s,Lo(%s,%s)", Command.KEY_UNIQUE_ID, Command.KEY_INDEX, Command.KEY_DATA); - break; - default: - break; + case Command.TYPE_CUSTOM -> formattedCommand = formatCommand( + command, "GSC,%s,%s", Command.KEY_UNIQUE_ID, Command.KEY_DATA); + case Command.TYPE_ALARM_DISMISS -> formattedCommand = formatCommand( + command, "GSC,%s,Na", Command.KEY_UNIQUE_ID); + case Command.TYPE_OUTPUT_CONTROL -> formattedCommand = formatCommand( + command, "GSC,%s,Lo(%s,%s)", Command.KEY_UNIQUE_ID, Command.KEY_INDEX, Command.KEY_DATA); } if (formattedCommand != null) { diff --git a/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java b/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java index 5c8d0bac2..933e6fe4f 100644 --- a/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/GotopProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2024 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,10 +37,14 @@ public class GotopProtocolDecoder extends BaseProtocolDecoder { .number("(d+),") // imei .expression("([^,]+),") // type .expression("([AV]),") // validity - .number("DATE:(dd)(dd)(dd),") // date (yyddmm) - .number("TIME:(dd)(dd)(dd),") // time (hhmmss) - .number("LAT:(d+.d+)([NS]),") // latitude - .number("LO[NT]:(d+.d+)([EW]),") // longitude + .text("DATE:").optional() + .number("(dd)(dd)(dd),") // date (yyddmm) + .text("TIME:").optional() + .number("(dd)(dd)(dd),") // time (hhmmss) + .text("LAT:").optional() + .number("(d+.d+)([NS]),") // latitude + .expression("LO[NT]:").optional() + .number("(d+.d+)([EW]),") // longitude .text("Speed:").number("(d+.d+),") // speed .expression("([^,]+),") // status .number("(d+)?") // course diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java index d1c35b478..554a23915 100644 --- a/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -141,35 +141,21 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { } else if (value.startsWith("oil")) { return Position.ALARM_FUEL_LEAK; } - switch (value) { - case "help me": - return Position.ALARM_SOS; - case "low battery": - return Position.ALARM_LOW_BATTERY; - case "stockade": - return Position.ALARM_GEOFENCE; - case "move": - return Position.ALARM_MOVEMENT; - case "speed": - return Position.ALARM_OVERSPEED; - case "door alarm": - return Position.ALARM_DOOR; - case "ac alarm": - return Position.ALARM_POWER_CUT; - case "accident alarm": - return Position.ALARM_ACCIDENT; - case "sensor alarm": - return Position.ALARM_VIBRATION; - case "bonnet alarm": - return Position.ALARM_BONNET; - case "footbrake alarm": - return Position.ALARM_FOOT_BRAKE; - case "DTC": - return Position.ALARM_FAULT; - case "tracker": - default: - return null; - } + return switch (value) { + case "help me" -> Position.ALARM_SOS; + case "low battery" -> Position.ALARM_LOW_BATTERY; + case "stockade" -> Position.ALARM_GEOFENCE; + case "move" -> Position.ALARM_MOVEMENT; + case "speed" -> Position.ALARM_OVERSPEED; + case "door alarm" -> Position.ALARM_DOOR; + case "ac alarm" -> Position.ALARM_POWER_CUT; + case "accident alarm" -> Position.ALARM_ACCIDENT; + case "sensor alarm" -> Position.ALARM_VIBRATION; + case "bonnet alarm" -> Position.ALARM_BONNET; + case "footbrake alarm" -> Position.ALARM_FOOT_BRAKE; + case "DTC" -> Position.ALARM_FAULT; + default -> null; + }; } private Position decodeRegular(Channel channel, SocketAddress remoteAddress, String sentence) { diff --git a/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java index 9a899eeeb..1af99d647 100644 --- a/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Gps103ProtocolEncoder.java @@ -45,29 +45,27 @@ public class Gps103ProtocolEncoder extends StringProtocolEncoder implements Stri @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return formatCommand(command, "**,imei:%s,%s", Command.KEY_UNIQUE_ID, Command.KEY_DATA); - case Command.TYPE_POSITION_STOP: - return formatCommand(command, "**,imei:%s,D", Command.KEY_UNIQUE_ID); - case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, "**,imei:%s,B", Command.KEY_UNIQUE_ID); - case Command.TYPE_POSITION_PERIODIC: - return formatCommand( - command, "**,imei:%s,C,%s", this, Command.KEY_UNIQUE_ID, Command.KEY_FREQUENCY); - case Command.TYPE_ENGINE_STOP: - return formatCommand(command, "**,imei:%s,J", Command.KEY_UNIQUE_ID); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "**,imei:%s,K", Command.KEY_UNIQUE_ID); - case Command.TYPE_ALARM_ARM: - return formatCommand(command, "**,imei:%s,L", Command.KEY_UNIQUE_ID); - case Command.TYPE_ALARM_DISARM: - return formatCommand(command, "**,imei:%s,M", Command.KEY_UNIQUE_ID); - case Command.TYPE_REQUEST_PHOTO: - return formatCommand(command, "**,imei:%s,160", Command.KEY_UNIQUE_ID); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_CUSTOM -> formatCommand( + command, "**,imei:%s,%s", Command.KEY_UNIQUE_ID, Command.KEY_DATA); + case Command.TYPE_POSITION_STOP -> formatCommand( + command, "**,imei:%s,D", Command.KEY_UNIQUE_ID); + case Command.TYPE_POSITION_SINGLE -> formatCommand( + command, "**,imei:%s,B", Command.KEY_UNIQUE_ID); + case Command.TYPE_POSITION_PERIODIC -> formatCommand( + command, "**,imei:%s,C,%s", this, Command.KEY_UNIQUE_ID, Command.KEY_FREQUENCY); + case Command.TYPE_ENGINE_STOP -> formatCommand( + command, "**,imei:%s,J", Command.KEY_UNIQUE_ID); + case Command.TYPE_ENGINE_RESUME -> formatCommand( + command, "**,imei:%s,K", Command.KEY_UNIQUE_ID); + case Command.TYPE_ALARM_ARM -> formatCommand( + command, "**,imei:%s,L", Command.KEY_UNIQUE_ID); + case Command.TYPE_ALARM_DISARM -> formatCommand( + command, "**,imei:%s,M", Command.KEY_UNIQUE_ID); + case Command.TYPE_REQUEST_PHOTO -> formatCommand( + command, "**,imei:%s,160", Command.KEY_UNIQUE_ID); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/GranitProtocolEncoder.java b/src/main/java/org/traccar/protocol/GranitProtocolEncoder.java index 66c2a4973..a171e2b6a 100644 --- a/src/main/java/org/traccar/protocol/GranitProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/GranitProtocolEncoder.java @@ -38,16 +38,12 @@ public class GranitProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_IDENTIFICATION: - return encodeCommand("BB+IDNT"); - case Command.TYPE_REBOOT_DEVICE: - return encodeCommand("BB+RESET"); - case Command.TYPE_POSITION_SINGLE: - return encodeCommand("BB+RRCD"); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_IDENTIFICATION -> encodeCommand("BB+IDNT"); + case Command.TYPE_REBOOT_DEVICE -> encodeCommand("BB+RESET"); + case Command.TYPE_POSITION_SINGLE -> encodeCommand("BB+RRCD"); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/GranitProtocolSmsEncoder.java b/src/main/java/org/traccar/protocol/GranitProtocolSmsEncoder.java index be0ab5130..6b8ef0969 100644 --- a/src/main/java/org/traccar/protocol/GranitProtocolSmsEncoder.java +++ b/src/main/java/org/traccar/protocol/GranitProtocolSmsEncoder.java @@ -28,14 +28,11 @@ public class GranitProtocolSmsEncoder extends StringProtocolEncoder { @Override protected String encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_REBOOT_DEVICE: - return "BB+RESET"; - case Command.TYPE_POSITION_PERIODIC: - return formatCommand(command, "BB+BBMD=%s", Command.KEY_FREQUENCY); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_REBOOT_DEVICE -> "BB+RESET"; + case Command.TYPE_POSITION_PERIODIC -> formatCommand(command, "BB+BBMD=%s", Command.KEY_FREQUENCY); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java index a1a9c3773..e25499190 100644 --- a/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -65,6 +65,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_STRING = 0x15; public static final int MSG_GPS_LBS_STATUS_1 = 0x16; public static final int MSG_WIFI = 0x17; + public static final int MSG_GPS_LBS_RFID = 0x17; public static final int MSG_GPS_LBS_STATUS_2 = 0x26; public static final int MSG_GPS_LBS_STATUS_3 = 0x27; public static final int MSG_LBS_MULTIPLE_1 = 0x28; @@ -87,6 +88,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_X1_GPS = 0x34; public static final int MSG_X1_PHOTO_INFO = 0x35; public static final int MSG_X1_PHOTO_DATA = 0x36; + public static final int MSG_STATUS_2 = 0x36; // Jimi IoT 4G public static final int MSG_WIFI_2 = 0x69; public static final int MSG_GPS_MODULAR = 0x70; public static final int MSG_WIFI_4 = 0xF3; @@ -100,6 +102,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_GPS_LBS_7 = 0xA0; // GK310 & JM-VL03 public static final int MSG_LBS_2 = 0xA1; // GK310 public static final int MSG_WIFI_3 = 0xA2; // GK310 + public static final int MSG_GPS_LBS_STATUS_5 = 0xA2; // LWxG public static final int MSG_FENCE_SINGLE = 0xA3; // GK310 public static final int MSG_FENCE_MULTI = 0xA4; // GK310 & JM-LL301 public static final int MSG_LBS_ALARM = 0xA5; // GK310 & JM-LL301 @@ -125,6 +128,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { JC400, SL4X, SEEWORLD, + RFID, + LW4G, } private Variant variant; @@ -172,9 +177,11 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { case MSG_GPS_LBS_STATUS_2: case MSG_GPS_LBS_STATUS_3: case MSG_GPS_LBS_STATUS_4: + case MSG_GPS_LBS_STATUS_5: case MSG_GPS_PHONE: case MSG_GPS_LBS_EXTEND: case MSG_GPS_LBS_7: + case MSG_GPS_LBS_RFID: case MSG_FENCE_SINGLE: case MSG_FENCE_MULTI: return true; @@ -196,7 +203,9 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { case MSG_GPS_LBS_STATUS_2: case MSG_GPS_LBS_STATUS_3: case MSG_GPS_LBS_STATUS_4: + case MSG_GPS_LBS_STATUS_5: case MSG_GPS_LBS_7: + case MSG_GPS_LBS_RFID: case MSG_FENCE_SINGLE: case MSG_FENCE_MULTI: case MSG_LBS_ALARM: @@ -210,11 +219,13 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { private static boolean hasStatus(int type) { switch (type) { case MSG_STATUS: + case MSG_STATUS_2: case MSG_LBS_STATUS: case MSG_GPS_LBS_STATUS_1: case MSG_GPS_LBS_STATUS_2: case MSG_GPS_LBS_STATUS_3: case MSG_GPS_LBS_STATUS_4: + case MSG_GPS_LBS_STATUS_5: case MSG_FENCE_MULTI: case MSG_LBS_ALARM: return true; @@ -350,13 +361,13 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { mnc = buf.readUnsignedByte(); } int lac; - if (type == MSG_LBS_ALARM || type == MSG_GPS_LBS_7) { + if (type == MSG_LBS_ALARM || type == MSG_GPS_LBS_7 || type == MSG_GPS_LBS_STATUS_5) { lac = buf.readInt(); } else { lac = buf.readUnsignedShort(); } long cid; - if (type == MSG_LBS_ALARM || type == MSG_GPS_LBS_7) { + if (type == MSG_LBS_ALARM || type == MSG_GPS_LBS_7 || variant == Variant.SL4X || type == MSG_GPS_LBS_STATUS_5) { cid = buf.readLong(); } else if (type == MSG_GPS_LBS_6 || variant == Variant.SEEWORLD) { cid = buf.readUnsignedInt(); @@ -412,54 +423,27 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { private String decodeAlarm(short value, String model) { boolean modelLW = model != null && model.toUpperCase().startsWith("LW"); - switch (value) { - case 0x01: - return Position.ALARM_SOS; - case 0x02: - return Position.ALARM_POWER_CUT; - case 0x03: - case 0x09: - return Position.ALARM_VIBRATION; - case 0x04: - return Position.ALARM_GEOFENCE_ENTER; - case 0x05: - return Position.ALARM_GEOFENCE_EXIT; - case 0x06: - return Position.ALARM_OVERSPEED; - case 0x0E: - case 0x0F: - return Position.ALARM_LOW_BATTERY; - case 0x11: - return Position.ALARM_POWER_OFF; - case 0x0C: - case 0x13: - case 0x25: - return Position.ALARM_TAMPERING; - case 0x14: - return Position.ALARM_DOOR; - case 0x18: - return modelLW ? Position.ALARM_ACCIDENT : Position.ALARM_REMOVING; - case 0x19: - return modelLW ? Position.ALARM_ACCELERATION : Position.ALARM_LOW_BATTERY; - case 0x1A: - case 0x28: - return Position.ALARM_BRAKING; - case 0x1B: - case 0x2A: - case 0x2B: - case 0x2E: - return Position.ALARM_CORNERING; - case 0x23: - return Position.ALARM_FALL_DOWN; - case 0x29: - return Position.ALARM_ACCELERATION; - case 0x2C: - return Position.ALARM_ACCIDENT; - case 0x30: - return Position.ALARM_JAMMING; - default: - return null; - } + return switch (value) { + case 0x01 -> Position.ALARM_SOS; + case 0x02 -> Position.ALARM_POWER_CUT; + case 0x03, 0x09 -> Position.ALARM_VIBRATION; + case 0x04 -> Position.ALARM_GEOFENCE_ENTER; + case 0x05 -> Position.ALARM_GEOFENCE_EXIT; + case 0x06 -> Position.ALARM_OVERSPEED; + case 0x0E, 0x0F -> Position.ALARM_LOW_BATTERY; + case 0x11 -> Position.ALARM_POWER_OFF; + case 0x0C, 0x13, 0x25 -> Position.ALARM_TAMPERING; + case 0x14 -> Position.ALARM_DOOR; + case 0x18 -> modelLW ? Position.ALARM_ACCIDENT : Position.ALARM_REMOVING; + case 0x19 -> modelLW ? Position.ALARM_ACCELERATION : Position.ALARM_LOW_BATTERY; + case 0x1A, 0x28 -> Position.ALARM_BRAKING; + case 0x1B, 0x2A, 0x2B, 0x2E -> Position.ALARM_CORNERING; + case 0x23 -> Position.ALARM_FALL_DOWN; + case 0x29 -> Position.ALARM_ACCELERATION; + case 0x2C -> Position.ALARM_ACCIDENT; + case 0x30 -> Position.ALARM_JAMMING; + default -> null; + }; } private Object decodeBasic(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { @@ -602,7 +586,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return null; - } else if (type == MSG_WIFI || type == MSG_WIFI_2 || type == MSG_WIFI_4) { + } else if ((type == MSG_WIFI && variant != Variant.RFID) || type == MSG_WIFI_2 || type == MSG_WIFI_4) { ByteBuf time = buf.readSlice(6); DateBuilder dateBuilder = new DateBuilder() @@ -686,7 +670,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (type == MSG_LBS_MULTIPLE_1 || type == MSG_LBS_MULTIPLE_2 || type == MSG_LBS_MULTIPLE_3 || type == MSG_LBS_EXTEND || type == MSG_LBS_WIFI || type == MSG_LBS_2 || type == MSG_LBS_3 - || type == MSG_WIFI_3 || type == MSG_WIFI_5) { + || (type == MSG_WIFI_3 && variant != Variant.LW4G) || type == MSG_WIFI_5) { DateBuilder dateBuilder = new DateBuilder((TimeZone) deviceSession.get(DeviceSession.KEY_TIMEZONE)) .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) @@ -824,11 +808,15 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { boolean hasLength = hasStatus(type) && type != MSG_LBS_STATUS && type != MSG_LBS_ALARM - && (type != MSG_GPS_LBS_STATUS_1 || variant != Variant.VXT01); + && (type != MSG_GPS_LBS_STATUS_1 || variant != Variant.VXT01) + && type != MSG_GPS_LBS_STATUS_5; decodeLbs(position, buf, type, hasLength); } if (hasStatus(type)) { + if (type == MSG_GPS_LBS_STATUS_5) { + buf.readUnsignedByte(); // network indicator + } decodeStatus(position, buf); if (variant == Variant.OBD6) { int signal = buf.readUnsignedShort(); @@ -842,8 +830,15 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // working mode position.set(Position.KEY_POWER, buf.readUnsignedShort() / 100.0); } else { + if (type == MSG_GPS_LBS_STATUS_5) { + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + } int battery = buf.readUnsignedByte(); - position.set(Position.KEY_BATTERY_LEVEL, battery <= 6 ? battery * 100 / 6 : battery); + if (battery <= 6) { + position.set(Position.KEY_BATTERY_LEVEL, battery * 100 / 6); + } else if (battery <= 100) { + position.set(Position.KEY_BATTERY_LEVEL, battery); + } position.set(Position.KEY_RSSI, buf.readUnsignedByte()); short alarmExtension = buf.readUnsignedByte(); if (variant != Variant.VXT01) { @@ -852,6 +847,28 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } } + if (type == MSG_STATUS_2) { + buf.readUnsignedByte(); // language + while (buf.readableBytes() > 6) { + int moduleType = buf.readUnsignedShort(); + int moduleLength = buf.readUnsignedByte(); + switch (moduleType) { + case 0x0018 -> position.set(Position.KEY_BATTERY, buf.readUnsignedShort() / 100.0); + case 0x0032 -> position.set("startupStatus", buf.readUnsignedByte()); + case 0x006A -> position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + default -> buf.skipBytes(moduleLength); + } + } + } + + if (type == MSG_GPS_LBS_STATUS_5) { + buf.readUnsignedByte(); // language + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + position.set(Position.KEY_HOURS, buf.readUnsignedInt() * 1000); + buf.skipBytes(8); // terminal id + position.set(Position.KEY_INPUT, buf.readUnsignedShort()); + } + if (type == MSG_GPS_LBS_1) { if (variant == Variant.GT06E_CARD) { position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); @@ -919,32 +936,39 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.set("humidity", buf.readUnsignedShort() * 0.01); } - if ((type == MSG_GPS_LBS_2 || type == MSG_GPS_LBS_3 || type == MSG_GPS_LBS_4) + if (type == MSG_GPS_LBS_STATUS_4 && variant == Variant.SL4X) { + position.setAltitude(buf.readShort()); + } + + if ((type == MSG_GPS_LBS_2 || type == MSG_GPS_LBS_3 || type == MSG_GPS_LBS_4 || type == MSG_GPS_LBS_5) && buf.readableBytes() >= 3 + 6) { position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); position.set(Position.KEY_EVENT, buf.readUnsignedByte()); // reason position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() > 0); + if (variant == Variant.SL4X) { + if (buf.readableBytes() > 2 + 6) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + } + position.setAltitude(buf.readShort()); + } } if (type == MSG_GPS_LBS_3) { int module = buf.readUnsignedShort(); int subLength = buf.readUnsignedByte(); switch (module) { - case 0x0027: - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); - break; - case 0x002E: - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - break; - case 0x003B: - position.setAccuracy(buf.readUnsignedShort() * 0.01); - break; - default: - buf.skipBytes(subLength); - break; + case 0x0027 -> position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + case 0x002E -> position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + case 0x003B -> position.setAccuracy(buf.readUnsignedShort() * 0.01); + default -> buf.skipBytes(subLength); } } + if (type == MSG_GPS_LBS_RFID) { + position.set(Position.KEY_DRIVER_UNIQUE_ID, ByteBufUtil.hexDump(buf.readSlice(8))); + buf.readUnsignedByte(); // validity + } + if (buf.readableBytes() == 3 + 6 || buf.readableBytes() == 3 + 4 + 6) { position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); buf.readUnsignedByte(); // upload mode @@ -979,38 +1003,17 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { short event = buf.readUnsignedByte(); position.set(Position.KEY_EVENT, event); switch (event) { - case 0x01: - position.set(Position.KEY_ALARM, extendedAlarm ? Position.ALARM_SOS : Position.ALARM_GENERAL); - break; - case 0x0E: - position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); - break; - case 0x76: - position.set(Position.KEY_ALARM, Position.ALARM_TEMPERATURE); - break; - case 0x80: - position.set(Position.KEY_ALARM, Position.ALARM_VIBRATION); - break; - case 0x87: - position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); - break; - case 0x88: - position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); - break; - case 0x90: - position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - break; - case 0x91: - position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); - break; - case 0x92: - position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); - break; - case 0x93: - position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); - break; - default: - break; + case 0x01 -> position.set( + Position.KEY_ALARM, extendedAlarm ? Position.ALARM_SOS : Position.ALARM_GENERAL); + case 0x0E -> position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); + case 0x76 -> position.set(Position.KEY_ALARM, Position.ALARM_TEMPERATURE); + case 0x80 -> position.set(Position.KEY_ALARM, Position.ALARM_VIBRATION); + case 0x87 -> position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); + case 0x88 -> position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); + case 0x90 -> position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + case 0x91 -> position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + case 0x92 -> position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + case 0x93 -> position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); } } else { @@ -1136,6 +1139,11 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ICCID, ByteBufUtil.hexDump(buf.readSlice(10)).replaceAll("f", "")); return position; + } else if (subType == 0x0b) { + + position.set("networkTechnology", buf.readByte() > 0 ? "4G" : "2G"); + return position; + } else if (subType == 0x0d) { if (buf.getByte(buf.readerIndex()) != '!') { @@ -1203,24 +1211,11 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { if (type == MSG_AZ735_ALARM) { switch (status) { - case 0xA0: - position.set(Position.KEY_ARMED, true); - break; - case 0xA1: - position.set(Position.KEY_ARMED, false); - break; - case 0xA2: - case 0xA3: - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - case 0xA4: - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - break; - case 0xA5: - position.set(Position.KEY_ALARM, Position.ALARM_DOOR); - break; - default: - break; + case 0xA0 -> position.set(Position.KEY_ARMED, true); + case 0xA1 -> position.set(Position.KEY_ARMED, false); + case 0xA2, 0xA3 -> position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + case 0xA4 -> position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); + case 0xA5 -> position.set(Position.KEY_ALARM, Position.ALARM_DOOR); } } @@ -1245,32 +1240,14 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { String[] values = pair.split("="); if (values.length >= 2) { switch (Integer.parseInt(values[0].substring(0, 2), 16)) { - case 40: - position.set(Position.KEY_ODOMETER, Integer.parseInt(values[1], 16) * 0.01); - break; - case 43: - position.set(Position.KEY_FUEL_LEVEL, Integer.parseInt(values[1], 16) * 0.01); - break; - case 45: - position.set(Position.KEY_COOLANT_TEMP, Integer.parseInt(values[1], 16) * 0.01); - break; - case 53: - position.set(Position.KEY_OBD_SPEED, Integer.parseInt(values[1], 16) * 0.01); - break; - case 54: - position.set(Position.KEY_RPM, Integer.parseInt(values[1], 16) * 0.01); - break; - case 71: - position.set(Position.KEY_FUEL_USED, Integer.parseInt(values[1], 16) * 0.01); - break; - case 73: - position.set(Position.KEY_HOURS, Integer.parseInt(values[1], 16) * 0.01); - break; - case 74: - position.set(Position.KEY_VIN, values[1]); - break; - default: - break; + case 40 -> position.set(Position.KEY_ODOMETER, Integer.parseInt(values[1], 16) * 0.01); + case 43 -> position.set(Position.KEY_FUEL_LEVEL, Integer.parseInt(values[1], 16) * 0.01); + case 45 -> position.set(Position.KEY_COOLANT_TEMP, Integer.parseInt(values[1], 16) * 0.01); + case 53 -> position.set(Position.KEY_OBD_SPEED, Integer.parseInt(values[1], 16) * 0.01); + case 54 -> position.set(Position.KEY_RPM, Integer.parseInt(values[1], 16) * 0.01); + case 71 -> position.set(Position.KEY_FUEL_USED, Integer.parseInt(values[1], 16) * 0.01); + case 73 -> position.set(Position.KEY_HOURS, Integer.parseInt(values[1], 16) * 0.01); + case 74 -> position.set(Position.KEY_VIN, values[1]); } } } @@ -1284,16 +1261,10 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { int moduleLength = buf.readUnsignedShort(); switch (moduleType) { - case 0x03: - position.set(Position.KEY_ICCID, ByteBufUtil.hexDump(buf.readSlice(10))); - break; - case 0x09: - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - break; - case 0x0a: - position.set(Position.KEY_SATELLITES_VISIBLE, buf.readUnsignedByte()); - break; - case 0x11: + case 0x03 -> position.set(Position.KEY_ICCID, ByteBufUtil.hexDump(buf.readSlice(10))); + case 0x09 -> position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + case 0x0a -> position.set(Position.KEY_SATELLITES_VISIBLE, buf.readUnsignedByte()); + case 0x11 -> { CellTower cellTower = CellTower.from( buf.readUnsignedShort(), buf.readUnsignedShort(), @@ -1303,22 +1274,16 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { if (cellTower.getCellId() > 0) { position.setNetwork(new Network(cellTower)); } - break; - case 0x18: - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); - break; - case 0x28: - position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); - break; - case 0x29: - position.set(Position.KEY_INDEX, buf.readUnsignedInt()); - break; - case 0x2a: + } + case 0x18 -> position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); + case 0x28 -> position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); + case 0x29 -> position.set(Position.KEY_INDEX, buf.readUnsignedInt()); + case 0x2a -> { int input = buf.readUnsignedByte(); position.set(Position.KEY_DOOR, BitUtil.to(input, 4) > 0); position.set("tamper", BitUtil.from(input, 4) > 0); - break; - case 0x2b: + } + case 0x2b -> { int event = buf.readUnsignedByte(); switch (event) { case 0x11: @@ -1337,11 +1302,9 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { break; } position.set(Position.KEY_EVENT, event); - break; - case 0x2e: - position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); - break; - case 0x33: + } + case 0x2e -> position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); + case 0x33 -> { position.setTime(new Date(buf.readUnsignedInt() * 1000)); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); position.setAltitude(buf.readShort()); @@ -1363,15 +1326,13 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.setLatitude(latitude); position.setLongitude(longitude); - break; - case 0x34: + } + case 0x34 -> { position.set(Position.KEY_EVENT, buf.readUnsignedByte()); buf.readUnsignedIntLE(); // time buf.skipBytes(buf.readUnsignedByte()); // content - break; - default: - buf.skipBytes(moduleLength); - break; + } + default -> buf.skipBytes(moduleLength); } } @@ -1486,12 +1447,20 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { variant = Variant.JC400; } else if (header == 0x7878 && type == MSG_LBS_3 && length == 0x37) { variant = Variant.SL4X; + } else if (header == 0x7878 && type == MSG_GPS_LBS_5 && length == 0x2a) { + variant = Variant.SL4X; } else if (header == 0x7878 && type == MSG_GPS_LBS_STATUS_4 && length == 0x27) { variant = Variant.SL4X; + } else if (header == 0x7878 && type == MSG_GPS_LBS_STATUS_4 && length == 0x29) { + variant = Variant.SL4X; } else if (header == 0x7878 && type == MSG_GPS_LBS_2 && length == 0x2f) { variant = Variant.SEEWORLD; } else if (header == 0x7878 && type == MSG_GPS_LBS_STATUS_1 && length == 0x26) { variant = Variant.SEEWORLD; + } else if (header == 0x7878 && type == MSG_GPS_LBS_RFID && length == 0x28) { + variant = Variant.RFID; + } else if (header == 0x7878 && type == MSG_GPS_LBS_STATUS_5 && length == 0x40) { + variant = Variant.LW4G; } else { variant = Variant.STANDARD; } diff --git a/src/main/java/org/traccar/protocol/Gt30ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Gt30ProtocolDecoder.java index fb3a2b8ae..b02285f69 100644 --- a/src/main/java/org/traccar/protocol/Gt30ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Gt30ProtocolDecoder.java @@ -55,20 +55,13 @@ public class Gt30ProtocolDecoder extends BaseProtocolDecoder { .compile(); private String decodeAlarm(int value) { - switch (value) { - case 0x01: - case 0x02: - case 0x03: - return Position.ALARM_SOS; - case 0x10: - return Position.ALARM_LOW_BATTERY; - case 0x11: - return Position.ALARM_OVERSPEED; - case 0x12: - return Position.ALARM_GEOFENCE; - default: - return null; - } + return switch (value) { + case 0x01, 0x02, 0x03 -> Position.ALARM_SOS; + case 0x10 -> Position.ALARM_LOW_BATTERY; + case 0x11 -> Position.ALARM_OVERSPEED; + case 0x12 -> Position.ALARM_GEOFENCE; + default -> null; + }; } @Override diff --git a/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java b/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java index 2ad4f644b..38c063b52 100644 --- a/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/H02ProtocolDecoder.java @@ -598,7 +598,7 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { String marker = buf.toString(0, 1, StandardCharsets.US_ASCII); switch (marker) { - case "*": + case "*" -> { String sentence = buf.toString(StandardCharsets.US_ASCII).trim(); int typeStart = sentence.indexOf(',', sentence.indexOf(',') + 1) + 1; int typeEnd = sentence.indexOf(',', typeStart); @@ -607,33 +607,30 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { } if (typeEnd > 0) { String type = sentence.substring(typeStart, typeEnd); - switch (type) { - case "V0": - case "HTBT": + return switch (type) { + case "V0", "HTBT" -> { if (channel != null) { String response = sentence.substring(0, typeEnd) + "#"; channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } - return decodeHeartbeat(sentence, channel, remoteAddress); - case "NBR": - return decodeLbs(sentence, channel, remoteAddress); - case "LINK": - return decodeLink(sentence, channel, remoteAddress); - case "V3": - return decodeV3(sentence, channel, remoteAddress); - case "VP1": - return decodeVp1(sentence, channel, remoteAddress); - default: - return decodeText(sentence, channel, remoteAddress); - } + yield decodeHeartbeat(sentence, channel, remoteAddress); + } + case "NBR" -> decodeLbs(sentence, channel, remoteAddress); + case "LINK" -> decodeLink(sentence, channel, remoteAddress); + case "V3" -> decodeV3(sentence, channel, remoteAddress); + case "VP1" -> decodeVp1(sentence, channel, remoteAddress); + default -> decodeText(sentence, channel, remoteAddress); + }; } else { return null; } - case "$": + } + case "$" -> { return decodeBinary(buf, channel, remoteAddress); - case "X": - default: + } + default -> { return null; + } } } diff --git a/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java b/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java index 86b8c80d4..8a0d232a0 100644 --- a/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/H02ProtocolEncoder.java @@ -49,27 +49,23 @@ public class H02ProtocolEncoder extends StringProtocolEncoder { protected Object encodeCommand(Command command, Date time) { String uniqueId = getUniqueId(command.getDeviceId()); - switch (command.getType()) { - case Command.TYPE_ALARM_ARM: - return formatCommand(time, uniqueId, "SCF", "0", "0"); - case Command.TYPE_ALARM_DISARM: - return formatCommand(time, uniqueId, "SCF", "1", "1"); - case Command.TYPE_ENGINE_STOP: - return formatCommand(time, uniqueId, "S20", "1", "1"); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(time, uniqueId, "S20", "1", "0"); - case Command.TYPE_POSITION_PERIODIC: + return switch (command.getType()) { + case Command.TYPE_ALARM_ARM -> formatCommand(time, uniqueId, "SCF", "0", "0"); + case Command.TYPE_ALARM_DISARM -> formatCommand(time, uniqueId, "SCF", "1", "1"); + case Command.TYPE_ENGINE_STOP -> formatCommand(time, uniqueId, "S20", "1", "1"); + case Command.TYPE_ENGINE_RESUME -> formatCommand(time, uniqueId, "S20", "1", "0"); + case Command.TYPE_POSITION_PERIODIC -> { String frequency = command.getAttributes().get(Command.KEY_FREQUENCY).toString(); if (AttributeUtil.lookup( getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), command.getDeviceId())) { - return formatCommand(time, uniqueId, "D1", frequency); + yield formatCommand(time, uniqueId, "D1", frequency); } else { - return formatCommand(time, uniqueId, "S71", "22", frequency); + yield formatCommand(time, uniqueId, "S71", "22", frequency); } - default: - return null; - } + } + default -> null; + }; } @Override diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java index 7d634b0f2..d020b5e44 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocolDecoder.java @@ -72,24 +72,16 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder { } private String decodeAlarm(int event) { - switch (event) { - case 4: - return Position.ALARM_FATIGUE_DRIVING; - case 6: - return Position.ALARM_SOS; - case 7: - return Position.ALARM_BRAKING; - case 8: - return Position.ALARM_ACCELERATION; - case 9: - return Position.ALARM_CORNERING; - case 10: - return Position.ALARM_ACCIDENT; - case 16: - return Position.ALARM_REMOVING; - default: - return null; - } + return switch (event) { + case 4 -> Position.ALARM_FATIGUE_DRIVING; + case 6 -> Position.ALARM_SOS; + case 7 -> Position.ALARM_BRAKING; + case 8 -> Position.ALARM_ACCELERATION; + case 9 -> Position.ALARM_CORNERING; + case 10 -> Position.ALARM_ACCIDENT; + case 16 -> Position.ALARM_REMOVING; + default -> null; + }; } @Override @@ -163,21 +155,12 @@ public class HuaShengProtocolDecoder extends BaseProtocolDecoder { while (buf.readableBytes() > 2) { String value = ByteBufUtil.hexDump(buf.readSlice(2)); int digit = Integer.parseInt(value.substring(0, 1), 16); - char prefix; - switch (digit >> 2) { - default: - prefix = 'P'; - break; - case 1: - prefix = 'C'; - break; - case 2: - prefix = 'B'; - break; - case 3: - prefix = 'U'; - break; - } + char prefix = switch (digit >> 2) { + default -> 'P'; + case 1 -> 'C'; + case 2 -> 'B'; + case 3 -> 'U'; + }; codes.append(prefix).append(digit % 4).append(value.substring(1)); if (buf.readableBytes() > 2) { codes.append(' '); diff --git a/src/main/java/org/traccar/protocol/HuaShengProtocolEncoder.java b/src/main/java/org/traccar/protocol/HuaShengProtocolEncoder.java index dc34f7b4e..7f9903e5e 100644 --- a/src/main/java/org/traccar/protocol/HuaShengProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/HuaShengProtocolEncoder.java @@ -54,14 +54,6 @@ public class HuaShengProtocolEncoder extends BaseProtocolEncoder { content.writeShort(command.getInteger(Command.KEY_FREQUENCY)); return encodeContent(HuaShengProtocolDecoder.MSG_SET_REQ, content); case Command.TYPE_OUTPUT_CONTROL: - /* -0x01: Lock the relay1; //relay on -0x02: Unlock the relay1; //relay off -0x03: Lock the relay2; //relay2 on -0x04: Unlock the relay2; //relay2 off -0x05: Lock the relay3; //relay3 on -0x06: Unlock the relay3; //realy3 off - */ content.writeByte( (command.getInteger(Command.KEY_INDEX) - 1) * 2 + (2 - command.getInteger(Command.KEY_DATA))); diff --git a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java index d010a8fe0..443da28a3 100644 --- a/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/HuabaoProtocolDecoder.java @@ -323,77 +323,39 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { int type = buf.readUnsignedByte(); int length = buf.readUnsignedByte(); switch (type) { - case 0x01: - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 100L); - break; - case 0x02: - position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShort() * 0.1); - break; - case 0x03: - position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort() * 0.1); - break; - case 0x56: + case 0x01 -> position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 100L); + case 0x02 -> position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShort() * 0.1); + case 0x03 -> position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort() * 0.1); + case 0x56 -> { buf.readUnsignedByte(); // power level position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); - break; - case 0x61: - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); - break; - case 0x69: - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); - break; - case 0x80: - position.set(Position.KEY_OBD_SPEED, buf.readUnsignedByte()); - break; - case 0x81: - position.set(Position.KEY_RPM, buf.readUnsignedShort()); - break; - case 0x82: - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.1); - break; - case 0x83: - position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedByte()); - break; - case 0x84: - position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte() - 40); - break; - case 0x85: - position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort()); - break; - case 0x86: - position.set("intakeTemp", buf.readUnsignedByte() - 40); - break; - case 0x87: - position.set("intakeFlow", buf.readUnsignedShort()); - break; - case 0x88: - position.set("intakePressure", buf.readUnsignedByte()); - break; - case 0x89: - position.set(Position.KEY_THROTTLE, buf.readUnsignedByte()); - break; - case 0x8B: + } + case 0x61 -> position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.01); + case 0x69 -> position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.01); + case 0x80 -> position.set(Position.KEY_OBD_SPEED, buf.readUnsignedByte()); + case 0x81 -> position.set(Position.KEY_RPM, buf.readUnsignedShort()); + case 0x82 -> position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.1); + case 0x83 -> position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedByte()); + case 0x84 -> position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte() - 40); + case 0x85 -> position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort()); + case 0x86 -> position.set("intakeTemp", buf.readUnsignedByte() - 40); + case 0x87 -> position.set("intakeFlow", buf.readUnsignedShort()); + case 0x88 -> position.set("intakePressure", buf.readUnsignedByte()); + case 0x89 -> position.set(Position.KEY_THROTTLE, buf.readUnsignedByte()); + case 0x8B -> { position.set(Position.KEY_VIN, buf.readCharSequence(17, StandardCharsets.US_ASCII).toString()); - break; - case 0x8C: - position.set(Position.KEY_OBD_ODOMETER, buf.readUnsignedInt() * 100L); - break; - case 0x8D: - position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedShort() * 1000L); - break; - case 0x8E: - position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); - break; - case 0xA0: + } + case 0x8C -> position.set(Position.KEY_OBD_ODOMETER, buf.readUnsignedInt() * 100L); + case 0x8D -> position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedShort() * 1000L); + case 0x8E -> position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); + case 0xA0 -> { String codes = buf.readCharSequence(length, StandardCharsets.US_ASCII).toString(); position.set(Position.KEY_DTCS, codes.replace(',', ' ')); - break; - case 0xCC: + } + case 0xCC -> { position.set(Position.KEY_ICCID, buf.readCharSequence(20, StandardCharsets.US_ASCII).toString()); - break; - default: - buf.skipBytes(length); - break; + } + default -> buf.skipBytes(length); } } } @@ -543,20 +505,10 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedInt(); // alarm serial number buf.readUnsignedByte(); // alarm status switch (buf.readUnsignedByte()) { - case 0x01: - position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - break; - case 0x02: - position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); - break; - case 0x03: - position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); - break; - case 0x16: - position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); - break; - default: - break; + case 0x01 -> position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + case 0x02 -> position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + case 0x03 -> position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + case 0x16 -> position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); } break; case 0x69: @@ -710,68 +662,49 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); break; + case 0xF1: + position.set(Position.KEY_POWER, buf.readUnsignedInt() * 0.001); + break; case 0xF3: while (buf.readerIndex() < endIndex) { int extendedType = buf.readUnsignedShort(); int extendedLength = buf.readUnsignedByte(); switch (extendedType) { - case 0x0002: - position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort() * 0.1); - break; - case 0x0003: - position.set(Position.KEY_RPM, buf.readUnsignedShort()); - break; - case 0x0004: - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); - break; - case 0x0005: - position.set(Position.KEY_OBD_ODOMETER, buf.readUnsignedInt() * 100); - break; - case 0x0007: - position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 0.1); - break; - case 0x0008: - position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedShort() * 0.1); - break; - case 0x0009: - position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedShort() - 40); - break; - case 0x000B: - position.set("intakePressure", buf.readUnsignedShort()); - break; - case 0x000C: - position.set("intakeTemp", buf.readUnsignedShort() - 40); - break; - case 0x000D: - position.set("intakeFlow", buf.readUnsignedShort()); - break; - case 0x000E: - position.set(Position.KEY_THROTTLE, buf.readUnsignedShort() * 100 / 255); - break; - case 0x0050: + case 0x0002 -> position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort() * 0.1); + case 0x0003 -> position.set(Position.KEY_RPM, buf.readUnsignedShort()); + case 0x0004 -> position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); + case 0x0005 -> position.set(Position.KEY_OBD_ODOMETER, buf.readUnsignedInt() * 100); + case 0x0007 -> position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 0.1); + case 0x0008 -> position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedShort() * 0.1); + case 0x0009 -> position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedShort() - 40); + case 0x000B -> position.set("intakePressure", buf.readUnsignedShort()); + case 0x000C -> position.set("intakeTemp", buf.readUnsignedShort() - 40); + case 0x000D -> position.set("intakeFlow", buf.readUnsignedShort()); + case 0x000E -> position.set(Position.KEY_THROTTLE, buf.readUnsignedShort() * 100 / 255); + case 0x0050 -> { position.set(Position.KEY_VIN, buf.readSlice(17).toString(StandardCharsets.US_ASCII)); - break; - case 0x0100: - position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedShort() * 0.1); - break; - case 0x0102: - position.set("tripFuel", buf.readUnsignedShort() * 0.1); - break; - case 0x0112: - position.set("hardAccelerationCount", buf.readUnsignedShort()); - break; - case 0x0113: - position.set("hardDecelerationCount", buf.readUnsignedShort()); - break; - case 0x0114: - position.set("hardCorneringCount", buf.readUnsignedShort()); - break; - default: - buf.skipBytes(extendedLength); - break; + } + case 0x0100 -> position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedShort() * 0.1); + case 0x0102 -> position.set("tripFuel", buf.readUnsignedShort() * 0.1); + case 0x0112 -> position.set("hardAccelerationCount", buf.readUnsignedShort()); + case 0x0113 -> position.set("hardDecelerationCount", buf.readUnsignedShort()); + case 0x0114 -> position.set("hardCorneringCount", buf.readUnsignedShort()); + default -> buf.skipBytes(extendedLength); } } break; + case 0xF7: + position.set(Position.KEY_BATTERY, buf.readUnsignedInt() * 0.001); + if (length >= 5) { + short batteryStatus = buf.readUnsignedByte(); + if (batteryStatus == 2 || batteryStatus == 3) { + position.set(Position.KEY_CHARGE, true); + } + } + if (length >= 6) { + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + } + break; case 0xFE: if (length == 1) { position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); @@ -982,77 +915,34 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { int id = buf.readUnsignedShort(); int length = buf.readUnsignedByte(); switch (id) { - case 0x0102: - case 0x0528: - case 0x0546: + case 0x0102, 0x0528, 0x0546 -> { position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 100); - break; - case 0x0103: - position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedInt() * 0.01); - break; - case 0x0111: - position.set("fuelTemp", buf.readUnsignedByte() - 40); - break; - case 0x012E: - position.set("oilLevel", buf.readUnsignedShort() * 0.1); - break; - case 0x052A: - position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShort() * 0.01); - break; - case 0x0105: - case 0x052C: - position.set(Position.KEY_FUEL_USED, buf.readUnsignedInt() * 0.01); - break; - case 0x014A: - case 0x0537: - case 0x0538: - case 0x0539: + } + case 0x0103 -> position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedInt() * 0.01); + case 0x0111 -> position.set("fuelTemp", buf.readUnsignedByte() - 40); + case 0x012E -> position.set("oilLevel", buf.readUnsignedShort() * 0.1); + case 0x052A -> position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShort() * 0.01); + case 0x0105, 0x052C -> position.set(Position.KEY_FUEL_USED, buf.readUnsignedInt() * 0.01); + case 0x014A, 0x0537, 0x0538, 0x0539 -> { position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() * 0.01); - break; - case 0x052B: - position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); - break; - case 0x052D: - position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte() - 40); - break; - case 0x052E: - position.set("airTemp", buf.readUnsignedByte() - 40); - break; - case 0x0530: - position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); - break; - case 0x0535: - position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort() * 0.1); - break; - case 0x0536: - position.set(Position.KEY_RPM, buf.readUnsignedShort()); - break; - case 0x053D: - position.set("intakePressure", buf.readUnsignedShort() * 0.1); - break; - case 0x0544: - position.set("liquidLevel", buf.readUnsignedByte()); - break; - case 0x0547: - case 0x0548: - position.set(Position.KEY_THROTTLE, buf.readUnsignedByte()); - break; - default: + } + case 0x052B -> position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); + case 0x052D -> position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte() - 40); + case 0x052E -> position.set("airTemp", buf.readUnsignedByte() - 40); + case 0x0530 -> position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); + case 0x0535 -> position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort() * 0.1); + case 0x0536 -> position.set(Position.KEY_RPM, buf.readUnsignedShort()); + case 0x053D -> position.set("intakePressure", buf.readUnsignedShort() * 0.1); + case 0x0544 -> position.set("liquidLevel", buf.readUnsignedByte()); + case 0x0547, 0x0548 -> position.set(Position.KEY_THROTTLE, buf.readUnsignedByte()); + default -> { switch (length) { - case 1: - position.set(Position.PREFIX_IO + id, buf.readUnsignedByte()); - break; - case 2: - position.set(Position.PREFIX_IO + id, buf.readUnsignedShort()); - break; - case 4: - position.set(Position.PREFIX_IO + id, buf.readUnsignedInt()); - break; - default: - buf.skipBytes(length); - break; + case 1 -> position.set(Position.PREFIX_IO + id, buf.readUnsignedByte()); + case 2 -> position.set(Position.PREFIX_IO + id, buf.readUnsignedShort()); + case 4 -> position.set(Position.PREFIX_IO + id, buf.readUnsignedInt()); + default -> buf.skipBytes(length); } - break; + } } } getLastLocation(position, time); @@ -1133,24 +1023,12 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder { case 0x15: int event = buf.readInt(); switch (event) { - case 51: - position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - break; - case 52: - position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); - break; - case 53: - position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); - break; - case 54: - position.set(Position.KEY_ALARM, Position.ALARM_LANE_CHANGE); - break; - case 56: - position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); - break; - default: - position.set(Position.KEY_EVENT, event); - break; + case 51 -> position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + case 52 -> position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + case 53 -> position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + case 54 -> position.set(Position.KEY_ALARM, Position.ALARM_LANE_CHANGE); + case 56 -> position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); + default -> position.set(Position.KEY_EVENT, event); } getLastLocation(position, time); break; diff --git a/src/main/java/org/traccar/protocol/IntellitracProtocolDecoder.java b/src/main/java/org/traccar/protocol/IntellitracProtocolDecoder.java index b86584016..0a8331218 100644 --- a/src/main/java/org/traccar/protocol/IntellitracProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/IntellitracProtocolDecoder.java @@ -66,27 +66,17 @@ public class IntellitracProtocolDecoder extends BaseProtocolDecoder { .compile(); private String decodeAlarm(int value) { - switch (value) { - case 164: - return Position.ALARM_GEOFENCE_ENTER; - case 165: - return Position.ALARM_GEOFENCE_EXIT; - case 168: - case 169: - return Position.ALARM_LOW_POWER; - case 170: - return Position.ALARM_POWER_OFF; - case 176: - return Position.ALARM_POWER_RESTORED; - case 180: - return Position.ALARM_FALL_DOWN; - case 225: - return Position.ALARM_JAMMING; - case 995: - return Position.ALARM_SOS; - default: - return null; - } + return switch (value) { + case 164 -> Position.ALARM_GEOFENCE_ENTER; + case 165 -> Position.ALARM_GEOFENCE_EXIT; + case 168, 169 -> Position.ALARM_LOW_POWER; + case 170 -> Position.ALARM_POWER_OFF; + case 176 -> Position.ALARM_POWER_RESTORED; + case 180 -> Position.ALARM_FALL_DOWN; + case 225 -> Position.ALARM_JAMMING; + case 995 -> Position.ALARM_SOS; + default -> null; + }; } @Override diff --git a/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java b/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java index d9e6670c6..7ad2befc7 100644 --- a/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java @@ -36,193 +36,92 @@ public class IotmProtocolDecoder extends BaseMqttProtocolDecoder { } private Object readValue(ByteBuf buf, int sensorType) { - switch (sensorType) { - case 0: - return false; - case 1: - return true; - case 3: - return 0; - case 4: - return buf.readUnsignedByte(); - case 5: - return buf.readUnsignedShortLE(); - case 6: - return buf.readUnsignedIntLE(); - case 7: - case 11: - return buf.readLongLE(); - case 8: - return buf.readByte(); - case 9: - return buf.readShortLE(); - case 10: - return buf.readIntLE(); - case 12: - return buf.readFloatLE(); - case 13: - return buf.readDoubleLE(); - case 32: - return buf.readCharSequence(buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString(); - case 33: - return ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte())); - case 64: - return buf.readCharSequence(buf.readUnsignedShortLE(), StandardCharsets.US_ASCII).toString(); - case 65: - return ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedShortLE())); - case 2: - default: - return null; - } + return switch (sensorType) { + case 0 -> false; + case 1 -> true; + case 3 -> 0; + case 4 -> buf.readUnsignedByte(); + case 5 -> buf.readUnsignedShortLE(); + case 6 -> buf.readUnsignedIntLE(); + case 7, 11 -> buf.readLongLE(); + case 8 -> buf.readByte(); + case 9 -> buf.readShortLE(); + case 10 -> buf.readIntLE(); + case 12 -> buf.readFloatLE(); + case 13 -> buf.readDoubleLE(); + case 32 -> buf.readCharSequence(buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString(); + case 33 -> ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte())); + case 64 -> buf.readCharSequence(buf.readUnsignedShortLE(), StandardCharsets.US_ASCII).toString(); + case 65 -> ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedShortLE())); + default -> null; + }; } private void decodeSensor(Position position, ByteBuf record, int sensorType, int sensorId) { String key; switch (sensorId) { - case 0x0002: - position.set(Position.KEY_MOTION, sensorType > 0); - break; - case 0x0008: - case 0x009B: + case 0x0002 -> position.set(Position.KEY_MOTION, sensorType > 0); + case 0x0008, 0x009B -> { if (sensorType > 0) { position.set(Position.KEY_ALARM, Position.ALARM_JAMMING); } - break; - case 0x0010: - case 0x0011: - case 0x0012: - case 0x0013: - case 0x0014: - case 0x0015: + } + case 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015 -> { key = Position.PREFIX_IN + (sensorId - 0x0010 + 2); position.set(key, sensorType > 0); - break; - case 0x0062: - position.set("doorFL", sensorType > 0); - break; - case 0x0063: - position.set("doorFR", sensorType > 0); - break; - case 0x0064: - position.set("doorRL", sensorType > 0); - break; - case 0x0065: - position.set("doorRR", sensorType > 0); - break; - case 0x001E: - position.set("buttonPresent", sensorType > 0); - break; - case 0x006D: - position.set(Position.KEY_IGNITION, sensorType > 0); - break; - case 0x008B: - position.set("handBrake", sensorType > 0); - break; - case 0x008C: - position.set("footBrake", sensorType > 0); - break; - case 0x0094: - case 0x0095: - case 0x0096: + } + case 0x0062 -> position.set("doorFL", sensorType > 0); + case 0x0063 -> position.set("doorFR", sensorType > 0); + case 0x0064 -> position.set("doorRL", sensorType > 0); + case 0x0065 -> position.set("doorRR", sensorType > 0); + case 0x001E -> position.set("buttonPresent", sensorType > 0); + case 0x006D -> position.set(Position.KEY_IGNITION, sensorType > 0); + case 0x008B -> position.set("handBrake", sensorType > 0); + case 0x008C -> position.set("footBrake", sensorType > 0); + case 0x0094, 0x0095, 0x0096 -> { key = Position.PREFIX_OUT + (sensorId - 0x0094 + 1); position.set(key, sensorType > 0); - break; - case 0x009A: - position.set(Position.PREFIX_OUT + 4, sensorType > 0); - break; - case 0x2000: - position.set(Position.KEY_OBD_SPEED, record.readUnsignedByte()); - break; - case 0x2001: - position.set(Position.KEY_SATELLITES, record.readUnsignedByte()); - break; - case 0x2006: - position.set(Position.KEY_THROTTLE, record.readUnsignedByte()); - break; - case 0x2007: - position.set(Position.KEY_FUEL_LEVEL, record.readUnsignedByte()); - break; - case 0x2008: - position.set(Position.KEY_COOLANT_TEMP, record.readUnsignedByte()); - break; - case 0x2009: - position.set("fuel2", record.readUnsignedByte()); - break; - case 0x200A: - position.set(Position.KEY_ENGINE_LOAD, record.readUnsignedByte()); - break; - case 0x2041: - position.set(Position.KEY_BATTERY_LEVEL, record.readUnsignedByte()); - break; - case 0x3000: - position.set(Position.KEY_POWER, record.readUnsignedShortLE() * 0.001); - break; - case 0x3001: - case 0x3002: - case 0x3003: + } + case 0x009A -> position.set(Position.PREFIX_OUT + 4, sensorType > 0); + case 0x2000 -> position.set(Position.KEY_OBD_SPEED, record.readUnsignedByte()); + case 0x2001 -> position.set(Position.KEY_SATELLITES, record.readUnsignedByte()); + case 0x2006 -> position.set(Position.KEY_THROTTLE, record.readUnsignedByte()); + case 0x2007 -> position.set(Position.KEY_FUEL_LEVEL, record.readUnsignedByte()); + case 0x2008 -> position.set(Position.KEY_COOLANT_TEMP, record.readUnsignedByte()); + case 0x2009 -> position.set("fuel2", record.readUnsignedByte()); + case 0x200A -> position.set(Position.KEY_ENGINE_LOAD, record.readUnsignedByte()); + case 0x2041 -> position.set(Position.KEY_BATTERY_LEVEL, record.readUnsignedByte()); + case 0x3000 -> position.set(Position.KEY_POWER, record.readUnsignedShortLE() * 0.001); + case 0x3001, 0x3002, 0x3003 -> { key = Position.PREFIX_ADC + (0x3003 - sensorId + 3); position.set(key, record.readUnsignedShortLE() * 0.001); - break; - case 0x3004: - position.set(Position.KEY_BATTERY, record.readUnsignedShortLE() * 0.001); - break; - case 0x300C: - position.set(Position.KEY_RPM, record.readUnsignedShortLE()); - break; - case 0x3021: - position.set(Position.KEY_FUEL_CONSUMPTION, record.readUnsignedShortLE() * 0.05); - break; - case 0x3037: - position.set("cargoWeight", record.readUnsignedShortLE() * 2); - break; - case 0x4001: - position.set(Position.KEY_FUEL_USED, record.readUnsignedIntLE()); - break; - case 0x4002: - position.set(Position.KEY_HOURS, record.readUnsignedIntLE()); - break; - case 0x4003: - position.set(Position.KEY_ODOMETER, record.readUnsignedIntLE() * 5); - break; - case 0x4063: - position.set(Position.KEY_AXLE_WEIGHT, record.readUnsignedIntLE()); - break; - case 0x5000: - position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(record.readLongLE())); - break; - case 0x5004: - case 0x5005: - case 0x5006: - case 0x5007: + } + case 0x3004 -> position.set(Position.KEY_BATTERY, record.readUnsignedShortLE() * 0.001); + case 0x300C -> position.set(Position.KEY_RPM, record.readUnsignedShortLE()); + case 0x3021 -> position.set(Position.KEY_FUEL_CONSUMPTION, record.readUnsignedShortLE() * 0.05); + case 0x3037 -> position.set("cargoWeight", record.readUnsignedShortLE() * 2); + case 0x4001 -> position.set(Position.KEY_FUEL_USED, record.readUnsignedIntLE()); + case 0x4002 -> position.set(Position.KEY_HOURS, record.readUnsignedIntLE()); + case 0x4003 -> position.set(Position.KEY_ODOMETER, record.readUnsignedIntLE() * 5); + case 0x4063 -> position.set(Position.KEY_AXLE_WEIGHT, record.readUnsignedIntLE()); + case 0x5000 -> position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(record.readLongLE())); + case 0x5004, 0x5005, 0x5006, 0x5007 -> { key = Position.PREFIX_TEMP + (sensorId - 0x5004 + 1); position.set(key, record.readLongLE()); - break; - case 0x500D: - position.set("trailerId", String.valueOf(record.readLongLE())); - break; - case 0xA000: - position.set(Position.KEY_DEVICE_TEMP, record.readFloatLE()); - break; - case 0xA001: - position.set(Position.KEY_ACCELERATION, record.readFloatLE()); - break; - case 0xA002: - position.set("cornering", record.readFloatLE()); - break; - case 0xA017: - case 0xA018: - case 0xA019: - case 0xA01A: + } + case 0x500D -> position.set("trailerId", String.valueOf(record.readLongLE())); + case 0xA000 -> position.set(Position.KEY_DEVICE_TEMP, record.readFloatLE()); + case 0xA001 -> position.set(Position.KEY_ACCELERATION, record.readFloatLE()); + case 0xA002 -> position.set("cornering", record.readFloatLE()); + case 0xA017, 0xA018, 0xA019, 0xA01A -> { key = Position.PREFIX_TEMP + (sensorId - 0xA017 + 1); position.set(key, record.readFloatLE()); - break; - case 0xB002: - position.set(Position.KEY_OBD_ODOMETER, record.readDoubleLE()); - break; - default: + } + case 0xB002 -> position.set(Position.KEY_OBD_ODOMETER, record.readDoubleLE()); + default -> { key = Position.PREFIX_IO + sensorId; position.getAttributes().put(key, readValue(record, sensorType)); - break; + } } } diff --git a/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java b/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java index 8a8d734cf..832275239 100644 --- a/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ItsProtocolDecoder.java @@ -116,29 +116,18 @@ public class ItsProtocolDecoder extends BaseProtocolDecoder { .compile(); private String decodeAlarm(String status) { - switch (status) { - case "WD": - case "EA": - return Position.ALARM_SOS; - case "BL": - return Position.ALARM_LOW_BATTERY; - case "HB": - return Position.ALARM_BRAKING; - case "HA": - return Position.ALARM_ACCELERATION; - case "RT": - return Position.ALARM_CORNERING; - case "OS": - return Position.ALARM_OVERSPEED; - case "TA": - return Position.ALARM_TAMPERING; - case "BD": - return Position.ALARM_POWER_CUT; - case "BR": - return Position.ALARM_POWER_RESTORED; - default: - return null; - } + return switch (status) { + case "WD", "EA" -> Position.ALARM_SOS; + case "BL" -> Position.ALARM_LOW_BATTERY; + case "HB" -> Position.ALARM_BRAKING; + case "HA" -> Position.ALARM_ACCELERATION; + case "RT" -> Position.ALARM_CORNERING; + case "OS" -> Position.ALARM_OVERSPEED; + case "TA" -> Position.ALARM_TAMPERING; + case "BD" -> Position.ALARM_POWER_CUT; + case "BR" -> Position.ALARM_POWER_RESTORED; + default -> null; + }; } @Override diff --git a/src/main/java/org/traccar/protocol/ItsProtocolEncoder.java b/src/main/java/org/traccar/protocol/ItsProtocolEncoder.java index f82b8e3ac..60536485c 100644 --- a/src/main/java/org/traccar/protocol/ItsProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/ItsProtocolEncoder.java @@ -27,15 +27,11 @@ public class ItsProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Command command) { - - switch (command.getType()) { - case Command.TYPE_ENGINE_STOP: - return "@SET#RLP,OP1,"; - case Command.TYPE_ENGINE_RESUME: - return "@CLR#RLP,OP1,"; - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_ENGINE_STOP -> "@SET#RLP,OP1,"; + case Command.TYPE_ENGINE_RESUME -> "@CLR#RLP,OP1,"; + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/Ivt401ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Ivt401ProtocolDecoder.java index 972f22ebe..1b2b84a2e 100644 --- a/src/main/java/org/traccar/protocol/Ivt401ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Ivt401ProtocolDecoder.java @@ -159,17 +159,11 @@ public class Ivt401ProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext(6)) { position.set(Position.KEY_ALARM, parser.nextInt() == 1 ? Position.ALARM_OVERSPEED : null); switch (parser.nextInt()) { - case 1: - position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - break; - case 2: - position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); - break; - case 3: - position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); - break; - default: - break; + case 1 -> position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + case 2 -> position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + case 3 -> position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + default -> { + } } position.set(Position.KEY_ALARM, parser.nextInt() == 1 ? Position.ALARM_LOW_BATTERY : null); position.set(Position.KEY_ALARM, parser.nextInt() == 1 ? Position.ALARM_POWER_CUT : null); diff --git a/src/main/java/org/traccar/protocol/JidoProtocolDecoder.java b/src/main/java/org/traccar/protocol/JidoProtocolDecoder.java index 98fb36e11..d843ba675 100644 --- a/src/main/java/org/traccar/protocol/JidoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/JidoProtocolDecoder.java @@ -66,14 +66,11 @@ public class JidoProtocolDecoder extends BaseProtocolDecoder { .compile(); private String decodeAlarm(int type) { - switch (type) { - case 3: - return Position.ALARM_LOW_BATTERY; - case 4: - return Position.ALARM_TAMPERING; - default: - return null; - } + return switch (type) { + case 3 -> Position.ALARM_LOW_BATTERY; + case 4 -> Position.ALARM_TAMPERING; + default -> null; + }; } @Override diff --git a/src/main/java/org/traccar/protocol/Jt600ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Jt600ProtocolEncoder.java index 199467a38..1b1ccb981 100644 --- a/src/main/java/org/traccar/protocol/Jt600ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Jt600ProtocolEncoder.java @@ -30,19 +30,16 @@ public class Jt600ProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_ENGINE_STOP: - return "(S07,0)"; - case Command.TYPE_ENGINE_RESUME: - return "(S07,1)"; - case Command.TYPE_SET_TIMEZONE: + return switch (command.getType()) { + case Command.TYPE_ENGINE_STOP -> "(S07,0)"; + case Command.TYPE_ENGINE_RESUME -> "(S07,1)"; + case Command.TYPE_SET_TIMEZONE -> { int offset = TimeZone.getTimeZone(command.getString(Command.KEY_TIMEZONE)).getRawOffset() / 60000; - return "(S09,1," + offset + ")"; - case Command.TYPE_REBOOT_DEVICE: - return "(S17)"; - default: - return null; - } + yield "(S09,1," + offset + ")"; + } + case Command.TYPE_REBOOT_DEVICE -> "(S17)"; + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/KhdProtocolDecoder.java b/src/main/java/org/traccar/protocol/KhdProtocolDecoder.java index 2b234ab21..6ef280166 100644 --- a/src/main/java/org/traccar/protocol/KhdProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/KhdProtocolDecoder.java @@ -191,15 +191,11 @@ public class KhdProtocolDecoder extends BaseProtocolDecoder { int dataLength = buf.readUnsignedByte(); switch (dataType) { - case 0x01: - position.set(Position.KEY_FUEL_LEVEL, - buf.readUnsignedByte() * 100 + buf.readUnsignedByte()); - break; - case 0x02: - position.set(Position.PREFIX_TEMP + 1, - buf.readUnsignedByte() * 100 + buf.readUnsignedByte()); - break; - case 0x05: + case 0x01 -> position.set(Position.KEY_FUEL_LEVEL, + buf.readUnsignedByte() * 100 + buf.readUnsignedByte()); + case 0x02 -> position.set(Position.PREFIX_TEMP + 1, + buf.readUnsignedByte() * 100 + buf.readUnsignedByte()); + case 0x05 -> { int sign = buf.readUnsignedByte(); switch (sign) { case 1: @@ -212,19 +208,17 @@ public class KhdProtocolDecoder extends BaseProtocolDecoder { break; } position.set(Position.KEY_DRIVER_UNIQUE_ID, BufferUtil.readString(buf, dataLength - 1)); - break; - case 0x18: + } + case 0x18 -> { for (int i = 1; i <= 4; i++) { double value = buf.readUnsignedShort(); if (value > 0x0000 && value < 0xFFFF) { position.set("fuel" + i, value / 0xFFFE); } } - break; - case 0x20: - position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); - break; - case 0x23: + } + case 0x20 -> position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + case 0x23 -> { Network network = new Network(); int count = buf.readUnsignedByte(); for (int i = 0; i < count; i++) { @@ -235,9 +229,7 @@ public class KhdProtocolDecoder extends BaseProtocolDecoder { if (count > 0) { position.setNetwork(network); } - break; - default: - break; + } } } diff --git a/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java b/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java index 12353b415..c91743a4f 100644 --- a/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/KhdProtocolEncoder.java @@ -73,26 +73,20 @@ public class KhdProtocolEncoder extends BaseProtocolEncoder { String uniqueId = getUniqueId(command.getDeviceId()); - switch (command.getType()) { - case Command.TYPE_ENGINE_STOP: - return encodeCommand(MSG_CUT_OIL, uniqueId, null); - case Command.TYPE_ENGINE_RESUME: - return encodeCommand(MSG_RESUME_OIL, uniqueId, null); - case Command.TYPE_GET_VERSION: - return encodeCommand(MSG_CHECK_VERSION, uniqueId, null); - case Command.TYPE_FACTORY_RESET: - return encodeCommand(MSG_FACTORY_RESET, uniqueId, null); - case Command.TYPE_SET_SPEED_LIMIT: + return switch (command.getType()) { + case Command.TYPE_ENGINE_STOP -> encodeCommand(MSG_CUT_OIL, uniqueId, null); + case Command.TYPE_ENGINE_RESUME -> encodeCommand(MSG_RESUME_OIL, uniqueId, null); + case Command.TYPE_GET_VERSION -> encodeCommand(MSG_CHECK_VERSION, uniqueId, null); + case Command.TYPE_FACTORY_RESET -> encodeCommand(MSG_FACTORY_RESET, uniqueId, null); + case Command.TYPE_SET_SPEED_LIMIT -> { ByteBuf content = Unpooled.buffer(); content.writeByte(command.getInteger(Command.KEY_DATA)); - return encodeCommand(MSG_RESUME_OIL, uniqueId, content); - case Command.TYPE_SET_ODOMETER: - return encodeCommand(MSG_DELETE_MILEAGE, uniqueId, null); - case Command.TYPE_POSITION_SINGLE: - return encodeCommand(MSG_ON_DEMAND_TRACK, uniqueId, null); - default: - return null; - } + yield encodeCommand(MSG_RESUME_OIL, uniqueId, content); + } + case Command.TYPE_SET_ODOMETER -> encodeCommand(MSG_DELETE_MILEAGE, uniqueId, null); + case Command.TYPE_POSITION_SINGLE -> encodeCommand(MSG_ON_DEMAND_TRACK, uniqueId, null); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/L100ProtocolDecoder.java b/src/main/java/org/traccar/protocol/L100ProtocolDecoder.java index 820de8f1c..62fb6b7bb 100644 --- a/src/main/java/org/traccar/protocol/L100ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/L100ProtocolDecoder.java @@ -242,17 +242,9 @@ public class L100ProtocolDecoder extends BaseProtocolDecoder { parser.next(); // reserved switch (parser.nextInt()) { - case 0: - position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); - break; - case 2: - position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - break; - case 1: - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - break; - default: - break; + case 0 -> position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + case 2 -> position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + case 1 -> position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); } position.set(Position.KEY_CHARGE, parser.nextInt() == 1); @@ -314,14 +306,8 @@ public class L100ProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); switch (parser.next()) { - case "P": - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - break; - case "T": - position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); - break; - default: - break; + case "P" -> position.set(Position.KEY_ALARM, Position.ALARM_SOS); + case "T" -> position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); } position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java index 343d42e09..3e7d53ced 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java @@ -82,31 +82,19 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { .compile(); private String decodeAlarm(String event) { - switch (event) { - case "Z": - return Position.ALARM_LOW_BATTERY; - case "Y": - return Position.ALARM_TOW; - case "X": - return Position.ALARM_GEOFENCE_ENTER; - case "T": - return Position.ALARM_TAMPERING; - case "H": - return Position.ALARM_POWER_OFF; - case "8": - return Position.ALARM_VIBRATION; - case "7": - case "4": - return Position.ALARM_GEOFENCE_EXIT; - case "6": - return Position.ALARM_OVERSPEED; - case "5": - return Position.ALARM_POWER_CUT; - case "3": - return Position.ALARM_SOS; - default: - return null; - } + return switch (event) { + case "Z" -> Position.ALARM_LOW_BATTERY; + case "Y" -> Position.ALARM_TOW; + case "X" -> Position.ALARM_GEOFENCE_ENTER; + case "T" -> Position.ALARM_TAMPERING; + case "H" -> Position.ALARM_POWER_OFF; + case "8" -> Position.ALARM_VIBRATION; + case "7", "4" -> Position.ALARM_GEOFENCE_EXIT; + case "6" -> Position.ALARM_OVERSPEED; + case "5" -> Position.ALARM_POWER_CUT; + case "3" -> Position.ALARM_SOS; + default -> null; + }; } private String decodeEvent(String event, Position position, String model) { @@ -140,30 +128,13 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder { String event, String devicePassword, Channel channel, SocketAddress remoteAddress) { String responseCode = null; - switch (event) { - case "3": - responseCode = "d"; - break; - case "M": - responseCode = "m"; - break; - case "S": - case "T": - responseCode = "t"; - break; - case "X": - case "4": - responseCode = "x"; - break; - case "Y": - responseCode = "y"; - break; - case "Z": - responseCode = "z"; - break; - default: - break; + case "3" -> responseCode = "d"; + case "M" -> responseCode = "m"; + case "S", "T" -> responseCode = "t"; + case "X", "4" -> responseCode = "x"; + case "Y" -> responseCode = "y"; + case "Z" -> responseCode = "z"; } if (responseCode != null) { diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolEncoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolEncoder.java index aaa5a70f7..f1c556eea 100644 --- a/src/main/java/org/traccar/protocol/LaipacProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/LaipacProtocolEncoder.java @@ -38,19 +38,15 @@ public class LaipacProtocolEncoder extends StringProtocolEncoder { initDevicePassword(command, LaipacProtocolDecoder.DEFAULT_DEVICE_PASSWORD); - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return formatCommand(command, "%s", - Command.KEY_DATA); - case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, "AVREQ,%s,1", - Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_REBOOT_DEVICE: - return formatCommand(command, "AVRESET,%s,%s", - Command.KEY_UNIQUE_ID, Command.KEY_DEVICE_PASSWORD); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_CUSTOM -> formatCommand( + command, "%s", Command.KEY_DATA); + case Command.TYPE_POSITION_SINGLE -> formatCommand( + command, "AVREQ,%s,1", Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_REBOOT_DEVICE -> formatCommand( + command, "AVRESET,%s,%s", Command.KEY_UNIQUE_ID, Command.KEY_DEVICE_PASSWORD); + default -> null; + }; } diff --git a/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java b/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java index 6affb85c5..bc70e8c81 100644 --- a/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/LeafSpyProtocolDecoder.java @@ -55,56 +55,36 @@ public class LeafSpyProtocolDecoder extends BaseHttpProtocolDecoder { for (Map.Entry<String, List<String>> entry : params.entrySet()) { for (String value : entry.getValue()) { switch (entry.getKey()) { - case "pass": + case "pass" -> { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, value); if (deviceSession == null) { sendResponse(channel, HttpResponseStatus.BAD_REQUEST); return null; } position.setDeviceId(deviceSession.getDeviceId()); - break; - case "Lat": - position.setLatitude(Double.parseDouble(value)); - break; - case "Long": - position.setLongitude(Double.parseDouble(value)); - break; - case "RPM": + } + case "Lat" -> position.setLatitude(Double.parseDouble(value)); + case "Long" -> position.setLongitude(Double.parseDouble(value)); + case "RPM" -> { position.set(Position.KEY_RPM, Integer.parseInt(value)); position.setSpeed(convertSpeed(Double.parseDouble(value) / 63, "kmh")); - break; - case "Elv": - position.setAltitude(Double.parseDouble(value)); - break; - case "SOC": - position.set(Position.KEY_BATTERY_LEVEL, Double.parseDouble(value)); - break; - case "user": - position.set(Position.KEY_DRIVER_UNIQUE_ID, value); - break; - case "ChrgMode": - position.set(Position.KEY_CHARGE, Integer.parseInt(value) != 0); - break; - case "Odo": - position.set(Position.KEY_OBD_ODOMETER, Integer.parseInt(value) * 1000); - break; - default: + } + case "Elv" -> position.setAltitude(Double.parseDouble(value)); + case "SOC" -> position.set(Position.KEY_BATTERY_LEVEL, Double.parseDouble(value)); + case "user" -> position.set(Position.KEY_DRIVER_UNIQUE_ID, value); + case "ChrgMode" -> position.set(Position.KEY_CHARGE, Integer.parseInt(value) != 0); + case "Odo" -> position.set(Position.KEY_OBD_ODOMETER, Integer.parseInt(value) * 1000); + default -> { try { position.set(entry.getKey(), Double.parseDouble(value)); } catch (NumberFormatException e) { switch (value) { - case "true": - position.set(entry.getKey(), true); - break; - case "false": - position.set(entry.getKey(), false); - break; - default: - position.set(entry.getKey(), value); - break; + case "true" -> position.set(entry.getKey(), true); + case "false" -> position.set(entry.getKey(), false); + default -> position.set(entry.getKey(), value); } } - break; + } } } } diff --git a/src/main/java/org/traccar/protocol/MegastekProtocolDecoder.java b/src/main/java/org/traccar/protocol/MegastekProtocolDecoder.java index 06b6f0e76..c16a0752d 100644 --- a/src/main/java/org/traccar/protocol/MegastekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MegastekProtocolDecoder.java @@ -387,54 +387,28 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_GEOFENCE_EXIT; } } - switch (value) { - case "pw on": - case "poweron": - return Position.ALARM_POWER_ON; - case "poweroff": - return Position.ALARM_POWER_OFF; - case "sos": - case "help": - return Position.ALARM_SOS; - case "over speed": - case "overspeed": - return Position.ALARM_OVERSPEED; - case "lowspeed": - return Position.ALARM_LOW_SPEED; - case "low battery": - case "lowbattery": - return Position.ALARM_LOW_BATTERY; - case "low extern voltage": - return Position.ALARM_LOW_POWER; - case "gps cut": - return Position.ALARM_GPS_ANTENNA_CUT; - case "vib": - return Position.ALARM_VIBRATION; - case "move in": - return Position.ALARM_GEOFENCE_ENTER; - case "move out": - return Position.ALARM_GEOFENCE_EXIT; - case "corner": - return Position.ALARM_CORNERING; - case "fatigue": - return Position.ALARM_FATIGUE_DRIVING; - case "psd": - return Position.ALARM_POWER_CUT; - case "psr": - return Position.ALARM_POWER_RESTORED; - case "hit": - return Position.ALARM_VIBRATION; - case "belt on": - case "belton": - return Position.ALARM_LOCK; - case "belt off": - case "beltoff": - return Position.ALARM_UNLOCK; - case "error": - return Position.ALARM_FAULT; - default: - return null; - } + return switch (value) { + case "pw on", "poweron" -> Position.ALARM_POWER_ON; + case "poweroff" -> Position.ALARM_POWER_OFF; + case "sos", "help" -> Position.ALARM_SOS; + case "over speed", "overspeed" -> Position.ALARM_OVERSPEED; + case "lowspeed" -> Position.ALARM_LOW_SPEED; + case "low battery", "lowbattery" -> Position.ALARM_LOW_BATTERY; + case "low extern voltage" -> Position.ALARM_LOW_POWER; + case "gps cut" -> Position.ALARM_GPS_ANTENNA_CUT; + case "vib" -> Position.ALARM_VIBRATION; + case "move in" -> Position.ALARM_GEOFENCE_ENTER; + case "move out" -> Position.ALARM_GEOFENCE_EXIT; + case "corner" -> Position.ALARM_CORNERING; + case "fatigue" -> Position.ALARM_FATIGUE_DRIVING; + case "psd" -> Position.ALARM_POWER_CUT; + case "psr" -> Position.ALARM_POWER_RESTORED; + case "hit" -> Position.ALARM_VIBRATION; + case "belt on", "belton" -> Position.ALARM_LOCK; + case "belt off", "beltoff" -> Position.ALARM_UNLOCK; + case "error" -> Position.ALARM_FAULT; + default -> null; + }; } @Override diff --git a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java index 1f8c4d2da..524d86289 100644 --- a/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeiligaoProtocolDecoder.java @@ -141,6 +141,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_OBD_RT = 0x9901; public static final int MSG_OBD_RTA = 0x9902; + public static final int MSG_DTC = 0x9903; public static final int MSG_TRACK_ON_DEMAND = 0x4101; public static final int MSG_TRACK_BY_INTERVAL = 0x4102; @@ -208,30 +209,35 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { } } - private String decodeAlarm(short value) { - switch (value) { - case 0x01: - return Position.ALARM_SOS; - case 0x10: - return Position.ALARM_LOW_BATTERY; - case 0x11: - return Position.ALARM_OVERSPEED; - case 0x12: - return Position.ALARM_MOVEMENT; - case 0x13: - return Position.ALARM_GEOFENCE_ENTER; - case 0x14: - return Position.ALARM_ACCIDENT; - case 0x50: - return Position.ALARM_POWER_OFF; - case 0x53: - return Position.ALARM_GPS_ANTENNA_CUT; - case 0x72: - return Position.ALARM_BRAKING; - case 0x73: - return Position.ALARM_ACCELERATION; - default: - return null; + private String decodeAlarm(String model, short value) { + if ("TK218".equals(model)) { + return switch (value) { + case 0x01 -> Position.ALARM_SOS; + case 0x10 -> Position.ALARM_LOW_BATTERY; + case 0x11 -> Position.ALARM_OVERSPEED; + case 0x12 -> Position.ALARM_MOVEMENT; + case 0x13 -> Position.ALARM_GEOFENCE; + case 0x60 -> Position.ALARM_FATIGUE_DRIVING; + case 0x71 -> Position.ALARM_BRAKING; + case 0x72 -> Position.ALARM_ACCELERATION; + case 0x73 -> Position.ALARM_ACCIDENT; + case 0x74 -> Position.ALARM_IDLE; + default -> null; + }; + } else { + return switch (value) { + case 0x01 -> Position.ALARM_SOS; + case 0x10 -> Position.ALARM_LOW_BATTERY; + case 0x11 -> Position.ALARM_OVERSPEED; + case 0x12 -> Position.ALARM_MOVEMENT; + case 0x13 -> Position.ALARM_GEOFENCE_ENTER; + case 0x14 -> Position.ALARM_ACCIDENT; + case 0x50 -> Position.ALARM_POWER_OFF; + case 0x53 -> Position.ALARM_GPS_ANTENNA_CUT; + case 0x72 -> Position.ALARM_BRAKING; + case 0x73 -> Position.ALARM_ACCELERATION; + default -> null; + }; } } @@ -352,6 +358,12 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { return position; } + private Position decodeDtc(Position position, String sentence) { + getLastLocation(position, null); + position.set(Position.KEY_DTCS, sentence.replace(',', ' ')); + return position; + } + private List<Position> decodeRetransmission(ByteBuf buf, DeviceSession deviceSession) { List<Position> positions = new LinkedList<>(); @@ -448,7 +460,8 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { if (command == MSG_ALARM) { short alarmCode = buf.readUnsignedByte(); - position.set(Position.KEY_ALARM, decodeAlarm(alarmCode)); + String model = getDeviceModel(deviceSession); + position.set(Position.KEY_ALARM, decodeAlarm(model, alarmCode)); if (alarmCode >= 0x02 && alarmCode <= 0x05) { position.set(Position.PREFIX_IN + alarmCode, 1); } else if (alarmCode >= 0x32 && alarmCode <= 0x35) { @@ -478,21 +491,15 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { String sentence = buf.toString(buf.readerIndex(), buf.readableBytes() - 4, StandardCharsets.US_ASCII); - switch (command) { - case MSG_POSITION: - case MSG_POSITION_LOGGED: - case MSG_ALARM: - case MSG_POSITION_IMAGE: - return decodeRegular(position, sentence); - case MSG_RFID: - return decodeRfid(position, sentence); - case MSG_OBD_RT: - return decodeObd(position, sentence); - case MSG_OBD_RTA: - return decodeObdA(position, sentence); - default: - return null; - } + return switch (command) { + case MSG_POSITION, MSG_POSITION_LOGGED, MSG_ALARM, MSG_POSITION_IMAGE -> + decodeRegular(position, sentence); + case MSG_RFID -> decodeRfid(position, sentence); + case MSG_OBD_RT -> decodeObd(position, sentence); + case MSG_OBD_RTA -> decodeObdA(position, sentence); + case MSG_DTC -> decodeDtc(position, sentence); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocol.java b/src/main/java/org/traccar/protocol/MeitrackProtocol.java index 4109b22c9..560ec87e8 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocol.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2024 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ public class MeitrackProtocol extends BaseProtocol { @Inject public MeitrackProtocol(Config config) { setSupportedDataCommands( + Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME, diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java index 88b6380a5..e9e37d18a 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -108,41 +108,24 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { .compile(); private String decodeAlarm(int event) { - switch (event) { - case 1: - return Position.ALARM_SOS; - case 17: - return Position.ALARM_LOW_BATTERY; - case 18: - return Position.ALARM_LOW_POWER; - case 19: - return Position.ALARM_OVERSPEED; - case 20: - return Position.ALARM_GEOFENCE_ENTER; - case 21: - return Position.ALARM_GEOFENCE_EXIT; - case 22: - return Position.ALARM_POWER_RESTORED; - case 23: - return Position.ALARM_POWER_CUT; - case 36: - return Position.ALARM_TOW; - case 44: - return Position.ALARM_JAMMING; - case 78: - return Position.ALARM_ACCIDENT; - case 90: - case 91: - return Position.ALARM_CORNERING; - case 129: - return Position.ALARM_BRAKING; - case 130: - return Position.ALARM_ACCELERATION; - case 135: - return Position.ALARM_FATIGUE_DRIVING; - default: - return null; - } + return switch (event) { + case 1 -> Position.ALARM_SOS; + case 17 -> Position.ALARM_LOW_BATTERY; + case 18 -> Position.ALARM_LOW_POWER; + case 19 -> Position.ALARM_OVERSPEED; + case 20 -> Position.ALARM_GEOFENCE_ENTER; + case 21 -> Position.ALARM_GEOFENCE_EXIT; + case 22 -> Position.ALARM_POWER_RESTORED; + case 23 -> Position.ALARM_POWER_CUT; + case 36 -> Position.ALARM_TOW; + case 44 -> Position.ALARM_JAMMING; + case 78 -> Position.ALARM_ACCIDENT; + case 90, 91 -> Position.ALARM_CORNERING; + case 129 -> Position.ALARM_BRAKING; + case 130 -> Position.ALARM_ACCELERATION; + case 135 -> Position.ALARM_FATIGUE_DRIVING; + default -> null; + }; } private Position decodeRegular(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { @@ -207,35 +190,22 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { } switch (Objects.requireNonNullElse(getDeviceModel(deviceSession), "").toUpperCase()) { - case "MVT340": - case "MVT380": + case "MVT340", "MVT380" -> { position.set(Position.KEY_BATTERY, parser.nextHexInt() * 3.0 * 2.0 / 1024.0); position.set(Position.KEY_POWER, parser.nextHexInt(0) * 3.0 * 16.0 / 1024.0); - break; - case "MT90": + } + case "MT90" -> { position.set(Position.KEY_BATTERY, parser.nextHexInt() * 3.3 * 2.0 / 4096.0); position.set(Position.KEY_POWER, parser.nextHexInt(0)); - break; - case "T1": - case "T3": - case "MVT100": - case "MVT600": - case "MVT800": - case "TC68": - case "TC68S": + } + case "T1", "T3", "MVT100", "MVT600", "MVT800", "TC68", "TC68S" -> { position.set(Position.KEY_BATTERY, parser.nextHexInt() * 3.3 * 2.0 / 4096.0); position.set(Position.KEY_POWER, parser.nextHexInt(0) * 3.3 * 16.0 / 4096.0); - break; - case "T311": - case "T322X": - case "T333": - case "T355": - case "T366": - case "T366G": - default: + } + default -> { position.set(Position.KEY_BATTERY, parser.nextHexInt() / 100.0); position.set(Position.KEY_POWER, parser.nextHexInt(0) / 100.0); - break; + } } } @@ -243,12 +213,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { String eventData = parser.next(); if (eventData != null && !eventData.isEmpty()) { switch (event) { - case 37: - position.set(Position.KEY_DRIVER_UNIQUE_ID, eventData); - break; - default: - position.set("eventData", eventData); - break; + case 37 -> position.set(Position.KEY_DRIVER_UNIQUE_ID, eventData); + default -> position.set("eventData", eventData); } } @@ -402,42 +368,22 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { boolean extension = buf.getUnsignedByte(buf.readerIndex()) == 0xFE; int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte(); switch (id) { - case 0x01: - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); - break; - case 0x05: - position.setValid(buf.readUnsignedByte() > 0); - break; - case 0x06: - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - break; - case 0x07: - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - break; - case 0x14: - position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); - break; - case 0x15: - position.set(Position.KEY_INPUT, buf.readUnsignedByte()); - break; - case 0x47: + case 0x01 -> position.set(Position.KEY_EVENT, buf.readUnsignedByte()); + case 0x05 -> position.setValid(buf.readUnsignedByte() > 0); + case 0x06 -> position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + case 0x07 -> position.set(Position.KEY_RSSI, buf.readUnsignedByte()); + case 0x14 -> position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); + case 0x15 -> position.set(Position.KEY_INPUT, buf.readUnsignedByte()); + case 0x47 -> { int lockState = buf.readUnsignedByte(); if (lockState > 0) { position.set(Position.KEY_LOCK, lockState == 2); } - break; - case 0x97: - position.set(Position.KEY_THROTTLE, buf.readUnsignedByte()); - break; - case 0x9D: - position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); - break; - case 0xFE69: - position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); - break; - default: - buf.readUnsignedByte(); - break; + } + case 0x97 -> position.set(Position.KEY_THROTTLE, buf.readUnsignedByte()); + case 0x9D -> position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte()); + case 0xFE69 -> position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + default -> buf.readUnsignedByte(); } } @@ -446,58 +392,23 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { boolean extension = buf.getUnsignedByte(buf.readerIndex()) == 0xFE; int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte(); switch (id) { - case 0x08: - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); - break; - case 0x09: - position.setCourse(buf.readUnsignedShortLE()); - break; - case 0x0A: - position.set(Position.KEY_HDOP, buf.readUnsignedShortLE()); - break; - case 0x0B: - position.setAltitude(buf.readShortLE()); - break; - case 0x16: - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE() * 0.01); - break; - case 0x17: - position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShortLE() * 0.01); - break; - case 0x19: - position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.01); - break; - case 0x1A: - position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.01); - break; - case 0x29: - position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShortLE() * 0.01); - break; - case 0x40: - position.set(Position.KEY_EVENT, buf.readUnsignedShortLE()); - break; - case 0x91: - case 0x92: - position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShortLE()); - break; - case 0x98: - position.set(Position.KEY_FUEL_USED, buf.readUnsignedShortLE()); - break; - case 0x99: - position.set(Position.KEY_RPM, buf.readUnsignedShortLE()); - break; - case 0x9C: - position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedShortLE()); - break; - case 0x9F: - position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedShortLE()); - break; - case 0xC9: - position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShortLE()); - break; - default: - buf.readUnsignedShortLE(); - break; + case 0x08 -> position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); + case 0x09 -> position.setCourse(buf.readUnsignedShortLE()); + case 0x0A -> position.set(Position.KEY_HDOP, buf.readUnsignedShortLE()); + case 0x0B -> position.setAltitude(buf.readShortLE()); + case 0x16 -> position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShortLE() * 0.01); + case 0x17 -> position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShortLE() * 0.01); + case 0x19 -> position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.01); + case 0x1A -> position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.01); + case 0x29 -> position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedShortLE() * 0.01); + case 0x40 -> position.set(Position.KEY_EVENT, buf.readUnsignedShortLE()); + case 0x91, 0x92 -> position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShortLE()); + case 0x98 -> position.set(Position.KEY_FUEL_USED, buf.readUnsignedShortLE()); + case 0x99 -> position.set(Position.KEY_RPM, buf.readUnsignedShortLE()); + case 0x9C -> position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedShortLE()); + case 0x9F -> position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedShortLE()); + case 0xC9 -> position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShortLE()); + default -> buf.readUnsignedShortLE(); } } @@ -506,39 +417,17 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { boolean extension = buf.getUnsignedByte(buf.readerIndex()) == 0xFE; int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte(); switch (id) { - case 0x02: - position.setLatitude(buf.readIntLE() * 0.000001); - break; - case 0x03: - position.setLongitude(buf.readIntLE() * 0.000001); - break; - case 0x04: - position.setTime(new Date((946684800 + buf.readUnsignedIntLE()) * 1000)); // 2000-01-01 - break; - case 0x0C: - position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); - break; - case 0x0D: - position.set("runtime", buf.readUnsignedIntLE()); - break; - case 0x25: - position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(buf.readUnsignedIntLE())); - break; - case 0x9B: - position.set(Position.KEY_OBD_ODOMETER, buf.readUnsignedIntLE()); - break; - case 0xA0: - position.set(Position.KEY_FUEL_USED, buf.readUnsignedIntLE() * 0.001); - break; - case 0xA2: - position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedIntLE() * 0.01); - break; - case 0xFEF4: - position.set(Position.KEY_HOURS, buf.readUnsignedIntLE() * 60000); - break; - default: - buf.readUnsignedIntLE(); - break; + case 0x02 -> position.setLatitude(buf.readIntLE() * 0.000001); + case 0x03 -> position.setLongitude(buf.readIntLE() * 0.000001); + case 0x04 -> position.setTime(new Date((946684800 + buf.readUnsignedIntLE()) * 1000)); // 2000-01-01 + case 0x0C -> position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); + case 0x0D -> position.set("runtime", buf.readUnsignedIntLE()); + case 0x25 -> position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(buf.readUnsignedIntLE())); + case 0x9B -> position.set(Position.KEY_OBD_ODOMETER, buf.readUnsignedIntLE()); + case 0xA0 -> position.set(Position.KEY_FUEL_USED, buf.readUnsignedIntLE() * 0.001); + case 0xA2 -> position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedIntLE() * 0.01); + case 0xFEF4 -> position.set(Position.KEY_HOURS, buf.readUnsignedIntLE() * 60000); + default -> buf.readUnsignedIntLE(); } } @@ -548,48 +437,27 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { int id = extension ? buf.readUnsignedShort() : buf.readUnsignedByte(); int length = buf.readUnsignedByte(); switch (id) { - case 0x1D: - case 0x1E: - case 0x1F: - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - case 0x25: + case 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25 -> { String wifiMac = ByteBufUtil.hexDump(buf.readSlice(6)).replaceAll("(..)", "$1:"); network.addWifiAccessPoint(WifiAccessPoint.from( wifiMac.substring(0, wifiMac.length() - 1), buf.readShortLE())); - break; - case 0x0E: - case 0x0F: - case 0x10: - case 0x12: - case 0x13: + } + case 0x0E, 0x0F, 0x10, 0x12, 0x13 -> { network.addCellTower(CellTower.from( buf.readUnsignedShortLE(), buf.readUnsignedShortLE(), buf.readUnsignedShortLE(), buf.readUnsignedIntLE(), buf.readShortLE())); - break; - case 0x2A: - case 0x2B: - case 0x2C: - case 0x2D: - case 0x2E: - case 0x2F: - case 0x30: - case 0x31: + } + case 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31 -> { buf.readUnsignedByte(); // label position.set(Position.PREFIX_TEMP + (id - 0x2A), buf.readShortLE() * 0.01); - break; - case 0x4B: - buf.skipBytes(length); // network information - break; - case 0xFE31: + } + case 0x4B -> buf.skipBytes(length); // network information + case 0xFE31 -> { buf.readUnsignedByte(); // alarm protocol buf.readUnsignedByte(); // alarm type buf.skipBytes(length - 2); - break; - case 0xFE73: + } + case 0xFE73 -> { buf.readUnsignedByte(); // version position.set( "tagName", @@ -602,8 +470,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedShortLE(); // low temperature threshold buf.readUnsignedShortLE(); // high humidity threshold buf.readUnsignedShortLE(); // low humidity threshold - break; - case 0xFEA8: + } + case 0xFEA8 -> { for (int k = 1; k <= 3; k++) { if (buf.readUnsignedByte() > 0) { String key = k == 1 ? Position.KEY_BATTERY_LEVEL : "battery" + k + "Level"; @@ -613,10 +481,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { } } buf.readUnsignedByte(); // battery alert - break; - default: - buf.skipBytes(length); - break; + } + default -> buf.skipBytes(length); } } @@ -650,24 +516,25 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { index = buf.indexOf(index + 1, buf.writerIndex(), (byte) ','); String type = buf.toString(index + 1, 3, StandardCharsets.US_ASCII); - switch (type) { - case "AAC": + return switch (type) { + case "AAC" -> { if (channel != null) { String response = String.format("@@z27,%s,AAC,1*", imei); response += Checksum.sum(response) + "\r\n"; channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } - return null; - case "D00": + yield null; + } + case "D00" -> { if (photo == null) { photo = Unpooled.buffer(); } index = index + 1 + type.length() + 1; - int endIndex = buf.indexOf(index, buf.writerIndex(), (byte) ','); + int endIndex = buf.indexOf(index, buf.writerIndex(), (byte) ','); String file = buf.toString(index, endIndex - index, StandardCharsets.US_ASCII); index = endIndex + 1; - endIndex = buf.indexOf(index, buf.writerIndex(), (byte) ','); + endIndex = buf.indexOf(index, buf.writerIndex(), (byte) ','); int total = Integer.parseInt(buf.toString(index, endIndex - index, StandardCharsets.US_ASCII)); index = endIndex + 1; endIndex = buf.indexOf(index, buf.writerIndex(), (byte) ','); @@ -686,31 +553,31 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { photo.release(); photo = null; - return position; + yield position; } else { if ((current + 1) % 8 == 0) { requestPhotoPacket(channel, remoteAddress, imei, file, current + 1); } - return null; + yield null; } - case "D03": + } + case "D03" -> { photo = Unpooled.buffer(); requestPhotoPacket(channel, remoteAddress, imei, "camera_picture.jpg", 0); - return null; - case "D82": + yield null; + } + case "D82" -> { Position position = new Position(getProtocolName()); position.setDeviceId(getDeviceSession(channel, remoteAddress, imei).getDeviceId()); getLastLocation(position, null); String result = buf.toString(index + 1, buf.writerIndex() - index - 4, StandardCharsets.US_ASCII); position.set(Position.KEY_RESULT, result); - return position; - case "CCC": - return decodeBinaryC(channel, remoteAddress, buf); - case "CCE": - return decodeBinaryE(channel, remoteAddress, buf); - default: - return decodeRegular(channel, remoteAddress, buf); - } + yield position; + } + case "CCC" -> decodeBinaryC(channel, remoteAddress, buf); + case "CCE" -> decodeBinaryE(channel, remoteAddress, buf); + default -> decodeRegular(channel, remoteAddress, buf); + }; } } diff --git a/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java b/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java index 365dbb35a..9b43f3988 100644 --- a/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/MeitrackProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2024 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,18 +22,16 @@ import org.traccar.helper.Checksum; import org.traccar.helper.model.AttributeUtil; import org.traccar.model.Command; -import java.util.Map; - public class MeitrackProtocolEncoder extends StringProtocolEncoder { public MeitrackProtocolEncoder(Protocol protocol) { super(protocol); } - private Object formatCommand(Command command, char dataId, String content) { + private Object formatCommand(Command command, String content) { String uniqueId = getUniqueId(command.getDeviceId()); int length = 1 + uniqueId.length() + 1 + content.length() + 5; - String result = String.format("@@%c%02d,%s,%s*", dataId, length, uniqueId, content); + String result = String.format("@@A%02d,%s,%s*", length, uniqueId, content); result += Checksum.sum(result) + "\r\n"; return result; } @@ -41,31 +39,27 @@ public class MeitrackProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Command command) { - Map<String, Object> attributes = command.getAttributes(); - boolean alternative = AttributeUtil.lookup( getCacheManager(), Keys.PROTOCOL_ALTERNATIVE.withPrefix(getProtocolName()), command.getDeviceId()); - switch (command.getType()) { - case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, 'Q', "A10"); - case Command.TYPE_ENGINE_STOP: - return formatCommand(command, 'M', "C01,0,12222"); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, 'M', "C01,0,02222"); - case Command.TYPE_ALARM_ARM: - return formatCommand(command, 'M', alternative ? "B21,1" : "C01,0,22122"); - case Command.TYPE_ALARM_DISARM: - return formatCommand(command, 'M', alternative ? "B21,0" : "C01,0,22022"); - case Command.TYPE_REQUEST_PHOTO: + return switch (command.getType()) { + case Command.TYPE_CUSTOM -> formatCommand(command, command.getString(Command.KEY_DATA)); + case Command.TYPE_POSITION_SINGLE -> formatCommand(command, "A10"); + case Command.TYPE_ENGINE_STOP -> formatCommand(command, "C01,0,12222"); + case Command.TYPE_ENGINE_RESUME -> formatCommand(command, "C01,0,02222"); + case Command.TYPE_ALARM_ARM -> formatCommand(command, alternative ? "B21,1" : "C01,0,22122"); + case Command.TYPE_ALARM_DISARM -> formatCommand(command, alternative ? "B21,0" : "C01,0,22022"); + case Command.TYPE_REQUEST_PHOTO -> { int index = command.getInteger(Command.KEY_INDEX); - return formatCommand(command, 'D', "D03," + (index > 0 ? index : 1) + ",camera_picture.jpg"); - case Command.TYPE_SEND_SMS: - return formatCommand(command, 'f', "C02,0," - + attributes.get(Command.KEY_PHONE) + "," + attributes.get(Command.KEY_MESSAGE)); - default: - return null; - } + yield formatCommand(command, "D03," + (index > 0 ? index : 1) + ",camera_picture.jpg"); + } + case Command.TYPE_SEND_SMS -> { + String phone = command.getString(Command.KEY_PHONE); + String message = command.getString(Command.KEY_MESSAGE); + yield formatCommand(command, "C02,0," + phone + "," + message); + } + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java index 84ba75e7c..4d7171d3f 100644 --- a/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MictrackProtocolDecoder.java @@ -65,22 +65,15 @@ public class MictrackProtocolDecoder extends BaseProtocolDecoder { } private String decodeAlarm(int event) { - switch (event) { - case 0: - return Position.ALARM_POWER_ON; - case 5: - return Position.ALARM_SOS; - case 8: - return Position.ALARM_LOW_BATTERY; - case 9: - return Position.ALARM_GEOFENCE_ENTER; - case 10: - return Position.ALARM_GEOFENCE_EXIT; - case 12: - return Position.ALARM_POWER_OFF; - default: - return null; - } + return switch (event) { + case 0 -> Position.ALARM_POWER_ON; + case 5 -> Position.ALARM_SOS; + case 8 -> Position.ALARM_LOW_BATTERY; + case 9 -> Position.ALARM_GEOFENCE_ENTER; + case 10 -> Position.ALARM_GEOFENCE_EXIT; + case 12 -> Position.ALARM_POWER_OFF; + default -> null; + }; } private void decodeLocation(Position position, String data) throws ParseException { @@ -231,28 +224,15 @@ public class MictrackProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_TYPE, Integer.parseInt(fragments[1])); switch (fragments[3]) { - case "R0": - decodeLocation(position, fragments[4]); - break; - case "R1": - decodeNetwork(position, fragments[4], true, false, false); - break; - case "R2": - case "R3": - decodeNetwork(position, fragments[4], false, false, true); - break; - case "R12": - case "R13": - decodeNetwork(position, fragments[4], true, false, true); - break; - case "RH": - decodeStatus(position, fragments[4]); - break; - case "Y1": - decodeNetwork(position, fragments[4], true, true, false); - break; - default: + case "R0" -> decodeLocation(position, fragments[4]); + case "R1" -> decodeNetwork(position, fragments[4], true, false, false); + case "R2", "R3" -> decodeNetwork(position, fragments[4], false, false, true); + case "R12", "R13" -> decodeNetwork(position, fragments[4], true, false, true); + case "RH" -> decodeStatus(position, fragments[4]); + case "Y1" -> decodeNetwork(position, fragments[4], true, true, false); + default -> { return null; + } } return position; diff --git a/src/main/java/org/traccar/protocol/MiniFinderProtocolEncoder.java b/src/main/java/org/traccar/protocol/MiniFinderProtocolEncoder.java index 059f688f7..ed2891f33 100644 --- a/src/main/java/org/traccar/protocol/MiniFinderProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/MiniFinderProtocolEncoder.java @@ -29,25 +29,18 @@ public class MiniFinderProtocolEncoder extends StringProtocolEncoder implements @Override public String formatValue(String key, Object value) { - switch (key) { - case Command.KEY_ENABLE: - return (Boolean) value ? "1" : "0"; - case Command.KEY_TIMEZONE: - return String.format("%+03d", TimeZone.getTimeZone((String) value).getRawOffset() / 3600000); - case Command.KEY_INDEX: - switch (((Number) value).intValue()) { - case 0: - return "A"; - case 1: - return "B"; - case 2: - return "C"; - default: - return null; - } - default: - return null; - } + return switch (key) { + case Command.KEY_ENABLE -> (Boolean) value ? "1" : "0"; + case Command.KEY_TIMEZONE -> String.format( + "%+03d", TimeZone.getTimeZone((String) value).getRawOffset() / 3600000); + case Command.KEY_INDEX -> switch (((Number) value).intValue()) { + case 0 -> "A"; + case 1 -> "B"; + case 2 -> "C"; + default -> null; + }; + default -> null; + }; } @Override @@ -55,33 +48,31 @@ public class MiniFinderProtocolEncoder extends StringProtocolEncoder implements initDevicePassword(command, "123456"); - switch (command.getType()) { - case Command.TYPE_SET_TIMEZONE: - return formatCommand(command, "%sL%s", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_TIMEZONE); - case Command.TYPE_VOICE_MONITORING: - return formatCommand(command, "%sP%s", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE); - case Command.TYPE_ALARM_SPEED: - return formatCommand(command, "%sJ1%s", Command.KEY_DEVICE_PASSWORD, Command.KEY_DATA); - case Command.TYPE_ALARM_GEOFENCE: - return formatCommand(command, "%sR1%s", Command.KEY_DEVICE_PASSWORD, Command.KEY_RADIUS); - case Command.TYPE_ALARM_VIBRATION: - return formatCommand(command, "%sW1,%s", Command.KEY_DEVICE_PASSWORD, Command.KEY_DATA); - case Command.TYPE_SET_AGPS: - return formatCommand(command, "%sAGPS%s", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE); - case Command.TYPE_ALARM_FALL: - return formatCommand(command, "%sF%s", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE); - case Command.TYPE_MODE_POWER_SAVING: - return formatCommand(command, "%sSP%s", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE); - case Command.TYPE_MODE_DEEP_SLEEP: - return formatCommand(command, "%sDS%s", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE); - case Command.TYPE_SOS_NUMBER: - return formatCommand(command, "%s%s1,%s", this, - Command.KEY_DEVICE_PASSWORD, Command.KEY_INDEX, Command.KEY_PHONE); - case Command.TYPE_SET_INDICATOR: - return formatCommand(command, "%sLED%s", Command.KEY_DEVICE_PASSWORD, Command.KEY_DATA); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_SET_TIMEZONE -> formatCommand( + command, "%sL%s", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_TIMEZONE); + case Command.TYPE_VOICE_MONITORING -> formatCommand( + command, "%sP%s", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE); + case Command.TYPE_ALARM_SPEED -> formatCommand( + command, "%sJ1%s", Command.KEY_DEVICE_PASSWORD, Command.KEY_DATA); + case Command.TYPE_ALARM_GEOFENCE -> formatCommand( + command, "%sR1%s", Command.KEY_DEVICE_PASSWORD, Command.KEY_RADIUS); + case Command.TYPE_ALARM_VIBRATION -> formatCommand( + command, "%sW1,%s", Command.KEY_DEVICE_PASSWORD, Command.KEY_DATA); + case Command.TYPE_SET_AGPS -> formatCommand( + command, "%sAGPS%s", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE); + case Command.TYPE_ALARM_FALL -> formatCommand( + command, "%sF%s", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE); + case Command.TYPE_MODE_POWER_SAVING -> formatCommand( + command, "%sSP%s", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE); + case Command.TYPE_MODE_DEEP_SLEEP -> formatCommand( + command, "%sDS%s", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_ENABLE); + case Command.TYPE_SOS_NUMBER -> formatCommand( + command, "%s%s1,%s", this, Command.KEY_DEVICE_PASSWORD, Command.KEY_INDEX, Command.KEY_PHONE); + case Command.TYPE_SET_INDICATOR -> formatCommand( + command, "%sLED%s", Command.KEY_DEVICE_PASSWORD, Command.KEY_DATA); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index 2d6bde89f..ad73e7642 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -85,22 +85,18 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { int endIndex = buf.readUnsignedByte() + buf.readerIndex(); int key = buf.readUnsignedByte(); switch (key) { - case 0x11: - case 0x21: - case 0x22: + case 0x11, 0x21, 0x22 -> { body.writeByte(9 + 1); // length body.writeByte(key); body.writeIntLE(0); // latitude body.writeIntLE(0); // longitude body.writeByte(0); // address - break; - case 0x12: + } + case 0x12 -> { body.writeByte(5); // length body.writeByte(key); body.writeIntLE((int) (System.currentTimeMillis() / 1000)); - break; - default: - break; + } } buf.readerIndex(endIndex); } @@ -161,7 +157,8 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { DeviceSession deviceSession = null; while (buf.isReadable()) { - int endIndex = buf.readUnsignedByte() + buf.readerIndex(); + int length = buf.readUnsignedByte(); + int endIndex = buf.readerIndex() + length; int key = buf.readUnsignedByte(); if (keys.contains(key)) { @@ -185,6 +182,9 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(alarm, 31)) { position.set("bark", true); } + if (length == 5) { + position.setDeviceTime(new Date(buf.readUnsignedIntLE() * 1000)); + } break; case 0x14: position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); @@ -203,6 +203,7 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); break; case 0x21: + case 0x29: int mcc = buf.readUnsignedShortLE(); int mnc = buf.readUnsignedByte(); if (position.getNetwork() == null) { @@ -210,8 +211,14 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { } while (buf.readerIndex() < endIndex) { int rssi = buf.readByte(); - position.getNetwork().addCellTower(CellTower.from( - mcc, mnc, buf.readUnsignedShortLE(), buf.readUnsignedShortLE(), rssi)); + int lac = buf.readUnsignedShortLE(); + long cid; + if (key == 0x29) { + cid = buf.readLongLE(); + } else { + cid = buf.readUnsignedShortLE(); + } + position.getNetwork().addCellTower(CellTower.from(mcc, mnc, lac, cid, rssi)); } break; case 0x22: @@ -226,10 +233,22 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { } break; case 0x23: - position.set("tagId", readTagId(buf)); - position.setLatitude(buf.readIntLE() * 0.0000001); - position.setLongitude(buf.readIntLE() * 0.0000001); - position.setValid(true); + case 0x26: + if (length >= 7) { + position.set("tagId", readTagId(buf)); + } + if (length >= 15) { + position.setLatitude(buf.readIntLE() * 0.0000001); + position.setLongitude(buf.readIntLE() * 0.0000001); + position.setValid(true); + } + if (key == 0x26) { + position.set(Position.KEY_HDOP, buf.readUnsignedShortLE() * 0.1); + position.setAltitude(buf.readShortLE()); + } else if (length > 15) { + position.set("description", buf.readCharSequence( + length, StandardCharsets.US_ASCII).toString()); + } break; case 0x24: position.setTime(new Date(buf.readUnsignedIntLE() * 1000)); @@ -245,6 +264,13 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY_LEVEL, BitUtil.from(status, 24)); position.set(Position.KEY_STATUS, status); break; + case 0x27: + position.setLatitude(buf.readIntLE() * 0.0000001); + position.setLongitude(buf.readIntLE() * 0.0000001); + position.setValid(true); + position.set(Position.KEY_HDOP, buf.readUnsignedShortLE() * 0.1); + position.setAltitude(buf.readShortLE()); + break; case 0x28: int beaconFlags = buf.readUnsignedByte(); position.set("tagId", readTagId(buf)); @@ -267,6 +293,10 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { position.setLatitude(buf.readIntLE() * 0.0000001); position.setLongitude(buf.readIntLE() * 0.0000001); position.setValid(true); + if (endIndex > buf.readerIndex()) { + position.set("description", buf.readCharSequence( + endIndex - buf.readerIndex(), StandardCharsets.US_ASCII).toString()); + } break; case 0x30: buf.readUnsignedIntLE(); // timestamp @@ -367,145 +397,89 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { int key = buf.readUnsignedByte(); switch (key) { - case 0x01: - position.set("moduleNumber", buf.readUnsignedInt()); - break; - case 0x02: - position.set(Position.KEY_VERSION_FW, String.valueOf(buf.readUnsignedInt())); - break; - case 0x03: - position.set("imei", buf.readCharSequence(length, StandardCharsets.US_ASCII).toString()); - break; - case 0x04: - position.set(Position.KEY_ICCID, BufferUtil.readString(buf, length)); - break; - case 0x05: - position.set("bleMac", ByteBufUtil.hexDump(buf.readSlice(length))); - break; - case 0x06: - position.set("settingTime", buf.readUnsignedInt()); - break; - case 0x07: - position.set("runTimes", buf.readUnsignedInt()); - break; - case 0x0A: + case 0x01 -> position.set("moduleNumber", buf.readUnsignedInt()); + case 0x02 -> position.set(Position.KEY_VERSION_FW, String.valueOf(buf.readUnsignedInt())); + case 0x03 -> position.set("imei", buf.readCharSequence(length, StandardCharsets.US_ASCII).toString()); + case 0x04 -> position.set(Position.KEY_ICCID, BufferUtil.readString(buf, length)); + case 0x05 -> position.set("bleMac", ByteBufUtil.hexDump(buf.readSlice(length))); + case 0x06 -> position.set("settingTime", buf.readUnsignedInt()); + case 0x07 -> position.set("runTimes", buf.readUnsignedInt()); + case 0x0A -> { position.set("interval", buf.readUnsignedMedium()); position.set("petMode", buf.readUnsignedByte()); - break; - case 0x0D: - position.set("passwordProtect", buf.readUnsignedInt()); - break; - case 0x0E: - position.set("timeZone", (int) buf.readByte()); - break; - case 0x0F: - position.set("enableControl", buf.readUnsignedInt()); - break; - case 0x13: - position.set("deviceName", BufferUtil.readString(buf, length)); - break; - case 0x14: + } + case 0x0D -> position.set("passwordProtect", buf.readUnsignedInt()); + case 0x0E -> position.set("timeZone", (int) buf.readByte()); + case 0x0F -> position.set("enableControl", buf.readUnsignedInt()); + case 0x13 -> position.set("deviceName", BufferUtil.readString(buf, length)); + case 0x14 -> { position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); - break; - case 0x15: + } + case 0x15 -> { position.set("bleLatitude", buf.readIntLE() * 0.0000001); position.set("bleLongitude", buf.readIntLE() * 0.0000001); position.set("bleLocation", BufferUtil.readString(buf, length - 8)); - break; - case 0x17: - position.set("gpsUrl", BufferUtil.readString(buf, length)); - break; - case 0x18: - position.set("lbsUrl", BufferUtil.readString(buf, length)); - break; - case 0x1A: - position.set("firmware", BufferUtil.readString(buf, length)); - break; - case 0x1B: - position.set("gsmModule", BufferUtil.readString(buf, length)); - break; - case 0x1D: + } + case 0x17 -> position.set("gpsUrl", BufferUtil.readString(buf, length)); + case 0x18 -> position.set("lbsUrl", BufferUtil.readString(buf, length)); + case 0x1A -> position.set("firmware", BufferUtil.readString(buf, length)); + case 0x1B -> position.set("gsmModule", BufferUtil.readString(buf, length)); + case 0x1D -> { position.set("agpsUpdate", buf.readUnsignedByte()); position.set("agpsLatitude", buf.readIntLE() * 0.0000001); position.set("agpsLongitude", buf.readIntLE() * 0.0000001); - break; - case 0x30: + } + case 0x30 -> { position.set("numberFlag", buf.readUnsignedByte()); position.set("number", BufferUtil.readString(buf, length - 1)); - break; - case 0x31: + } + case 0x31 -> { position.set("prefixFlag", buf.readUnsignedByte()); position.set("prefix", BufferUtil.readString(buf, length - 1)); - break; - case 0x33: - position.set("phoneSwitches", buf.readUnsignedByte()); - break; - case 0x40: - position.set("apn", BufferUtil.readString(buf, length)); - break; - case 0x41: - position.set("apnUser", BufferUtil.readString(buf, length)); - break; - case 0x42: - position.set("apnPassword", BufferUtil.readString(buf, length)); - break; - case 0x43: + } + case 0x33 -> position.set("phoneSwitches", buf.readUnsignedByte()); + case 0x40 -> position.set("apn", BufferUtil.readString(buf, length)); + case 0x41 -> position.set("apnUser", BufferUtil.readString(buf, length)); + case 0x42 -> position.set("apnPassword", BufferUtil.readString(buf, length)); + case 0x43 -> { buf.readUnsignedByte(); // flag position.set("port", buf.readUnsignedShort()); position.set("server", BufferUtil.readString(buf, length - 3)); - break; - case 0x44: + } + case 0x44 -> { position.set("heartbeatInterval", buf.readUnsignedInt()); position.set("uploadInterval", buf.readUnsignedInt()); position.set("uploadLazyInterval", buf.readUnsignedInt()); - break; - case 0x47: - position.set("deviceId", BufferUtil.readString(buf, length)); - break; - case 0x4E: - position.set("gsmBand", buf.readUnsignedByte()); - break; - case 0x50: - position.set("powerAlert", buf.readUnsignedInt()); - break; - case 0x51: - position.set("geoAlert", buf.readUnsignedInt()); - break; - case 0x53: - position.set("motionAlert", buf.readUnsignedInt()); - break; - case 0x5C: + } + case 0x47 -> position.set("deviceId", BufferUtil.readString(buf, length)); + case 0x4E -> position.set("gsmBand", buf.readUnsignedByte()); + case 0x50 -> position.set("powerAlert", buf.readUnsignedInt()); + case 0x51 -> position.set("geoAlert", buf.readUnsignedInt()); + case 0x53 -> position.set("motionAlert", buf.readUnsignedInt()); + case 0x5C -> { position.set("barkLevel", buf.readUnsignedByte()); position.set("barkInterval", buf.readUnsignedInt()); - break; - case 0x61: - position.set("msisdn", BufferUtil.readString(buf, length)); - break; - case 0x62: + } + case 0x61 -> position.set("msisdn", BufferUtil.readString(buf, length)); + case 0x62 -> { position.set("wifiWhitelist", buf.readUnsignedByte()); position.set("wifiWhitelistMac", ByteBufUtil.hexDump(buf.readSlice(6))); - break; - case 0x64: + } + case 0x64 -> { position.set(Position.KEY_RSSI, buf.readUnsignedByte()); position.set("networkBand", buf.readUnsignedInt()); position.set(Position.KEY_OPERATOR, BufferUtil.readString(buf, length - 5)); - break; - case 0x65: + } + case 0x65 -> { position.set(Position.KEY_RSSI, buf.readUnsignedByte()); position.set("networkStatus", buf.readUnsignedByte()); position.set("serverStatus", buf.readUnsignedByte()); position.set("networkPlmn", ByteBufUtil.hexDump(buf.readSlice(6))); position.set("homePlmn", ByteBufUtil.hexDump(buf.readSlice(6))); - break; - case 0x66: - position.set("imsi", BufferUtil.readString(buf, length)); - break; - case 0x75: - position.set("extraEnableControl", buf.readUnsignedInt()); - break; - default: - break; + } + case 0x66 -> position.set("imsi", BufferUtil.readString(buf, length)); + case 0x75 -> position.set("extraEnableControl", buf.readUnsignedInt()); } buf.readerIndex(endIndex); diff --git a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java index d7600ecbb..314562bd6 100644 --- a/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/MobilogixProtocolDecoder.java @@ -59,24 +59,16 @@ public class MobilogixProtocolDecoder extends BaseProtocolDecoder { .compile(); private String decodeAlarm(String type) { - switch (type) { - case "T8": - return Position.ALARM_LOW_BATTERY; - case "T9": - return Position.ALARM_VIBRATION; - case "T10": - return Position.ALARM_POWER_CUT; - case "T11": - return Position.ALARM_LOW_POWER; - case "T12": - return Position.ALARM_GEOFENCE_EXIT; - case "T13": - return Position.ALARM_OVERSPEED; - case "T15": - return Position.ALARM_TOW; - default: - return null; - } + return switch (type) { + case "T8" -> Position.ALARM_LOW_BATTERY; + case "T9" -> Position.ALARM_VIBRATION; + case "T10" -> Position.ALARM_POWER_CUT; + case "T11" -> Position.ALARM_LOW_POWER; + case "T12" -> Position.ALARM_GEOFENCE_EXIT; + case "T13" -> Position.ALARM_OVERSPEED; + case "T15" -> Position.ALARM_TOW; + default -> null; + }; } @Override diff --git a/src/main/java/org/traccar/protocol/Mta6ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Mta6ProtocolDecoder.java index 9704cf099..c76588d38 100644 --- a/src/main/java/org/traccar/protocol/Mta6ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Mta6ProtocolDecoder.java @@ -75,21 +75,11 @@ public class Mta6ProtocolDecoder extends BaseProtocolDecoder { public float readFloat(ByteBuf buf) { switch (buf.getUnsignedByte(buf.readerIndex()) >> 6) { - case 0: - previousFloat = buf.readInt() << 2; - break; - case 1: - previousFloat = (previousFloat & 0xffffff00) + ((buf.readUnsignedByte() & 0x3f) << 2); - break; - case 2: - previousFloat = (previousFloat & 0xffff0000) + ((buf.readUnsignedShort() & 0x3fff) << 2); - break; - case 3: - previousFloat = (previousFloat & 0xff000000) + ((buf.readUnsignedMedium() & 0x3fffff) << 2); - break; - default: - LOGGER.warn("MTA6 float decoding error", new IllegalArgumentException()); - break; + case 0 -> previousFloat = buf.readInt() << 2; + case 1 -> previousFloat = (previousFloat & 0xffffff00) + ((buf.readUnsignedByte() & 0x3f) << 2); + case 2 -> previousFloat = (previousFloat & 0xffff0000) + ((buf.readUnsignedShort() & 0x3fff) << 2); + case 3 -> previousFloat = (previousFloat & 0xff000000) + ((buf.readUnsignedMedium() & 0x3fffff) << 2); + default -> LOGGER.warn("MTA6 float decoding error"); } return Float.intBitsToFloat(previousFloat); } diff --git a/src/main/java/org/traccar/protocol/NavigilProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavigilProtocolDecoder.java index 6dadbc559..5d3bae8e8 100644 --- a/src/main/java/org/traccar/protocol/NavigilProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavigilProtocolDecoder.java @@ -287,22 +287,15 @@ public class NavigilProtocolDecoder extends BaseProtocolDecoder { sendAcknowledgment(channel, sequenceNumber); } - switch (messageId) { - case MSG_UNIT_REPORT: - return parseUnitReport(deviceSession, buf, sequenceNumber); - case MSG_TG2_REPORT: - return parseTg2Report(deviceSession, buf, sequenceNumber); - case MSG_POSITION_REPORT: - return parsePositionReport(deviceSession, buf, sequenceNumber, timestamp); - case MSG_POSITION_REPORT_2: - return parsePositionReport2(deviceSession, buf, sequenceNumber, timestamp); - case MSG_SNAPSHOT4: - return parseSnapshot4(deviceSession, buf, sequenceNumber); - case MSG_TRACKING_DATA: - return parseTrackingData(deviceSession, buf, sequenceNumber, timestamp); - default: - return null; - } + return switch (messageId) { + case MSG_UNIT_REPORT -> parseUnitReport(deviceSession, buf, sequenceNumber); + case MSG_TG2_REPORT -> parseTg2Report(deviceSession, buf, sequenceNumber); + case MSG_POSITION_REPORT -> parsePositionReport(deviceSession, buf, sequenceNumber, timestamp); + case MSG_POSITION_REPORT_2 -> parsePositionReport2(deviceSession, buf, sequenceNumber, timestamp); + case MSG_SNAPSHOT4 -> parseSnapshot4(deviceSession, buf, sequenceNumber); + case MSG_TRACKING_DATA -> parseTrackingData(deviceSession, buf, sequenceNumber, timestamp); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/NavisFrameDecoder.java b/src/main/java/org/traccar/protocol/NavisFrameDecoder.java index 8a0bb0b9a..9d560d19c 100644 --- a/src/main/java/org/traccar/protocol/NavisFrameDecoder.java +++ b/src/main/java/org/traccar/protocol/NavisFrameDecoder.java @@ -57,17 +57,12 @@ public class NavisFrameDecoder extends BaseFrameDecoder { String type = buf.toString(buf.readerIndex(), 2, StandardCharsets.US_ASCII); switch (type) { // FLEX 1.0 - case "~A": - length = flexDataSize * buf.getByte(buf.readerIndex() + FLEX_HEADER_LENGTH) + 1 + 1; - break; - case "~T": - length = flexDataSize + 4 + 1; - break; - case "~C": - length = flexDataSize + 1; - break; + case "~A" -> length = flexDataSize * buf.getByte(buf.readerIndex() + FLEX_HEADER_LENGTH) + 1 + 1; + case "~T" -> length = flexDataSize + 4 + 1; + case "~C" -> length = flexDataSize + 1; + // FLEX 2.0 (Extra packages) - case "~E": + case "~E" -> { length++; for (int i = 0; i < buf.getByte(buf.readerIndex() + FLEX_HEADER_LENGTH); i++) { if (buf.readableBytes() > FLEX_HEADER_LENGTH + length + 1) { @@ -77,12 +72,11 @@ public class NavisFrameDecoder extends BaseFrameDecoder { } } length++; - break; - case "~X": - length = buf.getUnsignedShortLE(buf.readerIndex() + FLEX_HEADER_LENGTH) + 4 + 1; - break; - default: + } + case "~X" -> length = buf.getUnsignedShortLE(buf.readerIndex() + FLEX_HEADER_LENGTH) + 4 + 1; + default -> { return null; + } } if (buf.readableBytes() >= FLEX_HEADER_LENGTH + length) { diff --git a/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java b/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java index 77158b315..8a0566754 100644 --- a/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NavisProtocolDecoder.java @@ -317,136 +317,90 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder { } switch (i) { - case 0: - position.set(Position.KEY_INDEX, buf.readUnsignedIntLE()); - break; - case 1: - position.set(Position.KEY_EVENT, buf.readUnsignedShortLE()); - break; - case 3: + case 0 -> position.set(Position.KEY_INDEX, buf.readUnsignedIntLE()); + case 1 -> position.set(Position.KEY_EVENT, buf.readUnsignedShortLE()); + case 3 -> { short armedStatus = buf.readUnsignedByte(); position.set(Position.KEY_ARMED, BitUtil.check(armedStatus, 0)); if (BitUtil.check(armedStatus, 1)) { position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); } - break; - case 4: + } + case 4 -> { status = buf.readUnsignedByte(); position.set(Position.KEY_STATUS, status); - break; - case 5: + } + case 5 -> { int status2 = buf.readUnsignedByte(); position.set(Position.KEY_STATUS, (short) (BitUtil.to(status, 8) | (status2 << 8))); - break; - case 6: - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - break; - case 7: + } + case 6 -> position.set(Position.KEY_RSSI, buf.readUnsignedByte()); + case 7 -> { int navSensorState = buf.readUnsignedByte(); position.setValid(BitUtil.check(navSensorState, 1)); position.set(Position.KEY_SATELLITES, BitUtil.from(navSensorState, 2)); - break; - case 8: - position.setTime(new DateBuilder(new Date(buf.readUnsignedIntLE() * 1000)).getDate()); - break; - case 9: - position.setLatitude(buf.readIntLE() / 600000.0); - break; - case 10: - position.setLongitude(buf.readIntLE() / 600000.0); - break; - case 11: - position.setAltitude(buf.readIntLE() * 0.1); - break; - case 12: - position.setSpeed(UnitsConverter.knotsFromKph(buf.readFloatLE())); - break; - case 13: - position.setCourse(buf.readUnsignedShortLE()); - break; - case 14: - position.set(Position.KEY_ODOMETER, buf.readFloatLE() * 1000); - break; - case 15: - position.set(Position.KEY_DISTANCE, buf.readFloatLE() * 1000); - break; - case 18: - position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.001); - break; - case 19: - position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.001); - break; - case 20: - case 21: - case 22: - case 23: - case 24: - case 25: - case 26: - case 27: - position.set(Position.PREFIX_ADC + (i - 19), buf.readUnsignedShortLE()); - break; - case 28: + } + case 8 -> position.setTime(new DateBuilder(new Date(buf.readUnsignedIntLE() * 1000)).getDate()); + case 9 -> position.setLatitude(buf.readIntLE() / 600000.0); + case 10 -> position.setLongitude(buf.readIntLE() / 600000.0); + case 11 -> position.setAltitude(buf.readIntLE() * 0.1); + case 12 -> position.setSpeed(UnitsConverter.knotsFromKph(buf.readFloatLE())); + case 13 -> position.setCourse(buf.readUnsignedShortLE()); + case 14 -> position.set(Position.KEY_ODOMETER, buf.readFloatLE() * 1000); + case 15 -> position.set(Position.KEY_DISTANCE, buf.readFloatLE() * 1000); + case 18 -> position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.001); + case 19 -> position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.001); + case 20, 21, 22, 23, 24, 25, 26, 27 -> + position.set(Position.PREFIX_ADC + (i - 19), buf.readUnsignedShortLE()); + case 28 -> { input = buf.readUnsignedByte(); position.set(Position.KEY_INPUT, input); for (int k = 0; k < 8; k++) { position.set(Position.PREFIX_IN + (k + 1), BitUtil.check(input, k)); } - break; - case 29: + } + case 29 -> { short input2 = buf.readUnsignedByte(); position.set(Position.KEY_INPUT, (short) (BitUtil.to(input, 8) | (input2 << 8))); for (int k = 0; k < 8; k++) { position.set(Position.PREFIX_IN + (k + 9), BitUtil.check(input2, k)); } - break; - case 30: + } + case 30 -> { output = buf.readUnsignedByte(); position.set(Position.KEY_OUTPUT, output); for (int k = 0; k < 8; k++) { position.set(Position.PREFIX_OUT + (k + 1), BitUtil.check(output, k)); } - break; - case 31: + } + case 31 -> { short output2 = buf.readUnsignedByte(); position.set(Position.KEY_OUTPUT, (short) (BitUtil.to(output, 8) | (output2 << 8))); for (int k = 0; k < 8; k++) { position.set(Position.PREFIX_OUT + (k + 9), BitUtil.check(output2, k)); } - break; - case 36: - position.set(Position.KEY_HOURS, buf.readUnsignedIntLE() * 1000); - break; - case 44: - case 45: - case 46: - case 47: - case 48: - case 49: - case 50: - case 51: - position.set(Position.PREFIX_TEMP + (i - 43), buf.readByte()); - break; - case 68: - position.set("can-speed", buf.readUnsignedByte()); - break; + } + case 36 -> position.set(Position.KEY_HOURS, buf.readUnsignedIntLE() * 1000); + case 44, 45, 46, 47, 48, 49, 50, 51 -> position.set(Position.PREFIX_TEMP + (i - 43), buf.readByte()); + case 68 -> position.set("can-speed", buf.readUnsignedByte()); + // FLEX 2.0 - case 69: + case 69 -> { int satVisible = 0; for (int k = 0; k < 8; k++) { satVisible += buf.readUnsignedByte(); } position.set(Position.KEY_SATELLITES_VISIBLE, satVisible); - break; - case 70: + } + case 70 -> { position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); position.set(Position.KEY_PDOP, buf.readUnsignedByte() * 0.1); - break; - default: + } + default -> { if (i < FLEX_FIELDS_SIZES.length) { buf.skipBytes(FLEX_FIELDS_SIZES[i]); } - break; + } } } @@ -616,17 +570,15 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder { } else { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession != null) { - switch (type) { - case "*>A": - return processNtcbArray(deviceSession, channel, buf); - case "*>T": - return processNtcbSingle(deviceSession, channel, buf); - case "*>F": + return switch (type) { + case "*>A" -> processNtcbArray(deviceSession, channel, buf); + case "*>T" -> processNtcbSingle(deviceSession, channel, buf); + case "*>F" -> { buf.skipBytes(3); - return processFlexNegotiation(channel, buf); - default: - break; - } + yield processFlexNegotiation(channel, buf); + } + default -> null; + }; } } @@ -644,23 +596,16 @@ public class NavisProtocolDecoder extends BaseProtocolDecoder { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession != null) { - switch (type) { + return switch (type) { // FLEX 1.0 - case "~A": - return processFlexArray(this::parseFlexPosition, type, deviceSession, channel, buf); - case "~T": - case "~C": - return processFlexSingle(this::parseFlexPosition, type, deviceSession, channel, buf); + case "~A" -> processFlexArray(this::parseFlexPosition, type, deviceSession, channel, buf); + case "~T", "~C" -> processFlexSingle(this::parseFlexPosition, type, deviceSession, channel, buf); // FLEX 2.0 (extra packages) - case "~E": - return processFlexArray(this::parseFlex20Position, type, deviceSession, channel, buf); - case "~X": - return processFlexSingle(this::parseFlex20Position, type, deviceSession, channel, buf); - default: - break; - } + case "~E" -> processFlexArray(this::parseFlex20Position, type, deviceSession, channel, buf); + case "~X" -> processFlexSingle(this::parseFlex20Position, type, deviceSession, channel, buf); + default -> null; + }; } - return null; } diff --git a/src/main/java/org/traccar/protocol/NdtpV6ProtocolEncoder.java b/src/main/java/org/traccar/protocol/NdtpV6ProtocolEncoder.java index 7aac8658a..eac6de133 100644 --- a/src/main/java/org/traccar/protocol/NdtpV6ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/NdtpV6ProtocolEncoder.java @@ -27,16 +27,12 @@ public class NdtpV6ProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_IDENTIFICATION: - return "BB+IDNT"; - case Command.TYPE_REBOOT_DEVICE: - return "BB+RESET"; - case Command.TYPE_POSITION_SINGLE: - return "BB+RRCD"; - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_IDENTIFICATION -> "BB+IDNT"; + case Command.TYPE_REBOOT_DEVICE -> "BB+RESET"; + case Command.TYPE_POSITION_SINGLE -> "BB+RRCD"; + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java b/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java index 35614ccca..d53271778 100644 --- a/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NiotProtocolDecoder.java @@ -99,14 +99,8 @@ public class NiotProtocolDecoder extends BaseProtocolDecoder { int statusX = buf.readUnsignedByte(); position.setValid(BitUtil.check(statusX, 7)); switch (BitUtil.between(statusX, 3, 5)) { - case 0b10: - position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); - break; - case 0b01: - position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); - break; - default: - break; + case 0b10 -> position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); + case 0b01 -> position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); } position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); diff --git a/src/main/java/org/traccar/protocol/NoranProtocolDecoder.java b/src/main/java/org/traccar/protocol/NoranProtocolDecoder.java index 53b58f9b6..80ac587e5 100644 --- a/src/main/java/org/traccar/protocol/NoranProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NoranProtocolDecoder.java @@ -90,20 +90,10 @@ public class NoranProtocolDecoder extends BaseProtocolDecoder { short alarm = buf.readUnsignedByte(); switch (alarm) { - case 1: - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - break; - case 2: - position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); - break; - case 3: - position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE_EXIT); - break; - case 9: - position.set(Position.KEY_ALARM, Position.ALARM_POWER_OFF); - break; - default: - break; + case 1 -> position.set(Position.KEY_ALARM, Position.ALARM_SOS); + case 2 -> position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); + case 3 -> position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE_EXIT); + case 9 -> position.set(Position.KEY_ALARM, Position.ALARM_POWER_OFF); } if (newFormat) { diff --git a/src/main/java/org/traccar/protocol/NoranProtocolEncoder.java b/src/main/java/org/traccar/protocol/NoranProtocolEncoder.java index e02a1313c..c8043224d 100644 --- a/src/main/java/org/traccar/protocol/NoranProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/NoranProtocolEncoder.java @@ -49,21 +49,17 @@ public class NoranProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_POSITION_SINGLE: - return encodeContent("*KW,000,000,000000#"); - case Command.TYPE_POSITION_PERIODIC: + return switch (command.getType()) { + case Command.TYPE_POSITION_SINGLE -> encodeContent("*KW,000,000,000000#"); + case Command.TYPE_POSITION_PERIODIC -> { int interval = command.getInteger(Command.KEY_FREQUENCY); - return encodeContent("*KW,000,002,000000," + interval + "#"); - case Command.TYPE_POSITION_STOP: - return encodeContent("*KW,000,002,000000,0#"); - case Command.TYPE_ENGINE_STOP: - return encodeContent("*KW,000,007,000000,0#"); - case Command.TYPE_ENGINE_RESUME: - return encodeContent("*KW,000,007,000000,1#"); - default: - return null; - } + yield encodeContent("*KW,000,002,000000," + interval + "#"); + } + case Command.TYPE_POSITION_STOP -> encodeContent("*KW,000,002,000000,0#"); + case Command.TYPE_ENGINE_STOP -> encodeContent("*KW,000,007,000000,0#"); + case Command.TYPE_ENGINE_RESUME -> encodeContent("*KW,000,007,000000,1#"); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/NyitechProtocolDecoder.java b/src/main/java/org/traccar/protocol/NyitechProtocolDecoder.java index 49bc5b824..0366cffcd 100644 --- a/src/main/java/org/traccar/protocol/NyitechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/NyitechProtocolDecoder.java @@ -63,18 +63,13 @@ public class NyitechProtocolDecoder extends BaseProtocolDecoder { } private String decodeAlarm(int type) { - switch (type) { - case 0x09: - return Position.ALARM_ACCELERATION; - case 0x0a: - return Position.ALARM_BRAKING; - case 0x0b: - return Position.ALARM_CORNERING; - case 0x0e: - return Position.ALARM_SOS; - default: - return null; - } + return switch (type) { + case 0x09 -> Position.ALARM_ACCELERATION; + case 0x0a -> Position.ALARM_BRAKING; + case 0x0b -> Position.ALARM_CORNERING; + case 0x0e -> Position.ALARM_SOS; + default -> null; + }; } @Override @@ -121,18 +116,10 @@ public class NyitechProtocolDecoder extends BaseProtocolDecoder { int pid = buf.readUnsignedShortLE(); int length = buf.readUnsignedByte(); switch (length) { - case 1: - position.add(ObdDecoder.decodeData(pid, buf.readByte(), true)); - break; - case 2: - position.add(ObdDecoder.decodeData(pid, buf.readShortLE(), true)); - break; - case 4: - position.add(ObdDecoder.decodeData(pid, buf.readIntLE(), true)); - break; - default: - buf.skipBytes(length); - break; + case 1 -> position.add(ObdDecoder.decodeData(pid, buf.readByte(), true)); + case 2 -> position.add(ObdDecoder.decodeData(pid, buf.readShortLE(), true)); + case 4 -> position.add(ObdDecoder.decodeData(pid, buf.readIntLE(), true)); + default -> buf.skipBytes(length); } } } diff --git a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java index 7ed13d647..48303a65d 100644 --- a/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OrbcommProtocolDecoder.java @@ -85,24 +85,14 @@ public class OrbcommProtocolDecoder extends BaseProtocolDecoder { JsonObject field = fields.getJsonObject(j); String value = field.getString("Value"); switch (field.getString("Name").toLowerCase()) { - case "eventtime": - position.setDeviceTime(new Date(Long.parseLong(value) * 1000)); - break; - case "latitude": - position.setLatitude(Integer.parseInt(value) / 60000.0); - break; - case "longitude": - position.setLongitude(Integer.parseInt(value) / 60000.0); - break; - case "speed": - position.setSpeed(UnitsConverter.knotsFromKph(Integer.parseInt(value))); - break; - case "heading": + case "eventtime" -> position.setDeviceTime(new Date(Long.parseLong(value) * 1000)); + case "latitude" -> position.setLatitude(Integer.parseInt(value) / 60000.0); + case "longitude" -> position.setLongitude(Integer.parseInt(value) / 60000.0); + case "speed" -> position.setSpeed(UnitsConverter.knotsFromKph(Integer.parseInt(value))); + case "heading" -> { int heading = Integer.parseInt(value); position.setCourse(heading <= 360 ? heading : 0); - break; - default: - break; + } } } diff --git a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java index c8968023a..b044b9596 100644 --- a/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OsmAndProtocolDecoder.java @@ -151,15 +151,9 @@ public class OsmAndProtocolDecoder extends BaseHttpProtocolDecoder { position.set(entry.getKey(), Double.parseDouble(value)); } catch (NumberFormatException e) { switch (value) { - case "true": - position.set(entry.getKey(), true); - break; - case "false": - position.set(entry.getKey(), false); - break; - default: - position.set(entry.getKey(), value); - break; + case "true" -> position.set(entry.getKey(), true); + case "false" -> position.set(entry.getKey(), false); + default -> position.set(entry.getKey(), value); } } break; diff --git a/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java b/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java index f71778412..0a6026d91 100644 --- a/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OutsafeProtocolDecoder.java @@ -77,10 +77,10 @@ public class OutsafeProtocolDecoder extends BaseHttpProtocolDecoder { } private void decodeUnknownParam(String name, JsonValue value, Position position) { - if (value instanceof JsonNumber) { - position.set(name, ((JsonNumber) value).doubleValue()); - } else if (value instanceof JsonString) { - position.set(name, ((JsonString) value).getString()); + if (value instanceof JsonNumber jsonNumber) { + position.set(name, jsonNumber.doubleValue()); + } else if (value instanceof JsonString jsonString) { + position.set(name, jsonString.getString()); } else if (value == JsonValue.TRUE || value == JsonValue.FALSE) { position.set(name, value == JsonValue.TRUE); } diff --git a/src/main/java/org/traccar/protocol/OwnTracksProtocolDecoder.java b/src/main/java/org/traccar/protocol/OwnTracksProtocolDecoder.java index e54d07fa7..f04c4a295 100644 --- a/src/main/java/org/traccar/protocol/OwnTracksProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/OwnTracksProtocolDecoder.java @@ -167,31 +167,15 @@ public class OwnTracksProtocolDecoder extends BaseHttpProtocolDecoder { private void setEventOrAlarm(Position position, String trigger, Integer reportType) { switch (trigger) { - case "9": - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - case "1": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_ON); - break; - case "i": - position.set(Position.KEY_IGNITION, true); - break; - case "I": - position.set(Position.KEY_IGNITION, false); - break; - case "E": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED); - break; - case "e": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); - break; - case "!": - position.set(Position.KEY_ALARM, Position.ALARM_TOW); - break; - case "s": - position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); - break; - case "h": + case "9" -> position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + case "1" -> position.set(Position.KEY_ALARM, Position.ALARM_POWER_ON); + case "i" -> position.set(Position.KEY_IGNITION, true); + case "I" -> position.set(Position.KEY_IGNITION, false); + case "E" -> position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED); + case "e" -> position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); + case "!" -> position.set(Position.KEY_ALARM, Position.ALARM_TOW); + case "s" -> position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); + case "h" -> { switch (reportType) { case 0: case 3: @@ -207,9 +191,7 @@ public class OwnTracksProtocolDecoder extends BaseHttpProtocolDecoder { position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); break; } - break; - default: - break; + } } } } diff --git a/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java b/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java index 7079745be..87ae74727 100644 --- a/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PacificTrackProtocolDecoder.java @@ -94,101 +94,45 @@ public class PacificTrackProtocolDecoder extends BaseProtocolDecoder { int fieldPrefix = BitUtil.from(field, 5); if (fieldPrefix < 0b100) { switch (BitUtil.between(field, 2, 5)) { - case 0b000: - position.set("bus", BitUtil.to(field, 2)); - break; - case 0b001: - position.set("currentGear", BitUtil.to(field, 2)); - break; - default: - break; + case 0b000 -> position.set("bus", BitUtil.to(field, 2)); + case 0b001 -> position.set("currentGear", BitUtil.to(field, 2)); } } else if (fieldPrefix < 0b101) { switch (BitUtil.to(field, 5)) { - case 0b00000: - position.set(Position.KEY_OBD_SPEED, buf.readUnsignedByte()); - break; - case 0b00001: - position.set(Position.KEY_RPM, buf.readUnsignedByte() * 32); - break; - case 0b00011: - position.set("oilPressure", buf.readUnsignedByte() * 4); - break; - case 0b00100: - position.set("oilLevel", buf.readUnsignedByte() * 0.4); - break; - case 0b00101: - position.set("oilTemp", buf.readUnsignedByte() - 40); - break; - case 0b00110: - position.set("coolantLevel", buf.readUnsignedByte() * 0.4); - break; - case 0b00111: - position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte() - 40); - break; - case 0b01000: - position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte() * 0.4); - break; - case 0b01001: - position.set("defLevel", buf.readUnsignedByte() * 0.4); - break; - case 0b01010: - position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedByte()); - break; - case 0b01011: - position.set("barometer", buf.readUnsignedByte() * 0.5); - break; - case 0b01100: - position.set("intakeManifoldTemp", buf.readUnsignedByte() - 40); - break; - case 0b01101: - position.set("fuelTankTemp", buf.readUnsignedByte() - 40); - break; - case 0b01110: - position.set("intercoolerTemp", buf.readUnsignedByte() - 40); - break; - case 0b01111: - position.set("turboOilTemp", buf.readUnsignedByte() - 40); - break; - case 0b10000: - position.set("transOilTemp", buf.readUnsignedByte() - 40); - break; - default: - buf.readUnsignedByte(); - break; + case 0b00000 -> position.set(Position.KEY_OBD_SPEED, buf.readUnsignedByte()); + case 0b00001 -> position.set(Position.KEY_RPM, buf.readUnsignedByte() * 32); + case 0b00011 -> position.set("oilPressure", buf.readUnsignedByte() * 4); + case 0b00100 -> position.set("oilLevel", buf.readUnsignedByte() * 0.4); + case 0b00101 -> position.set("oilTemp", buf.readUnsignedByte() - 40); + case 0b00110 -> position.set("coolantLevel", buf.readUnsignedByte() * 0.4); + case 0b00111 -> position.set(Position.KEY_COOLANT_TEMP, buf.readUnsignedByte() - 40); + case 0b01000 -> position.set(Position.KEY_FUEL_LEVEL, buf.readUnsignedByte() * 0.4); + case 0b01001 -> position.set("defLevel", buf.readUnsignedByte() * 0.4); + case 0b01010 -> position.set(Position.KEY_ENGINE_LOAD, buf.readUnsignedByte()); + case 0b01011 -> position.set("barometer", buf.readUnsignedByte() * 0.5); + case 0b01100 -> position.set("intakeManifoldTemp", buf.readUnsignedByte() - 40); + case 0b01101 -> position.set("fuelTankTemp", buf.readUnsignedByte() - 40); + case 0b01110 -> position.set("intercoolerTemp", buf.readUnsignedByte() - 40); + case 0b01111 -> position.set("turboOilTemp", buf.readUnsignedByte() - 40); + case 0b10000 -> position.set("transOilTemp", buf.readUnsignedByte() - 40); + default -> buf.readUnsignedByte(); } } else if (fieldPrefix < 0b110) { switch (BitUtil.to(field, 5)) { - case 0b00010: - position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() / 512.0); - break; - case 0b00011: - position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedShort() * 0.03125 - 273); - break; - default: - buf.readUnsignedShort(); - break; + case 0b00010 -> position.set( + Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedShort() / 512.0); + case 0b00011 -> position.set( + Position.PREFIX_TEMP + 1, buf.readUnsignedShort() * 0.03125 - 273); + default -> buf.readUnsignedShort(); } } else if (fieldPrefix < 0b111) { switch (BitUtil.to(field, 5)) { - case 0b00000: - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 100); - break; - case 0b00001: - position.set(Position.KEY_HOURS, buf.readUnsignedInt() * 180); - break; - case 0b00010: - position.set("idleHours", buf.readUnsignedInt() * 180); - break; - case 0b00100: - position.set(Position.KEY_FUEL_USED, buf.readUnsignedInt() * 0.5); - break; - case 0b00101: - position.set("fuelUsedIdle", buf.readUnsignedInt() * 0.5); - break; - default: - buf.readUnsignedInt(); - break; + case 0b00000 -> position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 100); + case 0b00001 -> position.set(Position.KEY_HOURS, buf.readUnsignedInt() * 180); + case 0b00010 -> position.set("idleHours", buf.readUnsignedInt() * 180); + case 0b00100 -> position.set(Position.KEY_FUEL_USED, buf.readUnsignedInt() * 0.5); + case 0b00101 -> position.set("fuelUsedIdle", buf.readUnsignedInt() * 0.5); + default -> buf.readUnsignedInt(); } } else { buf.skipBytes(buf.readUnsignedByte()); diff --git a/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java b/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java index 6ee95d18a..aca5d3eb6 100644 --- a/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/PluginProtocolDecoder.java @@ -125,15 +125,8 @@ public class PluginProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext()) { int event = parser.nextInt(); switch (event) { - case 11317: - position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - break; - case 11319: - position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); - break; - default: - break; - + case 11317 -> position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + case 11319 -> position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); } position.set(Position.KEY_EVENT, event); } diff --git a/src/main/java/org/traccar/protocol/PortmanProtocolEncoder.java b/src/main/java/org/traccar/protocol/PortmanProtocolEncoder.java index eb3115db8..22c4c3127 100644 --- a/src/main/java/org/traccar/protocol/PortmanProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/PortmanProtocolEncoder.java @@ -28,14 +28,11 @@ public class PortmanProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_ENGINE_STOP: - return formatCommand(command, "&&%s,XA5\r\n", Command.KEY_UNIQUE_ID); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "&&%s,XA6\r\n", Command.KEY_UNIQUE_ID); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_ENGINE_STOP -> formatCommand(command, "&&%s,XA5\r\n", Command.KEY_UNIQUE_ID); + case Command.TYPE_ENGINE_RESUME -> formatCommand(command, "&&%s,XA6\r\n", Command.KEY_UNIQUE_ID); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java b/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java index a109e7a07..354fc5992 100644 --- a/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/PretraceProtocolEncoder.java @@ -36,15 +36,13 @@ public class PretraceProtocolEncoder extends BaseProtocolEncoder { String uniqueId = getUniqueId(command.getDeviceId()); - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return formatCommand(uniqueId, command.getString(Command.KEY_DATA)); - case Command.TYPE_POSITION_PERIODIC: - return formatCommand( - uniqueId, String.format("D221%1$d,%1$d,,", command.getInteger(Command.KEY_FREQUENCY))); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_CUSTOM -> formatCommand( + uniqueId, command.getString(Command.KEY_DATA)); + case Command.TYPE_POSITION_PERIODIC -> formatCommand( + uniqueId, String.format("D221%1$d,%1$d,,", command.getInteger(Command.KEY_FREQUENCY))); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/PstProtocolEncoder.java b/src/main/java/org/traccar/protocol/PstProtocolEncoder.java index f3d193324..ad7186630 100644 --- a/src/main/java/org/traccar/protocol/PstProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/PstProtocolEncoder.java @@ -49,14 +49,11 @@ public class PstProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_ENGINE_STOP: - return encodeContent(command.getDeviceId(), 0x0002, 0xffff, 0xffff); - case Command.TYPE_ENGINE_RESUME: - return encodeContent(command.getDeviceId(), 0x0001, 0xffff, 0xffff); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_ENGINE_STOP -> encodeContent(command.getDeviceId(), 0x0002, 0xffff, 0xffff); + case Command.TYPE_ENGINE_RESUME -> encodeContent(command.getDeviceId(), 0x0001, 0xffff, 0xffff); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java index 2a6a81a65..2e88186b8 100644 --- a/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Pt502ProtocolDecoder.java @@ -66,28 +66,18 @@ public class Pt502ProtocolDecoder extends BaseProtocolDecoder { .compile(); private String decodeAlarm(String value) { - switch (value) { - case "IN1": - return Position.ALARM_SOS; - case "GOF": - return Position.ALARM_GEOFENCE; - case "TOW": - return Position.ALARM_TOW; - case "HDA": - return Position.ALARM_ACCELERATION; - case "HDB": - return Position.ALARM_BRAKING; - case "FDA": - return Position.ALARM_FATIGUE_DRIVING; - case "SKA": - return Position.ALARM_VIBRATION; - case "PMA": - return Position.ALARM_MOVEMENT; - case "CPA": - return Position.ALARM_POWER_CUT; - default: - return null; - } + return switch (value) { + case "IN1" -> Position.ALARM_SOS; + case "GOF" -> Position.ALARM_GEOFENCE; + case "TOW" -> Position.ALARM_TOW; + case "HDA" -> Position.ALARM_ACCELERATION; + case "HDB" -> Position.ALARM_BRAKING; + case "FDA" -> Position.ALARM_FATIGUE_DRIVING; + case "SKA" -> Position.ALARM_VIBRATION; + case "PMA" -> Position.ALARM_MOVEMENT; + case "CPA" -> Position.ALARM_POWER_CUT; + default -> null; + }; } private Position decodePosition(Channel channel, SocketAddress remoteAddress, String sentence) { diff --git a/src/main/java/org/traccar/protocol/Pt502ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Pt502ProtocolEncoder.java index 364ecae86..2530ae131 100644 --- a/src/main/java/org/traccar/protocol/Pt502ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Pt502ProtocolEncoder.java @@ -44,20 +44,15 @@ public class Pt502ProtocolEncoder extends StringProtocolEncoder implements Strin @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return formatCommand(command, "%s\r\n", Command.KEY_DATA); - case Command.TYPE_OUTPUT_CONTROL: - return formatCommand(command, "#OPC%s,%s\r\n", Command.KEY_INDEX, Command.KEY_DATA); - case Command.TYPE_SET_TIMEZONE: - return formatCommand(command, "#TMZ%s\r\n", Command.KEY_TIMEZONE); - case Command.TYPE_ALARM_SPEED: - return formatCommand(command, "#SPD%s\r\n", Command.KEY_DATA); - case Command.TYPE_REQUEST_PHOTO: - return formatCommand(command, "#PHO\r\n"); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_CUSTOM -> formatCommand(command, "%s\r\n", Command.KEY_DATA); + case Command.TYPE_OUTPUT_CONTROL -> + formatCommand(command, "#OPC%s,%s\r\n", Command.KEY_INDEX, Command.KEY_DATA); + case Command.TYPE_SET_TIMEZONE -> formatCommand(command, "#TMZ%s\r\n", Command.KEY_TIMEZONE); + case Command.TYPE_ALARM_SPEED -> formatCommand(command, "#SPD%s\r\n", Command.KEY_DATA); + case Command.TYPE_REQUEST_PHOTO -> formatCommand(command, "#PHO\r\n"); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/RetranslatorProtocolDecoder.java b/src/main/java/org/traccar/protocol/RetranslatorProtocolDecoder.java index afbf7e511..6296eb5b9 100644 --- a/src/main/java/org/traccar/protocol/RetranslatorProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RetranslatorProtocolDecoder.java @@ -81,22 +81,14 @@ public class RetranslatorProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_SATELLITES, buf.readByte()); } else { switch (dataType) { - case 1: + case 1 -> { int len = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0x00) - buf.readerIndex(); position.set(name, buf.readCharSequence(len, StandardCharsets.US_ASCII).toString()); buf.readByte(); - break; - case 3: - position.set(name, buf.readInt()); - break; - case 4: - position.set(name, buf.readDoubleLE()); - break; - case 5: - position.set(name, buf.readLong()); - break; - default: - break; + } + case 3 -> position.set(name, buf.readInt()); + case 4 -> position.set(name, buf.readDoubleLE()); + case 5 -> position.set(name, buf.readLong()); } } diff --git a/src/main/java/org/traccar/protocol/RoboTrackFrameDecoder.java b/src/main/java/org/traccar/protocol/RoboTrackFrameDecoder.java index 85ed6c76f..237519a23 100644 --- a/src/main/java/org/traccar/protocol/RoboTrackFrameDecoder.java +++ b/src/main/java/org/traccar/protocol/RoboTrackFrameDecoder.java @@ -23,22 +23,15 @@ import org.traccar.BaseFrameDecoder; public class RoboTrackFrameDecoder extends BaseFrameDecoder { private int messageLength(ByteBuf buf) { - switch (buf.getUnsignedByte(buf.readerIndex())) { - case RoboTrackProtocolDecoder.MSG_ID: - return 69; - case RoboTrackProtocolDecoder.MSG_ACK: - return 3; - case RoboTrackProtocolDecoder.MSG_GPS: - case RoboTrackProtocolDecoder.MSG_GSM: - case RoboTrackProtocolDecoder.MSG_IMAGE_START: - return 24; - case RoboTrackProtocolDecoder.MSG_IMAGE_DATA: - return 8 + buf.getUnsignedShortLE(buf.readerIndex() + 1); - case RoboTrackProtocolDecoder.MSG_IMAGE_END: - return 6; - default: - return Integer.MAX_VALUE; - } + return switch (buf.getUnsignedByte(buf.readerIndex())) { + case RoboTrackProtocolDecoder.MSG_ID -> 69; + case RoboTrackProtocolDecoder.MSG_ACK -> 3; + case RoboTrackProtocolDecoder.MSG_GPS, RoboTrackProtocolDecoder.MSG_GSM, + RoboTrackProtocolDecoder.MSG_IMAGE_START -> 24; + case RoboTrackProtocolDecoder.MSG_IMAGE_DATA -> 8 + buf.getUnsignedShortLE(buf.readerIndex() + 1); + case RoboTrackProtocolDecoder.MSG_IMAGE_END -> 6; + default -> Integer.MAX_VALUE; + }; } @Override diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java index e1efb5757..057c593d3 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -64,34 +64,28 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_TYPE, type); - switch (type) { - case MSG_DEVICE_CONFIGURATION: - case MSG_DEVICE_VERSION: - case MSG_FIRMWARE_UPDATE: - case MSG_SMS_VIA_GPRS_RESPONSE: + return switch (type) { + case MSG_DEVICE_CONFIGURATION, MSG_DEVICE_VERSION, MSG_FIRMWARE_UPDATE, MSG_SMS_VIA_GPRS_RESPONSE -> { position.set(Position.KEY_RESULT, buf.toString(buf.readerIndex(), buf.readableBytes() - 2, StandardCharsets.US_ASCII).trim()); - return position; - case MSG_SET_IO: + yield position; + } + case MSG_SET_IO -> { position.set(Position.KEY_RESULT, String.valueOf(buf.readUnsignedByte())); - return position; - default: - return null; - } + yield position; + } + default -> null; + }; } private long readValue(ByteBuf buf, int length, boolean signed) { - switch (length) { - case 1: - return signed ? buf.readByte() : buf.readUnsignedByte(); - case 2: - return signed ? buf.readShort() : buf.readUnsignedShort(); - case 4: - return signed ? buf.readInt() : buf.readUnsignedInt(); - default: - return buf.readLong(); - } + return switch (length) { + case 1 -> signed ? buf.readByte() : buf.readUnsignedByte(); + case 2 -> signed ? buf.readShort() : buf.readUnsignedShort(); + case 4 -> signed ? buf.readInt() : buf.readUnsignedInt(); + default -> buf.readLong(); + }; } private void decodeDriver(Position position, String part1, String part2) { @@ -106,136 +100,70 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { private void decodeParameter(Position position, int id, ByteBuf buf, int length) { switch (id) { - case 2: - case 3: - case 4: - case 5: - position.set(Position.PREFIX_IN + (id - 1), readValue(buf, length, false)); - break; - case 13: - case 173: - position.set(Position.KEY_MOTION, readValue(buf, length, false) > 0); - break; - case 20: - position.set(Position.PREFIX_ADC + 3, readValue(buf, length, false)); - break; - case 21: - position.set(Position.PREFIX_ADC + 4, readValue(buf, length, false)); - break; - case 22: - position.set(Position.PREFIX_ADC + 1, readValue(buf, length, false)); - break; - case 23: - position.set(Position.PREFIX_ADC + 2, readValue(buf, length, false)); - break; - case 29: - position.set(Position.KEY_POWER, readValue(buf, length, false) * 0.001); - break; - case 30: - position.set(Position.KEY_BATTERY, readValue(buf, length, false) * 0.001); - break; - case 32: - position.set(Position.KEY_DEVICE_TEMP, readValue(buf, length, true)); - break; - case 39: - position.set(Position.KEY_ENGINE_LOAD, readValue(buf, length, false)); - break; - case 65: - position.set(Position.KEY_ODOMETER, readValue(buf, length, false)); - break; - case 74: - position.set(Position.PREFIX_TEMP + 3, readValue(buf, length, true) * 0.1); - break; - case 78: - case 79: - case 80: - position.set(Position.PREFIX_TEMP + (id - 78), readValue(buf, length, true) * 0.1); - break; - case 88: + case 2, 3, 4, 5 -> position.set(Position.PREFIX_IN + (id - 1), readValue(buf, length, false)); + case 13, 173 -> position.set(Position.KEY_MOTION, readValue(buf, length, false) > 0); + case 20 -> position.set(Position.PREFIX_ADC + 3, readValue(buf, length, false)); + case 21 -> position.set(Position.PREFIX_ADC + 4, readValue(buf, length, false)); + case 22 -> position.set(Position.PREFIX_ADC + 1, readValue(buf, length, false)); + case 23 -> position.set(Position.PREFIX_ADC + 2, readValue(buf, length, false)); + case 29 -> position.set(Position.KEY_POWER, readValue(buf, length, false) * 0.001); + case 30 -> position.set(Position.KEY_BATTERY, readValue(buf, length, false) * 0.001); + case 32 -> position.set(Position.KEY_DEVICE_TEMP, readValue(buf, length, true)); + case 39 -> position.set(Position.KEY_ENGINE_LOAD, readValue(buf, length, false)); + case 65 -> position.set(Position.KEY_ODOMETER, readValue(buf, length, false)); + case 74 -> position.set(Position.PREFIX_TEMP + 3, readValue(buf, length, true) * 0.1); + case 78, 79, 80 -> position.set(Position.PREFIX_TEMP + (id - 78), readValue(buf, length, true) * 0.1); + case 88 -> { if (readValue(buf, length, false) > 0) { position.set(Position.KEY_ALARM, Position.ALARM_JAMMING); } - break; - case 94: - position.set(Position.KEY_RPM, readValue(buf, length, false) * 0.25); - break; - case 95: - position.set(Position.KEY_OBD_SPEED, readValue(buf, length, false)); - break; - case 98: - position.set(Position.KEY_FUEL_LEVEL, readValue(buf, length, false) * 100 / 255.0); - break; - case 100: - position.set(Position.KEY_FUEL_CONSUMPTION, readValue(buf, length, false) / 20.0); - break; - case 134: + } + case 94 -> position.set(Position.KEY_RPM, readValue(buf, length, false) * 0.25); + case 95 -> position.set(Position.KEY_OBD_SPEED, readValue(buf, length, false)); + case 98 -> position.set(Position.KEY_FUEL_LEVEL, readValue(buf, length, false) * 100 / 255.0); + case 100 -> position.set(Position.KEY_FUEL_CONSUMPTION, readValue(buf, length, false) / 20.0); + case 134 -> { if (readValue(buf, length, false) > 0) { position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); } - break; - case 136: + } + case 136 -> { if (readValue(buf, length, false) > 0) { position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); } - break; - case 150: - position.set(Position.KEY_OPERATOR, readValue(buf, length, false)); - break; - case 163: - position.set(Position.KEY_ODOMETER, readValue(buf, length, false) * 5); - break; - case 164: - position.set(Position.KEY_ODOMETER_TRIP, readValue(buf, length, false) * 5); - break; - case 165: - position.set(Position.KEY_OBD_SPEED, readValue(buf, length, false) / 256.0); - break; - case 166: - case 197: - position.set(Position.KEY_RPM, readValue(buf, length, false) * 0.125); - break; - case 170: - position.set(Position.KEY_CHARGE, readValue(buf, length, false) > 0); - break; - case 205: - position.set(Position.KEY_FUEL_LEVEL, readValue(buf, length, false)); - break; - case 207: - position.set(Position.KEY_FUEL_LEVEL, readValue(buf, length, false) * 0.4); - break; - case 208: - position.set(Position.KEY_FUEL_USED, readValue(buf, length, false) * 0.5); - break; - case 251: - case 409: - position.set(Position.KEY_IGNITION, readValue(buf, length, false) > 0); - break; - case 410: + } + case 150 -> position.set(Position.KEY_OPERATOR, readValue(buf, length, false)); + case 163 -> position.set(Position.KEY_ODOMETER, readValue(buf, length, false) * 5); + case 164 -> position.set(Position.KEY_ODOMETER_TRIP, readValue(buf, length, false) * 5); + case 165 -> position.set(Position.KEY_OBD_SPEED, readValue(buf, length, false) / 256.0); + case 166, 197 -> position.set(Position.KEY_RPM, readValue(buf, length, false) * 0.125); + case 170 -> position.set(Position.KEY_CHARGE, readValue(buf, length, false) > 0); + case 205 -> position.set(Position.KEY_FUEL_LEVEL, readValue(buf, length, false)); + case 207 -> position.set(Position.KEY_FUEL_LEVEL, readValue(buf, length, false) * 0.4); + case 208 -> position.set(Position.KEY_FUEL_USED, readValue(buf, length, false) * 0.5); + case 251, 409 -> position.set(Position.KEY_IGNITION, readValue(buf, length, false) > 0); + case 410 -> { if (readValue(buf, length, false) > 0) { position.set(Position.KEY_ALARM, Position.ALARM_TOW); } - break; - case 411: + } + case 411 -> { if (readValue(buf, length, false) > 0) { position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); } - break; - case 415: + } + case 415 -> { if (readValue(buf, length, false) == 0) { position.set(Position.KEY_ALARM, Position.ALARM_GPS_ANTENNA_CUT); } - break; - case 645: - position.set(Position.KEY_OBD_ODOMETER, readValue(buf, length, false) * 1000); - break; - case 758: + } + case 645 -> position.set(Position.KEY_OBD_ODOMETER, readValue(buf, length, false) * 1000); + case 758 -> { if (readValue(buf, length, false) == 1) { position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); } - break; - default: - position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); - break; + } + default -> position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); } } diff --git a/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java b/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java index 5ec971a98..79c572707 100644 --- a/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/RuptelaProtocolEncoder.java @@ -48,50 +48,57 @@ public class RuptelaProtocolEncoder extends BaseProtocolEncoder { ByteBuf content = Unpooled.buffer(); - switch (command.getType()) { - case Command.TYPE_CUSTOM: + return switch (command.getType()) { + case Command.TYPE_CUSTOM -> { String data = command.getString(Command.KEY_DATA); if (data.matches("(\\p{XDigit}{2})+")) { content.writeBytes(DataConverter.parseHex(data)); - return content; + yield content; } else { content.writeBytes(data.getBytes(StandardCharsets.US_ASCII)); - return encodeContent(RuptelaProtocolDecoder.MSG_SMS_VIA_GPRS, content); + yield encodeContent(RuptelaProtocolDecoder.MSG_SMS_VIA_GPRS, content); } - case Command.TYPE_ENGINE_STOP: + } + case Command.TYPE_ENGINE_STOP -> { content.writeBytes("pass immobilizer 10".getBytes(StandardCharsets.US_ASCII)); - return encodeContent(RuptelaProtocolDecoder.MSG_SMS_VIA_GPRS, content); - case Command.TYPE_ENGINE_RESUME: + yield encodeContent(RuptelaProtocolDecoder.MSG_SMS_VIA_GPRS, content); + } + case Command.TYPE_ENGINE_RESUME -> { content.writeBytes("pass resetimmob".getBytes(StandardCharsets.US_ASCII)); - return encodeContent(RuptelaProtocolDecoder.MSG_SMS_VIA_GPRS, content); - case Command.TYPE_REQUEST_PHOTO: + yield encodeContent(RuptelaProtocolDecoder.MSG_SMS_VIA_GPRS, content); + } + case Command.TYPE_REQUEST_PHOTO -> { content.writeByte(1); // sub-command content.writeByte(0); // source content.writeInt(0); // start timestamp content.writeInt(Integer.MAX_VALUE); // end timestamp - return encodeContent(RuptelaProtocolDecoder.MSG_FILES, content); - case Command.TYPE_CONFIGURATION: + yield encodeContent(RuptelaProtocolDecoder.MSG_FILES, content); + } + case Command.TYPE_CONFIGURATION -> { content.writeBytes((command.getString(Command.KEY_DATA) + "\r\n").getBytes(StandardCharsets.US_ASCII)); - return encodeContent(RuptelaProtocolDecoder.MSG_DEVICE_CONFIGURATION, content); - case Command.TYPE_GET_VERSION: - return encodeContent(RuptelaProtocolDecoder.MSG_DEVICE_VERSION, content); - case Command.TYPE_FIRMWARE_UPDATE: + yield encodeContent(RuptelaProtocolDecoder.MSG_DEVICE_CONFIGURATION, content); + } + case Command.TYPE_GET_VERSION -> encodeContent(RuptelaProtocolDecoder.MSG_DEVICE_VERSION, content); + case Command.TYPE_FIRMWARE_UPDATE -> { content.writeBytes("|FU_STRT*\r\n".getBytes(StandardCharsets.US_ASCII)); - return encodeContent(RuptelaProtocolDecoder.MSG_FIRMWARE_UPDATE, content); - case Command.TYPE_OUTPUT_CONTROL: + yield encodeContent(RuptelaProtocolDecoder.MSG_FIRMWARE_UPDATE, content); + } + case Command.TYPE_OUTPUT_CONTROL -> { content.writeInt(command.getInteger(Command.KEY_INDEX)); content.writeInt(command.getInteger(Command.KEY_DATA)); - return encodeContent(RuptelaProtocolDecoder.MSG_SET_IO, content); - case Command.TYPE_SET_CONNECTION: + yield encodeContent(RuptelaProtocolDecoder.MSG_SET_IO, content); + } + case Command.TYPE_SET_CONNECTION -> { String c = command.getString(Command.KEY_SERVER) + "," + command.getInteger(Command.KEY_PORT) + ",TCP"; content.writeBytes(c.getBytes(StandardCharsets.US_ASCII)); - return encodeContent(RuptelaProtocolDecoder.MSG_SET_CONNECTION, content); - case Command.TYPE_SET_ODOMETER: + yield encodeContent(RuptelaProtocolDecoder.MSG_SET_CONNECTION, content); + } + case Command.TYPE_SET_ODOMETER -> { content.writeInt(command.getInteger(Command.KEY_DATA)); - return encodeContent(RuptelaProtocolDecoder.MSG_SET_ODOMETER, content); - default: - return null; - } + yield encodeContent(RuptelaProtocolDecoder.MSG_SET_ODOMETER, content); + } + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java b/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java index e0dfab9b2..2be3f6489 100644 --- a/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SigfoxProtocolDecoder.java @@ -209,42 +209,28 @@ public class SigfoxProtocolDecoder extends BaseHttpProtocolDecoder { while (buf.isReadable()) { int type = buf.readUnsignedByte(); switch (type) { - case 0x01: + case 0x01 -> { position.setValid(true); position.setLatitude(buf.readMedium()); position.setLongitude(buf.readMedium()); - break; - case 0x02: + } + case 0x02 -> { position.setValid(true); position.setLatitude(buf.readFloat()); position.setLongitude(buf.readFloat()); - break; - case 0x03: - position.set(Position.PREFIX_TEMP + 1, buf.readByte() * 0.5); - break; - case 0x04: - position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 0.1); - break; - case 0x05: - position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); - break; - case 0x06: + } + case 0x03 -> position.set(Position.PREFIX_TEMP + 1, buf.readByte() * 0.5); + case 0x04 -> position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 0.1); + case 0x05 -> position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + case 0x06 -> { String mac = ByteBufUtil.hexDump(buf.readSlice(6)).replaceAll("(..)", "$1:"); position.setNetwork(new Network(WifiAccessPoint.from( mac.substring(0, mac.length() - 1), buf.readUnsignedByte()))); - break; - case 0x07: - buf.skipBytes(10); // wifi extended - break; - case 0x08: - buf.skipBytes(6); // accelerometer - break; - case 0x09: - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - break; - default: - buf.readUnsignedByte(); // fence number - break; + } + case 0x07 -> buf.skipBytes(10); // wifi extended + case 0x08 -> buf.skipBytes(6); // accelerometer + case 0x09 -> position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); + default -> buf.readUnsignedByte(); // fence number } } } finally { diff --git a/src/main/java/org/traccar/protocol/SnapperProtocolDecoder.java b/src/main/java/org/traccar/protocol/SnapperProtocolDecoder.java index ef1a4426a..1af4ec9eb 100644 --- a/src/main/java/org/traccar/protocol/SnapperProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SnapperProtocolDecoder.java @@ -93,19 +93,17 @@ public class SnapperProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // index int type = buf.readUnsignedByte(); switch (type) { - case 0x00: + case 0x00 -> { position.set(Position.KEY_POWER, buf.readUnsignedByte() * 0.1); position.set(Position.KEY_DEVICE_TEMP, buf.readByte()); position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - break; - case 0x01: + } + case 0x01 -> { position.set("interiorTemp", buf.readByte()); position.set("engineTemp", buf.readByte()); buf.readUnsignedByte(); // reserved - break; - default: - buf.skipBytes(3); - break; + } + default -> buf.skipBytes(3); } } } @@ -185,19 +183,22 @@ public class SnapperProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - switch (type) { - case MSG_SEND_EVENTS: + return switch (type) { + case MSG_SEND_EVENTS -> { decodeEvents(position, buf); getLastLocation(position, null); // TODO read timestamp - return position; - case MSG_SEND_TECH_INFO: + yield position; + } + case MSG_SEND_TECH_INFO -> { decodeTechInfo(position, buf); getLastLocation(position, null); - return position; - case MSG_SEND_GPS_DATA: + yield position; + } + case MSG_SEND_GPS_DATA -> { decodeGpsData(position, buf.readSlice(length)); - return position; - case MSG_SEND_CONCATENATED_PACKET: + yield position; + } + case MSG_SEND_CONCATENATED_PACKET -> { int count = buf.readUnsignedShortLE(); for (int i = 0; i < count; i++) { int partType = buf.readUnsignedShortLE(); @@ -220,10 +221,10 @@ public class SnapperProtocolDecoder extends BaseProtocolDecoder { if (position.getFixTime() == null) { getLastLocation(position, null); } - return position; - default: - return null; - } + yield position; + } + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java index 193005e28..33d1153cf 100644 --- a/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StarLinkProtocolDecoder.java @@ -97,26 +97,17 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { } private String decodeAlarm(int event) { - switch (event) { - case 6: - return Position.ALARM_OVERSPEED; - case 7: - return Position.ALARM_GEOFENCE_ENTER; - case 8: - return Position.ALARM_GEOFENCE_EXIT; - case 9: - return Position.ALARM_POWER_CUT; - case 11: - return Position.ALARM_LOW_BATTERY; - case 26: - return Position.ALARM_TOW; - case 36: - return Position.ALARM_SOS; - case 42: - return Position.ALARM_JAMMING; - default: - return null; - } + return switch (event) { + case 6 -> Position.ALARM_OVERSPEED; + case 7 -> Position.ALARM_GEOFENCE_ENTER; + case 8 -> Position.ALARM_GEOFENCE_EXIT; + case 9 -> Position.ALARM_POWER_CUT; + case 11 -> Position.ALARM_LOW_BATTERY; + case 26 -> Position.ALARM_TOW; + case 36 -> Position.ALARM_SOS; + case 42 -> Position.ALARM_JAMMING; + default -> null; + }; } @Override @@ -156,22 +147,11 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { continue; } switch (dataTags[i]) { - case "#ALT#": - case "#ALTD#": - position.setAltitude(Double.parseDouble(data[i])); - break; - case "#DAL#": - case "#DID#": - position.set(Position.KEY_DRIVER_UNIQUE_ID, data[i]); - break; - case "#EDT#": - position.setDeviceTime(dateFormat.parse(data[i])); - break; - case "#EDV1#": - case "#EDV2#": - position.set("external" + dataTags[i].charAt(4), data[i]); - break; - case "#EID#": + case "#ALT#", "#ALTD#" -> position.setAltitude(Double.parseDouble(data[i])); + case "#DAL#", "#DID#" -> position.set(Position.KEY_DRIVER_UNIQUE_ID, data[i]); + case "#EDT#" -> position.setDeviceTime(dateFormat.parse(data[i])); + case "#EDV1#", "#EDV2#" -> position.set("external" + dataTags[i].charAt(4), data[i]); + case "#EID#" -> { event = Integer.parseInt(data[i]); position.set(Position.KEY_ALARM, decodeAlarm(event)); position.set(Position.KEY_EVENT, event); @@ -180,137 +160,58 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { } else if (event == 25) { position.set(Position.KEY_IGNITION, false); } - break; - case "#EDSC#": - position.set("reason", data[i]); - break; - case "#IARM#": - position.set(Position.KEY_ARMED, Integer.parseInt(data[i]) > 0); - break; - case "#PDT#": - position.setFixTime(dateFormat.parse(data[i])); - break; - case "#LAT#": - position.setLatitude(parseCoordinate(data[i])); - break; - case "#LONG#": - position.setLongitude(parseCoordinate(data[i])); - break; - case "#SPD#": - position.setSpeed(Double.parseDouble(data[i])); - break; - case "#SPDK#": - position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(data[i]))); - break; - case "#HEAD#": - position.setCourse(Integer.parseInt(data[i])); - break; - case "#ODO#": - case "#ODOD#": - position.set(Position.KEY_ODOMETER, (long) (Double.parseDouble(data[i]) * 1000)); - break; - case "#BATC#": - position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(data[i])); - break; - case "#BATH#": - position.set("batteryHealth", Integer.parseInt(data[i])); - break; - case "#TVI#": - position.set(Position.KEY_DEVICE_TEMP, Double.parseDouble(data[i])); - break; - case "#CFL#": - position.set(Position.KEY_FUEL_LEVEL, Integer.parseInt(data[i])); - break; - case "#CFL2#": - position.set("fuel2", Integer.parseInt(data[i])); - break; - case "#IN1#": - case "#IN2#": - case "#IN3#": - case "#IN4#": - position.set(Position.PREFIX_IN + dataTags[i].charAt(3), Integer.parseInt(data[i])); - break; - case "#OUT1#": - case "#OUT2#": - case "#OUT3#": - case "#OUT4#": - position.set(Position.PREFIX_OUT + dataTags[i].charAt(4), Integer.parseInt(data[i])); - break; - case "#OUTA#": - case "#OUTB#": - case "#OUTC#": - case "#OUTD#": - position.set(Position.PREFIX_OUT + (dataTags[i].charAt(4) - 'A' + 1), Integer.parseInt(data[i])); - break; - case "#PDOP#": - position.set(Position.KEY_PDOP, Double.parseDouble(data[i])); - break; - case "#LAC#": + } + case "#EDSC#" -> position.set("reason", data[i]); + case "#IARM#" -> position.set(Position.KEY_ARMED, Integer.parseInt(data[i]) > 0); + case "#PDT#" -> position.setFixTime(dateFormat.parse(data[i])); + case "#LAT#" -> position.setLatitude(parseCoordinate(data[i])); + case "#LONG#" -> position.setLongitude(parseCoordinate(data[i])); + case "#SPD#" -> position.setSpeed(Double.parseDouble(data[i])); + case "#SPDK#" -> position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(data[i]))); + case "#HEAD#" -> position.setCourse(Integer.parseInt(data[i])); + case "#ODO#", "#ODOD#" -> + position.set(Position.KEY_ODOMETER, (long) (Double.parseDouble(data[i]) * 1000)); + case "#BATC#" -> position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(data[i])); + case "#BATH#" -> position.set("batteryHealth", Integer.parseInt(data[i])); + case "#TVI#" -> position.set(Position.KEY_DEVICE_TEMP, Double.parseDouble(data[i])); + case "#CFL#" -> position.set(Position.KEY_FUEL_LEVEL, Integer.parseInt(data[i])); + case "#CFL2#" -> position.set("fuel2", Integer.parseInt(data[i])); + case "#IN1#", "#IN2#", "#IN3#", "#IN4#" -> position.set( + Position.PREFIX_IN + dataTags[i].charAt(3), Integer.parseInt(data[i])); + case "#OUT1#", "#OUT2#", "#OUT3#", "#OUT4#" -> position.set( + Position.PREFIX_OUT + dataTags[i].charAt(4), Integer.parseInt(data[i])); + case "#OUTA#", "#OUTB#", "#OUTC#", "#OUTD#" -> position.set( + Position.PREFIX_OUT + (dataTags[i].charAt(4) - 'A' + 1), Integer.parseInt(data[i])); + case "#PDOP#" -> position.set(Position.KEY_PDOP, Double.parseDouble(data[i])); + case "#LAC#" -> { if (!data[i].isEmpty()) { lac = Integer.parseInt(data[i]); } - break; - case "#CID#": + } + case "#CID#" -> { if (!data[i].isEmpty()) { cid = Integer.parseInt(data[i]); } - break; - case "#CSS#": - position.set(Position.KEY_RSSI, Integer.parseInt(data[i])); - break; - case "#VIN#": - position.set(Position.KEY_POWER, Double.parseDouble(data[i])); - break; - case "#VBAT#": - position.set(Position.KEY_BATTERY, Double.parseDouble(data[i])); - break; - case "#DEST#": - position.set("destination", data[i]); - break; - case "#IGN#": - case "#IGNL#": - case "#ENG#": - position.set(Position.KEY_IGNITION, Integer.parseInt(data[i]) > 0); - break; - case "#DUR#": - case "#TDUR#": - position.set(Position.KEY_HOURS, Integer.parseInt(data[i])); - break; - case "#SAT#": - case "#SATN#": - position.set(Position.KEY_SATELLITES_VISIBLE, Integer.parseInt(data[i])); - break; - case "#SATU#": - position.set(Position.KEY_SATELLITES, Integer.parseInt(data[i])); - break; - case "#STRT#": - position.set("starter", Double.parseDouble(data[i])); - break; - case "#TS1#": - position.set("sensor1State", Integer.parseInt(data[i])); - break; - case "#TS2#": - position.set("sensor2State", Integer.parseInt(data[i])); - break; - case "#TD1#": - case "#TD2#": + } + case "#CSS#" -> position.set(Position.KEY_RSSI, Integer.parseInt(data[i])); + case "#VIN#" -> position.set(Position.KEY_POWER, Double.parseDouble(data[i])); + case "#VBAT#" -> position.set(Position.KEY_BATTERY, Double.parseDouble(data[i])); + case "#DEST#" -> position.set("destination", data[i]); + case "#IGN#", "#IGNL#", "#ENG#" -> position.set(Position.KEY_IGNITION, Integer.parseInt(data[i]) > 0); + case "#DUR#", "#TDUR#" -> position.set(Position.KEY_HOURS, Integer.parseInt(data[i])); + case "#SAT#", "#SATN#" -> position.set(Position.KEY_SATELLITES_VISIBLE, Integer.parseInt(data[i])); + case "#SATU#" -> position.set(Position.KEY_SATELLITES, Integer.parseInt(data[i])); + case "#STRT#" -> position.set("starter", Double.parseDouble(data[i])); + case "#TS1#" -> position.set("sensor1State", Integer.parseInt(data[i])); + case "#TS2#" -> position.set("sensor2State", Integer.parseInt(data[i])); + case "#TD1#", "#TD2#" -> { StarLinkMessage.mEventReport_TDx message = StarLinkMessage.mEventReport_TDx.parseFrom(DataConverter.parseBase64(data[i])); - position.set( - "sensor" + message.getSensorNumber() + "Id", - message.getSensorID()); - position.set( - "sensor" + message.getSensorNumber() + "Temp", - message.getTemperature() * 0.1); - position.set( - "sensor" + message.getSensorNumber() + "Humidity", - message.getTemperature() * 0.1); - position.set( - "sensor" + message.getSensorNumber() + "Voltage", - message.getVoltage() * 0.001); - break; - default: - break; + position.set("sensor" + message.getSensorNumber() + "Id", message.getSensorID()); + position.set("sensor" + message.getSensorNumber() + "Temp", message.getTemperature() * 0.1); + position.set("sensor" + message.getSensorNumber() + "Humidity", message.getTemperature() * 0.1); + position.set("sensor" + message.getSensorNumber() + "Voltage", message.getVoltage() * 0.001); + } } } diff --git a/src/main/java/org/traccar/protocol/StarcomProtocolDecoder.java b/src/main/java/org/traccar/protocol/StarcomProtocolDecoder.java index 325847b16..8efa23fa3 100644 --- a/src/main/java/org/traccar/protocol/StarcomProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StarcomProtocolDecoder.java @@ -45,74 +45,32 @@ public class StarcomProtocolDecoder extends BaseProtocolDecoder { String key = entry.substring(0, delimiter); String value = entry.substring(delimiter + 1); switch (key) { - case "unit": + case "unit" -> { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, value); if (deviceSession != null) { position.setDeviceId(deviceSession.getDeviceId()); } - break; - case "gps_valid": - position.setValid(Integer.parseInt(value) != 0); - break; - case "datetime_actual": - position.setTime(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse(value)); - break; - case "latitude": - position.setLatitude(Double.parseDouble(value)); - break; - case "longitude": - position.setLongitude(Double.parseDouble(value)); - break; - case "altitude": - position.setAltitude(Double.parseDouble(value)); - break; - case "velocity": - position.setSpeed(UnitsConverter.knotsFromKph(Integer.parseInt(value))); - break; - case "heading": - position.setCourse(Integer.parseInt(value)); - break; - case "eventid": - position.set(Position.KEY_EVENT, Integer.parseInt(value)); - break; - case "odometer": - position.set(Position.KEY_ODOMETER, (long) (Double.parseDouble(value) * 1000)); - break; - case "satellites": - position.set(Position.KEY_SATELLITES, Integer.parseInt(value)); - break; - case "ignition": - position.set(Position.KEY_IGNITION, Integer.parseInt(value) != 0); - break; - case "door": - position.set(Position.KEY_DOOR, Integer.parseInt(value) != 0); - break; - case "arm": - position.set(Position.KEY_ARMED, Integer.parseInt(value) != 0); - break; - case "fuel": - position.set(Position.KEY_FUEL_LEVEL, Integer.parseInt(value)); - break; - case "rpm": - position.set(Position.KEY_RPM, Integer.parseInt(value)); - break; - case "main_voltage": - position.set(Position.KEY_POWER, Double.parseDouble(value)); - break; - case "backup_voltage": - position.set(Position.KEY_BATTERY, Double.parseDouble(value)); - break; - case "analog1": - case "analog2": - case "analog3": - position.set(Position.PREFIX_ADC + (key.charAt(key.length() - 1) - '0'), Double.parseDouble(value)); - break; - case "extra1": - case "extra2": - case "extra3": - default: - position.set(key, value); - break; + } + case "gps_valid" -> position.setValid(Integer.parseInt(value) != 0); + case "datetime_actual" -> position.setTime(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse(value)); + case "latitude" -> position.setLatitude(Double.parseDouble(value)); + case "longitude" -> position.setLongitude(Double.parseDouble(value)); + case "altitude" -> position.setAltitude(Double.parseDouble(value)); + case "velocity" -> position.setSpeed(UnitsConverter.knotsFromKph(Integer.parseInt(value))); + case "heading" -> position.setCourse(Integer.parseInt(value)); + case "eventid" -> position.set(Position.KEY_EVENT, Integer.parseInt(value)); + case "odometer" -> position.set(Position.KEY_ODOMETER, (long) (Double.parseDouble(value) * 1000)); + case "satellites" -> position.set(Position.KEY_SATELLITES, Integer.parseInt(value)); + case "ignition" -> position.set(Position.KEY_IGNITION, Integer.parseInt(value) != 0); + case "door" -> position.set(Position.KEY_DOOR, Integer.parseInt(value) != 0); + case "arm" -> position.set(Position.KEY_ARMED, Integer.parseInt(value) != 0); + case "fuel" -> position.set(Position.KEY_FUEL_LEVEL, Integer.parseInt(value)); + case "rpm" -> position.set(Position.KEY_RPM, Integer.parseInt(value)); + case "main_voltage" -> position.set(Position.KEY_POWER, Double.parseDouble(value)); + case "backup_voltage" -> position.set(Position.KEY_BATTERY, Double.parseDouble(value)); + case "analog1", "analog2", "analog3" -> position.set( + Position.PREFIX_ADC + (key.charAt(key.length() - 1) - '0'), Double.parseDouble(value)); + default -> position.set(key, value); } } diff --git a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java index 0eeb5b2aa..4b7e2cfad 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StartekProtocolDecoder.java @@ -98,27 +98,17 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { .compile(); private String decodeAlarm(int value) { - switch (value) { - case 1: - return Position.ALARM_SOS; - case 5: - case 6: - return Position.ALARM_DOOR; - case 17: - return Position.ALARM_LOW_POWER; - case 18: - return Position.ALARM_POWER_CUT; - case 19: - return Position.ALARM_POWER_RESTORED; - case 39: - return Position.ALARM_ACCELERATION; - case 40: - return Position.ALARM_BRAKING; - case 41: - return Position.ALARM_CORNERING; - default: - return null; - } + return switch (value) { + case 1 -> Position.ALARM_SOS; + case 5, 6 -> Position.ALARM_DOOR; + case 17 -> Position.ALARM_LOW_POWER; + case 18 -> Position.ALARM_POWER_CUT; + case 19 -> Position.ALARM_POWER_RESTORED; + case 39 -> Position.ALARM_ACCELERATION; + case 40 -> Position.ALARM_BRAKING; + case 41 -> Position.ALARM_CORNERING; + default -> null; + }; } @Override @@ -137,19 +127,18 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { String type = parser.next(); String content = parser.next(); - switch (type) { - case "000": - return decodePosition(deviceSession, content); - case "710": - return decodeSerial(deviceSession, content); - default: + return switch (type) { + case "000" -> decodePosition(deviceSession, content); + case "710" -> decodeSerial(deviceSession, content); + default -> { Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); position.set(Position.KEY_TYPE, type); position.set(Position.KEY_RESULT, content); - return position; - } + yield position; + } + }; } private Object decodePosition(DeviceSession deviceSession, String content) { @@ -268,7 +257,7 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { int index = 0; String type = values[index++]; switch (type) { - case "T1": + case "T1" -> { index += 1; // speed position.set(Position.KEY_RPM, Double.parseDouble(values[index++])); index += 1; // fuel consumption @@ -298,8 +287,8 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { index += 1; // brake pedal position.set("catalystLevel", Double.parseDouble(values[index++])); index += 1; // fuel type - break; - case "T2": + } + case "T2" -> { position.set(Position.KEY_ODOMETER, Double.parseDouble(values[index++]) * 1000); index += 1; // total fuel index += 1; // fuel used cruise @@ -322,9 +311,7 @@ public class StartekProtocolDecoder extends BaseProtocolDecoder { index += 1; // total cruise control distance position.set(Position.KEY_FUEL_USED, Double.parseDouble(values[index++])); index += 1; // total drive time - break; - default: - break; + } } } diff --git a/src/main/java/org/traccar/protocol/StartekProtocolEncoder.java b/src/main/java/org/traccar/protocol/StartekProtocolEncoder.java index 011a8dfae..f001b698f 100644 --- a/src/main/java/org/traccar/protocol/StartekProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/StartekProtocolEncoder.java @@ -39,18 +39,14 @@ public class StartekProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Channel channel, Command command) { - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return formatCommand(command, "%s", Command.KEY_DATA); - case Command.TYPE_OUTPUT_CONTROL: - return formatCommand(command, "900,%s,%s", Command.KEY_INDEX, Command.KEY_DATA); - case Command.TYPE_ENGINE_STOP: - return formatCommand(command, "900,1,1"); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "900,1,0"); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_CUSTOM -> formatCommand(command, "%s", Command.KEY_DATA); + case Command.TYPE_OUTPUT_CONTROL -> + formatCommand(command, "900,%s,%s", Command.KEY_INDEX, Command.KEY_DATA); + case Command.TYPE_ENGINE_STOP -> formatCommand(command, "900,1,1"); + case Command.TYPE_ENGINE_RESUME -> formatCommand(command, "900,1,0"); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/StbProtocolDecoder.java b/src/main/java/org/traccar/protocol/StbProtocolDecoder.java index c52ab485f..18f529712 100644 --- a/src/main/java/org/traccar/protocol/StbProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/StbProtocolDecoder.java @@ -75,36 +75,24 @@ public class StbProtocolDecoder extends BaseProtocolDecoder { JsonObject propertyObject = property.asJsonObject(); String id = propertyObject.getString("id"); switch (id) { - case "01101001": - locationType = Integer.parseInt(propertyObject.getString("value")); - break; - case "01102001": - position.setLongitude( - Double.parseDouble(propertyObject.getString("value"))); - break; - case "01103001": - position.setLatitude( - Double.parseDouble(propertyObject.getString("value"))); - break; - case "01118001": - position.set( - Position.KEY_DEVICE_TEMP, Double.parseDouble(propertyObject.getString("value"))); - break; - case "01122001": - position.set( - "batteryControl", Integer.parseInt(propertyObject.getString("value"))); - break; - case "02301001": - position.set( - "switchCabinetCommand", Integer.parseInt(propertyObject.getString("value"))); - break; - default: + case "01101001" -> locationType = Integer.parseInt(propertyObject.getString("value")); + case "01102001" -> position.setLongitude( + Double.parseDouble(propertyObject.getString("value"))); + case "01103001" -> position.setLatitude( + Double.parseDouble(propertyObject.getString("value"))); + case "01118001" -> position.set( + Position.KEY_DEVICE_TEMP, Double.parseDouble(propertyObject.getString("value"))); + case "01122001" -> position.set( + "batteryControl", Integer.parseInt(propertyObject.getString("value"))); + case "02301001" -> position.set( + "switchCabinetCommand", Integer.parseInt(propertyObject.getString("value"))); + default -> { String key = "id" + id; if (propertyObject.containsKey("doorId")) { key += "Door" + propertyObject.getString("doorId"); } position.set(key, propertyObject.getString("value")); - break; + } } } if (locationType > 0) { diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java index c9d6f16ef..8a440e765 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolDecoder.java @@ -167,56 +167,34 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } private String decodeEmergency(int value) { - switch (value) { - case 1: - return Position.ALARM_SOS; - case 2: - return Position.ALARM_PARKING; - case 3: - return Position.ALARM_POWER_CUT; - case 5: - case 6: - return Position.ALARM_DOOR; - case 7: - return Position.ALARM_MOVEMENT; - case 8: - return Position.ALARM_VIBRATION; - default: - return null; - } + return switch (value) { + case 1 -> Position.ALARM_SOS; + case 2 -> Position.ALARM_PARKING; + case 3 -> Position.ALARM_POWER_CUT; + case 5, 6 -> Position.ALARM_DOOR; + case 7 -> Position.ALARM_MOVEMENT; + case 8 -> Position.ALARM_VIBRATION; + default -> null; + }; } private String decodeAlert(int value) { - switch (value) { - case 1: - return Position.ALARM_OVERSPEED; - case 5: - return Position.ALARM_GEOFENCE_EXIT; - case 6: - return Position.ALARM_GEOFENCE_ENTER; - case 14: - return Position.ALARM_LOW_BATTERY; - case 15: - return Position.ALARM_VIBRATION; - case 16: - return Position.ALARM_ACCIDENT; - case 40: - return Position.ALARM_POWER_RESTORED; - case 41: - return Position.ALARM_POWER_CUT; - case 42: - return Position.ALARM_SOS; - case 46: - return Position.ALARM_ACCELERATION; - case 47: - return Position.ALARM_BRAKING; - case 50: - return Position.ALARM_JAMMING; - case 132: - return Position.ALARM_DOOR; - default: - return null; - } + return switch (value) { + case 1 -> Position.ALARM_OVERSPEED; + case 5 -> Position.ALARM_GEOFENCE_EXIT; + case 6 -> Position.ALARM_GEOFENCE_ENTER; + case 14 -> Position.ALARM_LOW_BATTERY; + case 15 -> Position.ALARM_VIBRATION; + case 16 -> Position.ALARM_ACCIDENT; + case 40 -> Position.ALARM_POWER_RESTORED; + case 41 -> Position.ALARM_POWER_CUT; + case 42 -> Position.ALARM_SOS; + case 46 -> Position.ALARM_ACCELERATION; + case 47 -> Position.ALARM_BRAKING; + case 50 -> Position.ALARM_JAMMING; + case 132 -> Position.ALARM_DOOR; + default -> null; + }; } private Position decode4( Channel channel, SocketAddress remoteAddress, String[] values) throws ParseException { @@ -323,19 +301,13 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { value = value.substring(0, value.indexOf('.')); } switch (pair[0].charAt(0)) { - case 't': - position.set(Position.PREFIX_TEMP + pair[0].charAt(2), Integer.parseInt(value, 16)); - break; - case 'N': + case 't' -> position.set(Position.PREFIX_TEMP + pair[0].charAt(2), Integer.parseInt(value, 16)); + case 'N' -> { int fuel = Integer.parseInt(value, 16); totalFuel += fuel; position.set("fuel" + pair[0].charAt(2), fuel); - break; - case 'Q': - position.set("drivingQuality", Integer.parseInt(value, 16)); - break; - default: - break; + } + case 'Q' -> position.set("drivingQuality", Integer.parseInt(value, 16)); } } } else { @@ -411,24 +383,14 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } switch (type) { - case "STT": + case "STT" -> { position.set(Position.KEY_STATUS, Integer.parseInt(values[index++])); position.set(Position.KEY_INDEX, Integer.parseInt(values[index++])); - break; - case "EMG": - position.set(Position.KEY_ALARM, decodeEmergency(Integer.parseInt(values[index++]))); - break; - case "EVT": - position.set(Position.KEY_EVENT, Integer.parseInt(values[index++])); - break; - case "ALT": - position.set(Position.KEY_ALARM, decodeAlert(Integer.parseInt(values[index++]))); - break; - case "UEX": - index = decodeSerialData(position, values, index); - break; - default: - break; + } + case "EMG" -> position.set(Position.KEY_ALARM, decodeEmergency(Integer.parseInt(values[index++]))); + case "EVT" -> position.set(Position.KEY_EVENT, Integer.parseInt(values[index++])); + case "ALT" -> position.set(Position.KEY_ALARM, decodeAlert(Integer.parseInt(values[index++]))); + case "UEX" -> index = decodeSerialData(position, values, index); } if (isHbm(deviceSession.getDeviceId())) { @@ -608,7 +570,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } switch (type) { - case "ALT": + case "ALT" -> { if (BitUtil.check(mask, 19)) { int alertId = Integer.parseInt(values[index++]); position.set(Position.KEY_ALARM, decodeAlert(alertId)); @@ -619,11 +581,9 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(mask, 21)) { position.set("alertData", values[index++]); } - break; - case "UEX": - index = decodeSerialData(position, values, index); - break; - default: + } + case "UEX" -> index = decodeSerialData(position, values, index); + default -> { if (BitUtil.check(mask, 19)) { position.set("mode", Integer.parseInt(values[index++])); } @@ -633,7 +593,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(mask, 21)) { position.set(Position.KEY_INDEX, Integer.parseInt(values[index++])); } - break; + } } if (BitUtil.check(mask, 22)) { diff --git a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java index a4faacf13..a6a05707e 100644 --- a/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/SuntechProtocolEncoder.java @@ -52,73 +52,59 @@ public class SuntechProtocolEncoder extends StringProtocolEncoder { } protected Object encodeUniversalCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_REBOOT_DEVICE: - return formatCommand(command, "CMD;%s;03;03\r", Command.KEY_UNIQUE_ID); - case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, "CMD;%s;03;01\r", Command.KEY_UNIQUE_ID); - case Command.TYPE_OUTPUT_CONTROL: + return switch (command.getType()) { + case Command.TYPE_REBOOT_DEVICE -> formatCommand(command, "CMD;%s;03;03\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_POSITION_SINGLE -> formatCommand(command, "CMD;%s;03;01\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_OUTPUT_CONTROL -> { if (command.getAttributes().get(Command.KEY_DATA).equals("1")) { - switch (command.getInteger(Command.KEY_INDEX)) { - case 1: - return formatCommand(command, "CMD;%s;04;01\r", Command.KEY_UNIQUE_ID); - case 2: - return formatCommand(command, "CMD;%s;04;03\r", Command.KEY_UNIQUE_ID); - case 3: - return formatCommand(command, "CMD;%s;04;09\r", Command.KEY_UNIQUE_ID); - default: - return null; - } + yield switch (command.getInteger(Command.KEY_INDEX)) { + case 1 -> formatCommand(command, "CMD;%s;04;01\r", Command.KEY_UNIQUE_ID); + case 2 -> formatCommand(command, "CMD;%s;04;03\r", Command.KEY_UNIQUE_ID); + case 3 -> formatCommand(command, "CMD;%s;04;09\r", Command.KEY_UNIQUE_ID); + default -> null; + }; } else { - switch (command.getInteger(Command.KEY_INDEX)) { - case 1: - return formatCommand(command, "CMD;%s;04;02\r", Command.KEY_UNIQUE_ID); - case 2: - return formatCommand(command, "CMD;%s;04;04\r", Command.KEY_UNIQUE_ID); - case 3: - return formatCommand(command, "CMD;%s;04;10\r", Command.KEY_UNIQUE_ID); - default: - return null; - } + yield switch (command.getInteger(Command.KEY_INDEX)) { + case 1 -> formatCommand(command, "CMD;%s;04;02\r", Command.KEY_UNIQUE_ID); + case 2 -> formatCommand(command, "CMD;%s;04;04\r", Command.KEY_UNIQUE_ID); + case 3 -> formatCommand(command, "CMD;%s;04;10\r", Command.KEY_UNIQUE_ID); + default -> null; + }; } - case Command.TYPE_ENGINE_STOP: - return formatCommand(command, "CMD;%s;04;01\r", Command.KEY_UNIQUE_ID); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "CMD;%s;04;02\r", Command.KEY_UNIQUE_ID); - case Command.TYPE_ALARM_ARM: - return formatCommand(command, "CMD;%s;04;03\r", Command.KEY_UNIQUE_ID); - case Command.TYPE_ALARM_DISARM: - return formatCommand(command, "CMD;%s;04;04\r", Command.KEY_UNIQUE_ID); - default: - return null; - } + } + case Command.TYPE_ENGINE_STOP -> formatCommand(command, "CMD;%s;04;01\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_ENGINE_RESUME -> formatCommand(command, "CMD;%s;04;02\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_ALARM_ARM -> formatCommand(command, "CMD;%s;04;03\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_ALARM_DISARM -> formatCommand(command, "CMD;%s;04;04\r", Command.KEY_UNIQUE_ID); + default -> null; + }; } protected Object encodeLegacyCommand(String prefix, Command command) { - switch (command.getType()) { - case Command.TYPE_REBOOT_DEVICE: - return formatCommand(command, prefix + "CMD;%s;02;Reboot\r", Command.KEY_UNIQUE_ID); - case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, prefix + "CMD;%s;02;StatusReq\r", Command.KEY_UNIQUE_ID); - case Command.TYPE_OUTPUT_CONTROL: + return switch (command.getType()) { + case Command.TYPE_REBOOT_DEVICE -> + formatCommand(command, prefix + "CMD;%s;02;Reboot\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_POSITION_SINGLE -> + formatCommand(command, prefix + "CMD;%s;02;StatusReq\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_OUTPUT_CONTROL -> { if (command.getAttributes().get(Command.KEY_DATA).equals("1")) { - return formatCommand(command, prefix + "CMD;%s;02;Enable%s\r", + yield formatCommand(command, prefix + "CMD;%s;02;Enable%s\r", Command.KEY_UNIQUE_ID, Command.KEY_INDEX); } else { - return formatCommand(command, prefix + "CMD;%s;02;Disable%s\r", + yield formatCommand(command, prefix + "CMD;%s;02;Disable%s\r", Command.KEY_UNIQUE_ID, Command.KEY_INDEX); } - case Command.TYPE_ENGINE_STOP: - return formatCommand(command, prefix + "CMD;%s;02;Enable1\r", Command.KEY_UNIQUE_ID); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, prefix + "CMD;%s;02;Disable1\r", Command.KEY_UNIQUE_ID); - case Command.TYPE_ALARM_ARM: - return formatCommand(command, prefix + "CMD;%s;02;Enable2\r", Command.KEY_UNIQUE_ID); - case Command.TYPE_ALARM_DISARM: - return formatCommand(command, prefix + "CMD;%s;02;Disable2\r", Command.KEY_UNIQUE_ID); - default: - return null; - } + } + case Command.TYPE_ENGINE_STOP -> + formatCommand(command, prefix + "CMD;%s;02;Enable1\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_ENGINE_RESUME -> + formatCommand(command, prefix + "CMD;%s;02;Disable1\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_ALARM_ARM -> + formatCommand(command, prefix + "CMD;%s;02;Enable2\r", Command.KEY_UNIQUE_ID); + case Command.TYPE_ALARM_DISARM -> + formatCommand(command, prefix + "CMD;%s;02;Disable2\r", Command.KEY_UNIQUE_ID); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/SviasProtocolEncoder.java b/src/main/java/org/traccar/protocol/SviasProtocolEncoder.java index d218f63ce..b62c1b773 100644 --- a/src/main/java/org/traccar/protocol/SviasProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/SviasProtocolEncoder.java @@ -28,26 +28,17 @@ public class SviasProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return formatCommand(command, "%s", Command.KEY_DATA); - case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, "AT+STR=1*"); - case Command.TYPE_SET_ODOMETER: - return formatCommand(command, "AT+ODT=%s*", Command.KEY_DATA); - case Command.TYPE_ENGINE_STOP: - return formatCommand(command, "AT+OUT=1,1*"); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "AT+OUT=1,0*"); - case Command.TYPE_ALARM_ARM: - return formatCommand(command, "AT+OUT=2,1*"); - case Command.TYPE_ALARM_DISARM: - return formatCommand(command, "AT+OUT=2,0*"); - case Command.TYPE_ALARM_REMOVE: - return formatCommand(command, "AT+PNC=600*"); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_CUSTOM -> formatCommand(command, "%s", Command.KEY_DATA); + case Command.TYPE_POSITION_SINGLE -> formatCommand(command, "AT+STR=1*"); + case Command.TYPE_SET_ODOMETER -> formatCommand(command, "AT+ODT=%s*", Command.KEY_DATA); + case Command.TYPE_ENGINE_STOP -> formatCommand(command, "AT+OUT=1,1*"); + case Command.TYPE_ENGINE_RESUME -> formatCommand(command, "AT+OUT=1,0*"); + case Command.TYPE_ALARM_ARM -> formatCommand(command, "AT+OUT=2,1*"); + case Command.TYPE_ALARM_DISARM -> formatCommand(command, "AT+OUT=2,0*"); + case Command.TYPE_ALARM_REMOVE -> formatCommand(command, "AT+PNC=600*"); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java index 9e7518ce5..2538c914d 100644 --- a/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T55ProtocolDecoder.java @@ -420,9 +420,8 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { sentence = sentence.substring(index); } else { deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null && remoteAddress instanceof InetSocketAddress) { - String host = ((InetSocketAddress) remoteAddress).getHostString(); - deviceSession = getDeviceSession(channel, remoteAddress, host); + if (deviceSession == null && remoteAddress instanceof InetSocketAddress inetSocketAddress) { + deviceSession = getDeviceSession(channel, remoteAddress, inetSocketAddress.getHostString()); } } diff --git a/src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java b/src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java index 9e64ec9be..c58960ab5 100644 --- a/src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T622IridiumProtocolDecoder.java @@ -84,62 +84,24 @@ public class T622IridiumProtocolDecoder extends BaseProtocolDecoder { for (int parameter : parameters) { switch (parameter) { - case 0x01: - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); - break; - case 0x02: - position.setLatitude(buf.readIntLE() / 1000000.0); - break; - case 0x03: - position.setLongitude(buf.readIntLE() / 1000000.0); - break; - case 0x04: - position.setTime(new Date((buf.readUnsignedIntLE() + 946684800) * 1000)); - break; - case 0x05: - position.setValid(buf.readUnsignedByte() > 0); - break; - case 0x06: - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - break; - case 0x07: - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - break; - case 0x08: - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); - break; - case 0x09: - position.setCourse(buf.readUnsignedShortLE()); - break; - case 0x0A: - position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); - break; - case 0x0B: - position.setAltitude(buf.readShortLE()); - break; - case 0x0C: - position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); - break; - case 0x0D: - position.set(Position.KEY_HOURS, buf.readUnsignedIntLE() * 1000); - break; - case 0x14: - position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); - break; - case 0x15: - position.set(Position.KEY_INPUT, buf.readUnsignedByte()); - break; - case 0x19: - position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.01); - break; - case 0x1A: - position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.01); - break; - case 0x1B: - buf.readUnsignedByte(); // geofence - break; - default: - break; + case 0x01 -> position.set(Position.KEY_EVENT, buf.readUnsignedByte()); + case 0x02 -> position.setLatitude(buf.readIntLE() / 1000000.0); + case 0x03 -> position.setLongitude(buf.readIntLE() / 1000000.0); + case 0x04 -> position.setTime(new Date((buf.readUnsignedIntLE() + 946684800) * 1000)); + case 0x05 -> position.setValid(buf.readUnsignedByte() > 0); + case 0x06 -> position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + case 0x07 -> position.set(Position.KEY_RSSI, buf.readUnsignedByte()); + case 0x08 -> position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); + case 0x09 -> position.setCourse(buf.readUnsignedShortLE()); + case 0x0A -> position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); + case 0x0B -> position.setAltitude(buf.readShortLE()); + case 0x0C -> position.set(Position.KEY_ODOMETER, buf.readUnsignedIntLE()); + case 0x0D -> position.set(Position.KEY_HOURS, buf.readUnsignedIntLE() * 1000); + case 0x14 -> position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); + case 0x15 -> position.set(Position.KEY_INPUT, buf.readUnsignedByte()); + case 0x19 -> position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.01); + case 0x1A -> position.set(Position.KEY_POWER, buf.readUnsignedShortLE() * 0.01); + case 0x1B -> buf.readUnsignedByte(); // geofence } } diff --git a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java index 23750be8d..d5be0416d 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolDecoder.java @@ -81,55 +81,33 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { } private String decodeAlarm1(int value) { - switch (value) { - case 1: - return Position.ALARM_POWER_CUT; - case 2: - return Position.ALARM_LOW_BATTERY; - case 3: - return Position.ALARM_SOS; - case 4: - return Position.ALARM_OVERSPEED; - case 5: - return Position.ALARM_GEOFENCE_ENTER; - case 6: - return Position.ALARM_GEOFENCE_EXIT; - case 7: - return Position.ALARM_TOW; - case 8: - case 10: - return Position.ALARM_VIBRATION; - case 21: - return Position.ALARM_JAMMING; - case 23: - return Position.ALARM_POWER_RESTORED; - case 24: - return Position.ALARM_LOW_POWER; - default: - return null; - } + return switch (value) { + case 1 -> Position.ALARM_POWER_CUT; + case 2 -> Position.ALARM_LOW_BATTERY; + case 3 -> Position.ALARM_SOS; + case 4 -> Position.ALARM_OVERSPEED; + case 5 -> Position.ALARM_GEOFENCE_ENTER; + case 6 -> Position.ALARM_GEOFENCE_EXIT; + case 7 -> Position.ALARM_TOW; + case 8, 10 -> Position.ALARM_VIBRATION; + case 21 -> Position.ALARM_JAMMING; + case 23 -> Position.ALARM_POWER_RESTORED; + case 24 -> Position.ALARM_LOW_POWER; + default -> null; + }; } private String decodeAlarm2(int value) { - switch (value) { - case 1: - case 4: - return Position.ALARM_REMOVING; - case 2: - return Position.ALARM_TAMPERING; - case 3: - return Position.ALARM_SOS; - case 5: - return Position.ALARM_FALL_DOWN; - case 6: - return Position.ALARM_LOW_BATTERY; - case 14: - return Position.ALARM_GEOFENCE_ENTER; - case 15: - return Position.ALARM_GEOFENCE_EXIT; - default: - return null; - } + return switch (value) { + case 1, 4 -> Position.ALARM_REMOVING; + case 2 -> Position.ALARM_TAMPERING; + case 3 -> Position.ALARM_SOS; + case 5 -> Position.ALARM_FALL_DOWN; + case 6 -> Position.ALARM_LOW_BATTERY; + case 14 -> Position.ALARM_GEOFENCE_ENTER; + case 15 -> Position.ALARM_GEOFENCE_EXIT; + default -> null; + }; } private Date readDate(ByteBuf buf) { @@ -195,24 +173,15 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); switch (buf.readUnsignedByte()) { - case 0: - case 4: - position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); - break; - case 1: - case 3: - case 5: - position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - break; - case 2: + case 0, 4 -> position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + case 1, 3, 5 -> position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + case 2 -> { if (type == MSG_DRIVER_BEHAVIOR_1) { position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); } else { position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); } - break; - default: - break; + } } position.setTime(readDate(buf)); @@ -275,14 +244,14 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { int i = 1; while (buf.isReadable()) { switch (buf.readUnsignedShort()) { - case 0x01: + case 0x01 -> { position.set("tag" + i + "Id", ByteBufUtil.hexDump(buf.readSlice(6))); position.set("tag" + i + "Battery", buf.readUnsignedByte() * 0.01 + 1.22); position.set("tag" + i + "TirePressure", buf.readUnsignedByte() * 1.527 * 2); position.set("tag" + i + "TireTemp", buf.readUnsignedByte() - 55); position.set("tag" + i + "TireStatus", buf.readUnsignedByte()); - break; - case 0x02: + } + case 0x02 -> { position.set("tag" + i + "Id", ByteBufUtil.hexDump(buf.readSlice(6))); position.set("tag" + i + "Battery", BcdUtil.readInteger(buf, 2) * 0.1); switch (buf.readUnsignedByte()) { @@ -297,8 +266,8 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { } buf.readUnsignedByte(); // status buf.skipBytes(16); // location - break; - case 0x03: + } + case 0x03 -> { position.set(Position.KEY_DRIVER_UNIQUE_ID, ByteBufUtil.hexDump(buf.readSlice(6))); position.set("tag" + i + "Battery", BcdUtil.readInteger(buf, 2) * 0.1); if (buf.readUnsignedByte() == 1) { @@ -306,8 +275,8 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { } buf.readUnsignedByte(); // status buf.skipBytes(16); // location - break; - case 0x04: + } + case 0x04 -> { position.set("tag" + i + "Id", ByteBufUtil.hexDump(buf.readSlice(6))); position.set("tag" + i + "Battery", buf.readUnsignedByte() * 0.01 + 2); buf.readUnsignedByte(); // battery level @@ -315,23 +284,21 @@ public class T800xProtocolDecoder extends BaseProtocolDecoder { position.set("tag" + i + "Humidity", buf.readUnsignedShort() * 0.01); position.set("tag" + i + "LightSensor", buf.readUnsignedShort()); position.set("tag" + i + "Rssi", buf.readUnsignedByte() - 128); - break; - case 0x05: + } + case 0x05 -> { position.set("tag" + i + "Id", ByteBufUtil.hexDump(buf.readSlice(6))); position.set("tag" + i + "Battery", buf.readUnsignedByte() * 0.01 + 2); buf.readUnsignedByte(); // battery level position.set("tag" + i + "Temp", decodeBleTemp(buf)); position.set("tag" + i + "Door", buf.readUnsignedByte() > 0); position.set("tag" + i + "Rssi", buf.readUnsignedByte() - 128); - break; - case 0x06: + } + case 0x06 -> { position.set("tag" + i + "Id", ByteBufUtil.hexDump(buf.readSlice(6))); position.set("tag" + i + "Battery", buf.readUnsignedByte() * 0.01 + 2); position.set("tag" + i + "Output", buf.readUnsignedByte() > 0); position.set("tag" + i + "Rssi", buf.readUnsignedByte() - 128); - break; - default: - break; + } } i += 1; } diff --git a/src/main/java/org/traccar/protocol/T800xProtocolEncoder.java b/src/main/java/org/traccar/protocol/T800xProtocolEncoder.java index 74587c8b1..2360484ee 100644 --- a/src/main/java/org/traccar/protocol/T800xProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/T800xProtocolEncoder.java @@ -58,12 +58,10 @@ public class T800xProtocolEncoder extends BaseProtocolEncoder { header = channel.pipeline().get(T800xProtocolDecoder.class).getHeader(); } - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return encodeContent(command, header, command.getString(Command.KEY_DATA)); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_CUSTOM -> encodeContent(command, header, command.getString(Command.KEY_DATA)); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java b/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java index 448d7ffca..bfa8b10c2 100644 --- a/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TaipProtocolDecoder.java @@ -122,30 +122,21 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { } private String decodeAlarm(int value) { - switch (value) { - case 0x01: - return Position.ALARM_SOS; - case 0x02: - return Position.ALARM_POWER_CUT; - default: - return null; - } + return switch (value) { + case 0x01 -> Position.ALARM_SOS; + case 0x02 -> Position.ALARM_POWER_CUT; + default -> null; + }; } private String decodeAlarm2(int value) { - switch (value) { - case 22: - return Position.ALARM_ACCELERATION; - case 23: - return Position.ALARM_BRAKING; - case 24: - return Position.ALARM_ACCIDENT; - case 26: - case 28: - return Position.ALARM_CORNERING; - default: - return null; - } + return switch (value) { + case 22 -> Position.ALARM_ACCELERATION; + case 23 -> Position.ALARM_BRAKING; + case 24 -> Position.ALARM_ACCIDENT; + case 26, 28 -> Position.ALARM_CORNERING; + default -> null; + }; } @Override @@ -273,7 +264,7 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { String key = attribute.substring(0, index).toLowerCase(); String value = attribute.substring(index + 1); switch (key) { - case "id": + case "id" -> { uniqueId = value; deviceSession = getDeviceSession(channel, remoteAddress, value); if (deviceSession != null) { @@ -282,31 +273,19 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { if (messageIndex == null) { indexFirst = false; } - break; - case "io": + } + case "io" -> { position.set(Position.KEY_IGNITION, BitUtil.check(value.charAt(0) - '0', 0)); position.set(Position.KEY_CHARGE, BitUtil.check(value.charAt(0) - '0', 1)); position.set(Position.KEY_OUTPUT, value.charAt(1) - '0'); position.set(Position.KEY_INPUT, value.charAt(2) - '0'); - break; - case "ix": - position.set(Position.PREFIX_IO + 1, value); - break; - case "ad": - position.set(Position.PREFIX_ADC + 1, Integer.parseInt(value)); - break; - case "sv": - position.set(Position.KEY_SATELLITES, Integer.parseInt(value)); - break; - case "bl": - position.set(Position.KEY_BATTERY, Integer.parseInt(value) * 0.001); - break; - case "vo": - position.set(Position.KEY_ODOMETER, Long.parseLong(value)); - break; - default: - position.set(key, value); - break; + } + case "ix" -> position.set(Position.PREFIX_IO + 1, value); + case "ad" -> position.set(Position.PREFIX_ADC + 1, Integer.parseInt(value)); + case "sv" -> position.set(Position.KEY_SATELLITES, Integer.parseInt(value)); + case "bl" -> position.set(Position.KEY_BATTERY, Integer.parseInt(value) * 0.001); + case "vo" -> position.set(Position.KEY_ODOMETER, Long.parseLong(value)); + default -> position.set(key, value); } } else if (attribute.startsWith("#")) { messageIndex = attribute; diff --git a/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java b/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java index 9681dc565..d7fbb1870 100644 --- a/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TelicProtocolDecoder.java @@ -58,25 +58,16 @@ public class TelicProtocolDecoder extends BaseProtocolDecoder { .compile(); private String decodeAlarm(int eventId) { - - switch (eventId) { - case 1: - return Position.ALARM_POWER_ON; - case 2: - return Position.ALARM_SOS; - case 5: - return Position.ALARM_POWER_OFF; - case 7: - return Position.ALARM_GEOFENCE_ENTER; - case 8: - return Position.ALARM_GEOFENCE_EXIT; - case 22: - return Position.ALARM_LOW_BATTERY; - case 25: - return Position.ALARM_MOVEMENT; - default: - return null; - } + return switch (eventId) { + case 1 -> Position.ALARM_POWER_ON; + case 2 -> Position.ALARM_SOS; + case 5 -> Position.ALARM_POWER_OFF; + case 7 -> Position.ALARM_GEOFENCE_ENTER; + case 8 -> Position.ALARM_GEOFENCE_EXIT; + case 22 -> Position.ALARM_LOW_BATTERY; + case 25 -> Position.ALARM_MOVEMENT; + default -> null; + }; } @Override diff --git a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java index de42031d7..93280c5aa 100644 --- a/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -179,16 +179,12 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } private long readValue(ByteBuf buf, int length) { - switch (length) { - case 1: - return buf.readUnsignedByte(); - case 2: - return buf.readUnsignedShort(); - case 4: - return buf.readUnsignedInt(); - default: - return buf.readLong(); - } + return switch (length) { + case 1 -> buf.readUnsignedByte(); + case 2 -> buf.readUnsignedShort(); + case 4 -> buf.readUnsignedInt(); + default -> buf.readLong(); + }; } private static void register(int id, Set<String> models, BiConsumer<Position, ByteBuf> handler) { @@ -200,7 +196,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { "FMB001", "FMB010", "FMB002", "FMB020", "FMB003", "FMB110", "FMB120", "FMB122", "FMB125", "FMB130", "FMB140", "FMU125", "FMB900", "FMB920", "FMB962", "FMB964", "FM3001", "FMB202", "FMB204", "FMB206", "FMT100", "MTB100", "FMP100", "MSP500", "FMC125", "FMM125", "FMU130", "FMC130", "FMM130", "FMB150", - "FMC150", "FMM150"); + "FMC150", "FMM150", "FMC920"); register(1, null, (p, b) -> p.set(Position.PREFIX_IN + 1, b.readUnsignedByte() > 0)); register(2, null, (p, b) -> p.set(Position.PREFIX_IN + 2, b.readUnsignedByte() > 0)); @@ -274,22 +270,17 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { register(249, fmbXXX, (p, b) -> { p.set(Position.KEY_ALARM, b.readUnsignedByte() > 0 ? Position.ALARM_JAMMING : null); }); + register(251, fmbXXX, (p, b) -> { + p.set(Position.KEY_ALARM, b.readUnsignedByte() > 0 ? Position.ALARM_IDLE : null); + }); register(252, fmbXXX, (p, b) -> { p.set(Position.KEY_ALARM, b.readUnsignedByte() > 0 ? Position.ALARM_POWER_CUT : null); }); register(253, null, (p, b) -> { switch (b.readUnsignedByte()) { - case 1: - p.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - break; - case 2: - p.set(Position.KEY_ALARM, Position.ALARM_BRAKING); - break; - case 3: - p.set(Position.KEY_ALARM, Position.ALARM_CORNERING); - break; - default: - break; + case 1 -> p.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + case 2 -> p.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + case 3 -> p.set(Position.KEY_ALARM, Position.ALARM_CORNERING); } }); register(636, fmbXXX, (p, b) -> p.set("cid4g", b.readUnsignedInt())); @@ -298,44 +289,22 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { private void decodeGh3000Parameter(Position position, int id, ByteBuf buf, int length) { switch (id) { - case 1: - position.set(Position.KEY_BATTERY_LEVEL, readValue(buf, length)); - break; - case 2: - position.set("usbConnected", readValue(buf, length) == 1); - break; - case 5: - position.set("uptime", readValue(buf, length)); - break; - case 20: - position.set(Position.KEY_HDOP, readValue(buf, length) * 0.1); - break; - case 21: - position.set(Position.KEY_VDOP, readValue(buf, length) * 0.1); - break; - case 22: - position.set(Position.KEY_PDOP, readValue(buf, length) * 0.1); - break; - case 67: - position.set(Position.KEY_BATTERY, readValue(buf, length) * 0.001); - break; - case 221: - position.set("button", readValue(buf, length)); - break; - case 222: + case 1 -> position.set(Position.KEY_BATTERY_LEVEL, readValue(buf, length)); + case 2 -> position.set("usbConnected", readValue(buf, length) == 1); + case 5 -> position.set("uptime", readValue(buf, length)); + case 20 -> position.set(Position.KEY_HDOP, readValue(buf, length) * 0.1); + case 21 -> position.set(Position.KEY_VDOP, readValue(buf, length) * 0.1); + case 22 -> position.set(Position.KEY_PDOP, readValue(buf, length) * 0.1); + case 67 -> position.set(Position.KEY_BATTERY, readValue(buf, length) * 0.001); + case 221 -> position.set("button", readValue(buf, length)); + case 222 -> { if (readValue(buf, length) == 1) { position.set(Position.KEY_ALARM, Position.ALARM_SOS); } - break; - case 240: - position.set(Position.KEY_MOTION, readValue(buf, length) == 1); - break; - case 244: - position.set(Position.KEY_ROAMING, readValue(buf, length) == 1); - break; - default: - position.set(Position.PREFIX_IO + id, readValue(buf, length)); - break; + } + case 240 -> position.set(Position.KEY_MOTION, readValue(buf, length) == 1); + case 244 -> position.set(Position.KEY_ROAMING, readValue(buf, length) == 1); + default -> position.set(Position.PREFIX_IO + id, readValue(buf, length)); } } @@ -599,26 +568,24 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { int parameterId = beacon.readUnsignedByte(); int parameterLength = beacon.readUnsignedByte(); switch (parameterId) { - case 0: - position.set("tag" + i + "Rssi", (int) beacon.readByte()); - break; - case 1: + case 0 -> position.set("tag" + i + "Rssi", (int) beacon.readByte()); + case 1 -> { String beaconId = ByteBufUtil.hexDump(beacon.readSlice(parameterLength)); position.set("tag" + i + "Id", beaconId); - break; - case 2: - String beaconData = ByteBufUtil.hexDump(beacon.readSlice(parameterLength)); - position.set("tag" + i + "Data", beaconData); - break; - case 13: - position.set("tag" + i + "LowBattery", beacon.readUnsignedByte()); - break; - case 14: - position.set("tag" + i + "Battery", beacon.readUnsignedShort()); - break; - default: - beacon.skipBytes(parameterLength); - break; + } + case 2 -> { + ByteBuf beaconData = beacon.readSlice(parameterLength); + int flag = beaconData.readUnsignedByte(); + if (BitUtil.check(flag, 6)) { + position.set("tag" + i + "LowBattery", true); + } + if (BitUtil.check(flag, 7)) { + position.set("tag" + i + "Voltage", beaconData.readUnsignedByte() * 10 + 2000); + } + } + case 13 -> position.set("tag" + i + "LowBattery", beacon.readUnsignedByte()); + case 14 -> position.set("tag" + i + "Battery", beacon.readUnsignedShort()); + default -> beacon.skipBytes(parameterLength); } } } diff --git a/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java b/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java index e7ab23e5b..c929621b5 100644 --- a/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ThinkPowerProtocolDecoder.java @@ -63,67 +63,43 @@ public class ThinkPowerProtocolDecoder extends BaseProtocolDecoder { private void decodeValue(Position position, int type, ByteBuf buf) { switch (type) { - case 0x01: + case 0x01 -> { position.setValid(true); position.setLatitude(BufferUtil.readSignedMagnitudeInt(buf) * 0.0000001); position.setLongitude(BufferUtil.readSignedMagnitudeInt(buf) * 0.0000001); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); position.setCourse(buf.readUnsignedShort() * 0.01); - break; - case 0x02: - position.setValid(buf.readUnsignedByte() > 0); - break; - case 0x03: - buf.skipBytes(3); // geofence - break; - case 0x06: - case 0x07: - case 0x08: - buf.skipBytes(2); // g-sensor x/y/z - break; - case 0x09: - buf.readUnsignedByte(); // collision alarm - break; - case 0x0A: - buf.readUnsignedByte(); // drop alarm - break; - case 0x10: + } + case 0x02 -> position.setValid(buf.readUnsignedByte() > 0); + case 0x03 -> buf.skipBytes(3); // geofence + case 0x06, 0x07, 0x08 -> buf.skipBytes(2); // g-sensor x/y/z + case 0x09 -> buf.readUnsignedByte(); // collision alarm + case 0x0A -> buf.readUnsignedByte(); // drop alarm + case 0x10 -> { if (buf.readUnsignedByte() > 0) { position.set(Position.KEY_ALARM, Position.ALARM_SOS); } - break; - case 0x12: - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.1); - break; - case 0x13: + } + case 0x12 -> position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.1); + case 0x13 -> { if (buf.readUnsignedByte() > 0) { position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); } - break; - case 0x16: - buf.readUnsignedShort(); // temperature - break; - case 0x17: - buf.readUnsignedByte(); // humidity - break; - case 0x18: - buf.readUnsignedShort(); // high temperature - break; - case 0x19: - buf.readUnsignedByte(); // high humidity - break; - case 0x50: + } + case 0x16 -> buf.readUnsignedShort(); // temperature + case 0x17 -> buf.readUnsignedByte(); // humidity + case 0x18 -> buf.readUnsignedShort(); // high temperature + case 0x19 -> buf.readUnsignedByte(); // high humidity + case 0x50 -> { if (buf.readUnsignedByte() > 0) { position.set(Position.KEY_ALARM, Position.ALARM_REMOVING); } - break; - case 0x51: + } + case 0x51 -> { if (buf.readUnsignedByte() > 0) { position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); } - break; - default: - break; + } } } diff --git a/src/main/java/org/traccar/protocol/ThurayaProtocolDecoder.java b/src/main/java/org/traccar/protocol/ThurayaProtocolDecoder.java index a287ece34..ea1879cf2 100644 --- a/src/main/java/org/traccar/protocol/ThurayaProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/ThurayaProtocolDecoder.java @@ -110,24 +110,16 @@ public class ThurayaProtocolDecoder extends BaseProtocolDecoder { } private String decodeAlarm(int event) { - switch (event) { - case 10: - return Position.ALARM_VIBRATION; - case 11: - return Position.ALARM_OVERSPEED; - case 12: - return Position.ALARM_POWER_CUT; - case 13: - return Position.ALARM_LOW_BATTERY; - case 18: - return Position.ALARM_GPS_ANTENNA_CUT; - case 20: - return Position.ALARM_ACCELERATION; - case 21: - return Position.ALARM_BRAKING; - default: - return null; - } + return switch (event) { + case 10 -> Position.ALARM_VIBRATION; + case 11 -> Position.ALARM_OVERSPEED; + case 12 -> Position.ALARM_POWER_CUT; + case 13 -> Position.ALARM_LOW_BATTERY; + case 18 -> Position.ALARM_GPS_ANTENNA_CUT; + case 20 -> Position.ALARM_ACCELERATION; + case 21 -> Position.ALARM_BRAKING; + default -> null; + }; } private String readString(ByteBuf buf) { diff --git a/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java index 6c926da90..7a7a0cc3b 100644 --- a/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tk103ProtocolDecoder.java @@ -157,123 +157,52 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { .compile(); private String decodeAlarm(int value) { - switch (value) { - case 1: - return Position.ALARM_ACCIDENT; - case 2: - return Position.ALARM_SOS; - case 3: - return Position.ALARM_VIBRATION; - case 4: - return Position.ALARM_LOW_SPEED; - case 5: - return Position.ALARM_OVERSPEED; - case 6: - return Position.ALARM_GEOFENCE_EXIT; - default: - return null; - } + return switch (value) { + case 1 -> Position.ALARM_ACCIDENT; + case 2 -> Position.ALARM_SOS; + case 3 -> Position.ALARM_VIBRATION; + case 4 -> Position.ALARM_LOW_SPEED; + case 5 -> Position.ALARM_OVERSPEED; + case 6 -> Position.ALARM_GEOFENCE_EXIT; + default -> null; + }; } private void decodeType(Position position, String type, String data) { switch (type) { - case "BQ81": + case "BQ81" -> { switch (Integer.parseInt(data)) { - case 0: - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - case 1: - position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); - break; - case 2: - position.set(Position.KEY_ALARM, Position.ALARM_IDLE); - break; - case 3: - position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - break; - case 4: - position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); - break; - case 5: - position.set(Position.KEY_ALARM, Position.ALARM_TEMPERATURE); - break; - default: - break; + case 0 -> position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + case 1 -> position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); + case 2 -> position.set(Position.KEY_ALARM, Position.ALARM_IDLE); + case 3 -> position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + case 4 -> position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + case 5 -> position.set(Position.KEY_ALARM, Position.ALARM_TEMPERATURE); } - break; - case "BO01": - position.set(Position.KEY_ALARM, decodeAlarm(data.charAt(0) - '0')); - break; - case "ZC11": - case "DW31": - case "DW51": - position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); - break; - case "ZC12": - case "DW32": - case "DW52": - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - case "ZC13": - case "DW33": - case "DW53": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); - break; - case "ZC15": - case "DW35": - case "DW55": - position.set(Position.KEY_IGNITION, true); - break; - case "ZC16": - case "DW36": - case "DW56": - position.set(Position.KEY_IGNITION, false); - break; - case "ZC29": - case "DW42": - case "DW62": - position.set(Position.KEY_IGNITION, true); - break; - case "ZC17": - case "DW37": - case "DW57": - position.set(Position.KEY_ALARM, Position.ALARM_REMOVING); - break; - case "ZC25": - case "DW3E": - case "DW5E": - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - break; - case "ZC26": - case "DW3F": - case "DW5F": - position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); - break; - case "ZC27": - case "DW40": - case "DW60": - position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); - break; - default: - break; + } + case "BO01" -> position.set(Position.KEY_ALARM, decodeAlarm(data.charAt(0) - '0')); + case "ZC11", "DW31", "DW51" -> position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); + case "ZC12", "DW32", "DW52" -> position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + case "ZC13", "DW33", "DW53" -> position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); + case "ZC15", "DW35", "DW55" -> position.set(Position.KEY_IGNITION, true); + case "ZC16", "DW36", "DW56" -> position.set(Position.KEY_IGNITION, false); + case "ZC29", "DW42", "DW62" -> position.set(Position.KEY_IGNITION, true); + case "ZC17", "DW37", "DW57" -> position.set(Position.KEY_ALARM, Position.ALARM_REMOVING); + case "ZC25", "DW3E", "DW5E" -> position.set(Position.KEY_ALARM, Position.ALARM_SOS); + case "ZC26", "DW3F", "DW5F" -> position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); + case "ZC27", "DW40", "DW60" -> position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); } } private Integer decodeBattery(int value) { - switch (value) { - case 6: - return 100; - case 5: - return 80; - case 4: - return 50; - case 3: - return 20; - case 2: - return 10; - default: - return null; - } + return switch (value) { + case 6 -> 100; + case 5 -> 80; + case 4 -> 50; + case 3 -> 20; + case 2 -> 10; + default -> null; + }; } private Position decodeBattery(Channel channel, SocketAddress remoteAddress, String sentence) { @@ -516,32 +445,30 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { int key = Integer.parseInt(pair[0], 16); ByteBuf buf = Unpooled.wrappedBuffer(DataConverter.parseHex(pair[1])); switch (key) { - case 0x90: + case 0x90 -> { position.set("cumulativeVoltage", buf.readUnsignedShortLE() * 0.1); position.set("gatherVoltage", buf.readUnsignedShortLE() * 0.1); position.set("current", (buf.readUnsignedShortLE() - 30000) * 0.1); position.set("soc", buf.readUnsignedShortLE() * 0.1); - break; - case 0x91: + } + case 0x91 -> { position.set("maxCellVoltage", buf.readUnsignedShortLE() * 0.001); position.set("maxCellVoltageCount", buf.readUnsignedByte()); position.set("minCellVoltage", buf.readUnsignedShortLE() * 0.001); position.set("minCellVoltageCount", buf.readUnsignedByte()); - break; - case 0x92: + } + case 0x92 -> { position.set("maxTemp", buf.readUnsignedByte() - 40); position.set("maxTempCount", buf.readUnsignedByte()); position.set("minTemp", buf.readUnsignedByte() - 40); position.set("minTempCount", buf.readUnsignedByte()); - break; - case 0x96: + } + case 0x96 -> { buf.readUnsignedByte(); // frame while (buf.isReadable()) { position.set("cellTemp" + buf.readerIndex(), buf.readUnsignedByte() - 40); } - break; - default: - break; + } } } diff --git a/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java index e3e1ae961..ed6eed6a7 100644 --- a/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Tk103ProtocolEncoder.java @@ -49,65 +49,48 @@ public class Tk103ProtocolEncoder extends StringProtocolEncoder { initDevicePassword(command, "123456"); if (alternative || forceAlternative) { - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return formatAlt(command, "%s", Command.KEY_DATA); - case Command.TYPE_GET_VERSION: - return formatAlt(command, "*about*"); - case Command.TYPE_POWER_OFF: - return formatAlt(command, "*turnoff*"); - case Command.TYPE_REBOOT_DEVICE: - return formatAlt(command, "88888888"); - case Command.TYPE_POSITION_SINGLE: - return formatAlt(command, "*getposl*"); - case Command.TYPE_POSITION_PERIODIC: - return formatAlt(command, "*routetrack*99*"); - case Command.TYPE_POSITION_STOP: - return formatAlt(command, "*routetrackoff*"); - case Command.TYPE_GET_DEVICE_STATUS: - return formatAlt(command, "*status*"); - case Command.TYPE_IDENTIFICATION: - return formatAlt(command, "999999"); - case Command.TYPE_MODE_DEEP_SLEEP: - return formatAlt(command, command.getBoolean(Command.KEY_ENABLE) ? "*sleep*2*" : "*sleepoff*"); - case Command.TYPE_MODE_POWER_SAVING: - return formatAlt(command, command.getBoolean(Command.KEY_ENABLE) ? "*sleepv*" : "*sleepoff*"); - case Command.TYPE_ALARM_SOS: - return formatAlt(command, command.getBoolean(Command.KEY_ENABLE) ? "*soson*" : "*sosoff*"); - case Command.TYPE_SET_CONNECTION: + return switch (command.getType()) { + case Command.TYPE_CUSTOM -> formatAlt(command, "%s", Command.KEY_DATA); + case Command.TYPE_GET_VERSION -> formatAlt(command, "*about*"); + case Command.TYPE_POWER_OFF -> formatAlt(command, "*turnoff*"); + case Command.TYPE_REBOOT_DEVICE -> formatAlt(command, "88888888"); + case Command.TYPE_POSITION_SINGLE -> formatAlt(command, "*getposl*"); + case Command.TYPE_POSITION_PERIODIC -> formatAlt(command, "*routetrack*99*"); + case Command.TYPE_POSITION_STOP -> formatAlt(command, "*routetrackoff*"); + case Command.TYPE_GET_DEVICE_STATUS -> formatAlt(command, "*status*"); + case Command.TYPE_IDENTIFICATION -> formatAlt(command, "999999"); + case Command.TYPE_MODE_DEEP_SLEEP -> + formatAlt(command, command.getBoolean(Command.KEY_ENABLE) ? "*sleep*2*" : "*sleepoff*"); + case Command.TYPE_MODE_POWER_SAVING -> + formatAlt(command, command.getBoolean(Command.KEY_ENABLE) ? "*sleepv*" : "*sleepoff*"); + case Command.TYPE_ALARM_SOS -> + formatAlt(command, command.getBoolean(Command.KEY_ENABLE) ? "*soson*" : "*sosoff*"); + case Command.TYPE_SET_CONNECTION -> { String server = command.getString(Command.KEY_SERVER).replace(".", "*"); - return formatAlt(command, "*setip*" + server + "*%s*", Command.KEY_PORT); - case Command.TYPE_SOS_NUMBER: - return formatAlt(command, "*master*%s*%s*", Command.KEY_DEVICE_PASSWORD, Command.KEY_PHONE); - default: - return null; - } + yield formatAlt(command, "*setip*" + server + "*%s*", Command.KEY_PORT); + } + case Command.TYPE_SOS_NUMBER -> + formatAlt(command, "*master*%s*%s*", Command.KEY_DEVICE_PASSWORD, Command.KEY_PHONE); + default -> null; + }; } else { - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return formatCommand(command, "(%s%s)", Command.KEY_UNIQUE_ID, Command.KEY_DATA); - case Command.TYPE_GET_VERSION: - return formatCommand(command, "(%sAP07)", Command.KEY_UNIQUE_ID); - case Command.TYPE_REBOOT_DEVICE: - return formatCommand(command, "(%sAT00)", Command.KEY_UNIQUE_ID); - case Command.TYPE_SET_ODOMETER: - return formatCommand(command, "(%sAX01)", Command.KEY_UNIQUE_ID); - case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, "(%sAP00)", Command.KEY_UNIQUE_ID); - case Command.TYPE_POSITION_PERIODIC: + return switch (command.getType()) { + case Command.TYPE_CUSTOM -> formatCommand(command, "(%s%s)", Command.KEY_UNIQUE_ID, Command.KEY_DATA); + case Command.TYPE_GET_VERSION -> formatCommand(command, "(%sAP07)", Command.KEY_UNIQUE_ID); + case Command.TYPE_REBOOT_DEVICE -> formatCommand(command, "(%sAT00)", Command.KEY_UNIQUE_ID); + case Command.TYPE_SET_ODOMETER -> formatCommand(command, "(%sAX01)", Command.KEY_UNIQUE_ID); + case Command.TYPE_POSITION_SINGLE -> formatCommand(command, "(%sAP00)", Command.KEY_UNIQUE_ID); + case Command.TYPE_POSITION_PERIODIC -> { String frequency = String.format("%04X", command.getInteger(Command.KEY_FREQUENCY)); - return formatCommand(command, "(%sAR00" + frequency + "0000)", Command.KEY_UNIQUE_ID); - case Command.TYPE_POSITION_STOP: - return formatCommand(command, "(%sAR0000000000)", Command.KEY_UNIQUE_ID); - case Command.TYPE_ENGINE_STOP: - return formatCommand(command, "(%sAV010)", Command.KEY_UNIQUE_ID); - case Command.TYPE_ENGINE_RESUME: - return formatCommand(command, "(%sAV011)", Command.KEY_UNIQUE_ID); - case Command.TYPE_OUTPUT_CONTROL: - return formatCommand(command, "(%sAV00%s)", Command.KEY_UNIQUE_ID, Command.KEY_DATA); - default: - return null; - } + yield formatCommand(command, "(%sAR00" + frequency + "0000)", Command.KEY_UNIQUE_ID); + } + case Command.TYPE_POSITION_STOP -> formatCommand(command, "(%sAR0000000000)", Command.KEY_UNIQUE_ID); + case Command.TYPE_ENGINE_STOP -> formatCommand(command, "(%sAV010)", Command.KEY_UNIQUE_ID); + case Command.TYPE_ENGINE_RESUME -> formatCommand(command, "(%sAV011)", Command.KEY_UNIQUE_ID); + case Command.TYPE_OUTPUT_CONTROL -> + formatCommand(command, "(%sAV00%s)", Command.KEY_UNIQUE_ID, Command.KEY_DATA); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/Tlt2hProtocol.java b/src/main/java/org/traccar/protocol/Tlt2hProtocol.java index 6763e9b6b..4f306bcf5 100644 --- a/src/main/java/org/traccar/protocol/Tlt2hProtocol.java +++ b/src/main/java/org/traccar/protocol/Tlt2hProtocol.java @@ -38,6 +38,14 @@ public class Tlt2hProtocol extends BaseProtocol { pipeline.addLast(new Tlt2hProtocolDecoder(Tlt2hProtocol.this)); } }); + addServer(new TrackerServer(config, getName(), true) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline, Config config) { + pipeline.addLast(new StringDecoder()); + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new Tlt2hProtocolDecoder(Tlt2hProtocol.this)); + } + }); } } diff --git a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java index 6be3d2dc3..2d59ffda8 100644 --- a/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Tlt2hProtocolDecoder.java @@ -101,40 +101,17 @@ public class Tlt2hProtocolDecoder extends BaseProtocolDecoder { private void decodeStatus(Position position, String status) { switch (status) { - case "AUTOSTART": - case "AUTO": - position.set(Position.KEY_IGNITION, true); - break; - case "AUTOSTOP": - case "AUTOLOW": - position.set(Position.KEY_IGNITION, false); - break; - case "TOWED": - position.set(Position.KEY_ALARM, Position.ALARM_TOW); - break; - case "SOS": - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - break; - case "DEF": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); - break; - case "BLP": - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - case "CLP": - position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); - break; - case "OS": - position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE_EXIT); - break; - case "RS": - position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE_ENTER); - break; - case "OVERSPEED": - position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); - break; - default: - break; + case "AUTOSTART", "AUTO" -> position.set(Position.KEY_IGNITION, true); + case "AUTOSTOP", "AUTOLOW" -> position.set(Position.KEY_IGNITION, false); + case "TOWED" -> position.set(Position.KEY_ALARM, Position.ALARM_TOW); + case "SHAKE" -> position.set(Position.KEY_ALARM, Position.ALARM_VIBRATION); + case "SOS" -> position.set(Position.KEY_ALARM, Position.ALARM_SOS); + case "DEF" -> position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); + case "BLP" -> position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + case "CLP" -> position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); + case "OS" -> position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE_EXIT); + case "RS" -> position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE_ENTER); + case "OVERSPEED" -> position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); } } diff --git a/src/main/java/org/traccar/protocol/TlvProtocolDecoder.java b/src/main/java/org/traccar/protocol/TlvProtocolDecoder.java index 7870c778a..21ed8fba4 100644 --- a/src/main/java/org/traccar/protocol/TlvProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TlvProtocolDecoder.java @@ -62,19 +62,9 @@ public class TlvProtocolDecoder extends BaseProtocolDecoder { if (channel != null) { switch (type) { - case "0A": - case "0C": - sendResponse(channel, remoteAddress, type); - break; - case "0B": - sendResponse(channel, remoteAddress, type, "1482202689", "10", "20", "15"); - break; - case "0E": - case "0F": - sendResponse(channel, remoteAddress, type, "30", "Unknown"); - break; - default: - break; + case "0A", "0C" -> sendResponse(channel, remoteAddress, type); + case "0B" -> sendResponse(channel, remoteAddress, type, "1482202689", "10", "20", "15"); + case "0E", "0F" -> sendResponse(channel, remoteAddress, type, "30", "Unknown"); } } diff --git a/src/main/java/org/traccar/protocol/TmgProtocolDecoder.java b/src/main/java/org/traccar/protocol/TmgProtocolDecoder.java index 00dc2a09b..9a8f5830a 100644 --- a/src/main/java/org/traccar/protocol/TmgProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TmgProtocolDecoder.java @@ -104,28 +104,12 @@ public class TmgProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); switch (type) { - case "rmv": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); - break; - case "ebl": - position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); - break; - case "ibl": - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - case "tmp": - case "smt": - case "btt": - position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); - break; - case "ion": - position.set(Position.KEY_IGNITION, true); - break; - case "iof": - position.set(Position.KEY_IGNITION, false); - break; - default: - break; + case "rmv" -> position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); + case "ebl" -> position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); + case "ibl" -> position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + case "tmp", "smt", "btt" -> position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); + case "ion" -> position.set(Position.KEY_IGNITION, true); + case "iof" -> position.set(Position.KEY_IGNITION, false); } position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); diff --git a/src/main/java/org/traccar/protocol/TopinProtocolEncoder.java b/src/main/java/org/traccar/protocol/TopinProtocolEncoder.java index 77f80b9d4..b3b6bc23f 100644 --- a/src/main/java/org/traccar/protocol/TopinProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/TopinProtocolEncoder.java @@ -54,13 +54,13 @@ public class TopinProtocolEncoder extends BaseProtocolEncoder { ByteBuf content = Unpooled.buffer(); - switch (command.getType()) { - case Command.TYPE_SOS_NUMBER: + return switch (command.getType()) { + case Command.TYPE_SOS_NUMBER -> { content.writeCharSequence(command.getString(Command.KEY_PHONE), StandardCharsets.US_ASCII); - return encodeContent(TopinProtocolDecoder.MSG_SOS_NUMBER, content); - default: - return null; - } + yield encodeContent(TopinProtocolDecoder.MSG_SOS_NUMBER, content); + } + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java index 6f039c324..c48db5b3f 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolDecoder.java @@ -218,57 +218,35 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { .compile(); private String decodeAlarm123(int value) { - switch (value) { - case 0x01: - return Position.ALARM_SOS; - case 0x10: - return Position.ALARM_LOW_BATTERY; - case 0x11: - return Position.ALARM_OVERSPEED; - case 0x30: - return Position.ALARM_PARKING; - case 0x42: - return Position.ALARM_GEOFENCE_EXIT; - case 0x43: - return Position.ALARM_GEOFENCE_ENTER; - default: - return null; - } + return switch (value) { + case 0x01 -> Position.ALARM_SOS; + case 0x10 -> Position.ALARM_LOW_BATTERY; + case 0x11 -> Position.ALARM_OVERSPEED; + case 0x30 -> Position.ALARM_PARKING; + case 0x42 -> Position.ALARM_GEOFENCE_EXIT; + case 0x43 -> Position.ALARM_GEOFENCE_ENTER; + default -> null; + }; } private String decodeAlarm4(int value) { - switch (value) { - case 0x01: - return Position.ALARM_SOS; - case 0x02: - return Position.ALARM_OVERSPEED; - case 0x04: - return Position.ALARM_GEOFENCE_EXIT; - case 0x05: - return Position.ALARM_GEOFENCE_ENTER; - case 0x06: - return Position.ALARM_TOW; - case 0x07: - return Position.ALARM_GPS_ANTENNA_CUT; - case 0x10: - return Position.ALARM_POWER_CUT; - case 0x11: - return Position.ALARM_POWER_RESTORED; - case 0x12: - return Position.ALARM_LOW_POWER; - case 0x13: - return Position.ALARM_LOW_BATTERY; - case 0x40: - return Position.ALARM_VIBRATION; - case 0x41: - return Position.ALARM_IDLE; - case 0x42: - return Position.ALARM_ACCELERATION; - case 0x43: - return Position.ALARM_BRAKING; - default: - return null; - } + return switch (value) { + case 0x01 -> Position.ALARM_SOS; + case 0x02 -> Position.ALARM_OVERSPEED; + case 0x04 -> Position.ALARM_GEOFENCE_EXIT; + case 0x05 -> Position.ALARM_GEOFENCE_ENTER; + case 0x06 -> Position.ALARM_TOW; + case 0x07 -> Position.ALARM_GPS_ANTENNA_CUT; + case 0x10 -> Position.ALARM_POWER_CUT; + case 0x11 -> Position.ALARM_POWER_RESTORED; + case 0x12 -> Position.ALARM_LOW_POWER; + case 0x13 -> Position.ALARM_LOW_BATTERY; + case 0x40 -> Position.ALARM_VIBRATION; + case 0x41 -> Position.ALARM_IDLE; + case 0x42 -> Position.ALARM_ACCELERATION; + case 0x43 -> Position.ALARM_BRAKING; + default -> null; + }; } private Position decode12(Channel channel, SocketAddress remoteAddress, String sentence, Pattern pattern) { diff --git a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java index 4b22ade03..fea9e2d2c 100644 --- a/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/TotemProtocolEncoder.java @@ -28,28 +28,27 @@ public class TotemProtocolEncoder extends StringProtocolEncoder { } public static String formatContent(Command command) { - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return String.format("%s,%s", - command.getAttributes().get(Command.KEY_DEVICE_PASSWORD), - command.getAttributes().get(Command.KEY_DATA) - ); - case Command.TYPE_REBOOT_DEVICE: - return String.format("%s,006", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); - case Command.TYPE_FACTORY_RESET: - return String.format("%s,007", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); - case Command.TYPE_GET_VERSION: - return String.format("%s,056", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); - case Command.TYPE_POSITION_SINGLE: - return String.format("%s,012", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); - // Assuming PIN 8 (Output C) is the power wire, like manual says but it can be PIN 5,7,8 - case Command.TYPE_ENGINE_STOP: - return String.format("%s,025,C,1", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); - case Command.TYPE_ENGINE_RESUME: - return String.format("%s,025,C,0", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_CUSTOM -> + String.format( + "%s,%s", + command.getAttributes().get(Command.KEY_DEVICE_PASSWORD), + command.getAttributes().get(Command.KEY_DATA)); + case Command.TYPE_REBOOT_DEVICE -> + String.format("%s,006", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); + case Command.TYPE_FACTORY_RESET -> + String.format("%s,007", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); + case Command.TYPE_GET_VERSION -> + String.format("%s,056", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); + case Command.TYPE_POSITION_SINGLE -> + String.format("%s,012", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); + // Assuming PIN 8 (Output C) is the power wire, like manual says, but it can be PIN 5,7,8 + case Command.TYPE_ENGINE_STOP -> + String.format("%s,025,C,1", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); + case Command.TYPE_ENGINE_RESUME -> + String.format("%s,025,C,0", command.getAttributes().get(Command.KEY_DEVICE_PASSWORD)); + default -> null; + }; } @Override diff --git a/src/main/java/org/traccar/protocol/TrakMateProtocolDecoder.java b/src/main/java/org/traccar/protocol/TrakMateProtocolDecoder.java index b1f50dc10..78c21b40d 100644 --- a/src/main/java/org/traccar/protocol/TrakMateProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TrakMateProtocolDecoder.java @@ -91,16 +91,12 @@ public class TrakMateProtocolDecoder extends BaseProtocolDecoder { .compile(); private String decodeAlarm(int value) { - switch (value) { - case 1: - return Position.ALARM_SOS; - case 3: - return Position.ALARM_GEOFENCE; - case 4: - return Position.ALARM_POWER_CUT; - default: - return null; - } + return switch (value) { + case 1 -> Position.ALARM_SOS; + case 3 -> Position.ALARM_GEOFENCE; + case 4 -> Position.ALARM_POWER_CUT; + default -> null; + }; } private Object decodeSrt(Channel channel, SocketAddress remoteAddress, String sentence) { @@ -220,14 +216,11 @@ public class TrakMateProtocolDecoder extends BaseProtocolDecoder { } String type = sentence.substring(typeIndex + 3, typeIndex + 6); - switch (type) { - case "ALT": - return decodeAlt(channel, remoteAddress, sentence); - case "SRT": - return decodeSrt(channel, remoteAddress, sentence); - default: - return decodePer(channel, remoteAddress, sentence); - } + return switch (type) { + case "ALT" -> decodeAlt(channel, remoteAddress, sentence); + case "SRT" -> decodeSrt(channel, remoteAddress, sentence); + default -> decodePer(channel, remoteAddress, sentence); + }; } } diff --git a/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java b/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java index 4a9a9a58f..f12211f81 100644 --- a/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TramigoProtocolDecoder.java @@ -167,7 +167,7 @@ public class TramigoProtocolDecoder extends BaseProtocolDecoder { while (buf.isReadable()) { int type = buf.readUnsignedByte(); switch (type) { - case 0: + case 0 -> { position.set(Position.KEY_EVENT, buf.readUnsignedShortLE()); buf.readUnsignedIntLE(); // event data @@ -193,34 +193,19 @@ public class TramigoProtocolDecoder extends BaseProtocolDecoder { position.setFixTime(new Date(buf.readUnsignedIntLE() * 1000)); buf.readUnsignedByte(); // reserved - break; - case 1: - buf.skipBytes(buf.readUnsignedShortLE() - 3); // landmark - break; - case 4: - buf.skipBytes(53); // trip - break; - case 20: - buf.skipBytes(32); // extended - break; - case 22: + } + case 1 -> buf.skipBytes(buf.readUnsignedShortLE() - 3); // landmark + case 4 -> buf.skipBytes(53); // trip + case 20 -> buf.skipBytes(32); // extended + case 22 -> { buf.readUnsignedByte(); // zone flag buf.skipBytes(buf.readUnsignedShortLE()); // zone name - break; - case 30: - buf.skipBytes(79); // system status - break; - case 40: - buf.skipBytes(40); // analog - break; - case 50: - buf.skipBytes(buf.readUnsignedShortLE() - 3); // console - break; - case 255: - buf.skipBytes(4); // acknowledgement - break; - default: - throw new IllegalArgumentException(String.format("Unknown type %d", type)); + } + case 30 -> buf.skipBytes(79); // system status + case 40 -> buf.skipBytes(40); // analog + case 50 -> buf.skipBytes(buf.readUnsignedShortLE() - 3); // console + case 255 -> buf.skipBytes(4); // acknowledgement + default -> throw new IllegalArgumentException(String.format("Unknown type %d", type)); } } diff --git a/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java b/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java index 816b5d2cf..e3f7ae36f 100644 --- a/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TranSyncProtocolDecoder.java @@ -37,24 +37,16 @@ public class TranSyncProtocolDecoder extends BaseProtocolDecoder { } private String decodeAlarm(int value) { - switch (value) { - case 4: - return Position.ALARM_LOW_BATTERY; - case 6: - return Position.ALARM_POWER_RESTORED; - case 10: - return Position.ALARM_SOS; - case 13: - return Position.ALARM_BRAKING; - case 14: - return Position.ALARM_ACCELERATION; - case 17: - return Position.ALARM_OVERSPEED; - case 23: - return Position.ALARM_ACCIDENT; - default: - return null; - } + return switch (value) { + case 4 -> Position.ALARM_LOW_BATTERY; + case 6 -> Position.ALARM_POWER_RESTORED; + case 10 -> Position.ALARM_SOS; + case 13 -> Position.ALARM_BRAKING; + case 14 -> Position.ALARM_ACCELERATION; + case 17 -> Position.ALARM_OVERSPEED; + case 23 -> Position.ALARM_ACCIDENT; + default -> null; + }; } @Override diff --git a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java index 1187250f8..e39b17307 100644 --- a/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TrvProtocolDecoder.java @@ -180,7 +180,7 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { channel.writeAndFlush(new NetworkMessage(responseHeader + "," + time + ",0#", remoteAddress)); } else if (type.equals("AP14")) { channel.writeAndFlush(new NetworkMessage(responseHeader + ",0.000,0.000#", remoteAddress)); - } else { + } else if (!type.equals("AP12") && !sentence.substring(responseHeader.length() + 1).matches("^\\d{6}$")) { channel.writeAndFlush(new NetworkMessage(responseHeader + "#", remoteAddress)); } } @@ -249,15 +249,8 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext()) { switch (parser.nextInt()) { - case 1: - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - break; - case 5: - case 6: - position.set(Position.KEY_ALARM, Position.ALARM_FALL_DOWN); - break; - default: - break; + case 1 -> position.set(Position.KEY_ALARM, Position.ALARM_SOS); + case 5, 6 -> position.set(Position.KEY_ALARM, Position.ALARM_FALL_DOWN); } } @@ -332,28 +325,24 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { String[] values = sentence.split(","); switch (type) { - case "AP49": - position.set(Position.KEY_HEART_RATE, Integer.parseInt(values[1])); - break; - case "APHT": + case "AP49" -> position.set(Position.KEY_HEART_RATE, Integer.parseInt(values[1])); + case "APHT" -> { position.set(Position.KEY_HEART_RATE, Integer.parseInt(values[1])); position.set("pressureSystolic", Integer.parseInt(values[2])); position.set("pressureDiastolic", Integer.parseInt(values[3])); - break; - case "APHP": + } + case "APHP" -> { position.set(Position.KEY_HEART_RATE, Integer.parseInt(values[1])); position.set("pressureSystolic", Integer.parseInt(values[2])); position.set("pressureDiastolic", Integer.parseInt(values[3])); position.set("spo2", Integer.parseInt(values[4])); position.set("bloodSugar", Double.parseDouble(values[5])); position.set("temperature", Double.parseDouble(values[6])); - break; - case "AP50": + } + case "AP50" -> { position.set("temperature", Double.parseDouble(values[1])); position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(values[2])); - break; - default: - break; + } } return position; diff --git a/src/main/java/org/traccar/protocol/TytanProtocolDecoder.java b/src/main/java/org/traccar/protocol/TytanProtocolDecoder.java index 6169e0545..04461f9cc 100644 --- a/src/main/java/org/traccar/protocol/TytanProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TytanProtocolDecoder.java @@ -51,55 +51,39 @@ public class TytanProtocolDecoder extends BaseProtocolDecoder { int n; switch (type) { - case 2: - position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedMedium()); - break; - case 5: - position.set(Position.KEY_INPUT, buf.readUnsignedByte()); - break; - case 6: + case 2 -> position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedMedium()); + case 5 -> position.set(Position.KEY_INPUT, buf.readUnsignedByte()); + case 6 -> { n = buf.readUnsignedByte() >> 4; if (n < 2) { position.set(Position.PREFIX_ADC + n, buf.readFloat()); } else { position.set("di" + (n - 2), buf.readFloat()); } - break; - case 7: + } + case 7 -> { int alarm = buf.readUnsignedByte(); buf.readUnsignedByte(); if (BitUtil.check(alarm, 5)) { position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); } - break; - case 8: - position.set("antihijack", buf.readUnsignedByte()); - break; - case 9: - position.set("unauthorized", ByteBufUtil.hexDump(buf.readSlice(8))); - break; - case 10: - position.set("authorized", ByteBufUtil.hexDump(buf.readSlice(8))); - break; - case 24: + } + case 8 -> position.set("antihijack", buf.readUnsignedByte()); + case 9 -> position.set("unauthorized", ByteBufUtil.hexDump(buf.readSlice(8))); + case 10 -> position.set("authorized", ByteBufUtil.hexDump(buf.readSlice(8))); + case 24 -> { for (int i = 0; i < length / 2; i++) { position.set(Position.PREFIX_TEMP + buf.readUnsignedByte(), buf.readByte()); } - break; - case 28: + } + case 28 -> { position.set(Position.KEY_AXLE_WEIGHT, buf.readUnsignedShort()); buf.readUnsignedByte(); - break; - case 90: - position.set(Position.KEY_POWER, buf.readFloat()); - break; - case 101: - position.set(Position.KEY_OBD_SPEED, buf.readUnsignedByte()); - break; - case 102: - position.set(Position.KEY_RPM, buf.readUnsignedByte() * 50); - break; - case 107: + } + case 90 -> position.set(Position.KEY_POWER, buf.readFloat()); + case 101 -> position.set(Position.KEY_OBD_SPEED, buf.readUnsignedByte()); + case 102 -> position.set(Position.KEY_RPM, buf.readUnsignedByte() * 50); + case 107 -> { int fuel = buf.readUnsignedShort(); int fuelFormat = fuel >> 14; if (fuelFormat == 1) { @@ -109,16 +93,10 @@ public class TytanProtocolDecoder extends BaseProtocolDecoder { } else if (fuelFormat == 3) { position.set("fuelValue", (fuel & 0x3fff) * -0.5 + " l"); } - break; - case 108: - position.set(Position.KEY_OBD_ODOMETER, buf.readUnsignedInt() * 5); - break; - case 150: - position.set(Position.KEY_DOOR, buf.readUnsignedByte()); - break; - default: - buf.skipBytes(length); - break; + } + case 108 -> position.set(Position.KEY_OBD_ODOMETER, buf.readUnsignedInt() * 5); + case 150 -> position.set(Position.KEY_DOOR, buf.readUnsignedByte()); + default -> buf.skipBytes(length); } } } diff --git a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java index f0b1e709d..8fbea5808 100644 --- a/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/TzoneProtocolDecoder.java @@ -60,26 +60,17 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { } private String decodeAlarm(Short value) { - switch (value) { - case 0x01: - return Position.ALARM_SOS; - case 0x10: - return Position.ALARM_LOW_BATTERY; - case 0x11: - return Position.ALARM_OVERSPEED; - case 0x14: - return Position.ALARM_BRAKING; - case 0x15: - return Position.ALARM_ACCELERATION; - case 0x30: - return Position.ALARM_PARKING; - case 0x42: - return Position.ALARM_GEOFENCE_EXIT; - case 0x43: - return Position.ALARM_GEOFENCE_ENTER; - default: - return null; - } + return switch (value) { + case 0x01 -> Position.ALARM_SOS; + case 0x10 -> Position.ALARM_LOW_BATTERY; + case 0x11 -> Position.ALARM_OVERSPEED; + case 0x14 -> Position.ALARM_BRAKING; + case 0x15 -> Position.ALARM_ACCELERATION; + case 0x30 -> Position.ALARM_PARKING; + case 0x42 -> Position.ALARM_GEOFENCE_EXIT; + case 0x43 -> Position.ALARM_GEOFENCE_ENTER; + default -> null; + }; } private boolean decodeGps(Position position, ByteBuf buf, int hardware) { diff --git a/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java b/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java index c9b35158e..edcf46c2e 100644 --- a/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/UlbotechProtocolDecoder.java @@ -147,21 +147,12 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder { int id = BitUtil.from(value, 12); value = BitUtil.to(value, 12); switch (id) { - case 0: - position.set(Position.KEY_POWER, value * (100 + 10) / 4096.0 - 10); - break; - case 1: - position.set(Position.PREFIX_TEMP + 1, value * (125 + 55) / 4096.0 - 55); - break; - case 2: - position.set(Position.KEY_BATTERY, value * (100 + 10) / 4096.0 - 10); - break; - case 3: - position.set(Position.PREFIX_ADC + 1, value * (100 + 10) / 4096.0 - 10); - break; - default: - position.set(Position.PREFIX_IO + id, value); - break; + case 0 -> position.set(Position.KEY_POWER, value * (100 + 10) / 4096.0 - 10); + case 1 -> position.set(Position.PREFIX_TEMP + 1, value * (125 + 55) / 4096.0 - 55); + case 2 -> position.set(Position.KEY_BATTERY, value * (100 + 10) / 4096.0 - 10); + case 3 -> position.set(Position.PREFIX_ADC + 1, value * (100 + 10) / 4096.0 - 10); + case 5, 6, 7, 8, 9 -> position.set("fuel" + (id - 4), value * 2000 / 4096.0); + default -> position.set(Position.PREFIX_IO + id, value); } } } @@ -236,8 +227,7 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder { int length = type == DATA_CANBUS ? buf.readUnsignedShort() : buf.readUnsignedByte(); switch (type) { - - case DATA_GPS: + case DATA_GPS -> { hasLocation = true; position.setLatitude(buf.readInt() / 1000000.0); position.setLongitude(buf.readInt() / 1000000.0); @@ -246,9 +236,8 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder { int hdop = buf.readUnsignedShort(); position.setValid(hdop < 9999); position.set(Position.KEY_HDOP, hdop * 0.01); - break; - - case DATA_LBS: + } + case DATA_LBS -> { if (length == 11) { position.setNetwork(new Network(CellTower.from( buf.readUnsignedShort(), buf.readUnsignedShort(), @@ -261,72 +250,39 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder { if (length > 9 && length != 11) { buf.skipBytes(length - 9); } - break; - - case DATA_STATUS: + } + case DATA_STATUS -> { int status = buf.readUnsignedShort(); position.set(Position.KEY_IGNITION, BitUtil.check(status, 9)); position.set(Position.KEY_STATUS, status); position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedShort())); - break; - - case DATA_ODOMETER: - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - break; - - case DATA_ADC: - decodeAdc(position, buf, length); - break; - - case DATA_GEOFENCE: + } + case DATA_ODOMETER -> position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + case DATA_ADC -> decodeAdc(position, buf, length); + case DATA_GEOFENCE -> { position.set("geofenceIn", buf.readUnsignedInt()); position.set("geofenceAlarm", buf.readUnsignedInt()); - break; - - case DATA_OBD2: - decodeObd(position, buf, length); - break; - - case DATA_FUEL: - position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedInt() / 10000.0); - break; - - case DATA_OBD2_ALARM: - decodeObd(position, buf, length); - break; - - case DATA_HARSH_DRIVER: - decodeDriverBehavior(position, buf); - break; - - case DATA_CANBUS: - position.set("can", ByteBufUtil.hexDump(buf.readSlice(length))); - break; - - case DATA_J1708: - decodeJ1708(position, buf, length); - break; - - case DATA_VIN: - position.set(Position.KEY_VIN, buf.readSlice(length).toString(StandardCharsets.US_ASCII)); - break; - - case DATA_RFID: + } + case DATA_OBD2 -> decodeObd(position, buf, length); + case DATA_FUEL -> position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedInt() / 10000.0); + case DATA_OBD2_ALARM -> decodeObd(position, buf, length); + case DATA_HARSH_DRIVER -> decodeDriverBehavior(position, buf); + case DATA_CANBUS -> position.set("can", ByteBufUtil.hexDump(buf.readSlice(length))); + case DATA_J1708 -> decodeJ1708(position, buf, length); + case DATA_VIN -> + position.set(Position.KEY_VIN, buf.readSlice(length).toString(StandardCharsets.US_ASCII)); + case DATA_RFID -> { position.set(Position.KEY_DRIVER_UNIQUE_ID, buf.readSlice(length - 1).toString(StandardCharsets.US_ASCII)); position.set("authorized", buf.readUnsignedByte() != 0); - break; - - case DATA_EVENT: + } + case DATA_EVENT -> { position.set(Position.KEY_EVENT, buf.readUnsignedByte()); if (length > 1) { position.set("eventMask", buf.readUnsignedInt()); } - break; - - default: - buf.skipBytes(length); - break; + } + default -> buf.skipBytes(length); } } diff --git a/src/main/java/org/traccar/protocol/UlbotechProtocolEncoder.java b/src/main/java/org/traccar/protocol/UlbotechProtocolEncoder.java index 5528c7242..10f408821 100644 --- a/src/main/java/org/traccar/protocol/UlbotechProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/UlbotechProtocolEncoder.java @@ -30,13 +30,11 @@ public class UlbotechProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return Unpooled.copiedBuffer( - "*TS01," + command.getString(Command.KEY_DATA) + "#", StandardCharsets.US_ASCII); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_CUSTOM -> Unpooled.copiedBuffer( + "*TS01," + command.getString(Command.KEY_DATA) + "#", StandardCharsets.US_ASCII); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/UproProtocolDecoder.java b/src/main/java/org/traccar/protocol/UproProtocolDecoder.java index 8d2e5de0a..b866c4112 100644 --- a/src/main/java/org/traccar/protocol/UproProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/UproProtocolDecoder.java @@ -154,29 +154,21 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { String stringValue; switch (dataType) { - case 'A': - decodeLocation(position, data.toString(StandardCharsets.US_ASCII)); - break; - case 'B': - position.set(Position.KEY_STATUS, data.toString(StandardCharsets.US_ASCII)); - break; - case 'C': + case 'A' -> decodeLocation(position, data.toString(StandardCharsets.US_ASCII)); + case 'B' -> position.set(Position.KEY_STATUS, data.toString(StandardCharsets.US_ASCII)); + case 'C' -> { long odometer = 0; while (data.isReadable()) { odometer <<= 4; odometer += data.readByte() - (byte) '0'; } position.set(Position.KEY_ODOMETER, odometer * 2 * 1852 / 3600); - break; - case 'F': - position.setSpeed( - Integer.parseInt(data.readSlice(4).toString(StandardCharsets.US_ASCII)) * 0.1); - break; - case 'G': - position.setAltitude( - Integer.parseInt(data.readSlice(6).toString(StandardCharsets.US_ASCII)) * 0.1); - break; - case 'I': + } + case 'F' -> position.setSpeed( + Integer.parseInt(data.readSlice(4).toString(StandardCharsets.US_ASCII)) * 0.1); + case 'G' -> position.setAltitude( + Integer.parseInt(data.readSlice(6).toString(StandardCharsets.US_ASCII)) * 0.1); + case 'I' -> { stringValue = data.toString(StandardCharsets.US_ASCII); count = Integer.parseInt(stringValue.substring(0, 1)); if (stringValue.length() == 6 + count * 10) { @@ -191,8 +183,8 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { Integer.parseInt(stringValue.substring(offset + 8, offset + 10)))); } } - break; - case 'J': + } + case 'J' -> { if (data.readableBytes() == 6) { char index = (char) data.readUnsignedByte(); int status = data.readUnsignedByte(); @@ -202,11 +194,9 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { } position.set(Position.PREFIX_TEMP + index, value); } - break; - case 'K': - position.set("statusExtended", data.toString(StandardCharsets.US_ASCII)); - break; - case 'M': + } + case 'K' -> position.set("statusExtended", data.toString(StandardCharsets.US_ASCII)); + case 'M' -> { if (data.readableBytes() == 3) { position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(data.readSlice(3).toString(StandardCharsets.US_ASCII)) * 0.1); @@ -217,16 +207,12 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { "humidity" + index, Integer.parseInt(data.readSlice(2).toString(StandardCharsets.US_ASCII))); } - break; - case 'N': - position.set(Position.KEY_RSSI, - Integer.parseInt(data.readSlice(2).toString(StandardCharsets.US_ASCII))); - break; - case 'O': - position.set(Position.KEY_SATELLITES, - Integer.parseInt(data.readSlice(2).toString(StandardCharsets.US_ASCII))); - break; - case 'P': + } + case 'N' -> position.set(Position.KEY_RSSI, + Integer.parseInt(data.readSlice(2).toString(StandardCharsets.US_ASCII))); + case 'O' -> position.set(Position.KEY_SATELLITES, + Integer.parseInt(data.readSlice(2).toString(StandardCharsets.US_ASCII))); + case 'P' -> { if (data.readableBytes() >= 16) { position.setNetwork(new Network(CellTower.from( Integer.parseInt(data.readSlice(4).toString(StandardCharsets.US_ASCII)), @@ -234,13 +220,13 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { Integer.parseInt(data.readSlice(4).toString(StandardCharsets.US_ASCII), 16), Integer.parseInt(data.readSlice(4).toString(StandardCharsets.US_ASCII), 16)))); } - break; - case 'Q': + } + case 'Q' -> { if (!head.startsWith("HQ")) { position.set("obdPid", ByteBufUtil.hexDump(data)); } - break; - case 'R': + } + case 'R' -> { if (head.startsWith("HQ")) { position.set(Position.KEY_RSSI, Integer.parseInt(data.readSlice(2).toString(StandardCharsets.US_ASCII))); @@ -249,25 +235,19 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { } else { position.set("odbTravel", ByteBufUtil.hexDump(data)); } - break; - case 'S': - position.set("obdTraffic", ByteBufUtil.hexDump(data)); - break; - case 'T': + } + case 'S' -> position.set("obdTraffic", ByteBufUtil.hexDump(data)); + case 'T' -> { if (data.readableBytes() == 2) { position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(data.toString(StandardCharsets.US_ASCII))); } - break; - case 'V': - position.set(Position.KEY_POWER, - Integer.parseInt(data.readSlice(4).toString(StandardCharsets.US_ASCII)) * 0.1); - break; - case 'W': - position.set(Position.KEY_ALARM, - decodeAlarm(Integer.parseInt(data.readSlice(2).toString(StandardCharsets.US_ASCII)))); - break; - case 'X': + } + case 'V' -> position.set(Position.KEY_POWER, + Integer.parseInt(data.readSlice(4).toString(StandardCharsets.US_ASCII)) * 0.1); + case 'W' -> position.set(Position.KEY_ALARM, + decodeAlarm(Integer.parseInt(data.readSlice(2).toString(StandardCharsets.US_ASCII)))); + case 'X' -> { String[] cells = data.toString(StandardCharsets.US_ASCII).split(";"); if (!cells[0].startsWith("(")) { for (int i = 0; i < cells.length; i++) { @@ -285,8 +265,8 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { } position.setNetwork(network); } - break; - case 'Y': + } + case 'Y' -> { stringValue = data.toString(StandardCharsets.US_ASCII); count = Integer.parseInt(stringValue.substring(0, 1)); if (stringValue.length() == 6 + count * 14) { @@ -298,24 +278,20 @@ public class UproProtocolDecoder extends BaseProtocolDecoder { mcc, mnc, Integer.parseInt(stringValue.substring(offset, offset + 4), 16), Long.parseLong(stringValue.substring(offset + 4, offset + 12), 16), - Integer.parseInt(stringValue.substring(offset + 12, offset + 14)))); + Integer.parseInt(stringValue.substring(offset + 12, offset + 14), 16))); } } else { position.set(Position.KEY_POWER, Integer.parseInt(data.readSlice(5).toString(StandardCharsets.US_ASCII)) * 0.001); } - break; - case 'b': + } + case 'b' -> { if (data.readableBytes() > 3) { position.set("serial", data.toString(StandardCharsets.US_ASCII).substring(3)); } - break; - case 'd': - position.set(Position.PREFIX_ADC + 1, - Integer.parseInt(data.toString(StandardCharsets.US_ASCII)) / 100.0); - break; - default: - break; + } + case 'd' -> position.set(Position.PREFIX_ADC + 1, + Integer.parseInt(data.toString(StandardCharsets.US_ASCII)) / 100.0); } } diff --git a/src/main/java/org/traccar/protocol/VltProtocolDecoder.java b/src/main/java/org/traccar/protocol/VltProtocolDecoder.java index 01c0563f5..40fb5eef7 100644 --- a/src/main/java/org/traccar/protocol/VltProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/VltProtocolDecoder.java @@ -121,19 +121,18 @@ public class VltProtocolDecoder extends BaseHttpProtocolDecoder { sendResponse(channel, HttpResponseStatus.OK); - switch (type) { - case "NRM": - return decodePosition(deviceSession, sentence.substring(3 + 15)); - case "BTH": + return switch (type) { + case "NRM" -> decodePosition(deviceSession, sentence.substring(3 + 15)); + case "BTH" -> { List<Position> positions = new LinkedList<>(); int count = Integer.parseInt(sentence.substring(index, index += 3)); for (int i = 0; i < count; i++) { positions.add(decodePosition(deviceSession, sentence.substring(index, index += 78))); } - return positions; - default: - return null; - } + yield positions; + } + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/VtfmsProtocolDecoder.java b/src/main/java/org/traccar/protocol/VtfmsProtocolDecoder.java index bf0cdcb51..36cc98df9 100644 --- a/src/main/java/org/traccar/protocol/VtfmsProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/VtfmsProtocolDecoder.java @@ -77,20 +77,14 @@ public class VtfmsProtocolDecoder extends BaseProtocolDecoder { .compile(); private String decodeAlarm(int value) { - switch (value) { - case 10: - return Position.ALARM_OVERSPEED; - case 14: - return Position.ALARM_POWER_CUT; - case 15: - return Position.ALARM_POWER_RESTORED; - case 32: - return Position.ALARM_BRAKING; - case 33: - return Position.ALARM_ACCELERATION; - default: - return null; - } + return switch (value) { + case 10 -> Position.ALARM_OVERSPEED; + case 14 -> Position.ALARM_POWER_CUT; + case 15 -> Position.ALARM_POWER_RESTORED; + case 32 -> Position.ALARM_BRAKING; + case 33 -> Position.ALARM_ACCELERATION; + default -> null; + }; } private double convertToDegrees(double value) { diff --git a/src/main/java/org/traccar/protocol/WatchFrameDecoder.java b/src/main/java/org/traccar/protocol/WatchFrameDecoder.java index 9dfae8726..992cb02ab 100644 --- a/src/main/java/org/traccar/protocol/WatchFrameDecoder.java +++ b/src/main/java/org/traccar/protocol/WatchFrameDecoder.java @@ -32,14 +32,8 @@ public class WatchFrameDecoder extends BaseFrameDecoder { for (int i = buf.readerIndex(); i < buf.writerIndex(); i++) { byte b = buf.getByte(i); switch (b) { - case '[': - brackets += 1; - break; - case ']': - brackets -= 1; - break; - default: - break; + case '[' -> brackets += 1; + case ']' -> brackets -= 1; } if (brackets == 0 && i > buf.readerIndex()) { endIndex = i + 1; @@ -54,24 +48,13 @@ public class WatchFrameDecoder extends BaseFrameDecoder { if (b1 == '}') { byte b2 = buf.readByte(); switch (b2) { - case 0x01: - frame.writeByte('}'); - break; - case 0x02: - frame.writeByte('['); - break; - case 0x03: - frame.writeByte(']'); - break; - case 0x04: - frame.writeByte(','); - break; - case 0x05: - frame.writeByte('*'); - break; - default: - throw new IllegalArgumentException(String.format( - "unexpected byte at %d: 0x%02x", buf.readerIndex() - 1, b2)); + case 0x01 -> frame.writeByte('}'); + case 0x02 -> frame.writeByte('['); + case 0x03 -> frame.writeByte(']'); + case 0x04 -> frame.writeByte(','); + case 0x05 -> frame.writeByte('*'); + default -> throw new IllegalArgumentException( + String.format("unexpected byte at %d: 0x%02x", buf.readerIndex() - 1, b2)); } } else { frame.writeByte(b1); diff --git a/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java b/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java index 14ebe2852..2911d423a 100644 --- a/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/WatchProtocolEncoder.java @@ -134,42 +134,28 @@ public class WatchProtocolEncoder extends StringProtocolEncoder implements Strin @Override protected Object encodeCommand(Channel channel, Command command) { - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return formatTextCommand(channel, command, command.getString(Command.KEY_DATA)); - case Command.TYPE_POSITION_SINGLE: - return formatTextCommand(channel, command, "CR"); - case Command.TYPE_SOS_NUMBER: - return formatTextCommand(channel, command, "SOS%s,%s", Command.KEY_INDEX, Command.KEY_PHONE); - case Command.TYPE_ALARM_SOS: - return formatTextCommand(channel, command, "SOSSMS,%s", Command.KEY_ENABLE); - case Command.TYPE_ALARM_BATTERY: - return formatTextCommand(channel, command, "LOWBAT,%s", Command.KEY_ENABLE); - case Command.TYPE_REBOOT_DEVICE: - return formatTextCommand(channel, command, "RESET"); - case Command.TYPE_POWER_OFF: - return formatTextCommand(channel, command, "POWEROFF"); - case Command.TYPE_ALARM_REMOVE: - return formatTextCommand(channel, command, "REMOVE,%s", Command.KEY_ENABLE); - case Command.TYPE_SILENCE_TIME: - return formatTextCommand(channel, command, "SILENCETIME,%s", Command.KEY_DATA); - case Command.TYPE_ALARM_CLOCK: - return formatTextCommand(channel, command, "REMIND,%s", Command.KEY_DATA); - case Command.TYPE_SET_PHONEBOOK: - return formatTextCommand(channel, command, "PHB,%s", Command.KEY_DATA); - case Command.TYPE_MESSAGE: - return formatTextCommand(channel, command, "MESSAGE,%s", Command.KEY_MESSAGE); - case Command.TYPE_VOICE_MESSAGE: - return formatBinaryCommand(channel, command, "TK,", getBinaryData(command)); - case Command.TYPE_POSITION_PERIODIC: - return formatTextCommand(channel, command, "UPLOAD,%s", Command.KEY_FREQUENCY); - case Command.TYPE_SET_TIMEZONE: - return formatTextCommand(channel, command, "LZ,%s,%s", Command.KEY_LANGUAGE, Command.KEY_TIMEZONE); - case Command.TYPE_SET_INDICATOR: - return formatTextCommand(channel, command, "FLOWER,%s", Command.KEY_DATA); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_CUSTOM -> formatTextCommand(channel, command, command.getString(Command.KEY_DATA)); + case Command.TYPE_POSITION_SINGLE -> formatTextCommand(channel, command, "CR"); + case Command.TYPE_SOS_NUMBER -> + formatTextCommand(channel, command, "SOS%s,%s", Command.KEY_INDEX, Command.KEY_PHONE); + case Command.TYPE_ALARM_SOS -> formatTextCommand(channel, command, "SOSSMS,%s", Command.KEY_ENABLE); + case Command.TYPE_ALARM_BATTERY -> formatTextCommand(channel, command, "LOWBAT,%s", Command.KEY_ENABLE); + case Command.TYPE_REBOOT_DEVICE -> formatTextCommand(channel, command, "RESET"); + case Command.TYPE_POWER_OFF -> formatTextCommand(channel, command, "POWEROFF"); + case Command.TYPE_ALARM_REMOVE -> formatTextCommand(channel, command, "REMOVE,%s", Command.KEY_ENABLE); + case Command.TYPE_SILENCE_TIME -> formatTextCommand(channel, command, "SILENCETIME,%s", Command.KEY_DATA); + case Command.TYPE_ALARM_CLOCK -> formatTextCommand(channel, command, "REMIND,%s", Command.KEY_DATA); + case Command.TYPE_SET_PHONEBOOK -> formatTextCommand(channel, command, "PHB,%s", Command.KEY_DATA); + case Command.TYPE_MESSAGE -> formatTextCommand(channel, command, "MESSAGE,%s", Command.KEY_MESSAGE); + case Command.TYPE_VOICE_MESSAGE -> formatBinaryCommand(channel, command, "TK,", getBinaryData(command)); + case Command.TYPE_POSITION_PERIODIC -> + formatTextCommand(channel, command, "UPLOAD,%s", Command.KEY_FREQUENCY); + case Command.TYPE_SET_TIMEZONE -> + formatTextCommand(channel, command, "LZ,%s,%s", Command.KEY_LANGUAGE, Command.KEY_TIMEZONE); + case Command.TYPE_SET_INDICATOR -> formatTextCommand(channel, command, "FLOWER,%s", Command.KEY_DATA); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/WialonProtocolEncoder.java b/src/main/java/org/traccar/protocol/WialonProtocolEncoder.java index 93086bf8a..7712f3cfc 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/WialonProtocolEncoder.java @@ -28,18 +28,14 @@ public class WialonProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_REBOOT_DEVICE: - return formatCommand(command, "reboot\r\n"); - case Command.TYPE_SEND_USSD: - return formatCommand(command, "USSD:%s\r\n", Command.KEY_PHONE); - case Command.TYPE_IDENTIFICATION: - return formatCommand(command, "VER?\r\n"); - case Command.TYPE_OUTPUT_CONTROL: - return formatCommand(command, "L%s=%s\r\n", Command.KEY_INDEX, Command.KEY_DATA); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_REBOOT_DEVICE -> formatCommand(command, "reboot\r\n"); + case Command.TYPE_SEND_USSD -> formatCommand(command, "USSD:%s\r\n", Command.KEY_PHONE); + case Command.TYPE_IDENTIFICATION -> formatCommand(command, "VER?\r\n"); + case Command.TYPE_OUTPUT_CONTROL -> + formatCommand(command, "L%s=%s\r\n", Command.KEY_INDEX, Command.KEY_DATA); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/WliProtocolDecoder.java b/src/main/java/org/traccar/protocol/WliProtocolDecoder.java index ec1c4d17a..a01cdb0cf 100644 --- a/src/main/java/org/traccar/protocol/WliProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WliProtocolDecoder.java @@ -99,54 +99,28 @@ public class WliProtocolDecoder extends BaseProtocolDecoder { String value = buf.readCharSequence( endIndex - buf.readerIndex(), StandardCharsets.US_ASCII).toString(); - int networkFieldsOffset; - switch (type) { - case 0xE4: - networkFieldsOffset = 10; - break; - case 0xCB: - networkFieldsOffset = 80; - break; - case 0x1E: - networkFieldsOffset = 182; - break; - case 0xC9: - default: - networkFieldsOffset = 35; - break; - } + int networkFieldsOffset = switch (type) { + case 0xE4 -> 10; + case 0xCB -> 80; + case 0x1E -> 182; + default -> 35; + }; if (fieldNumber - networkFieldsOffset >= 0 && fieldNumber - networkFieldsOffset < 10) { switch (fieldNumber - networkFieldsOffset) { - case 0: - cellTower.setMobileCountryCode(Integer.parseInt(value)); - break; - case 1: - cellTower.setMobileNetworkCode(Integer.parseInt(value)); - break; - case 2: - cellTower.setLocationAreaCode(Integer.parseInt(value)); - break; - case 3: - cellTower.setCellId(Long.parseLong(value)); - break; - case 4: - cellTower.setSignalStrength(Integer.parseInt(value)); - break; - default: - break; + case 0 -> cellTower.setMobileCountryCode(Integer.parseInt(value)); + case 1 -> cellTower.setMobileNetworkCode(Integer.parseInt(value)); + case 2 -> cellTower.setLocationAreaCode(Integer.parseInt(value)); + case 3 -> cellTower.setCellId(Long.parseLong(value)); + case 4 -> cellTower.setSignalStrength(Integer.parseInt(value)); } } else { switch (fieldNumber) { - case 246: + case 246 -> { String[] values = value.split(","); position.set(Position.KEY_POWER, Integer.parseInt(values[2]) * 0.01); position.set(Position.KEY_BATTERY, Integer.parseInt(values[3]) * 0.01); - break; - case 255: - position.setDeviceTime(new Date(Long.parseLong(value) * 1000)); - break; - default: - break; + } + case 255 -> position.setDeviceTime(new Date(Long.parseLong(value) * 1000)); } } diff --git a/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java b/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java index fb213dc40..035a5d2d3 100644 --- a/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/WondexProtocolEncoder.java @@ -30,22 +30,16 @@ public class WondexProtocolEncoder extends StringProtocolEncoder { initDevicePassword(command, "0000"); - switch (command.getType()) { - case Command.TYPE_REBOOT_DEVICE: - return formatCommand(command, "$WP+REBOOT=%s", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_GET_DEVICE_STATUS: - return formatCommand(command, "$WP+TEST=%s", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_GET_MODEM_STATUS: - return formatCommand(command, "$WP+GSMINFO=%s", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_IDENTIFICATION: - return formatCommand(command, "$WP+IMEI=%s", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, "$WP+GETLOCATION=%s", Command.KEY_DEVICE_PASSWORD); - case Command.TYPE_GET_VERSION: - return formatCommand(command, "$WP+VER=%s", Command.KEY_DEVICE_PASSWORD); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_REBOOT_DEVICE -> formatCommand(command, "$WP+REBOOT=%s", Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_GET_DEVICE_STATUS -> formatCommand(command, "$WP+TEST=%s", Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_GET_MODEM_STATUS -> formatCommand(command, "$WP+GSMINFO=%s", Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_IDENTIFICATION -> formatCommand(command, "$WP+IMEI=%s", Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_POSITION_SINGLE -> + formatCommand(command, "$WP+GETLOCATION=%s", Command.KEY_DEVICE_PASSWORD); + case Command.TYPE_GET_VERSION -> formatCommand(command, "$WP+VER=%s", Command.KEY_DEVICE_PASSWORD); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/WristbandProtocolDecoder.java b/src/main/java/org/traccar/protocol/WristbandProtocolDecoder.java index 323992ddd..f8cfe2b5e 100644 --- a/src/main/java/org/traccar/protocol/WristbandProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WristbandProtocolDecoder.java @@ -155,31 +155,22 @@ public class WristbandProtocolDecoder extends BaseProtocolDecoder { String data = parser.next(); switch (type) { - case 90: - sendResponse(channel, imei, version, type, getServer(channel, ',')); - break; - case 91: + case 90 -> sendResponse(channel, imei, version, type, getServer(channel, ',')); + case 91 -> { String time = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()); sendResponse(channel, imei, version, type, time + "|" + getServer(channel, ',')); - break; - case 1: + } + case 1 -> { positions.add(decodeStatus(deviceSession, data)); sendResponse(channel, imei, version, type, data.split(",")[1]); - break; - case 2: + } + case 2 -> { for (String fragment : data.split("\\|")) { positions.add(decodePosition(deviceSession, fragment)); } - break; - case 3: - case 4: - positions.add(decodeNetwork(deviceSession, data, type == 3)); - break; - case 64: - sendResponse(channel, imei, version, type, data); - break; - default: - break; + } + case 3, 4 -> positions.add(decodeNetwork(deviceSession, data, type == 3)); + case 64 -> sendResponse(channel, imei, version, type, data); } return positions.isEmpty() ? null : positions; diff --git a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java index 8f3fa5672..f08e60a67 100644 --- a/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Xexun2ProtocolEncoder.java @@ -52,19 +52,14 @@ public class Xexun2ProtocolEncoder extends BaseProtocolEncoder { protected Object encodeCommand(Command command) { String uniqueId = getUniqueId(command.getDeviceId()); - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return encodeContent(uniqueId, command.getString(Command.KEY_DATA)); - case Command.TYPE_POSITION_PERIODIC: - return encodeContent(uniqueId, - String.format("tracking_send=%1$d,%1$d", command.getInteger(Command.KEY_FREQUENCY))); - case Command.TYPE_POWER_OFF: - return encodeContent(uniqueId, "of=1"); - case Command.TYPE_REBOOT_DEVICE: - return encodeContent(uniqueId, "reset"); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_CUSTOM -> encodeContent(uniqueId, command.getString(Command.KEY_DATA)); + case Command.TYPE_POSITION_PERIODIC -> encodeContent( + uniqueId, String.format("tracking_send=%1$d,%1$d", command.getInteger(Command.KEY_FREQUENCY))); + case Command.TYPE_POWER_OFF -> encodeContent(uniqueId, "of=1"); + case Command.TYPE_REBOOT_DEVICE -> encodeContent(uniqueId, "reset"); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/XexunProtocolDecoder.java b/src/main/java/org/traccar/protocol/XexunProtocolDecoder.java index e41d467d5..5d8507543 100644 --- a/src/main/java/org/traccar/protocol/XexunProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/XexunProtocolDecoder.java @@ -65,33 +65,16 @@ public class XexunProtocolDecoder extends BaseProtocolDecoder { .any() .compile(); - private String decodeStatus(Position position, String value) { + private void decodeStatus(Position position, String value) { if (value != null) { switch (value.toLowerCase()) { - case "acc on": - case "accstart": - position.set(Position.KEY_IGNITION, true); - break; - case "acc off": - case "accstop": - position.set(Position.KEY_IGNITION, false); - break; - case "help me!": - case "help me": - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - break; - case "low battery": - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - case "move!": - case "moved!": - position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); - break; - default: - break; + case "acc on", "accstart" -> position.set(Position.KEY_IGNITION, true); + case "acc off", "accstop" -> position.set(Position.KEY_IGNITION, false); + case "help me!", "help me" -> position.set(Position.KEY_ALARM, Position.ALARM_SOS); + case "low battery" -> position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + case "move!", "moved!" -> position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); } } - return null; } @Override diff --git a/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java b/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java index 220c28054..56681bb40 100644 --- a/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/XirgoProtocolDecoder.java @@ -116,63 +116,22 @@ public class XirgoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_EVENT, event); switch (event) { - case 4001: - case 4003: - case 6011: - case 6013: - position.set(Position.KEY_IGNITION, true); - break; - case 4002: - case 4004: - case 6012: - case 6014: - position.set(Position.KEY_IGNITION, false); - break; - case 4005: - position.set(Position.KEY_CHARGE, false); - break; - case 6002: - position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); - break; - case 6006: - position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); - break; - case 6007: - position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); - break; - case 6008: - position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); - break; - case 6009: - position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); - break; - case 6010: - position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED); - break; - case 6016: - position.set(Position.KEY_ALARM, Position.ALARM_IDLE); - break; - case 6017: - position.set(Position.KEY_ALARM, Position.ALARM_TOW); - break; - case 6030: - case 6071: - position.set(Position.KEY_MOTION, true); - break; - case 6031: - position.set(Position.KEY_MOTION, false); - break; - case 6032: - position.set(Position.KEY_ALARM, Position.ALARM_PARKING); - break; - case 6090: - position.set(Position.KEY_ALARM, Position.ALARM_REMOVING); - break; - case 6091: - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - default: - break; + case 4001, 4003, 6011, 6013 -> position.set(Position.KEY_IGNITION, true); + case 4002, 4004, 6012, 6014 -> position.set(Position.KEY_IGNITION, false); + case 4005 -> position.set(Position.KEY_CHARGE, false); + case 6002 -> position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED); + case 6006 -> position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + case 6007 -> position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); + case 6008 -> position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); + case 6009 -> position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); + case 6010 -> position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED); + case 6016 -> position.set(Position.KEY_ALARM, Position.ALARM_IDLE); + case 6017 -> position.set(Position.KEY_ALARM, Position.ALARM_TOW); + case 6030, 6071 -> position.set(Position.KEY_MOTION, true); + case 6031 -> position.set(Position.KEY_MOTION, false); + case 6032 -> position.set(Position.KEY_ALARM, Position.ALARM_PARKING); + case 6090 -> position.set(Position.KEY_ALARM, Position.ALARM_REMOVING); + case 6091 -> position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); } } @@ -213,76 +172,49 @@ public class XirgoProtocolDecoder extends BaseProtocolDecoder { for (int i = 0; i < keys.length; i++) { switch (keys[i]) { - case "UID": - case "IM": + case "UID", "IM" -> { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[i]); if (deviceSession != null) { position.setDeviceId(deviceSession.getDeviceId()); } - break; - case "EV": - decodeEvent(position, Integer.parseInt(values[i])); - break; - case "D": + } + case "EV" -> decodeEvent(position, Integer.parseInt(values[i])); + case "D" -> { String[] date = values[i].split("/"); dateBuilder.setMonth(Integer.parseInt(date[0])); dateBuilder.setDay(Integer.parseInt(date[1])); dateBuilder.setYear(Integer.parseInt(date[2])); - break; - case "T": + } + case "T" -> { String[] time = values[i].split(":"); dateBuilder.setHour(Integer.parseInt(time[0])); dateBuilder.setMinute(Integer.parseInt(time[1])); dateBuilder.setSecond(Integer.parseInt(time[2])); - break; - case "LT": - position.setLatitude(Double.parseDouble(values[i])); - break; - case "LN": - position.setLongitude(Double.parseDouble(values[i])); - break; - case "AL": - position.setAltitude(Integer.parseInt(values[i])); - break; - case "GSPT": - position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[i]))); - break; - case "HD": + } + case "LT" -> position.setLatitude(Double.parseDouble(values[i])); + case "LN" -> position.setLongitude(Double.parseDouble(values[i])); + case "AL" -> position.setAltitude(Integer.parseInt(values[i])); + case "GSPT" -> position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[i]))); + case "HD" -> { if (values[i].contains(".")) { position.setCourse(Double.parseDouble(values[i])); } else { position.setCourse(Integer.parseInt(values[i]) * 0.1); } - break; - case "SV": - position.set(Position.KEY_SATELLITES, Integer.parseInt(values[i])); - break; - case "BV": - position.set(Position.KEY_BATTERY, Double.parseDouble(values[i])); - break; - case "CQ": - position.set(Position.KEY_RSSI, Integer.parseInt(values[i])); - break; - case "MI": - position.set(Position.KEY_ODOMETER, Integer.parseInt(values[i])); - break; - case "GS": - position.setValid(Integer.parseInt(values[i]) == 3); - break; - case "SI": - position.set(Position.KEY_ICCID, values[i]); - break; - case "IG": + } + case "SV" -> position.set(Position.KEY_SATELLITES, Integer.parseInt(values[i])); + case "BV" -> position.set(Position.KEY_BATTERY, Double.parseDouble(values[i])); + case "CQ" -> position.set(Position.KEY_RSSI, Integer.parseInt(values[i])); + case "MI" -> position.set(Position.KEY_ODOMETER, Integer.parseInt(values[i])); + case "GS" -> position.setValid(Integer.parseInt(values[i]) == 3); + case "SI" -> position.set(Position.KEY_ICCID, values[i]); + case "IG" -> { int ignition = Integer.parseInt(values[i]); if (ignition > 0) { position.set(Position.KEY_IGNITION, ignition == 1); } - break; - case "OT": - position.set(Position.KEY_OUTPUT, Integer.parseInt(values[i])); - break; - default: - break; + } + case "OT" -> position.set(Position.KEY_OUTPUT, Integer.parseInt(values[i])); } } diff --git a/src/main/java/org/traccar/protocol/XirgoProtocolEncoder.java b/src/main/java/org/traccar/protocol/XirgoProtocolEncoder.java index aa85e9e0e..76ec03d7a 100644 --- a/src/main/java/org/traccar/protocol/XirgoProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/XirgoProtocolEncoder.java @@ -28,12 +28,11 @@ public class XirgoProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Command command) { - switch (command.getType()) { - case Command.TYPE_OUTPUT_CONTROL: - return String.format("+XT:7005,%d,1", command.getInteger(Command.KEY_DATA) + 1); - default: - return null; - } + return switch (command.getType()) { + case Command.TYPE_OUTPUT_CONTROL -> + String.format("+XT:7005,%d,1", command.getInteger(Command.KEY_DATA) + 1); + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/Xrb28ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xrb28ProtocolDecoder.java index 6033293c4..4f915af15 100644 --- a/src/main/java/org/traccar/protocol/Xrb28ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xrb28ProtocolDecoder.java @@ -119,56 +119,33 @@ public class Xrb28ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); switch (type) { - case "Q0": + case "Q0" -> { position.set(Position.KEY_BATTERY, Integer.parseInt(values[index++]) * 0.01); position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(values[index++])); position.set(Position.KEY_RSSI, Integer.parseInt(values[index++])); - break; - case "H0": + } + case "H0" -> { position.set(Position.KEY_BLOCKED, Integer.parseInt(values[index++]) > 0); position.set(Position.KEY_BATTERY, Integer.parseInt(values[index++]) * 0.01); position.set(Position.KEY_RSSI, Integer.parseInt(values[index++])); position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(values[index++])); - break; - case "W0": + } + case "W0" -> { switch (Integer.parseInt(values[index++])) { - case 1: - position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); - break; - case 2: - position.set(Position.KEY_ALARM, Position.ALARM_FALL_DOWN); - break; - case 3: - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - default: - break; + case 1 -> position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); + case 2 -> position.set(Position.KEY_ALARM, Position.ALARM_FALL_DOWN); + case 3 -> position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); } - break; - case "E0": + } + case "E0" -> { position.set(Position.KEY_ALARM, Position.ALARM_FAULT); position.set("error", Integer.parseInt(values[index++])); - break; - case "S1": - position.set(Position.KEY_EVENT, Integer.parseInt(values[index++])); - break; - case "R0": - case "L0": - case "L1": - case "S4": - case "S5": - case "S6": - case "S7": - case "V0": - case "G0": - case "K0": - case "I0": - case "M0": + } + case "S1" -> position.set(Position.KEY_EVENT, Integer.parseInt(values[index++])); + case "R0", "L0", "L1", "S4", "S5", "S6", "S7", "V0", "G0", "K0", "I0", "M0" -> { String[] remaining = Arrays.copyOfRange(values, index, values.length); position.set(Position.KEY_RESULT, String.join(",", remaining)); - break; - default: - break; + } } return !position.getAttributes().isEmpty() ? position : null; diff --git a/src/main/java/org/traccar/protocol/Xrb28ProtocolEncoder.java b/src/main/java/org/traccar/protocol/Xrb28ProtocolEncoder.java index 3e69af329..cdb55c310 100644 --- a/src/main/java/org/traccar/protocol/Xrb28ProtocolEncoder.java +++ b/src/main/java/org/traccar/protocol/Xrb28ProtocolEncoder.java @@ -33,25 +33,22 @@ public class Xrb28ProtocolEncoder extends BaseProtocolEncoder { @Override protected Object encodeCommand(Channel channel, Command command) { - switch (command.getType()) { - case Command.TYPE_CUSTOM: - return formatCommand(command, command.getString(Command.KEY_DATA)); - case Command.TYPE_POSITION_SINGLE: - return formatCommand(command, "D0"); - case Command.TYPE_POSITION_PERIODIC: - return formatCommand(command, "D1," + command.getInteger(Command.KEY_FREQUENCY)); - case Command.TYPE_ENGINE_STOP: - case Command.TYPE_ALARM_DISARM: + return switch (command.getType()) { + case Command.TYPE_CUSTOM -> formatCommand(command, command.getString(Command.KEY_DATA)); + case Command.TYPE_POSITION_SINGLE -> formatCommand(command, "D0"); + case Command.TYPE_POSITION_PERIODIC -> + formatCommand(command, "D1," + command.getInteger(Command.KEY_FREQUENCY)); + case Command.TYPE_ENGINE_STOP, Command.TYPE_ALARM_DISARM -> { if (channel != null) { Xrb28ProtocolDecoder decoder = channel.pipeline().get(Xrb28ProtocolDecoder.class); if (decoder != null) { decoder.setPendingCommand(command.getType()); } } - return formatCommand(command, "R0,0,20,1234," + System.currentTimeMillis() / 1000); - default: - return null; - } + yield formatCommand(command, "R0,0,20,1234," + System.currentTimeMillis() / 1000); + } + default -> null; + }; } } diff --git a/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java index 11f9e0654..ce097740a 100644 --- a/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Xt2400ProtocolDecoder.java @@ -126,76 +126,41 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder { for (byte b : format) { int tag = b & 0xFF; switch (tag) { - case 0x03: + case 0x03 -> { DeviceSession deviceSession = getDeviceSession( channel, remoteAddress, String.valueOf(buf.readUnsignedInt())); if (deviceSession == null) { return null; } position.setDeviceId(deviceSession.getDeviceId()); - break; - case 0x04: - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); - break; - case 0x05: - position.set(Position.KEY_INDEX, buf.readUnsignedShort()); - break; - case 0x06: - position.setTime(new Date(buf.readUnsignedInt() * 1000)); - break; - case 0x07: - position.setLatitude(buf.readInt() * 0.000001); - break; - case 0x08: - position.setLongitude(buf.readInt() * 0.000001); - break; - case 0x09: - position.setAltitude(buf.readShort() * 0.1); - break; - case 0x0a: - position.setCourse(buf.readShort() * 0.1); - break; - case 0x0b: - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); - break; - case 0x10: - position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedInt()); - break; - case 0x12: - position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); - break; - case 0x13: - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - break; - case 0x14: - position.set(Position.KEY_RSSI, buf.readShort()); - break; - case 0x16: - position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 0.1); - break; - case 0x17: - position.set(Position.KEY_POWER, buf.readUnsignedByte() * 0.1); - break; - case 0x57: - position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort()); - break; - case 0x65: - position.set(Position.KEY_VIN, buf.readSlice(17).toString(StandardCharsets.US_ASCII)); - break; - case 0x6C: + } + case 0x04 -> position.set(Position.KEY_EVENT, buf.readUnsignedByte()); + case 0x05 -> position.set(Position.KEY_INDEX, buf.readUnsignedShort()); + case 0x06 -> position.setTime(new Date(buf.readUnsignedInt() * 1000)); + case 0x07 -> position.setLatitude(buf.readInt() * 0.000001); + case 0x08 -> position.setLongitude(buf.readInt() * 0.000001); + case 0x09 -> position.setAltitude(buf.readShort() * 0.1); + case 0x0a -> position.setCourse(buf.readShort() * 0.1); + case 0x0b -> position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte())); + case 0x10 -> position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedInt()); + case 0x12 -> position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); + case 0x13 -> position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + case 0x14 -> position.set(Position.KEY_RSSI, buf.readShort()); + case 0x16 -> position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 0.1); + case 0x17 -> position.set(Position.KEY_POWER, buf.readUnsignedByte() * 0.1); + case 0x57 -> position.set(Position.KEY_OBD_SPEED, buf.readUnsignedShort()); + case 0x65 -> position.set(Position.KEY_VIN, buf.readSlice(17).toString(StandardCharsets.US_ASCII)); + case 0x6C -> { buf.readUnsignedByte(); // mil int ecuCount = buf.readUnsignedByte(); for (int i = 0; i < ecuCount; i++) { buf.readUnsignedByte(); // ecu id buf.skipBytes(buf.readUnsignedByte() * 6); } - break; - case 0x73: - position.set(Position.KEY_VERSION_FW, buf.readSlice(16).toString(StandardCharsets.US_ASCII).trim()); - break; - default: - buf.skipBytes(getTagLength(tag)); - break; + } + case 0x73 -> position.set( + Position.KEY_VERSION_FW, buf.readSlice(16).toString(StandardCharsets.US_ASCII).trim()); + default -> buf.skipBytes(getTagLength(tag)); } } diff --git a/src/main/java/org/traccar/schedule/ScheduleManager.java b/src/main/java/org/traccar/schedule/ScheduleManager.java index 742428fd8..fd8171148 100644 --- a/src/main/java/org/traccar/schedule/ScheduleManager.java +++ b/src/main/java/org/traccar/schedule/ScheduleManager.java @@ -20,6 +20,9 @@ import org.traccar.LifecycleObject; import jakarta.inject.Inject; import jakarta.inject.Singleton; +import org.traccar.config.Config; +import org.traccar.config.Keys; + import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.stream.Stream; @@ -28,11 +31,13 @@ import java.util.stream.Stream; public class ScheduleManager implements LifecycleObject { private final Injector injector; + private final boolean secondary; private ScheduledExecutorService executor; @Inject - public ScheduleManager(Injector injector) { + public ScheduleManager(Injector injector, Config config) { this.injector = injector; + secondary = config.getBoolean(Keys.BROADCAST_SECONDARY); } @Override @@ -46,7 +51,12 @@ public class ScheduleManager implements LifecycleObject { TaskReports.class, TaskDeviceInactivityCheck.class, TaskWebSocketKeepalive.class) - .forEachOrdered(task -> injector.getInstance(task).schedule(executor)); + .forEachOrdered(taskClass -> { + var task = injector.getInstance(taskClass); + if (task.multipleInstances() || !secondary) { + task.schedule(executor); + } + }); } @Override diff --git a/src/main/java/org/traccar/schedule/ScheduleTask.java b/src/main/java/org/traccar/schedule/ScheduleTask.java index 1b537213b..a2a31ac4f 100644 --- a/src/main/java/org/traccar/schedule/ScheduleTask.java +++ b/src/main/java/org/traccar/schedule/ScheduleTask.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2022 - 2024 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,5 +18,10 @@ package org.traccar.schedule; import java.util.concurrent.ScheduledExecutorService; public interface ScheduleTask extends Runnable { + + default boolean multipleInstances() { + return true; + } + void schedule(ScheduledExecutorService executor); } diff --git a/src/main/java/org/traccar/schedule/SingleScheduleTask.java b/src/main/java/org/traccar/schedule/SingleScheduleTask.java new file mode 100644 index 000000000..a0f1deee4 --- /dev/null +++ b/src/main/java/org/traccar/schedule/SingleScheduleTask.java @@ -0,0 +1,23 @@ +/* + * Copyright 2024 Anton Tananaev (anton@traccar.org) + * + * 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.schedule; + +public abstract class SingleScheduleTask implements ScheduleTask { + @Override + public boolean multipleInstances() { + return false; + } +} diff --git a/src/main/java/org/traccar/schedule/TaskDeleteTemporary.java b/src/main/java/org/traccar/schedule/TaskDeleteTemporary.java index 0cead59fb..eb49b7e46 100644 --- a/src/main/java/org/traccar/schedule/TaskDeleteTemporary.java +++ b/src/main/java/org/traccar/schedule/TaskDeleteTemporary.java @@ -28,7 +28,7 @@ import java.util.Date; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -public class TaskDeleteTemporary implements ScheduleTask { +public class TaskDeleteTemporary extends SingleScheduleTask { private static final Logger LOGGER = LoggerFactory.getLogger(TaskDeleteTemporary.class); diff --git a/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java b/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java index 8e45568d5..9bc98d8d3 100644 --- a/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java +++ b/src/main/java/org/traccar/schedule/TaskDeviceInactivityCheck.java @@ -34,7 +34,7 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -public class TaskDeviceInactivityCheck implements ScheduleTask { +public class TaskDeviceInactivityCheck extends SingleScheduleTask { private static final Logger LOGGER = LoggerFactory.getLogger(TaskDeviceInactivityCheck.class); diff --git a/src/main/java/org/traccar/schedule/TaskExpirations.java b/src/main/java/org/traccar/schedule/TaskExpirations.java index e16dcd86c..03be0c97f 100644 --- a/src/main/java/org/traccar/schedule/TaskExpirations.java +++ b/src/main/java/org/traccar/schedule/TaskExpirations.java @@ -36,7 +36,7 @@ import org.traccar.storage.query.Request; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -public class TaskExpirations implements ScheduleTask { +public class TaskExpirations extends SingleScheduleTask { private static final Logger LOGGER = LoggerFactory.getLogger(TaskExpirations.class); diff --git a/src/main/java/org/traccar/schedule/TaskHealthCheck.java b/src/main/java/org/traccar/schedule/TaskHealthCheck.java index a60935f18..56ac4b91d 100644 --- a/src/main/java/org/traccar/schedule/TaskHealthCheck.java +++ b/src/main/java/org/traccar/schedule/TaskHealthCheck.java @@ -24,6 +24,8 @@ import org.traccar.config.Keys; import jakarta.inject.Inject; import jakarta.ws.rs.client.Client; +import org.traccar.database.StatisticsManager; + import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -33,6 +35,7 @@ public class TaskHealthCheck implements ScheduleTask { private final Config config; private final Client client; + private final StatisticsManager statisticsManager; private final long gracePeriod = System.currentTimeMillis() + TimeUnit.HOURS.toMillis(1); @@ -40,11 +43,16 @@ public class TaskHealthCheck implements ScheduleTask { private boolean enabled; private long period; + private double dropThreshold; + + private int messageLastTotal; + private int messageLastPeriod; @Inject - public TaskHealthCheck(Config config, Client client) { + public TaskHealthCheck(Config config, Client client, StatisticsManager statisticsManager) { this.config = config; this.client = client; + this.statisticsManager = statisticsManager; if (!config.getBoolean(Keys.WEB_DISABLE_HEALTH_CHECK) && System.getProperty("os.name").toLowerCase().startsWith("linux")) { try { @@ -55,6 +63,7 @@ public class TaskHealthCheck implements ScheduleTask { } if (period > 0) { LOGGER.info("Health check enabled with period {}", period); + dropThreshold = config.getDouble(Keys.WEB_HEALTH_CHECK_DROP_THRESHOLD); enabled = true; } } catch (UnsatisfiedLinkError e) { @@ -80,11 +89,28 @@ public class TaskHealthCheck implements ScheduleTask { public void run() { LOGGER.debug("Health check running"); if (System.currentTimeMillis() > gracePeriod) { + boolean success = true; + int status = client.target(getUrl()).request().get().getStatus(); - if (status == 200) { + if (status != 200) { + success = false; + LOGGER.warn("Web health check failed with status {}", status); + } + + int messageCurrentTotal = statisticsManager.messageStoredCount(); + int messageCurrentPeriod = messageCurrentTotal - messageLastTotal; + if (dropThreshold > 0 && messageLastPeriod > 0) { + double drop = messageCurrentPeriod / (double) messageLastPeriod; + if (drop < dropThreshold) { + success = false; + LOGGER.warn("Message health check failed with drop {}", drop); + } + } + messageLastTotal = messageCurrentTotal; + messageLastPeriod = messageCurrentPeriod; + + if (success) { notifyWatchdog(); - } else { - LOGGER.warn("Health check failed with status {}", status); } } else { notifyWatchdog(); diff --git a/src/main/java/org/traccar/schedule/TaskReports.java b/src/main/java/org/traccar/schedule/TaskReports.java index 070fa9d2b..32f6fea87 100644 --- a/src/main/java/org/traccar/schedule/TaskReports.java +++ b/src/main/java/org/traccar/schedule/TaskReports.java @@ -41,6 +41,8 @@ import org.traccar.storage.query.Condition; import org.traccar.storage.query.Request; import jakarta.inject.Inject; + +import java.time.Instant; import java.util.Collections; import java.util.Date; import java.util.HashSet; @@ -50,7 +52,7 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -public class TaskReports implements ScheduleTask { +public class TaskReports extends SingleScheduleTask { private static final Logger LOGGER = LoggerFactory.getLogger(TaskReports.class); @@ -83,12 +85,12 @@ public class TaskReports implements ScheduleTask { var lastEvents = calendar.findPeriods(lastCheck); var currentEvents = calendar.findPeriods(currentCheck); - Set<Period> finishedEvents = new HashSet<>(lastEvents); + Set<Period<Instant>> finishedEvents = new HashSet<>(lastEvents); finishedEvents.removeAll(currentEvents); - for (Period period : finishedEvents) { + for (Period<Instant> period : finishedEvents) { RequestScoper scope = ServletScopes.scopeRequest(Collections.emptyMap()); try (RequestScoper.CloseableScope ignored = scope.open()) { - executeReport(report, period.getStart(), period.getEnd()); + executeReport(report, Date.from(period.getStart()), Date.from(period.getEnd())); } } } @@ -116,34 +118,32 @@ public class TaskReports implements ScheduleTask { for (User user : users) { LogAction.report(user.getId(), true, report.getType(), from, to, deviceIds, groupIds); switch (report.getType()) { - case "events": + case "events" -> { var eventsReportProvider = injector.getInstance(EventsReportProvider.class); reportMailer.sendAsync(user.getId(), stream -> eventsReportProvider.getExcel( stream, user.getId(), deviceIds, groupIds, List.of(), from, to)); - break; - case "route": + } + case "route" -> { var routeReportProvider = injector.getInstance(RouteReportProvider.class); reportMailer.sendAsync(user.getId(), stream -> routeReportProvider.getExcel( stream, user.getId(), deviceIds, groupIds, from, to)); - break; - case "summary": + } + case "summary" -> { var summaryReportProvider = injector.getInstance(SummaryReportProvider.class); reportMailer.sendAsync(user.getId(), stream -> summaryReportProvider.getExcel( stream, user.getId(), deviceIds, groupIds, from, to, false)); - break; - case "trips": + } + case "trips" -> { var tripsReportProvider = injector.getInstance(TripsReportProvider.class); reportMailer.sendAsync(user.getId(), stream -> tripsReportProvider.getExcel( stream, user.getId(), deviceIds, groupIds, from, to)); - break; - case "stops": + } + case "stops" -> { var stopsReportProvider = injector.getInstance(StopsReportProvider.class); reportMailer.sendAsync(user.getId(), stream -> stopsReportProvider.getExcel( stream, user.getId(), deviceIds, groupIds, from, to)); - break; - default: - LOGGER.warn("Unsupported report type {}", report.getType()); - break; + } + default -> LOGGER.warn("Unsupported report type {}", report.getType()); } } } diff --git a/src/main/java/org/traccar/session/ConnectionKey.java b/src/main/java/org/traccar/session/ConnectionKey.java index 3b7e2ebf8..807e68776 100644 --- a/src/main/java/org/traccar/session/ConnectionKey.java +++ b/src/main/java/org/traccar/session/ConnectionKey.java @@ -18,37 +18,9 @@ package org.traccar.session; import io.netty.channel.Channel; import java.net.SocketAddress; -import java.util.Objects; - -public class ConnectionKey { - - private final SocketAddress localAddress; - private final SocketAddress remoteAddress; +public record ConnectionKey(SocketAddress localAddress, SocketAddress remoteAddress) { public ConnectionKey(Channel channel, SocketAddress remoteAddress) { this(channel.localAddress(), remoteAddress); } - - public ConnectionKey(SocketAddress localAddress, SocketAddress remoteAddress) { - this.localAddress = localAddress; - this.remoteAddress = remoteAddress; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ConnectionKey that = (ConnectionKey) o; - return Objects.equals(localAddress, that.localAddress) && Objects.equals(remoteAddress, that.remoteAddress); - } - - @Override - public int hashCode() { - return Objects.hash(localAddress, remoteAddress); - } - } diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java index 8431a0327..a80c6aad1 100644 --- a/src/main/java/org/traccar/session/ConnectionManager.java +++ b/src/main/java/org/traccar/session/ConnectionManager.java @@ -241,17 +241,11 @@ public class ConnectionManager implements BroadcastInterface { if (!status.equals(oldStatus)) { String eventType; Map<Event, Position> events = new HashMap<>(); - switch (status) { - case Device.STATUS_ONLINE: - eventType = Event.TYPE_DEVICE_ONLINE; - break; - case Device.STATUS_UNKNOWN: - eventType = Event.TYPE_DEVICE_UNKNOWN; - break; - default: - eventType = Event.TYPE_DEVICE_OFFLINE; - break; - } + eventType = switch (status) { + case Device.STATUS_ONLINE -> Event.TYPE_DEVICE_ONLINE; + case Device.STATUS_UNKNOWN -> Event.TYPE_DEVICE_UNKNOWN; + default -> Event.TYPE_DEVICE_OFFLINE; + }; events.put(new Event(eventType, deviceId), null); notificationManager.updateEvents(events); } diff --git a/src/main/java/org/traccar/session/cache/CacheGraph.java b/src/main/java/org/traccar/session/cache/CacheGraph.java index c99997288..a4c2ce61b 100644 --- a/src/main/java/org/traccar/session/cache/CacheGraph.java +++ b/src/main/java/org/traccar/session/cache/CacheGraph.java @@ -38,7 +38,7 @@ public class CacheGraph { CacheKey key = new CacheKey(clazz, id); CacheNode node = nodes.remove(key); if (node != null) { - node.getAllLinks(false).forEach(child -> child.getLinks(key.getClazz(), true).remove(node)); + node.getAllLinks(false).forEach(child -> child.getLinks(key.clazz(), true).remove(node)); } roots.remove(key); } diff --git a/src/main/java/org/traccar/session/cache/CacheKey.java b/src/main/java/org/traccar/session/cache/CacheKey.java index f27d5fbf5..001058e4c 100644 --- a/src/main/java/org/traccar/session/cache/CacheKey.java +++ b/src/main/java/org/traccar/session/cache/CacheKey.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2022 - 2024 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,45 +17,8 @@ package org.traccar.session.cache; import org.traccar.model.BaseModel; -import java.util.Objects; - -class CacheKey { - - private final Class<? extends BaseModel> clazz; - private final long id; - +record CacheKey(Class<? extends BaseModel> clazz, long id) { CacheKey(BaseModel object) { this(object.getClass(), object.getId()); } - - CacheKey(Class<? extends BaseModel> clazz, long id) { - this.clazz = clazz; - this.id = id; - } - - public Class<? extends BaseModel> getClazz() { - return clazz; - } - - public boolean classIs(Class<? extends BaseModel> clazz) { - return clazz.equals(this.clazz); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - CacheKey cacheKey = (CacheKey) o; - return id == cacheKey.id && Objects.equals(clazz, cacheKey.clazz); - } - - @Override - public int hashCode() { - return Objects.hash(clazz, id); - } - } diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java index 064e5672f..39546a5a7 100644 --- a/src/main/java/org/traccar/session/cache/CacheManager.java +++ b/src/main/java/org/traccar/session/cache/CacheManager.java @@ -170,7 +170,7 @@ public class CacheManager implements BroadcastInterface { public void removeDevice(long deviceId) { try { lock.writeLock().lock(); - if (deviceReferences.computeIfAbsent(deviceId, k -> new AtomicInteger()).incrementAndGet() <= 0) { + if (deviceReferences.computeIfAbsent(deviceId, k -> new AtomicInteger()).decrementAndGet() <= 0) { graph.removeObject(Device.class, deviceId); devicePositions.remove(deviceId); deviceReferences.remove(deviceId); @@ -296,8 +296,8 @@ public class CacheManager implements BroadcastInterface { } } } else { - if (object instanceof GroupedModel) { - long groupId = ((GroupedModel) object).getGroupId(); + if (object instanceof GroupedModel groupedModel) { + long groupId = groupedModel.getGroupId(); if (groupId > 0) { invalidatePermission(object.getClass(), object.getId(), Group.class, groupId, true); } @@ -319,8 +319,8 @@ public class CacheManager implements BroadcastInterface { } } - if (object instanceof Schedulable) { - long calendarId = ((Schedulable) object).getCalendarId(); + if (object instanceof Schedulable schedulable) { + long calendarId = schedulable.getCalendarId(); if (calendarId > 0) { invalidatePermission(object.getClass(), object.getId(), Calendar.class, calendarId, true); } diff --git a/src/main/java/org/traccar/storage/DatabaseStorage.java b/src/main/java/org/traccar/storage/DatabaseStorage.java index d20429319..1ff043e77 100644 --- a/src/main/java/org/traccar/storage/DatabaseStorage.java +++ b/src/main/java/org/traccar/storage/DatabaseStorage.java @@ -206,28 +206,23 @@ public class DatabaseStorage extends Storage { private Map<String, Object> getConditionVariables(Condition genericCondition) { Map<String, Object> results = new HashMap<>(); - if (genericCondition instanceof Condition.Compare) { - var condition = (Condition.Compare) genericCondition; + if (genericCondition instanceof Condition.Compare condition) { if (condition.getValue() != null) { results.put(condition.getVariable(), condition.getValue()); } - } else if (genericCondition instanceof Condition.Between) { - var condition = (Condition.Between) genericCondition; + } else if (genericCondition instanceof Condition.Between condition) { results.put(condition.getFromVariable(), condition.getFromValue()); results.put(condition.getToVariable(), condition.getToValue()); - } else if (genericCondition instanceof Condition.Binary) { - var condition = (Condition.Binary) genericCondition; + } else if (genericCondition instanceof Condition.Binary condition) { results.putAll(getConditionVariables(condition.getFirst())); results.putAll(getConditionVariables(condition.getSecond())); - } else if (genericCondition instanceof Condition.Permission) { - var condition = (Condition.Permission) genericCondition; + } else if (genericCondition instanceof Condition.Permission condition) { if (condition.getOwnerId() > 0) { results.put(Permission.getKey(condition.getOwnerClass()), condition.getOwnerId()); } else { results.put(Permission.getKey(condition.getPropertyClass()), condition.getPropertyId()); } - } else if (genericCondition instanceof Condition.LatestPositions) { - var condition = (Condition.LatestPositions) genericCondition; + } else if (genericCondition instanceof Condition.LatestPositions condition) { if (condition.getDeviceId() > 0) { results.put("deviceId", condition.getDeviceId()); } @@ -249,43 +244,38 @@ public class DatabaseStorage extends Storage { if (appendWhere) { result.append(" WHERE "); } - if (genericCondition instanceof Condition.Compare) { + if (genericCondition instanceof Condition.Compare condition) { - var condition = (Condition.Compare) genericCondition; result.append(condition.getColumn()); result.append(" "); result.append(condition.getOperator()); result.append(" :"); result.append(condition.getVariable()); - } else if (genericCondition instanceof Condition.Between) { + } else if (genericCondition instanceof Condition.Between condition) { - var condition = (Condition.Between) genericCondition; result.append(condition.getColumn()); result.append(" BETWEEN :"); result.append(condition.getFromVariable()); result.append(" AND :"); result.append(condition.getToVariable()); - } else if (genericCondition instanceof Condition.Binary) { + } else if (genericCondition instanceof Condition.Binary condition) { - var condition = (Condition.Binary) genericCondition; result.append(formatCondition(condition.getFirst(), false)); result.append(" "); result.append(condition.getOperator()); result.append(" "); result.append(formatCondition(condition.getSecond(), false)); - } else if (genericCondition instanceof Condition.Permission) { + } else if (genericCondition instanceof Condition.Permission condition) { - var condition = (Condition.Permission) genericCondition; result.append("id IN ("); result.append(formatPermissionQuery(condition)); result.append(")"); - } else if (genericCondition instanceof Condition.LatestPositions) { + } else if (genericCondition instanceof Condition.LatestPositions condition) { - var condition = (Condition.LatestPositions) genericCondition; result.append("id IN ("); result.append("SELECT positionId FROM "); result.append(getStorageName(Device.class)); diff --git a/src/main/java/org/traccar/storage/MemoryStorage.java b/src/main/java/org/traccar/storage/MemoryStorage.java index 9b5db1209..1ec8bfe57 100644 --- a/src/main/java/org/traccar/storage/MemoryStorage.java +++ b/src/main/java/org/traccar/storage/MemoryStorage.java @@ -60,54 +60,44 @@ public class MemoryStorage extends Storage { return true; } - if (genericCondition instanceof Condition.Compare) { + if (genericCondition instanceof Condition.Compare condition) { - var condition = (Condition.Compare) genericCondition; Object value = retrieveValue(object, condition.getVariable()); int result = ((Comparable) value).compareTo(condition.getValue()); - switch (condition.getOperator()) { - case "<": - return result < 0; - case "<=": - return result <= 0; - case ">": - return result > 0; - case ">=": - return result >= 0; - case "=": - return result == 0; - default: - throw new RuntimeException("Unsupported comparison condition"); - } + return switch (condition.getOperator()) { + case "<" -> result < 0; + case "<=" -> result <= 0; + case ">" -> result > 0; + case ">=" -> result >= 0; + case "=" -> result == 0; + default -> throw new RuntimeException("Unsupported comparison condition"); + }; - } else if (genericCondition instanceof Condition.Between) { + } else if (genericCondition instanceof Condition.Between condition) { - var condition = (Condition.Between) genericCondition; Object fromValue = retrieveValue(object, condition.getFromVariable()); int fromResult = ((Comparable) fromValue).compareTo(condition.getFromValue()); Object toValue = retrieveValue(object, condition.getToVariable()); int toResult = ((Comparable) toValue).compareTo(condition.getToValue()); return fromResult >= 0 && toResult <= 0; - } else if (genericCondition instanceof Condition.Binary) { + } else if (genericCondition instanceof Condition.Binary condition) { - var condition = (Condition.Binary) genericCondition; if (condition.getOperator().equals("AND")) { return checkCondition(condition.getFirst(), object) && checkCondition(condition.getSecond(), object); } else if (condition.getOperator().equals("OR")) { return checkCondition(condition.getFirst(), object) || checkCondition(condition.getSecond(), object); } - } else if (genericCondition instanceof Condition.Permission) { + } else if (genericCondition instanceof Condition.Permission condition) { - var condition = (Condition.Permission) genericCondition; long id = (Long) retrieveValue(object, "id"); return getPermissionsSet(condition.getOwnerClass(), condition.getPropertyClass()).stream() .anyMatch(pair -> { if (condition.getOwnerId() > 0) { - return pair.getFirst() == condition.getOwnerId() && pair.getSecond() == id; + return pair.first() == condition.getOwnerId() && pair.second() == id; } else { - return pair.getFirst() == id && pair.getSecond() == condition.getPropertyId(); + return pair.first() == id && pair.second() == condition.getPropertyId(); } }); @@ -178,9 +168,9 @@ public class MemoryStorage extends Storage { Class<? extends BaseModel> ownerClass, long ownerId, Class<? extends BaseModel> propertyClass, long propertyId) { return getPermissionsSet(ownerClass, propertyClass).stream() - .filter(pair -> ownerId == 0 || pair.getFirst().equals(ownerId)) - .filter(pair -> propertyId == 0 || pair.getSecond().equals(propertyId)) - .map(pair -> new Permission(ownerClass, pair.getFirst(), propertyClass, pair.getSecond())) + .filter(pair -> ownerId == 0 || pair.first().equals(ownerId)) + .filter(pair -> propertyId == 0 || pair.second().equals(propertyId)) + .map(pair -> new Permission(ownerClass, pair.first(), propertyClass, pair.second())) .collect(Collectors.toList()); } diff --git a/src/main/java/org/traccar/storage/QueryBuilder.java b/src/main/java/org/traccar/storage/QueryBuilder.java index 2f4c07406..6a9c46807 100644 --- a/src/main/java/org/traccar/storage/QueryBuilder.java +++ b/src/main/java/org/traccar/storage/QueryBuilder.java @@ -267,18 +267,18 @@ public final class QueryBuilder { } public QueryBuilder setValue(String name, Object value) throws SQLException { - if (value instanceof Boolean) { - setBoolean(name, (Boolean) value); - } else if (value instanceof Integer) { - setInteger(name, (Integer) value); - } else if (value instanceof Long) { - setLong(name, (Long) value); - } else if (value instanceof Double) { - setDouble(name, (Double) value); - } else if (value instanceof String) { - setString(name, (String) value); - } else if (value instanceof Date) { - setDate(name, (Date) value); + if (value instanceof Boolean booleanValue) { + setBoolean(name, booleanValue); + } else if (value instanceof Integer integerValue) { + setInteger(name, integerValue); + } else if (value instanceof Long longValue) { + setLong(name, longValue); + } else if (value instanceof Double doubleValue) { + setDouble(name, doubleValue); + } else if (value instanceof String stringValue) { + setString(name, stringValue); + } else if (value instanceof Date dateValue) { + setDate(name, dateValue); } return this; } diff --git a/src/test/java/org/traccar/ProtocolTest.java b/src/test/java/org/traccar/ProtocolTest.java index 23ba562f8..1ad192f85 100644 --- a/src/test/java/org/traccar/ProtocolTest.java +++ b/src/test/java/org/traccar/ProtocolTest.java @@ -28,6 +28,7 @@ import java.util.TimeZone; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -117,15 +118,10 @@ public class ProtocolTest extends BaseTest { position = (Position) decodedObject; } switch (key) { - case "speed": - assertEquals(expected, position.getSpeed()); - break; - case "course": - assertEquals(expected, position.getCourse()); - break; - default: - assertEquals(expected, position.getAttributes().get(key)); - break; + case "speed" -> assertEquals(expected, position.getSpeed()); + case "course" -> assertEquals(expected, position.getCourse()); + case "altitude" -> assertEquals(expected, position.getAltitude()); + default -> assertEquals(expected, position.getAttributes().get(key)); } } @@ -156,7 +152,7 @@ public class ProtocolTest extends BaseTest { private void verifyDecodedList(Object decodedObject, boolean checkLocation, Position expected) { assertNotNull(decodedObject, "list is null"); - assertTrue(decodedObject instanceof List, "not a list"); + assertInstanceOf(List.class, decodedObject, "not a list"); assertFalse(((List<?>) decodedObject).isEmpty(), "list is empty"); for (Object item : (List<?>) decodedObject) { @@ -168,7 +164,7 @@ public class ProtocolTest extends BaseTest { private void verifyDecodedPosition(Object decodedObject, boolean checkLocation, boolean checkAttributes, Position expected) { assertNotNull(decodedObject, "position is null"); - assertTrue(decodedObject instanceof Position, "not a position"); + assertInstanceOf(Position.class, decodedObject, "not a position"); Position position = (Position) decodedObject; @@ -222,55 +218,55 @@ public class ProtocolTest extends BaseTest { } if (attributes.containsKey(Position.KEY_INDEX)) { - assertTrue(attributes.get(Position.KEY_INDEX) instanceof Number); + assertInstanceOf(Number.class, attributes.get(Position.KEY_INDEX)); } if (attributes.containsKey(Position.KEY_HDOP)) { - assertTrue(attributes.get(Position.KEY_HDOP) instanceof Number); + assertInstanceOf(Number.class, attributes.get(Position.KEY_HDOP)); } if (attributes.containsKey(Position.KEY_VDOP)) { - assertTrue(attributes.get(Position.KEY_VDOP) instanceof Number); + assertInstanceOf(Number.class, attributes.get(Position.KEY_VDOP)); } if (attributes.containsKey(Position.KEY_PDOP)) { - assertTrue(attributes.get(Position.KEY_PDOP) instanceof Number); + assertInstanceOf(Number.class, attributes.get(Position.KEY_PDOP)); } if (attributes.containsKey(Position.KEY_SATELLITES)) { - assertTrue(attributes.get(Position.KEY_SATELLITES) instanceof Number); + assertInstanceOf(Number.class, attributes.get(Position.KEY_SATELLITES)); } if (attributes.containsKey(Position.KEY_SATELLITES_VISIBLE)) { - assertTrue(attributes.get(Position.KEY_SATELLITES_VISIBLE) instanceof Number); + assertInstanceOf(Number.class, attributes.get(Position.KEY_SATELLITES_VISIBLE)); } if (attributes.containsKey(Position.KEY_RSSI)) { - assertTrue(attributes.get(Position.KEY_RSSI) instanceof Number); + assertInstanceOf(Number.class, attributes.get(Position.KEY_RSSI)); } if (attributes.containsKey(Position.KEY_ODOMETER)) { - assertTrue(attributes.get(Position.KEY_ODOMETER) instanceof Number); + assertInstanceOf(Number.class, attributes.get(Position.KEY_ODOMETER)); } if (attributes.containsKey(Position.KEY_RPM)) { - assertTrue(attributes.get(Position.KEY_RPM) instanceof Number); + assertInstanceOf(Number.class, attributes.get(Position.KEY_RPM)); } if (attributes.containsKey(Position.KEY_FUEL_LEVEL)) { - assertTrue(attributes.get(Position.KEY_FUEL_LEVEL) instanceof Number); + assertInstanceOf(Number.class, attributes.get(Position.KEY_FUEL_LEVEL)); } if (attributes.containsKey(Position.KEY_FUEL_USED)) { - assertTrue(attributes.get(Position.KEY_FUEL_USED) instanceof Number); + assertInstanceOf(Number.class, attributes.get(Position.KEY_FUEL_USED)); } if (attributes.containsKey(Position.KEY_POWER)) { - assertTrue(attributes.get(Position.KEY_POWER) instanceof Number); + assertInstanceOf(Number.class, attributes.get(Position.KEY_POWER)); } if (attributes.containsKey(Position.KEY_BATTERY)) { - assertTrue(attributes.get(Position.KEY_BATTERY) instanceof Number); + assertInstanceOf(Number.class, attributes.get(Position.KEY_BATTERY)); } if (attributes.containsKey(Position.KEY_BATTERY_LEVEL)) { @@ -279,39 +275,39 @@ public class ProtocolTest extends BaseTest { } if (attributes.containsKey(Position.KEY_CHARGE)) { - assertTrue(attributes.get(Position.KEY_CHARGE) instanceof Boolean); + assertInstanceOf(Boolean.class, attributes.get(Position.KEY_CHARGE)); } if (attributes.containsKey(Position.KEY_IGNITION)) { - assertTrue(attributes.get(Position.KEY_IGNITION) instanceof Boolean); + assertInstanceOf(Boolean.class, attributes.get(Position.KEY_IGNITION)); } if (attributes.containsKey(Position.KEY_MOTION)) { - assertTrue(attributes.get(Position.KEY_MOTION) instanceof Boolean); + assertInstanceOf(Boolean.class, attributes.get(Position.KEY_MOTION)); } if (attributes.containsKey(Position.KEY_ARCHIVE)) { - assertTrue(attributes.get(Position.KEY_ARCHIVE) instanceof Boolean); + assertInstanceOf(Boolean.class, attributes.get(Position.KEY_ARCHIVE)); } if (attributes.containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { - assertTrue(attributes.get(Position.KEY_DRIVER_UNIQUE_ID) instanceof String); + assertInstanceOf(String.class, attributes.get(Position.KEY_DRIVER_UNIQUE_ID)); } if (attributes.containsKey(Position.KEY_STEPS)) { - assertTrue(attributes.get(Position.KEY_STEPS) instanceof Number); + assertInstanceOf(Number.class, attributes.get(Position.KEY_STEPS)); } if (attributes.containsKey(Position.KEY_ROAMING)) { - assertTrue(attributes.get(Position.KEY_ROAMING) instanceof Boolean); + assertInstanceOf(Boolean.class, attributes.get(Position.KEY_ROAMING)); } if (attributes.containsKey(Position.KEY_HOURS)) { - assertTrue(attributes.get(Position.KEY_HOURS) instanceof Number); + assertInstanceOf(Number.class, attributes.get(Position.KEY_HOURS)); } if (attributes.containsKey(Position.KEY_RESULT)) { - assertTrue(attributes.get(Position.KEY_RESULT) instanceof String); + assertInstanceOf(String.class, attributes.get(Position.KEY_RESULT)); } if (position.getNetwork() != null) { @@ -348,7 +344,7 @@ public class ProtocolTest extends BaseTest { protected void verifyFrame(ByteBuf expected, Object object) { assertNotNull(object, "buffer is null"); - assertTrue(object instanceof ByteBuf, "not a buffer"); + assertInstanceOf(ByteBuf.class, object, "not a buffer"); assertEquals(ByteBufUtil.hexDump(expected), ByteBufUtil.hexDump((ByteBuf) object)); } diff --git a/src/test/java/org/traccar/geocoder/GeocoderTest.java b/src/test/java/org/traccar/geocoder/GeocoderTest.java index ef2dd062d..2aa7ab77c 100644 --- a/src/test/java/org/traccar/geocoder/GeocoderTest.java +++ b/src/test/java/org/traccar/geocoder/GeocoderTest.java @@ -20,7 +20,7 @@ public class GeocoderTest { @Disabled @Test public void testGoogle() { - Geocoder geocoder = new GoogleGeocoder(client, null, null, 0, new AddressFormat()); + Geocoder geocoder = new GoogleGeocoder(client, null, null, null, 0, new AddressFormat()); String address = geocoder.getAddress(31.776797, 35.211489, null); assertEquals("1 Ibn Shaprut St, Jerusalem, Jerusalem District, IL", address); } @@ -69,9 +69,9 @@ public class GeocoderTest { @Disabled @Test public void testBan() { - Geocoder geocoder = new BanGeocoder(client, 0, new AddressFormat("%f [%d], %c")); + Geocoder geocoder = new BanGeocoder(client, 0, new AddressFormat()); String address = geocoder.getAddress(48.8575, 2.2944, null); - assertEquals("8 Avenue Gustave Eiffel 75007 Paris [75, Paris, Île-de-France], FR", address); + assertEquals("8 Avenue Gustave Eiffel, Paris, FR", address); } @Disabled @@ -122,4 +122,11 @@ public class GeocoderTest { assertEquals("114 East 13th Street, New York, New York, US", address); } + @Disabled + @Test + public void testGeocodeJSON() { + Geocoder geocoder = new GeocodeJsonGeocoder(client, null, null, null, 0, new AddressFormat()); + String address = geocoder.getAddress(40.7337807, -73.9974401, null); + assertEquals("35 West 9th Street, New York, New York, US", address); + } } diff --git a/src/test/java/org/traccar/protocol/AstraProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/AstraProtocolDecoderTest.java index 3dabcac5d..dc48fc829 100644 --- a/src/test/java/org/traccar/protocol/AstraProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/AstraProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class AstraProtocolDecoderTest extends ProtocolTest { var decoder = inject(new AstraProtocolDecoder(null)); + verifyPositions(decoder, false, binary( + "5800cb02052196881aff5b3c0000200010bf53cbfab10000000100393d5853cbfab0031b93affffb034b0000ae00000000010000000c000c00000000000000787e00000000000000000000000000000000000000000000000000000000000000000000000000000000003d0000200010bf53cbfae60000280000293c5853cbfae6031b93affffb034b0000ae00000000010000000d000c00000000000000ae7e0000000000000000000000000000000000000000000000000000000000000000000000000000000000e604")); + verifyPositions(decoder, binary( "4b00700529c0c265976b8202cba9ff00676d864554a9c30000000020073401006436000300030008000000000000a0000100001920c43d00009600428302cba9ff00676d864554aa3e000000002007240100643b000300020008000000000000b0000100001920c43d00009600420f0e")); diff --git a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index 925a0da1c..04980117b 100644 --- a/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { var decoder = inject(new Gl200TextProtocolDecoder(null)); + verifyAttributes(decoder, buffer( + "+RESP:GTINF,423036,866884046104139,,41,89103000000064820042,22,99,0,,,3.82,0,0,1,0,0,20240622183159,57,,,,,20240623011548,005C$")); + verifyAttribute(decoder, buffer( "+RESP:GTERI,8020050704,867488060246195,,00000004,28823,10,1,1,0.0,33,10.1,10.606120,43.656780,20240408084402,0222,0010,7D53,00DD120D,02,0,0.0,,,,,100,210100,0,1,FFFFF,YS2R4X20009288827,2,H1910197,58234.30,500,1,90,H1.5,P84.00,,0,4616.20,2.28,2.16,5.64,5358,1038,0010,00,00,20240408084403,1809$"), Position.KEY_BATTERY_LEVEL, 100); @@ -513,6 +516,13 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, buffer( "+RESP:GTCAN,8020050605,867488060270575,,00,1,FFFFFFFF,8LBETF3W4N0001613,,,22.54,0,,,,,,,7.84,4.61,3.24,3.33,,8080,,,00,0.00,0.00,1,14,14,2371,0,001FFFFF,,,,,,,,,7158,9998,0,7.84,0.00,0.00,558,,,,,,,C0,,,,,0,0.0,346,2848.5,-78.592371,-0.968132,20240202083437,0740,0002,526C,00AE7907,00,20240202083440,3F6D$")); + verifyAttribute(decoder, buffer( + "+BUFF:GTIGN,6E0202,868589060169789,ra79,379,1,0.0,105,532.2,-70.616413,-33.393457,20240610201712,0730,0001,333A,00CFA301,01,11,,0.0,20240610201713,3AE2$"), + Position.KEY_IGNITION, true); + + verifyAttribute(decoder, buffer( + "+RESP:GTIGF,6E0202,868589060169789,ra79,145,1,0.0,83,532.2,-70.616413,-33.393457,20240610201937,0730,0001,333A,00CFA301,01,12,,0.0,20240610201938,3AE9$"), + Position.KEY_IGNITION, false); } } diff --git a/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java index aea6e7592..8601618bd 100644 --- a/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/GotopProtocolDecoderTest.java @@ -11,6 +11,12 @@ public class GotopProtocolDecoderTest extends ProtocolTest { var decoder = inject(new GotopProtocolDecoder(null)); + verifyPosition(decoder, text( + "012896001901633,CMD-T,A,130104,175950,24.0234233S,029.4691133E,Speed:001.8,90-24,1.3,10,10,65501-0371-170D,12,1-1,00.00")); + + verifyPosition(decoder, text( + "012896001901633,CMD-T,A,130104,175950,24.0234233S,029.4691133E,Speed:001.8,90-24,1.3,00.00")); + verifyNull(decoder, text( "")); diff --git a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 05a33cc72..bb809529a 100644 --- a/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -18,8 +18,30 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { "78780D01086471700328358100093F040D0A")); verifyAttribute(decoder, binary( - "78782732180214123324ca0162bdf0041f45d900190b0a02d4000bc5270000ec025206040202005e07e10d0a"), - Position.KEY_ALARM, Position.ALARM_POWER_CUT); + "787817360005040002003201010018020192006a015f0324aeaf0d0a"), + Position.KEY_BATTERY, 4.02); + + verifyPosition(decoder, binary( + "787840a218061b0e0f05cf021d22430aa2660b005c00014e140000026500000000024d4e02114504df06031c010007d00000000000086973105524576500c802a86fda0d0a")); + + verifyAttribute(decoder, binary( + "79790007940B010A0B5ACE0D0A"), + "networkTechnology", "4G"); + + verifyAttribute(decoder, binary( + "7878293218061301261ccd0274c4ad050d7c960018000a02d4000ac3c70dbdc40b46f004210202af001784290d0a"), + "altitude", -31703.0); + + verifyAttribute(decoder, binary( + "78782a31180613012b39cc0274c4dc050d7cd000180002d4000ac3c70dbdc4150100000000000002a6000ea40b0d0a"), + "altitude", 678.0); + + verifyAttribute(decoder, binary( + "7878281718060e021831c6026e8acc0c361b1000140001cc00286d000f4dbf0000012ca7e001000004b2630d0a"), + Position.KEY_DRIVER_UNIQUE_ID, "bf0000012ca7e001"); + + verifyNotNull(decoder, binary( + "78782732180214123324ca0162bdf0041f45d900190b0a02d4000bc5270000ec025206040202005e07e10d0a")); verifyAttribute(decoder, binary( "78782616170A080C0E24C0027C58AD0C2B8B0100454E0901CC0025030328E7A0005D4B13021EC373170D0A"), diff --git a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java index 2ba37ab09..286ebfed1 100644 --- a/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/HuabaoProtocolDecoderTest.java @@ -227,6 +227,14 @@ public class HuabaoProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "7e0002000004304832546500b7ca7e")); + verifyAttribute(decoder, binary( + "7E020000964130564801050048000000001000004F01651E2E02CAEC3802E80000001524062616002101040000000330011F31010EF1040000308CF231414F56585F564C3330302D4C415F48322E315F4547393135554C4141425230334130324D30385F56322E312E305F763130F3011FF400F5080000000000000001F6084008FFFFFFFD0009F70600000E870246F912000F000000010000062A00082406261600184D7E"), + Position.KEY_CHARGE, true); + + verifyAttribute(decoder, binary( + "7E020000964130564801050048000000001000004F01651E2E02CAEC3802E80000001524062616002101040000000330011F31010EF1040000308CF231414F56585F564C3330302D4C415F48322E315F4547393135554C4141425230334130324D30385F56322E312E305F763130F3011FF400F5080000000000000001F6084008FFFFFFFD0009F70600000E870246F912000F000000010000062A00082406261600184D7E"), + Position.KEY_POWER, 12.428); + } } diff --git a/src/test/java/org/traccar/protocol/MeiligaoProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/MeiligaoProtocolDecoderTest.java index 8074636a3..8e2f55117 100644 --- a/src/test/java/org/traccar/protocol/MeiligaoProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/MeiligaoProtocolDecoderTest.java @@ -12,6 +12,10 @@ public class MeiligaoProtocolDecoderTest extends ProtocolTest { var decoder = inject(new MeiligaoProtocolDecoder(null)); verifyAttribute(decoder, binary( + "242400166578902354329399034331453838d2c40d0a"), + Position.KEY_DTCS, "C1E88"); + + verifyAttribute(decoder, binary( "2424008f142180340967ff99553033333233302e3030302c412c313531362e383039392c4e2c31303435322e383835352c452c302e30302c33332c3038313232302c2c2a33367c302e387c3132337c323130307c303030302c303030302c303230452c303241417c30323038303030353038394530304531434638347c31437c31373243353832437c3042a8060d0a"), Position.KEY_SATELLITES, 11); diff --git a/src/test/java/org/traccar/protocol/MeitrackProtocolEncoderTest.java b/src/test/java/org/traccar/protocol/MeitrackProtocolEncoderTest.java index ac9854b8e..71620b967 100644 --- a/src/test/java/org/traccar/protocol/MeitrackProtocolEncoderTest.java +++ b/src/test/java/org/traccar/protocol/MeitrackProtocolEncoderTest.java @@ -17,19 +17,19 @@ public class MeitrackProtocolEncoderTest extends ProtocolTest { command.setDeviceId(1); command.setType(Command.TYPE_POSITION_SINGLE); - assertEquals("@@Q25,123456789012345,A10*68\r\n", encoder.encodeCommand(command)); + assertEquals("@@A25,123456789012345,A10*58\r\n", encoder.encodeCommand(command)); command.setDeviceId(1); command.setType(Command.TYPE_REQUEST_PHOTO); - assertEquals("@@D46,123456789012345,D03,1,camera_picture.jpg*1F\r\n", encoder.encodeCommand(command)); + assertEquals("@@A46,123456789012345,D03,1,camera_picture.jpg*1C\r\n", encoder.encodeCommand(command)); command.setDeviceId(1); command.setType(Command.TYPE_SEND_SMS); command.set(Command.KEY_PHONE, "15360853789"); command.set(Command.KEY_MESSAGE, "Meitrack"); - assertEquals("@@f48,123456789012345,C02,0,15360853789,Meitrack*B0\r\n", encoder.encodeCommand(command)); + assertEquals("@@A48,123456789012345,C02,0,15360853789,Meitrack*8B\r\n", encoder.encodeCommand(command)); } diff --git a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index 2a8ff87b6..d8e480f25 100644 --- a/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -15,6 +15,10 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "000F313233343536373839303132333435")); + verifyAttribute(decoder, binary( + "00000000000000768e010000018fdc4b27cb015b3e33ceefa529030009013f0e0000022400010000000000000000000102240049010f0001c60106babbf36300550202806d0f0001ca01063456555565690202806b0f0001d10106467975425450020280690b0001c90106fa54ba8d00550b0001cf0106cabbf36300550100005455"), + "tag1Voltage", 3090); + verifyPositions(decoder, binary( "00000000000000728e010000018b23dd796300fbf7263c24f9e11a0000000000000002240001000000000000000000010224004501210001e50110cde39f7e42bb55aa788e4a29ed650055020ab70a8f264c6000ffff6b210001b00110f89b907e42bb55aaa3463b29ed650055020ab708bb2600ae0500096c01000051d4")); diff --git a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java index a17fc341f..944b684d0 100644 --- a/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/TrvProtocolDecoderTest.java @@ -14,6 +14,9 @@ public class TrvProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, text( "TRVAP00352121088015548")); + verifyNull(decoder, text( + "IWAPXL,080835")); + verifyAttribute(decoder, text( "IWAP10080524A2232.9806N11404.9355E000.1061830323.8706000908000502,460,0,9520,3671,01,zhcn,00,HOME|74-DE-2B-44-88-8C|97&HOME1|74-DE-2B-44-88-8C|97&HOME2|74-DE-2B-44-88-8C|97&HOME3|74-DE-2B-44-88-8C|97"), Position.KEY_ALARM, Position.ALARM_SOS); @@ -96,6 +99,9 @@ public class TrvProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "TRVYP14220217A5235.7885N00724.1840E000.0130919177.561000050660000200004,262,01,14635,52789,FritzBox7|DC-39-8F-7E-94-73|-89&FritzBox7|24-4E-5D-71-C3-9C|-90&MY_IOT|80-B4-F7-77-9C-7C|-81&MYAP|44-D4-F7-77-9C-7C|-80#")); + verifyNull(decoder, text( + "IWAP12,080835,+491773329827,+491773329826,+49306618438")); + } } diff --git a/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java index f070c6201..ac9c83e01 100644 --- a/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/UproProtocolDecoderTest.java @@ -12,6 +12,9 @@ public class UproProtocolDecoderTest extends ProtocolTest { var decoder = inject(new UproProtocolDecoder(null)); verifyPosition(decoder, buffer( + "*HQ200862406278000161,AB1&A1103312243149711422697470000040724&B0100000000&F0000&R2900&N04&Y3246011F4202C1460D351F4202C146113A1F4204C1460B3C&Q06f4911e6155e127b04e2640509e325091e3cc45ed4e788a20e024a151f81a679be2a45250d4f7e7dff75b&T63&J000300&K00100&X(k89882280666065148193)(10)(J0000)(PMODE,0,10)(20)(5000A)#")); + + verifyPosition(decoder, buffer( "*HQ201999999,BA&A1656512233362911356523660000230618&B0100060010&C00000<6<&F0000&R2405&V0109&W0000003E&K00100&T65&I54600027A00FCB6227A00FCA5727A00E955327A00E8B5327A00F9748&Y54600027A000000FCB6227A000000FCA5727A000000E955327A000000E8B5327A000000F9748&b00A7E81007607#")); verifyPosition(decoder, buffer( diff --git a/swagger.json b/swagger.json index b6d1ff241..7366da5bb 100644 --- a/swagger.json +++ b/swagger.json @@ -2,7 +2,7 @@ "openapi": "3.0.1", "info": { "title": "Traccar", - "version": "6.2", + "version": "6.3", "description": "Traccar GPS tracking server API documentation. To use the API you need to have a server instance. For testing purposes you can use one of free [demo servers](https://www.traccar.org/demo-server/). For production use you can install your own server or get a [subscription service](https://www.traccar.org/product/tracking-server/).", "contact": { "name": "Traccar Support", diff --git a/tools/test-integration.py b/tools/test-integration.py index 29c741390..0dfa78f43 100755 --- a/tools/test-integration.py +++ b/tools/test-integration.py @@ -180,8 +180,9 @@ def send_message(port, message): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', port)) s.send(message.encode('ascii')) - time.sleep(1.0) + time.sleep(0.5) s.close() + time.sleep(0.5) def get_protocols(cookie, device_id): params = { 'deviceId' : device_id, 'from' : '2000-01-01T00:00:00.000Z', 'to' : '2050-01-01T00:00:00.000Z' } |