2023-11-24 02:36:31 +02:00
|
|
|
extends Node
|
2024-03-17 01:14:31 +02:00
|
|
|
## Manages the connection to the home automation system and provides a unified interface to the different home automation systems.
|
2023-11-24 02:36:31 +02:00
|
|
|
|
2024-04-17 17:49:58 +03:00
|
|
|
const EntityGroups = preload ("res://lib/utils/entity_group.gd")
|
2024-03-12 15:51:09 +02:00
|
|
|
const HassWebSocket = preload ("res://lib/home_apis/hass_ws/hass.gd")
|
2024-03-17 18:05:45 +02:00
|
|
|
const VoiceAssistant = preload ("res://lib/home_apis/voice_handler.gd")
|
2023-11-24 02:36:31 +02:00
|
|
|
|
|
|
|
const apis = {
|
|
|
|
"hass_ws": HassWebSocket
|
|
|
|
}
|
|
|
|
|
2024-04-17 17:49:58 +03:00
|
|
|
var groups = EntityGroups.new()
|
|
|
|
|
2024-03-17 01:14:31 +02:00
|
|
|
## Emitted when the connection to the home automation system is established
|
2023-11-24 02:36:31 +02:00
|
|
|
signal on_connect()
|
2024-03-17 01:14:31 +02:00
|
|
|
|
|
|
|
## Emitted when the connection to the home automation system is lost
|
2023-11-24 02:36:31 +02:00
|
|
|
signal on_disconnect()
|
2024-03-17 01:14:31 +02:00
|
|
|
|
|
|
|
## The current home automation system adapter
|
2023-11-24 02:36:31 +02:00
|
|
|
var api: Node
|
2024-05-06 14:34:56 +03:00
|
|
|
var reconnect_timer := Timer.new()
|
2023-11-24 02:36:31 +02:00
|
|
|
|
|
|
|
func _ready():
|
2024-05-06 12:41:23 +03:00
|
|
|
start()
|
2023-11-24 02:36:31 +02:00
|
|
|
|
2024-05-06 14:34:56 +03:00
|
|
|
reconnect_timer.wait_time = 60
|
|
|
|
reconnect_timer.one_shot = false
|
|
|
|
reconnect_timer.autostart = true
|
|
|
|
|
|
|
|
add_child(reconnect_timer)
|
|
|
|
|
|
|
|
reconnect_timer.timeout.connect(func():
|
|
|
|
if has_connected() == false:
|
|
|
|
start()
|
|
|
|
)
|
|
|
|
|
2024-05-06 12:41:23 +03:00
|
|
|
## Starts the adapter with the settings from the settings file
|
|
|
|
func start():
|
2024-01-25 17:29:33 +02:00
|
|
|
var success = Store.settings.load_local()
|
2023-11-24 02:36:31 +02:00
|
|
|
|
2024-01-25 17:29:33 +02:00
|
|
|
if success:
|
2024-04-09 18:46:59 +03:00
|
|
|
start_adapter(Store.settings.state.type.to_lower(), Store.settings.state.url, Store.settings.state.token)
|
2023-11-24 02:36:31 +02:00
|
|
|
|
2024-03-17 01:14:31 +02:00
|
|
|
## Starts the adapter for the given type and url
|
2023-11-24 02:36:31 +02:00
|
|
|
func start_adapter(type: String, url: String, token: String):
|
|
|
|
print("Starting adapter: %s" % type)
|
|
|
|
if api != null:
|
|
|
|
api.on_connect.disconnect(_on_connect)
|
|
|
|
api.on_disconnect.disconnect(_on_disconnect)
|
|
|
|
remove_child(api)
|
|
|
|
api.queue_free()
|
|
|
|
api = null
|
|
|
|
|
|
|
|
api = apis[type].new(url, token)
|
|
|
|
add_child(api)
|
|
|
|
|
|
|
|
api.on_connect.connect(func():
|
2024-01-25 17:29:33 +02:00
|
|
|
Store.house.load_local()
|
2023-11-24 02:36:31 +02:00
|
|
|
on_connect.emit()
|
|
|
|
)
|
|
|
|
|
|
|
|
api.on_disconnect.connect(func():
|
|
|
|
on_disconnect.emit()
|
|
|
|
)
|
|
|
|
|
|
|
|
func _on_connect():
|
|
|
|
on_connect.emit()
|
|
|
|
|
|
|
|
func _on_disconnect():
|
|
|
|
on_disconnect.emit()
|
|
|
|
|
2024-03-17 01:14:31 +02:00
|
|
|
## Returns true if the adapter is connected to the home automation system
|
2023-11-24 02:36:31 +02:00
|
|
|
func has_connected():
|
|
|
|
if api == null:
|
|
|
|
return false
|
|
|
|
return api.has_connected()
|
|
|
|
|
|
|
|
## Get a list of all devices
|
|
|
|
func get_devices():
|
|
|
|
assert(has_connected(), "Not connected")
|
|
|
|
return await api.get_devices()
|
|
|
|
|
|
|
|
## Get a single device by id
|
|
|
|
func get_device(id: String):
|
|
|
|
assert(has_connected(), "Not connected")
|
|
|
|
return await api.get_device(id)
|
|
|
|
|
|
|
|
## Returns the current state of an entity
|
|
|
|
func get_state(entity: String):
|
|
|
|
assert(has_connected(), "Not connected")
|
2024-04-17 17:49:58 +03:00
|
|
|
|
|
|
|
var group = groups.get_group(entity)
|
|
|
|
|
|
|
|
if group != null:
|
|
|
|
return await api.get_state(group[0])
|
|
|
|
|
2023-11-24 02:36:31 +02:00
|
|
|
return await api.get_state(entity)
|
|
|
|
|
|
|
|
## Updates the state of the entity and returns the resulting state
|
2024-03-12 15:51:09 +02:00
|
|
|
func set_state(entity: String, state: Variant, attributes: Dictionary={}):
|
2023-11-24 02:36:31 +02:00
|
|
|
assert(has_connected(), "Not connected")
|
2024-04-17 17:49:58 +03:00
|
|
|
|
|
|
|
var group = groups.get_group(entity)
|
|
|
|
|
|
|
|
if group != null:
|
|
|
|
for group_entity in group:
|
|
|
|
api.set_state(group_entity, state, attributes)
|
|
|
|
|
|
|
|
return null
|
|
|
|
|
2023-11-24 02:36:31 +02:00
|
|
|
return await api.set_state(entity, state, attributes)
|
|
|
|
|
|
|
|
## Watches the state and each time it changes, calls the callback with the changed state, returns a function to stop watching the state
|
|
|
|
func watch_state(entity: String, callback: Callable):
|
|
|
|
assert(has_connected(), "Not connected")
|
2024-04-17 17:49:58 +03:00
|
|
|
|
|
|
|
var group = groups.get_group(entity)
|
|
|
|
|
|
|
|
if group != null:
|
|
|
|
api.watch_state(group[0], callback)
|
|
|
|
|
2023-11-24 02:36:31 +02:00
|
|
|
return api.watch_state(entity, callback)
|
2023-12-09 19:39:38 +02:00
|
|
|
|
2024-03-17 18:05:45 +02:00
|
|
|
## Returns true if the adapter has an integration in the home automation system
|
|
|
|
## allowing to send the room position of the headset.
|
|
|
|
func has_integration() -> bool:
|
|
|
|
if has_connected() == false||api.has_method("has_integration") == false:
|
|
|
|
return false
|
|
|
|
|
|
|
|
return api.has_integration()
|
|
|
|
|
|
|
|
## Updates the room position of the headset in the home automation system
|
|
|
|
func update_room(room: String) -> void:
|
|
|
|
if has_connected() == false||api.has_method("update_room") == false:
|
|
|
|
return
|
|
|
|
|
|
|
|
api.update_room(room)
|
|
|
|
|
|
|
|
## Returns the VoiceHandler if the adapter has a voice assistant
|
|
|
|
func get_voice_assistant() -> VoiceAssistant:
|
|
|
|
assert(has_connected(), "Not connected")
|
|
|
|
|
|
|
|
if api.has_method("get_voice_assistant") == false:
|
|
|
|
return null
|
|
|
|
|
2024-04-11 17:51:30 +03:00
|
|
|
return api.get_voice_assistant()
|
|
|
|
|
2024-05-27 18:22:20 +03:00
|
|
|
func get_history(entity_id, start, interval, end=null):
|
2024-04-11 17:51:30 +03:00
|
|
|
assert(has_connected(), "Not connected")
|
|
|
|
|
|
|
|
if api.has_method("get_history") == false:
|
|
|
|
return null
|
|
|
|
|
2024-04-17 17:49:58 +03:00
|
|
|
if groups.is_group(entity_id):
|
|
|
|
return null
|
|
|
|
|
2024-05-27 18:22:20 +03:00
|
|
|
return await api.get_history(entity_id, start, interval, end)
|