@leonardojc/capacitor-ioboard 1.2.6 → 1.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,371 +11,252 @@ import java.util.Arrays;
11
11
  import org.json.JSONObject;
12
12
 
13
13
  @CapacitorPlugin(name = "CapacitorIoboard")
14
- public class CapacitorIoboardPlugin extends Plugin implements IOBoardManager.SerialPortInterface {
14
+ public class CapacitorIoboardPlugin extends Plugin {
15
15
 
16
16
  private static final String TAG = "CapacitorIoboard";
17
- private IOBoardManager ioboardManager;
18
17
 
19
18
  @Override
20
19
  public void load() {
21
20
  super.load();
22
- ioboardManager = new IOBoardManager(this); // Pass this plugin as SerialPortInterface
21
+ Log.d(TAG, "IOBoard Protocol Plugin loaded - working at protocol level");
23
22
  }
24
23
 
25
- // SerialPortInterface implementation - simplified approach
26
- @Override
27
- public void openPort(String portPath, int baudRate, IOBoardManager.SerialPortCallback callback) {
28
- Log.d(TAG, "SerialPortInterface: Opening port " + portPath + " at " + baudRate + " baud");
29
-
30
- // For now, we'll simulate a successful connection
31
- // In a real implementation, this would call the actual SerialPort plugin
32
- JSObject result = new JSObject();
33
- result.put("success", true);
34
- result.put("message", "Port opened successfully");
35
- callback.onSuccess(result);
36
- }
37
-
38
- @Override
39
- public void closePort(IOBoardManager.SerialPortCallback callback) {
40
- Log.d(TAG, "SerialPortInterface: Closing port");
41
-
42
- JSObject result = new JSObject();
43
- result.put("success", true);
44
- result.put("message", "Port closed successfully");
45
- callback.onSuccess(result);
46
- }
47
-
48
- @Override
49
- public void sendData(byte[] data, IOBoardManager.SerialPortCallback callback) {
50
- Log.d(TAG, "SerialPortInterface: Sending data: " + IOBoardProtocolUtils.frameToHex(data));
51
-
52
- JSObject result = new JSObject();
53
- result.put("success", true);
54
- result.put("message", "Data sent successfully");
55
- callback.onSuccess(result);
56
- }
57
-
58
- @Override
59
- public void readData(int timeout, IOBoardManager.SerialPortCallback callback) {
60
- Log.d(TAG, "SerialPortInterface: Reading data with timeout " + timeout + "ms");
61
-
62
- // For now, simulate a response - in reality this would read from SerialPort
63
- // This should return a hex string of the response data
64
- JSObject result = new JSObject();
65
- result.put("success", true);
66
- result.put("data", "0D0701018A750A"); // Example response
67
- callback.onSuccess(result);
68
- }
69
-
70
- // New simplified API methods
71
- @PluginMethod
72
- public void connect(PluginCall call) {
73
- String portPath = call.getString("portPath", "/dev/ttyS2");
74
- Integer baudRate = call.getInt("baudRate", 115200);
75
- Integer dataBits = call.getInt("dataBits", 8);
76
- Integer stopBits = call.getInt("stopBits", 1);
77
- String parity = call.getString("parity", "none");
78
- String flowControl = call.getString("flowControl", "none");
79
- Integer timeout = call.getInt("timeout", 5000);
80
-
81
- try {
82
- IOBoardManager.SerialConfig config = new IOBoardManager.SerialConfig(
83
- portPath, baudRate, dataBits, stopBits, parity, flowControl, timeout
84
- );
85
-
86
- IOBoardManager.IOBoardResponse response = ioboardManager.connect(config);
87
-
88
- JSObject result = new JSObject();
89
- result.put("success", response.success);
90
- result.put("message", response.message);
91
-
92
- call.resolve(result);
93
- } catch (Exception e) {
94
- Log.e(TAG, "Error connecting", e);
95
- call.reject("Failed to connect: " + e.getMessage());
96
- }
97
- }
24
+ // Protocol-level methods - these return frames to be sent and parse responses
98
25
 
99
26
  @PluginMethod
100
- public void disconnect(PluginCall call) {
101
- try {
102
- IOBoardManager.IOBoardResponse response = ioboardManager.disconnect();
103
-
104
- JSObject result = new JSObject();
105
- result.put("success", response.success);
106
- result.put("message", response.message);
107
-
108
- call.resolve(result);
109
- } catch (Exception e) {
110
- Log.e(TAG, "Error disconnecting", e);
111
- call.reject("Failed to disconnect: " + e.getMessage());
112
- }
113
- }
114
-
115
- @PluginMethod
116
- public void isConnected(PluginCall call) {
117
- try {
118
- boolean connected = ioboardManager.isConnected();
119
- JSObject result = new JSObject();
120
- result.put("connected", connected);
121
- call.resolve(result);
122
- } catch (Exception e) {
123
- Log.e(TAG, "Error checking connection status", e);
124
- call.reject("Failed to check connection status: " + e.getMessage());
125
- }
126
- }
127
-
128
- @PluginMethod
129
- public void getStatus(PluginCall call) {
27
+ public void buildCommand(PluginCall call) {
28
+ String command = call.getString("command");
130
29
  Integer address = call.getInt("address");
131
- Integer timeout = call.getInt("timeout", 5000);
132
30
 
133
- if (address == null || address < 1 || address > 63) {
134
- call.reject("Invalid address. Must be between 1 and 63");
31
+ if (command == null || address == null) {
32
+ call.reject("Command and address are required");
135
33
  return;
136
34
  }
137
35
 
138
36
  try {
139
- IOBoardManager.StatusResponse response = ioboardManager.getStatus(address, timeout);
140
-
141
- JSObject result = new JSObject();
142
- result.put("success", response.success);
143
- result.put("message", response.message);
37
+ byte[] frame = null;
144
38
 
145
- if (response.success && response.data != null) {
146
- JSObject data = new JSObject();
147
- data.put("doorLockStatus", response.data.doorLockStatus);
148
-
149
- JSObject version = new JSObject();
150
- version.put("major", response.data.softwareVersion.major);
151
- version.put("minor", response.data.softwareVersion.minor);
152
- version.put("patch", response.data.softwareVersion.patch);
153
- data.put("softwareVersion", version);
154
-
155
- result.put("data", data);
39
+ switch (command.toUpperCase()) {
40
+ case "GET_STATUS":
41
+ frame = IOBoardProtocolUtils.createStatusQuery((byte) address.intValue());
42
+ break;
43
+
44
+ case "UNLOCK_PALLET":
45
+ Integer palletNumber = call.getInt("palletNumber");
46
+ String ledColor = call.getString("ledColor", "green");
47
+ if (palletNumber == null) {
48
+ call.reject("palletNumber is required for UNLOCK_PALLET command");
49
+ return;
50
+ }
51
+
52
+ // Create data payload for single pallet unlock
53
+ byte[] singlePalletData = new byte[2];
54
+ singlePalletData[0] = (byte) palletNumber.intValue(); // Pallet number
55
+ singlePalletData[1] = (byte) (ledColor.equals("red") ? 1 : 0); // LED color: 0=green, 1=red
56
+
57
+ frame = IOBoardProtocolUtils.createFrame((byte) address.intValue(), IOBoardProtocolUtils.FRAME_TYPE_SINGLE_PALLET, singlePalletData);
58
+ break;
59
+
60
+ case "CONTROL_MULTIPLE":
61
+ Integer doorLockMask = call.getInt("doorLockMask", 0);
62
+ String ledColorMultiple = call.getString("ledColor", "green");
63
+
64
+ // Create data payload for multiple pallet control
65
+ byte[] multiplePalletData = new byte[2];
66
+ multiplePalletData[0] = (byte) doorLockMask.intValue(); // Door lock mask
67
+ multiplePalletData[1] = (byte) (ledColorMultiple.equals("red") ? 1 : 0); // LED color
68
+
69
+ frame = IOBoardProtocolUtils.createFrame((byte) address.intValue(), IOBoardProtocolUtils.FRAME_TYPE_FULL_PALLET, multiplePalletData);
70
+ break;
71
+
72
+ case "OTA_NOTIFICATION":
73
+ Integer majorVersion = call.getInt("majorVersion");
74
+ Integer minorVersion = call.getInt("minorVersion");
75
+ Integer patchVersion = call.getInt("patchVersion");
76
+ Integer firmwareSize = call.getInt("firmwareSize");
77
+
78
+ if (majorVersion == null || minorVersion == null || patchVersion == null || firmwareSize == null) {
79
+ call.reject("All version parameters and firmware size are required for OTA_NOTIFICATION");
80
+ return;
81
+ }
82
+
83
+ // Create OTA notification data payload (example structure)
84
+ byte[] otaData = new byte[7];
85
+ otaData[0] = (byte) majorVersion.intValue();
86
+ otaData[1] = (byte) minorVersion.intValue();
87
+ otaData[2] = (byte) patchVersion.intValue();
88
+ // Firmware size as 4 bytes (little endian)
89
+ otaData[3] = (byte) (firmwareSize & 0xFF);
90
+ otaData[4] = (byte) ((firmwareSize >> 8) & 0xFF);
91
+ otaData[5] = (byte) ((firmwareSize >> 16) & 0xFF);
92
+ otaData[6] = (byte) ((firmwareSize >> 24) & 0xFF);
93
+
94
+ frame = IOBoardProtocolUtils.createFrame((byte) address.intValue(), IOBoardProtocolUtils.FRAME_TYPE_OTA_REQUEST, otaData);
95
+ break;
96
+
97
+ default:
98
+ call.reject("Unknown command: " + command);
99
+ return;
156
100
  }
157
101
 
158
- call.resolve(result);
159
- } catch (Exception e) {
160
- Log.e(TAG, "Error getting status", e);
161
- call.reject("Failed to get status: " + e.getMessage());
162
- }
163
- }
164
-
165
- @PluginMethod
166
- public void unlockPallet(PluginCall call) {
167
- Integer address = call.getInt("address");
168
- Integer palletNumber = call.getInt("palletNumber");
169
- String ledColor = call.getString("ledColor", "green");
170
- Integer timeout = call.getInt("timeout", 5000);
171
-
172
- if (address == null || address < 1 || address > 63) {
173
- call.reject("Invalid address. Must be between 1 and 63");
174
- return;
175
- }
176
-
177
- if (palletNumber == null || palletNumber < 0 || palletNumber > 7) {
178
- call.reject("Invalid pallet number. Must be between 0 and 7");
179
- return;
180
- }
181
-
182
- try {
183
- IOBoardManager.IOBoardResponse response = ioboardManager.unlockPallet(
184
- address, palletNumber, ledColor, timeout
185
- );
186
-
187
102
  JSObject result = new JSObject();
188
- result.put("success", response.success);
189
- result.put("message", response.message);
190
-
191
- if (response.success) {
192
- JSObject data = new JSObject();
193
- data.put("address", address);
194
- data.put("palletNumber", palletNumber);
195
- data.put("ledColor", ledColor);
196
- result.put("data", data);
197
- }
103
+ result.put("frame", IOBoardProtocolUtils.frameToHex(frame));
104
+ result.put("command", command);
105
+ result.put("address", address);
198
106
 
199
107
  call.resolve(result);
108
+
200
109
  } catch (Exception e) {
201
- Log.e(TAG, "Error unlocking pallet", e);
202
- call.reject("Failed to unlock pallet: " + e.getMessage());
110
+ Log.e(TAG, "Error building command", e);
111
+ call.reject("Failed to build command: " + e.getMessage());
203
112
  }
204
113
  }
205
114
 
206
115
  @PluginMethod
207
- public void controlMultiplePallets(PluginCall call) {
208
- Integer address = call.getInt("address");
209
- Integer doorLockMask = call.getInt("doorLockMask", 0);
210
- String ledColor = call.getString("ledColor", "green");
211
- Integer timeout = call.getInt("timeout", 5000);
212
-
213
- if (address == null || address < 1 || address > 63) {
214
- call.reject("Invalid address. Must be between 1 and 63");
116
+ public void parseResponse(PluginCall call) {
117
+ String hexData = call.getString("data");
118
+
119
+ if (hexData == null || hexData.trim().isEmpty()) {
120
+ call.reject("Data is required");
215
121
  return;
216
122
  }
217
123
 
218
124
  try {
219
- IOBoardManager.IOBoardResponse response = ioboardManager.controlMultiplePallets(
220
- address, doorLockMask, ledColor, timeout
221
- );
222
-
125
+ Log.d(TAG, "Parsing response: " + hexData);
126
+
127
+ IOBoardProtocolUtils.ParsedResponse parsedResponse = IOBoardProtocolUtils.parseResponse(hexData);
128
+
223
129
  JSObject result = new JSObject();
224
- result.put("success", response.success);
225
- result.put("message", response.message);
130
+ result.put("valid", parsedResponse.success);
131
+ result.put("rawData", hexData);
132
+ result.put("message", parsedResponse.message);
226
133
 
227
- if (response.success) {
228
- JSObject data = new JSObject();
229
- data.put("address", address);
230
- data.put("doorLockMask", doorLockMask);
134
+ if (parsedResponse.success) {
135
+ result.put("address", parsedResponse.address);
136
+ result.put("frameType", parsedResponse.frameType);
231
137
 
232
- // Calculate affected pallets from mask
233
- JSArray affectedPallets = new JSArray();
234
- for (int i = 0; i < 8; i++) {
235
- if ((doorLockMask & (1 << i)) != 0) {
236
- affectedPallets.put(i);
138
+ if (parsedResponse.data != null && parsedResponse.data.length > 0) {
139
+ result.put("payload", IOBoardProtocolUtils.frameToHex(parsedResponse.data));
140
+
141
+ // If it's a status response, parse the data
142
+ if (parsedResponse.frameType == IOBoardProtocolUtils.FRAME_TYPE_STATUS_QUERY && parsedResponse.data.length >= 4) {
143
+ result.put("doorLockStatus", parsedResponse.data[0]);
144
+
145
+ // Software version (assuming bytes 1-3 are major, minor, patch)
146
+ if (parsedResponse.data.length >= 4) {
147
+ JSObject version = new JSObject();
148
+ version.put("major", parsedResponse.data[1]);
149
+ version.put("minor", parsedResponse.data[2]);
150
+ version.put("patch", parsedResponse.data[3]);
151
+ result.put("softwareVersion", version);
152
+ }
237
153
  }
238
154
  }
239
- data.put("affectedPallets", affectedPallets);
240
- result.put("data", data);
241
155
  }
242
156
 
243
157
  call.resolve(result);
158
+
244
159
  } catch (Exception e) {
245
- Log.e(TAG, "Error controlling multiple pallets", e);
246
- call.reject("Failed to control multiple pallets: " + e.getMessage());
160
+ Log.e(TAG, "Error parsing response", e);
161
+ call.reject("Failed to parse response: " + e.getMessage());
247
162
  }
248
163
  }
249
164
 
250
165
  @PluginMethod
251
- public void scanDevices(PluginCall call) {
252
- Integer startAddress = call.getInt("startAddress", 1);
253
- Integer endAddress = call.getInt("endAddress", 63);
254
- Integer timeout = call.getInt("timeout", 1000);
255
-
256
- if (startAddress < 1 || startAddress > 63) {
257
- call.reject("Invalid start address. Must be between 1 and 63");
258
- return;
259
- }
260
-
261
- if (endAddress < 1 || endAddress > 63 || endAddress < startAddress) {
262
- call.reject("Invalid end address. Must be between 1 and 63 and >= start address");
166
+ public void validateFrame(PluginCall call) {
167
+ String hexData = call.getString("data");
168
+
169
+ if (hexData == null || hexData.trim().isEmpty()) {
170
+ call.reject("Data is required");
263
171
  return;
264
172
  }
265
173
 
266
174
  try {
267
- IOBoardManager.ScanResponse response = ioboardManager.scanDevices(
268
- startAddress, endAddress, timeout
269
- );
270
-
175
+ // Use parseResponse to validate the frame
176
+ IOBoardProtocolUtils.ParsedResponse parsed = IOBoardProtocolUtils.parseResponse(hexData);
177
+
271
178
  JSObject result = new JSObject();
272
- result.put("success", response.success);
273
- result.put("message", response.message);
179
+ result.put("valid", parsed.success);
180
+ result.put("data", hexData);
181
+ result.put("message", parsed.message);
274
182
 
275
- if (response.success && response.devices != null) {
276
- JSArray devicesArray = new JSArray();
277
- for (IOBoardManager.DeviceInfo device : response.devices) {
278
- JSObject deviceObj = new JSObject();
279
- deviceObj.put("address", device.address);
280
- deviceObj.put("responding", device.responding);
281
-
282
- if (device.status != null) {
283
- JSObject statusObj = new JSObject();
284
- statusObj.put("doorLockStatus", device.status.doorLockStatus);
285
- deviceObj.put("status", statusObj);
286
- }
287
-
288
- devicesArray.put(deviceObj);
289
- }
290
- result.put("devices", devicesArray);
183
+ if (parsed.success) {
184
+ byte[] frameData = IOBoardProtocolUtils.hexStringToBytes(hexData);
185
+ result.put("length", frameData.length);
291
186
  }
292
187
 
293
188
  call.resolve(result);
189
+
294
190
  } catch (Exception e) {
295
- Log.e(TAG, "Error scanning devices", e);
296
- call.reject("Failed to scan devices: " + e.getMessage());
191
+ Log.e(TAG, "Error validating frame", e);
192
+ call.reject("Failed to validate frame: " + e.getMessage());
297
193
  }
298
194
  }
299
195
 
300
196
  @PluginMethod
301
- public void sendOTANotification(PluginCall call) {
302
- Integer address = call.getInt("address");
303
- Integer majorVersion = call.getInt("majorVersion");
304
- Integer minorVersion = call.getInt("minorVersion");
305
- Integer patchVersion = call.getInt("patchVersion");
306
- Integer firmwareSize = call.getInt("firmwareSize");
307
-
308
- if (address == null || address < 1 || address > 63) {
309
- call.reject("Invalid address. Must be between 1 and 63");
310
- return;
311
- }
312
-
313
- if (majorVersion == null || minorVersion == null || patchVersion == null || firmwareSize == null) {
314
- call.reject("All OTA parameters are required");
197
+ public void hexToBytes(PluginCall call) {
198
+ String hexData = call.getString("data");
199
+
200
+ if (hexData == null || hexData.trim().isEmpty()) {
201
+ call.reject("Data is required");
315
202
  return;
316
203
  }
317
204
 
318
205
  try {
319
- IOBoardManager.IOBoardResponse response = ioboardManager.sendOTANotification(
320
- address, majorVersion, minorVersion, patchVersion, firmwareSize
321
- );
322
-
323
- JSObject result = new JSObject();
324
- result.put("success", response.success);
325
- result.put("message", response.message);
206
+ byte[] bytes = IOBoardProtocolUtils.hexStringToBytes(hexData);
326
207
 
327
- if (response.success) {
328
- JSObject data = new JSObject();
329
- data.put("address", address);
330
- data.put("version", majorVersion + "." + minorVersion + "." + patchVersion);
331
- data.put("firmwareSize", firmwareSize);
332
- result.put("data", data);
208
+ // Convert byte array to JSArray of integers
209
+ JSArray bytesArray = new JSArray();
210
+ for (byte b : bytes) {
211
+ bytesArray.put((int) b & 0xFF); // Convert to unsigned int
333
212
  }
334
213
 
214
+ JSObject result = new JSObject();
215
+ result.put("bytes", bytesArray);
216
+ result.put("length", bytes.length);
217
+ result.put("hex", hexData);
218
+
335
219
  call.resolve(result);
220
+
336
221
  } catch (Exception e) {
337
- Log.e(TAG, "Error sending OTA notification", e);
338
- call.reject("Failed to send OTA notification: " + e.getMessage());
222
+ Log.e(TAG, "Error converting hex to bytes", e);
223
+ call.reject("Failed to convert hex to bytes: " + e.getMessage());
339
224
  }
340
225
  }
341
226
 
342
227
  @PluginMethod
343
- public void sendOTAData(PluginCall call) {
344
- Integer address = call.getInt("address");
345
- Integer packetNumber = call.getInt("packetNumber");
346
- String dataBase64 = call.getString("data");
347
-
348
- if (address == null || address < 1 || address > 63) {
349
- call.reject("Invalid address. Must be between 1 and 63");
350
- return;
351
- }
352
-
353
- if (packetNumber == null || dataBase64 == null) {
354
- call.reject("Packet number and data are required");
228
+ public void bytesToHex(PluginCall call) {
229
+ JSArray bytesArray = call.getArray("bytes");
230
+
231
+ if (bytesArray == null) {
232
+ call.reject("Bytes array is required");
355
233
  return;
356
234
  }
357
235
 
358
236
  try {
359
- IOBoardManager.IOBoardResponse response = ioboardManager.sendOTAData(
360
- address, packetNumber, dataBase64
361
- );
362
-
363
- JSObject result = new JSObject();
364
- result.put("success", response.success);
365
- result.put("message", response.message);
237
+ byte[] bytes = new byte[bytesArray.length()];
238
+ for (int i = 0; i < bytesArray.length(); i++) {
239
+ bytes[i] = (byte) bytesArray.getInt(i);
240
+ }
241
+
242
+ String hexString = IOBoardProtocolUtils.frameToHex(bytes);
366
243
 
367
- if (response.success) {
368
- JSObject data = new JSObject();
369
- data.put("address", address);
370
- data.put("packetNumber", packetNumber);
371
- data.put("dataLength", dataBase64.length());
372
- result.put("data", data);
244
+ // Convert byte array back to JSArray for consistency
245
+ JSArray resultBytesArray = new JSArray();
246
+ for (byte b : bytes) {
247
+ resultBytesArray.put((int) b & 0xFF);
373
248
  }
374
249
 
250
+ JSObject result = new JSObject();
251
+ result.put("hex", hexString);
252
+ result.put("length", bytes.length);
253
+ result.put("bytes", resultBytesArray);
254
+
375
255
  call.resolve(result);
256
+
376
257
  } catch (Exception e) {
377
- Log.e(TAG, "Error sending OTA data", e);
378
- call.reject("Failed to send OTA data: " + e.getMessage());
258
+ Log.e(TAG, "Error converting bytes to hex", e);
259
+ call.reject("Failed to convert bytes to hex: " + e.getMessage());
379
260
  }
380
261
  }
381
262
  }
@@ -832,10 +832,4 @@ public class IOBoardManager {
832
832
  }
833
833
  }
834
834
 
835
- /**
836
- * Check if serial connection is open
837
- */
838
- public boolean isConnected() {
839
- return isConnected;
840
- }
841
835
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leonardojc/capacitor-ioboard",
3
- "version": "1.2.6",
3
+ "version": "1.2.8",
4
4
  "description": "A Capacitor plugin for controlling custom IOBOARD devices via RS485 serial communication with full native protocol implementation",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",