@@ -69,6 +69,8 @@ public class LoxoneWebSocket {
6969 private CountDownLatch authSeqLatch ;
7070 private CountDownLatch visuLatch ;
7171
72+ private SyncCommandGuard <?> syncCommandGuard ;
73+
7274 private int authTimeoutSeconds = 3 ;
7375 private int visuTimeoutSeconds = 3 ;
7476 private int retries = 5 ;
@@ -115,7 +117,7 @@ public void registerListener(@NotNull final LoxoneEventListener listener) {
115117 eventListeners .add (listener );
116118 }
117119
118- public void sendCommand (@ NotNull final Command <?> command ) {
120+ public synchronized void sendCommand (@ NotNull final Command <?> command ) {
119121 requireNonNull (command , "command can't be null" );
120122 if (command .isWsSupported ()) {
121123 sendWithRetry (command , retries );
@@ -124,10 +126,25 @@ public void sendCommand(@NotNull final Command<?> command) {
124126 }
125127 }
126128
127- public void sendSecureCommand (@ NotNull final ControlCommand <?> command ) {
129+ public synchronized void sendSecureCommand (@ NotNull final ControlCommand <?> command ) {
128130 sendSecureWithRetry (command , retries );
129131 }
130132
133+ public synchronized <T > T commandRequest (@ NotNull final Command <T > command ) {
134+ requireNonNull (command , "command can't be null" );
135+ if (command .isWsSupported ()) {
136+ try {
137+ syncCommandGuard = new SyncCommandGuard <>(command );
138+ sendWithRetry (command , retries );
139+ return (T ) syncCommandGuard .waitForResponse (retries * authTimeoutSeconds );
140+ } finally {
141+ syncCommandGuard = null ;
142+ }
143+ } else {
144+ throw new IllegalArgumentException ("Only websocket commands are supported" );
145+ }
146+ }
147+
131148 public void close () {
132149 scheduler .shutdownNow ();
133150 closeWebSocket ();
@@ -328,7 +345,7 @@ void sendInternal(final Command<?> command) {
328345 LOG .debug ("Sending websocket message: " + command .getCommand ());
329346 webSocketClient .send (command .getCommand ());
330347 // KEEP_ALIVE command has no response at all
331- if (!KEEP_ALIVE .getCommand ().equals (command .getCommand ())) {
348+ if (!KEEP_ALIVE .getCommand ().equals (command .getCommand ()) && syncCommandGuard == null ) {
332349 commands .add (command );
333350 }
334351 }
@@ -339,7 +356,12 @@ void sendInternal(final Command<?> command) {
339356 */
340357 void processMessage (final String message ) {
341358 try {
342- final Command <?> command = commands .remove ();
359+ Command <?> command ;
360+ if (syncCommandGuard != null ) {
361+ command = syncCommandGuard .getCommand ();
362+ } else {
363+ command = commands .remove ();
364+ }
343365 if (!Void .class .equals (command .getResponseType ())) {
344366 final Object parsedMessage = Codec .readMessage (message , command .getResponseType ());
345367 if (parsedMessage instanceof LoxoneMessage ) {
@@ -467,26 +489,29 @@ private boolean checkLoxoneMessage(final Command<?> command, final LoxoneMessage
467489
468490 @ SuppressWarnings ("unchecked" )
469491 private void processCommand (final Command <?> command , final Object message , final boolean isError ) {
470- CommandResponseListener .State commandState = CommandResponseListener .State .IGNORED ;
471- final Iterator <CommandResponseListener <?>> listeners = commandResponseListeners .iterator ();
472- while (listeners .hasNext () && commandState != CommandResponseListener .State .CONSUMED ) {
473- @ SuppressWarnings ("rawtypes" )
474- final CommandResponseListener next = listeners .next ();
475- if (isError && next instanceof LoxoneMessageCommandResponseListener ) {
476- if (((LoxoneMessageCommandResponseListener ) next ).acceptsErrorResponses ()) {
492+ if (syncCommandGuard != null ) {
493+ syncCommandGuard .receive (message );
494+ } else {
495+ CommandResponseListener .State commandState = CommandResponseListener .State .IGNORED ;
496+ final Iterator <CommandResponseListener <?>> listeners = commandResponseListeners .iterator ();
497+ while (listeners .hasNext () && commandState != CommandResponseListener .State .CONSUMED ) {
498+ @ SuppressWarnings ("rawtypes" ) final CommandResponseListener next = listeners .next ();
499+ if (isError && next instanceof LoxoneMessageCommandResponseListener ) {
500+ if (((LoxoneMessageCommandResponseListener ) next ).acceptsErrorResponses ()) {
501+ commandState = commandState .fold (next .onCommand (command , message ));
502+ }
503+ } else if (next .accepts (message .getClass ())) {
477504 commandState = commandState .fold (next .onCommand (command , message ));
478505 }
479- } else if (next .accepts (message .getClass ())) {
480- commandState = commandState .fold (next .onCommand (command , message ));
481506 }
482- }
483507
484- if (commandState == CommandResponseListener .State .IGNORED ) {
485- LOG .warn ("No command listener registered, ignoring command=" + command );
486- }
508+ if (commandState == CommandResponseListener .State .IGNORED ) {
509+ LOG .warn ("No command listener registered, ignoring command=" + command );
510+ }
487511
488- if (command != null && command .getCommand ().startsWith (C_SYS_ENC )) {
489- LOG .warn ("Encrypted message receive is not supported" );
512+ if (command != null && command .getCommand ().startsWith (C_SYS_ENC )) {
513+ LOG .warn ("Encrypted message receive is not supported" );
514+ }
490515 }
491516 }
492517
0 commit comments