From eb327121b8ca5de9e023c5c75a87055897a23562 Mon Sep 17 00:00:00 2001 From: Nitwel Date: Fri, 24 Nov 2023 01:36:31 +0100 Subject: [PATCH] rework to HomeApi and fix device loading --- README.md | 6 +- assets/icons/wifi_white_24dp.svg | 3 + assets/icons/wifi_white_24dp.svg.import | 39 ++++++++ content/entities/light/light.gd | 8 +- content/entities/sensor/sensor.gd | 4 +- content/entities/switch/switch.gd | 6 +- content/system/raycast/raycast.gd | 4 +- content/ui/components/input/input.gd | 3 +- content/ui/components/input/input.tscn | 8 +- content/ui/menu/edit/edit_menu.gd | 25 ++++- content/ui/menu/settings/ball.tscn | 2 +- content/ui/menu/settings/settings_menu.gd | 13 +-- content/ui/menu/settings/settings_menu.tscn | 26 +++-- lib/globals/home_adapters.gd | 11 --- lib/globals/home_api.gd | 94 +++++++++++++++++++ lib/home_adapters/adapter.gd | 61 ------------ lib/{home_adapters => home_apis}/hass/hass.gd | 4 +- .../hass/templates/devices.j2 | 0 .../hass_ws/callback_map.gd | 0 .../hass_ws/hass.gd | 27 ++---- .../hass_ws/templates/devices.j2 | 0 project.godot | 2 +- 22 files changed, 212 insertions(+), 134 deletions(-) create mode 100644 assets/icons/wifi_white_24dp.svg create mode 100644 assets/icons/wifi_white_24dp.svg.import delete mode 100644 lib/globals/home_adapters.gd create mode 100644 lib/globals/home_api.gd delete mode 100644 lib/home_adapters/adapter.gd rename lib/{home_adapters => home_apis}/hass/hass.gd (98%) rename lib/{home_adapters => home_apis}/hass/templates/devices.j2 (100%) rename lib/{home_adapters => home_apis}/hass_ws/callback_map.gd (100%) rename lib/{home_adapters => home_apis}/hass_ws/hass.gd (96%) rename lib/{home_adapters => home_apis}/hass_ws/templates/devices.j2 (100%) diff --git a/README.md b/README.md index b66e0f6..455dde4 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ In order to contribute to this project, you need the following to be setup befor ## Fundamentals -Communication with the Smart Home Environment is done using the `HomeAdapters` global. Each environment is made up of devices and entities. +Communication with the Smart Home Environment is done using the `HomeApi` global. Each environment is made up of devices and entities. A device is a collection of different entities and entities can represent many different things in a smart home. For example, the entity of name `lights.smart_lamp_1` would control the kitchen lamps while `state.smart_lamp_1_temp` would show the current temperature of the lamp. @@ -55,9 +55,9 @@ For example, the entity of name `lights.smart_lamp_1` would control the kitchen └── home_adapters (Code allowing control smart home entities) ``` -### Home Adapters +### Home Api -The `HomeAdapters` global allows to communicate with different backends and offers a set of fundamental functions allowing communication with the Smart Home. +The `HomeApi` global allows to communicate with different backends and offers a set of fundamental functions allowing communication with the Smart Home. ```python Device { diff --git a/assets/icons/wifi_white_24dp.svg b/assets/icons/wifi_white_24dp.svg new file mode 100644 index 0000000..0c6dad7 --- /dev/null +++ b/assets/icons/wifi_white_24dp.svg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:053d1e42a72e988fad4b2ef981eb72ec850f1f7da6963b257c8935e8392cb37b +size 324 diff --git a/assets/icons/wifi_white_24dp.svg.import b/assets/icons/wifi_white_24dp.svg.import new file mode 100644 index 0000000..60fc20e --- /dev/null +++ b/assets/icons/wifi_white_24dp.svg.import @@ -0,0 +1,39 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://co5fgm68t4j6o" +path.s3tc="res://.godot/imported/wifi_white_24dp.svg-9edf937c7c00e607b2e1a7211dd6ea49.s3tc.ctex" +path.etc2="res://.godot/imported/wifi_white_24dp.svg-9edf937c7c00e607b2e1a7211dd6ea49.etc2.ctex" +metadata={ +"imported_formats": ["s3tc_bptc", "etc2_astc"], +"vram_texture": true +} + +[deps] + +source_file="res://assets/icons/wifi_white_24dp.svg" +dest_files=["res://.godot/imported/wifi_white_24dp.svg-9edf937c7c00e607b2e1a7211dd6ea49.s3tc.ctex", "res://.godot/imported/wifi_white_24dp.svg-9edf937c7c00e607b2e1a7211dd6ea49.etc2.ctex"] + +[params] + +compress/mode=2 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 +svg/scale=8.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/content/entities/light/light.gd b/content/entities/light/light.gd index e3a768b..92f97ea 100644 --- a/content/entities/light/light.gd +++ b/content/entities/light/light.gd @@ -13,10 +13,10 @@ var brightness = 0 # 0-255 # Called when the node enters the scene tree for the first time. func _ready(): - var stateInfo = await HomeAdapters.adapter.get_state(entity_id) + var stateInfo = await HomeApi.get_state(entity_id) set_state(stateInfo["state"] == "on") - await HomeAdapters.adapter.watch_state(entity_id, func(new_state): + await HomeApi.watch_state(entity_id, func(new_state): if (new_state["state"] == "on") == state: return set_state(new_state["state"] == "on") @@ -44,7 +44,7 @@ func _on_click(event): if !state && brightness != null: attributes["brightness"] = int(brightness) - HomeAdapters.adapter.set_state(entity_id, "on" if !state else "off", attributes) + HomeApi.set_state(entity_id, "on" if !state else "off", attributes) set_state(!state, brightness) else: _on_clickable_on_click(event) @@ -71,5 +71,5 @@ func _on_clickable_on_click(event): slider_knob.position = new_pos - HomeAdapters.adapter.set_state(entity_id, "on" if state else "off", {"brightness": int(ratio * 255)}) + HomeApi.set_state(entity_id, "on" if state else "off", {"brightness": int(ratio * 255)}) set_state(state, ratio * 255) diff --git a/content/entities/sensor/sensor.gd b/content/entities/sensor/sensor.gd index 149d7bd..5af77dc 100644 --- a/content/entities/sensor/sensor.gd +++ b/content/entities/sensor/sensor.gd @@ -5,10 +5,10 @@ extends StaticBody3D # Called when the node enters the scene tree for the first time. func _ready(): - var stateInfo = await HomeAdapters.adapter.get_state(entity_id) + var stateInfo = await HomeApi.get_state(entity_id) set_text(stateInfo) - await HomeAdapters.adapter.watch_state(entity_id, func(new_state): + await HomeApi.watch_state(entity_id, func(new_state): set_text(new_state) ) diff --git a/content/entities/switch/switch.gd b/content/entities/switch/switch.gd index 3239121..c2df949 100644 --- a/content/entities/switch/switch.gd +++ b/content/entities/switch/switch.gd @@ -5,7 +5,7 @@ extends StaticBody3D # Called when the node enters the scene tree for the first time. func _ready(): - var stateInfo = await HomeAdapters.adapter.get_state(entity_id) + var stateInfo = await HomeApi.get_state(entity_id) if stateInfo == null: return @@ -14,7 +14,7 @@ func _ready(): else: sprite.set_frame(1) - await HomeAdapters.adapter.watch_state(entity_id, func(new_state): + await HomeApi.watch_state(entity_id, func(new_state): if new_state["state"] == "on": sprite.set_frame(0) else: @@ -23,7 +23,7 @@ func _ready(): func _on_click(event): - HomeAdapters.adapter.set_state(entity_id, "off" if sprite.get_frame() == 0 else "on") + HomeApi.set_state(entity_id, "off" if sprite.get_frame() == 0 else "on") if sprite.get_frame() == 0: sprite.set_frame(1) else: diff --git a/content/system/raycast/raycast.gd b/content/system/raycast/raycast.gd index 3b9d6ce..5c4cca9 100644 --- a/content/system/raycast/raycast.gd +++ b/content/system/raycast/raycast.gd @@ -84,11 +84,11 @@ func _on_button_released(button: String): last_collided = null moved = false -func _emit_event(type: String, target: Object): +func _emit_event(type: String, target): var event = EventRay.new() event.controller = controller event.target = target event.ray = self event.is_right_controller = is_right - EventSystem.emit(type, event) \ No newline at end of file + EventSystem.emit(type, event) diff --git a/content/ui/components/input/input.gd b/content/ui/components/input/input.gd index e5df071..5633288 100644 --- a/content/ui/components/input/input.gd +++ b/content/ui/components/input/input.gd @@ -19,7 +19,8 @@ var text_handler = preload("res://content/ui/components/input/text_handler.gd"). get: return text_handler.text set(value): - text_handler.set_text(value, EventSystem.is_focused(self) == false) + var focused = Engine.is_editor_hint() == false && EventSystem.is_focused(self) == false + text_handler.set_text(value, focused) if label != null: label.text = text_handler.get_display_text() diff --git a/content/ui/components/input/input.tscn b/content/ui/components/input/input.tscn index 633210b..f5a390e 100644 --- a/content/ui/components/input/input.tscn +++ b/content/ui/components/input/input.tscn @@ -5,11 +5,11 @@ [sub_resource type="BoxMesh" id="BoxMesh_kjbca"] resource_local_to_scene = true -size = Vector3(0.15, 0.006, 0.03) +size = Vector3(0.2, 0.006, 0.03) [sub_resource type="BoxShape3D" id="BoxShape3D_x4yp8"] resource_local_to_scene = true -size = Vector3(0.15, 0.006, 0.03) +size = Vector3(0.2, 0.006, 0.03) [sub_resource type="SystemFont" id="SystemFont_nbea0"] @@ -55,7 +55,7 @@ _data = { [node name="Input" type="StaticBody3D" groups=["ui_focus"]] script = ExtResource("1_uml3t") -text = "Hello World" +width = 0.2 [node name="Box" type="MeshInstance3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.003, 0) @@ -67,7 +67,7 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.003, 0) shape = SubResource("BoxShape3D_x4yp8") [node name="Label" type="Label3D" parent="."] -transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.073, 0.00618291, 0) +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, -0.098, 0.00618291, 0) pixel_size = 0.0004 text = "Hello World" font = SubResource("SystemFont_nbea0") diff --git a/content/ui/menu/edit/edit_menu.gd b/content/ui/menu/edit/edit_menu.gd index 04589eb..4804e7e 100644 --- a/content/ui/menu/edit/edit_menu.gd +++ b/content/ui/menu/edit/edit_menu.gd @@ -19,11 +19,6 @@ var pages = 0 var selected_device = null # Called when the node enters the scene tree for the first time. func _ready(): - HomeAdapters.adapter.adapter.on_connect.connect(func(): - devices = await HomeAdapters.adapter.get_devices() - render() - ) - next_page_button.get_node("Clickable").on_click.connect(func(_event): print("next page") next_page() @@ -33,6 +28,26 @@ func _ready(): previous_page() ) +func _enter_tree(): + if HomeApi.has_connected(): + load_devices() + else: + HomeApi.on_connect.connect(func(): + if is_inside_tree(): + load_devices() + ) + +func load_devices(): + if devices.size() == 0: + devices = await HomeApi.get_devices() + render() + + HomeApi.on_disconnect.connect(func(): + devices = [] + if is_inside_tree(): + render() + ) + func update_pages(): if selected_device == null: pages = ceil(float(devices.size()) / page_size) diff --git a/content/ui/menu/settings/ball.tscn b/content/ui/menu/settings/ball.tscn index 5158fa8..03a7b90 100644 --- a/content/ui/menu/settings/ball.tscn +++ b/content/ui/menu/settings/ball.tscn @@ -8,7 +8,7 @@ radius = 0.08 height = 0.16 [node name="Ball" type="RigidBody3D"] -angular_damp = 39.224 +angular_damp = 4.0 [node name="CollisionShape3D" type="CollisionShape3D" parent="."] shape = SubResource("SphereShape3D_orlq6") diff --git a/content/ui/menu/settings/settings_menu.gd b/content/ui/menu/settings/settings_menu.gd index 1eabd4d..1138dfd 100644 --- a/content/ui/menu/settings/settings_menu.gd +++ b/content/ui/menu/settings/settings_menu.gd @@ -25,22 +25,23 @@ func _ready(): input_token.text = config["token"] button_connect.on_button_down.connect(func(): - HomeAdapters.adapter.adapter.url = input_url.text + "/api/websocket" - HomeAdapters.adapter.adapter.token = input_token.text - HomeAdapters.adapter.adapter.retries = 5 - HomeAdapters.adapter.adapter.connect_ws() + var url = input_url.text + "/api/websocket" + var token = input_token.text + + HomeApi.start_adapter("hass_ws", url, token) ConfigData.save_config({ + "api_type": "hass_ws", "url": input_url.text, "token": input_token.text }) ) - HomeAdapters.adapter.adapter.on_connect.connect(func(): + HomeApi.on_connect.connect(func(): connection_status.text = "Connected" ) - HomeAdapters.adapter.adapter.on_disconnect.connect(func(): + HomeApi.on_disconnect.connect(func(): connection_status.text = "Disconnected" ) diff --git a/content/ui/menu/settings/settings_menu.tscn b/content/ui/menu/settings/settings_menu.tscn index 2587855..b4a7f00 100644 --- a/content/ui/menu/settings/settings_menu.tscn +++ b/content/ui/menu/settings/settings_menu.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=6 format=3 uid="uid://c6r4higceibif"] +[gd_scene load_steps=7 format=3 uid="uid://c6r4higceibif"] [ext_resource type="Script" path="res://content/ui/menu/settings/settings_menu.gd" id="1_0lte6"] [ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="1_faxng"] [ext_resource type="Script" path="res://content/functions/clickable.gd" id="3_qmg6q"] [ext_resource type="PackedScene" uid="uid://blrhy2uccrdn4" path="res://content/ui/components/input/input.tscn" id="4_q3x6k"] +[ext_resource type="Texture2D" uid="uid://co5fgm68t4j6o" path="res://assets/icons/wifi_white_24dp.svg" id="5_muw54"] [sub_resource type="BoxMesh" id="BoxMesh_e51x8"] size = Vector3(0.3, 0.01, 0.3) @@ -30,40 +31,45 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0458097, 0, 0.253575) script = ExtResource("3_qmg6q") [node name="ConnectionStatus" type="Label3D" parent="Content"] -transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.26, 0, 0.29) +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.250698, 0, 0.161303) pixel_size = 0.0003 text = "Disconnected" [node name="LabelURL" type="Label3D" parent="Content"] transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.01, 0, 0.03) pixel_size = 0.0005 -text = "URL" +text = "url: +" font_size = 36 horizontal_alignment = 0 [node name="InputURL" parent="Content" instance=ExtResource("4_q3x6k")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.18, 0, 0.03) -width = 0.2 -text = "" +text = "ws://192.168.33.33:8123" [node name="LabelToken" type="Label3D" parent="Content"] transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.01, 0, 0.07) pixel_size = 0.0005 -text = "TOKEN" +text = "token:" font_size = 36 horizontal_alignment = 0 [node name="InputToken" parent="Content" instance=ExtResource("4_q3x6k")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.18, 0, 0.07) -width = 0.2 -text = "" +text = "..." [node name="LabelConnect" type="Label3D" parent="Content"] -transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.15, 0, 0.12) +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.14, 0, 0.12) pixel_size = 0.0005 -text = "TOKEN" +text = "Connect" font_size = 36 horizontal_alignment = 0 [node name="Connect" parent="Content" instance=ExtResource("1_faxng")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.25, 0, 0.12) + +[node name="Sprite3D" type="Sprite3D" parent="Content"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.25, 0.012, 0.12) +pixel_size = 0.0002 +axis = 1 +texture = ExtResource("5_muw54") diff --git a/lib/globals/home_adapters.gd b/lib/globals/home_adapters.gd deleted file mode 100644 index 275327c..0000000 --- a/lib/globals/home_adapters.gd +++ /dev/null @@ -1,11 +0,0 @@ -extends Node - -const Adapter = preload("res://lib/home_adapters/adapter.gd") - -var adapter = Adapter.new(Adapter.ADAPTER_TYPES.HASS_WS) -# var adapter_http = Adapter.new(Adapter.ADAPTER_TYPES.HASS) - -func _ready(): - add_child(adapter) - # add_child(adapter_http) - diff --git a/lib/globals/home_api.gd b/lib/globals/home_api.gd new file mode 100644 index 0000000..245c052 --- /dev/null +++ b/lib/globals/home_api.gd @@ -0,0 +1,94 @@ +extends Node + +const Hass = preload("res://lib/home_apis/hass/hass.gd") +const HassWebSocket = preload("res://lib/home_apis/hass_ws/hass.gd") + + +const apis = { + "hass": Hass, + "hass_ws": HassWebSocket +} + +const methods = [ + "get_devices", + "get_device", + "get_state", + "set_state", + "watch_state" +] + +signal on_connect() +signal on_disconnect() +var api: Node + +func _ready(): + print("HomeApi ready") + + var config = ConfigData.load_config() + + if config.has("api_type") && config.has("url") && config.has("token"): + var type = config["api_type"] + var url = config["url"] + "/api/websocket" + var token = config["token"] + + start_adapter(type, url, token) + + +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(): + on_connect.emit() + ) + + api.on_disconnect.connect(func(): + on_disconnect.emit() + ) + + for method in methods: + assert(api.has_method(method), "%s Api does not implement method: %s" % [type, method]) + +func _on_connect(): + on_connect.emit() + +func _on_disconnect(): + on_disconnect.emit() + +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") + return await api.get_state(entity) + +## Updates the state of the entity and returns the resulting state +func set_state(entity: String, state: String, attributes: Dictionary = {}): + assert(has_connected(), "Not connected") + 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") + return api.watch_state(entity, callback) diff --git a/lib/home_adapters/adapter.gd b/lib/home_adapters/adapter.gd deleted file mode 100644 index 5942bda..0000000 --- a/lib/home_adapters/adapter.gd +++ /dev/null @@ -1,61 +0,0 @@ -extends Node - -const Hass = preload("res://lib/home_adapters/hass/hass.gd") -const HassWebSocket = preload("res://lib/home_adapters/hass_ws/hass.gd") - -enum ADAPTER_TYPES { - HASS, - HASS_WS -} - -const adapters = { - ADAPTER_TYPES.HASS: Hass, - ADAPTER_TYPES.HASS_WS: HassWebSocket -} - -const methods = [ - "get_devices", - "get_device", - "get_state", - "set_state", - "watch_state" -] - -var adapter: Node - -func _init(type: ADAPTER_TYPES): - - var url = "" - var token = "" - var config = ConfigData.load_config() - - if config.has("url"): - url = config["url"] + "/api/websocket" - if config.has("token"): - token = config["token"] - - adapter = adapters[type].new(url, token) - add_child(adapter) - - for method in methods: - assert(adapter.has_method(method), "Adapter does not implement method: " + method) - -## Get a list of all devices -func get_devices(): - return await adapter.get_devices() - -## Get a single device by id -func get_device(id: String): - return await adapter.get_device(id) - -## Returns the current state of an entity -func get_state(entity: String): - return await adapter.get_state(entity) - -## Updates the state of the entity and returns the resulting state -func set_state(entity: String, state: String, attributes: Dictionary = {}): - return await adapter.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): - return adapter.watch_state(entity, callback) diff --git a/lib/home_adapters/hass/hass.gd b/lib/home_apis/hass/hass.gd similarity index 98% rename from lib/home_adapters/hass/hass.gd rename to lib/home_apis/hass/hass.gd index 3924522..88e101c 100644 --- a/lib/home_adapters/hass/hass.gd +++ b/lib/home_apis/hass/hass.gd @@ -4,7 +4,7 @@ var url: String = "http://192.168.33.33:8123" var token: String = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIzZjQ0ZGM2N2Y3YzY0MDc1OGZlMWI2ZjJlNmIxZjRkNSIsImlhdCI6MTY5ODAxMDcyOCwiZXhwIjoyMDEzMzcwNzI4fQ.K6ydLUC-4Q7BNIRCU1nWlI2s6sg9UCiOu-Lpedw2zJc" var headers: PackedStringArray = PackedStringArray([]) -var devices_template = FileAccess.get_file_as_string("res://lib/home_adapters/hass/templates/devices.j2") +var devices_template = FileAccess.get_file_as_string("res://lib/home_apis/hass/templates/devices.j2") func _init(url := self.url, token := self.token): self.url = url @@ -32,8 +32,6 @@ func get_state(entity: String): return json - - func set_state(entity: String, state: String, attributes: Dictionary = {}): var type = entity.split('.')[0] var response diff --git a/lib/home_adapters/hass/templates/devices.j2 b/lib/home_apis/hass/templates/devices.j2 similarity index 100% rename from lib/home_adapters/hass/templates/devices.j2 rename to lib/home_apis/hass/templates/devices.j2 diff --git a/lib/home_adapters/hass_ws/callback_map.gd b/lib/home_apis/hass_ws/callback_map.gd similarity index 100% rename from lib/home_adapters/hass_ws/callback_map.gd rename to lib/home_apis/hass_ws/callback_map.gd diff --git a/lib/home_adapters/hass_ws/hass.gd b/lib/home_apis/hass_ws/hass.gd similarity index 96% rename from lib/home_adapters/hass_ws/hass.gd rename to lib/home_apis/hass_ws/hass.gd index 6406f13..b163183 100644 --- a/lib/home_adapters/hass_ws/hass.gd +++ b/lib/home_apis/hass_ws/hass.gd @@ -1,6 +1,10 @@ extends Node -var devices_template := FileAccess.get_file_as_string("res://lib/home_adapters/hass_ws/templates/devices.j2") +signal on_connect() +signal on_disconnect() +var connected := false + +var devices_template := FileAccess.get_file_as_string("res://lib/home_apis/hass_ws/templates/devices.j2") var socket := WebSocketPeer.new() # in seconds var request_timeout := 10.0 @@ -13,7 +17,7 @@ var token := "" var LOG_MESSAGES := false var authenticated := false -var loading := true + var id := 1 var entities: Dictionary = {} var retries := 5 @@ -21,9 +25,6 @@ var retries := 5 var entitiy_callbacks := CallbackMap.new() var packet_callbacks := CallbackMap.new() -signal on_connect() -signal on_disconnect() - func _init(url := self.url, token := self.token): self.url = url self.token = token @@ -114,7 +115,7 @@ func start_subscriptions(): "attributes": packet.event.a[entity]["a"] } entitiy_callbacks.call_key(entity, [entities[entity]]) - loading = false + connected = true on_connect.emit() if packet.event.has("c"): @@ -201,10 +202,10 @@ func decode_packet(packet: PackedByteArray): func encode_packet(packet: Dictionary): return JSON.stringify(packet) -func get_devices(): - if loading: - await on_connect +func has_connected(): + return connected +func get_devices(): var result = await send_request_packet({ "type": "render_template", "template": devices_template, @@ -218,18 +219,12 @@ func get_device(id: String): pass func get_state(entity: String): - if loading: - await on_connect - if entities.has(entity): return entities[entity] return null func watch_state(entity: String, callback: Callable): - if loading: - await on_connect - entitiy_callbacks.add(entity, callback) return func(): @@ -237,8 +232,6 @@ func watch_state(entity: String, callback: Callable): func set_state(entity: String, state: String, attributes: Dictionary = {}): - assert(!loading, "Still loading") - var domain = entity.split(".")[0] var service: String diff --git a/lib/home_adapters/hass_ws/templates/devices.j2 b/lib/home_apis/hass_ws/templates/devices.j2 similarity index 100% rename from lib/home_adapters/hass_ws/templates/devices.j2 rename to lib/home_apis/hass_ws/templates/devices.j2 diff --git a/project.godot b/project.godot index 03f59f8..69cb30a 100644 --- a/project.godot +++ b/project.godot @@ -20,7 +20,7 @@ config/icon="res://assets/logo.png" XRToolsUserSettings="*res://addons/godot-xr-tools/user_settings/user_settings.gd" ConfigData="*res://lib/globals/config_data.gd" Request="*res://lib/globals/request.gd" -HomeAdapters="*res://lib/globals/home_adapters.gd" +HomeApi="*res://lib/globals/home_api.gd" AudioPlayer="*res://lib/globals/audio_player.gd" EventSystem="*res://lib/globals/event_system.gd"