@leonardojc/capacitor-ioboard 1.1.0
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.
- package/CapacitorIoboard.podspec +13 -0
- package/LICENSE +21 -0
- package/README.md +292 -0
- package/android/build.gradle +39 -0
- package/android/src/main/AndroidManifest.xml +8 -0
- package/android/src/main/java/com/leonardojc/capacitor/ioboard/CapacitorIoboardPlugin.java +336 -0
- package/android/src/main/java/com/leonardojc/capacitor/ioboard/IOBoardManager.java +657 -0
- package/dist/esm/definitions.d.ts +154 -0
- package/dist/esm/definitions.js +43 -0
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/protocol.d.ts +62 -0
- package/dist/esm/protocol.js +191 -0
- package/dist/esm/web.d.ts +17 -0
- package/dist/esm/web.js +167 -0
- package/dist/plugin.cjs.js +422 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +425 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Plugin/CapacitorIoboard.swift +8 -0
- package/ios/Plugin/CapacitorIoboardPlugin.m +15 -0
- package/ios/Plugin/CapacitorIoboardPlugin.swift +142 -0
- package/package.json +97 -0
|
@@ -0,0 +1,657 @@
|
|
|
1
|
+
package com.leonardojc.capacitor.ioboard;
|
|
2
|
+
|
|
3
|
+
import android.util.Log;
|
|
4
|
+
import android.util.Base64;
|
|
5
|
+
import java.util.Arrays;
|
|
6
|
+
import java.util.concurrent.TimeUnit;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Manager class for IOBOARD communication protocol
|
|
10
|
+
* This class integrates with the @leonardojc/capacitor-serial-port plugin
|
|
11
|
+
*/
|
|
12
|
+
public class IOBoardManager {
|
|
13
|
+
|
|
14
|
+
private static final String TAG = "IOBoardManager";
|
|
15
|
+
private static final int SOI = 0x0D; // Start of frame
|
|
16
|
+
private static final int EOI = 0x0A; // End of frame
|
|
17
|
+
|
|
18
|
+
// Frame types
|
|
19
|
+
private static final int FRAME_TYPE_STATUS_QUERY = 0x00;
|
|
20
|
+
private static final int FRAME_TYPE_SINGLE_PALLET = 0x01;
|
|
21
|
+
private static final int FRAME_TYPE_FULL_PALLET = 0x02;
|
|
22
|
+
private static final int FRAME_TYPE_OTA_REQUEST = 0xF1;
|
|
23
|
+
private static final int FRAME_TYPE_OTA_DATA = 0xF2;
|
|
24
|
+
|
|
25
|
+
private boolean isConnected = false;
|
|
26
|
+
|
|
27
|
+
// Response classes
|
|
28
|
+
public static class IOBoardResponse {
|
|
29
|
+
public boolean success;
|
|
30
|
+
public String message;
|
|
31
|
+
|
|
32
|
+
public IOBoardResponse(boolean success, String message) {
|
|
33
|
+
this.success = success;
|
|
34
|
+
this.message = message;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public static class StatusData {
|
|
39
|
+
public int doorLockStatus;
|
|
40
|
+
public SoftwareVersion softwareVersion;
|
|
41
|
+
|
|
42
|
+
public StatusData(int doorLockStatus, SoftwareVersion softwareVersion) {
|
|
43
|
+
this.doorLockStatus = doorLockStatus;
|
|
44
|
+
this.softwareVersion = softwareVersion;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public static class SoftwareVersion {
|
|
49
|
+
public int major;
|
|
50
|
+
public int minor;
|
|
51
|
+
public int patch;
|
|
52
|
+
|
|
53
|
+
public SoftwareVersion(int major, int minor, int patch) {
|
|
54
|
+
this.major = major;
|
|
55
|
+
this.minor = minor;
|
|
56
|
+
this.patch = patch;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public static class StatusResponse extends IOBoardResponse {
|
|
61
|
+
public StatusData data;
|
|
62
|
+
|
|
63
|
+
public StatusResponse(boolean success, String message, StatusData data) {
|
|
64
|
+
super(success, message);
|
|
65
|
+
this.data = data;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public static class LEDControl {
|
|
70
|
+
public int red;
|
|
71
|
+
public int green;
|
|
72
|
+
public int blue;
|
|
73
|
+
public int intensity;
|
|
74
|
+
public int blinkTimes;
|
|
75
|
+
public int blinkSpeed;
|
|
76
|
+
|
|
77
|
+
public LEDControl(int red, int green, int blue, int intensity, int blinkTimes, int blinkSpeed) {
|
|
78
|
+
this.red = Math.max(0, Math.min(255, red));
|
|
79
|
+
this.green = Math.max(0, Math.min(255, green));
|
|
80
|
+
this.blue = Math.max(0, Math.min(255, blue));
|
|
81
|
+
this.intensity = Math.max(0, Math.min(255, intensity));
|
|
82
|
+
this.blinkTimes = Math.max(0, Math.min(255, blinkTimes));
|
|
83
|
+
this.blinkSpeed = Math.max(0, Math.min(30, blinkSpeed));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public static class SerialConfig {
|
|
88
|
+
public String portPath;
|
|
89
|
+
public int baudRate;
|
|
90
|
+
public int dataBits;
|
|
91
|
+
public int stopBits;
|
|
92
|
+
public String parity;
|
|
93
|
+
public String flowControl;
|
|
94
|
+
public int timeout;
|
|
95
|
+
|
|
96
|
+
public SerialConfig(String portPath, int baudRate, int dataBits, int stopBits, String parity, String flowControl, int timeout) {
|
|
97
|
+
this.portPath = portPath;
|
|
98
|
+
this.baudRate = baudRate;
|
|
99
|
+
this.dataBits = dataBits;
|
|
100
|
+
this.stopBits = stopBits;
|
|
101
|
+
this.parity = parity;
|
|
102
|
+
this.flowControl = flowControl;
|
|
103
|
+
this.timeout = timeout;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// New classes for simplified API
|
|
108
|
+
public static class DeviceInfo {
|
|
109
|
+
public int address;
|
|
110
|
+
public boolean responding;
|
|
111
|
+
public StatusData status;
|
|
112
|
+
|
|
113
|
+
public DeviceInfo(int address, boolean responding, StatusData status) {
|
|
114
|
+
this.address = address;
|
|
115
|
+
this.responding = responding;
|
|
116
|
+
this.status = status;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
public static class ScanResponse extends IOBoardResponse {
|
|
121
|
+
public DeviceInfo[] devices;
|
|
122
|
+
|
|
123
|
+
public ScanResponse(boolean success, String message, DeviceInfo[] devices) {
|
|
124
|
+
super(success, message);
|
|
125
|
+
this.devices = devices;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Calculate CRC-16 CCITT checksum
|
|
131
|
+
*/
|
|
132
|
+
private int calculateCRC16(int[] data) {
|
|
133
|
+
int crc = 0xFFFF;
|
|
134
|
+
|
|
135
|
+
for (int dataByte : data) {
|
|
136
|
+
crc ^= (dataByte << 8);
|
|
137
|
+
|
|
138
|
+
for (int bit = 0; bit < 8; bit++) {
|
|
139
|
+
if ((crc & 0x8000) != 0) {
|
|
140
|
+
crc = (crc << 1) ^ 0x1021;
|
|
141
|
+
} else {
|
|
142
|
+
crc = crc << 1;
|
|
143
|
+
}
|
|
144
|
+
crc &= 0xFFFF;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return crc;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Build a command frame for IOBOARD
|
|
153
|
+
*/
|
|
154
|
+
private int[] buildFrame(int address, int frameType, int[] data) {
|
|
155
|
+
// Calculate frame size: SOI + Address + FrameType + Data + CRC(2) + EOI
|
|
156
|
+
int frameSize = 1 + 1 + 1 + data.length + 2 + 1;
|
|
157
|
+
int[] frame = new int[frameSize];
|
|
158
|
+
int index = 0;
|
|
159
|
+
|
|
160
|
+
// SOI
|
|
161
|
+
frame[index++] = SOI;
|
|
162
|
+
|
|
163
|
+
// Address
|
|
164
|
+
frame[index++] = address;
|
|
165
|
+
|
|
166
|
+
// Frame Type
|
|
167
|
+
frame[index++] = frameType;
|
|
168
|
+
|
|
169
|
+
// Data
|
|
170
|
+
for (int dataByte : data) {
|
|
171
|
+
frame[index++] = dataByte;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Calculate CRC for address + frameType + data
|
|
175
|
+
int[] crcData = new int[1 + 1 + data.length];
|
|
176
|
+
crcData[0] = address;
|
|
177
|
+
crcData[1] = frameType;
|
|
178
|
+
System.arraycopy(data, 0, crcData, 2, data.length);
|
|
179
|
+
|
|
180
|
+
int crc = calculateCRC16(crcData);
|
|
181
|
+
|
|
182
|
+
// CRC (high byte first)
|
|
183
|
+
frame[index++] = (crc >> 8) & 0xFF;
|
|
184
|
+
frame[index++] = crc & 0xFF;
|
|
185
|
+
|
|
186
|
+
// EOI
|
|
187
|
+
frame[index] = EOI;
|
|
188
|
+
|
|
189
|
+
return frame;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Convert frame to byte array for serial transmission
|
|
194
|
+
*/
|
|
195
|
+
private byte[] frameToBytes(int[] frame) {
|
|
196
|
+
byte[] bytes = new byte[frame.length];
|
|
197
|
+
for (int i = 0; i < frame.length; i++) {
|
|
198
|
+
bytes[i] = (byte) (frame[i] & 0xFF);
|
|
199
|
+
}
|
|
200
|
+
return bytes;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Convert frame to hex string for debugging
|
|
205
|
+
*/
|
|
206
|
+
private String frameToHex(int[] frame) {
|
|
207
|
+
StringBuilder sb = new StringBuilder();
|
|
208
|
+
for (int i = 0; i < frame.length; i++) {
|
|
209
|
+
if (i > 0) sb.append(" ");
|
|
210
|
+
sb.append(String.format("%02X", frame[i]));
|
|
211
|
+
}
|
|
212
|
+
return sb.toString();
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// New simplified API methods
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Connect to serial port
|
|
219
|
+
*/
|
|
220
|
+
public IOBoardResponse connect(SerialConfig config) {
|
|
221
|
+
Log.d(TAG, "Connecting to serial port: " + config.portPath + " at " + config.baudRate + " baud");
|
|
222
|
+
|
|
223
|
+
try {
|
|
224
|
+
// TODO: Initialize connection with serial port plugin
|
|
225
|
+
// For now, just set the connected flag
|
|
226
|
+
isConnected = true;
|
|
227
|
+
|
|
228
|
+
return new IOBoardResponse(true, "Connected to " + config.portPath + " successfully");
|
|
229
|
+
|
|
230
|
+
} catch (Exception e) {
|
|
231
|
+
Log.e(TAG, "Error connecting", e);
|
|
232
|
+
return new IOBoardResponse(false, "Error connecting: " + e.getMessage());
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Disconnect from serial port
|
|
238
|
+
*/
|
|
239
|
+
public IOBoardResponse disconnect() {
|
|
240
|
+
Log.d(TAG, "Disconnecting from serial port");
|
|
241
|
+
|
|
242
|
+
try {
|
|
243
|
+
// TODO: Close connection with serial port plugin
|
|
244
|
+
isConnected = false;
|
|
245
|
+
|
|
246
|
+
return new IOBoardResponse(true, "Disconnected successfully");
|
|
247
|
+
|
|
248
|
+
} catch (Exception e) {
|
|
249
|
+
Log.e(TAG, "Error disconnecting", e);
|
|
250
|
+
return new IOBoardResponse(false, "Error disconnecting: " + e.getMessage());
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Get status of IOBOARD device
|
|
256
|
+
*/
|
|
257
|
+
public StatusResponse getStatus(int address, int timeout) {
|
|
258
|
+
Log.d(TAG, "Getting status for address: " + address + " with timeout: " + timeout + "ms");
|
|
259
|
+
|
|
260
|
+
if (!isConnected) {
|
|
261
|
+
return new StatusResponse(false, "No serial connection established", null);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
try {
|
|
265
|
+
// Build status query frame
|
|
266
|
+
int[] frame = buildFrame(address, FRAME_TYPE_STATUS_QUERY, new int[0]);
|
|
267
|
+
|
|
268
|
+
Log.d(TAG, "Sending status query frame: " + frameToHex(frame));
|
|
269
|
+
|
|
270
|
+
// TODO: Send frame via serial port plugin and receive response
|
|
271
|
+
// For now, return a mock response
|
|
272
|
+
StatusData mockData = new StatusData(0b11010001, new SoftwareVersion(1, 2, 3));
|
|
273
|
+
return new StatusResponse(true, "Status retrieved successfully", mockData);
|
|
274
|
+
|
|
275
|
+
} catch (Exception e) {
|
|
276
|
+
Log.e(TAG, "Error getting status", e);
|
|
277
|
+
return new StatusResponse(false, "Error getting status: " + e.getMessage(), null);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Unlock a specific pallet with LED indication
|
|
283
|
+
*/
|
|
284
|
+
public IOBoardResponse unlockPallet(int address, int palletNumber, String ledColor, int timeout) {
|
|
285
|
+
Log.d(TAG, "Unlocking pallet - Address: " + address + ", Pallet: " + palletNumber + ", LED: " + ledColor);
|
|
286
|
+
|
|
287
|
+
if (!isConnected) {
|
|
288
|
+
return new IOBoardResponse(false, "No serial connection established");
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
try {
|
|
292
|
+
// Convert LED color to RGB values
|
|
293
|
+
LEDControl ledControl = getLEDControlFromColor(ledColor);
|
|
294
|
+
|
|
295
|
+
// Build data array for single pallet control
|
|
296
|
+
int[] data = new int[8];
|
|
297
|
+
data[0] = palletNumber;
|
|
298
|
+
data[1] = 1; // doorLock = true (unlock)
|
|
299
|
+
data[2] = ledControl.red;
|
|
300
|
+
data[3] = ledControl.green;
|
|
301
|
+
data[4] = ledControl.blue;
|
|
302
|
+
data[5] = ledControl.intensity;
|
|
303
|
+
data[6] = ledControl.blinkTimes;
|
|
304
|
+
data[7] = ledControl.blinkSpeed;
|
|
305
|
+
|
|
306
|
+
int[] frame = buildFrame(address, FRAME_TYPE_SINGLE_PALLET, data);
|
|
307
|
+
|
|
308
|
+
Log.d(TAG, "Sending unlock pallet frame: " + frameToHex(frame));
|
|
309
|
+
|
|
310
|
+
// TODO: Send frame via serial port plugin and receive response
|
|
311
|
+
return new IOBoardResponse(true, "Pallet " + palletNumber + " unlocked successfully");
|
|
312
|
+
|
|
313
|
+
} catch (Exception e) {
|
|
314
|
+
Log.e(TAG, "Error unlocking pallet", e);
|
|
315
|
+
return new IOBoardResponse(false, "Error unlocking pallet: " + e.getMessage());
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Control multiple pallets using a bitmask
|
|
321
|
+
*/
|
|
322
|
+
public IOBoardResponse controlMultiplePallets(int address, int doorLockMask, String ledColor, int timeout) {
|
|
323
|
+
Log.d(TAG, "Controlling multiple pallets - Address: " + address + ", Mask: 0x" + Integer.toHexString(doorLockMask));
|
|
324
|
+
|
|
325
|
+
if (!isConnected) {
|
|
326
|
+
return new IOBoardResponse(false, "No serial connection established");
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
try {
|
|
330
|
+
// Convert LED color to RGB values
|
|
331
|
+
LEDControl ledControl = getLEDControlFromColor(ledColor);
|
|
332
|
+
|
|
333
|
+
// Build data array for full pallet control
|
|
334
|
+
int[] data = new int[2 + (8 * 6)];
|
|
335
|
+
int index = 0;
|
|
336
|
+
|
|
337
|
+
data[index++] = doorLockMask;
|
|
338
|
+
data[index++] = 0; // extendedControl
|
|
339
|
+
|
|
340
|
+
// Add LED controls for 8 pallets
|
|
341
|
+
for (int i = 0; i < 8; i++) {
|
|
342
|
+
// If pallet is affected by mask, use specified LED color, otherwise turn off
|
|
343
|
+
LEDControl led = ((doorLockMask & (1 << i)) != 0) ? ledControl : new LEDControl(0, 0, 0, 0, 0, 0);
|
|
344
|
+
data[index++] = led.red;
|
|
345
|
+
data[index++] = led.green;
|
|
346
|
+
data[index++] = led.blue;
|
|
347
|
+
data[index++] = led.intensity;
|
|
348
|
+
data[index++] = led.blinkTimes;
|
|
349
|
+
data[index++] = led.blinkSpeed;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
int[] frame = buildFrame(address, FRAME_TYPE_FULL_PALLET, data);
|
|
353
|
+
|
|
354
|
+
Log.d(TAG, "Sending multiple pallets control frame: " + frameToHex(frame));
|
|
355
|
+
|
|
356
|
+
// TODO: Send frame via serial port plugin and receive response
|
|
357
|
+
return new IOBoardResponse(true, "Multiple pallets controlled successfully");
|
|
358
|
+
|
|
359
|
+
} catch (Exception e) {
|
|
360
|
+
Log.e(TAG, "Error controlling multiple pallets", e);
|
|
361
|
+
return new IOBoardResponse(false, "Error controlling multiple pallets: " + e.getMessage());
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Scan for devices in address range
|
|
367
|
+
*/
|
|
368
|
+
public ScanResponse scanDevices(int startAddress, int endAddress, int timeout) {
|
|
369
|
+
Log.d(TAG, "Scanning devices from address " + startAddress + " to " + endAddress);
|
|
370
|
+
|
|
371
|
+
if (!isConnected) {
|
|
372
|
+
return new ScanResponse(false, "No serial connection established", null);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
try {
|
|
376
|
+
int deviceCount = endAddress - startAddress + 1;
|
|
377
|
+
DeviceInfo[] devices = new DeviceInfo[deviceCount];
|
|
378
|
+
|
|
379
|
+
// TODO: Actually scan devices by sending status queries
|
|
380
|
+
// For now, create mock responses
|
|
381
|
+
for (int i = 0; i < deviceCount; i++) {
|
|
382
|
+
int address = startAddress + i;
|
|
383
|
+
boolean responding = (i % 3 == 0); // Mock: every 3rd device responds
|
|
384
|
+
StatusData status = responding ? new StatusData(0x00, new SoftwareVersion(1, 0, 0)) : null;
|
|
385
|
+
devices[i] = new DeviceInfo(address, responding, status);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
return new ScanResponse(true, "Scanned addresses " + startAddress + "-" + endAddress, devices);
|
|
389
|
+
|
|
390
|
+
} catch (Exception e) {
|
|
391
|
+
Log.e(TAG, "Error scanning devices", e);
|
|
392
|
+
return new ScanResponse(false, "Error scanning devices: " + e.getMessage(), null);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Send OTA notification (renamed method)
|
|
398
|
+
*/
|
|
399
|
+
public IOBoardResponse sendOTANotification(int address, int majorVersion, int minorVersion, int patchVersion, int firmwareSize) {
|
|
400
|
+
return otaNotification(address, majorVersion, minorVersion, patchVersion, firmwareSize);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Send OTA data (renamed method)
|
|
405
|
+
*/
|
|
406
|
+
public IOBoardResponse sendOTAData(int address, int packetNumber, String dataBase64) {
|
|
407
|
+
return otaData(address, packetNumber, dataBase64);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Helper method to convert color name to LED control
|
|
412
|
+
*/
|
|
413
|
+
private LEDControl getLEDControlFromColor(String color) {
|
|
414
|
+
switch (color.toLowerCase()) {
|
|
415
|
+
case "red":
|
|
416
|
+
return new LEDControl(255, 0, 0, 255, 0, 0);
|
|
417
|
+
case "green":
|
|
418
|
+
return new LEDControl(0, 255, 0, 255, 0, 0);
|
|
419
|
+
case "blue":
|
|
420
|
+
return new LEDControl(0, 0, 255, 255, 0, 0);
|
|
421
|
+
case "yellow":
|
|
422
|
+
return new LEDControl(255, 255, 0, 255, 0, 0);
|
|
423
|
+
case "cyan":
|
|
424
|
+
return new LEDControl(0, 255, 255, 255, 0, 0);
|
|
425
|
+
case "magenta":
|
|
426
|
+
return new LEDControl(255, 0, 255, 255, 0, 0);
|
|
427
|
+
case "white":
|
|
428
|
+
return new LEDControl(255, 255, 255, 255, 0, 0);
|
|
429
|
+
case "off":
|
|
430
|
+
return new LEDControl(0, 0, 0, 0, 0, 0);
|
|
431
|
+
default:
|
|
432
|
+
return new LEDControl(0, 255, 0, 255, 0, 0); // Default to green
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// Legacy methods (keep for backwards compatibility during transition)
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Query status of IOBOARD device
|
|
440
|
+
*/
|
|
441
|
+
public StatusResponse queryStatus(int address) {
|
|
442
|
+
Log.d(TAG, "Querying status for address: " + address);
|
|
443
|
+
|
|
444
|
+
if (!isConnected) {
|
|
445
|
+
return new StatusResponse(false, "No serial connection established", null);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
try {
|
|
449
|
+
// Build status query frame
|
|
450
|
+
int[] frame = buildFrame(address, FRAME_TYPE_STATUS_QUERY, new int[0]);
|
|
451
|
+
|
|
452
|
+
Log.d(TAG, "Sending status query frame: " + frameToHex(frame));
|
|
453
|
+
|
|
454
|
+
// TODO: Send frame via serial port plugin and receive response
|
|
455
|
+
// For now, return a mock response
|
|
456
|
+
StatusData mockData = new StatusData(0x00, new SoftwareVersion(1, 0, 0));
|
|
457
|
+
return new StatusResponse(true, "Status queried successfully", mockData);
|
|
458
|
+
|
|
459
|
+
} catch (Exception e) {
|
|
460
|
+
Log.e(TAG, "Error querying status", e);
|
|
461
|
+
return new StatusResponse(false, "Error querying status: " + e.getMessage(), null);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Control a single pallet
|
|
467
|
+
*/
|
|
468
|
+
public IOBoardResponse controlSinglePallet(int address, int palletNumber, boolean doorLock, LEDControl ledControl) {
|
|
469
|
+
Log.d(TAG, "Controlling single pallet - Address: " + address + ", Pallet: " + palletNumber);
|
|
470
|
+
|
|
471
|
+
if (!isConnected) {
|
|
472
|
+
return new IOBoardResponse(false, "No serial connection established");
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
try {
|
|
476
|
+
// Build data array
|
|
477
|
+
int[] data = new int[8];
|
|
478
|
+
data[0] = palletNumber;
|
|
479
|
+
data[1] = doorLock ? 1 : 0;
|
|
480
|
+
data[2] = ledControl.red;
|
|
481
|
+
data[3] = ledControl.green;
|
|
482
|
+
data[4] = ledControl.blue;
|
|
483
|
+
data[5] = ledControl.intensity;
|
|
484
|
+
data[6] = ledControl.blinkTimes;
|
|
485
|
+
data[7] = ledControl.blinkSpeed;
|
|
486
|
+
|
|
487
|
+
int[] frame = buildFrame(address, FRAME_TYPE_SINGLE_PALLET, data);
|
|
488
|
+
|
|
489
|
+
Log.d(TAG, "Sending single pallet control frame: " + frameToHex(frame));
|
|
490
|
+
|
|
491
|
+
// TODO: Send frame via serial port plugin and receive response
|
|
492
|
+
return new IOBoardResponse(true, "Single pallet controlled successfully");
|
|
493
|
+
|
|
494
|
+
} catch (Exception e) {
|
|
495
|
+
Log.e(TAG, "Error controlling single pallet", e);
|
|
496
|
+
return new IOBoardResponse(false, "Error controlling single pallet: " + e.getMessage());
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Control all pallets
|
|
502
|
+
*/
|
|
503
|
+
public IOBoardResponse controlFullPallet(int address, int doorLockControl, int extendedControl, LEDControl[] ledControls) {
|
|
504
|
+
Log.d(TAG, "Controlling full pallet - Address: " + address);
|
|
505
|
+
|
|
506
|
+
if (!isConnected) {
|
|
507
|
+
return new IOBoardResponse(false, "No serial connection established");
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
try {
|
|
511
|
+
// Build data array: doorLockControl + extendedControl + 8 LED controls (6 bytes each)
|
|
512
|
+
int[] data = new int[2 + (8 * 6)];
|
|
513
|
+
int index = 0;
|
|
514
|
+
|
|
515
|
+
data[index++] = doorLockControl;
|
|
516
|
+
data[index++] = extendedControl;
|
|
517
|
+
|
|
518
|
+
// Add LED controls for 8 pallets
|
|
519
|
+
for (int i = 0; i < 8; i++) {
|
|
520
|
+
LEDControl led = (i < ledControls.length) ? ledControls[i] : new LEDControl(0, 0, 0, 0, 0, 0);
|
|
521
|
+
data[index++] = led.red;
|
|
522
|
+
data[index++] = led.green;
|
|
523
|
+
data[index++] = led.blue;
|
|
524
|
+
data[index++] = led.intensity;
|
|
525
|
+
data[index++] = led.blinkTimes;
|
|
526
|
+
data[index++] = led.blinkSpeed;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
int[] frame = buildFrame(address, FRAME_TYPE_FULL_PALLET, data);
|
|
530
|
+
|
|
531
|
+
Log.d(TAG, "Sending full pallet control frame: " + frameToHex(frame));
|
|
532
|
+
|
|
533
|
+
// TODO: Send frame via serial port plugin and receive response
|
|
534
|
+
return new IOBoardResponse(true, "Full pallet controlled successfully");
|
|
535
|
+
|
|
536
|
+
} catch (Exception e) {
|
|
537
|
+
Log.e(TAG, "Error controlling full pallet", e);
|
|
538
|
+
return new IOBoardResponse(false, "Error controlling full pallet: " + e.getMessage());
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* Send OTA notification
|
|
544
|
+
*/
|
|
545
|
+
public IOBoardResponse otaNotification(int address, int majorVersion, int minorVersion, int patchVersion, int firmwareSize) {
|
|
546
|
+
Log.d(TAG, "Sending OTA notification - Address: " + address + ", Version: " + majorVersion + "." + minorVersion + "." + patchVersion);
|
|
547
|
+
|
|
548
|
+
if (!isConnected) {
|
|
549
|
+
return new IOBoardResponse(false, "No serial connection established");
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
try {
|
|
553
|
+
// Build OTA notification data: version(3) + firmware size(4)
|
|
554
|
+
int[] data = new int[7];
|
|
555
|
+
data[0] = majorVersion;
|
|
556
|
+
data[1] = minorVersion;
|
|
557
|
+
data[2] = patchVersion;
|
|
558
|
+
data[3] = firmwareSize & 0xFF;
|
|
559
|
+
data[4] = (firmwareSize >> 8) & 0xFF;
|
|
560
|
+
data[5] = (firmwareSize >> 16) & 0xFF;
|
|
561
|
+
data[6] = (firmwareSize >> 24) & 0xFF;
|
|
562
|
+
|
|
563
|
+
int[] frame = buildFrame(address, FRAME_TYPE_OTA_REQUEST, data);
|
|
564
|
+
|
|
565
|
+
Log.d(TAG, "Sending OTA notification frame: " + frameToHex(frame));
|
|
566
|
+
|
|
567
|
+
// TODO: Send frame via serial port plugin and receive response
|
|
568
|
+
return new IOBoardResponse(true, "OTA notification sent successfully");
|
|
569
|
+
|
|
570
|
+
} catch (Exception e) {
|
|
571
|
+
Log.e(TAG, "Error sending OTA notification", e);
|
|
572
|
+
return new IOBoardResponse(false, "Error sending OTA notification: " + e.getMessage());
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* Send OTA data packet
|
|
578
|
+
*/
|
|
579
|
+
public IOBoardResponse otaData(int address, int packetNumber, String dataBase64) {
|
|
580
|
+
Log.d(TAG, "Sending OTA data - Address: " + address + ", Packet: " + packetNumber);
|
|
581
|
+
|
|
582
|
+
if (!isConnected) {
|
|
583
|
+
return new IOBoardResponse(false, "No serial connection established");
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
try {
|
|
587
|
+
// Decode base64 data
|
|
588
|
+
byte[] firmwareData = Base64.decode(dataBase64, Base64.DEFAULT);
|
|
589
|
+
|
|
590
|
+
// Build OTA data: packet number(4) + data
|
|
591
|
+
int[] data = new int[4 + firmwareData.length];
|
|
592
|
+
data[0] = packetNumber & 0xFF;
|
|
593
|
+
data[1] = (packetNumber >> 8) & 0xFF;
|
|
594
|
+
data[2] = (packetNumber >> 16) & 0xFF;
|
|
595
|
+
data[3] = (packetNumber >> 24) & 0xFF;
|
|
596
|
+
|
|
597
|
+
for (int i = 0; i < firmwareData.length; i++) {
|
|
598
|
+
data[4 + i] = firmwareData[i] & 0xFF;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
int[] frame = buildFrame(address, FRAME_TYPE_OTA_DATA, data);
|
|
602
|
+
|
|
603
|
+
Log.d(TAG, "Sending OTA data frame: " + frameToHex(frame));
|
|
604
|
+
|
|
605
|
+
// TODO: Send frame via serial port plugin and receive response
|
|
606
|
+
return new IOBoardResponse(true, "OTA data sent successfully");
|
|
607
|
+
|
|
608
|
+
} catch (Exception e) {
|
|
609
|
+
Log.e(TAG, "Error sending OTA data", e);
|
|
610
|
+
return new IOBoardResponse(false, "Error sending OTA data: " + e.getMessage());
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* Open serial connection
|
|
616
|
+
*/
|
|
617
|
+
public IOBoardResponse openConnection(SerialConfig config) {
|
|
618
|
+
Log.d(TAG, "Opening serial connection - BaudRate: " + config.baudRate);
|
|
619
|
+
|
|
620
|
+
try {
|
|
621
|
+
// TODO: Initialize connection with serial port plugin
|
|
622
|
+
// For now, just set the connected flag
|
|
623
|
+
isConnected = true;
|
|
624
|
+
|
|
625
|
+
return new IOBoardResponse(true, "Serial connection opened successfully");
|
|
626
|
+
|
|
627
|
+
} catch (Exception e) {
|
|
628
|
+
Log.e(TAG, "Error opening connection", e);
|
|
629
|
+
return new IOBoardResponse(false, "Error opening connection: " + e.getMessage());
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* Close serial connection
|
|
635
|
+
*/
|
|
636
|
+
public IOBoardResponse closeConnection() {
|
|
637
|
+
Log.d(TAG, "Closing serial connection");
|
|
638
|
+
|
|
639
|
+
try {
|
|
640
|
+
// TODO: Close connection with serial port plugin
|
|
641
|
+
isConnected = false;
|
|
642
|
+
|
|
643
|
+
return new IOBoardResponse(true, "Serial connection closed successfully");
|
|
644
|
+
|
|
645
|
+
} catch (Exception e) {
|
|
646
|
+
Log.e(TAG, "Error closing connection", e);
|
|
647
|
+
return new IOBoardResponse(false, "Error closing connection: " + e.getMessage());
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* Check if serial connection is open
|
|
653
|
+
*/
|
|
654
|
+
public boolean isConnected() {
|
|
655
|
+
return isConnected;
|
|
656
|
+
}
|
|
657
|
+
}
|