@@ -147,17 +147,6 @@ public TuyaDeviceHandler(Thing thing, Gson gson,
147147
148148 @ Override
149149 public void processDeviceStatus (Map <Integer , Object > deviceStatus ) {
150- // Older devices may need to use the control method to request device status.
151- if (deviceStatus .isEmpty ()) {
152- TuyaDevice tuyaDevice = this .tuyaDevice ;
153- if (tuyaDevice != null ) {
154- logger .debug ("'{}' switching to control instead of query" , thing .getUID ());
155- tuyaDevice .setQueryUsesControl ();
156- tuyaDevice .requestStatus (List .of ());
157- }
158- return ;
159- }
160-
161150 // Changes to function DPs might lead to changes in status DPs. For instance, if a
162151 // power switch is turned on the measured current and power can be expected to change
163152 // within a few seconds.
@@ -178,6 +167,8 @@ public void processDeviceStatus(Map<Integer, Object> deviceStatus) {
178167 }
179168
180169 if (needRefresh && configuration .pollingInterval > 0 ) {
170+ // We cannot assume that DPs are current or that the device will automatically
171+ // re-measure on a function change.
181172 TuyaDevice tuyaDevice = this .tuyaDevice ;
182173 if (tuyaDevice != null ) {
183174 ScheduledFuture <?> pollingJob = this .pollingJob ;
@@ -186,7 +177,7 @@ public void processDeviceStatus(Map<Integer, Object> deviceStatus) {
186177 }
187178
188179 pollBurst = 3 ;
189- this .pollingJob = scheduler .scheduleWithFixedDelay (this ::burstPoller , 1 , 1 , TimeUnit .SECONDS );
180+ this .pollingJob = scheduler .scheduleWithFixedDelay (this ::burstPoller , 0 , 1 , TimeUnit .SECONDS );
190181 }
191182 } else if (!missingStatus ) {
192183 // If we have updates for everything we can stand down the burst polling.
@@ -200,19 +191,19 @@ private void burstPoller() {
200191 TuyaDevice tuyaDevice = this .tuyaDevice ;
201192 if (tuyaDevice != null ) {
202193 if (pollBurst > 0 ) {
203- tuyaDevice .refreshStatus (List . of () );
194+ tuyaDevice .refreshStatus ();
204195 pollBurst = pollBurst - 1 ;
205196 } else {
206197 ScheduledFuture <?> pollingJob = this .pollingJob ;
207198 if (pollingJob != null ) {
208199 this .pollingJob = null ;
209- pollingJob .cancel (true );
200+ pollingJob .cancel (false );
210201 }
211202
212203 int pollingInterval = configuration .pollingInterval ;
213204 if (pollingInterval > 0 ) {
214205 this .pollingJob = scheduler .scheduleWithFixedDelay (() -> {
215- tuyaDevice .refreshStatus (List . of () );
206+ tuyaDevice .refreshStatus ();
216207 }, pollingInterval , pollingInterval , TimeUnit .SECONDS );
217208 }
218209 }
@@ -324,7 +315,7 @@ private void processChannelStatus(Integer dp, Object value) {
324315 }
325316
326317 @ Override
327- public void connectionStatus (boolean status ) {
318+ public void connectionStatus (boolean status , int initialDelay ) {
328319 if (status ) {
329320 logger .debug ("{}: connected" , thing .getUID ().getId ());
330321
@@ -335,17 +326,25 @@ public void connectionStatus(boolean status) {
335326
336327 TuyaDevice tuyaDevice = this .tuyaDevice ;
337328 if (tuyaDevice != null ) {
338- // When we first connect the device state is unknown so we want to know everything
339- // it is willing to tell us.
340- tuyaDevice .requestStatus (List .of ());
341-
342329 if (pollingJob == null ) {
343- int pollingInterval = configuration .pollingInterval ;
344- if (pollingInterval > 0 ) {
345- pollingJob = scheduler .scheduleWithFixedDelay (() -> {
346- tuyaDevice .refreshStatus (List .of ());
347- }, pollingInterval , pollingInterval , TimeUnit .SECONDS );
348- }
330+ // When we first connect the device state is unknown so we want to query for everything.
331+ // Some devices seem to initialize their stacks in the wrong order and
332+ // requests that come too soon can be either ignored completely or responded
333+ // to with a, "not supported". The lower level protocol handler suggests an
334+ // initial delay where it might be advisable.
335+ this .pollingJob = scheduler .schedule (() -> {
336+ tuyaDevice .requestStatus ();
337+
338+ // After that we poll for the measurable DPs.
339+ int pollingInterval = configuration .pollingInterval ;
340+ if (pollingInterval > 0 ) {
341+ // The first refresh request is immediate because we do not know how old
342+ // the current status might be.
343+ pollingJob = scheduler .scheduleWithFixedDelay (() -> {
344+ tuyaDevice .refreshStatus ();
345+ }, 0 , pollingInterval , TimeUnit .SECONDS );
346+ }
347+ }, initialDelay , TimeUnit .MILLISECONDS );
349348 } else {
350349 logger .debug ("{}: polling job already exists?!?" , thing .getUID ().getId ());
351350 }
@@ -586,7 +585,7 @@ public void initialize() {
586585
587586 this .tuyaDevice = new TuyaDevice (gson , this , eventLoopGroup , configuration .deviceId ,
588587 configuration .localKey .getBytes (StandardCharsets .UTF_8 ), configuration .ip , configuration .port ,
589- configuration .protocol );
588+ configuration .protocol , schemaDps . values (). stream (). map ( e -> e . id ). toList () );
590589 } else {
591590 updateStatus (ThingStatus .OFFLINE , ThingStatusDetail .CONFIGURATION_PENDING , "@text/offline.wait-for-ip" );
592591 }
@@ -618,7 +617,7 @@ public void deviceInfoChanged(DeviceInfo deviceInfo) {
618617
619618 this .tuyaDevice = new TuyaDevice (gson , this , eventLoopGroup , configuration .deviceId ,
620619 configuration .localKey .getBytes (StandardCharsets .UTF_8 ), configuration .ip , configuration .port ,
621- configuration .protocol );
620+ configuration .protocol , schemaDps . values (). stream (). map ( e -> e . id ). toList () );
622621 } catch (IllegalArgumentException e ) {
623622 logger .warn ("{}" , e .getMessage ());
624623 updateStatus (ThingStatus .OFFLINE , ThingStatusDetail .COMMUNICATION_ERROR , e .getMessage ());
0 commit comments