@@ -473,7 +473,96 @@ async def _authenticate(self) -> None:
473
473
datetime .now (),
474
474
)
475
475
476
- async def update_device_info (self ) -> None :
476
+ async def _get_accounts (self ) -> Optional [dict ]:
477
+
478
+ _LOGGER .debug ("Retrieving account information" )
479
+
480
+ # Retrieve the accounts
481
+ _ , accounts_resp = await self .request (
482
+ method = "get" , returns = "json" , url = ACCOUNTS_ENDPOINT
483
+ )
484
+
485
+ if accounts_resp is not None and accounts_resp .get ("accounts" ) is not None :
486
+ accounts = {}
487
+ for account in accounts_resp ["accounts" ]:
488
+ account_id = account .get ("id" )
489
+ if account_id is not None :
490
+ _LOGGER .debug (
491
+ f"Got account { account_id } with name { account .get ('name' )} "
492
+ )
493
+ accounts .update ({account_id : account .get ("name" )})
494
+ else :
495
+ _LOGGER .debug (f"No accounts found" )
496
+ accounts = None
497
+
498
+ return accounts
499
+
500
+ async def _get_devices_for_account (self , account ) -> None :
501
+
502
+ _LOGGER .debug (f"Retrieving devices for account { self .accounts [account ]} " )
503
+
504
+ _ , devices_resp = await self .request (
505
+ method = "get" ,
506
+ returns = "json" ,
507
+ url = DEVICES_ENDPOINT .format (account_id = account ),
508
+ )
509
+
510
+ state_update_timestmp = datetime .utcnow ()
511
+ if devices_resp is not None and devices_resp .get ("items" ) is not None :
512
+ for device in devices_resp .get ("items" ):
513
+ serial_number = device .get ("serial_number" )
514
+ if serial_number is None :
515
+ _LOGGER .debug (f"No serial number for device with name { device .get ('name' )} ." )
516
+ continue
517
+
518
+ if serial_number in self .devices :
519
+ _LOGGER .debug (f"Updating information for device with serial number { serial_number } " )
520
+ myqdevice = self .devices [serial_number ]
521
+
522
+ # When performing commands we might update the state temporary, need to ensure
523
+ # that the state is not set back to something else if MyQ does not yet have updated
524
+ # state
525
+ last_update = myqdevice .device_json ["state" ].get ("last_update" )
526
+ myqdevice .device_json = device
527
+
528
+ if myqdevice .device_json ["state" ].get ("last_update" ) is not None and \
529
+ myqdevice .device_json ["state" ].get ("last_update" ) != last_update :
530
+ # MyQ has updated device state, reset ours ensuring we have the one from MyQ.
531
+ myqdevice .state = None
532
+ _LOGGER .debug (f"State for device { myqdevice .name } was updated to { myqdevice .state } " )
533
+
534
+ myqdevice .state_update = state_update_timestmp
535
+ else :
536
+ if device .get ("device_family" ) == DEVICE_FAMILY_GARAGEDOOR :
537
+ _LOGGER .debug (f"Adding new garage door with serial number { serial_number } " )
538
+ self .devices [serial_number ] = MyQGaragedoor (
539
+ api = self ,
540
+ account = account ,
541
+ device_json = device ,
542
+ state_update = state_update_timestmp ,
543
+ )
544
+ elif device .get ("device_family" ) == DEVICE_FAMLY_LAMP :
545
+ _LOGGER .debug (f"Adding new lamp with serial number { serial_number } " )
546
+ self .devices [serial_number ] = MyQLamp (
547
+ api = self ,
548
+ account = account ,
549
+ device_json = device ,
550
+ state_update = state_update_timestmp ,
551
+ )
552
+ elif device .get ("device_family" ) == DEVICE_FAMILY_GATEWAY :
553
+ _LOGGER .debug (f"Adding new gateway with serial number { serial_number } " )
554
+ self .devices [serial_number ] = MyQDevice (
555
+ api = self ,
556
+ account = account ,
557
+ device_json = device ,
558
+ state_update = state_update_timestmp ,
559
+ )
560
+ else :
561
+ _LOGGER .warning (f"Unknown device family { device .get ('device_family' )} " )
562
+ else :
563
+ _LOGGER .debug (f"No devices found for account { self .accounts [account ]} " )
564
+
565
+ async def update_device_info (self , for_account : str = None ) -> None :
477
566
"""Get up-to-date device info."""
478
567
# The MyQ API can time out if state updates are too frequent; therefore,
479
568
# if back-to-back requests occur within a threshold, respond to only the first
@@ -486,113 +575,40 @@ async def update_device_info(self) -> None:
486
575
self .last_state_update + DEFAULT_STATE_UPDATE_INTERVAL
487
576
)
488
577
489
- if call_dt < next_available_call_dt :
578
+ # Ensure we're within our minimum update interval AND update request is not for a specific device
579
+ if call_dt < next_available_call_dt and for_account is None :
490
580
_LOGGER .debug (
491
581
"Ignoring device update request as it is within throttle window"
492
582
)
493
583
return
494
584
495
- _LOGGER .debug (
496
- "Updating device information, starting with retrieving accounts"
497
- )
498
- _ , accounts_resp = await self .request (
499
- method = "get" , returns = "json" , url = ACCOUNTS_ENDPOINT
500
- )
501
- self .accounts = {}
502
- if accounts_resp is not None and accounts_resp .get ("accounts" ) is not None :
503
- for account in accounts_resp ["accounts" ]:
504
- account_id = account .get ("id" )
505
- if account_id is not None :
506
- _LOGGER .debug (
507
- f"Got account { account_id } with name { account .get ('name' )} "
508
- )
509
- self .accounts .update ({account_id : account .get ("name" )})
510
- else :
511
- _LOGGER .debug (f"No accounts found" )
512
- self .devices = []
585
+ _LOGGER .debug ("Updating device information" )
586
+ # If update request is for a specific account then do not retrieve account information.
587
+ if for_account is None :
588
+ self .accounts = await self ._get_accounts ()
513
589
514
- for account in self .accounts :
515
- _LOGGER .debug (
516
- f"Retrieving devices for account { self .accounts [account ]} "
517
- )
518
- _ , devices_resp = await self .request (
519
- method = "get" ,
520
- returns = "json" ,
521
- url = DEVICES_ENDPOINT .format (account_id = account ),
522
- )
523
-
524
- state_update_timestmp = datetime .utcnow ()
525
- if devices_resp is not None and devices_resp .get ("items" ) is not None :
526
- for device in devices_resp .get ("items" ):
527
- serial_number = device .get ("serial_number" )
528
- if serial_number is None :
529
- _LOGGER .debug (
530
- f"No serial number for device with name { device .get ('name' )} ."
531
- )
532
- continue
533
-
534
- if serial_number in self .devices :
535
- _LOGGER .debug (
536
- f"Updating information for device with serial number { serial_number } "
537
- )
538
- myqdevice = self .devices [serial_number ]
539
-
540
- # When performing commands we might update the state temporary, need to ensure
541
- # that the state is not set back to something else if MyQ does not yet have updated
542
- # state
543
- last_update = myqdevice .device_json ["state" ].get ("last_update" )
544
- myqdevice .device_json = device
545
-
546
- if myqdevice .device_json ["state" ].get ("last_update" ) is not None and \
547
- myqdevice .device_json ["state" ].get ("last_update" ) != last_update :
548
- # MyQ has updated device state, reset ours ensuring we have the one from MyQ.
549
- myqdevice .state = None
550
- _LOGGER .debug (f"State for device { myqdevice .name } was updated to { myqdevice .state } " )
551
-
552
-
553
- myqdevice .state_update = state_update_timestmp
554
- else :
555
- if device .get ("device_family" ) == DEVICE_FAMILY_GARAGEDOOR :
556
- _LOGGER .debug (
557
- f"Adding new garage door with serial number { serial_number } "
558
- )
559
- self .devices [serial_number ] = MyQGaragedoor (
560
- api = self ,
561
- account = account ,
562
- device_json = device ,
563
- state_update = state_update_timestmp ,
564
- )
565
- elif device .get ("device_family" ) == DEVICE_FAMLY_LAMP :
566
- _LOGGER .debug (
567
- f"Adding new lamp with serial number { serial_number } "
568
- )
569
- self .devices [serial_number ] = MyQLamp (
570
- api = self ,
571
- account = account ,
572
- device_json = device ,
573
- state_update = state_update_timestmp ,
574
- )
575
- elif device .get ("device_family" ) == DEVICE_FAMILY_GATEWAY :
576
- _LOGGER .debug (
577
- f"Adding new gateway with serial number { serial_number } "
578
- )
579
- self .devices [serial_number ] = MyQDevice (
580
- api = self ,
581
- account = account ,
582
- device_json = device ,
583
- state_update = state_update_timestmp ,
584
- )
585
- else :
586
- _LOGGER .warning (
587
- f"Unknown device family { device .get ('device_family' )} "
588
- )
589
- else :
590
- _LOGGER .debug (
591
- f"No devices found for account { self .accounts [account ]} "
592
- )
590
+ if self .accounts is None :
591
+ _LOGGER .debug (f"No accounts found" )
593
592
self .devices = []
593
+ accounts = {}
594
+ else :
595
+ accounts = self .accounts
596
+ else :
597
+ # Request is for specific account, thus restrict retrieval to the 1 account.
598
+ if self .accounts .get (for_account ) is None :
599
+ # Checking to ensure we know the account, but this should never happen.
600
+ _LOGGER .debug (f"Unable to perform update request for account { account } as it is not known." )
601
+ accounts = {}
602
+ else :
603
+ accounts = ({for_account : self .accounts .get (for_account )})
604
+
605
+ for account in accounts :
606
+ _LOGGER .debug (f"Retrieving devices for account { self .accounts [account ]} " )
607
+ await self ._get_devices_for_account (account = account )
594
608
595
- self .last_state_update = datetime .utcnow ()
609
+ # Update our last update timestamp UNLESS this is for a specific account
610
+ if for_account is None :
611
+ self .last_state_update = datetime .utcnow ()
596
612
597
613
598
614
async def login (username : str , password : str , websession : ClientSession = None ) -> API :
0 commit comments