128 lines
3.3 KiB
GDScript3
128 lines
3.3 KiB
GDScript3
|
extends Node
|
||
|
|
||
|
var devices_template = FileAccess.get_file_as_string("res://src/home_adapters/hass/templates/devices.j2")
|
||
|
var socket = WebSocketPeer.new()
|
||
|
# in seconds
|
||
|
var request_timeout: float = 10
|
||
|
|
||
|
var url: String = "ws://192.168.33.33:8123/api/websocket"
|
||
|
var token: String = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIzZjQ0ZGM2N2Y3YzY0MDc1OGZlMWI2ZjJlNmIxZjRkNSIsImlhdCI6MTY5ODAxMDcyOCwiZXhwIjoyMDEzMzcwNzI4fQ.K6ydLUC-4Q7BNIRCU1nWlI2s6sg9UCiOu-Lpedw2zJc"
|
||
|
|
||
|
|
||
|
var authenticated: bool = false
|
||
|
var id = 1
|
||
|
|
||
|
signal packet_received(packet: Dictionary)
|
||
|
|
||
|
func _init(url := self.url, token := self.token):
|
||
|
self.url = url
|
||
|
self.token = token
|
||
|
|
||
|
devices_template = devices_template.replace("\n", " ").replace("\t", "").replace("\r", " ").replace("\"", "\\\"")
|
||
|
connect_ws()
|
||
|
|
||
|
func connect_ws():
|
||
|
print("Connecting to %s" % self.url)
|
||
|
socket.connect_to_url(self.url)
|
||
|
|
||
|
func _process(delta):
|
||
|
socket.poll()
|
||
|
|
||
|
var state = socket.get_ready_state()
|
||
|
if state == WebSocketPeer.STATE_OPEN:
|
||
|
while socket.get_available_packet_count():
|
||
|
handle_packet(socket.get_packet())
|
||
|
elif state == WebSocketPeer.STATE_CLOSING:
|
||
|
pass
|
||
|
elif state == WebSocketPeer.STATE_CLOSED:
|
||
|
var code = socket.get_close_code()
|
||
|
var reason = socket.get_close_reason()
|
||
|
print("WS connection closed with code: %s, reason: %s" % [code, reason])
|
||
|
authenticated = false
|
||
|
set_process(false)
|
||
|
|
||
|
func handle_packet(raw_packet: PackedByteArray):
|
||
|
var packet = decode_packet(raw_packet)
|
||
|
|
||
|
print("Received packet: %s" % packet)
|
||
|
|
||
|
if packet.type == "auth_required":
|
||
|
send_packet({
|
||
|
"type": "auth",
|
||
|
"access_token": self.token
|
||
|
})
|
||
|
|
||
|
elif packet.type == "auth_ok":
|
||
|
authenticated = true
|
||
|
elif packet.type == "auth_invalid":
|
||
|
authenticated = false
|
||
|
print("Authentication failed")
|
||
|
set_process(false)
|
||
|
else:
|
||
|
packet_received.emit(packet)
|
||
|
|
||
|
|
||
|
func send_request_packet(packet: Dictionary):
|
||
|
packet.id = id
|
||
|
id += 1
|
||
|
|
||
|
send_packet(packet)
|
||
|
|
||
|
var promise = Promise.new(func(resolve: Callable, reject: Callable):
|
||
|
var handle_packet = func(recieved_packet: Dictionary):
|
||
|
print("Received packet in handler: %s" % recieved_packet)
|
||
|
if packet.id == recieved_packet.id:
|
||
|
print("same id")
|
||
|
resolve.call(recieved_packet)
|
||
|
packet_received.disconnect(handle_packet)
|
||
|
|
||
|
packet_received.connect(handle_packet)
|
||
|
|
||
|
var timeout = Timer.new()
|
||
|
timeout.set_wait_time(request_timeout)
|
||
|
timeout.set_one_shot(true)
|
||
|
timeout.timeout.connect(func():
|
||
|
reject.call(Promise.Rejection.new("Request timed out"))
|
||
|
packet_received.disconnect(handle_packet)
|
||
|
)
|
||
|
add_child(timeout)
|
||
|
timeout.start()
|
||
|
)
|
||
|
|
||
|
return await promise.settled
|
||
|
|
||
|
|
||
|
func send_packet(packet: Dictionary):
|
||
|
print("Sending packet: %s" % encode_packet(packet))
|
||
|
socket.send_text(encode_packet(packet))
|
||
|
|
||
|
func decode_packet(packet: PackedByteArray):
|
||
|
return JSON.parse_string(packet.get_string_from_utf8())
|
||
|
|
||
|
func encode_packet(packet: Dictionary):
|
||
|
return JSON.stringify(packet)
|
||
|
|
||
|
func load_devices():
|
||
|
pass
|
||
|
|
||
|
func get_state(entity: String):
|
||
|
assert(authenticated, "Not authenticated")
|
||
|
|
||
|
var result = await send_request_packet({
|
||
|
"type": "get_states"
|
||
|
})
|
||
|
|
||
|
if result.status == Promise.Status.RESOLVED:
|
||
|
return result.payload
|
||
|
return null
|
||
|
|
||
|
|
||
|
func watch_state(entity: String, callback: Callable):
|
||
|
assert(authenticated, "Not authenticated")
|
||
|
|
||
|
|
||
|
func set_state(entity: String, state: String, attributes: Dictionary = {}):
|
||
|
assert(authenticated, "Not authenticated")
|
||
|
|
||
|
|