项目作者: erickvneri

项目描述 :
SmartThings Schema Connector Python SDK.
高级语言: Python
项目地址: git://github.com/erickvneri/st-schema-python.git
创建时间: 2020-04-17T20:39:56Z
项目社区:https://github.com/erickvneri/st-schema-python

开源协议:MIT License

下载


SmartThings Schema Connector Python SDK

made-with-python
PyPI license
st-schema-python
PyPI download week

The SmartThings Schema Connector Python SDK is a package that simplify resources of
Schema Connector instances through built-in interfaces.

Installation

Install it using pip:

  1. pip install st-schema-python

SchemaConnector structure

Using class inheritance, we’ll gain access to a series of resources to control the request and response data of Interaction types.

  1. from stschema import SchemaConnector
  2. class MyConnector(SchemaConnector):
  3. def __init__(self, *opts):
  4. SchemaConnector.__init__(self, enable_logger=True)
  5. def discovery_handler(self, request_id, access_token):
  6. # The discovery_handler built-in method
  7. # gives access to discoveryRequest data.
  8. #
  9. # SchemaDevice instances must be passed
  10. # as a list argument to discovery_response
  11. # built-in method.
  12. declared_devices = [...]
  13. return self.discovery_response(declared_devices, request_id)
  14. def state_refresh_handler(self, devices, request_id, access_token):
  15. # The state_refresh_handler gives access to
  16. # stateRefreshRequest data.
  17. # A filtered list of SchemaDevice instances
  18. # must be passed as response to the
  19. # state_refresh_response built-in method.
  20. filtered_devices = [...]
  21. return self.state_refresh_response(filtered_devices, request_id)
  22. def command_handler(self, devices, request_id, access_token):
  23. # The command_handler gives access to the
  24. # commandRequest data.
  25. # A list of an updated SchemaDevice instance
  26. # must be passed as response to the
  27. # command_response built-in method.
  28. updated_device = [...]
  29. return self.command_response(updated_device, request_id)
  30. def grant_callback_access(self, callback_authentication, callback_urls):
  31. # Built-in method triggered with the
  32. # grantCallbackAccess interaction type.
  33. pass
  34. def integration_deleted(self, callback_authentication):
  35. # Built-in method triggered with the
  36. # integrationDeleted interactionType.
  37. pass
  38. def interaction_result_handler(self, interaction_result, origin):
  39. # The interaction_result_handler provides
  40. # a description of the error triggered
  41. # between interaction type responses.
  42. pass

Note: If any resource handler is not implemented but gets used by the SchemaConnector. interaction_handler built-in method, a NotImplementedError exception will be raised.


SchemaDevice definition.

SchemaDevice instance supporting the minimal requirements to create a virtual device at the SmartThings ecosystem.

  1. Device definition using the SchemaDevice class and the set_mn instance method to specify the manufacturer’s information:
  1. from stschema import SchemaDevice
  2. my_device = SchemaDevice(
  3. '{{external_device_id}}',
  4. '{{friendly_name}}',
  5. '{{device_handler_type}}'
  6. )
  7. my_device.set_mn(
  8. '{{manufacturer_name}}',
  9. '{{model_name}}'
  10. )
  1. States definition applying the set_state instance method:
  1. my_device.set_state(
  2. 'st.{{capability_id}}',
  3. '{{attribute}}',
  4. '{{value}}'
  5. )

SchemaConnector as a web-service with the Http.server built-in module.

Using the Python’s built-in module Http.server, here’s an example of an application that will host our Webhook endpoint and our SchemaConnector instance
to create and control a virtual switch at the SmartThings app.

  1. from http.server import BaseHTTPRequestHandler, HTTPServer
  2. from stschema import SchemaConnector, SchemaDevice
  3. import json
  4. # MyConnector definition
  5. class MyConnector(SchemaConnector):
  6. def __init__(self, *opts):
  7. SchemaConnector.__init__(self, enable_logger=True)
  8. def discovery_handler(self, request_id, access_token):
  9. # Device definition using the SchemaDevice class
  10. my_switch = SchemaDevice( # Device info
  11. 'xyz_example_id_xyz',
  12. 'Office light',
  13. 'c2c-switch')
  14. my_switch.set_mn( # Manufacturer info
  15. 'Switch Mn Example',
  16. 'Model X1')
  17. my_switch.set_context(
  18. 'Office',
  19. [],
  20. ['light'])
  21. declared_devices = [my_switch]
  22. return self.discovery_response(declared_devices, request_id)
  23. def state_refresh_handler(self, devices, request_id, access_token):
  24. # State Refresh Request information
  25. device_id = devices[0]['externalDeviceId']
  26. # SchemaDevice Instance
  27. # and state definition.
  28. my_device = SchemaDevice(device_id)
  29. my_device.set_state(
  30. 'st.switch',
  31. 'switch',
  32. 'on'
  33. )
  34. # Collection of devices, in this
  35. # case, just my_device instance.
  36. filtered_devices = [my_device]
  37. return self.state_refresh_response(filtered_devices, request_id)
  38. def command_handler(self, devices, request_id, access_token):
  39. # Command Request information
  40. device_id = devices[0]['externalDeviceId']
  41. command = devices[0]['commands'][0]
  42. # SchemaDevice instance applying
  43. # the updated state as commanded.
  44. my_device = SchemaDevice(device_id)
  45. my_device.set_state(
  46. 'st.switch',
  47. 'switch',
  48. command['command'] # 'on' or 'off'
  49. )
  50. # Updated device passed as a list argument.
  51. updated_device = [my_device]
  52. return self.command_response(updated_device, request_id)
  53. def interaction_result_handler(self, interaction_result: dict, origin: str):
  54. print(interaction_result, origin)
  55. pass
  56. # MyConnector instance
  57. my_connector = MyConnector()
  58. class WebhookServer(BaseHTTPRequestHandler):
  59. """
  60. This class will serve as endpoint to handle
  61. the POST Http Requests sent to the
  62. registered Target Url. Notice that this
  63. webhook instance won't differentiate endpoints.
  64. """
  65. def do_POST(self):
  66. # POST Http Request handler.
  67. content_length = int(self.headers['Content-Length'])
  68. req_body = self.rfile.read(content_length).decode('utf-8')
  69. # getting JSON body from request.
  70. json_data = json.loads(req_body)
  71. return self._set_response(json_data)
  72. def _set_response(self, data):
  73. # interaction_handler is a
  74. # SchemaConnector built-in method
  75. # that takes the JSON body as
  76. # argument.
  77. connector_handler = my_connector.interaction_handler(data)
  78. # JSON Interaction types responses
  79. res_data = json.dumps(connector_handler).encode('utf-8')
  80. self._set_headers()
  81. self.wfile.write(res_data)
  82. def _set_headers(self):
  83. # Declare application/json
  84. # headers to parse JSON string
  85. # response.
  86. self.send_response(200)
  87. self.send_header('Content-type', 'application/json')
  88. self.end_headers()
  89. if __name__ == '__main__':
  90. server_address = ('', 8000)
  91. http = HTTPServer(server_address, WebhookServer)
  92. http.serve_forever()

Notice that the SchemaConnector.grant_callback_access built-in resource hasn’t been implemented. In this case, when the Schema Connector instance gets integrated for the first time at the SmartThings ecosystem, the NotImplementedError exception will be raised as following:

  1. ...
  2. NotImplementedError: [grant_callback_access] - Interaction resource handler not implemented

Developer Note.

Before pushing any updates into the SmartThings Schema Connector Python SDK, please install pytest and execute the follwing command to run the full test suite.

  1. python3 -m pytest -p no:cacheprovider

To learn more about SmartThings Schema Connector integrations, visit the SmartThings Community Forums.