switchbot.py
Go to the documentation of this file.
1 from __future__ import print_function
2 
3 import json
4 import os.path
5 import requests
6 
7 
8 class SwitchBotAPIClient(object):
9  """
10  For Using SwitchBot via official API.
11  Please see https://github.com/OpenWonderLabs/SwitchBotAPI for details.
12  """
13  def __init__(self, token):
14  self._host_domain = "https://api.switch-bot.com/v1.0/"
15  self.token = token
16  self.device_list = None
18  self.scene_list = None
19  self.device_name_id = {}
20  self.scene_name_id = {}
21  self.update_device_list()
22  self.update_scene_list()
23 
24 
25  def request(self, method='GET', devices_or_scenes='devices', service_id='', service='', json_body=None):
26  """
27  Execute HTTP request
28  """
29  if devices_or_scenes not in ['devices', 'scenes']:
30  raise ValueError('Please set devices_or_scenes variable devices or scenes')
31 
32  url = os.path.join(self._host_domain, devices_or_scenes, service_id, service)
33 
34  if method == 'GET':
35  response = requests.get(
36  url,
37  headers={'Authorization': self.token}
38  )
39  elif method == 'POST':
40  response = requests.post(
41  url,
42  json_body,
43  headers={
44  'Content-Type': 'application/json; charset=utf8',
45  'Authorization': self.token
46  })
47  else:
48  raise ValueError('Got unexpected http request method. Please use GET or POST.')
49 
50  response_json = response.json()
51 
52  # Catch the HTTP 4XX, 5XX error
53  try:
54  response.raise_for_status()
55  except requests.exceptions.RequestException as e:
56  if response.status_code == 422:
57  raise InvalidRequestError()
58  elif response.status_code == 429:
59  raise ExceededRequestError()
60  else:
61  raise e
62  else:
63  if response_json['statusCode'] == 100:
64  return response_json
65  elif response_json['statusCode'] == 151:
66  raise DeviceTypeError()
67  elif response_json['statusCode'] == 152:
68  raise DeviceNotFoundError()
69  elif response_json['statusCode'] == 160:
71  elif response_json['statusCode'] == 161:
72  raise DeviceOfflineError()
73  elif response_json['statusCode'] == 171:
74  raise HubDeviceOfflineError()
75  elif response_json['statusCode'] == 190:
76  raise DeviceInternalError()
77  else:
78  raise ValueError("Got unknown status code : " + str(response_json['statusCode']))
79 
80 
81  def update_device_list(self):
82  """
83  Update the information of deviceIds, deviceNames, deviceBots.
84  """
85  res = self.request()
86  self.device_list = res['body']['deviceList']
87  self.infrared_remote_list = res['body']['infraredRemoteList']
88  for device in self.device_list:
89  self.device_name_id[device['deviceName']] = device['deviceId']
90  for infrated_remote in self.infrared_remote_list:
91  self.device_name_id[device['deviceName']] = device['deviceId']
92 
93  return self.device_list, self.infrared_remote_list
94 
95 
96  def update_scene_list(self):
97  """
98  Update the information of sceneIDs, sceneNames.
99  """
100  self.scene_list = self.request(devices_or_scenes='scenes')['body']
101  for scene in self.scene_list:
102  self.scene_name_id[scene['sceneName']] = device['sceneId']
103 
104  return self.scene_list
105 
106 
107  def device_status(self, device_id=None, device_name=None):
108  """
109  Get the device status.
110  """
111  if device_id:
112  pass
113  elif device_name:
114  try:
115  device_id = self.device_name_id[device_name]
116  except KeyError as e:
117  raise KeyError("Device name:{} is not registered at switchbot server. Please check the setting.".format(device_name))
118  else:
119  raise ValueError("Please set device_id or device_name.")
120 
121  return self.request(service_id=device_id, service='status')['body']
122 
123 
124  def control_device(self, command, parameter='default', command_type='command', device_id=None, device_name=None):
125  """
126  Send Command to the device. Please see https://github.com/OpenWonderLabs/SwitchBotAPI#send-device-control-commands for command options.
127  """
128  json_body = json.dumps({
129  "command": command,
130  "parameter": parameter,
131  "commandType": command_type
132  })
133  if device_id:
134  pass
135  elif device_name:
136  try:
137  device_id = self.device_name_id[device_name]
138  except KeyError as e:
139  raise KeyError("Device name:{} is not registered at switchbot server. Please check the setting.".format(device_name))
140  else:
141  raise ValueError("Please set device_id or device_name.")
142 
143  return self.request(method='POST', service_id=device_id, service='commands', json_body=json_body)['message']
144 
145 
146  def execute_scene(self, scene_id=None, scene_name=None):
147  """
148  Execute your registered scene.
149  """
150  if scene_id:
151  pass
152  elif scene_name:
153  try:
154  scene_id = self.scene_name_id[scene_name]
155  except KeyError as e:
156  raise KeyError("Scene name:{} is not registered at switchbot server. Please check the setting.".format(scene_name))
157  else:
158  raise ValueError("Please set scene_id or scene_name.")
159 
160  return self.request(method='POST', devices_or_scenes='scenes', service_id=scene_id, service='execute')['message']
161 
162 
163 # Error classes
164 class DeviceError(Exception):
165  def __init__(self):
166  pass
167 
168 class DeviceTypeError(DeviceError):
169  def __str__(self):
170  return("Device type is not correct")
171 
173  def __str__(self):
174  return("The device is not found")
175 
177  def __str__(self):
178  return("Your command is not supported")
179 
181  def __str__(self):
182  return("The device is offline now")
183 
185  def __str__(self):
186  return("The hub device is offline now")
187 
189  def __str__(self):
190  return("Device internal error due to device states not synchronized with server. Or command format is invalid")
191 
192 
193 class SwitchBotAPIError(Exception):
194  def __init__(self):
195  pass
196 
197 class InvalidRequestError(SwitchBotAPIError):
198  def __str__(self):
199  return("The client has issued an invalid request. This is commonly used to specify validation errors in a request payload.")
200 
202  def __str__(self):
203  return("The client has exceeded the number of requests allowed for a given time window.")
def control_device(self, command, parameter='default', command_type='command', device_id=None, device_name=None)
Definition: switchbot.py:124
def device_status(self, device_id=None, device_name=None)
Definition: switchbot.py:107
def execute_scene(self, scene_id=None, scene_name=None)
Definition: switchbot.py:146
def request(self, method='GET', devices_or_scenes='devices', service_id='', service='', json_body=None)
Definition: switchbot.py:25


switchbot_ros
Author(s): Yoshiki Obinata
autogenerated on Sat Jun 24 2023 02:40:43