├── .gitignore
├── LICENSE
├── README.md
├── adapter
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── com
│ │ └── devesion
│ │ └── commons
│ │ └── obd
│ │ └── adapter
│ │ ├── command
│ │ ├── AbstractCommand.java
│ │ ├── CommandResult.java
│ │ ├── ObdCommand.java
│ │ ├── ObdCommandVisitor.java
│ │ ├── at
│ │ │ ├── AbstractAtCommand.java
│ │ │ ├── AbstractSetStateCommand.java
│ │ │ ├── AdaptiveTimeoutProtocolCommand.java
│ │ │ ├── AtCommand.java
│ │ │ ├── EnableBaudRateCommand.java
│ │ │ ├── ResetCommand.java
│ │ │ ├── SelectProtocolCommand.java
│ │ │ ├── SetBaudRateCommand.java
│ │ │ ├── SetDefaultsCommand.java
│ │ │ ├── SetEchoCommand.java
│ │ │ ├── SetHeadersCommand.java
│ │ │ ├── SetLineFeedCommand.java
│ │ │ ├── SetMemoryCommand.java
│ │ │ └── SetSpacesCommand.java
│ │ ├── diagnostic
│ │ │ ├── AbstractDiagnosticCommand.java
│ │ │ ├── DiagnosticCommand.java
│ │ │ ├── DiagnosticCommandMode.java
│ │ │ ├── DiagnosticCommandPid.java
│ │ │ ├── info
│ │ │ │ └── InfoCommandPid.java
│ │ │ ├── monitors
│ │ │ │ └── MonitorCommandPid.java
│ │ │ └── sensors
│ │ │ │ ├── AbstractSensorCommand.java
│ │ │ │ ├── AmbientAirTemperatureCommand.java
│ │ │ │ ├── EngineCoolantTemperatureCommand.java
│ │ │ │ ├── EngineLoadCommand.java
│ │ │ │ ├── EngineRpmCommand.java
│ │ │ │ ├── EngineRuntimeCommand.java
│ │ │ │ ├── FuelConsumptionRateCommand.java
│ │ │ │ ├── FuelLevelCommand.java
│ │ │ │ ├── FuelPressureCommand.java
│ │ │ │ ├── FuelTypeCommand.java
│ │ │ │ ├── IntakeAirTemperatureCommand.java
│ │ │ │ ├── MassAirFlowCommand.java
│ │ │ │ ├── SensorCommand.java
│ │ │ │ ├── SensorCommandPid.java
│ │ │ │ ├── SpeedCommand.java
│ │ │ │ ├── ThrottlePositionCommand.java
│ │ │ │ └── units
│ │ │ │ ├── AbstractSensorCommandValue.java
│ │ │ │ ├── AirFlowValue.java
│ │ │ │ ├── FuelConsumptionValue.java
│ │ │ │ ├── FuelPressureValue.java
│ │ │ │ ├── FuelTypeValue.java
│ │ │ │ ├── PercentageValue.java
│ │ │ │ ├── PressureValue.java
│ │ │ │ ├── RpmValue.java
│ │ │ │ ├── SensorCommandValue.java
│ │ │ │ ├── SimpleValue.java
│ │ │ │ ├── SpeedValue.java
│ │ │ │ ├── TemperatureValue.java
│ │ │ │ ├── TimeValue.java
│ │ │ │ ├── UnitFactory.java
│ │ │ │ └── VoltageValue.java
│ │ └── invoker
│ │ │ ├── CommandExceptionFactory.java
│ │ │ └── CommandInvoker.java
│ │ ├── link
│ │ ├── CommandMarshaller.java
│ │ ├── CommandUnmarshaller.java
│ │ ├── ObdLink.java
│ │ └── elm
│ │ │ ├── AbstractCommandMarshaller.java
│ │ │ ├── AbstractCommandUnmarshaller.java
│ │ │ ├── AtCommandMarshaller.java
│ │ │ ├── AtCommandUnmarshaller.java
│ │ │ ├── CommandMarshallerBridge.java
│ │ │ ├── CommandUnmarshallerBridge.java
│ │ │ ├── DiagnosticCommandMarshaller.java
│ │ │ ├── DiagnosticCommandUnmarshaller.java
│ │ │ ├── ElmLink.java
│ │ │ └── ElmTransport.java
│ │ └── shared
│ │ ├── HexTools.java
│ │ ├── ObdAbstractRuntimeException.java
│ │ ├── ObdCommandResponseException.java
│ │ ├── ObdCommunicationException.java
│ │ ├── ObdInvalidCommandResponseException.java
│ │ ├── ObdNoDataForCommandResponseException.java
│ │ ├── ObdNotProperlyInitializedException.java
│ │ └── ObdNumberedEnum.java
│ └── test
│ └── java
│ └── com
│ └── devesion
│ └── commons
│ └── obd
│ ├── ObdAdapterClient.java
│ ├── TestSupport.java
│ └── adapter
│ ├── command
│ ├── AbstractCommandTest.java
│ ├── CommandResultTest.java
│ ├── at
│ │ ├── AbstractAtCommandTest.java
│ │ ├── AbstractSetStateCommandTest.java
│ │ ├── SelectProtocolCommandTest.java
│ │ ├── SetEchoCommandTest.java
│ │ ├── SetHeadersCommandTest.java
│ │ ├── SetLineFeedCommandTest.java
│ │ ├── SetMemoryCommandTest.java
│ │ └── SetSpacesCommandTest.java
│ ├── diagnostic
│ │ ├── AbstractDiagnosticCommandTest.java
│ │ └── sensors
│ │ │ ├── AbstractSensorCommandTest.java
│ │ │ ├── AmbientAirTemperatureCommandTest.java
│ │ │ ├── BaseSensorCommandTest.java
│ │ │ ├── EngineCoolantTemperatureCommandTest.java
│ │ │ ├── EngineLoadCommandTest.java
│ │ │ ├── EngineRpmCommandTest.java
│ │ │ ├── EngineRuntimeCommandTest.java
│ │ │ ├── FuelConsumptionRateCommandTest.java
│ │ │ ├── FuelLevelCommandTest.java
│ │ │ ├── FuelTypeCommandTest.java
│ │ │ ├── IntakeAirTemperatureCommandTest.java
│ │ │ ├── MassAirFlowCommandTest.java
│ │ │ ├── ThrottlePositionCommandTest.java
│ │ │ └── units
│ │ │ ├── AirFlowValueTest.java
│ │ │ ├── BaseValueTest.java
│ │ │ ├── FuelConsumptionValueTest.java
│ │ │ ├── FuelTypeValueTest.java
│ │ │ ├── RpmValueTest.java
│ │ │ ├── SimpleValueTest.java
│ │ │ ├── TemperatureValueTest.java
│ │ │ ├── TimeValueTest.java
│ │ │ └── UnitFactoryTest.java
│ └── invoker
│ │ └── CommandInvokerTest.java
│ ├── link
│ └── elm
│ │ ├── AbstractCommandUnmarshallerTest.java
│ │ ├── DiagnosticCommandUnmarshallerTest.java
│ │ ├── ElmLinkTest.java
│ │ └── ElmTransportTest.java
│ └── shared
│ ├── BaseObdCommandResponseExceptionTest.java
│ ├── ObdCommandResponseExceptionTest.java
│ ├── ObdInvalidCommandResponseExceptionTest.java
│ └── ObdnoDataForCommandResponseExceptionTest.java
├── client
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── autonalyzer
│ │ └── adapter
│ │ └── android
│ │ ├── Launcher.java
│ │ ├── domain
│ │ ├── DiagnosticStatus.java
│ │ ├── DiagnosticStatusFactory.java
│ │ ├── DiagnosticStatusSpecification.java
│ │ └── DiagnosticTransportSpecification.java
│ │ └── infrastructure
│ │ ├── DefaultDiagnosticStatusFactory.java
│ │ ├── DiagnosticStatusReadException.java
│ │ ├── gateway
│ │ ├── DiagnosticStatusGateway.java
│ │ ├── ProbingDiagnosticStatusGateway.java
│ │ ├── ProbingDiagnosticStatusGatewayFactory.java
│ │ └── elm
│ │ │ ├── ElmDiagnosticStatusGateway.java
│ │ │ └── ProbingElmDiagnosticStatusGateway.java
│ │ └── transport
│ │ ├── DiagnosticTransport.java
│ │ ├── DiagnosticTransportFactory.java
│ │ ├── DiagnosticTransportProbe.java
│ │ ├── ProbingDiagnosticTransportFactory.java
│ │ └── serial
│ │ ├── SerialDiagnosticTransport.java
│ │ └── SerialDiagnosticTransportFactory.java
│ └── resources
│ └── log4j.properties
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 | target
3 | bin
4 |
5 | # Package Files #
6 | *.jar
7 | *.war
8 | *.ear
9 |
10 | # IDE files #
11 | .settings
12 | .project
13 | .classpath
14 | .idea
15 | *.iml
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction, and
10 | distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright
13 | owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all other entities
16 | that control, are controlled by, or are under common control with that entity.
17 | For the purposes of this definition, "control" means (i) the power, direct or
18 | indirect, to cause the direction or management of such entity, whether by
19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
20 | outstanding shares, or (iii) beneficial ownership of such entity.
21 |
22 | "You" (or "Your") shall mean an individual or Legal Entity exercising
23 | permissions granted by this License.
24 |
25 | "Source" form shall mean the preferred form for making modifications, including
26 | but not limited to software source code, documentation source, and configuration
27 | files.
28 |
29 | "Object" form shall mean any form resulting from mechanical transformation or
30 | translation of a Source form, including but not limited to compiled object code,
31 | generated documentation, and conversions to other media types.
32 |
33 | "Work" shall mean the work of authorship, whether in Source or Object form, made
34 | available under the License, as indicated by a copyright notice that is included
35 | in or attached to the work (an example is provided in the Appendix below).
36 |
37 | "Derivative Works" shall mean any work, whether in Source or Object form, that
38 | is based on (or derived from) the Work and for which the editorial revisions,
39 | annotations, elaborations, or other modifications represent, as a whole, an
40 | original work of authorship. For the purposes of this License, Derivative Works
41 | shall not include works that remain separable from, or merely link (or bind by
42 | name) to the interfaces of, the Work and Derivative Works thereof.
43 |
44 | "Contribution" shall mean any work of authorship, including the original version
45 | of the Work and any modifications or additions to that Work or Derivative Works
46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work
47 | by the copyright owner or by an individual or Legal Entity authorized to submit
48 | on behalf of the copyright owner. For the purposes of this definition,
49 | "submitted" means any form of electronic, verbal, or written communication sent
50 | to the Licensor or its representatives, including but not limited to
51 | communication on electronic mailing lists, source code control systems, and
52 | issue tracking systems that are managed by, or on behalf of, the Licensor for
53 | the purpose of discussing and improving the Work, but excluding communication
54 | that is conspicuously marked or otherwise designated in writing by the copyright
55 | owner as "Not a Contribution."
56 |
57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf
58 | of whom a Contribution has been received by Licensor and subsequently
59 | incorporated within the Work.
60 |
61 | 2. Grant of Copyright License.
62 |
63 | Subject to the terms and conditions of this License, each Contributor hereby
64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
65 | irrevocable copyright license to reproduce, prepare Derivative Works of,
66 | publicly display, publicly perform, sublicense, and distribute the Work and such
67 | Derivative Works in Source or Object form.
68 |
69 | 3. Grant of Patent License.
70 |
71 | Subject to the terms and conditions of this License, each Contributor hereby
72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
73 | irrevocable (except as stated in this section) patent license to make, have
74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where
75 | such license applies only to those patent claims licensable by such Contributor
76 | that are necessarily infringed by their Contribution(s) alone or by combination
77 | of their Contribution(s) with the Work to which such Contribution(s) was
78 | submitted. If You institute patent litigation against any entity (including a
79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a
80 | Contribution incorporated within the Work constitutes direct or contributory
81 | patent infringement, then any patent licenses granted to You under this License
82 | for that Work shall terminate as of the date such litigation is filed.
83 |
84 | 4. Redistribution.
85 |
86 | You may reproduce and distribute copies of the Work or Derivative Works thereof
87 | in any medium, with or without modifications, and in Source or Object form,
88 | provided that You meet the following conditions:
89 |
90 | You must give any other recipients of the Work or Derivative Works a copy of
91 | this License; and
92 | You must cause any modified files to carry prominent notices stating that You
93 | changed the files; and
94 | You must retain, in the Source form of any Derivative Works that You distribute,
95 | all copyright, patent, trademark, and attribution notices from the Source form
96 | of the Work, excluding those notices that do not pertain to any part of the
97 | Derivative Works; and
98 | If the Work includes a "NOTICE" text file as part of its distribution, then any
99 | Derivative Works that You distribute must include a readable copy of the
100 | attribution notices contained within such NOTICE file, excluding those notices
101 | that do not pertain to any part of the Derivative Works, in at least one of the
102 | following places: within a NOTICE text file distributed as part of the
103 | Derivative Works; within the Source form or documentation, if provided along
104 | with the Derivative Works; or, within a display generated by the Derivative
105 | Works, if and wherever such third-party notices normally appear. The contents of
106 | the NOTICE file are for informational purposes only and do not modify the
107 | License. You may add Your own attribution notices within Derivative Works that
108 | You distribute, alongside or as an addendum to the NOTICE text from the Work,
109 | provided that such additional attribution notices cannot be construed as
110 | modifying the License.
111 | You may add Your own copyright statement to Your modifications and may provide
112 | additional or different license terms and conditions for use, reproduction, or
113 | distribution of Your modifications, or for any such Derivative Works as a whole,
114 | provided Your use, reproduction, and distribution of the Work otherwise complies
115 | with the conditions stated in this License.
116 |
117 | 5. Submission of Contributions.
118 |
119 | Unless You explicitly state otherwise, any Contribution intentionally submitted
120 | for inclusion in the Work by You to the Licensor shall be under the terms and
121 | conditions of this License, without any additional terms or conditions.
122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of
123 | any separate license agreement you may have executed with Licensor regarding
124 | such Contributions.
125 |
126 | 6. Trademarks.
127 |
128 | This License does not grant permission to use the trade names, trademarks,
129 | service marks, or product names of the Licensor, except as required for
130 | reasonable and customary use in describing the origin of the Work and
131 | reproducing the content of the NOTICE file.
132 |
133 | 7. Disclaimer of Warranty.
134 |
135 | Unless required by applicable law or agreed to in writing, Licensor provides the
136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
138 | including, without limitation, any warranties or conditions of TITLE,
139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
140 | solely responsible for determining the appropriateness of using or
141 | redistributing the Work and assume any risks associated with Your exercise of
142 | permissions under this License.
143 |
144 | 8. Limitation of Liability.
145 |
146 | In no event and under no legal theory, whether in tort (including negligence),
147 | contract, or otherwise, unless required by applicable law (such as deliberate
148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be
149 | liable to You for damages, including any direct, indirect, special, incidental,
150 | or consequential damages of any character arising as a result of this License or
151 | out of the use or inability to use the Work (including but not limited to
152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or
153 | any and all other commercial damages or losses), even if such Contributor has
154 | been advised of the possibility of such damages.
155 |
156 | 9. Accepting Warranty or Additional Liability.
157 |
158 | While redistributing the Work or Derivative Works thereof, You may choose to
159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or
160 | other liability obligations and/or rights consistent with this License. However,
161 | in accepting such obligations, You may act only on Your own behalf and on Your
162 | sole responsibility, not on behalf of any other Contributor, and only if You
163 | agree to indemnify, defend, and hold each Contributor harmless for any liability
164 | incurred by, or claims asserted against, such Contributor by reason of your
165 | accepting any such warranty or additional liability.
166 |
167 | END OF TERMS AND CONDITIONS
168 |
169 | APPENDIX: How to apply the Apache License to your work
170 |
171 | To apply the Apache License to your work, attach the following boilerplate
172 | notice, with the fields enclosed by brackets "[]" replaced with your own
173 | identifying information. (Don't include the brackets!) The text should be
174 | enclosed in the appropriate comment syntax for the file format. We also
175 | recommend that a file or class name and description of purpose be included on
176 | the same "printed page" as the copyright notice for easier identification within
177 | third-party archives.
178 |
179 | Copyright [yyyy] [name of copyright owner]
180 |
181 | Licensed under the Apache License, Version 2.0 (the "License");
182 | you may not use this file except in compliance with the License.
183 | You may obtain a copy of the License at
184 |
185 | http://www.apache.org/licenses/LICENSE-2.0
186 |
187 | Unless required by applicable law or agreed to in writing, software
188 | distributed under the License is distributed on an "AS IS" BASIS,
189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
190 | See the License for the specific language governing permissions and
191 | limitations under the License.
192 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # java-obd-adapter
2 | java-obd-adapter - OBD-II Java Adapter API
3 |
4 | ### Requisites
5 | * Java 7
6 | * Maven 3
7 |
8 | ### Supported Commands
9 |
10 | AT Commands
11 | * AT Z - AT Reset
12 | * AT SP - AT Select Protocol
13 | * AT D - AT Defaults
14 | * AT E - AT Set Echo On/Off
15 | * AT H - AT Set Headers On/Off
16 | * AT L - AT Set Linefeed On/Off
17 | * AT M - AT Set Memory On/Off
18 | * AT S - AT Set Spaces On/Off
19 |
20 | Diagnostic Commands
21 | * 01 04 - ENGINE_LOAD
22 | * 01 05 - ENGINE_COOLANT_TEMPERATURE
23 | * 01 0C - ENGINE_RPM
24 | * 01 0D - VEHICLE_SPEED
25 | * 01 0F - INTAKE_AIR_TEMPERATURE
26 | * 01 10 - MASS_AIR_FLOW
27 | * 01 11 - THROTTLE_POSITION_PERCENTAGE
28 | * 01 1F - ENGINE_RUN_TIME
29 | * 01 2F - FUEL_LEVEL
30 | * 01 46 - AMBIENT_AIR_TEMPERATURE
31 | * 01 51 - FUEL_TYPE
32 | * 01 5E - FUEL_CONSUMPTION_1
33 | * 01 5F - FUEL_CONSUMPTION_2
34 |
35 | ### Usage
36 | ```
37 |
38 | com.devesion.commons.obd
39 | obd-adapter
40 | 1.0-SNAPSHOT
41 |
42 | ```
43 |
44 | ```
45 | private void invokeInitialCommands() {
46 | invokeCommandQuietly(new ResetCommand());
47 | invokeCommand(new SetEchoCommand(false));
48 | invokeCommand(new SetLineFeedCommand(false));
49 | invokeCommand(new SetHeadersCommand(false));
50 | invokeCommand(new SetSpacesCommand(false));
51 | invokeCommand(new AdaptiveTimeoutProtocolCommand());
52 | invokeCommand(new SelectProtocolCommand());
53 | }
54 |
55 | private int readEngineRpm() {
56 | EngineRpmCommand engineRpmCommand = new EngineRpmCommand();
57 | invokeCommand(engineRpmCommand);
58 | return engineRpmCommand.getValue().getIntValue();
59 | }
60 |
61 | private int readVehicleSpeed() {
62 | SpeedCommand speedCommand = new SpeedCommand();
63 | invokeCommand(speedCommand);
64 | return speedCommand.getValue().getIntValue();
65 | }
66 |
67 | private float readThrottlePositionPercentage() {
68 | ThrottlePositionCommand throttlePositionCommand = new ThrottlePositionCommand();
69 | invokeCommand(throttlePositionCommand);
70 | return throttlePositionCommand.getValue().getIntValue();
71 | }
72 |
73 | private double readMassAirFlow() {
74 | MassAirFlowCommand massAirFlowObdCommand = new MassAirFlowCommand();
75 | invokeCommand(massAirFlowObdCommand);
76 | return massAirFlowObdCommand.getValue().getFloatValue();
77 | }
78 |
79 | private void invokeCommand(ObdCommand command) {
80 | try {
81 | CommandInvoker commandInvoker = createCommandInvoker();
82 | log.info("invoking command {}", command);
83 | commandInvoker.invoke(command);
84 | } catch (Exception e) {
85 | throw new DiagnosticStatusReadException(e);
86 | }
87 | }
88 |
89 | private void invokeCommandQuietly(ObdCommand command) {
90 | CommandInvoker commandInvoker = createCommandInvoker();
91 | log.info("invoking command {}", command);
92 | commandInvoker.invokeQuietly(command);
93 | }
94 |
95 | private CommandInvoker createCommandInvoker(InputStream inputStream, OutputStream outputStream) {
96 | ObdLink obdLink = new ElmLink(inputStream, outputStream);
97 | return new CommandInvoker(obdLink);
98 | }
99 | ```
100 |
101 |
102 | [](https://bitdeli.com/free "Bitdeli Badge")
103 |
104 |
--------------------------------------------------------------------------------
/adapter/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | obd-adapter
7 | com.devesion.commons.obd
8 | 1.0-SNAPSHOT
9 |
10 |
11 | 4.0.0
12 | adapter
13 | ${project.groupId}.${project.artifactId}
14 |
15 |
16 |
17 | org.rxtx
18 | rxtx
19 | 2.1.7
20 | test
21 |
22 |
23 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/AbstractCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command;
2 |
3 | /**
4 | * Skeletal implementation of {@link com.devesion.commons.obd.adapter.command.ObdCommand} interface.
5 | */
6 | public abstract class AbstractCommand implements ObdCommand {
7 |
8 | private CommandResult result = CommandResult.empty();
9 |
10 | public CommandResult getResult() {
11 | return result;
12 | }
13 |
14 | @Override
15 | public void setResult(CommandResult result) {
16 | this.result = result;
17 | }
18 |
19 | @Override
20 | public boolean checkResponseEnabled() {
21 | return true;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/CommandResult.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command;
2 |
3 | import lombok.AccessLevel;
4 | import lombok.Getter;
5 | import lombok.ToString;
6 |
7 | import java.nio.IntBuffer;
8 |
9 | /**
10 | * Represents OBD command result.
11 | */
12 | @ToString
13 | public class CommandResult {
14 |
15 | @Getter(AccessLevel.PACKAGE)
16 | private IntBuffer responseBuffer;
17 |
18 | private CommandResult(IntBuffer responseBuffer) {
19 | this.responseBuffer = responseBuffer;
20 | }
21 |
22 | public static CommandResult empty() {
23 | return withBuffer(IntBuffer.allocate(10));
24 | }
25 |
26 | public static CommandResult withBuffer(IntBuffer responseBuffer) {
27 | return new CommandResult(responseBuffer);
28 | }
29 |
30 | public int getByteNumber(int byteNumber) {
31 | return responseBuffer.get(byteNumber);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/ObdCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command;
2 |
3 | /**
4 | * Represents OBD command interface.
5 | */
6 | public interface ObdCommand {
7 |
8 | CommandResult getResult();
9 |
10 | void setResult(CommandResult result);
11 |
12 | boolean checkResponseEnabled();
13 |
14 | void accept(ObdCommandVisitor visitor);
15 | }
16 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/ObdCommandVisitor.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command;
2 |
3 | import com.devesion.commons.obd.adapter.command.at.AtCommand;
4 | import com.devesion.commons.obd.adapter.command.diagnostic.DiagnosticCommand;
5 |
6 | /**
7 | * OBD Command Visitor Interface.
8 | */
9 | public interface ObdCommandVisitor {
10 |
11 | void visit(AtCommand command);
12 |
13 | void visit(DiagnosticCommand command);
14 | }
15 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/at/AbstractAtCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | import com.devesion.commons.obd.adapter.command.AbstractCommand;
4 | import com.devesion.commons.obd.adapter.command.ObdCommandVisitor;
5 | import lombok.EqualsAndHashCode;
6 |
7 | /**
8 | * Supertype for every AT Command.
9 | */
10 | @EqualsAndHashCode(callSuper = true)
11 | abstract class AbstractAtCommand extends AbstractCommand implements AtCommand {
12 |
13 | @Override
14 | public void accept(ObdCommandVisitor visitor) {
15 | visitor.visit(this);
16 | }
17 |
18 | @Override
19 | public String toString() {
20 | final StringBuilder sb = new StringBuilder("AbstractAtCommand{");
21 | sb.append("operands='").append(getOperands()).append("'}");
22 | return sb.toString();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/at/AbstractSetStateCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | /**
4 | * Represents AT set boolean state Command.
5 | */
6 | public class AbstractSetStateCommand extends AbstractAtCommand {
7 |
8 | private final String operandPrefix;
9 | private final boolean enabled;
10 |
11 | public AbstractSetStateCommand(String operandPrefix, boolean enabled) {
12 | this.operandPrefix = operandPrefix;
13 | this.enabled = enabled;
14 | }
15 |
16 | @Override
17 | public String getOperands() {
18 | int enabledInt = enabled ? 1 : 0;
19 | return operandPrefix + enabledInt;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/at/AdaptiveTimeoutProtocolCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | /**
4 | * Represents AT Adaptive Timing Protocol Command.
5 | */
6 | public class AdaptiveTimeoutProtocolCommand extends AbstractAtCommand {
7 |
8 | @Override
9 | public String getOperands() {
10 | return "AT 2";
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/at/AtCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | import com.devesion.commons.obd.adapter.command.ObdCommand;
4 |
5 | public interface AtCommand extends ObdCommand {
6 |
7 | String getOperands();
8 | }
9 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/at/EnableBaudRateCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | /**
4 | * Represents AT Reset Command.
5 | */
6 | public class EnableBaudRateCommand extends AbstractAtCommand {
7 |
8 | @Override
9 | public String getOperands() {
10 | return "PP 0C ON";
11 | }
12 |
13 | @Override
14 | public boolean checkResponseEnabled() {
15 | return false;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/at/ResetCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | /**
4 | * Represents AT Reset Command.
5 | */
6 | public class ResetCommand extends AbstractAtCommand {
7 |
8 | @Override
9 | public String getOperands() {
10 | return "Z";
11 | }
12 |
13 | @Override
14 | public boolean checkResponseEnabled() {
15 | return false;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/at/SelectProtocolCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | /**
4 | * Represents AT Select Protocol Command.
5 | */
6 | public class SelectProtocolCommand extends AbstractAtCommand {
7 |
8 | @Override
9 | public String getOperands() {
10 | return "SP 0";
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/at/SetBaudRateCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | /**
4 | * Represents AT Reset Command.
5 | */
6 | public class SetBaudRateCommand extends AbstractAtCommand {
7 |
8 | @Override
9 | public String getOperands() {
10 | return "PP 0C SV 23";
11 | }
12 |
13 | @Override
14 | public boolean checkResponseEnabled() {
15 | return false;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/at/SetDefaultsCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | /**
4 | * Represents AT Defaults Command.
5 | */
6 | public class SetDefaultsCommand extends AbstractAtCommand {
7 |
8 | @Override
9 | public String getOperands() {
10 | return "D";
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/at/SetEchoCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | /**
4 | * Represents AT Set Echo On/Off Command.
5 | */
6 | public class SetEchoCommand extends AbstractSetStateCommand {
7 |
8 | private static final String SET_ECHO_PREFIX = "E";
9 |
10 | public SetEchoCommand(boolean enabled) {
11 | super(SET_ECHO_PREFIX, enabled);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/at/SetHeadersCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | /**
4 | * Represents AT Set Headers On/Off Command.
5 | */
6 | public class SetHeadersCommand extends AbstractSetStateCommand {
7 |
8 | private static final String SET_HEADERS_PREFIX = "H";
9 |
10 | public SetHeadersCommand(boolean enabled) {
11 | super(SET_HEADERS_PREFIX, enabled);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/at/SetLineFeedCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | /**
4 | * Represents AT Set Linefeed On/Off Command.
5 | */
6 | public class SetLineFeedCommand extends AbstractSetStateCommand {
7 |
8 | private static final String SET_LINE_FEED_PREFIX = "L";
9 |
10 | public SetLineFeedCommand(boolean enabled) {
11 | super(SET_LINE_FEED_PREFIX, enabled);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/at/SetMemoryCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | /**
4 | * Represents AT Set Memory On/Off Command.
5 | */
6 | public class SetMemoryCommand extends AbstractSetStateCommand {
7 |
8 | private static final String SET_MEMORY_PREFIX = "M";
9 |
10 | public SetMemoryCommand(boolean enabled) {
11 | super(SET_MEMORY_PREFIX, enabled);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/at/SetSpacesCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | /**
4 | * Represents AT Set Spaces On/Off Command.
5 | */
6 | public class SetSpacesCommand extends AbstractSetStateCommand {
7 |
8 | private static final String SET_SPACES_PREFIX = "S";
9 |
10 | public SetSpacesCommand(boolean enabled) {
11 | super(SET_SPACES_PREFIX, enabled);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/AbstractDiagnosticCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic;
2 |
3 | import com.devesion.commons.obd.adapter.command.AbstractCommand;
4 | import com.devesion.commons.obd.adapter.command.ObdCommandVisitor;
5 | import lombok.EqualsAndHashCode;
6 |
7 | @EqualsAndHashCode(callSuper = true)
8 | public abstract class AbstractDiagnosticCommand extends AbstractCommand implements DiagnosticCommand {
9 |
10 | @Override
11 | public void accept(ObdCommandVisitor visitor) {
12 | visitor.visit(this);
13 | }
14 |
15 | @Override
16 | public String toString() {
17 | final StringBuilder sb = new StringBuilder("AbstractDiagnosticCommand{");
18 | sb.append("mode='").append(getMode()).append("', pid='").append(getPid()).append("'}");
19 | return sb.toString();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/DiagnosticCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic;
2 |
3 | import com.devesion.commons.obd.adapter.command.ObdCommand;
4 | import com.devesion.commons.obd.adapter.shared.ObdNumberedEnum;
5 |
6 | public interface DiagnosticCommand extends ObdCommand {
7 |
8 | ObdNumberedEnum getMode();
9 |
10 | ObdNumberedEnum getPid();
11 | }
12 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/DiagnosticCommandMode.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic;
2 |
3 | import com.devesion.commons.obd.adapter.shared.ObdNumberedEnum;
4 | import lombok.Getter;
5 |
6 | public enum DiagnosticCommandMode implements ObdNumberedEnum {
7 | SENSORS(1),
8 | TROUBLES(3),
9 | CLEAR(4),
10 | MONITORS(6),
11 | INFO(9);
12 |
13 | @Getter
14 | private int number;
15 |
16 | DiagnosticCommandMode(int number) {
17 | this.number = number;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/DiagnosticCommandPid.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic;
2 |
3 | import com.devesion.commons.obd.adapter.shared.ObdNumberedEnum;
4 |
5 | public interface DiagnosticCommandPid extends ObdNumberedEnum {
6 | }
7 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/info/InfoCommandPid.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.info;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.DiagnosticCommandPid;
4 | import lombok.Getter;
5 |
6 | // TODO:
7 | public enum InfoCommandPid implements DiagnosticCommandPid {
8 | ONE(1);
9 |
10 | @Getter
11 | private int number;
12 |
13 | InfoCommandPid(int number) {
14 | this.number = number;
15 | }
16 | }
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/monitors/MonitorCommandPid.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.monitors;
2 |
3 | // TODO:
4 | public enum MonitorCommandPid {
5 | ONE(1);
6 |
7 | private int number;
8 |
9 | MonitorCommandPid(int number) {
10 | this.number = number;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/AbstractSensorCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.AbstractDiagnosticCommand;
4 | import com.devesion.commons.obd.adapter.command.diagnostic.DiagnosticCommandMode;
5 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.UnitFactory;
6 | import com.devesion.commons.obd.adapter.shared.ObdNumberedEnum;
7 | import lombok.AccessLevel;
8 | import lombok.Getter;
9 | import lombok.Setter;
10 |
11 | abstract class AbstractSensorCommand extends AbstractDiagnosticCommand implements SensorCommand {
12 |
13 | @Getter(AccessLevel.PACKAGE)
14 | @Setter(AccessLevel.PACKAGE)
15 | private UnitFactory unitFactory = new UnitFactory();
16 |
17 | @Override
18 | public ObdNumberedEnum getMode() {
19 | return DiagnosticCommandMode.SENSORS;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/AmbientAirTemperatureCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.SensorCommandValue;
4 | import com.devesion.commons.obd.adapter.shared.ObdNumberedEnum;
5 |
6 | /**
7 | * Reads current ambient air temperature.
8 | */
9 | public class AmbientAirTemperatureCommand extends AbstractSensorCommand {
10 |
11 | @Override
12 | public ObdNumberedEnum getPid() {
13 | return SensorCommandPid.AMBIENT_AIR_TEMPERATURE;
14 | }
15 |
16 | @Override
17 | public SensorCommandValue getValue() {
18 | return getUnitFactory().createTemperatureValue(getResult());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/EngineCoolantTemperatureCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.SensorCommandValue;
4 | import com.devesion.commons.obd.adapter.shared.ObdNumberedEnum;
5 |
6 | /**
7 | * Reads current engine coolant temperature.
8 | */
9 | public class EngineCoolantTemperatureCommand extends AbstractSensorCommand {
10 |
11 | @Override
12 | public ObdNumberedEnum getPid() {
13 | return SensorCommandPid.ENGINE_COOLANT_TEMPERATURE;
14 | }
15 |
16 | @Override
17 | public SensorCommandValue getValue() {
18 | return getUnitFactory().createTemperatureValue(getResult());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/EngineLoadCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.SensorCommandValue;
4 | import com.devesion.commons.obd.adapter.shared.ObdNumberedEnum;
5 |
6 | /**
7 | * Reads current engine load.
8 | */
9 | public class EngineLoadCommand extends AbstractSensorCommand {
10 |
11 | @Override
12 | public ObdNumberedEnum getPid() {
13 | return SensorCommandPid.ENGINE_LOAD;
14 | }
15 |
16 | @Override
17 | public SensorCommandValue getValue() {
18 | return getUnitFactory().createPercentageValue(getResult());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/EngineRpmCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.SensorCommandValue;
4 | import com.devesion.commons.obd.adapter.shared.ObdNumberedEnum;
5 |
6 | /**
7 | * Reads current engine RPM.
8 | */
9 | public class EngineRpmCommand extends AbstractSensorCommand {
10 |
11 | @Override
12 | public ObdNumberedEnum getPid() {
13 | return SensorCommandPid.ENGINE_RPM;
14 | }
15 |
16 | @Override
17 | public SensorCommandValue getValue() {
18 | return getUnitFactory().createRpmValue(getResult());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/EngineRuntimeCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.SensorCommandValue;
4 | import com.devesion.commons.obd.adapter.shared.ObdNumberedEnum;
5 |
6 | /**
7 | * Reads current engine run time.
8 | */
9 | public class EngineRuntimeCommand extends AbstractSensorCommand {
10 |
11 | @Override
12 | public ObdNumberedEnum getPid() {
13 | return SensorCommandPid.ENGINE_RUN_TIME;
14 | }
15 |
16 | @Override
17 | public SensorCommandValue getValue() {
18 | return getUnitFactory().createTimeValue(getResult());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/FuelConsumptionRateCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.SensorCommandValue;
4 | import com.devesion.commons.obd.adapter.shared.ObdNumberedEnum;
5 |
6 | /**
7 | * Reads current fuel consumption rate.
8 | */
9 | public class FuelConsumptionRateCommand extends AbstractSensorCommand {
10 |
11 | @Override
12 | public ObdNumberedEnum getPid() {
13 | return SensorCommandPid.FUEL_CONSUMPTION_1;
14 | }
15 |
16 | @Override
17 | public SensorCommandValue getValue() {
18 | return getUnitFactory().createFuelConsumptionValue(getResult());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/FuelLevelCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.SensorCommandValue;
4 | import com.devesion.commons.obd.adapter.shared.ObdNumberedEnum;
5 |
6 | /**
7 | * Reads current fuel level percentage.
8 | */
9 | public class FuelLevelCommand extends AbstractSensorCommand {
10 |
11 | @Override
12 | public ObdNumberedEnum getPid() {
13 | return SensorCommandPid.FUEL_LEVEL;
14 | }
15 |
16 | @Override
17 | public SensorCommandValue getValue() {
18 | return getUnitFactory().createFuelLevelValue(getResult());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/FuelPressureCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.SensorCommandValue;
4 | import com.devesion.commons.obd.adapter.shared.ObdNumberedEnum;
5 |
6 | /**
7 | * Reads current fuel pressure in kPa.
8 | */
9 | public class FuelPressureCommand extends AbstractSensorCommand {
10 |
11 | @Override
12 | public ObdNumberedEnum getPid() {
13 | return SensorCommandPid.FUEL_PRESSURE;
14 | }
15 |
16 | @Override
17 | public SensorCommandValue getValue() {
18 | return getUnitFactory().createFuelPressureValue(getResult());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/FuelTypeCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.SensorCommandValue;
4 | import com.devesion.commons.obd.adapter.shared.ObdNumberedEnum;
5 |
6 | /**
7 | * Reads current fuel type.
8 | */
9 | public class FuelTypeCommand extends AbstractSensorCommand {
10 |
11 | @Override
12 | public ObdNumberedEnum getPid() {
13 | return SensorCommandPid.FUEL_TYPE;
14 | }
15 |
16 | @Override
17 | public SensorCommandValue getValue() {
18 | return getUnitFactory().createFuelTypeValue(getResult());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/IntakeAirTemperatureCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.SensorCommandValue;
4 | import com.devesion.commons.obd.adapter.shared.ObdNumberedEnum;
5 |
6 | /**
7 | * Reads current intake air temperature.
8 | */
9 | public class IntakeAirTemperatureCommand extends AbstractSensorCommand {
10 |
11 | @Override
12 | public ObdNumberedEnum getPid() {
13 | return SensorCommandPid.INTAKE_AIR_TEMPERATURE;
14 | }
15 |
16 | @Override
17 | public SensorCommandValue getValue() {
18 | return getUnitFactory().createTemperatureValue(getResult());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/MassAirFlowCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.SensorCommandValue;
4 | import com.devesion.commons.obd.adapter.shared.ObdNumberedEnum;
5 |
6 | /**
7 | * Reads current MAF value.
8 | */
9 | public class MassAirFlowCommand extends AbstractSensorCommand {
10 |
11 | @Override
12 | public ObdNumberedEnum getPid() {
13 | return SensorCommandPid.MASS_AIR_FLOW;
14 | }
15 |
16 | @Override
17 | public SensorCommandValue getValue() {
18 | return getUnitFactory().createAirFlowValue(getResult());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/SensorCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.DiagnosticCommand;
4 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.SensorCommandValue;
5 |
6 | public interface SensorCommand extends DiagnosticCommand {
7 |
8 | SensorCommandValue getValue();
9 | }
10 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/SensorCommandPid.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.DiagnosticCommandPid;
4 | import lombok.Getter;
5 |
6 | /**
7 | * Popular com.autonalyzer.adapter.android.infrastture.diagnostic command sensor's PIDs - OBD Mode 1.
8 | */
9 | public enum SensorCommandPid implements DiagnosticCommandPid {
10 | PIDS_SUPPORTED_SET_1(0x00),
11 | OVERALL_STATUS(0x01),
12 | FUEL_SYSTEM_STATUS(0x03),
13 | ENGINE_LOAD(0x04),
14 | ENGINE_COOLANT_TEMPERATURE(0x05),
15 | SHORT_TERM_FUEL_BANK1(0x06),
16 | LONG_TERM_FUEL_BANK1(0x07),
17 | SHORT_TERM_FUEL_BANK2(0x08),
18 | LONG_TERM_FUEL_BANK2(0x09),
19 | FUEL_PRESSURE(0x0A),
20 | INTAKE_MANIFOLD_PRESSURE(0x0B),
21 | ENGINE_RPM(0x0C),
22 | VEHICLE_SPEED(0x0D),
23 | INTAKE_AIR_TEMPERATURE(0x0F),
24 | MASS_AIR_FLOW(0x10),
25 | THROTTLE_POSITION_PERCENTAGE(0x11),
26 | ENGINE_RUN_TIME(0x1F),
27 | PIDS_SUPPORTED_SET_2(0x20),
28 | FUEL_LEVEL(0x2F),
29 | BAROMETRIC_PRESSURE(0x33),
30 | AMBIENT_AIR_TEMPERATURE(0x46),
31 | FUEL_TYPE(0x51),
32 | FUEL_CONSUMPTION_1(0x5E),
33 | FUEL_CONSUMPTION_2(0x5F),
34 | ENGINE_TORQUE_NM(0x63),
35 | ENGINE_TORQUE_PERCENTAGE(0x64),
36 | TURBOCHARGER_PRESSURE(0x6F),
37 | EXHAUST_PRESSURE(0x73);
38 |
39 | @Getter
40 | private int number;
41 |
42 | SensorCommandPid(int number) {
43 | this.number = number;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/SpeedCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.SensorCommandValue;
4 | import com.devesion.commons.obd.adapter.shared.ObdNumberedEnum;
5 |
6 | /**
7 | * Reads current Vehicle Speed value.
8 | */
9 | public class SpeedCommand extends AbstractSensorCommand {
10 |
11 | @Override
12 | public ObdNumberedEnum getPid() {
13 | return SensorCommandPid.VEHICLE_SPEED;
14 | }
15 |
16 | @Override
17 | public SensorCommandValue getValue() {
18 | return getUnitFactory().createSpeedValue(getResult());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/ThrottlePositionCommand.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.SensorCommandValue;
4 | import com.devesion.commons.obd.adapter.shared.ObdNumberedEnum;
5 |
6 | /**
7 | * Reads current Throttle Position Percentage.
8 | */
9 | public class ThrottlePositionCommand extends AbstractSensorCommand {
10 |
11 | @Override
12 | public ObdNumberedEnum getPid() {
13 | return SensorCommandPid.THROTTLE_POSITION_PERCENTAGE;
14 | }
15 |
16 | @Override
17 | public SensorCommandValue getValue() {
18 | return getUnitFactory().createPercentageValue(getResult());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/AbstractSensorCommandValue.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 | import lombok.AccessLevel;
5 | import lombok.Getter;
6 | import lombok.extern.slf4j.Slf4j;
7 |
8 | @Slf4j
9 | abstract class AbstractSensorCommandValue implements SensorCommandValue {
10 |
11 | @Getter(AccessLevel.PACKAGE)
12 | private CommandResult commandResult = CommandResult.empty();
13 |
14 | public AbstractSensorCommandValue(CommandResult commandResult) {
15 | this.commandResult = commandResult;
16 | }
17 |
18 | @Override
19 | public int getIntValue() {
20 | return (int) getFloatValue();
21 | }
22 |
23 | @Override
24 | public float getFloatValue() {
25 | return calculateValue();
26 | }
27 |
28 | protected int getResultByteNumber(int byteNumber) {
29 | return commandResult.getByteNumber(byteNumber);
30 | }
31 |
32 | protected abstract float calculateValue();
33 |
34 | @Override
35 | public String toString() {
36 | final StringBuilder sb = new StringBuilder("AbstractSensorCommandValue{");
37 | sb.append("intValue=").append(getIntValue()).append(", ").append("floatValue=").append(getFloatValue()).append('}');
38 | return sb.toString();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/AirFlowValue.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 |
5 | /**
6 | * Represents Air Flow Value Object.
7 | */
8 | class AirFlowValue extends SimpleValue {
9 |
10 | private static final float AIR_FLOW_DIVISOR = 100.0f;
11 |
12 | AirFlowValue(CommandResult commandResult) {
13 | super(commandResult, AIR_FLOW_DIVISOR);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/FuelConsumptionValue.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 |
5 | /**
6 | * Represents Fuel Consumption Value Object.
7 | */
8 | class FuelConsumptionValue extends SimpleValue {
9 |
10 | private static final float FUEL_CONSUMPTION_DIVISOR = 20f;
11 |
12 | FuelConsumptionValue(CommandResult commandResult) {
13 | super(commandResult, FUEL_CONSUMPTION_DIVISOR);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/FuelPressureValue.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 |
5 | /**
6 | * Represents Fuel pressure Value Object.
7 | */
8 | class FuelPressureValue extends PressureValue {
9 |
10 | FuelPressureValue(CommandResult commandResult) {
11 | super(commandResult);
12 | }
13 |
14 | @Override
15 | protected float calculateValue() {
16 | int majorByte = getResultByteNumber(0);
17 | return majorByte * 3;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/FuelTypeValue.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 | import com.google.common.base.Optional;
5 | import lombok.AccessLevel;
6 | import lombok.Getter;
7 |
8 | /**
9 | * Represents Fuel Type Value Object.
10 | */
11 | class FuelTypeValue extends AbstractSensorCommandValue {
12 |
13 | public FuelTypeValue(CommandResult commandResult) {
14 | super(commandResult);
15 | }
16 |
17 | @Override
18 | protected float calculateValue() {
19 | return getResultByteNumber(0);
20 | }
21 |
22 | public Optional getType() {
23 | return FuelType.valueOf(getIntValue());
24 | }
25 |
26 | public enum FuelType {
27 | GASOLINE(0x01),
28 | METHANOL(0x02),
29 | ETHANOL(0x03),
30 | DIESEL(0x04),
31 | LPG(0x05),
32 | CNG(0x06),
33 | PROPANE(0x07),
34 | ELECTRIC(0x08),
35 | BIFUEL_RUNNING_GASOLINE(0x09),
36 | BIFUEL_RUNNING_METHANOL(0x0A),
37 | BIFUEL_RUNNING_ETHANOL(0x0B),
38 | BIFUEL_RUNNING_LPG(0x0C),
39 | BIFUEL_RUNNING_CNG(0x0D),
40 | BIFUEL_RUNNING_PROPANE(0x0E),
41 | BIFUEL_RUNNING_ELECTRIC(0x0F),
42 | BIFUEL_RUNNING_GASOLINE_ELECTRIC(0x10),
43 | HYBRID_GASOLINE(0x11),
44 | HYBRID_ETHANOL(0x12),
45 | HYBRID_DIESEL(0x13),
46 | HYBRID_ELECTRIC(0x14),
47 | HYBRID_MIXED(0x15),
48 | HYBRID_REGENERATIVE(0x16);
49 |
50 | @Getter(AccessLevel.PACKAGE)
51 | private int typeNumber;
52 |
53 | FuelType(int typeNumber) {
54 | this.typeNumber = typeNumber;
55 | }
56 |
57 | public static Optional valueOf(int typeNumber) {
58 | for (FuelType type : values()) {
59 | if (type.typeNumber == typeNumber) {
60 | return Optional.of(type);
61 | }
62 | }
63 |
64 | return Optional.absent();
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/PercentageValue.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 |
5 | /**
6 | * Represents Percentage Value Object.
7 | */
8 | class PercentageValue extends AbstractSensorCommandValue {
9 |
10 | PercentageValue(CommandResult commandResult) {
11 | super(commandResult);
12 | }
13 |
14 | @Override
15 | protected float calculateValue() {
16 | int majorByte = getResultByteNumber(0);
17 | return (majorByte * 100.0f) / 255.0f;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/PressureValue.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 |
5 | /**
6 | * Represents Pressure Value Object.
7 | */
8 | class PressureValue extends AbstractSensorCommandValue {
9 |
10 | PressureValue(CommandResult commandResult) {
11 | super(commandResult);
12 | }
13 |
14 | @Override
15 | protected float calculateValue() {
16 | return 0;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/RpmValue.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 |
5 | /**
6 | * Represents RPM Value Object.
7 | */
8 | class RpmValue extends SimpleValue {
9 |
10 | private static final float RPM_DIVISOR = 4.0f;
11 |
12 | RpmValue(CommandResult commandResult) {
13 | super(commandResult, RPM_DIVISOR);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/SensorCommandValue.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | public interface SensorCommandValue {
4 |
5 | int getIntValue();
6 |
7 | float getFloatValue();
8 | }
9 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/SimpleValue.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 | import lombok.extern.slf4j.Slf4j;
5 |
6 | @Slf4j
7 | class SimpleValue extends AbstractSensorCommandValue {
8 |
9 | private static final int DEFAULT_MULTIPLIER = 256;
10 | private final float multiplier;
11 | private final float divisor;
12 |
13 | SimpleValue(CommandResult commandResult, float divisor) {
14 | super(commandResult);
15 | this.multiplier = DEFAULT_MULTIPLIER;
16 | this.divisor = divisor;
17 | }
18 |
19 | SimpleValue(CommandResult commandResult, float multiplier, float divisor) {
20 | super(commandResult);
21 | this.multiplier = multiplier;
22 | this.divisor = divisor;
23 | }
24 |
25 | @Override
26 | protected float calculateValue() {
27 | int majorByte = getResultByteNumber(0);
28 | int minorByte = getResultByteNumber(1);
29 | return (majorByte * multiplier + minorByte) / divisor;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/SpeedValue.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 |
5 | /**
6 | * Represents Speeds Value Object.
7 | */
8 | class SpeedValue extends AbstractSensorCommandValue {
9 |
10 | SpeedValue(CommandResult commandResult) {
11 | super(commandResult);
12 | }
13 |
14 | @Override
15 | protected float calculateValue() {
16 | return getResultByteNumber(0);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/TemperatureValue.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 |
5 | /**
6 | * Represents Temperature Value Object.
7 | */
8 | class TemperatureValue extends AbstractSensorCommandValue {
9 |
10 | TemperatureValue(CommandResult commandResult) {
11 | super(commandResult);
12 | }
13 |
14 | @Override
15 | protected float calculateValue() {
16 | int majorByte = getResultByteNumber(0);
17 | return majorByte - 40;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/TimeValue.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 |
5 | /**
6 | * Represents Time Value Object.
7 | */
8 | class TimeValue extends SimpleValue {
9 |
10 | private static final float RPM_DIVISOR = 1.0f;
11 |
12 | TimeValue(CommandResult commandResult) {
13 | super(commandResult, RPM_DIVISOR);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/UnitFactory.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 |
5 | public class UnitFactory {
6 |
7 | public SensorCommandValue createAirFlowValue(CommandResult commandResult) {
8 | return new AirFlowValue(commandResult);
9 | }
10 |
11 | public SensorCommandValue createFuelConsumptionValue(CommandResult commandResult) {
12 | return new FuelConsumptionValue(commandResult);
13 | }
14 |
15 | public SensorCommandValue createFuelLevelValue(CommandResult commandResult) {
16 | return new PercentageValue(commandResult);
17 | }
18 |
19 | public SensorCommandValue createFuelTypeValue(CommandResult commandResult) {
20 | return new FuelTypeValue(commandResult);
21 | }
22 |
23 | public SensorCommandValue createPercentageValue(CommandResult commandResult) {
24 | return new PercentageValue(commandResult);
25 | }
26 |
27 | public SensorCommandValue createPressureValue(CommandResult commandResult) {
28 | return new PressureValue(commandResult);
29 | }
30 |
31 | public SensorCommandValue createFuelPressureValue(CommandResult commandResult) {
32 | return new FuelPressureValue(commandResult);
33 | }
34 |
35 | public SensorCommandValue createRpmValue(CommandResult commandResult) {
36 | return new RpmValue(commandResult);
37 | }
38 |
39 | public SensorCommandValue createSpeedValue(CommandResult commandResult) {
40 | return new SpeedValue(commandResult);
41 | }
42 |
43 | public SensorCommandValue createTemperatureValue(CommandResult commandResult) {
44 | return new TemperatureValue(commandResult);
45 | }
46 |
47 | public SensorCommandValue createTimeValue(CommandResult commandResult) {
48 | return new TimeValue(commandResult);
49 | }
50 |
51 | public SensorCommandValue createVoltageValue(CommandResult commandResult) {
52 | return new VoltageValue(commandResult);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/VoltageValue.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 |
5 | /**
6 | * Represents Voltage Value Object.
7 | */
8 | class VoltageValue extends AbstractSensorCommandValue {
9 |
10 | VoltageValue(CommandResult commandResult) {
11 | super(commandResult);
12 | }
13 |
14 | @Override
15 | protected float calculateValue() {
16 | return 0;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/invoker/CommandExceptionFactory.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.invoker;
2 |
3 | class CommandExceptionFactory {
4 | }
5 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/command/invoker/CommandInvoker.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.invoker;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 | import com.devesion.commons.obd.adapter.command.ObdCommand;
5 | import com.devesion.commons.obd.adapter.link.ObdLink;
6 | import lombok.extern.slf4j.Slf4j;
7 |
8 | /**
9 | * Responsible for invoking OBD Commands.
10 | */
11 | @Slf4j
12 | public class CommandInvoker {
13 |
14 | private final ObdLink obdLink;
15 |
16 | public CommandInvoker(ObdLink obdLink) {
17 | this.obdLink = obdLink;
18 | }
19 |
20 | public void invokeQuietly(ObdCommand command) {
21 | try {
22 | invoke(command);
23 | } catch (Exception e) {
24 | log.error("cannot invoke command {} - {}", command, e.getMessage());
25 | }
26 | }
27 |
28 | public void invoke(ObdCommand command) {
29 | log.debug("invoking OBD Command '{}'", command);
30 | CommandResult result = obdLink.sendCommand(command);
31 | log.debug("OBD Command result '{}'", result);
32 | command.setResult(result);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/link/CommandMarshaller.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.link;
2 |
3 | import com.devesion.commons.obd.adapter.command.ObdCommand;
4 |
5 | /**
6 | * Represents OBD command marshaller interface.
7 | */
8 | public interface CommandMarshaller {
9 |
10 | String marshal(ObdCommand command);
11 | }
12 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/link/CommandUnmarshaller.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.link;
2 |
3 | import com.devesion.commons.obd.adapter.command.ObdCommand;
4 | import com.devesion.commons.obd.adapter.command.CommandResult;
5 |
6 | /**
7 | * Represents OBD command unmarshaller interface.
8 | */
9 | public interface CommandUnmarshaller {
10 |
11 | CommandResult unmarshal(ObdCommand command, String data);
12 | }
13 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/link/ObdLink.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.link;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 | import com.devesion.commons.obd.adapter.command.ObdCommand;
5 |
6 | /**
7 | * Represents OBD link between two nodes (ie. bluetooth device and PC).
8 | */
9 | public interface ObdLink {
10 |
11 | CommandResult sendCommand(ObdCommand command);
12 | }
13 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/link/elm/AbstractCommandMarshaller.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.link.elm;
2 |
3 | import com.devesion.commons.obd.adapter.link.CommandMarshaller;
4 | import com.devesion.commons.obd.adapter.shared.HexTools;
5 |
6 | abstract class AbstractCommandMarshaller implements CommandMarshaller {
7 | private static final String SPACE = " ";
8 | private static final String CR = "\r";
9 |
10 | protected String buildRequest(String mnemonic, String operands) {
11 | return mnemonic + SPACE + operands + CR;
12 | }
13 |
14 | protected String buildRequestWithCount(String mnemonic, String operands, int count) {
15 | return mnemonic + SPACE + operands + HexTools.toHexString(count) + CR;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/link/elm/AbstractCommandUnmarshaller.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.link.elm;
2 |
3 | import com.devesion.commons.obd.adapter.command.ObdCommand;
4 | import com.devesion.commons.obd.adapter.link.CommandUnmarshaller;
5 | import com.devesion.commons.obd.adapter.shared.ObdNoDataForCommandResponseException;
6 | import com.devesion.commons.obd.adapter.shared.ObdNotProperlyInitializedException;
7 |
8 | abstract class AbstractCommandUnmarshaller implements CommandUnmarshaller {
9 |
10 | private static final String ELM_WHITE = "[\\s]";
11 | private static final String ELM_CAN_BUS_SEPARATOR = "[0-9]:";
12 | private static final String ELM_NODATA_ERROR = "NODATA";
13 | private static final String ELM_SEARCHING_ERROR = "SEARCHING";
14 | private static final String ELM_BUS_ERROR = "BUS";
15 |
16 | protected String normalizeResponse(String responseData) {
17 | return responseData
18 | .replaceAll(ELM_WHITE, "")
19 | .replaceAll(ELM_CAN_BUS_SEPARATOR, "")
20 | .toUpperCase();
21 | }
22 |
23 | protected void checkResponse(ObdCommand command, String responseData) {
24 | if (responseData.contains(ELM_NODATA_ERROR)) {
25 | throw new ObdNoDataForCommandResponseException(command, responseData);
26 | }
27 |
28 | if (responseData.contains(ELM_SEARCHING_ERROR)) {
29 | throw new ObdNotProperlyInitializedException(command, responseData);
30 | }
31 |
32 | if (responseData.contains(ELM_BUS_ERROR)) {
33 | throw new ObdNotProperlyInitializedException(command, responseData);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/link/elm/AtCommandMarshaller.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.link.elm;
2 |
3 | import com.devesion.commons.obd.adapter.command.ObdCommand;
4 | import com.devesion.commons.obd.adapter.command.at.AtCommand;
5 | import lombok.extern.slf4j.Slf4j;
6 |
7 | @Slf4j
8 | class AtCommandMarshaller extends AbstractCommandMarshaller {
9 |
10 | private static final String PROTOCOL_COMMAND_MNEMONIC = "AT";
11 |
12 | @Override
13 | public String marshal(ObdCommand command) {
14 | AtCommand protocolCommand = (AtCommand) command;
15 | String commandMnemonic = PROTOCOL_COMMAND_MNEMONIC;
16 | String commandOperands = protocolCommand.getOperands();
17 | return buildRequest(commandMnemonic, commandOperands);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/link/elm/AtCommandUnmarshaller.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.link.elm;
2 |
3 | import com.devesion.commons.obd.adapter.command.ObdCommand;
4 | import com.devesion.commons.obd.adapter.command.CommandResult;
5 | import com.devesion.commons.obd.adapter.shared.ObdInvalidCommandResponseException;
6 | import lombok.extern.slf4j.Slf4j;
7 |
8 | @Slf4j
9 | class AtCommandUnmarshaller extends AbstractCommandUnmarshaller {
10 |
11 | private static final String ELM_PROTOCOL_ACK_OK = "OK";
12 |
13 | @Override
14 | public CommandResult unmarshal(ObdCommand command, String responseData) {
15 | log.debug("unmarshaling response '{}", responseData);
16 |
17 | responseData = normalizeResponse(responseData);
18 | log.debug("after normalization '{}", responseData);
19 |
20 | if (command.checkResponseEnabled()) {
21 | checkResponse(command, responseData);
22 | if (responseData.contains(ELM_PROTOCOL_ACK_OK)) {
23 | return CommandResult.empty();
24 | }
25 |
26 | throw new ObdInvalidCommandResponseException(command, responseData);
27 | }
28 |
29 | return CommandResult.empty();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/link/elm/CommandMarshallerBridge.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.link.elm;
2 |
3 | import com.devesion.commons.obd.adapter.command.ObdCommand;
4 | import com.devesion.commons.obd.adapter.command.ObdCommandVisitor;
5 | import com.devesion.commons.obd.adapter.command.at.AtCommand;
6 | import com.devesion.commons.obd.adapter.command.diagnostic.DiagnosticCommand;
7 | import com.devesion.commons.obd.adapter.link.CommandMarshaller;
8 | import lombok.AccessLevel;
9 | import lombok.Getter;
10 |
11 | /**
12 | * Represents OBD command marshaller bridge implementation.
13 | */
14 | class CommandMarshallerBridge implements CommandMarshaller {
15 |
16 | @Override
17 | public String marshal(ObdCommand command) {
18 | MarshallerFactoryVisitor marshallerFactoryVisitor = new MarshallerFactoryVisitor();
19 | command.accept(marshallerFactoryVisitor);
20 | CommandMarshaller concreteMarshaller = marshallerFactoryVisitor.getConcreteMarshaller();
21 | return concreteMarshaller.marshal(command);
22 | }
23 |
24 | private class MarshallerFactoryVisitor implements ObdCommandVisitor {
25 |
26 | @Getter(AccessLevel.PRIVATE)
27 | private CommandMarshaller concreteMarshaller;
28 |
29 | @Override
30 | public void visit(AtCommand command) {
31 | concreteMarshaller = new AtCommandMarshaller();
32 | }
33 |
34 | @Override
35 | public void visit(DiagnosticCommand command) {
36 | concreteMarshaller = new DiagnosticCommandMarshaller();
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/link/elm/CommandUnmarshallerBridge.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.link.elm;
2 |
3 | import com.devesion.commons.obd.adapter.command.ObdCommand;
4 | import com.devesion.commons.obd.adapter.command.ObdCommandVisitor;
5 | import com.devesion.commons.obd.adapter.command.at.AtCommand;
6 | import com.devesion.commons.obd.adapter.command.diagnostic.DiagnosticCommand;
7 | import com.devesion.commons.obd.adapter.command.CommandResult;
8 | import com.devesion.commons.obd.adapter.link.CommandUnmarshaller;
9 | import lombok.AccessLevel;
10 | import lombok.Getter;
11 |
12 | /**
13 | * Represents OBD command unmarshaller bridge implementation.
14 | */
15 | class CommandUnmarshallerBridge implements CommandUnmarshaller {
16 |
17 | @Override
18 | public CommandResult unmarshal(ObdCommand command, String responseData) {
19 | UnmarshallerFactoryVisitor unmarshallerFactoryVisitor = new UnmarshallerFactoryVisitor();
20 | command.accept(unmarshallerFactoryVisitor);
21 | CommandUnmarshaller concreteUnmarshaller = unmarshallerFactoryVisitor.getConcreteUnmarshaller();
22 | return concreteUnmarshaller.unmarshal(command, responseData);
23 | }
24 |
25 | private class UnmarshallerFactoryVisitor implements ObdCommandVisitor {
26 |
27 | @Getter(AccessLevel.PRIVATE)
28 | private CommandUnmarshaller concreteUnmarshaller;
29 |
30 | @Override
31 | public void visit(AtCommand command) {
32 | concreteUnmarshaller = new AtCommandUnmarshaller();
33 | }
34 |
35 | @Override
36 | public void visit(DiagnosticCommand command) {
37 | concreteUnmarshaller = new DiagnosticCommandUnmarshaller();
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/link/elm/DiagnosticCommandMarshaller.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.link.elm;
2 |
3 | import com.devesion.commons.obd.adapter.command.ObdCommand;
4 | import com.devesion.commons.obd.adapter.command.diagnostic.DiagnosticCommand;
5 | import com.devesion.commons.obd.adapter.shared.HexTools;
6 | import lombok.extern.slf4j.Slf4j;
7 |
8 | @Slf4j
9 | class DiagnosticCommandMarshaller extends AbstractCommandMarshaller {
10 |
11 | @Override
12 | public String marshal(ObdCommand command) {
13 | DiagnosticCommand diagnosticCommand = (DiagnosticCommand) command;
14 | String commandMnemonic = HexTools.toHexString(diagnosticCommand.getMode());
15 | String commandOperands = HexTools.toHexString(diagnosticCommand.getPid());
16 | return buildRequestWithCount(commandMnemonic, commandOperands, 1);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/link/elm/DiagnosticCommandUnmarshaller.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.link.elm;
2 |
3 | import com.devesion.commons.obd.adapter.command.ObdCommand;
4 | import com.devesion.commons.obd.adapter.command.diagnostic.DiagnosticCommand;
5 | import com.devesion.commons.obd.adapter.command.CommandResult;
6 | import com.devesion.commons.obd.adapter.shared.HexTools;
7 | import com.devesion.commons.obd.adapter.shared.ObdInvalidCommandResponseException;
8 | import lombok.extern.slf4j.Slf4j;
9 |
10 | import java.nio.IntBuffer;
11 |
12 | @Slf4j
13 | class DiagnosticCommandUnmarshaller extends AbstractCommandUnmarshaller {
14 |
15 | private static final String ELM_DIAGNOSTIC_ACK_OK = "41";
16 | private static final String ELM_DIAGNOSTIC_RESPONSE_REGEXP = "([0-9A-F]{2})+";
17 | private static final int ELM_MAX_COMMAND_RESPONSE_LENGTH = 256;
18 |
19 | @Override
20 | public CommandResult unmarshal(ObdCommand command, String responseData) {
21 | DiagnosticCommand diagnosticCommand = (DiagnosticCommand) command;
22 | log.debug("unmarshaling response");
23 | log.debug(responseData);
24 |
25 | responseData = normalizeResponse(responseData);
26 | log.debug("after normalization '{}'", responseData);
27 |
28 | responseData = omitMagicSequence(diagnosticCommand, responseData);
29 | log.debug("after omitting magic sequence '{}'", responseData);
30 |
31 | checkResponse(command, responseData);
32 | checkDiagnosticResponse(command, responseData);
33 |
34 | IntBuffer responseBuffer = readByteBuffer(responseData);
35 | return CommandResult.withBuffer(responseBuffer);
36 | }
37 |
38 | private void checkDiagnosticResponse(ObdCommand command, String responseData) {
39 | if (!responseData.matches(ELM_DIAGNOSTIC_RESPONSE_REGEXP)) {
40 | throw new ObdInvalidCommandResponseException(command, responseData);
41 | }
42 | }
43 |
44 | private String omitMagicSequence(DiagnosticCommand command, String responseData) {
45 | String magicSequence = ELM_DIAGNOSTIC_ACK_OK + HexTools.toHexString(command.getPid());
46 | log.debug("magic sequence {}", magicSequence);
47 |
48 | int magicSequenceIndex = responseData.indexOf(magicSequence);
49 | if (magicSequenceIndex < 0) {
50 | return responseData;
51 | }
52 |
53 | int magicSequenceLength = magicSequence.length();
54 | return responseData.substring(magicSequenceIndex + magicSequenceLength);
55 | }
56 |
57 | private IntBuffer readByteBuffer(String data) {
58 | IntBuffer buffer = IntBuffer.allocate(ELM_MAX_COMMAND_RESPONSE_LENGTH);
59 | int readByteIndex = 0;
60 | int readCharIndex = 0;
61 | while (readByteIndex < data.length()) {
62 | int readByte = HexTools.fromHexString(data, readByteIndex, readByteIndex + 2);
63 | buffer.put(readByte);
64 | readByteIndex += 2;
65 | readCharIndex += 1;
66 |
67 | if (readCharIndex >= ELM_MAX_COMMAND_RESPONSE_LENGTH) {
68 | break;
69 | }
70 | }
71 |
72 | buffer.flip();
73 | return buffer;
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/link/elm/ElmLink.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.link.elm;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 | import com.devesion.commons.obd.adapter.command.ObdCommand;
5 | import com.devesion.commons.obd.adapter.link.CommandMarshaller;
6 | import com.devesion.commons.obd.adapter.link.CommandUnmarshaller;
7 | import com.devesion.commons.obd.adapter.link.ObdLink;
8 | import lombok.AccessLevel;
9 | import lombok.Getter;
10 | import lombok.extern.slf4j.Slf4j;
11 |
12 | import java.io.InputStream;
13 | import java.io.OutputStream;
14 |
15 | /**
16 | * Represents ELM link between two nodes (ie. bluetooth device and PC).
17 | */
18 | @Slf4j
19 | public class ElmLink implements ObdLink {
20 |
21 | private final ElmTransport transport;
22 |
23 | @Getter(AccessLevel.PACKAGE)
24 | private CommandMarshaller commandMarshaller;
25 |
26 | @Getter(AccessLevel.PACKAGE)
27 | private CommandUnmarshaller commandUnmarshaller;
28 |
29 | public ElmLink(InputStream inputStream, OutputStream outputStream) {
30 | this(new ElmTransport(inputStream, outputStream));
31 | }
32 |
33 | public ElmLink(ElmTransport transport) {
34 | this(transport, new CommandMarshallerBridge(), new CommandUnmarshallerBridge());
35 | }
36 |
37 | public ElmLink(ElmTransport transport, CommandMarshaller commandMarshaller, CommandUnmarshaller commandUnmarshaller) {
38 | this.transport = transport;
39 | this.commandMarshaller = commandMarshaller;
40 | this.commandUnmarshaller = commandUnmarshaller;
41 | }
42 |
43 | @Override
44 | public CommandResult sendCommand(ObdCommand command) {
45 | String commandData = commandMarshaller.marshal(command);
46 | String commandResultData = transport.sendDataAndReadResponse(commandData);
47 | return commandUnmarshaller.unmarshal(command, commandResultData);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/link/elm/ElmTransport.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.link.elm;
2 |
3 | import com.devesion.commons.obd.adapter.shared.ObdCommunicationException;
4 | import lombok.extern.slf4j.Slf4j;
5 |
6 | import java.io.IOException;
7 | import java.io.InputStream;
8 | import java.io.OutputStream;
9 |
10 | /**
11 | * Represents ELM IO transport between two nodes (ie. bluetooth device and PC).
12 | */
13 | @Slf4j
14 | public class ElmTransport {
15 | private static final char ELM_PROMPT = '>';
16 |
17 | private final InputStream inputStream;
18 | private final OutputStream outputStream;
19 |
20 | public ElmTransport(InputStream inputStream, OutputStream outputStream) {
21 | this.inputStream = inputStream;
22 | this.outputStream = outputStream;
23 | }
24 |
25 | public String sendDataAndReadResponse(String data) {
26 | sendData(data);
27 | return readData();
28 | }
29 |
30 | public void sendData(String data) {
31 | log.debug("Sending bytes '{}'", data);
32 | writeBytes(data);
33 | }
34 |
35 | private void writeBytes(String data) {
36 | try {
37 | outputStream.write(data.getBytes());
38 | outputStream.flush();
39 | } catch (IOException e) {
40 | throw new ObdCommunicationException("cannot send data to output stream", e);
41 | }
42 | }
43 |
44 | public String readData() {
45 | log.debug("waiting for response");
46 | StringBuilder res = new StringBuilder();
47 | char c;
48 | while ((c = readChar()) != ELM_PROMPT) {
49 | log.debug("read char '{}'", c);
50 | res.append(c);
51 | }
52 |
53 | log.debug("reading end");
54 | String data = res.toString().trim();
55 | log.debug("Read raw data '{}'", data);
56 | return data;
57 | }
58 |
59 | private char readChar() {
60 | try {
61 | return (char) inputStream.read();
62 | } catch (IOException e) {
63 | throw new ObdCommunicationException("cannot read data from input stream", e);
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/shared/HexTools.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.shared;
2 |
3 | public final class HexTools {
4 |
5 | private HexTools() {
6 | throw new AssertionError();
7 | }
8 |
9 | public static int fromHexString(String data, int begin, int end) {
10 | return Integer.decode("0x" + data.substring(begin, end));
11 | }
12 |
13 | public static String toHexString(ObdNumberedEnum numberedEnum) {
14 | return toHexString(numberedEnum.getNumber());
15 | }
16 |
17 | public static String toHexString(int value) {
18 | return Integer.toHexString(0x100 | (0xFF & value)).substring(1).toUpperCase();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/shared/ObdAbstractRuntimeException.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.shared;
2 |
3 | /**
4 | * Runtime exception superclass for OBD Adapter.
5 | */
6 | public abstract class ObdAbstractRuntimeException extends RuntimeException {
7 |
8 | public ObdAbstractRuntimeException() {
9 | }
10 |
11 | public ObdAbstractRuntimeException(String message, Throwable cause) {
12 | super(message, cause);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/shared/ObdCommandResponseException.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.shared;
2 |
3 | import com.devesion.commons.obd.adapter.command.ObdCommand;
4 | import lombok.Getter;
5 |
6 | /**
7 | * Represents invalid OBD command.
8 | */
9 | public class ObdCommandResponseException extends ObdCommunicationException {
10 |
11 | @Getter
12 | private ObdCommand command;
13 |
14 | private String responseData;
15 |
16 | public ObdCommandResponseException(ObdCommand command) {
17 | this.command = command;
18 | }
19 |
20 | public ObdCommandResponseException(ObdCommand command, String responseData) {
21 | this.command = command;
22 | this.responseData = responseData;
23 | }
24 |
25 | @Override
26 | public String getMessage() {
27 | String message = "command '" + command + "";
28 |
29 | if (responseData != null) {
30 | message += "', response '" + responseData + "'";
31 | }
32 |
33 | return message;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/shared/ObdCommunicationException.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.shared;
2 |
3 | /**
4 | * Represents general OBD communication exception.
5 | */
6 | public class ObdCommunicationException extends ObdAbstractRuntimeException {
7 |
8 | public ObdCommunicationException() {
9 | }
10 |
11 | public ObdCommunicationException(String message, Throwable cause) {
12 | super(message, cause);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/shared/ObdInvalidCommandResponseException.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.shared;
2 |
3 | import com.devesion.commons.obd.adapter.command.ObdCommand;
4 |
5 | /**
6 | * Represents invalid OBD command.
7 | */
8 | public class ObdInvalidCommandResponseException extends ObdCommandResponseException {
9 |
10 | private String responseData;
11 |
12 | public ObdInvalidCommandResponseException(ObdCommand command, String responseData) {
13 | super(command, responseData);
14 | this.responseData = responseData;
15 | }
16 |
17 | @Override
18 | public String getMessage() {
19 | StringBuilder sb = new StringBuilder();
20 | String superMessage = super.getMessage();
21 | sb.append(superMessage).append(", responseData - '").append(responseData).append("'");
22 | return sb.toString();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/shared/ObdNoDataForCommandResponseException.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.shared;
2 |
3 | import com.devesion.commons.obd.adapter.command.ObdCommand;
4 |
5 | /**
6 | * Represents OBD "NO DATA" response.
7 | */
8 | public class ObdNoDataForCommandResponseException extends ObdCommandResponseException {
9 |
10 | public ObdNoDataForCommandResponseException(ObdCommand command) {
11 | super(command);
12 | }
13 |
14 | public ObdNoDataForCommandResponseException(ObdCommand command, String responseData) {
15 | super(command, responseData);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/shared/ObdNotProperlyInitializedException.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.shared;
2 |
3 | import com.devesion.commons.obd.adapter.command.ObdCommand;
4 |
5 | /**
6 | * Represents OBD "SEARCHING..." or "BUS INIT" response.
7 | */
8 | public class ObdNotProperlyInitializedException extends ObdCommandResponseException {
9 |
10 | public ObdNotProperlyInitializedException(ObdCommand command, String responseData) {
11 | super(command, responseData);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/adapter/src/main/java/com/devesion/commons/obd/adapter/shared/ObdNumberedEnum.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.shared;
2 |
3 | public interface ObdNumberedEnum {
4 |
5 | int getNumber();
6 | }
7 |
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/ObdAdapterClient.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd;
2 |
3 | import com.devesion.commons.obd.adapter.command.at.AdaptiveTimeoutProtocolCommand;
4 | import com.devesion.commons.obd.adapter.command.at.ResetCommand;
5 | import com.devesion.commons.obd.adapter.command.at.SelectProtocolCommand;
6 | import com.devesion.commons.obd.adapter.command.at.SetDefaultsCommand;
7 | import com.devesion.commons.obd.adapter.command.at.SetEchoCommand;
8 | import com.devesion.commons.obd.adapter.command.at.SetLineFeedCommand;
9 | import com.devesion.commons.obd.adapter.command.at.SetMemoryCommand;
10 | import com.devesion.commons.obd.adapter.command.at.SetSpacesCommand;
11 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.EngineCoolantTemperatureCommand;
12 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.EngineLoadCommand;
13 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.EngineRpmCommand;
14 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.IntakeAirTemperatureCommand;
15 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.MassAirFlowCommand;
16 | import com.devesion.commons.obd.adapter.command.invoker.CommandInvoker;
17 | import com.devesion.commons.obd.adapter.link.ObdLink;
18 | import com.devesion.commons.obd.adapter.link.elm.ElmLink;
19 | import gnu.io.CommPortIdentifier;
20 | import gnu.io.SerialPort;
21 | import gnu.io.SerialPortEvent;
22 | import gnu.io.SerialPortEventListener;
23 | import lombok.extern.slf4j.Slf4j;
24 |
25 | import java.io.InputStream;
26 | import java.io.OutputStream;
27 | import java.util.Enumeration;
28 |
29 | @Slf4j
30 | public class ObdAdapterClient implements SerialPortEventListener {
31 |
32 | private static final int TIME_OUT = 2000;
33 | private static final int DATA_RATE = 38400;
34 | private InputStream is;
35 | private OutputStream os;
36 |
37 | public static void main(String... args) {
38 | ObdAdapterClient client = new ObdAdapterClient();
39 | client.run();
40 | }
41 |
42 | private void run() {
43 | prepareSerialPort();
44 | sendTestCommands();
45 | }
46 |
47 | private void prepareSerialPort() {
48 | // String wantedPortName = "/dev/pts/34";
49 | String wantedPortName = "/dev/ttyUSB0";
50 | System.setProperty("gnu.io.rxtx.SerialPorts", wantedPortName);
51 | Enumeration portIdentifiers = CommPortIdentifier.getPortIdentifiers();
52 |
53 | CommPortIdentifier portId = null;
54 |
55 | while (portIdentifiers.hasMoreElements()) {
56 | CommPortIdentifier pid = (CommPortIdentifier) portIdentifiers.nextElement();
57 | if (pid.getPortType() == CommPortIdentifier.PORT_SERIAL &&
58 | pid.getName().equals(wantedPortName)) {
59 | portId = pid;
60 | break;
61 | }
62 | }
63 |
64 | try {
65 | // open serial port, and use class name for the appName.
66 | SerialPort serialPort = (SerialPort) portId.open(ObdAdapterClient.class.getName(), TIME_OUT);
67 |
68 | // set port parameters
69 | serialPort.setSerialPortParams(DATA_RATE,
70 | SerialPort.DATABITS_8,
71 | SerialPort.STOPBITS_1,
72 | SerialPort.PARITY_NONE);
73 |
74 | // open the streams
75 | is = serialPort.getInputStream();
76 | os = serialPort.getOutputStream();
77 |
78 | // add event listeners
79 | serialPort.addEventListener(this);
80 | serialPort.notifyOnDataAvailable(false);
81 | } catch (Exception e) {
82 | log.error("cannot connect to serial port", e);
83 | }
84 | }
85 |
86 | private void sendTestCommands() {
87 | ObdLink obdLink = new ElmLink(is, os);
88 | CommandInvoker commandInvoker = new CommandInvoker(obdLink);
89 |
90 | ResetCommand resetCommand = new ResetCommand();
91 | commandInvoker.invoke(resetCommand);
92 |
93 | SetDefaultsCommand setDefaultsCommand = new SetDefaultsCommand();
94 | commandInvoker.invoke(setDefaultsCommand);
95 |
96 | SetEchoCommand setEchoCommand = new SetEchoCommand(false);
97 | commandInvoker.invoke(setEchoCommand);
98 |
99 | SetMemoryCommand setMemoryCommand = new SetMemoryCommand(false);
100 | commandInvoker.invoke(setMemoryCommand);
101 |
102 | SetLineFeedCommand setLinefeedCommand = new SetLineFeedCommand(false);
103 | commandInvoker.invoke(setLinefeedCommand);
104 |
105 | SetSpacesCommand setSpacesCommand = new SetSpacesCommand(false);
106 | commandInvoker.invoke(setSpacesCommand);
107 |
108 | AdaptiveTimeoutProtocolCommand adaptiveTimeoutProtocol = new AdaptiveTimeoutProtocolCommand();
109 | commandInvoker.invoke(adaptiveTimeoutProtocol);
110 |
111 | SelectProtocolCommand selectProtocolCommand = new SelectProtocolCommand();
112 | commandInvoker.invoke(selectProtocolCommand);
113 |
114 | EngineRpmCommand engineRpmCommand = new EngineRpmCommand();
115 | log.info("command - '{}'", engineRpmCommand);
116 | commandInvoker.invoke(engineRpmCommand);
117 | log.info("command response - '{}'\n", engineRpmCommand.getValue());
118 |
119 | EngineLoadCommand engineLoadCommand = new EngineLoadCommand();
120 | commandInvoker.invoke(engineLoadCommand);
121 |
122 | EngineCoolantTemperatureCommand engineCoolantTemperatureCommand = new EngineCoolantTemperatureCommand();
123 | log.info("command - '{}'", engineCoolantTemperatureCommand);
124 | commandInvoker.invoke(engineCoolantTemperatureCommand);
125 | log.info("command response - '{}'\n", engineCoolantTemperatureCommand.getValue());
126 |
127 | IntakeAirTemperatureCommand intakeAirTemperatureCommand = new IntakeAirTemperatureCommand();
128 | commandInvoker.invoke(intakeAirTemperatureCommand);
129 |
130 | MassAirFlowCommand massAirFlowCommand = new MassAirFlowCommand();
131 | log.info("command - '{}'", massAirFlowCommand);
132 | commandInvoker.invoke(massAirFlowCommand);
133 | log.info("command response - '{}'\n", massAirFlowCommand.getValue());
134 | //
135 | // ThrottlePositionCommand throttlePositionCommand = new ThrottlePositionCommand();
136 | // log.info("command - '{}'", throttlePositionCommand);
137 | // commandInvoker.invoke(throttlePositionCommand);
138 | // log.info("command response - '{}'\n", throttlePositionCommand.getValue().getFloatValue());
139 | //
140 | // EngineRuntimeCommand engineRuntimeCommand = new EngineRuntimeCommand();
141 | // commandInvoker.invoke(engineRuntimeCommand);
142 | }
143 |
144 | @Override
145 | public void serialEvent(SerialPortEvent oEvent) {
146 | // Ignore all the other eventTypes, but you should consider the other
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/TestSupport.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd;
2 |
3 | import org.mockito.invocation.InvocationOnMock;
4 | import org.mockito.stubbing.Answer;
5 |
6 | import java.util.UUID;
7 | import java.util.concurrent.ThreadLocalRandom;
8 |
9 | public final class TestSupport {
10 |
11 | private static ThreadLocalRandom random = ThreadLocalRandom.current();
12 |
13 | private TestSupport() {
14 | throw new AssertionError();
15 | }
16 |
17 | public static String getRandomString() {
18 | UUID randomUUID = UUID.randomUUID();
19 | return randomUUID.toString();
20 | }
21 |
22 | public static boolean getRandomBoolean() {
23 | return random.nextBoolean();
24 | }
25 |
26 | public static int getRandomInt() {
27 | return Math.abs(random.nextInt());
28 | }
29 |
30 | public static int getRandomInt(int max) {
31 | return Math.abs(random.nextInt(0, max));
32 | }
33 |
34 | public static long getRandomLong() {
35 | return Math.abs(random.nextLong());
36 | }
37 |
38 | public static int getRandomIntByte() {
39 | return getRandomInt(255);
40 | }
41 |
42 | public static class InputStreamAnswer implements Answer {
43 |
44 | private final byte[] rawData;
45 | private int curIndex = 0;
46 |
47 | public InputStreamAnswer(String streamData) {
48 | this.rawData = streamData.getBytes();
49 | }
50 |
51 | @Override
52 | public Object answer(InvocationOnMock invocation) throws Throwable {
53 | return rawData[curIndex++];
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/AbstractCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command;
2 |
3 | import org.mockito.Mock;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import static org.fest.assertions.api.Assertions.assertThat;
8 | import static org.mockito.MockitoAnnotations.initMocks;
9 | import static org.powermock.api.mockito.PowerMockito.verifyZeroInteractions;
10 |
11 | public class AbstractCommandTest {
12 |
13 | @Mock
14 | private CommandResult commandResultMock;
15 |
16 | @Mock
17 | private ObdCommandVisitor obdCommandVisitorMock;
18 |
19 | private AbstractCommand sut;
20 |
21 | @BeforeMethod
22 | private void beforeMethod() {
23 | initMocks(this);
24 | sut = new FakeAbstractCommand();
25 | }
26 |
27 | @Test
28 | public void getResultShouldReturnSetValue() throws Exception {
29 | // given
30 |
31 | // when
32 | sut.setResult(commandResultMock);
33 | CommandResult commandResult = sut.getResult();
34 |
35 | // then
36 | assertThat(commandResult).isEqualTo(commandResultMock);
37 | }
38 |
39 | @Test
40 | public void acceptShouldDoNothing() throws Exception {
41 | // given
42 |
43 | // when
44 | sut.accept(obdCommandVisitorMock);
45 |
46 | // then
47 | verifyZeroInteractions(obdCommandVisitorMock);
48 | }
49 |
50 | private static class FakeAbstractCommand extends AbstractCommand {
51 | @Override
52 | public void accept(ObdCommandVisitor visitor) {
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/CommandResultTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command;
2 |
3 | import com.devesion.commons.obd.TestSupport;
4 | import org.testng.annotations.Test;
5 |
6 | import java.nio.IntBuffer;
7 |
8 | import static org.fest.assertions.api.Assertions.assertThat;
9 |
10 | public class CommandResultTest {
11 |
12 | private CommandResult sut;
13 |
14 | @Test
15 | public void withBufferShouldCreateResultWithPassedBuffer() throws Exception {
16 | // given
17 | IntBuffer expectedResponseBuffer = IntBuffer.allocate(0);
18 |
19 | // when
20 | sut = CommandResult.withBuffer(expectedResponseBuffer);
21 | IntBuffer responseBuffer = sut.getResponseBuffer();
22 |
23 | // then
24 | assertThat(responseBuffer).isEqualTo(expectedResponseBuffer);
25 | }
26 |
27 | @Test
28 | public void emptyShouldCreateResultWithEmptyBuffer() throws Exception {
29 | // given
30 |
31 | // when
32 | sut = CommandResult.empty();
33 | IntBuffer responseBuffer = sut.getResponseBuffer();
34 |
35 | // then
36 | assertThat(responseBuffer.limit()).isEqualTo(10);
37 | }
38 |
39 | @Test
40 | public void getByteNumberShouldReturnProperByteFromBuffer() throws Exception {
41 | // given
42 | int responseBufferLength = 100;
43 | IntBuffer expectedResponseBuffer = IntBuffer.allocate(responseBufferLength);
44 | for (int i = 0; i < responseBufferLength; i++) {
45 | int randomValue = TestSupport.getRandomInt();
46 | expectedResponseBuffer.put(randomValue);
47 | }
48 |
49 | // when
50 | sut = CommandResult.withBuffer(expectedResponseBuffer);
51 |
52 | boolean valuesAreNotEqual = false;
53 | for (int i = 0; i < responseBufferLength; i++) {
54 | int readValue = sut.getByteNumber(i);
55 | int expectedValue = expectedResponseBuffer.get(i);
56 | valuesAreNotEqual |= (readValue != expectedValue);
57 | }
58 |
59 | // then
60 | assertThat(valuesAreNotEqual).isFalse();
61 | }
62 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/at/AbstractAtCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | import com.devesion.commons.obd.adapter.command.ObdCommandVisitor;
4 | import org.mockito.Mock;
5 | import org.testng.annotations.BeforeMethod;
6 | import org.testng.annotations.Test;
7 |
8 | import static org.mockito.Mockito.verify;
9 | import static org.mockito.MockitoAnnotations.initMocks;
10 |
11 | public class AbstractAtCommandTest {
12 |
13 | @Mock
14 | private ObdCommandVisitor protocolCommandVisitorMock;
15 |
16 | private AbstractAtCommand sut;
17 |
18 | @BeforeMethod
19 | private void beforeMethod() {
20 | initMocks(this);
21 | sut = new FakeAbstractProtocolCommand();
22 | }
23 |
24 | @Test
25 | public void testAccept() throws Exception {
26 | // given
27 |
28 | // when
29 | sut.accept(protocolCommandVisitorMock);
30 |
31 | // then
32 | verify(protocolCommandVisitorMock).visit(sut);
33 | }
34 |
35 | private static class FakeAbstractProtocolCommand extends AbstractAtCommand {
36 | @Override
37 | public String getOperands() {
38 | return null;
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/at/AbstractSetStateCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | import org.testng.annotations.Test;
4 |
5 | import static org.fest.assertions.api.Assertions.assertThat;
6 |
7 | abstract class AbstractSetStateCommandTest {
8 |
9 | private AtCommand sut;
10 |
11 | @Test
12 | protected void constructorShouldSetStateOff() throws Exception {
13 | // given
14 | String expectedOperands = getOperandPrefix() + "0";
15 |
16 | // when
17 | sut = createCommand(false);
18 |
19 | // then
20 | String operands = sut.getOperands();
21 | assertThat(operands).isEqualTo(expectedOperands);
22 | }
23 |
24 | @Test
25 | protected void constructorShouldSetStateOn() throws Exception {
26 | // given
27 | String expectedOperands = getOperandPrefix() + "1";
28 |
29 | // when
30 | sut = createCommand(true);
31 |
32 | // then
33 | String operands = sut.getOperands();
34 | assertThat(operands).isEqualTo(expectedOperands);
35 | }
36 |
37 | protected abstract String getOperandPrefix();
38 |
39 | protected abstract AtCommand createCommand(boolean state);
40 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/at/SelectProtocolCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | import org.testng.annotations.BeforeMethod;
4 | import org.testng.annotations.Test;
5 |
6 | import static org.fest.assertions.api.Assertions.assertThat;
7 |
8 | public class SelectProtocolCommandTest {
9 |
10 | private SelectProtocolCommand sut;
11 |
12 | @BeforeMethod
13 | private void beforeMethod() {
14 | sut = new SelectProtocolCommand();
15 | }
16 |
17 | @Test
18 | public void getOperandsShouldReturnProperElmCommand() throws Exception {
19 | // given
20 | String expectedOperands = "SP 0";
21 |
22 | // when
23 | String operands = sut.getOperands();
24 |
25 | // then
26 | assertThat(operands).isEqualTo(expectedOperands);
27 | }
28 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/at/SetEchoCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | import org.testng.annotations.Test;
4 |
5 | public class SetEchoCommandTest extends AbstractSetStateCommandTest {
6 |
7 | @Test
8 | public void constructorShouldSetEchoOff() throws Exception {
9 | constructorShouldSetStateOff();
10 | }
11 |
12 | @Test
13 | public void constructorShouldSetEchoOn() throws Exception {
14 | constructorShouldSetStateOn();
15 | }
16 |
17 | @Override
18 | protected String getOperandPrefix() {
19 | return "E";
20 | }
21 |
22 | @Override
23 | protected AtCommand createCommand(boolean state) {
24 | return new SetEchoCommand(state);
25 | }
26 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/at/SetHeadersCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | import org.testng.annotations.Test;
4 |
5 | public class SetHeadersCommandTest extends AbstractSetStateCommandTest {
6 |
7 | @Test
8 | public void constructorShouldSetHeadersOff() throws Exception {
9 | constructorShouldSetStateOff();
10 | }
11 |
12 | @Test
13 | public void constructorShouldSetHeadersOn() throws Exception {
14 | constructorShouldSetStateOn();
15 | }
16 |
17 | @Override
18 | protected String getOperandPrefix() {
19 | return "H";
20 | }
21 |
22 | @Override
23 | protected AtCommand createCommand(boolean state) {
24 | return new SetHeadersCommand(state);
25 | }
26 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/at/SetLineFeedCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | import org.testng.annotations.Test;
4 |
5 | public class SetLineFeedCommandTest extends AbstractSetStateCommandTest {
6 |
7 | @Test
8 | public void constructorShouldSetLineFeedOff() throws Exception {
9 | constructorShouldSetStateOff();
10 | }
11 |
12 | @Test
13 | public void constructorShouldSetLineFeedOn() throws Exception {
14 | constructorShouldSetStateOn();
15 | }
16 |
17 | @Override
18 | protected String getOperandPrefix() {
19 | return "L";
20 | }
21 |
22 | @Override
23 | protected AtCommand createCommand(boolean state) {
24 | return new SetLineFeedCommand(state);
25 | }
26 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/at/SetMemoryCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | import org.testng.annotations.Test;
4 |
5 | public class SetMemoryCommandTest extends AbstractSetStateCommandTest {
6 |
7 | @Test
8 | public void constructorShouldSetMemoryOff() throws Exception {
9 | constructorShouldSetStateOff();
10 | }
11 |
12 | @Test
13 | public void constructorShouldSetMemoryOn() throws Exception {
14 | constructorShouldSetStateOn();
15 | }
16 |
17 | @Override
18 | protected String getOperandPrefix() {
19 | return "M";
20 | }
21 |
22 | @Override
23 | protected AtCommand createCommand(boolean state) {
24 | return new SetMemoryCommand(state);
25 | }
26 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/at/SetSpacesCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.at;
2 |
3 | import org.testng.annotations.Test;
4 |
5 | public class SetSpacesCommandTest extends AbstractSetStateCommandTest {
6 |
7 | @Test
8 | public void constructorShouldSetSpacesOff() throws Exception {
9 | constructorShouldSetStateOff();
10 | }
11 |
12 | @Test
13 | public void constructorShouldSetSpacesOn() throws Exception {
14 | constructorShouldSetStateOn();
15 | }
16 |
17 | @Override
18 | protected String getOperandPrefix() {
19 | return "S";
20 | }
21 |
22 | @Override
23 | protected AtCommand createCommand(boolean state) {
24 | return new SetSpacesCommand(state);
25 | }
26 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/AbstractDiagnosticCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic;
2 |
3 | import com.devesion.commons.obd.adapter.command.ObdCommandVisitor;
4 | import com.devesion.commons.obd.adapter.shared.ObdNumberedEnum;
5 | import org.mockito.Mock;
6 | import org.testng.annotations.BeforeMethod;
7 | import org.testng.annotations.Test;
8 |
9 | import static org.mockito.Mockito.verify;
10 | import static org.mockito.MockitoAnnotations.initMocks;
11 |
12 | public class AbstractDiagnosticCommandTest {
13 |
14 | @Mock
15 | private ObdCommandVisitor diagnosticCommandVisitorMock;
16 |
17 | private AbstractDiagnosticCommand sut;
18 |
19 | @BeforeMethod
20 | private void beforeMethod() {
21 | initMocks(this);
22 | sut = new FakeAbstractDiagnosticCommand();
23 | }
24 |
25 | @Test
26 | public void testAccept() throws Exception {
27 | // given
28 |
29 | // when
30 | sut.accept(diagnosticCommandVisitorMock);
31 |
32 | // then
33 | verify(diagnosticCommandVisitorMock).visit(sut);
34 | }
35 |
36 | private static class FakeAbstractDiagnosticCommand extends AbstractDiagnosticCommand {
37 |
38 | @Override
39 | public ObdNumberedEnum getMode() {
40 | return null;
41 | }
42 |
43 | @Override
44 | public ObdNumberedEnum getPid() {
45 | return null;
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/AbstractSensorCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.DiagnosticCommandMode;
4 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.SensorCommandValue;
5 | import com.devesion.commons.obd.adapter.shared.ObdNumberedEnum;
6 | import org.testng.annotations.BeforeMethod;
7 | import org.testng.annotations.Test;
8 |
9 | import static org.fest.assertions.api.Assertions.assertThat;
10 | import static org.mockito.MockitoAnnotations.initMocks;
11 |
12 | public class AbstractSensorCommandTest {
13 |
14 | private AbstractSensorCommand sut;
15 |
16 | @BeforeMethod
17 | private void beforeMethod() {
18 | initMocks(this);
19 | sut = new FakeAbstractSensorCommand();
20 | }
21 |
22 | @Test
23 | public void getModeShouldReturnSensors() throws Exception {
24 | // given
25 |
26 | // when
27 | ObdNumberedEnum mode = sut.getMode();
28 |
29 | // then
30 | assertThat(mode).isEqualTo(DiagnosticCommandMode.SENSORS);
31 | }
32 |
33 | private static class FakeAbstractSensorCommand extends AbstractSensorCommand {
34 |
35 | @Override
36 | public SensorCommandValue getValue() {
37 | return null;
38 | }
39 |
40 | @Override
41 | public ObdNumberedEnum getPid() {
42 | return null;
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/AmbientAirTemperatureCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.UnitFactory;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import static org.mockito.MockitoAnnotations.initMocks;
8 |
9 | public class AmbientAirTemperatureCommandTest extends BaseSensorCommandTest {
10 |
11 | private AmbientAirTemperatureCommand sut;
12 |
13 | @BeforeMethod
14 | private void beforeMethod() {
15 | initMocks(this);
16 |
17 | sut = new AmbientAirTemperatureCommand();
18 | UnitFactory unitFactoryMock = recordUnitFactoryCreatesTemperature();
19 | sut.setUnitFactory(unitFactoryMock);
20 | }
21 |
22 | @Test
23 | public void getPidShouldReturnObdPidForSensor() throws Exception {
24 | testCommandReturnsProperPid(sut, SensorCommandPid.AMBIENT_AIR_TEMPERATURE);
25 | }
26 |
27 | @Test
28 | public void getValueShouldCreateTemperatureValueObjectFromResultBuffer() throws Exception {
29 | testCommandGetValueCreateProperValueObject(sut);
30 | }
31 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/BaseSensorCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.SensorCommandValue;
5 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.UnitFactory;
6 | import com.devesion.commons.obd.adapter.shared.ObdNumberedEnum;
7 | import org.mockito.Mock;
8 |
9 | import static org.fest.assertions.api.Assertions.assertThat;
10 | import static org.mockito.Mockito.when;
11 |
12 | abstract class BaseSensorCommandTest {
13 |
14 | @Mock
15 | private UnitFactory unitFactoryMock;
16 |
17 | @Mock
18 | private CommandResult commandResultMock;
19 |
20 | @Mock
21 | private SensorCommandValue sensorCommandValueMock;
22 |
23 | protected void testCommandReturnsProperPid(SensorCommand sut, SensorCommandPid pid) {
24 | // given
25 |
26 | // when
27 | ObdNumberedEnum mode = sut.getPid();
28 |
29 | // then
30 | assertThat(mode).isEqualTo(pid);
31 | }
32 |
33 | protected void testCommandGetValueCreateProperValueObject(SensorCommand sut) {
34 | // given
35 | sut.setResult(commandResultMock);
36 |
37 | // when
38 | SensorCommandValue value = sut.getValue();
39 |
40 | // then
41 | assertThat(value).isEqualTo(sensorCommandValueMock);
42 | }
43 |
44 | protected UnitFactory recordUnitFactoryCreatesTemperature() {
45 | when(unitFactoryMock.createTemperatureValue(commandResultMock)).thenReturn(sensorCommandValueMock);
46 | return unitFactoryMock;
47 | }
48 |
49 | protected UnitFactory recordUnitFactoryCreatesPercentage() {
50 | when(unitFactoryMock.createPercentageValue(commandResultMock)).thenReturn(sensorCommandValueMock);
51 | return unitFactoryMock;
52 | }
53 |
54 | protected UnitFactory recordUnitFactoryCreatesRpm() {
55 | when(unitFactoryMock.createRpmValue(commandResultMock)).thenReturn(sensorCommandValueMock);
56 | return unitFactoryMock;
57 | }
58 |
59 | protected UnitFactory recordUnitFactoryCreatesTime() {
60 | when(unitFactoryMock.createTimeValue(commandResultMock)).thenReturn(sensorCommandValueMock);
61 | return unitFactoryMock;
62 | }
63 |
64 | protected UnitFactory recordUnitFactoryCreatesFuelConsuption() {
65 | when(unitFactoryMock.createFuelConsumptionValue(commandResultMock)).thenReturn(sensorCommandValueMock);
66 | return unitFactoryMock;
67 | }
68 |
69 | protected UnitFactory recordUnitFactoryCreatesFuelLevel() {
70 | when(unitFactoryMock.createFuelLevelValue(commandResultMock)).thenReturn(sensorCommandValueMock);
71 | return unitFactoryMock;
72 | }
73 |
74 | protected UnitFactory recordUnitFactoryCreatesFuelType() {
75 | when(unitFactoryMock.createFuelTypeValue(commandResultMock)).thenReturn(sensorCommandValueMock);
76 | return unitFactoryMock;
77 | }
78 |
79 | protected UnitFactory recordUnitFactoryCreatesAirFlow() {
80 | when(unitFactoryMock.createAirFlowValue(commandResultMock)).thenReturn(sensorCommandValueMock);
81 | return unitFactoryMock;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/EngineCoolantTemperatureCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.UnitFactory;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import static org.mockito.MockitoAnnotations.initMocks;
8 |
9 | public class EngineCoolantTemperatureCommandTest extends BaseSensorCommandTest {
10 |
11 | private EngineCoolantTemperatureCommand sut;
12 |
13 | @BeforeMethod
14 | private void beforeMethod() {
15 | initMocks(this);
16 |
17 | sut = new EngineCoolantTemperatureCommand();
18 | UnitFactory unitFactoryMock = recordUnitFactoryCreatesTemperature();
19 | sut.setUnitFactory(unitFactoryMock);
20 | }
21 |
22 | @Test
23 | public void getPidShouldReturnObdPidForSensor() throws Exception {
24 | testCommandReturnsProperPid(sut, SensorCommandPid.ENGINE_COOLANT_TEMPERATURE);
25 | }
26 |
27 | @Test
28 | public void getValueShouldCreateTemperatureValueObjectFromResultBuffer() throws Exception {
29 | testCommandGetValueCreateProperValueObject(sut);
30 | }
31 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/EngineLoadCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.UnitFactory;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import static org.mockito.MockitoAnnotations.initMocks;
8 |
9 | public class EngineLoadCommandTest extends BaseSensorCommandTest {
10 |
11 | private EngineLoadCommand sut;
12 |
13 | @BeforeMethod
14 | private void beforeMethod() {
15 | initMocks(this);
16 |
17 | sut = new EngineLoadCommand();
18 | UnitFactory unitFactoryMock = recordUnitFactoryCreatesPercentage();
19 | sut.setUnitFactory(unitFactoryMock);
20 | }
21 |
22 | @Test
23 | public void getPidShouldReturnObdPidForSensor() throws Exception {
24 | testCommandReturnsProperPid(sut, SensorCommandPid.ENGINE_LOAD);
25 | }
26 |
27 | @Test
28 | public void getValueShouldCreatePercentageValueObjectFromResultBuffer() throws Exception {
29 | testCommandGetValueCreateProperValueObject(sut);
30 | }
31 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/EngineRpmCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.UnitFactory;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import static org.mockito.MockitoAnnotations.initMocks;
8 |
9 | public class EngineRpmCommandTest extends BaseSensorCommandTest {
10 |
11 | private EngineRpmCommand sut;
12 |
13 | @BeforeMethod
14 | private void beforeMethod() {
15 | initMocks(this);
16 |
17 | sut = new EngineRpmCommand();
18 | UnitFactory unitFactoryMock = recordUnitFactoryCreatesRpm();
19 | sut.setUnitFactory(unitFactoryMock);
20 | }
21 |
22 | @Test
23 | public void getPidShouldReturnObdPidForSensor() throws Exception {
24 | testCommandReturnsProperPid(sut, SensorCommandPid.ENGINE_RPM);
25 | }
26 |
27 | @Test
28 | public void getValueShouldCreateRpmValueObjectFromResultBuffer() throws Exception {
29 | testCommandGetValueCreateProperValueObject(sut);
30 | }
31 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/EngineRuntimeCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.UnitFactory;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import static org.mockito.MockitoAnnotations.initMocks;
8 |
9 | public class EngineRuntimeCommandTest extends BaseSensorCommandTest {
10 |
11 | private EngineRuntimeCommand sut;
12 |
13 | @BeforeMethod
14 | private void beforeMethod() {
15 | initMocks(this);
16 |
17 | sut = new EngineRuntimeCommand();
18 | UnitFactory unitFactoryMock = recordUnitFactoryCreatesTime();
19 | sut.setUnitFactory(unitFactoryMock);
20 | }
21 |
22 | @Test
23 | public void getPidShouldReturnObdPidForSensor() throws Exception {
24 | testCommandReturnsProperPid(sut, SensorCommandPid.ENGINE_RUN_TIME);
25 | }
26 |
27 | @Test
28 | public void getValueShouldCreateTimeValueObjectFromResultBuffer() throws Exception {
29 | testCommandGetValueCreateProperValueObject(sut);
30 | }
31 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/FuelConsumptionRateCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.UnitFactory;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import static org.mockito.MockitoAnnotations.initMocks;
8 |
9 | public class FuelConsumptionRateCommandTest extends BaseSensorCommandTest {
10 |
11 | private FuelConsumptionRateCommand sut;
12 |
13 | @BeforeMethod
14 | private void beforeMethod() {
15 | initMocks(this);
16 |
17 | sut = new FuelConsumptionRateCommand();
18 | UnitFactory unitFactoryMock = recordUnitFactoryCreatesFuelConsuption();
19 | sut.setUnitFactory(unitFactoryMock);
20 | }
21 |
22 | @Test
23 | public void getPidShouldReturnObdPidForSensor() throws Exception {
24 | testCommandReturnsProperPid(sut, SensorCommandPid.FUEL_CONSUMPTION_1);
25 | }
26 |
27 | @Test
28 | public void getValueShouldCreateFuelConsumptionValueObjectFromResultBuffer() throws Exception {
29 | testCommandGetValueCreateProperValueObject(sut);
30 | }
31 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/FuelLevelCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.UnitFactory;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import static org.mockito.MockitoAnnotations.initMocks;
8 |
9 | public class FuelLevelCommandTest extends BaseSensorCommandTest {
10 |
11 | private FuelLevelCommand sut;
12 |
13 | @BeforeMethod
14 | private void beforeMethod() {
15 | initMocks(this);
16 |
17 | sut = new FuelLevelCommand();
18 | UnitFactory unitFactoryMock = recordUnitFactoryCreatesFuelLevel();
19 | sut.setUnitFactory(unitFactoryMock);
20 | }
21 |
22 | @Test
23 | public void getPidShouldReturnObdPidForSensor() throws Exception {
24 | testCommandReturnsProperPid(sut, SensorCommandPid.FUEL_LEVEL);
25 | }
26 |
27 | @Test
28 | public void getValueShouldCreateFuelLevelValueObjectFromResultBuffer() throws Exception {
29 | testCommandGetValueCreateProperValueObject(sut);
30 | }
31 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/FuelTypeCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.UnitFactory;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import static org.mockito.MockitoAnnotations.initMocks;
8 |
9 | public class FuelTypeCommandTest extends BaseSensorCommandTest {
10 |
11 | private FuelTypeCommand sut;
12 |
13 | @BeforeMethod
14 | private void beforeMethod() {
15 | initMocks(this);
16 |
17 | sut = new FuelTypeCommand();
18 | UnitFactory unitFactoryMock = recordUnitFactoryCreatesFuelType();
19 | sut.setUnitFactory(unitFactoryMock);
20 | }
21 |
22 | @Test
23 | public void getPidShouldReturnObdPidForSensor() throws Exception {
24 | testCommandReturnsProperPid(sut, SensorCommandPid.FUEL_TYPE);
25 | }
26 |
27 | @Test
28 | public void getValueShouldCreateFuelTypeValueObjectFromResultBuffer() throws Exception {
29 | testCommandGetValueCreateProperValueObject(sut);
30 | }
31 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/IntakeAirTemperatureCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.UnitFactory;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import static org.mockito.MockitoAnnotations.initMocks;
8 |
9 | public class IntakeAirTemperatureCommandTest extends BaseSensorCommandTest {
10 |
11 | private IntakeAirTemperatureCommand sut;
12 |
13 | @BeforeMethod
14 | private void beforeMethod() {
15 | initMocks(this);
16 |
17 | sut = new IntakeAirTemperatureCommand();
18 | UnitFactory unitFactoryMock = recordUnitFactoryCreatesTemperature();
19 | sut.setUnitFactory(unitFactoryMock);
20 | }
21 |
22 | @Test
23 | public void getPidShouldReturnObdPidForSensor() throws Exception {
24 | testCommandReturnsProperPid(sut, SensorCommandPid.INTAKE_AIR_TEMPERATURE);
25 | }
26 |
27 | @Test
28 | public void getValueShouldCreateTemperatureValueObjectFromResultBuffer() throws Exception {
29 | testCommandGetValueCreateProperValueObject(sut);
30 | }
31 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/MassAirFlowCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.UnitFactory;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import static org.mockito.MockitoAnnotations.initMocks;
8 |
9 | public class MassAirFlowCommandTest extends BaseSensorCommandTest {
10 |
11 | private MassAirFlowCommand sut;
12 |
13 | @BeforeMethod
14 | private void beforeMethod() {
15 | initMocks(this);
16 |
17 | sut = new MassAirFlowCommand();
18 | UnitFactory unitFactoryMock = recordUnitFactoryCreatesAirFlow();
19 | sut.setUnitFactory(unitFactoryMock);
20 | }
21 |
22 | @Test
23 | public void getPidShouldReturnObdPidForSensor() throws Exception {
24 | testCommandReturnsProperPid(sut, SensorCommandPid.MASS_AIR_FLOW);
25 | }
26 |
27 | @Test
28 | public void getValueShouldCreateAirFlowValueObjectFromResultBuffer() throws Exception {
29 | testCommandGetValueCreateProperValueObject(sut);
30 | }
31 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/ThrottlePositionCommandTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors;
2 |
3 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.UnitFactory;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import static org.mockito.MockitoAnnotations.initMocks;
8 |
9 | public class ThrottlePositionCommandTest extends BaseSensorCommandTest {
10 |
11 | private ThrottlePositionCommand sut;
12 |
13 | @BeforeMethod
14 | private void beforeMethod() {
15 | initMocks(this);
16 |
17 | sut = new ThrottlePositionCommand();
18 | UnitFactory unitFactoryMock = recordUnitFactoryCreatesPercentage();
19 | sut.setUnitFactory(unitFactoryMock);
20 | }
21 |
22 | @Test
23 | public void getPidShouldReturnObdPidForSensor() throws Exception {
24 | testCommandReturnsProperPid(sut, SensorCommandPid.THROTTLE_POSITION_PERCENTAGE);
25 | }
26 |
27 | @Test
28 | public void getValueShouldCreatePercentageValueObjectFromResultBuffer() throws Exception {
29 | testCommandGetValueCreateProperValueObject(sut);
30 | }
31 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/AirFlowValueTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import static org.mockito.MockitoAnnotations.initMocks;
8 |
9 | public class AirFlowValueTest extends BaseValueTest {
10 |
11 | @BeforeMethod
12 | private void beforeMethod() {
13 | initMocks(this);
14 | }
15 |
16 | @Test
17 | public void constructorShouldSetDefaultDivisorAndMultiplier() throws Exception {
18 | constructorShouldSetDefaultDivisorAndMultiplier(256, 100);
19 | }
20 |
21 | @Override
22 | protected AbstractSensorCommandValue createSut(CommandResult commandResultMock) {
23 | return new AirFlowValue(commandResultMock);
24 | }
25 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/BaseValueTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 | import org.mockito.Mock;
5 |
6 | import static org.fest.assertions.api.Assertions.assertThat;
7 | import static org.mockito.Mockito.when;
8 |
9 | abstract class BaseValueTest {
10 |
11 | @Mock
12 | private CommandResult commandResultMock;
13 |
14 | protected void constructorShouldSetDefaultDivisorAndMultiplier(float multiplier, float divisor) throws Exception {
15 | // given
16 | when(commandResultMock.getByteNumber(0)).thenReturn(1);
17 | when(commandResultMock.getByteNumber(1)).thenReturn(0);
18 | float expectedValue = multiplier / divisor;
19 |
20 | // when
21 | AbstractSensorCommandValue sut = createSut(commandResultMock);
22 | float value = sut.calculateValue();
23 |
24 | // then
25 | assertThat(value).isEqualTo(expectedValue);
26 | }
27 |
28 | protected abstract AbstractSensorCommandValue createSut(CommandResult commandResultMock);
29 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/FuelConsumptionValueTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import static org.mockito.MockitoAnnotations.initMocks;
8 |
9 | public class FuelConsumptionValueTest extends BaseValueTest {
10 |
11 | @BeforeMethod
12 | private void beforeMethod() {
13 | initMocks(this);
14 | }
15 |
16 | @Test
17 | public void constructorShouldSetDefaultDivisorAndMultiplier() throws Exception {
18 | constructorShouldSetDefaultDivisorAndMultiplier(256, 20);
19 | }
20 |
21 | @Override
22 | protected AbstractSensorCommandValue createSut(CommandResult commandResultMock) {
23 | return new FuelConsumptionValue(commandResultMock);
24 | }
25 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/FuelTypeValueTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 | import com.google.common.base.Optional;
5 | import org.mockito.Mock;
6 | import org.testng.annotations.BeforeMethod;
7 | import org.testng.annotations.Test;
8 |
9 | import static com.devesion.commons.obd.adapter.command.diagnostic.sensors.units.FuelTypeValue.FuelType;
10 | import static org.fest.assertions.api.Assertions.assertThat;
11 | import static org.mockito.Mockito.when;
12 | import static org.mockito.MockitoAnnotations.initMocks;
13 |
14 | public class FuelTypeValueTest {
15 |
16 | @Mock
17 | private CommandResult commandResultMock;
18 |
19 | private FuelTypeValue sut;
20 |
21 | @BeforeMethod
22 | private void beforeMethod() {
23 | initMocks(this);
24 | sut = new FuelTypeValue(commandResultMock);
25 | }
26 |
27 | @Test
28 | public void getTypeShouldSelectProperEnumType() throws Exception {
29 | // given
30 |
31 | // when
32 | boolean fuelTypesAreEqual = true;
33 | for (FuelType expectedFuelType : FuelType.values()) {
34 | when(commandResultMock.getByteNumber(0)).thenReturn(expectedFuelType.getTypeNumber());
35 | Optional fuelTypeOptional = sut.getType();
36 | FuelType fuelType = fuelTypeOptional.get();
37 | fuelTypesAreEqual &= fuelType.equals(expectedFuelType);
38 | }
39 |
40 | // then
41 | assertThat(fuelTypesAreEqual).isTrue();
42 | }
43 |
44 | @Test
45 | public void getTypeShouldReturnAbsentForUnknownFuelTypeByte() throws Exception {
46 | // given
47 | int maxFuelTypeNumber = getMaxFuelTypeNumber();
48 | int unknownFuelTypeNumber = maxFuelTypeNumber + 1;
49 | when(commandResultMock.getByteNumber(0)).thenReturn(unknownFuelTypeNumber);
50 |
51 | // when
52 | Optional fuelTypeOptional = sut.getType();
53 |
54 | // then
55 | assertThat(fuelTypeOptional.isPresent()).isFalse();
56 | }
57 |
58 | private int getMaxFuelTypeNumber() {
59 | int maxFuelTypeNumber = 0;
60 | for (FuelType fuelType : FuelType.values()) {
61 | int fuelTypeNumber = fuelType.getTypeNumber();
62 | maxFuelTypeNumber = (maxFuelTypeNumber > fuelTypeNumber) ? maxFuelTypeNumber : fuelTypeNumber;
63 | }
64 |
65 | return maxFuelTypeNumber;
66 | }
67 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/RpmValueTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.testng.annotations.BeforeMethod;
6 | import org.testng.annotations.DataProvider;
7 | import org.testng.annotations.Test;
8 |
9 | import java.nio.IntBuffer;
10 |
11 | import static org.fest.assertions.api.Assertions.assertThat;
12 | import static org.mockito.MockitoAnnotations.initMocks;
13 |
14 | @Slf4j
15 | public class RpmValueTest extends BaseValueTest {
16 |
17 | @BeforeMethod
18 | private void beforeMethod() {
19 | initMocks(this);
20 | }
21 |
22 | @Test
23 | public void constructorShouldSetDefaultDivisorAndMultiplier() throws Exception {
24 | constructorShouldSetDefaultDivisorAndMultiplier(256, 4);
25 | }
26 |
27 | @Override
28 | protected AbstractSensorCommandValue createSut(CommandResult commandResultMock) {
29 | return new RpmValue(commandResultMock);
30 | }
31 |
32 | @DataProvider(name = "rpmValues")
33 | public Object[][] createData1() {
34 | return new Object[][] {
35 | { IntBuffer.wrap(new int[]{0x0C, 0x99}), 806},
36 | { IntBuffer.wrap(new int[]{0x0A, 0x96}), 677},
37 | { IntBuffer.wrap(new int[]{0x0A, 0x7A}), 670},
38 | { IntBuffer.wrap(new int[]{0x0A, 0x5A}), 662},
39 | };
40 | }
41 |
42 | @Test(dataProvider = "rpmValues")
43 | public void getIntValueShouldReturnProperValue(IntBuffer resultBuffer, float expectedValue) {
44 | // given
45 | CommandResult commandResult = CommandResult.withBuffer(resultBuffer);
46 |
47 | // when
48 | AbstractSensorCommandValue sut = new RpmValue(commandResult);
49 | sut.calculateValue();
50 | float value = sut.getIntValue();
51 |
52 | // then
53 | assertThat(value).isEqualTo(expectedValue);
54 | }
55 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/SimpleValueTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 | import org.mockito.Mock;
5 | import org.testng.annotations.BeforeMethod;
6 | import org.testng.annotations.Test;
7 |
8 | import static com.devesion.commons.obd.TestSupport.getRandomIntByte;
9 | import static org.fest.assertions.api.Assertions.assertThat;
10 | import static org.mockito.Mockito.when;
11 | import static org.mockito.MockitoAnnotations.initMocks;
12 |
13 | public class SimpleValueTest {
14 |
15 | @Mock
16 | private CommandResult commandResultMock;
17 |
18 | private SimpleValue sut;
19 |
20 | @BeforeMethod
21 | private void beforeMethod() {
22 | initMocks(this);
23 | recordCommandResultMockBehavior();
24 | }
25 |
26 | @Test
27 | public void testCalculateValue() throws Exception {
28 | // given
29 | int randomMultiplier = getRandomIntByte();
30 | int randomDivisor = getRandomIntByte();
31 | float expectedCalculatedValue = getExpectedCalculatedValue(randomMultiplier, randomDivisor);
32 |
33 | sut = new SimpleValue(commandResultMock, randomMultiplier, randomDivisor);
34 |
35 | // when
36 | float calculatedValue = sut.calculateValue();
37 |
38 | // then
39 | assertThat(calculatedValue).isEqualTo(expectedCalculatedValue);
40 | }
41 |
42 | @Test
43 | public void calculateValueShouldUseDefaultMultiplier() throws Exception {
44 | // given
45 | int defaultMultiplier = 255;
46 | int randomDivisor = getRandomIntByte();
47 | float expectedCalculatedValue = getExpectedCalculatedValue(defaultMultiplier, randomDivisor);
48 |
49 | sut = new SimpleValue(commandResultMock, defaultMultiplier, randomDivisor);
50 |
51 | // when
52 | float calculatedValue = sut.calculateValue();
53 |
54 | // then
55 | assertThat(calculatedValue).isEqualTo(expectedCalculatedValue);
56 | }
57 |
58 | private float getExpectedCalculatedValue(int randomMultiplier, float randomDivisor) {
59 | return (commandResultMock.getByteNumber(0) * randomMultiplier + commandResultMock.getByteNumber(1)) / randomDivisor;
60 | }
61 |
62 | private void recordCommandResultMockBehavior() {
63 | int randomMajorByte = getRandomIntByte();
64 | int randomMinorByte = getRandomIntByte();
65 | when(commandResultMock.getByteNumber(0)).thenReturn(randomMajorByte);
66 | when(commandResultMock.getByteNumber(1)).thenReturn(randomMinorByte);
67 | }
68 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/TemperatureValueTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import org.testng.annotations.Test;
4 |
5 | public class TemperatureValueTest {
6 | @Test
7 | public void Should() throws Exception {
8 | }
9 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/TimeValueTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import static org.mockito.MockitoAnnotations.initMocks;
8 |
9 | public class TimeValueTest extends BaseValueTest {
10 |
11 | @BeforeMethod
12 | private void beforeMethod() {
13 | initMocks(this);
14 | }
15 |
16 | @Test
17 | public void constructorShouldSetDefaultDivisorAndMultiplier() throws Exception {
18 | constructorShouldSetDefaultDivisorAndMultiplier(256, 1);
19 | }
20 |
21 | @Override
22 | protected AbstractSensorCommandValue createSut(CommandResult commandResultMock) {
23 | return new TimeValue(commandResultMock);
24 | }
25 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/diagnostic/sensors/units/UnitFactoryTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.diagnostic.sensors.units;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 | import org.mockito.Mock;
5 | import org.testng.annotations.BeforeMethod;
6 | import org.testng.annotations.Test;
7 |
8 | import static org.fest.assertions.api.Assertions.assertThat;
9 | import static org.mockito.MockitoAnnotations.initMocks;
10 |
11 | public class UnitFactoryTest {
12 |
13 | @Mock
14 | private CommandResult commandResultMock;
15 |
16 | private UnitFactory sut;
17 |
18 | @BeforeMethod
19 | private void beforeMethod() {
20 | initMocks(this);
21 | sut = new UnitFactory();
22 | }
23 |
24 | @Test
25 | public void testCreateAirFlowValue() throws Exception {
26 | // given
27 |
28 | // when
29 | SensorCommandValue valueObject = sut.createAirFlowValue(commandResultMock);
30 |
31 | // then
32 | assertValueObjectHasProperTypeAndResult(valueObject, AirFlowValue.class);
33 | }
34 |
35 | @Test
36 | public void testCreateFuelConsumptionValue() throws Exception {
37 | // given
38 |
39 | // when
40 | SensorCommandValue valueObject = sut.createFuelConsumptionValue(commandResultMock);
41 |
42 | // then
43 | assertValueObjectHasProperTypeAndResult(valueObject, FuelConsumptionValue.class);
44 | }
45 |
46 | @Test
47 | public void testCreateFuelLevelValue() throws Exception {
48 | // given
49 |
50 | // when
51 | SensorCommandValue valueObject = sut.createFuelLevelValue(commandResultMock);
52 |
53 | // then
54 | assertValueObjectHasProperTypeAndResult(valueObject, PercentageValue.class);
55 | }
56 |
57 | @Test
58 | public void testCreateFuelTypeValue() throws Exception {
59 | // given
60 |
61 | // when
62 | SensorCommandValue valueObject = sut.createFuelTypeValue(commandResultMock);
63 |
64 | // then
65 | assertValueObjectHasProperTypeAndResult(valueObject, FuelTypeValue.class);
66 | }
67 |
68 | @Test
69 | public void testCreatePercentageValue() throws Exception {
70 | // given
71 |
72 | // when
73 | SensorCommandValue valueObject = sut.createPercentageValue(commandResultMock);
74 |
75 | // then
76 | assertValueObjectHasProperTypeAndResult(valueObject, PercentageValue.class);
77 | }
78 |
79 | @Test
80 | public void testCreatePressureValue() throws Exception {
81 | // given
82 |
83 | // when
84 | SensorCommandValue valueObject = sut.createPressureValue(commandResultMock);
85 |
86 | // then
87 | assertValueObjectHasProperTypeAndResult(valueObject, PressureValue.class);
88 | }
89 |
90 | @Test
91 | public void testCreateRpmValue() throws Exception {
92 | // given
93 |
94 | // when
95 | SensorCommandValue valueObject = sut.createRpmValue(commandResultMock);
96 |
97 | // then
98 | assertValueObjectHasProperTypeAndResult(valueObject, RpmValue.class);
99 | }
100 |
101 | @Test
102 | public void testCreateTemperatureValue() throws Exception {
103 | // given
104 |
105 | // when
106 | SensorCommandValue valueObject = sut.createTemperatureValue(commandResultMock);
107 |
108 | // then
109 | assertValueObjectHasProperTypeAndResult(valueObject, TemperatureValue.class);
110 | }
111 |
112 | @Test
113 | public void testCreateTimeValue() throws Exception {
114 | // given
115 |
116 | // when
117 | SensorCommandValue valueObject = sut.createTimeValue(commandResultMock);
118 |
119 | // then
120 | assertValueObjectHasProperTypeAndResult(valueObject, TimeValue.class);
121 | }
122 |
123 | @Test
124 | public void testCreateVoltageValue() throws Exception {
125 | // given
126 |
127 | // when
128 | SensorCommandValue valueObject = sut.createVoltageValue(commandResultMock);
129 |
130 | // then
131 | assertValueObjectHasProperTypeAndResult(valueObject, VoltageValue.class);
132 | }
133 |
134 | @SuppressWarnings("unchecked")
135 | private void assertValueObjectHasProperTypeAndResult(SensorCommandValue valueObject, Class instanceClass) {
136 | assertThat(valueObject).isInstanceOf(instanceClass);
137 | assertThat(((T) valueObject).getCommandResult()).isEqualTo(commandResultMock);
138 | }
139 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/command/invoker/CommandInvokerTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.command.invoker;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 | import com.devesion.commons.obd.adapter.command.ObdCommand;
5 | import com.devesion.commons.obd.adapter.link.CommandMarshaller;
6 | import com.devesion.commons.obd.adapter.link.CommandUnmarshaller;
7 | import com.devesion.commons.obd.adapter.link.ObdLink;
8 | import org.mockito.Mock;
9 | import org.testng.annotations.BeforeMethod;
10 |
11 | import static org.mockito.MockitoAnnotations.initMocks;
12 |
13 | // TODO
14 | public class CommandInvokerTest {
15 |
16 | @Mock
17 | private ObdLink obdLinkMock;
18 |
19 | @Mock
20 | private CommandMarshaller commandMarshallerMock;
21 |
22 | @Mock
23 | private CommandUnmarshaller commandUnmarshallerMock;
24 |
25 | @Mock
26 | private ObdCommand obdCommandMock;
27 |
28 | @Mock
29 | private CommandResult commandResultMock;
30 |
31 | private CommandInvoker sut;
32 |
33 | @BeforeMethod
34 | private void beforeMethod() {
35 | initMocks(this);
36 | }
37 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/link/elm/AbstractCommandUnmarshallerTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.link.elm;
2 |
3 | import com.devesion.commons.obd.adapter.command.CommandResult;
4 | import com.devesion.commons.obd.adapter.command.ObdCommand;
5 | import junit.framework.TestCase;
6 | import org.testng.annotations.BeforeMethod;
7 | import org.testng.annotations.DataProvider;
8 | import org.testng.annotations.Test;
9 |
10 | import static org.fest.assertions.api.Assertions.assertThat;
11 |
12 | public class AbstractCommandUnmarshallerTest extends TestCase {
13 |
14 | private AbstractCommandUnmarshaller sut;
15 |
16 | @BeforeMethod
17 | public void beforeMethod() {
18 | sut = new FakeAbstractCommandUnmarshaller();
19 | }
20 |
21 | @DataProvider(name = "responselues")
22 | public Object[][] createData1() {
23 | return new Object[][] {
24 | { "1234 1234", "12341234"},
25 | { "123\n41\n2 3\n41 2", "1234123412"},
26 | { "0:410C0A820100\n" + "1:076D0000000000", "410C0A820100076D0000000000"}
27 | };
28 | }
29 |
30 | @Test(dataProvider = "responselues")
31 | public void normalizeResponseShouldNormalizeResponse(String responseToNormalize, String expectedResponse) {
32 | // given
33 |
34 | // when
35 | String normalizedResponse = sut.normalizeResponse(responseToNormalize);
36 |
37 | // then
38 | assertThat(normalizedResponse).isEqualTo(expectedResponse);
39 | }
40 |
41 | private class FakeAbstractCommandUnmarshaller extends AbstractCommandUnmarshaller {
42 |
43 | @Override
44 | public CommandResult unmarshal(ObdCommand command, String data) {
45 | return null;
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/link/elm/DiagnosticCommandUnmarshallerTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.link.elm;
2 |
3 | import junit.framework.TestCase;
4 |
5 | public class DiagnosticCommandUnmarshallerTest extends TestCase {
6 |
7 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/link/elm/ElmLinkTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.link.elm;
2 |
3 | import com.devesion.commons.obd.TestSupport;
4 | import com.devesion.commons.obd.adapter.command.CommandResult;
5 | import com.devesion.commons.obd.adapter.command.ObdCommand;
6 | import com.devesion.commons.obd.adapter.link.CommandMarshaller;
7 | import com.devesion.commons.obd.adapter.link.CommandUnmarshaller;
8 | import org.mockito.Mock;
9 | import org.testng.annotations.BeforeMethod;
10 | import org.testng.annotations.Test;
11 |
12 | import static org.fest.assertions.api.Assertions.assertThat;
13 | import static org.mockito.Mockito.when;
14 | import static org.mockito.MockitoAnnotations.initMocks;
15 |
16 | public class ElmLinkTest {
17 |
18 | @Mock
19 | private ElmTransport elmTransportMock;
20 |
21 | @Mock
22 | private CommandMarshaller commandMarshallerMock;
23 |
24 | @Mock
25 | private CommandUnmarshaller commandUnmarshallerMock;
26 |
27 | @Mock
28 | private ObdCommand obdCommandMock;
29 |
30 | @Mock
31 | private CommandResult commandResultMock;
32 |
33 | private ElmLink sut;
34 |
35 | @BeforeMethod
36 | private void beforeMethod() {
37 | initMocks(this);
38 | sut = new ElmLink(elmTransportMock, commandMarshallerMock, commandUnmarshallerMock);
39 |
40 | String commandData = TestSupport.getRandomString();
41 | String commandResponseData = TestSupport.getRandomString();
42 |
43 | when(elmTransportMock.sendDataAndReadResponse(commandData)).thenReturn(commandResponseData);
44 | when(commandMarshallerMock.marshal(obdCommandMock)).thenReturn(commandData);
45 | when(commandUnmarshallerMock.unmarshal(obdCommandMock, commandResponseData)).thenReturn(commandResultMock);
46 | }
47 |
48 | @Test
49 | public void constructorShouldSetDefaultMarshallers() throws Exception {
50 | // given
51 |
52 | // when
53 | sut = new ElmLink(elmTransportMock);
54 |
55 | // then
56 | CommandMarshaller commandMarshaller = sut.getCommandMarshaller();
57 | CommandUnmarshaller commandUnmarshaller = sut.getCommandUnmarshaller();
58 | assertThat(commandMarshaller).isNotNull();
59 | assertThat(commandUnmarshaller).isNotNull();
60 | }
61 |
62 | @Test
63 | public void invokeShouldMarshalCommandAndUnmarshalResponse() throws Exception {
64 | // given
65 |
66 | // when
67 | CommandResult commandResult = sut.sendCommand(obdCommandMock);
68 |
69 | // then
70 | assertThat(commandResult).isEqualTo(commandResultMock);
71 | }
72 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/link/elm/ElmTransportTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.link.elm;
2 |
3 | import com.devesion.commons.obd.TestSupport;
4 | import com.devesion.commons.obd.adapter.shared.ObdCommunicationException;
5 | import org.mockito.InOrder;
6 | import org.mockito.Mock;
7 | import org.testng.annotations.BeforeMethod;
8 | import org.testng.annotations.Test;
9 |
10 | import java.io.IOException;
11 | import java.io.InputStream;
12 | import java.io.OutputStream;
13 |
14 | import static com.devesion.commons.obd.TestSupport.InputStreamAnswer;
15 | import static com.googlecode.catchexception.CatchException.catchException;
16 | import static com.googlecode.catchexception.CatchException.caughtException;
17 | import static org.fest.assertions.api.Assertions.assertThat;
18 | import static org.mockito.Mockito.atLeastOnce;
19 | import static org.mockito.Mockito.doThrow;
20 | import static org.mockito.Mockito.inOrder;
21 | import static org.mockito.Mockito.when;
22 | import static org.mockito.MockitoAnnotations.initMocks;
23 |
24 | public class ElmTransportTest {
25 |
26 | @Mock
27 | private InputStream isMock;
28 |
29 | @Mock
30 | private OutputStream osMock;
31 |
32 | private ElmTransport sut;
33 |
34 | @BeforeMethod
35 | private void beforeMethod() {
36 | initMocks(this);
37 | sut = new ElmTransport(isMock, osMock);
38 | }
39 |
40 | @Test
41 | public void readDataShouldReadInputStreamToTheElmPrompt() throws Exception {
42 | // given
43 | String expectedData = getRandomStreamData();
44 | String streamData = " " + expectedData + ">";
45 |
46 | when(isMock.read()).thenAnswer(new InputStreamAnswer(streamData));
47 |
48 | // when
49 | String readData = sut.readData();
50 |
51 | // then
52 | assertThat(readData).isEqualTo(expectedData);
53 | }
54 |
55 | @Test
56 | @SuppressWarnings("unchecked")
57 | public void readDataShouldWrapExceptionsWithRuntimeException() throws Exception {
58 | // given
59 | when(isMock.read()).thenThrow(IOException.class);
60 |
61 | // when
62 | catchException(sut).readData();
63 |
64 | // then
65 | Exception exception = caughtException();
66 | assertThat(exception).isExactlyInstanceOf(ObdCommunicationException.class);
67 | }
68 |
69 | @Test
70 | public void sendDataShouldWriteDataToTheOutputStream() throws Exception {
71 | // given
72 | String expectedData = getRandomStreamData();
73 |
74 | // when
75 | sut.sendData(expectedData);
76 |
77 | // then
78 | InOrder inOrder = inOrder(osMock);
79 | inOrder.verify(osMock).write(expectedData.getBytes());
80 | inOrder.verify(osMock).flush();
81 | }
82 |
83 | @Test
84 | @SuppressWarnings("unchecked")
85 | public void sendDataShouldWrapExceptionsDuringWriteWithRuntimeException() throws Exception {
86 | // given
87 | String expectedData = getRandomStreamData();
88 | doThrow(IOException.class).when(osMock).write(expectedData.getBytes());
89 |
90 | // when
91 | catchException(sut).sendData(expectedData);
92 |
93 | // then
94 | Exception exception = caughtException();
95 | assertThat(exception).isExactlyInstanceOf(ObdCommunicationException.class);
96 | }
97 |
98 | @Test
99 | @SuppressWarnings("unchecked")
100 | public void sendDataShouldWrapExceptionsDuringFlushWithRuntimeException() throws Exception {
101 | // given
102 | String expectedData = getRandomStreamData();
103 | doThrow(IOException.class).when(osMock).flush();
104 |
105 | // when
106 | catchException(sut).sendData(expectedData);
107 |
108 | // then
109 | Exception exception = caughtException();
110 | assertThat(exception).isExactlyInstanceOf(ObdCommunicationException.class);
111 | }
112 |
113 | @Test
114 | public void testSendDataAndReadResponse() throws Exception {
115 | // given
116 | String expectedData = getRandomStreamData();
117 | String expectedResponseData = getRandomStreamData();
118 | String expectedResponseStreamData = " " + expectedResponseData + ">";
119 | when(isMock.read()).thenAnswer(new InputStreamAnswer(expectedResponseStreamData));
120 |
121 | // when
122 | String readData = sut.sendDataAndReadResponse(expectedData);
123 |
124 | // then
125 | InOrder inOrder = inOrder(isMock, osMock);
126 | inOrder.verify(osMock).write(expectedData.getBytes());
127 | inOrder.verify(osMock).flush();
128 | inOrder.verify(isMock, atLeastOnce()).read();
129 | assertThat(readData).isEqualTo(expectedResponseData);
130 | }
131 |
132 | private String getRandomStreamData() {
133 | return TestSupport.getRandomString() + " " + TestSupport.getRandomString() + " " + TestSupport.getRandomString();
134 | }
135 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/shared/BaseObdCommandResponseExceptionTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.shared;
2 |
3 | import com.devesion.commons.obd.adapter.command.ObdCommand;
4 | import org.mockito.Mock;
5 |
6 | import static org.fest.assertions.api.Assertions.assertThat;
7 |
8 | abstract class BaseObdCommandResponseExceptionTest {
9 |
10 | @Mock
11 | private ObdCommand obdCommandMock;
12 |
13 | protected void testConstructorShouldSetCommand() {
14 | // given
15 |
16 | // when
17 | ObdCommandResponseException sut = createException(obdCommandMock);
18 |
19 | // then
20 | assertThat(sut.getCommand()).isEqualTo(obdCommandMock);
21 | }
22 |
23 | protected abstract ObdCommandResponseException createException(ObdCommand obdCommandMock);
24 | }
25 |
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/shared/ObdCommandResponseExceptionTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.shared;
2 |
3 | import com.devesion.commons.obd.adapter.command.ObdCommand;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import static org.mockito.MockitoAnnotations.initMocks;
8 |
9 | public class ObdCommandResponseExceptionTest extends BaseObdCommandResponseExceptionTest {
10 |
11 | @BeforeMethod
12 | private void beforeMethod() {
13 | initMocks(this);
14 | }
15 |
16 | @Test
17 | public void constructorShouldSetCommand() throws Exception {
18 | testConstructorShouldSetCommand();
19 | }
20 |
21 | @Override
22 | protected ObdCommandResponseException createException(ObdCommand obdCommandMock) {
23 | return new ObdCommandResponseException(obdCommandMock);
24 | }
25 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/shared/ObdInvalidCommandResponseExceptionTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.shared;
2 |
3 | import com.devesion.commons.obd.adapter.command.ObdCommand;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import static org.mockito.MockitoAnnotations.initMocks;
8 |
9 | public class ObdInvalidCommandResponseExceptionTest extends BaseObdCommandResponseExceptionTest {
10 |
11 | @BeforeMethod
12 | private void beforeMethod() {
13 | initMocks(this);
14 | }
15 |
16 | @Test
17 | public void constructorShouldSetCommand() throws Exception {
18 | testConstructorShouldSetCommand();
19 | }
20 |
21 | @Override
22 | protected ObdCommandResponseException createException(ObdCommand obdCommandMock) {
23 | return new ObdInvalidCommandResponseException(obdCommandMock, "NODATA");
24 | }
25 | }
--------------------------------------------------------------------------------
/adapter/src/test/java/com/devesion/commons/obd/adapter/shared/ObdnoDataForCommandResponseExceptionTest.java:
--------------------------------------------------------------------------------
1 | package com.devesion.commons.obd.adapter.shared;
2 |
3 | import com.devesion.commons.obd.adapter.command.ObdCommand;
4 | import org.testng.annotations.BeforeMethod;
5 | import org.testng.annotations.Test;
6 |
7 | import static org.mockito.MockitoAnnotations.initMocks;
8 |
9 | public class ObdnoDataForCommandResponseExceptionTest extends BaseObdCommandResponseExceptionTest {
10 |
11 | @BeforeMethod
12 | private void beforeMethod() {
13 | initMocks(this);
14 | }
15 |
16 | @Test
17 | public void constructorShouldSetCommand() throws Exception {
18 | testConstructorShouldSetCommand();
19 | }
20 |
21 | @Override
22 | protected ObdCommandResponseException createException(ObdCommand obdCommandMock) {
23 | return new ObdNoDataForCommandResponseException(obdCommandMock);
24 | }
25 | }
--------------------------------------------------------------------------------
/client/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | obd-adapter
7 | com.devesion.commons.obd
8 | 1.0-SNAPSHOT
9 |
10 |
11 | 4.0.0
12 | client
13 | ${project.groupId}.${project.artifactId}
14 |
15 |
16 | 1.2.2.RELEASE
17 |
18 |
19 |
20 |
21 |
22 | org.springframework.boot
23 | spring-boot-maven-plugin
24 |
25 |
26 |
27 | repackage
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter
39 | ${project.dependency.spring-boot-dependencies.version}
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-starter-logging
44 |
45 |
46 |
47 |
48 |
49 | org.springframework.boot
50 | spring-boot-starter-log4j
51 | ${project.dependency.spring-boot-dependencies.version}
52 |
53 |
54 |
55 | com.devesion.commons.obd
56 | adapter
57 | 1.0-SNAPSHOT
58 |
59 |
60 |
61 | org.rxtx
62 | rxtx
63 | 2.1.7
64 |
65 |
66 |
--------------------------------------------------------------------------------
/client/src/main/java/com/autonalyzer/adapter/android/Launcher.java:
--------------------------------------------------------------------------------
1 | package com.autonalyzer.adapter.android;
2 |
3 | import com.autonalyzer.adapter.android.domain.DiagnosticStatus;
4 | import com.autonalyzer.adapter.android.domain.DiagnosticStatusFactory;
5 | import com.autonalyzer.adapter.android.infrastructure.DefaultDiagnosticStatusFactory;
6 | import com.google.common.base.Optional;
7 | import lombok.extern.slf4j.Slf4j;
8 |
9 | @Slf4j
10 | public class Launcher {
11 |
12 | public static void main(String[] args) {
13 | while (true) {
14 | DiagnosticStatusFactory statusFactory = new DefaultDiagnosticStatusFactory();
15 | Optional status = statusFactory.getCurrentStatus();
16 | log.info("status {}", status);
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/client/src/main/java/com/autonalyzer/adapter/android/domain/DiagnosticStatus.java:
--------------------------------------------------------------------------------
1 | package com.autonalyzer.adapter.android.domain;
2 |
3 | import lombok.EqualsAndHashCode;
4 | import lombok.Getter;
5 | import lombok.Setter;
6 | import lombok.ToString;
7 |
8 | @EqualsAndHashCode
9 | @ToString
10 | public class DiagnosticStatus {
11 |
12 | @Setter
13 | @Getter
14 | private int runtime;
15 |
16 | @Setter
17 | @Getter
18 | private int speed;
19 |
20 | @Setter
21 | @Getter
22 | private int rpm;
23 |
24 | @Setter
25 | @Getter
26 | private float throttlePosition;
27 |
28 | @Setter
29 | @Getter
30 | private double massAirFlow;
31 |
32 | @Setter
33 | @Getter
34 | private int load;
35 |
36 | @Setter
37 | @Getter
38 | private int fuelLevel;
39 |
40 | @Setter
41 | @Getter
42 | private int fuelPressure;
43 |
44 | @Setter
45 | @Getter
46 | private int fuelType;
47 |
48 | @Setter
49 | @Getter
50 | private double ambientTemperature;
51 |
52 | @Setter
53 | @Getter
54 | private double coolantTemperature;
55 |
56 | @Setter
57 | @Getter
58 | private double intakeAirTemperature;
59 | }
60 |
--------------------------------------------------------------------------------
/client/src/main/java/com/autonalyzer/adapter/android/domain/DiagnosticStatusFactory.java:
--------------------------------------------------------------------------------
1 | package com.autonalyzer.adapter.android.domain;
2 |
3 | import com.google.common.base.Optional;
4 |
5 | public interface DiagnosticStatusFactory {
6 |
7 | Optional getCurrentStatus();
8 | }
9 |
--------------------------------------------------------------------------------
/client/src/main/java/com/autonalyzer/adapter/android/domain/DiagnosticStatusSpecification.java:
--------------------------------------------------------------------------------
1 | package com.autonalyzer.adapter.android.domain;
2 |
3 | import lombok.EqualsAndHashCode;
4 | import lombok.ToString;
5 |
6 | @EqualsAndHashCode
7 | @ToString
8 | public class DiagnosticStatusSpecification {
9 |
10 | private String trackId;
11 |
12 | private DiagnosticTransportSpecification diagnosticTransportSpecification;
13 |
14 | public DiagnosticStatusSpecification(DiagnosticTransportSpecification diagnosticTransportSpecification) {
15 | this.diagnosticTransportSpecification = diagnosticTransportSpecification;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/client/src/main/java/com/autonalyzer/adapter/android/domain/DiagnosticTransportSpecification.java:
--------------------------------------------------------------------------------
1 | package com.autonalyzer.adapter.android.domain;
2 |
3 | public class DiagnosticTransportSpecification {
4 |
5 | private VehicleLinkType type;
6 | private String name;
7 |
8 | public DiagnosticTransportSpecification(String fqn) {
9 |
10 | }
11 |
12 | public DiagnosticTransportSpecification(String typeName, String deviceName) {
13 |
14 | }
15 |
16 | public DiagnosticTransportSpecification(VehicleLinkType type, String deviceName) {
17 | this.type = type;
18 | this.name = deviceName;
19 | }
20 |
21 | public enum VehicleLinkType {
22 | BLUETOOTH
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/client/src/main/java/com/autonalyzer/adapter/android/infrastructure/DefaultDiagnosticStatusFactory.java:
--------------------------------------------------------------------------------
1 | package com.autonalyzer.adapter.android.infrastructure;
2 |
3 | import com.autonalyzer.adapter.android.domain.DiagnosticStatus;
4 | import com.autonalyzer.adapter.android.domain.DiagnosticStatusFactory;
5 | import com.autonalyzer.adapter.android.infrastructure.gateway.DiagnosticStatusGateway;
6 | import com.autonalyzer.adapter.android.infrastructure.gateway.ProbingDiagnosticStatusGatewayFactory;
7 | import com.google.common.base.Optional;
8 | import lombok.extern.slf4j.Slf4j;
9 |
10 | @Slf4j
11 | public class DefaultDiagnosticStatusFactory implements DiagnosticStatusFactory {
12 |
13 | private ProbingDiagnosticStatusGatewayFactory diagnosticStatusGatewayFactory;
14 |
15 | private static Optional extends DiagnosticStatusGateway> diagnosticStatusGatewayOptional = Optional.absent();
16 |
17 | public DefaultDiagnosticStatusFactory() {
18 | this.diagnosticStatusGatewayFactory = new ProbingDiagnosticStatusGatewayFactory();
19 | }
20 |
21 | @Override
22 | public Optional getCurrentStatus() {
23 | try {
24 | openVehicleStatusGateway();
25 | return readCurrentStatus();
26 | } catch (DiagnosticStatusReadException e) {
27 | log.error("cannot read vehicle status - {}", e.getMessage());
28 | closeVehicleStatusGateway();
29 | return Optional.absent();
30 | }
31 | }
32 |
33 | private void openVehicleStatusGateway() {
34 | if (!diagnosticStatusGatewayOptional.isPresent()) {
35 | diagnosticStatusGatewayOptional = diagnosticStatusGatewayFactory.createDiagnosticStatusGateway();
36 | }
37 | }
38 |
39 | private Optional readCurrentStatus() {
40 | DiagnosticStatus vehicleStatus = null;
41 | if (diagnosticStatusGatewayOptional.isPresent()) {
42 | DiagnosticStatusGateway diagnosticStatusGateway = diagnosticStatusGatewayOptional.get();
43 | vehicleStatus = diagnosticStatusGateway.readCurrentStatus();
44 | }
45 |
46 | return Optional.fromNullable(vehicleStatus);
47 | }
48 |
49 | private void closeVehicleStatusGateway() {
50 | if (diagnosticStatusGatewayOptional.isPresent()) {
51 | DiagnosticStatusGateway diagnosticStatusGateway = diagnosticStatusGatewayOptional.get();
52 | diagnosticStatusGateway.close();
53 | diagnosticStatusGatewayOptional = Optional.absent();
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/client/src/main/java/com/autonalyzer/adapter/android/infrastructure/DiagnosticStatusReadException.java:
--------------------------------------------------------------------------------
1 | package com.autonalyzer.adapter.android.infrastructure;
2 |
3 | public class DiagnosticStatusReadException extends RuntimeException {
4 |
5 | public DiagnosticStatusReadException(String message) {
6 | super(message);
7 | }
8 |
9 | public DiagnosticStatusReadException(String message, Throwable cause) {
10 | super(message, cause);
11 | }
12 |
13 | public DiagnosticStatusReadException(Throwable cause) {
14 | super(cause);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/client/src/main/java/com/autonalyzer/adapter/android/infrastructure/gateway/DiagnosticStatusGateway.java:
--------------------------------------------------------------------------------
1 | package com.autonalyzer.adapter.android.infrastructure.gateway;
2 |
3 | import com.autonalyzer.adapter.android.domain.DiagnosticStatus;
4 |
5 | import java.io.Closeable;
6 |
7 | public interface DiagnosticStatusGateway extends Closeable {
8 |
9 | void open();
10 |
11 | DiagnosticStatus readCurrentStatus();
12 |
13 | void close();
14 | }
15 |
--------------------------------------------------------------------------------
/client/src/main/java/com/autonalyzer/adapter/android/infrastructure/gateway/ProbingDiagnosticStatusGateway.java:
--------------------------------------------------------------------------------
1 | package com.autonalyzer.adapter.android.infrastructure.gateway;
2 |
3 | public interface ProbingDiagnosticStatusGateway extends DiagnosticStatusGateway {
4 |
5 | boolean probe();
6 | }
7 |
--------------------------------------------------------------------------------
/client/src/main/java/com/autonalyzer/adapter/android/infrastructure/gateway/ProbingDiagnosticStatusGatewayFactory.java:
--------------------------------------------------------------------------------
1 | package com.autonalyzer.adapter.android.infrastructure.gateway;
2 |
3 | import com.autonalyzer.adapter.android.infrastructure.gateway.elm.ProbingElmDiagnosticStatusGateway;
4 | import com.autonalyzer.adapter.android.infrastructure.transport.DiagnosticTransport;
5 | import com.autonalyzer.adapter.android.infrastructure.transport.DiagnosticTransportFactory;
6 | import com.autonalyzer.adapter.android.infrastructure.transport.ProbingDiagnosticTransportFactory;
7 | import com.google.common.base.Optional;
8 | import lombok.extern.slf4j.Slf4j;
9 |
10 | import java.util.List;
11 |
12 | @Slf4j
13 | public class ProbingDiagnosticStatusGatewayFactory {
14 |
15 | private DiagnosticTransportFactory vehicleDiagnosticTransportFactory = new ProbingDiagnosticTransportFactory();
16 |
17 | public Optional extends DiagnosticStatusGateway> createDiagnosticStatusGateway() {
18 | log.info("creating new diagnosticStatusGateway");
19 |
20 | List transports = vehicleDiagnosticTransportFactory.createAvailableTransports();
21 | for (DiagnosticTransport transport : transports) {
22 | Optional extends DiagnosticStatusGateway> diagnosticStatusGatewayOptional = probeSingleTransport(transport);
23 | if (diagnosticStatusGatewayOptional.isPresent()) {
24 | return diagnosticStatusGatewayOptional;
25 | }
26 | }
27 |
28 | return Optional.absent();
29 | }
30 |
31 | private Optional extends DiagnosticStatusGateway> probeSingleTransport(DiagnosticTransport transport) {
32 | log.info("probing transport {}", transport);
33 |
34 | ProbingDiagnosticStatusGateway diagnosticStatusGateway = new ProbingElmDiagnosticStatusGateway(transport);
35 | if (diagnosticStatusGateway.probe()) {
36 | log.info("probe OK");
37 | return Optional.of(diagnosticStatusGateway);
38 | } else {
39 | log.info("probe FAIL");
40 | diagnosticStatusGateway.close();
41 | return Optional.absent();
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/client/src/main/java/com/autonalyzer/adapter/android/infrastructure/gateway/elm/ElmDiagnosticStatusGateway.java:
--------------------------------------------------------------------------------
1 | package com.autonalyzer.adapter.android.infrastructure.gateway.elm;
2 |
3 | import com.autonalyzer.adapter.android.domain.DiagnosticStatus;
4 | import com.autonalyzer.adapter.android.infrastructure.gateway.DiagnosticStatusGateway;
5 | import com.autonalyzer.adapter.android.infrastructure.transport.DiagnosticTransport;
6 | import com.devesion.commons.obd.adapter.command.ObdCommand;
7 | import com.devesion.commons.obd.adapter.command.at.AdaptiveTimeoutProtocolCommand;
8 | import com.devesion.commons.obd.adapter.command.at.ResetCommand;
9 | import com.devesion.commons.obd.adapter.command.at.SelectProtocolCommand;
10 | import com.devesion.commons.obd.adapter.command.at.SetEchoCommand;
11 | import com.devesion.commons.obd.adapter.command.at.SetHeadersCommand;
12 | import com.devesion.commons.obd.adapter.command.at.SetLineFeedCommand;
13 | import com.devesion.commons.obd.adapter.command.at.SetSpacesCommand;
14 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.AmbientAirTemperatureCommand;
15 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.EngineCoolantTemperatureCommand;
16 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.EngineLoadCommand;
17 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.EngineRpmCommand;
18 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.EngineRuntimeCommand;
19 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.FuelLevelCommand;
20 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.FuelPressureCommand;
21 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.FuelTypeCommand;
22 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.IntakeAirTemperatureCommand;
23 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.MassAirFlowCommand;
24 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.SensorCommand;
25 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.SpeedCommand;
26 | import com.devesion.commons.obd.adapter.command.diagnostic.sensors.ThrottlePositionCommand;
27 | import com.devesion.commons.obd.adapter.command.invoker.CommandInvoker;
28 | import com.devesion.commons.obd.adapter.link.ObdLink;
29 | import com.devesion.commons.obd.adapter.link.elm.ElmLink;
30 | import com.devesion.commons.obd.adapter.shared.ObdNoDataForCommandResponseException;
31 | import com.devesion.commons.obd.adapter.shared.ObdNotProperlyInitializedException;
32 | import com.google.common.util.concurrent.Uninterruptibles;
33 | import lombok.extern.slf4j.Slf4j;
34 |
35 | import java.io.InputStream;
36 | import java.io.OutputStream;
37 | import java.time.Duration;
38 | import java.time.Instant;
39 | import java.util.concurrent.TimeUnit;
40 |
41 | /**
42 | * Echo disabled
43 | * Linefeed disabled
44 | * Spaces disabled
45 | * Headers disabled
46 | * Adaptive Timing: 2
47 | * New Protocol: Automatic
48 | * Headers enabled
49 | * Headers disabled
50 | */
51 | @Slf4j
52 | public class ElmDiagnosticStatusGateway implements DiagnosticStatusGateway {
53 |
54 | private static final int SLOW_STATUS_DURATION = 10;
55 | private static final int VERY_SLOW_STATUS_DURATION = 60;
56 |
57 | private boolean opened = false;
58 | private boolean initialized = false;
59 |
60 | private Instant lastSlowStatusTime = Instant.now();
61 | private Instant lastVerySlowStatusTime = Instant.now();
62 |
63 | private final DiagnosticStatus diagnosticStatus = new DiagnosticStatus();
64 | private final DiagnosticTransport diagnosticTransport;
65 |
66 | public ElmDiagnosticStatusGateway(DiagnosticTransport diagnosticTransport) {
67 | this.diagnosticTransport = diagnosticTransport;
68 | }
69 |
70 | @Override
71 | public void open() {
72 | if (!opened) {
73 | openTransport();
74 | opened = true;
75 | }
76 | }
77 |
78 | private void initialize() {
79 | if (!initialized) {
80 | initializeCommands();
81 | initialized = true;
82 | }
83 | }
84 |
85 | private void initializeCommands() {
86 | log.info("Initializing ELM protocol");
87 | invokeCommandQuietly(new ResetCommand());
88 | // invokeCommandQuietly(new SetBaudRateCommand());
89 | // invokeCommandQuietly(new EnableBaudRateCommand());
90 | invokeCommandQuietly(new ResetCommand());
91 | invokeCommand(new SetEchoCommand(false));
92 | invokeCommand(new SetLineFeedCommand(false));
93 | invokeCommand(new SetHeadersCommand(false));
94 | invokeCommand(new SetSpacesCommand(false));
95 | invokeCommand(new AdaptiveTimeoutProtocolCommand());
96 | invokeCommand(new SelectProtocolCommand());
97 | }
98 |
99 | @Override
100 | public DiagnosticStatus readCurrentStatus() {
101 | try {
102 | open();
103 | initialize();
104 | readFastStatus(diagnosticStatus);
105 | readSlowStatus(diagnosticStatus);
106 | readVerySlowStatus(diagnosticStatus);
107 | } catch (ObdNotProperlyInitializedException e) {
108 | log.error("Reinitializing ELM due to {}", e.getMessage());
109 | deinitialize();
110 | close();
111 | sleepGap();
112 | } catch (Exception e) {
113 | log.error("Invoking fail - {}", e);
114 | }
115 |
116 | return diagnosticStatus;
117 | }
118 |
119 | private void readFastStatus(DiagnosticStatus diagnosticStatus) {
120 | diagnosticStatus.setRpm(readEngineRpm());
121 | diagnosticStatus.setSpeed(readVehicleSpeed());
122 | diagnosticStatus.setThrottlePosition(readThrottlePositionPercentage());
123 | diagnosticStatus.setMassAirFlow(readMassAirFlow());
124 | diagnosticStatus.setLoad(readEngineLoad());
125 | }
126 |
127 | private void readSlowStatus(DiagnosticStatus diagnosticStatus) {
128 | Instant now = Instant.now();
129 | Duration duration = Duration.between(lastSlowStatusTime, now);
130 | if (duration.getSeconds() > SLOW_STATUS_DURATION) {
131 | diagnosticStatus.setFuelPressure(readFuelPressure());
132 | diagnosticStatus.setCoolantTemperature(readCoolantTemperature());
133 | diagnosticStatus.setIntakeAirTemperature(readIntakeAirTemperature());
134 | lastSlowStatusTime = Instant.now();
135 | }
136 | }
137 |
138 | private void readVerySlowStatus(DiagnosticStatus diagnosticStatus) {
139 | Instant now = Instant.now();
140 | Duration duration = Duration.between(lastVerySlowStatusTime, now);
141 | if (duration.getSeconds() > VERY_SLOW_STATUS_DURATION) {
142 | diagnosticStatus.setFuelLevel(readFuelLevel());
143 | diagnosticStatus.setFuelType(readFuelType());
144 | diagnosticStatus.setRuntime(readEngineRuntime());
145 | diagnosticStatus.setAmbientTemperature(readAmbientAirTemperature());
146 | lastVerySlowStatusTime = Instant.now();
147 | }
148 | }
149 | private int readEngineRpm() {
150 | SensorCommand command = new EngineRpmCommand();
151 | invokeCommand(command);
152 | return command.getValue().getIntValue();
153 | }
154 |
155 | private int readVehicleSpeed() {
156 | SensorCommand command = new SpeedCommand();
157 | invokeCommand(command);
158 | return command.getValue().getIntValue();
159 | }
160 |
161 | private float readThrottlePositionPercentage() {
162 | SensorCommand command = new ThrottlePositionCommand();
163 | invokeCommand(command);
164 | return command.getValue().getIntValue();
165 | }
166 |
167 | private double readMassAirFlow() {
168 | SensorCommand command = new MassAirFlowCommand();
169 | invokeCommand(command);
170 | return command.getValue().getFloatValue();
171 | }
172 |
173 | private int readEngineLoad() {
174 | SensorCommand command = new EngineLoadCommand();
175 | invokeCommand(command);
176 | return command.getValue().getIntValue();
177 | }
178 |
179 | private int readFuelLevel() {
180 | SensorCommand command = new FuelLevelCommand();
181 | invokeCommand(command);
182 | return command.getValue().getIntValue();
183 | }
184 |
185 | private int readFuelType() {
186 | SensorCommand command = new FuelTypeCommand();
187 | invokeCommand(command);
188 | return command.getValue().getIntValue();
189 | }
190 |
191 | private int readFuelPressure() {
192 | SensorCommand command = new FuelPressureCommand();
193 | invokeCommand(command);
194 | return command.getValue().getIntValue();
195 | }
196 |
197 | private int readEngineRuntime() {
198 | SensorCommand command = new EngineRuntimeCommand();
199 | invokeCommand(command);
200 | return command.getValue().getIntValue();
201 | }
202 |
203 | private int readAmbientAirTemperature() {
204 | SensorCommand command = new AmbientAirTemperatureCommand();
205 | invokeCommand(command);
206 | return command.getValue().getIntValue();
207 | }
208 |
209 | private int readCoolantTemperature() {
210 | SensorCommand command = new EngineCoolantTemperatureCommand();
211 | invokeCommand(command);
212 | return command.getValue().getIntValue();
213 | }
214 |
215 | private int readIntakeAirTemperature() {
216 | SensorCommand command = new IntakeAirTemperatureCommand();
217 | invokeCommand(command);
218 | return command.getValue().getIntValue();
219 | }
220 |
221 | private void invokeCommand(ObdCommand command) {
222 | try {
223 | CommandInvoker commandInvoker = createCommandInvoker();
224 | log.debug("Invoking command {}", command);
225 | commandInvoker.invoke(command);
226 | } catch (ObdNoDataForCommandResponseException e) {
227 | log.debug("Invoking fail - {}", e.getMessage());
228 | }
229 | }
230 |
231 | private void invokeCommandQuietly(ObdCommand command) {
232 | CommandInvoker commandInvoker = createCommandInvoker();
233 | log.debug("Invoking command {}", command);
234 | commandInvoker.invokeQuietly(command);
235 | }
236 |
237 | private CommandInvoker createCommandInvoker() {
238 | InputStream inputStream = diagnosticTransport.getInputStream();
239 | OutputStream outputStream = diagnosticTransport.getOutputStream();
240 | ObdLink obdLink = new ElmLink(inputStream, outputStream);
241 | return new CommandInvoker(obdLink);
242 | }
243 |
244 | private void sleepGap() {
245 | Uninterruptibles.sleepUninterruptibly(5, TimeUnit.SECONDS);
246 | }
247 |
248 | @Override
249 | public void close() {
250 | closeTransport();
251 | opened = false;
252 | }
253 |
254 | private void deinitialize() {
255 | initialized = false;
256 | }
257 |
258 | private void openTransport() {
259 | diagnosticTransport.open();
260 | }
261 |
262 | private void closeTransport() {
263 | diagnosticTransport.close();
264 | }
265 | }
266 |
--------------------------------------------------------------------------------
/client/src/main/java/com/autonalyzer/adapter/android/infrastructure/gateway/elm/ProbingElmDiagnosticStatusGateway.java:
--------------------------------------------------------------------------------
1 | package com.autonalyzer.adapter.android.infrastructure.gateway.elm;
2 |
3 | import com.autonalyzer.adapter.android.infrastructure.gateway.ProbingDiagnosticStatusGateway;
4 | import com.autonalyzer.adapter.android.infrastructure.transport.DiagnosticTransport;
5 |
6 | public class ProbingElmDiagnosticStatusGateway extends ElmDiagnosticStatusGateway implements ProbingDiagnosticStatusGateway {
7 |
8 | public ProbingElmDiagnosticStatusGateway(DiagnosticTransport diagnosticTransport) {
9 | super(diagnosticTransport);
10 | }
11 |
12 | @Override
13 | public boolean probe() {
14 | try {
15 | open();
16 | return true;
17 | } catch (Exception e) {
18 | close();
19 | return false;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/client/src/main/java/com/autonalyzer/adapter/android/infrastructure/transport/DiagnosticTransport.java:
--------------------------------------------------------------------------------
1 | package com.autonalyzer.adapter.android.infrastructure.transport;
2 |
3 | import java.io.Closeable;
4 | import java.io.InputStream;
5 | import java.io.OutputStream;
6 |
7 | public interface DiagnosticTransport extends Closeable {
8 |
9 | void open();
10 |
11 | InputStream getInputStream();
12 |
13 | OutputStream getOutputStream();
14 |
15 | void close();
16 | }
17 |
--------------------------------------------------------------------------------
/client/src/main/java/com/autonalyzer/adapter/android/infrastructure/transport/DiagnosticTransportFactory.java:
--------------------------------------------------------------------------------
1 | package com.autonalyzer.adapter.android.infrastructure.transport;
2 |
3 | import java.util.List;
4 |
5 | public interface DiagnosticTransportFactory {
6 |
7 | List createAvailableTransports();
8 | }
9 |
--------------------------------------------------------------------------------
/client/src/main/java/com/autonalyzer/adapter/android/infrastructure/transport/DiagnosticTransportProbe.java:
--------------------------------------------------------------------------------
1 | package com.autonalyzer.adapter.android.infrastructure.transport;
2 |
3 | import java.util.List;
4 |
5 | public interface DiagnosticTransportProbe {
6 |
7 | List createAvailableTransports();
8 | }
9 |
--------------------------------------------------------------------------------
/client/src/main/java/com/autonalyzer/adapter/android/infrastructure/transport/ProbingDiagnosticTransportFactory.java:
--------------------------------------------------------------------------------
1 | package com.autonalyzer.adapter.android.infrastructure.transport;
2 |
3 | import com.autonalyzer.adapter.android.infrastructure.transport.serial.SerialDiagnosticTransportFactory;
4 | import com.google.common.collect.Lists;
5 |
6 | import java.util.List;
7 |
8 | public class ProbingDiagnosticTransportFactory implements DiagnosticTransportFactory {
9 |
10 | private List probes = Lists.newArrayList();
11 |
12 | public ProbingDiagnosticTransportFactory() {
13 | DiagnosticTransportProbe bluetoothTransportProbe = new SerialDiagnosticTransportFactory();
14 | registerDiagnosticTransportFactory(bluetoothTransportProbe);
15 | }
16 |
17 | private void registerDiagnosticTransportFactory(DiagnosticTransportProbe diagnosticTransportProbe) {
18 | probes.add(diagnosticTransportProbe);
19 | }
20 |
21 | @Override
22 | public List createAvailableTransports() {
23 | List allAvailableTransports = Lists.newArrayList();
24 | for (DiagnosticTransportProbe probe : probes) {
25 | List probedTransports = probe.createAvailableTransports();
26 | allAvailableTransports.addAll(probedTransports);
27 | }
28 |
29 | return allAvailableTransports;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/client/src/main/java/com/autonalyzer/adapter/android/infrastructure/transport/serial/SerialDiagnosticTransport.java:
--------------------------------------------------------------------------------
1 | package com.autonalyzer.adapter.android.infrastructure.transport.serial;
2 |
3 | import com.autonalyzer.adapter.android.infrastructure.transport.DiagnosticTransport;
4 | import gnu.io.CommPortIdentifier;
5 | import gnu.io.SerialPort;
6 | import gnu.io.SerialPortEvent;
7 | import gnu.io.SerialPortEventListener;
8 | import lombok.extern.slf4j.Slf4j;
9 |
10 | import java.io.IOException;
11 | import java.io.InputStream;
12 | import java.io.OutputStream;
13 | import java.util.Enumeration;
14 |
15 | @Slf4j
16 | public class SerialDiagnosticTransport implements DiagnosticTransport, SerialPortEventListener {
17 |
18 | private static final int TIME_OUT = 2000;
19 | // private static final int DATA_RATE = 38400;
20 |
21 | // private static final int DATA_RATE = 57600;
22 | private static final int DATA_RATE = 115200;
23 | // private static final int DATA_RATE = 38400;
24 | // private static final int DATA_RATE = 14400;
25 | private InputStream is;
26 | private OutputStream os;
27 |
28 | @Override
29 | public void close() {
30 | try {
31 | if (is != null) {
32 | is.close();
33 | }
34 |
35 | if (os != null) {
36 | os.close();
37 | }
38 | } catch (IOException e) {
39 | log.error("cannot close streams");
40 | }
41 | }
42 |
43 | @Override
44 | public void open() {
45 | log.info("opening serial transport");
46 | String wantedPortName = "/dev/ttyUSB0";
47 | // String wantedPortName = "/dev/rfcomm1";
48 | System.setProperty("gnu.io.rxtx.SerialPorts", wantedPortName);
49 | Enumeration portIdentifiers = CommPortIdentifier.getPortIdentifiers();
50 |
51 | CommPortIdentifier portId = null;
52 |
53 | while (portIdentifiers.hasMoreElements()) {
54 | CommPortIdentifier pid = (CommPortIdentifier) portIdentifiers.nextElement();
55 | log.info("pid {}", pid);
56 | if (pid.getPortType() == CommPortIdentifier.PORT_SERIAL &&
57 | pid.getName().equals(wantedPortName)) {
58 | portId = pid;
59 | break;
60 | }
61 | }
62 |
63 | if (portId == null) {
64 | return;
65 | }
66 |
67 | try {
68 | // open serial port, and use class name for the appName.
69 | SerialPort serialPort = (SerialPort) portId.open(SerialDiagnosticTransport.class.getName(), TIME_OUT);
70 |
71 | // set port parameters
72 | serialPort.setSerialPortParams(DATA_RATE,
73 | SerialPort.DATABITS_8,
74 | SerialPort.STOPBITS_1,
75 | SerialPort.PARITY_NONE);
76 |
77 | serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_XONXOFF_IN);
78 | serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_XONXOFF_OUT);
79 |
80 | // open the streams
81 | is = serialPort.getInputStream();
82 | os = serialPort.getOutputStream();
83 |
84 | // add event listeners
85 | serialPort.addEventListener(this);
86 | serialPort.notifyOnDataAvailable(false);
87 | log.info("serial transport opened");
88 | } catch (Exception e) {
89 | log.error("cannot connect to serial port", e);
90 | }
91 | }
92 |
93 | @Override
94 | public InputStream getInputStream() {
95 | return is;
96 | }
97 |
98 | @Override
99 | public OutputStream getOutputStream() {
100 | return os;
101 | }
102 |
103 | @Override
104 | public void serialEvent(SerialPortEvent oEvent) {
105 | // Ignore all the other eventTypes, but you should consider the other
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/client/src/main/java/com/autonalyzer/adapter/android/infrastructure/transport/serial/SerialDiagnosticTransportFactory.java:
--------------------------------------------------------------------------------
1 | package com.autonalyzer.adapter.android.infrastructure.transport.serial;
2 |
3 | import com.autonalyzer.adapter.android.infrastructure.transport.DiagnosticTransport;
4 | import com.autonalyzer.adapter.android.infrastructure.transport.DiagnosticTransportProbe;
5 | import com.google.common.collect.Lists;
6 | import lombok.extern.slf4j.Slf4j;
7 |
8 | import java.util.List;
9 |
10 | @Slf4j
11 | public class SerialDiagnosticTransportFactory implements DiagnosticTransportProbe {
12 |
13 | @Override
14 | public List createAvailableTransports() {
15 | DiagnosticTransport diagnosticTransport = new SerialDiagnosticTransport();
16 | return Lists.newArrayList(diagnosticTransport);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/client/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | # Set root logger level to DEBUG and its only appender to A1.
2 | log4j.rootLogger=INFO, A1, file
3 |
4 | log4j.appender.file=org.apache.log4j.RollingFileAppender
5 | log4j.appender.file.File=autonalyzer.log
6 | log4j.appender.file.MaxFileSize=100MB
7 | log4j.appender.file.MaxBackupIndex=10
8 | log4j.appender.file.layout=org.apache.log4j.PatternLayout
9 | log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
10 | log4j.appender.file.Threshold=DEBUG
11 |
12 | # A1 is set to be a ConsoleAppender.
13 | log4j.appender.A1=org.apache.log4j.ConsoleAppender
14 |
15 | # A1 uses PatternLayout.
16 | log4j.appender.A1.layout=org.apache.log4j.PatternLayout
17 | log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c\t - %m%n
18 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | org.sonatype.oss
8 | oss-parent
9 | 7
10 |
11 |
12 | 4.0.0
13 | com.devesion.commons.obd
14 | obd-adapter
15 | pom
16 | 1.0-SNAPSHOT
17 | ${project.groupId}.${project.artifactId}
18 |
19 |
20 |
21 | The Apache Software License, Version 2.0
22 | http://www.apache.org/licenses/LICENSE-2.0.txt
23 | repo
24 |
25 |
26 |
27 |
28 | scm:git:git@github.com:dembol/java-obd-adapter.git
29 | scm:git:git@github.com:dembol/java-obd-adapter.git
30 | git@github.com:dembol/java-obd-adapter.git
31 | HEAD
32 |
33 |
34 |
35 |
36 | dembol
37 | Lukasz Dembinski
38 | dembol@devesion.com
39 |
40 | developer
41 |
42 |
43 |
44 |
45 |
46 |
47 | ossrh
48 | https://oss.sonatype.org/content/repositories/snapshots
49 |
50 |
51 | ossrh
52 | https://oss.sonatype.org/service/local/staging/deploy/maven2/
53 |
54 |
55 |
56 |
57 | 1.8
58 | 1.16.2
59 | 1.7.6
60 | 18.0
61 |
62 | 1.5.1
63 | 1.9.5
64 | 1.0.4
65 | 2.0M5
66 | 6.8.5
67 | 4.6
68 |
69 |
70 |
71 |
72 |
73 | org.apache.maven.plugins
74 | maven-compiler-plugin
75 | 3.2
76 |
77 | ${java.version}
78 | ${java.version}
79 | true
80 |
81 |
82 |
83 | org.codehaus.mojo
84 | cobertura-maven-plugin
85 | 2.6
86 |
87 |
88 | org.apache.maven.plugins
89 | maven-release-plugin
90 | 2.2.2
91 |
92 | -Dgpg.passphrase=${gpg.passphrase}
93 |
94 |
95 |
96 | org.sonatype.plugins
97 | nexus-staging-maven-plugin
98 | 1.6.3
99 | true
100 |
101 | ossrh
102 | https://oss.sonatype.org/
103 | true
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 | org.codehaus.mojo
113 | cobertura-maven-plugin
114 |
115 |
116 |
117 |
118 |
119 |
120 | release-sign-artifacts
121 |
122 |
123 | performRelease
124 | true
125 |
126 |
127 |
128 |
129 |
130 | org.apache.maven.plugins
131 | maven-gpg-plugin
132 | 1.4
133 |
134 |
135 | sign-artifacts
136 | verify
137 |
138 | sign
139 |
140 |
141 | 2AC54014
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 | org.projectlombok
154 | lombok
155 | ${project.dependency.lombok.version}
156 |
157 |
158 |
159 | com.google.guava
160 | guava
161 | ${project.dependency.google.guava.version}
162 |
163 |
164 |
165 |
166 | org.slf4j
167 | slf4j-log4j12
168 | ${project.dependency.slf4j.log4j12.version}
169 |
170 |
171 |
172 |
173 | org.testng
174 | testng
175 | ${project.dependency.testng.version}
176 | test
177 |
178 |
179 | org.mockito
180 | mockito-all
181 | ${project.dependency.mockito.version}
182 | test
183 |
184 |
185 | org.powermock
186 | powermock-module-testng
187 | ${project.dependency.powermock.version}
188 | test
189 |
190 |
191 | org.powermock
192 | powermock-api-mockito
193 | ${project.dependency.powermock.version}
194 | test
195 |
196 |
197 | org.easytesting
198 | fest-assert-core
199 | ${project.dependency.fest-assert-core.version}
200 | test
201 |
202 |
203 | com.googlecode.catch-exception
204 | catch-exception
205 | ${project.dependency.google.catch-exception.version}
206 | test
207 |
208 |
209 |
210 |
211 | adapter
212 | client
213 |
214 |
--------------------------------------------------------------------------------