add option to add entities, switch + simple light support

This commit is contained in:
Nitwel 2023-10-31 22:15:33 +01:00
parent d24f3a7c7e
commit 555d501e18
18 changed files with 214 additions and 56 deletions

3
assets/design.afdesign Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a3a3204f122024fe25657532ccbe1c0d07eba475f37ebb686046ba71d358ad58
size 2087560

3
assets/logo.png Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b5d79d4a0c78bcce53fb01fa0353ec971eca5f6f8f3fb1fa7322f18f87a4781b
size 1122652

3
assets/logo.png.import Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1daf27643292c3a222f2a9e60dfe38db5e62963cbfa2dd313588aa98f4e053b4
size 753

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:06c7745de9d5236d8096979e16708530a3c61112b604a7603033ea8bc9097791
size 258636

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b936cb0718d6b36ba9070d10fe2a16b2dbff0a4f9649e80205e3218fdb4b9df9
size 1007

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3fa30c33f89997925bc7164245d51209879a912597a72b227b861f9a9841acec
size 249715

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:71e68850377c2368a7433084c550cc7c5fa5110184cf59fc6d7a8f77f5f4af89
size 1017

View File

@ -1,18 +1,10 @@
[gd_scene load_steps=13 format=3 uid="uid://eecv28y6jxk4"] [gd_scene load_steps=10 format=3 uid="uid://eecv28y6jxk4"]
[ext_resource type="Script" path="res://src/devices/light.gd" id="1_5mqma"]
[ext_resource type="PackedScene" uid="uid://clc5dre31iskm" path="res://addons/godot-xr-tools/xr/start_xr.tscn" id="1_i4c04"] [ext_resource type="PackedScene" uid="uid://clc5dre31iskm" path="res://addons/godot-xr-tools/xr/start_xr.tscn" id="1_i4c04"]
[ext_resource type="Script" path="res://src/raycast.gd" id="1_tsqxc"] [ext_resource type="Script" path="res://src/raycast.gd" id="1_tsqxc"]
[ext_resource type="Script" path="res://src/model.gd" id="2_7f1x4"] [ext_resource type="Script" path="res://src/model.gd" id="2_7f1x4"]
[ext_resource type="PackedScene" uid="uid://c3kdssrmv84kv" path="res://scenes/menu.tscn" id="3_1tbp3"] [ext_resource type="PackedScene" uid="uid://c3kdssrmv84kv" path="res://scenes/menu.tscn" id="3_1tbp3"]
[sub_resource type="SphereShape3D" id="SphereShape3D_2igmd"]
radius = 0.1
[sub_resource type="SphereMesh" id="SphereMesh_eme7e"]
radius = 0.1
height = 0.2
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_m58yb"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_m58yb"]
ao_enabled = true ao_enabled = true
@ -41,16 +33,6 @@ ambient_light_sky_contribution = 0.72
[node name="Main" type="Node3D"] [node name="Main" type="Node3D"]
[node name="Light" type="StaticBody3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.45064, 0, 0.20152)
script = ExtResource("1_5mqma")
[node name="CollisionShape3D" type="CollisionShape3D" parent="Light"]
shape = SubResource("SphereShape3D_2igmd")
[node name="MeshInstance3D" type="MeshInstance3D" parent="Light"]
mesh = SubResource("SphereMesh_eme7e")
[node name="XROrigin3D" type="XROrigin3D" parent="."] [node name="XROrigin3D" type="XROrigin3D" parent="."]
[node name="XRCamera3D" type="XRCamera3D" parent="XROrigin3D"] [node name="XRCamera3D" type="XRCamera3D" parent="XROrigin3D"]
@ -64,9 +46,8 @@ pose = &"aim"
[node name="MeshInstance3D" type="MeshInstance3D" parent="XROrigin3D/XRControllerLeft"] [node name="MeshInstance3D" type="MeshInstance3D" parent="XROrigin3D/XRControllerLeft"]
mesh = SubResource("BoxMesh_ir3co") mesh = SubResource("BoxMesh_ir3co")
[node name="Model" type="Node3D" parent="XROrigin3D/XRControllerLeft" node_paths=PackedStringArray("light")] [node name="Model" type="Node3D" parent="XROrigin3D/XRControllerLeft"]
script = ExtResource("2_7f1x4") script = ExtResource("2_7f1x4")
light = NodePath("../../../Light")
[node name="Menu" parent="XROrigin3D/XRControllerLeft" instance=ExtResource("3_1tbp3")] [node name="Menu" parent="XROrigin3D/XRControllerLeft" instance=ExtResource("3_1tbp3")]
transform = Transform3D(-4.37114e-08, 0, -1, -0.707107, 0.707107, 3.09086e-08, 0.707107, 0.707107, -3.09086e-08, 0.194945, 0, -0.0534939) transform = Transform3D(-4.37114e-08, 0, -1, -0.707107, 0.707107, 3.09086e-08, 0.707107, 0.707107, -3.09086e-08, 0.194945, 0, -0.0534939)

View File

@ -0,0 +1,33 @@
[gd_scene load_steps=6 format=3 uid="uid://cw86rc42dv2d8"]
[ext_resource type="Script" path="res://src/entities/light.gd" id="1_ykxy3"]
[ext_resource type="Texture2D" uid="uid://b72vsbcvqqxg7" path="res://assets/materials/swich_on.png" id="2_6gn2e"]
[ext_resource type="Texture2D" uid="uid://cvc0o6dsktnvl" path="res://assets/materials/switch_off.png" id="3_qlm62"]
[sub_resource type="SphereShape3D" id="SphereShape3D_ukj14"]
radius = 0.1
[sub_resource type="SpriteFrames" id="SpriteFrames_ldpuo"]
animations = [{
"frames": [{
"duration": 1.0,
"texture": ExtResource("2_6gn2e")
}, {
"duration": 1.0,
"texture": ExtResource("3_qlm62")
}],
"loop": true,
"name": &"default",
"speed": 5.0
}]
[node name="Light" type="StaticBody3D"]
script = ExtResource("1_ykxy3")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("SphereShape3D_ukj14")
[node name="Icon" type="AnimatedSprite3D" parent="."]
pixel_size = 0.0005
billboard = 1
sprite_frames = SubResource("SpriteFrames_ldpuo")

View File

@ -0,0 +1,33 @@
[gd_scene load_steps=6 format=3 uid="uid://cscl5k7lhopj5"]
[ext_resource type="Script" path="res://src/entities/switch.gd" id="1_8ffhi"]
[ext_resource type="Texture2D" uid="uid://b72vsbcvqqxg7" path="res://assets/materials/swich_on.png" id="1_w68gw"]
[ext_resource type="Texture2D" uid="uid://cvc0o6dsktnvl" path="res://assets/materials/switch_off.png" id="2_86ba1"]
[sub_resource type="SphereShape3D" id="SphereShape3D_ukj14"]
radius = 0.1
[sub_resource type="SpriteFrames" id="SpriteFrames_ldpuo"]
animations = [{
"frames": [{
"duration": 1.0,
"texture": ExtResource("1_w68gw")
}, {
"duration": 1.0,
"texture": ExtResource("2_86ba1")
}],
"loop": true,
"name": &"default",
"speed": 5.0
}]
[node name="Switch" type="StaticBody3D"]
script = ExtResource("1_8ffhi")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("SphereShape3D_ukj14")
[node name="Icon" type="AnimatedSprite3D" parent="."]
pixel_size = 0.0005
billboard = 1
sprite_frames = SubResource("SpriteFrames_ldpuo")

View File

@ -1,27 +0,0 @@
extends StaticBody3D
@onready var http_request = HTTPRequest.new()
@export var id = "switch.plug_printer_2"
@export var token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIzZjQ0ZGM2N2Y3YzY0MDc1OGZlMWI2ZjJlNmIxZjRkNSIsImlhdCI6MTY5ODAxMDcyOCwiZXhwIjoyMDEzMzcwNzI4fQ.K6ydLUC-4Q7BNIRCU1nWlI2s6sg9UCiOu-Lpedw2zJc"
# Called when the node enters the scene tree for the first time.
func _ready():
add_child(http_request)
http_request.request_completed.connect(self._on_request_completed)
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
pass
func _on_toggle():
print("Toggling " + id)
var headers = PackedStringArray(["Authorization: Bearer " + token, "Content-Type: application/json"])
var error = http_request.request("http://192.168.33.33:8123/api/services/switch/toggle", headers, HTTPClient.METHOD_POST, "{\"entity_id\": \"" + id + "\"}")
if error != OK:
push_error("An error occurred in the HTTP request.")
func _on_request_completed():
pass

23
src/entities/light.gd Normal file
View File

@ -0,0 +1,23 @@
extends StaticBody3D
@export var entity_id = "switch.plug_printer_2"
@onready var sprite: AnimatedSprite3D = $Icon
# Called when the node enters the scene tree for the first time.
func _ready():
var stateInfo = await HomeAdapters.adapter.get_state(entity_id)
if stateInfo["state"] == "on":
sprite.set_frame(0)
else:
sprite.set_frame(1)
func _on_toggle():
HomeAdapters.adapter.set_state(entity_id, "off" if sprite.get_frame() == 0 else "on")
if sprite.get_frame() == 0:
sprite.set_frame(1)
else:
sprite.set_frame(0)
func _on_request_completed():
pass

23
src/entities/switch.gd Normal file
View File

@ -0,0 +1,23 @@
extends StaticBody3D
@export var entity_id = "switch.plug_printer_2"
@onready var sprite: AnimatedSprite3D = $Icon
# Called when the node enters the scene tree for the first time.
func _ready():
var stateInfo = await HomeAdapters.adapter.get_state(entity_id)
if stateInfo["state"] == "on":
sprite.set_frame(0)
else:
sprite.set_frame(1)
func _on_toggle():
HomeAdapters.adapter.set_state(entity_id, "off" if sprite.get_frame() == 0 else "on")
if sprite.get_frame() == 0:
sprite.set_frame(1)
else:
sprite.set_frame(0)
func _on_request_completed():
pass

View File

@ -11,7 +11,9 @@ const adapters = {
} }
const methods = [ const methods = [
"load_devices" "load_devices",
"get_state",
"set_state"
] ]
var adapter: Node var adapter: Node
@ -24,3 +26,9 @@ func _init(type: ADAPTER_TYPES):
func load_devices(): func load_devices():
return await adapter.load_devices() return await adapter.load_devices()
func get_state(entity: String):
return await adapter.get_state(entity)
func set_state(entity: String, state: String, attributes: Dictionary = {}):
return await adapter.set_state(entity, state, attributes)

View File

@ -21,3 +21,43 @@ func load_devices():
print(json) print(json)
return json return json
func get_state(entity: String):
var type = entity.split('.')[0]
Request.request("%s/api/states/%s" % [url, entity], headers, HTTPClient.METHOD_GET)
var response = await Request.request_completed
var data_string = response[3].get_string_from_utf8().replace("'", "\"")
var json = JSON.parse_string(data_string)
print(json)
return json
func set_state(entity: String, state: String, attributes: Dictionary = {}):
var type = entity.split('.')[0]
var response
if type == 'switch':
if state == 'on':
Request.request("%s/api/services/switch/turn_on" % [url], headers, HTTPClient.METHOD_POST, "{\"entity_id\": \"%s\"}" % [entity])
response = await Request.request_completed
elif state == 'off':
Request.request("%s/api/services/switch/turn_off" % [url], headers, HTTPClient.METHOD_POST, "{\"entity_id\": \"%s\"}" % [entity])
response = await Request.request_completed
elif type == 'light':
if state == 'on':
Request.request("%s/api/services/light/turn_on" % [url], headers, HTTPClient.METHOD_POST, "{\"entity_id\": \"%s\"}" % [entity])
response = await Request.request_completed
elif state == 'off':
Request.request("%s/api/services/light/turn_off" % [url], headers, HTTPClient.METHOD_POST, "{\"entity_id\": \"%s\"}" % [entity])
response = await Request.request_completed
var data_string = response[3].get_string_from_utf8().replace("'", "\"")
var json = JSON.parse_string(data_string)
print(json)
return json

View File

@ -2,6 +2,8 @@ extends Node3D
const Device = preload("res://scenes/device.tscn") const Device = preload("res://scenes/device.tscn")
const Entity = preload("res://scenes/entity.tscn") const Entity = preload("res://scenes/entity.tscn")
const Switch = preload("res://scenes/entities/switch.tscn")
const Light = preload("res://scenes/entities/light.tscn")
@onready var devices_node = $Devices @onready var devices_node = $Devices
var devices var devices
@ -22,6 +24,7 @@ func render_devices():
var device_instance = Device.instantiate() var device_instance = Device.instantiate()
device_instance.set_position(Vector3(y * 0.08, 0, -x * 0.08)) device_instance.set_position(Vector3(y * 0.08, 0, -x * 0.08))
device_instance.click.connect(_on_device_click) device_instance.click.connect(_on_device_click)
device_instance.id = device.keys()[0]
devices_node.add_child(device_instance) devices_node.add_child(device_instance)
@ -39,7 +42,7 @@ func render_entities():
var info var info
for device in devices: for device in devices:
if device.values()[0].name == selected_device: if device.keys()[0] == selected_device:
info = device.values()[0] info = device.values()[0]
break break
@ -62,8 +65,8 @@ func render_entities():
x = 0 x = 0
y += 1 y += 1
func _on_device_click(device_name): func _on_device_click(device_id):
selected_device = device_name selected_device = device_id
print(selected_device) print(selected_device)
clear_menu() clear_menu()
render_entities() render_entities()
@ -74,6 +77,23 @@ func _on_entity_click(entity_name):
clear_menu() clear_menu()
render_devices() render_devices()
var type = entity_name.split(".")[0]
print(type)
if type == "switch":
var switch = Switch.instantiate()
switch.entity_id = entity_name
switch.set_position(global_position)
get_node("/root").add_child(switch)
if type == "light":
var light = Light.instantiate()
light.entity_id = entity_name
light.set_position(global_position)
get_node("/root").add_child(light)
func clear_menu(): func clear_menu():
for child in devices_node.get_children(): for child in devices_node.get_children():
devices_node.remove_child(child) devices_node.remove_child(child)

View File

@ -1,11 +1,12 @@
extends StaticBody3D extends StaticBody3D
@onready var label: Label3D = $Label @onready var label: Label3D = $Label
@export var id: String = "0"
signal click(name: String) signal click(id: String)
func _on_toggle(): func _on_toggle():
click.emit(label.text) click.emit(id)
func set_device_name(text): func set_device_name(text):
assert(label != null, "Device has to be added to the scene tree") assert(label != null, "Device has to be added to the scene tree")

View File

@ -1,12 +1,14 @@
extends StaticBody3D extends StaticBody3D
@onready var label: Label3D = $Label @onready var label: Label3D = $Label
@export var text = "Default"
signal click(name: String) signal click(name: String)
func _on_toggle(): func _on_toggle():
click.emit(label.text) click.emit(text)
func set_entity_name(text): func set_entity_name(text):
assert(label != null, "Entity has to be added to the scene tree") assert(label != null, "Entity has to be added to the scene tree")
label.text = text label.text = text.replace(".", "\n")
self.text = text