generated from ludeeus/integration_blueprint
/
websocket.py
136 lines (112 loc) · 3.96 KB
/
websocket.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
"""Websocket API for Node-RED."""
import voluptuous as vol
import logging
import json
import homeassistant.helpers.config_validation as cv
from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.components.websocket_api import (
async_register_command,
websocket_command,
async_response,
require_admin,
result_message,
event_message,
)
from homeassistant.const import CONF_STATE
from homeassistant.helpers.typing import HomeAssistantType
from .const import (
DOMAIN,
VERSION,
NODERED_DISCOVERY,
NODERED_ENTITY,
CONF_SERVER_ID,
CONF_NODE_ID,
)
_LOGGER = logging.getLogger(__name__)
def register_websocket_handlers(hass: HomeAssistantType):
"""Register the websocket handlers."""
async_register_command(hass, websocket_version)
async_register_command(hass, websocket_webhook)
async_register_command(hass, websocket_discovery)
async_register_command(hass, websocket_entity)
@require_admin
@websocket_command(
{
vol.Required("type"): "nodered/discovery",
vol.Required("component"): cv.string,
vol.Required(CONF_SERVER_ID): cv.string,
vol.Required(CONF_NODE_ID): cv.string,
vol.Optional("config", default={}): dict,
vol.Optional(CONF_STATE): vol.Any(bool, str, int, float),
vol.Optional("attributes"): dict,
vol.Optional("remove"): bool,
}
)
def websocket_discovery(hass, connection, msg):
"""Sensor command."""
msg["connection"] = connection
async_dispatcher_send(hass, NODERED_DISCOVERY.format(msg["component"]), msg)
connection.send_message(result_message(msg["id"], {"success": True}))
@require_admin
@websocket_command(
{
vol.Required("type"): "nodered/entity",
vol.Required(CONF_SERVER_ID): cv.string,
vol.Required(CONF_NODE_ID): cv.string,
vol.Required(CONF_STATE): vol.Any(bool, str, int, float),
vol.Optional("attributes", default={}): dict,
}
)
def websocket_entity(hass, connection, msg):
"""Sensor command."""
async_dispatcher_send(
hass, NODERED_ENTITY.format(msg[CONF_SERVER_ID], msg[CONF_NODE_ID]), msg
)
connection.send_message(result_message(msg["id"], {"success": True}))
@require_admin
@websocket_command({vol.Required("type"): "nodered/version"})
def websocket_version(hass, connection, msg):
"""Version command."""
connection.send_message(result_message(msg["id"], VERSION))
@require_admin
@async_response
@websocket_command(
{
vol.Required("type"): "nodered/webhook",
vol.Required("webhook_id"): cv.string,
vol.Required("name"): cv.string,
vol.Required(CONF_SERVER_ID): cv.string,
}
)
async def websocket_webhook(hass, connection, msg):
"""Create webhook command."""
webhook_id = msg["webhook_id"]
@callback
async def handle_webhook(hass, id, request):
"""Handle webhook callback."""
body = await request.text()
try:
data = json.loads(body) if body else {}
except ValueError:
data = body
_LOGGER.debug(f"Webhook recieved {id[:15]}..: {data}")
connection.send_message(event_message(msg["id"], {"data": data}))
def remove_webhook() -> None:
"""Remove webhook command."""
try:
hass.components.webhook.async_unregister(webhook_id)
except ValueError:
pass
_LOGGER.info(f"Webhook removed: {webhook_id[:15]}..")
connection.send_message(result_message(msg["id"], {"success": True}))
try:
hass.components.webhook.async_register(
DOMAIN, msg["name"], webhook_id, handle_webhook
)
except ValueError:
connection.send_message(result_message(msg["id"], {"success": False}))
return
_LOGGER.info(f"Webhook created: {webhook_id[:15]}..")
connection.subscriptions[msg["id"]] = remove_webhook
connection.send_message(result_message(msg["id"], {"success": True}))