27
27
import java .util .stream .Stream ;
28
28
29
29
import org .eclipse .jdt .annotation .NonNullByDefault ;
30
+ import org .eclipse .jdt .annotation .Nullable ;
31
+ import org .openhab .binding .insteon .internal .device .DeviceAddress ;
30
32
import org .openhab .binding .insteon .internal .device .InsteonAddress ;
31
33
import org .openhab .binding .insteon .internal .device .InsteonScene ;
32
34
import org .openhab .binding .insteon .internal .device .X10Address ;
@@ -82,19 +84,20 @@ private static enum MessageType {
82
84
83
85
private boolean monitoring = false ;
84
86
private boolean monitorAllDevices = false ;
85
- private Set <InsteonAddress > monitoredAddresses = new HashSet <>();
87
+ private Set <DeviceAddress > monitoredAddresses = new HashSet <>();
88
+ private @ Nullable X10Address lastX10Address ;
86
89
87
90
public DebugCommand (InsteonCommandExtension commandExtension ) {
88
91
super (NAME , DESCRIPTION , commandExtension );
89
92
}
90
93
91
94
@ Override
92
95
public List <String > getUsages () {
93
- return List .of (buildCommandUsage (LIST_MONITORED , "list monitored device(s)" ),
96
+ return List .of (buildCommandUsage (LIST_MONITORED , "list monitored Insteon/X10 device(s)" ),
94
97
buildCommandUsage (START_MONITORING + " " + ALL_OPTION + "|<address>" ,
95
- "start logging message events for device(s) in separate file(s)" ),
98
+ "start logging message events for Insteon/X10 device(s) in separate file(s)" ),
96
99
buildCommandUsage (STOP_MONITORING + " " + ALL_OPTION + "|<address>" ,
97
- "stop logging message events for device(s) in separate file(s)" ),
100
+ "stop logging message events for Insteon/X10 device(s) in separate file(s)" ),
98
101
buildCommandUsage (SEND_BROADCAST_MESSAGE + " <group> <cmd1> <cmd2>" ,
99
102
"send an Insteon broadcast message to a group" ),
100
103
buildCommandUsage (SEND_STANDARD_MESSAGE + " <address> <cmd1> <cmd2>" ,
@@ -196,14 +199,15 @@ public boolean complete(String[] args, int cursorArgumentIndex, int cursorPositi
196
199
case START_MONITORING :
197
200
strings = monitorAllDevices ? List .of ()
198
201
: Stream .concat (Stream .of (ALL_OPTION ),
199
- getModem ().getDB ().getDevices ().stream ()
202
+ Stream .concat (Stream .of (getModem ().getAddress ()),
203
+ getModem ().getDB ().getDevices ().stream ())
200
204
.filter (address -> !monitoredAddresses .contains (address ))
201
205
.map (InsteonAddress ::toString ))
202
206
.toList ();
203
207
break ;
204
208
case STOP_MONITORING :
205
209
strings = monitorAllDevices ? List .of (ALL_OPTION )
206
- : monitoredAddresses .stream ().map (InsteonAddress ::toString ).toList ();
210
+ : monitoredAddresses .stream ().map (DeviceAddress ::toString ).toList ();
207
211
break ;
208
212
case SEND_BROADCAST_MESSAGE :
209
213
strings = getModem ().getDB ().getBroadcastGroups ().stream ().map (String ::valueOf ).toList ();
@@ -235,54 +239,65 @@ public void disconnected() {
235
239
236
240
@ Override
237
241
public void messageReceived (Msg msg ) {
238
- try {
239
- InsteonAddress address = msg .getInsteonAddress (msg .isReply () ? "toAddress" : "fromAddress" );
240
- if (monitorAllDevices || monitoredAddresses .contains (address )) {
241
- logMessageEvent (address , msg );
242
- }
243
- } catch (FieldException ignored ) {
244
- // ignore message with no address field
245
- }
242
+ logMessageEvent (msg );
246
243
}
247
244
248
245
@ Override
249
246
public void messageSent (Msg msg ) {
250
- try {
251
- InsteonAddress address = msg .getInsteonAddress ("toAddress" );
252
- if (monitorAllDevices || monitoredAddresses .contains (address )) {
253
- logMessageEvent (address , msg );
247
+ logMessageEvent (msg );
248
+ }
249
+
250
+ private DeviceAddress getMsgEventAddress (Msg msg ) throws FieldException {
251
+ if (msg .isX10 ()) {
252
+ X10Address address = msg .isX10Address () ? msg .getX10Address () : lastX10Address ;
253
+ if (address == null ) {
254
+ throw new FieldException ("unknown x10 address" );
254
255
}
255
- } catch (FieldException ignored ) {
256
- // ignore message with no address field
256
+ lastX10Address = address ;
257
+ return address ;
258
+ } else if (msg .isInsteon ()) {
259
+ return msg .isInbound () && !msg .isReply () ? msg .getInsteonAddress ("fromAddress" )
260
+ : !msg .isAllLinkBroadcast () ? msg .getInsteonAddress ("toAddress" ) : getModem ().getAddress ();
261
+ } else {
262
+ return getModem ().getAddress ();
257
263
}
258
264
}
259
265
260
- private Path getMsgEventsFilePath (String address ) {
261
- return getBindingDataFilePath (MSG_EVENTS_FILE_PREFIX + "-" + address .toLowerCase ().replace ("." , "" ) + ".log" );
266
+ private Path getMsgEventsFilePath (DeviceAddress address ) {
267
+ String name = address .toString ().toLowerCase ().replace ("." , "" );
268
+ if (address instanceof X10Address ) {
269
+ name = "x10-" + name ;
270
+ }
271
+ return getBindingDataFilePath (MSG_EVENTS_FILE_PREFIX + "-" + name + ".log" );
262
272
}
263
273
264
- private void clearMonitorFiles (String address ) {
265
- String prefix = ALL_OPTION . equals ( address ) ? MSG_EVENTS_FILE_PREFIX
274
+ private void clearMonitorFiles (@ Nullable DeviceAddress address ) {
275
+ String prefix = address == null ? MSG_EVENTS_FILE_PREFIX
266
276
: getMsgEventsFilePath (address ).getFileName ().toString ();
267
277
268
278
getBindingDataFilePaths (prefix ).map (Path ::toFile ).forEach (File ::delete );
269
279
}
270
280
271
- private void logMessageEvent (InsteonAddress address , Msg msg ) {
272
- String timestamp = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss.SSS" ).format (new Date ());
273
- String line = timestamp + " " + msg + System .lineSeparator ();
274
- Path path = getMsgEventsFilePath (address .toString ());
275
-
281
+ private void logMessageEvent (Msg msg ) {
276
282
try {
277
- Files .createDirectories (path .getParent ());
278
- Files .writeString (path , line , StandardOpenOption .CREATE , StandardOpenOption .APPEND );
283
+ DeviceAddress address = getMsgEventAddress (msg );
284
+ if (monitorAllDevices || monitoredAddresses .contains (address )) {
285
+ String timestamp = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss.SSS" ).format (new Date ());
286
+ String line = timestamp + " " + msg + System .lineSeparator ();
287
+ Path path = getMsgEventsFilePath (address );
288
+
289
+ Files .createDirectories (path .getParent ());
290
+ Files .writeString (path , line , StandardOpenOption .CREATE , StandardOpenOption .APPEND );
291
+ }
292
+ } catch (FieldException e ) {
293
+ logger .warn ("failed to parse message" , e );
279
294
} catch (IOException e ) {
280
295
logger .warn ("failed to write to message event file" , e );
281
296
}
282
297
}
283
298
284
299
private void listMonitoredDevices (Console console ) {
285
- String addresses = monitoredAddresses .stream ().map (InsteonAddress ::toString ).collect (Collectors .joining (", " ));
300
+ String addresses = monitoredAddresses .stream ().map (DeviceAddress ::toString ).collect (Collectors .joining (", " ));
286
301
if (!addresses .isEmpty ()) {
287
302
console .println ("The monitored device(s) are: " + addresses );
288
303
} else if (monitorAllDevices ) {
@@ -292,30 +307,27 @@ private void listMonitoredDevices(Console console) {
292
307
}
293
308
}
294
309
295
- private void startMonitoring (Console console , String address ) {
296
- if (ALL_OPTION . equals ( address ) ) {
297
- if (! monitorAllDevices ) {
298
- monitorAllDevices = true ;
299
- monitoredAddresses . clear () ;
300
- console . println ( "Started monitoring all devices." );
301
- console .println ("Message events logged in " + getBindingDataDirPath () );
302
- clearMonitorFiles ( address );
303
- } else {
304
- console . println ( "Already monitoring all devices." );
305
- }
306
- } else if ( InsteonAddress .isValid (address )) {
307
- if (monitorAllDevices ) {
308
- console .println ("Already monitoring all devices." );
309
- } else if (monitoredAddresses .add (new InsteonAddress ( address ) )) {
310
+ private void startMonitoring (Console console , String arg ) {
311
+ if (monitorAllDevices ) {
312
+ console . println ( "Already monitoring all devices." );
313
+ } else if ( ALL_OPTION . equals ( arg )) {
314
+ monitorAllDevices = true ;
315
+ monitoredAddresses . clear ( );
316
+ console .println ("Started monitoring all devices." );
317
+ console . println ( "Message events logged in " + getBindingDataDirPath () );
318
+ clearMonitorFiles ( null );
319
+ } else {
320
+ DeviceAddress address = InsteonAddress . isValid ( arg ) ? new InsteonAddress ( arg )
321
+ : X10Address .isValid (arg ) ? new X10Address ( arg ) : null ;
322
+ if (address == null ) {
323
+ console .println ("Invalid device address argument: " + arg );
324
+ } else if (monitoredAddresses .add (address )) {
310
325
console .println ("Started monitoring the device " + address + "." );
311
326
console .println ("Message events logged in " + getMsgEventsFilePath (address ));
312
327
clearMonitorFiles (address );
313
328
} else {
314
329
console .println ("Already monitoring the device " + address + "." );
315
330
}
316
- } else {
317
- console .println ("Invalid device address" + address + "." );
318
- return ;
319
331
}
320
332
321
333
if (!monitoring ) {
@@ -324,31 +336,26 @@ private void startMonitoring(Console console, String address) {
324
336
}
325
337
}
326
338
327
- private void stopMonitoring (Console console , String address ) {
328
- if (!monitoring ) {
329
- console .println ("Not monitoring any devices." );
330
- return ;
331
- }
332
-
333
- if (ALL_OPTION .equals (address )) {
339
+ private void stopMonitoring (Console console , String arg ) {
340
+ if (ALL_OPTION .equals (arg )) {
334
341
if (monitorAllDevices ) {
335
342
monitorAllDevices = false ;
336
343
console .println ("Stopped monitoring all devices." );
337
344
} else {
338
345
console .println ("Not monitoring all devices." );
339
346
}
340
- } else if (InsteonAddress .isValid (address )) {
347
+ } else {
348
+ DeviceAddress address = InsteonAddress .isValid (arg ) ? new InsteonAddress (arg )
349
+ : X10Address .isValid (arg ) ? new X10Address (arg ) : null ;
341
350
if (monitorAllDevices ) {
342
351
console .println ("Not monitoring individual devices." );
343
- } else if (monitoredAddresses .remove (new InsteonAddress (address ))) {
352
+ } else if (address == null ) {
353
+ console .println ("Invalid device address argument: " + arg );
354
+ } else if (monitoredAddresses .remove (address )) {
344
355
console .println ("Stopped monitoring the device " + address + "." );
345
356
} else {
346
357
console .println ("Not monitoring the device " + address + "." );
347
- return ;
348
358
}
349
- } else {
350
- console .println ("Invalid address device address " + address + "." );
351
- return ;
352
359
}
353
360
354
361
if (!monitorAllDevices && monitoredAddresses .isEmpty ()) {
0 commit comments