1. import os
    2. import sys
    3. import threading
    4. import requests
    5. from collections import defaultdict
    6. from alibabacloud_iot20180120.client import Client as Iot20180120Client
    7. from alibabacloud_iot20180120.models import QueryDeviceDetailResponseBodyData, QueryDeviceByStatusResponseBody, \
    8. BatchQueryDeviceDetailResponseBodyData
    9. from alibabacloud_tea_openapi import models as open_api_models
    10. from alibabacloud_iot20180120 import models as iot_20180120_models
    11. statusList = [1, 3]
    12. endpoints = {
    13. '中国': 'iot.cn-shanghai.aliyuncs.com',
    14. '东南亚': 'iot.ap-southeast-1.aliyuncs.com',
    15. '美国': 'iot.us-east-1.aliyuncs.com',
    16. '欧洲': 'iot.eu-central-1.aliyuncs.com'
    17. }
    18. class Sample:
    19. def __init__(self):
    20. pass
    21. @staticmethod
    22. def create_client(endpoint) -> Iot20180120Client:
    23. """
    24. 使用AK&SK初始化账号Client
    25. @author:WHN
    26. @param: endpoint:区服
    27. @return: Client
    28. """
    29. config = open_api_models.Config(
    30. # 您的AccessKey ID,
    31. access_key_id='填入您的AccessKey ID',
    32. # 您的AccessKey Secret,
    33. access_key_secret='填入您的AccessKey Secret'
    34. )
    35. # 访问的域名
    36. config.endpoint = endpoints[endpoint]
    37. return Iot20180120Client(config)
    38. @staticmethod
    39. def query_device_detail(area: str, iot_id: str) -> QueryDeviceDetailResponseBodyData:
    40. """
    41. 查询指定设备的详细信息
    42. @author:WHN
    43. @param area:区服标识
    44. @param iot_id:设备ID
    45. @return: QueryDeviceDetailResponseBodyData
    46. """
    47. client = Sample.create_client(area)
    48. query_device_detail_request = iot_20180120_models.QueryDeviceDetailRequest(
    49. iot_id=iot_id
    50. )
    51. response = client.query_device_detail(query_device_detail_request)
    52. return response.body.data
    53. @staticmethod
    54. def batch_query_device_detail(area: str, product_key: str, device_name: list) -> list[BatchQueryDeviceDetailResponseBodyData] | None:
    55. """
    56. 批量查询指定设备的详细信息,每次最多100个设备
    57. @author:WHN
    58. @param area:区服标识
    59. @param product_key:ProductKey
    60. @param device_name:设备名称集合
    61. @return: BatchQueryDeviceDetailResponseBodyDataData
    62. """
    63. client = Sample.create_client(area)
    64. batch_query_device_detail_request = iot_20180120_models.BatchQueryDeviceDetailRequest(
    65. device_name=device_name,
    66. product_key=product_key
    67. )
    68. response = client.batch_query_device_detail(batch_query_device_detail_request)
    69. return response.body.data.data
    70. @staticmethod
    71. def query_device_by_status(
    72. area: str, status: int, page_size: int, current_page: int
    73. ) -> QueryDeviceByStatusResponseBody:
    74. """
    75. 根据设备状态查询设备列表,传入Status=1或3查询已激活的设备
    76. @author:WHN
    77. @param area:区服标识
    78. @param status:区服标识设备状态。可选值:0:未激活 1:在线 3:离线 8:已禁用
    79. @param page_size:每页显示的记录数量,最大值是50。默认值是10
    80. @param current_page:当前页数,默认值是 1
    81. @return: QueryDeviceResponseBody
    82. """
    83. client = Sample.create_client(area)
    84. query_device_by_status_request = iot_20180120_models.QueryDeviceByStatusRequest(
    85. status=status,
    86. page_size=page_size,
    87. current_page=current_page
    88. )
    89. response = client.query_device_by_status(query_device_by_status_request)
    90. return response.body
    91. # 阿里API:根据设备状态查询设备列表 + 批量查询指定产品下多个设备的详细信息
    92. def batch_cloud_order_device(area, iotIdList):
    93. try:
    94. device = []
    95. for status in statusList:
    96. statusResponsePage = Sample.query_device_by_status(area, status, 50, 1)
    97. # 循环分页查询在线、离线的设备
    98. for currentPage in range(1, statusResponsePage.page_count):
    99. statusResponse = Sample.query_device_by_status(area, status, 50, currentPage).data.to_map().get(
    100. 'SimpleDeviceInfo')
    101. # 根据product_key分组
    102. product_key_map = defaultdict(list)
    103. for statusData in statusResponse:
    104. product_key_map[statusData['ProductKey']].append(statusData)
    105. for key in product_key_map:
    106. # 批量获取device_name
    107. deviceNameList = [i['DeviceName'] for i in product_key_map.get(key)]
    108. deviceDetailList = Sample.batch_query_device_detail(area, key, deviceNameList)
    109. # 根据product_key、device_name集合,批量查询指定设备的详细信息
    110. for deviceData in deviceDetailList:
    111. deviceDetail = deviceData.to_map()
    112. deviceDetail['area'] = area
    113. if deviceDetail['IotId'] in iotIdList:
    114. deviceDetail['isOrder'] = 1
    115. if area == 'cn':
    116. # 根据ip获取地理位置
    117. location = getLocPyGaoDe(deviceDetail['IpAddress'])
    118. deviceDetail['province'] = location['province']
    119. deviceDetail['city'] = location['city']
    120. device.append(deviceDetail)
    121. print(deviceDetail)
    122. print('area:', area, ' deviceSize:', len(device))
    123. return device
    124. except BaseException as e:
    125. print(e)
    126. class myThread (threading.Thread):
    127. def __init__(self, area, iotIdList):
    128. threading.Thread.__init__(self)
    129. self.result = None
    130. self.area = area
    131. self.iotIdList = iotIdList
    132. def run(self):
    133. self.result = batch_cloud_order_device(self.area, self.iotIdList)
    134. def get_result(self):
    135. return self.result
    136. if __name__ == '__main__':
    137. # 查询设备索引
    138. iotIdList = select_order_device()
    139. device = []
    140. endpointList = endpoints.keys()
    141. threadList = []
    142. # 循环创建多个子线程
    143. for area in endpointList:
    144. thread = myThread(area, device)
    145. # 要先start
    146. thread.start()
    147. threadList.append(thread)
    148. for thread in threadList:
    149. # 然后再join,才能保证多个子线程同步进行
    150. thread.join()
    151. # 子线程结束后,汇总数据
    152. device.extend(thread.get_result())
    153. print("退出主线程")
    154. print(len(device))