Skip to content

Commit

Permalink
also refactor websocket for re-use
Browse files Browse the repository at this point in the history
  • Loading branch information
Robin Battey committed Oct 13, 2022
1 parent 49babd4 commit a78759b
Showing 1 changed file with 43 additions and 31 deletions.
74 changes: 43 additions & 31 deletions appdaemon/plugins/hass/hassplugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def list_constraints(self):
return []

#
# Persistent Session to HASS instance
# Persistent HTTP Session to HASS instance
#
@property
def session(self):
Expand All @@ -122,6 +122,47 @@ def session(self):
)
return self._session

#
# Connect and return a new WebSocket to HASS instance
#
async def create_websocket(self):
# change to websocket protocol
url = self.ha_url
if url.startswith("https://"):
url = url.replace("https", "wss", 1)
elif url.startswith("http://"):
url = url.replace("http", "ws", 1)

# ssl options
sslopt = {}
if self.cert_verify is False:
sslopt = {"cert_reqs": ssl.CERT_NONE}
if self.cert_path:
sslopt["ca_certs"] = self.cert_path
ws = websocket.create_connection("{}/api/websocket".format(url), sslopt=sslopt)

# wait for successful connection
res = await utils.run_in_executor(self, ws.recv)
result = json.loads(res)
self.logger.info("Connected to Home Assistant %s", result["ha_version"])

# Check if auth required, if so send password
if result["type"] == "auth_required":
if self.token is not None:
auth = json.dumps({"type": "auth", "access_token": self.token})
elif self.ha_key is not None:
auth = json.dumps({"type": "auth", "api_password": self.ha_key})
else:
raise ValueError("HASS requires authentication and none provided in plugin config")

await utils.run_in_executor(self, ws.send, auth)
result = json.loads(ws.recv())
if result["type"] != "auth_ok":
self.logger.warning("Error in authentication")
raise ValueError("Error in authentication")

return ws

#
# Get initial state
#
Expand Down Expand Up @@ -282,37 +323,8 @@ async def get_updates(self): # noqa: C901
#
# Connect to websocket interface
#
url = self.ha_url
if url.startswith("https://"):
url = url.replace("https", "wss", 1)
elif url.startswith("http://"):
url = url.replace("http", "ws", 1)

sslopt = {}
if self.cert_verify is False:
sslopt = {"cert_reqs": ssl.CERT_NONE}
if self.cert_path:
sslopt["ca_certs"] = self.cert_path
self.ws = websocket.create_connection("{}/api/websocket".format(url), sslopt=sslopt)
res = await utils.run_in_executor(self, self.ws.recv)
result = json.loads(res)
self.logger.info("Connected to Home Assistant %s", result["ha_version"])
#
# Check if auth required, if so send password
#
if result["type"] == "auth_required":
if self.token is not None:
auth = json.dumps({"type": "auth", "access_token": self.token})
elif self.ha_key is not None:
auth = json.dumps({"type": "auth", "api_password": self.ha_key})
else:
raise ValueError("HASS requires authentication and none provided in plugin config")
self.ws = await self.create_websocket()

await utils.run_in_executor(self, self.ws.send, auth)
result = json.loads(self.ws.recv())
if result["type"] != "auth_ok":
self.logger.warning("Error in authentication")
raise ValueError("Error in authentication")
#
# Subscribe to event stream
#
Expand Down

0 comments on commit a78759b

Please sign in to comment.