IotObject.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. import json
  4. from abc import ABCMeta,abstractmethod
  5. import boto3
  6. from awscrt import mqtt
  7. from Ansjer.config import AWS_IOT_SES_ACCESS_CHINA_REGION, AWS_IOT_SES_ACCESS_CHINA_ID, AWS_IOT_SES_ACCESS_CHINA_SECRET, \
  8. AWS_IOT_SES_ACCESS_FOREIGN_REGION_AMERICA, AWS_IOT_SES_ACCESS_FOREIGN_ID, AWS_IOT_SES_ACCESS_FOREIGN_SECRET, \
  9. AWS_IOT_SES_ACCESS_FOREIGN_REGION_EUROPE, AWS_IOT_SES_ACCESS_FOREIGN_REGION_ASIA, AWS_IOT_SES_ACCESS_CHINA_ROLE, \
  10. AWS_IOT_SES_ACCESS_FOREIGN_ROLE
  11. class IOTObject(metaclass=ABCMeta):
  12. @abstractmethod
  13. def create_provisioning_claim(self, templateName):
  14. pass
  15. @abstractmethod
  16. def create_keys_and_certificate(self, uid):
  17. pass
  18. class IOTClient(IOTObject):
  19. def __init__(self, region_id = 1):
  20. if region_id == 1:
  21. self.client = boto3.client('iot', region_name=AWS_IOT_SES_ACCESS_CHINA_REGION,
  22. aws_access_key_id=AWS_IOT_SES_ACCESS_CHINA_ID,
  23. aws_secret_access_key=AWS_IOT_SES_ACCESS_CHINA_SECRET)
  24. self.endpoint = 'a250bbr0p9u7as-ats.iot.cn-northwest-1.amazonaws.com.cn'
  25. self.iotrole = AWS_IOT_SES_ACCESS_CHINA_ROLE
  26. if region_id == 2:
  27. self.client = boto3.client('iot', region_name=AWS_IOT_SES_ACCESS_FOREIGN_REGION_ASIA,
  28. aws_access_key_id=AWS_IOT_SES_ACCESS_FOREIGN_ID,
  29. aws_secret_access_key=AWS_IOT_SES_ACCESS_FOREIGN_SECRET)
  30. self.endpoint = 'a2rqy12o004ad8-ats.iot.ap-southeast-1.amazonaws.com'
  31. self.iotrole = AWS_IOT_SES_ACCESS_FOREIGN_ROLE
  32. if region_id == 3:
  33. self.client = boto3.client('iot', region_name=AWS_IOT_SES_ACCESS_FOREIGN_REGION_AMERICA,
  34. aws_access_key_id=AWS_IOT_SES_ACCESS_FOREIGN_ID,
  35. aws_secret_access_key=AWS_IOT_SES_ACCESS_FOREIGN_SECRET)
  36. self.endpoint = 'a2rqy12o004ad8-ats.iot.us-east-1.amazonaws.com'
  37. self.iotrole = AWS_IOT_SES_ACCESS_FOREIGN_ROLE
  38. if region_id == 4:
  39. self.client = boto3.client('iot', region_name=AWS_IOT_SES_ACCESS_FOREIGN_REGION_EUROPE,
  40. aws_access_key_id=AWS_IOT_SES_ACCESS_FOREIGN_ID,
  41. aws_secret_access_key=AWS_IOT_SES_ACCESS_FOREIGN_SECRET)
  42. self.endpoint = 'a2rqy12o004ad8-ats.iot.eu-west-1.amazonaws.com'
  43. self.iotrole = AWS_IOT_SES_ACCESS_FOREIGN_ROLE
  44. def create_provisioning_claim(self, templateName):
  45. result = self.client.create_provisioning_claim(templateName=templateName)
  46. res = {
  47. 'certificateId': result['certificateId'],
  48. 'certificatePem': result['certificatePem'],
  49. 'publicKey': result['keyPair']['PublicKey'],
  50. 'privateKey': result['keyPair']['PrivateKey'],
  51. 'endpoint': self.endpoint
  52. }
  53. return res
  54. def create_keys_and_certificate(self, serial_number, thingGroup):
  55. try:
  56. result = self.client.create_keys_and_certificate(setAsActive=True)
  57. res = {
  58. 'certificateId': result['certificateId'],
  59. 'certificatePem': result['certificatePem'],
  60. 'publicKey': result['keyPair']['PublicKey'],
  61. 'privateKey': result['keyPair']['PrivateKey'],
  62. 'endpoint': self.endpoint
  63. }
  64. # 搜索是否存在该物品组
  65. thing_groups_res = self.client.list_thing_groups(nextToken='', maxResults=1,
  66. namePrefixFilter=thingGroup, recursive=False)
  67. if thing_groups_res['thingGroups']:
  68. thingGroupName = thing_groups_res['thingGroups'][0]['groupName'] # 获取物品组名称
  69. else:
  70. attributes = {
  71. "update_time": "0"
  72. }
  73. thingGroupProperties = {
  74. "thingGroupDescription": "OTA",
  75. "attributePayload": {
  76. "attributes": attributes,
  77. "merge": False # 更新时覆盖掉而不是合并
  78. }
  79. }
  80. create_thing_group_res = self.client.create_thing_group(thingGroupName=thingGroup,
  81. thingGroupProperties=thingGroupProperties)
  82. thingGroupName = create_thing_group_res['thingGroupName'] # 获取物品组名称
  83. print('物品组:', thingGroupName)
  84. # 根据证书ID注册物品和策略
  85. templateBody = {
  86. "Parameters": {
  87. "ThingName": {
  88. "Type": "String"
  89. },
  90. "SerialNumber": {
  91. "Type": "String"
  92. },
  93. "thingGroupName": {
  94. "Type": "String"
  95. },
  96. "AWS::IoT::Certificate::Id": {
  97. "Type": "String"
  98. }
  99. },
  100. "Resources": {
  101. "thing": {
  102. "Type": "AWS::IoT::Thing",
  103. "Properties": {
  104. "AttributePayload": {},
  105. # "ThingGroups" : ["v1-lightbulbs", {"Ref" : "DeviceLocation"}],
  106. "ThingName": {
  107. "Ref": "ThingName"
  108. },
  109. "ThingGroups": [{"Ref": "thingGroupName"}]
  110. },
  111. "OverrideSettings": {
  112. "AttributePayload": "MERGE",
  113. "ThingTypeName": "REPLACE",
  114. "ThingGroups": "DO_NOTHING"
  115. }
  116. },
  117. "certificate": {
  118. "Type": "AWS::IoT::Certificate",
  119. "Properties": {
  120. "CertificateId": {"Ref": "AWS::IoT::Certificate::Id"},
  121. "Status": "Active"
  122. }
  123. },
  124. "policy": {
  125. "Properties": {
  126. "PolicyName": "My_Iot_Policy"
  127. },
  128. "Type": "AWS::IoT::Policy"
  129. },
  130. }
  131. }
  132. templateBody = json.dumps(templateBody)
  133. parameters = {"ThingName": "Ansjer_Device_" + serial_number,
  134. "thingGroupName": thingGroupName,
  135. "AWS::IoT::Certificate::Id": res['certificateId']}
  136. self.client.register_thing(
  137. templateBody=templateBody,
  138. parameters=parameters
  139. )
  140. self.client.create_topic_rule(
  141. ruleName= 'Ansjer_Device_' + serial_number+'_LWT',
  142. topicRulePayload={
  143. "sql": 'my/things/'+ 'Ansjer_Device_' + serial_number+'/shadow/update-lwt',
  144. "ruleDisabled": False,
  145. "awsIotSqlVersion": "2016-03-23",
  146. 'actions': [
  147. {
  148. 'republish': {
  149. 'roleArn': self.iotrole,
  150. 'topic': '$$aws/things/'+ 'Ansjer_Device_' + serial_number+'/shadow/update',
  151. 'qos': mqtt.QoS.AT_LEAST_ONCE
  152. }
  153. }
  154. ]
  155. }
  156. )
  157. return res, parameters
  158. except Exception as e:
  159. print(e)
  160. # return response.json(500, repr(e))