update entity system, allow batch editing and add entities to mini_view

This commit is contained in:
Nitwel 2024-04-17 16:49:58 +02:00
parent 039f99048a
commit 09c502eea3
34 changed files with 415 additions and 156 deletions

View File

@ -3,25 +3,27 @@
importer="texture" importer="texture"
type="CompressedTexture2D" type="CompressedTexture2D"
uid="uid://co2ishj2hx57p" uid="uid://co2ishj2hx57p"
path="res://.godot/imported/switch_off.png-c31f6b401a5d3d7cba3c9d0f2c8b28fe.ctex" path.s3tc="res://.godot/imported/switch_off.png-c31f6b401a5d3d7cba3c9d0f2c8b28fe.s3tc.ctex"
path.etc2="res://.godot/imported/switch_off.png-c31f6b401a5d3d7cba3c9d0f2c8b28fe.etc2.ctex"
metadata={ metadata={
"vram_texture": false "imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
} }
[deps] [deps]
source_file="res://assets/materials/switch_off.png" source_file="res://assets/materials/switch_off.png"
dest_files=["res://.godot/imported/switch_off.png-c31f6b401a5d3d7cba3c9d0f2c8b28fe.ctex"] dest_files=["res://.godot/imported/switch_off.png-c31f6b401a5d3d7cba3c9d0f2c8b28fe.s3tc.ctex", "res://.godot/imported/switch_off.png-c31f6b401a5d3d7cba3c9d0f2c8b28fe.etc2.ctex"]
[params] [params]
compress/mode=0 compress/mode=2
compress/high_quality=false compress/high_quality=false
compress/lossy_quality=0.7 compress/lossy_quality=0.7
compress/hdr_compression=1 compress/hdr_compression=1
compress/normal_map=0 compress/normal_map=0
compress/channel_pack=0 compress/channel_pack=0
mipmaps/generate=false mipmaps/generate=true
mipmaps/limit=-1 mipmaps/limit=-1
roughness/mode=0 roughness/mode=0
roughness/src_normal="" roughness/src_normal=""
@ -31,4 +33,4 @@ process/normal_map_invert_y=false
process/hdr_as_srgb=false process/hdr_as_srgb=false
process/hdr_clamp_exposure=false process/hdr_clamp_exposure=false
process/size_limit=0 process/size_limit=0
detect_3d/compress_to=1 detect_3d/compress_to=0

View File

@ -1,12 +1,14 @@
extends Entity extends Entity
const Entity = preload("../entity.gd") const Entity = preload ("../entity.gd")
@onready var button = $Button @onready var button = $Button
func _ready(): func _ready():
super() super()
icon.value = "radio_button_checked"
var stateInfo = await HomeApi.get_state(entity_id) var stateInfo = await HomeApi.get_state(entity_id)
if stateInfo == null: if stateInfo == null:

View File

@ -8,7 +8,7 @@
[sub_resource type="BoxShape3D" id="BoxShape3D_um5pa"] [sub_resource type="BoxShape3D" id="BoxShape3D_um5pa"]
size = Vector3(0.0700684, 0.011734, 0.0703125) size = Vector3(0.0700684, 0.011734, 0.0703125)
[node name="Button" type="StaticBody3D" groups=["entity"]] [node name="Button" type="StaticBody3D" ]
script = ExtResource("1_ja7lt") script = ExtResource("1_ja7lt")
[node name="Button" parent="." instance=ExtResource("1_r4tef")] [node name="Button" parent="." instance=ExtResource("1_r4tef")]

View File

@ -1,6 +1,6 @@
extends Entity extends Entity
const Entity = preload("../entity.gd") const Entity = preload ("../entity.gd")
@export var view_width = 0.15 @export var view_width = 0.15
@ -8,11 +8,12 @@ const Entity = preload("../entity.gd")
@onready var http_request = $HTTPRequest @onready var http_request = $HTTPRequest
@onready var mesh = $MeshInstance3D @onready var mesh = $MeshInstance3D
# Called when the node enters the scene tree for the first time. # Called when the node enters the scene tree for the first time.
func _ready(): func _ready():
super() super()
icon.value = "photo_camera"
var stateInfo = await HomeApi.get_state(entity_id) var stateInfo = await HomeApi.get_state(entity_id)
set_state(stateInfo) set_state(stateInfo)
@ -36,7 +37,6 @@ func set_state(stateInfo):
if stateInfo["attributes"].has("entity_picture"): if stateInfo["attributes"].has("entity_picture"):
load_image(stateInfo["attributes"]["entity_picture"]) load_image(stateInfo["attributes"]["entity_picture"])
func load_image(url: String): func load_image(url: String):
http_request.request("http://192.168.33.33:8123" + url) http_request.request("http://192.168.33.33:8123" + url)

View File

@ -10,7 +10,7 @@ size = Vector2(0.15, 0.15)
[sub_resource type="BoxShape3D" id="BoxShape3D_te0pn"] [sub_resource type="BoxShape3D" id="BoxShape3D_te0pn"]
size = Vector3(0.15, 0.15, 0.01) size = Vector3(0.15, 0.15, 0.01)
[node name="Camera" type="StaticBody3D" groups=["entity"]] [node name="Camera" type="StaticBody3D" ]
script = ExtResource("1_htxq3") script = ExtResource("1_htxq3")
[node name="View" type="Sprite3D" parent="."] [node name="View" type="Sprite3D" parent="."]

View File

@ -1,6 +1,8 @@
extends StaticBody3D extends StaticBody3D
var entity_id: String var entity_id: String
var icon = R.state("question_mark")
var icon_color = R.state(Color(1, 1, 1, 1))
func _ready(): func _ready():
var movable = get_node("Movable") var movable = get_node("Movable")

View File

@ -1,12 +1,12 @@
extends Entity extends Entity
const Entity = preload("../entity.gd") const Entity = preload ("../entity.gd")
const color_wheel_img := preload("res://assets/canvas.png") const color_wheel_img := preload ("res://assets/canvas.png")
@export var color_off = Color(0.23, 0.23, 0.23) @export var color_off = Color(0.23, 0.23, 0.23)
@export var color_on = Color(1.0, 0.85, 0.0) @export var color_on = Color(1.0, 0.85, 0.0)
@onready var animation: AnimationPlayer = $AnimationPlayer @onready var lightbulb = $Lightbulb
@onready var slider: Slider3D = $Slider @onready var slider: Slider3D = $Slider
@onready var color_wheel = $ColorWheel @onready var color_wheel = $ColorWheel
@onready var color_puck = $ColorWheel/Puck @onready var color_puck = $ColorWheel/Puck
@ -17,105 +17,118 @@ const color_wheel_img := preload("res://assets/canvas.png")
var state = true var state = true
var brightness = 0 # 0-255 var brightness = 0 # 0-255
var color = color_on
var color_supported = false
# Called when the node enters the scene tree for the first time. # Called when the node enters the scene tree for the first time.
func _ready(): func _ready():
super() super()
icon.value = "lightbulb"
var stateInfo = await HomeApi.get_state(entity_id) var stateInfo = await HomeApi.get_state(entity_id)
set_state(stateInfo["state"] == "on") set_state(stateInfo["state"] == "on", stateInfo["attributes"])
if stateInfo.has("attributes") && stateInfo["attributes"].has("effect_list") && stateInfo["attributes"]["effect_list"].size() > 0: if stateInfo.has("attributes")&&stateInfo["attributes"].has("effect_list")&&stateInfo["attributes"]["effect_list"].size() > 0:
if stateInfo["attributes"].has("effect") && stateInfo["attributes"]["effect"] != null: if stateInfo["attributes"].has("effect")&&stateInfo["attributes"]["effect"] != null:
mode_label.text = stateInfo["attributes"]["effect"] mode_label.text = stateInfo["attributes"]["effect"]
mode_next.on_button_down.connect(func(): mode_next.on_button_down.connect(func():
var index = stateInfo["attributes"]["effect_list"].find(stateInfo["attributes"]["effect"]) var index=stateInfo["attributes"]["effect_list"].find(stateInfo["attributes"]["effect"])
if index == -1: if index == - 1:
index = 0 index=0
else: else:
index = (index + 1) % stateInfo["attributes"]["effect_list"].size() index=(index + 1) % stateInfo["attributes"]["effect_list"].size()
mode_label.text = stateInfo["attributes"]["effect_list"][index] mode_label.text=stateInfo["attributes"]["effect_list"][index]
HomeApi.set_state(entity_id, "on", {"effect": stateInfo["attributes"]["effect_list"][index]}) HomeApi.set_state(entity_id, "on", {"effect": stateInfo["attributes"]["effect_list"][index]})
) )
mode_before.on_button_down.connect(func(): mode_before.on_button_down.connect(func():
var index = stateInfo["attributes"]["effect_list"].find(stateInfo["attributes"]["effect"]) var index=stateInfo["attributes"]["effect_list"].find(stateInfo["attributes"]["effect"])
if index == -1: if index == - 1:
index = 0 index=0
else: else:
index = (index - 1) % stateInfo["attributes"]["effect_list"].size() index=(index - 1) % stateInfo["attributes"]["effect_list"].size()
mode_label.text = stateInfo["attributes"]["effect_list"][index] mode_label.text=stateInfo["attributes"]["effect_list"][index]
HomeApi.set_state(entity_id, "on", {"effect": stateInfo["attributes"]["effect_list"][index]}) HomeApi.set_state(entity_id, "on", {"effect": stateInfo["attributes"]["effect_list"][index]})
) )
else: else:
remove_child(modes) remove_child(modes)
if stateInfo.has("attributes")&&stateInfo["attributes"].has("supported_color_modes")&&stateInfo["attributes"]["supported_color_modes"].has("rgb"):
if stateInfo.has("attributes") && stateInfo["attributes"].has("supported_color_modes") && stateInfo["attributes"]["supported_color_modes"].has("rgb"):
color_wheel.get_node("Clickable").on_press_down.connect(func(event: EventPointer): color_wheel.get_node("Clickable").on_press_down.connect(func(event: EventPointer):
var target_point = color_wheel.to_local(event.ray.get_collision_point()) var target_point=color_wheel.to_local(event.ray.get_collision_point())
var delta = Vector2(target_point.x, target_point.z) * (1.0 / 0.08) var delta=Vector2(target_point.x, target_point.z) * (1.0 / 0.08)
if delta.length() > 1: if delta.length() > 1:
delta = delta.normalized() delta=delta.normalized()
print("delta", delta)
var color = color_wheel_img.get_image().get_pixel((delta.x * 0.5 + 0.5) * 1000, (delta.y * 0.5 + 0.5) * 1000) var color=color_wheel_img.get_image().get_pixel((delta.x * 0.5 + 0.5) * 1000, (delta.y * 0.5 + 0.5) * 1000)
color_puck.material_override.albedo_color = color print("color", color)
color_puck.position = Vector3(target_point.x, color_puck.position.y, target_point.z)
var attributes = { color_puck.material_override.albedo_color=color
color_puck.position=Vector3(target_point.x, color_puck.position.y, target_point.z)
var attributes={
"rgb_color": [int(color.r * 255), int(color.g * 255), int(color.b * 255)], "rgb_color": [int(color.r * 255), int(color.g * 255), int(color.b * 255)],
} }
HomeApi.set_state(entity_id, "on", attributes) HomeApi.set_state(entity_id, "on", attributes)
set_state(state, attributes)
) )
color_supported = true
else: else:
remove_child(color_wheel) remove_child(color_wheel)
await HomeApi.watch_state(entity_id, func(new_state): await HomeApi.watch_state(entity_id, func(new_state):
if (new_state["state"] == "on") == state: if (new_state["state"] == "on") == state:
return return
set_state(new_state["state"] == "on") set_state(new_state["state"] == "on", new_state["attributes"])
) )
slider.on_value_changed.connect(func(new_value): slider.on_value_changed.connect(func(new_value):
var value = new_value / 100 * 255 var value=new_value / 100 * 255
HomeApi.set_state(entity_id, "on" if state else "off", {"brightness": int(value)}) HomeApi.set_state(entity_id, "on" if state else "off", {"brightness": int(value)})
set_state(state, value) set_state(state, {"brightness": value})
) )
func set_state(new_state: bool, new_brightness = null): func set_state(new_state: bool, attributes={}):
if state == false && new_state == false: if state == false&&new_state == false:
return return
state = new_state state = new_state
brightness = new_brightness
if attributes.has("brightness"):
brightness = attributes["brightness"]
if attributes.has("rgb_color")&&attributes["rgb_color"] != null:
color = Color(attributes["rgb_color"][0] / 255.0, attributes["rgb_color"][1] / 255.0, attributes["rgb_color"][2] / 255.0, 1)
var tween = create_tween()
var target_color = color_off
if state: if state:
if brightness == null: if brightness == null:
animation.speed_scale = 1 target_color = color if color_supported else color_on
animation.play_backwards("light")
else: else:
var duration = animation.get_animation("light").length target_color = color_off.lerp(color if color_supported else color_on, brightness / 255.0)
animation.speed_scale = 0
animation.seek(lerpf(0, duration, 1 - (brightness / 255.0)), true)
else:
animation.speed_scale = 1
animation.play("light")
icon_color.value = target_color
tween.tween_property(lightbulb, "material_override:albedo_color", target_color, 0.3)
func _on_click(event): func _on_click(event):
if event.target == self: if event.target == self:
var attributes = {} var attributes = {}
if !state && brightness != null: if !state&&brightness != null:
attributes["brightness"] = int(brightness) attributes["brightness"] = int(brightness)
HomeApi.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) set_state(!state, attributes)

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=18 format=3 uid="uid://cw86rc42dv2d8"] [gd_scene load_steps=15 format=3 uid="uid://cw86rc42dv2d8"]
[ext_resource type="Script" path="res://content/entities/light/light.gd" id="1_ykxy3"] [ext_resource type="Script" path="res://content/entities/light/light.gd" id="1_ykxy3"]
[ext_resource type="Script" path="res://content/functions/movable.gd" id="4_4sfxb"] [ext_resource type="Script" path="res://content/functions/movable.gd" id="4_4sfxb"]
@ -12,43 +12,6 @@
[sub_resource type="SphereShape3D" id="SphereShape3D_ukj14"] [sub_resource type="SphereShape3D" id="SphereShape3D_ukj14"]
radius = 0.05 radius = 0.05
[sub_resource type="Animation" id="Animation_afofi"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("CSGCombiner3D:material_override:albedo_color")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Color(1, 0.85098, 0, 1)]
}
[sub_resource type="Animation" id="Animation_7o31s"]
resource_name = "light"
length = 0.3
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("CSGCombiner3D:material_override:albedo_color")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.3),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Color(1, 0.85098, 0, 1), Color(0.231373, 0.231373, 0.231373, 1)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_8a76q"]
_data = {
"RESET": SubResource("Animation_afofi"),
"light": SubResource("Animation_7o31s")
}
[sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_k3ob2"] [sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_k3ob2"]
points = PackedVector3Array(0, -0.005, -0.08, -0.00784652, -0.005, -0.0796241, 0, 0.005, -0.08, 0.00783085, -0.005, -0.0796241, -0.00784652, 0.005, -0.0796241, -0.0156147, -0.005, -0.0784651, 0.00783085, 0.005, -0.0796241, 0.0155991, -0.005, -0.0784651, -0.0156147, 0.005, -0.0784651, -0.0232263, -0.005, -0.0765701, 0.0155991, 0.005, -0.0784651, 0.0232106, -0.005, -0.0765701, -0.0232263, 0.005, -0.0765701, -0.0306186, -0.005, -0.0739233, 0.0232106, 0.005, -0.0765701, 0.030603, -0.005, -0.0739233, -0.0306186, 0.005, -0.0739233, -0.0377134, -0.005, -0.070556, 0.030603, 0.005, -0.0739233, 0.0376977, -0.005, -0.070556, -0.0377134, 0.005, -0.070556, -0.0444479, -0.005, -0.0665309, 0.0376977, 0.005, -0.070556, 0.0444323, -0.005, -0.0665309, -0.0444479, 0.005, -0.0665309, -0.0507596, -0.005, -0.0618481, 0.0444323, 0.005, -0.0665309, 0.0507439, -0.005, -0.0618481, -0.0507596, 0.005, -0.0618481, -0.0565701, -0.005, -0.0565701, 0.0507439, 0.005, -0.0618481, 0.0565544, -0.005, -0.0565701, -0.0565701, 0.005, -0.0565701, -0.0618481, -0.005, -0.0507596, 0.0565544, 0.005, -0.0565701, 0.0618324, -0.005, -0.0507596, -0.0618481, 0.005, -0.0507596, -0.0665309, -0.005, -0.0444479, 0.0618324, 0.005, -0.0507596, 0.0665153, -0.005, -0.0444479, -0.0665309, 0.005, -0.0444479, -0.070556, -0.005, -0.0377134, 0.0665153, 0.005, -0.0444479, 0.0705403, -0.005, -0.0377134, -0.070556, 0.005, -0.0377134, -0.0739233, -0.005, -0.0306186, 0.0705403, 0.005, -0.0377134, 0.0739076, -0.005, -0.0306186, -0.0739233, 0.005, -0.0306186, -0.0765701, -0.005, -0.0232263, 0.0739076, 0.005, -0.0306186, 0.0765544, -0.005, -0.0232263, -0.0765701, 0.005, -0.0232263, -0.0784651, -0.005, -0.0156147, 0.0765544, 0.005, -0.0232263, 0.0784495, -0.005, -0.0156147, -0.0784651, 0.005, -0.0156147, -0.0796241, -0.005, -0.00784652, 0.0784495, 0.005, -0.0156147, 0.0796085, -0.005, -0.00784652, -0.0796241, 0.005, -0.00784652, -0.08, -0.005, 0, 0.0796085, 0.005, -0.00784652, 0.08, -0.005, 0, -0.08, 0.005, 0, -0.0796241, -0.005, 0.00783085, 0.08, 0.005, 0, 0.0796085, -0.005, 0.00783085, -0.0796241, 0.005, 0.00783085, -0.0784651, -0.005, 0.0155991, 0.0796085, 0.005, 0.00783085, 0.0784495, -0.005, 0.0155991, -0.0784651, 0.005, 0.0155991, -0.0765701, -0.005, 0.0232106, 0.0784495, 0.005, 0.0155991, 0.0765544, -0.005, 0.0232106, -0.0765701, 0.005, 0.0232106, -0.0739233, -0.005, 0.030603, 0.0765544, 0.005, 0.0232106, 0.0739076, -0.005, 0.030603, -0.0739233, 0.005, 0.030603, -0.070556, -0.005, 0.0376977, 0.0739076, 0.005, 0.030603, 0.0705403, -0.005, 0.0376977, -0.070556, 0.005, 0.0376977, -0.0665309, -0.005, 0.0444323, 0.0705403, 0.005, 0.0376977, 0.0665153, -0.005, 0.0444323, -0.0665309, 0.005, 0.0444323, -0.0618481, -0.005, 0.0507439, 0.0665153, 0.005, 0.0444323, 0.0618324, -0.005, 0.0507439, -0.0618481, 0.005, 0.0507439, -0.0565701, -0.005, 0.0565544, 0.0618324, 0.005, 0.0507439, 0.0565544, -0.005, 0.0565544, -0.0565701, 0.005, 0.0565544, -0.0507596, -0.005, 0.0618324, 0.0565544, 0.005, 0.0565544, 0.0507439, -0.005, 0.0618324, -0.0507596, 0.005, 0.0618324, -0.0444479, -0.005, 0.0665153, 0.0507439, 0.005, 0.0618324, 0.0444323, -0.005, 0.0665153, -0.0444479, 0.005, 0.0665153, -0.0377134, -0.005, 0.0705403, 0.0444323, 0.005, 0.0665153, 0.0376977, -0.005, 0.0705403, -0.0377134, 0.005, 0.0705403, -0.0306186, -0.005, 0.0739076, 0.0376977, 0.005, 0.0705403, 0.030603, -0.005, 0.0739076, -0.0306186, 0.005, 0.0739076, -0.0232263, -0.005, 0.0765544, 0.030603, 0.005, 0.0739076, 0.0232106, -0.005, 0.0765544, -0.0232263, 0.005, 0.0765544, -0.0156147, -0.005, 0.0784495, 0.0232106, 0.005, 0.0765544, 0.0155991, -0.005, 0.0784495, -0.0156147, 0.005, 0.0784495, -0.00784652, -0.005, 0.0796085, 0.0155991, 0.005, 0.0784495, 0.00783085, -0.005, 0.0796085, -0.00784652, 0.005, 0.0796085, 0, -0.005, 0.08, 0.00783085, 0.005, 0.0796085, 0, 0.005, 0.08) points = PackedVector3Array(0, -0.005, -0.08, -0.00784652, -0.005, -0.0796241, 0, 0.005, -0.08, 0.00783085, -0.005, -0.0796241, -0.00784652, 0.005, -0.0796241, -0.0156147, -0.005, -0.0784651, 0.00783085, 0.005, -0.0796241, 0.0155991, -0.005, -0.0784651, -0.0156147, 0.005, -0.0784651, -0.0232263, -0.005, -0.0765701, 0.0155991, 0.005, -0.0784651, 0.0232106, -0.005, -0.0765701, -0.0232263, 0.005, -0.0765701, -0.0306186, -0.005, -0.0739233, 0.0232106, 0.005, -0.0765701, 0.030603, -0.005, -0.0739233, -0.0306186, 0.005, -0.0739233, -0.0377134, -0.005, -0.070556, 0.030603, 0.005, -0.0739233, 0.0376977, -0.005, -0.070556, -0.0377134, 0.005, -0.070556, -0.0444479, -0.005, -0.0665309, 0.0376977, 0.005, -0.070556, 0.0444323, -0.005, -0.0665309, -0.0444479, 0.005, -0.0665309, -0.0507596, -0.005, -0.0618481, 0.0444323, 0.005, -0.0665309, 0.0507439, -0.005, -0.0618481, -0.0507596, 0.005, -0.0618481, -0.0565701, -0.005, -0.0565701, 0.0507439, 0.005, -0.0618481, 0.0565544, -0.005, -0.0565701, -0.0565701, 0.005, -0.0565701, -0.0618481, -0.005, -0.0507596, 0.0565544, 0.005, -0.0565701, 0.0618324, -0.005, -0.0507596, -0.0618481, 0.005, -0.0507596, -0.0665309, -0.005, -0.0444479, 0.0618324, 0.005, -0.0507596, 0.0665153, -0.005, -0.0444479, -0.0665309, 0.005, -0.0444479, -0.070556, -0.005, -0.0377134, 0.0665153, 0.005, -0.0444479, 0.0705403, -0.005, -0.0377134, -0.070556, 0.005, -0.0377134, -0.0739233, -0.005, -0.0306186, 0.0705403, 0.005, -0.0377134, 0.0739076, -0.005, -0.0306186, -0.0739233, 0.005, -0.0306186, -0.0765701, -0.005, -0.0232263, 0.0739076, 0.005, -0.0306186, 0.0765544, -0.005, -0.0232263, -0.0765701, 0.005, -0.0232263, -0.0784651, -0.005, -0.0156147, 0.0765544, 0.005, -0.0232263, 0.0784495, -0.005, -0.0156147, -0.0784651, 0.005, -0.0156147, -0.0796241, -0.005, -0.00784652, 0.0784495, 0.005, -0.0156147, 0.0796085, -0.005, -0.00784652, -0.0796241, 0.005, -0.00784652, -0.08, -0.005, 0, 0.0796085, 0.005, -0.00784652, 0.08, -0.005, 0, -0.08, 0.005, 0, -0.0796241, -0.005, 0.00783085, 0.08, 0.005, 0, 0.0796085, -0.005, 0.00783085, -0.0796241, 0.005, 0.00783085, -0.0784651, -0.005, 0.0155991, 0.0796085, 0.005, 0.00783085, 0.0784495, -0.005, 0.0155991, -0.0784651, 0.005, 0.0155991, -0.0765701, -0.005, 0.0232106, 0.0784495, 0.005, 0.0155991, 0.0765544, -0.005, 0.0232106, -0.0765701, 0.005, 0.0232106, -0.0739233, -0.005, 0.030603, 0.0765544, 0.005, 0.0232106, 0.0739076, -0.005, 0.030603, -0.0739233, 0.005, 0.030603, -0.070556, -0.005, 0.0376977, 0.0739076, 0.005, 0.030603, 0.0705403, -0.005, 0.0376977, -0.070556, 0.005, 0.0376977, -0.0665309, -0.005, 0.0444323, 0.0705403, 0.005, 0.0376977, 0.0665153, -0.005, 0.0444323, -0.0665309, 0.005, 0.0444323, -0.0618481, -0.005, 0.0507439, 0.0665153, 0.005, 0.0444323, 0.0618324, -0.005, 0.0507439, -0.0618481, 0.005, 0.0507439, -0.0565701, -0.005, 0.0565544, 0.0618324, 0.005, 0.0507439, 0.0565544, -0.005, 0.0565544, -0.0565701, 0.005, 0.0565544, -0.0507596, -0.005, 0.0618324, 0.0565544, 0.005, 0.0565544, 0.0507439, -0.005, 0.0618324, -0.0507596, 0.005, 0.0618324, -0.0444479, -0.005, 0.0665153, 0.0507439, 0.005, 0.0618324, 0.0444323, -0.005, 0.0665153, -0.0444479, 0.005, 0.0665153, -0.0377134, -0.005, 0.0705403, 0.0444323, 0.005, 0.0665153, 0.0376977, -0.005, 0.0705403, -0.0377134, 0.005, 0.0705403, -0.0306186, -0.005, 0.0739076, 0.0376977, 0.005, 0.0705403, 0.030603, -0.005, 0.0739076, -0.0306186, 0.005, 0.0739076, -0.0232263, -0.005, 0.0765544, 0.030603, 0.005, 0.0739076, 0.0232106, -0.005, 0.0765544, -0.0232263, 0.005, 0.0765544, -0.0156147, -0.005, 0.0784495, 0.0232106, 0.005, 0.0765544, 0.0155991, -0.005, 0.0784495, -0.0156147, 0.005, 0.0784495, -0.00784652, -0.005, 0.0796085, 0.0155991, 0.005, 0.0784495, 0.00783085, -0.005, 0.0796085, -0.00784652, 0.005, 0.0796085, 0, -0.005, 0.08, 0.00783085, 0.005, 0.0796085, 0, 0.005, 0.08)
@ -67,7 +30,7 @@ top_radius = 0.01
bottom_radius = 0.01 bottom_radius = 0.01
height = 0.005 height = 0.005
[node name="Light" type="StaticBody3D" groups=["entity"]] [node name="Light" type="StaticBody3D"]
collision_mask = 0 collision_mask = 0
script = ExtResource("1_ykxy3") script = ExtResource("1_ykxy3")
@ -80,26 +43,21 @@ script = ExtResource("5_oh4jg")
[node name="Movable" type="Node" parent="."] [node name="Movable" type="Node" parent="."]
script = ExtResource("4_4sfxb") script = ExtResource("4_4sfxb")
[node name="CSGCombiner3D" type="CSGCombiner3D" parent="."] [node name="Lightbulb" type="CSGCombiner3D" parent="."]
transform = Transform3D(1, 9.69949e-05, 0.000589194, -9.77749e-05, 0.999999, 0.00135802, -0.000589065, -0.00135808, 0.999999, 0, 0, 0) transform = Transform3D(1, 9.69949e-05, 0.000589194, -9.77749e-05, 0.999999, 0.00135802, -0.000589065, -0.00135808, 0.999999, 0, 0, 0)
material_override = ExtResource("5_50gph") material_override = ExtResource("5_50gph")
[node name="CSGSphere3D" type="CSGSphere3D" parent="CSGCombiner3D"] [node name="CSGSphere3D" type="CSGSphere3D" parent="Lightbulb"]
radius = 0.05 radius = 0.05
radial_segments = 36 radial_segments = 36
rings = 12 rings = 12
[node name="CSGCylinder3D" type="CSGCylinder3D" parent="CSGCombiner3D"] [node name="CSGCylinder3D" type="CSGCylinder3D" parent="Lightbulb"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.0485739, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.0485739, 0)
radius = 0.02 radius = 0.02
height = 0.03 height = 0.03
sides = 36 sides = 36
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
libraries = {
"": SubResource("AnimationLibrary_8a76q")
}
[node name="Slider" parent="." instance=ExtResource("6_mhjlm")] [node name="Slider" parent="." instance=ExtResource("6_mhjlm")]
transform = Transform3D(1.91069e-15, 4.37114e-08, 1, 1, -4.37114e-08, 0, 4.37114e-08, 1, -4.37114e-08, 0.08, 0, 0) transform = Transform3D(1.91069e-15, 4.37114e-08, 1, 1, -4.37114e-08, 0, 4.37114e-08, 1, -4.37114e-08, 0.08, 0, 0)
max = 100.0 max = 100.0

View File

@ -2,7 +2,5 @@
[resource] [resource]
resource_local_to_scene = true resource_local_to_scene = true
albedo_color = Color(1, 0.85098, 0, 1)
emission_enabled = true
emission = Color(1, 0.65098, 0, 1) emission = Color(1, 0.65098, 0, 1)
emission_energy_multiplier = 0.0 emission_energy_multiplier = 0.0

View File

@ -9,6 +9,8 @@ const Entity = preload ("../entity.gd")
func _ready(): func _ready():
super() super()
icon.value = "finance"
label.text = entity_id label.text = entity_id
if HomeApi.has_connected() == false: if HomeApi.has_connected() == false:
@ -43,4 +45,4 @@ func request_history():
line_chart.y_axis_label.value = result.unit line_chart.y_axis_label.value = result.unit
func get_interface(): func get_interface():
return "line_chart" return "line_chart"

View File

@ -7,7 +7,7 @@
[sub_resource type="BoxShape3D" id="BoxShape3D_rmm5v"] [sub_resource type="BoxShape3D" id="BoxShape3D_rmm5v"]
size = Vector3(0.5, 0.3, 0.001) size = Vector3(0.5, 0.3, 0.001)
[node name="LineChart" type="StaticBody3D" groups=["entity"]] [node name="LineChart" type="StaticBody3D"]
collision_layer = 5 collision_layer = 5
collision_mask = 0 collision_mask = 0
script = ExtResource("1_5dxim") script = ExtResource("1_5dxim")

View File

@ -20,6 +20,8 @@ var volume = 50
func _ready(): func _ready():
super() super()
icon.value = "pause_circle"
var stateInfo = await HomeApi.get_state(entity_id) var stateInfo = await HomeApi.get_state(entity_id)
set_state(stateInfo) set_state(stateInfo)
@ -65,9 +67,11 @@ func set_state(stateInfo):
playing = true playing = true
play.label = "pause" play.label = "pause"
icon.value = "play_circle"
else: else:
playing = false playing = false
play.label = "play_arrow" play.label = "play_arrow"
icon.value = "pause_circle"
func load_image(url: String): func load_image(url: String):
http_request.request("http://192.168.33.33:8123" + url) http_request.request("http://192.168.33.33:8123" + url)

View File

@ -10,7 +10,7 @@
[sub_resource type="BoxShape3D" id="BoxShape3D_vi3eg"] [sub_resource type="BoxShape3D" id="BoxShape3D_vi3eg"]
size = Vector3(0.23, 0.142768, 0.01) size = Vector3(0.23, 0.142768, 0.01)
[node name="MediaPlayer" type="StaticBody3D" groups=["entity"]] [node name="MediaPlayer" type="StaticBody3D" ]
collision_mask = 0 collision_mask = 0
script = ExtResource("1_ame17") script = ExtResource("1_ame17")

View File

@ -8,6 +8,8 @@ const Entity = preload ("../entity.gd")
func _ready(): func _ready():
super() super()
icon.value = "sliders"
var stateInfo = await HomeApi.get_state(entity_id) var stateInfo = await HomeApi.get_state(entity_id)
if stateInfo == null: if stateInfo == null:
return return

View File

@ -8,7 +8,7 @@
[sub_resource type="BoxShape3D" id="BoxShape3D_7mk8w"] [sub_resource type="BoxShape3D" id="BoxShape3D_7mk8w"]
size = Vector3(0.0390625, 0.114258, 0.0142822) size = Vector3(0.0390625, 0.114258, 0.0142822)
[node name="Number" type="StaticBody3D" groups=["entity"]] [node name="Number" type="StaticBody3D" ]
script = ExtResource("1_26xwp") script = ExtResource("1_26xwp")
[node name="Slider" parent="." instance=ExtResource("2_sninv")] [node name="Slider" parent="." instance=ExtResource("2_sninv")]

View File

@ -14,6 +14,8 @@ var is_text = true
func _ready(): func _ready():
super() super()
icon.value = "sensors"
var stateInfo = await HomeApi.get_state(entity_id) var stateInfo = await HomeApi.get_state(entity_id)
set_text(stateInfo) set_text(stateInfo)

View File

@ -10,7 +10,7 @@
resource_local_to_scene = true resource_local_to_scene = true
size = Vector3(0.18, 0.03, 0.02) size = Vector3(0.18, 0.03, 0.02)
[node name="Sensor" type="StaticBody3D" groups=["entity"]] [node name="Sensor" type="StaticBody3D" ]
collision_mask = 0 collision_mask = 0
script = ExtResource("1_57ac8") script = ExtResource("1_57ac8")

View File

@ -1,13 +1,12 @@
extends Entity extends Entity
const Entity = preload("../entity.gd") const Entity = preload ("../entity.gd")
@onready var sprite: AnimatedSprite3D = $Icon @onready var sprite: AnimatedSprite3D = $Icon
# Called when the node enters the scene tree for the first time. # Called when the node enters the scene tree for the first time.
func _ready(): func _ready():
super() super()
var stateInfo = await HomeApi.get_state(entity_id) var stateInfo = await HomeApi.get_state(entity_id)
if stateInfo == null: if stateInfo == null:
return return
@ -17,13 +16,16 @@ func _ready():
else: else:
sprite.set_frame(1) sprite.set_frame(1)
icon.value = "toggle_" + stateInfo["state"]
await HomeApi.watch_state(entity_id, func(new_state): await HomeApi.watch_state(entity_id, func(new_state):
if new_state["state"] == "on": if new_state["state"] == "on":
sprite.set_frame(0) sprite.set_frame(0)
else: else:
sprite.set_frame(1) sprite.set_frame(1)
)
icon.value="toggle_" + new_state["state"]
)
func _on_click(event): func _on_click(event):
HomeApi.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")

View File

@ -23,7 +23,7 @@ animations = [{
"speed": 5.0 "speed": 5.0
}] }]
[node name="Switch" type="StaticBody3D" groups=["entity"]] [node name="Switch" type="StaticBody3D" ]
collision_mask = 0 collision_mask = 0
script = ExtResource("1_8ffhi") script = ExtResource("1_8ffhi")

View File

@ -40,7 +40,6 @@ func _ready():
_emit_action(name, false, true) _emit_action(name, false, true)
) )
remove_child(menu)
remove_child(keyboard) remove_child(keyboard)
EventSystem.on_action_down.connect(func(action): EventSystem.on_action_down.connect(func(action):
@ -81,13 +80,7 @@ func create_voice_assistant():
) )
func toggle_menu(): func toggle_menu():
if menu.show_menu == false: menu.show_menu.value = !menu.show_menu.value
add_child(menu)
menu.global_transform = _get_menu_transform()
menu.show_menu = !menu.show_menu
await menu.get_node("AnimationPlayer").animation_finished
if menu.show_menu == false:
remove_child(menu)
func _emit_action(name: String, value, right_controller: bool=true): func _emit_action(name: String, value, right_controller: bool=true):
var event = EventAction.new() var event = EventAction.new()
@ -126,14 +119,6 @@ func _input(event):
if event is InputEventKey and Input.is_key_pressed(KEY_M): if event is InputEventKey and Input.is_key_pressed(KEY_M):
toggle_menu() toggle_menu()
func _get_menu_transform():
var transform = camera.get_global_transform()
transform.origin -= transform.basis.z * 0.5
transform.basis = transform.basis.rotated(transform.basis.x, deg_to_rad(90))
return transform
func vector_key_mapping(key_positive_x: int, key_negative_x: int, key_positive_y: int, key_negative_y: int): func vector_key_mapping(key_positive_x: int, key_negative_x: int, key_positive_y: int, key_negative_y: int):
var x = 0 var x = 0
var y = 0 var y = 0

View File

@ -1,5 +1,7 @@
extends XRController3D extends XRController3D
const Entity = preload ("res://content/entities/entity.gd")
@onready var area = $trash_bin/Area3D @onready var area = $trash_bin/Area3D
@onready var trash_bin = $trash_bin @onready var trash_bin = $trash_bin
@onready var animation = $AnimationPlayer @onready var animation = $AnimationPlayer
@ -35,21 +37,21 @@ func _ready():
trash_bin_visible = false trash_bin_visible = false
EventSystem.on_grab_down.connect(func(event: EventPointer): EventSystem.on_grab_down.connect(func(event: EventPointer):
trash_bin_visible = event.target.is_in_group("entity") trash_bin_visible=event.target is Entity
) )
EventSystem.on_grab_move.connect(func(event): EventSystem.on_grab_move.connect(func(event):
if !trash_bin_visible: if !trash_bin_visible:
return return
if event.target.is_in_group("entity") && area.overlaps_body(event.target): if event.target is Entity&&area.overlaps_body(event.target):
if !to_delete.has(event.target): if !to_delete.has(event.target):
to_delete.append(event.target) to_delete.append(event.target)
trash_bin_large = true trash_bin_large=true
else: else:
to_delete.erase(event.target) to_delete.erase(event.target)
trash_bin_large = false trash_bin_large=false
) )
@ -60,6 +62,6 @@ func _ready():
for entity in to_delete: for entity in to_delete:
entity.queue_free() entity.queue_free()
to_delete.clear() to_delete.clear()
trash_bin_large = false trash_bin_large=false
trash_bin_visible = false trash_bin_visible=false
) )

View File

@ -0,0 +1,38 @@
extends StaticBody3D
const Entity = preload ("res://content/entities/entity.gd")
@export var entity: Entity
@onready var collision = $CollisionShape3D
@onready var label = $Label3D
var active = R.state(false)
var disabled = R.state(true)
var miniature = House.body.mini_view
func _ready():
R.effect(func(_arg):
label.text=entity.icon.value
label.modulate=entity.icon_color.value
)
# Update active
R.effect(func(_arg):
label.outline_modulate=Color(242, 90, 56, 1) if active.value else Color(0, 0, 0, 1)
)
# Update disabled
R.effect(func(_arg):
visible=!disabled.value
collision.disabled=disabled.value
)
func _on_click(_event: EventPointer):
if entity.has_method("quick_action"):
entity.quick_action()
else:
miniature.entity_select.toggle(entity)
func _on_move_start(_event: EventPointer):
miniature.entity_select.toggle(entity)

View File

@ -0,0 +1,22 @@
[gd_scene load_steps=4 format=3 uid="uid://b5buw1sas18n4"]
[ext_resource type="Script" path="res://content/system/dot/dot.gd" id="1_vdpux"]
[ext_resource type="FontVariation" uid="uid://sshfnckriqxn" path="res://assets/icons/icons.tres" id="4_504vw"]
[sub_resource type="SphereShape3D" id="SphereShape3D_3wgjq"]
custom_solver_bias = 0.2
radius = 0.1
[node name="Dot" type="StaticBody3D"]
script = ExtResource("1_vdpux")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("SphereShape3D_3wgjq")
[node name="Label3D" type="Label3D" parent="."]
pixel_size = 0.002
billboard = 1
text = "lightbulb"
font = ExtResource("4_504vw")
font_size = 100
outline_size = 18

View File

@ -12,6 +12,7 @@ const AlignReference = preload ("./align_reference.gd")
var fixing_reference: bool = false var fixing_reference: bool = false
var editing_room: RoomType = null var editing_room: RoomType = null
var loaded = R.state(false)
func _ready(): func _ready():
Store.house.on_loaded.connect(func(): Store.house.on_loaded.connect(func():
@ -19,6 +20,7 @@ func _ready():
) )
func update_house(): func update_house():
loaded.value = false
for old_room in get_rooms(0): for old_room in get_rooms(0):
old_room.queue_free() old_room.queue_free()
await old_room.tree_exited await old_room.tree_exited
@ -46,6 +48,8 @@ func update_house():
entity_instance.global_position = entity.position entity_instance.global_position = entity.position
entity_instance.global_rotation = entity.rotation entity_instance.global_rotation = entity.rotation
loaded.value = true
func create_room(room_name: String, level: int) -> RoomType: func create_room(room_name: String, level: int) -> RoomType:
var existing_room = Store.house.get_room(room_name) var existing_room = Store.house.get_room(room_name)

View File

@ -0,0 +1,72 @@
extends Marker3D
const DotScene = preload ("res://content/system/dot/dot.tscn")
const Entity = preload ("res://content/entities/entity.gd")
@onready var dots = $"../Small/Dots"
var active_type = null
var editing = R.state([])
var group_entity = null
func _ready():
await House.body.ready
# Update Group Entity
R.effect(func(_arg):
if editing.value.size() == 0:
if group_entity != null:
group_entity.queue_free()
group_entity=null
elif group_entity == null:
print(editing.value.map(func(entity): return entity.entity_id))
var id=HomeApi.groups.create(editing.value.map(func(entity): return entity.entity_id))
group_entity=EntityFactory.create_entity(id, active_type)
add_child(group_entity)
else:
HomeApi.groups.update_entities(group_entity.entity_id, editing.value.map(func(entity): return entity.entity_id))
)
var dots_disabled = R.computed(func(_arg):
return House.body.mini_view.small.value == false
)
# Update Entities
R.effect(func(_arg):
if House.body.loaded.value == false:
return
if Store.house.state.entities.size() == 0:
return
for old_dot in dots.get_children():
dots.remove_child(old_dot)
old_dot.free()
for room in House.body.get_rooms(0):
for entity in room.get_node("Entities").get_children():
var dot=DotScene.instantiate()
dot.position=House.body.to_local(entity.global_position)
dot.entity=entity
dot.active=R.computed(func(_arg2):
return editing.value.has(entity)
)
dot.disabled=dots_disabled
dots.add_child(dot)
)
func toggle(entity: Entity):
if active_type == null:
active_type = entity.entity_id.split(".")[0]
elif active_type != entity.entity_id.split(".")[0]:
return
if editing.value.has(entity):
editing.value.erase(entity)
if editing.value.size() == 0:
active_type = null
else:
editing.value.append(entity)
editing.value = editing.value

View File

@ -2,14 +2,15 @@ extends Node3D
const ConstructRoomMesh = preload ("res://lib/utils/mesh/construct_room_mesh.gd") const ConstructRoomMesh = preload ("res://lib/utils/mesh/construct_room_mesh.gd")
const wall_material = preload ("./mini_wall.tres") const wall_material = preload ("./mini_wall.tres")
const humidity_gradient = preload ("./humid_gradient.tres") const humidity_gradient = preload ("./humid_gradient.tres")
const temperature_gradient = preload ("./temp_gradient.tres") const temperature_gradient = preload ("./temp_gradient.tres")
@onready var body = $Body @onready var body = $Body
@onready var model = $Body/Model @onready var small_node = $Body/Small
@onready var model = $Body/Small/Model
@onready var collision_shape = $Body/CollisionShape3D @onready var collision_shape = $Body/CollisionShape3D
@onready var toggle_heatmap = $Body/HeatmapButton @onready var toggle_heatmap = $Body/HeatmapButton
@onready var entity_select = $Body/EntitySelect
enum HeatmapType { enum HeatmapType {
NONE = 0, NONE = 0,
@ -75,12 +76,15 @@ func _ready():
if small.value: if small.value:
var aabb=House.body.get_level_aabb(0) var aabb=House.body.get_level_aabb(0)
var height=aabb.size.y
aabb.position.y=- 0.03 aabb.position.y=- 0.03
aabb.size.y=0.06 aabb.size.y=0.06
var center=aabb.position + aabb.size / 2 var center=aabb.position + aabb.size / 2
collision_shape.shape.size=aabb.size * 0.1 collision_shape.shape.size=aabb.size * 0.1
entity_select.position=Vector3(0, height * 0.1 + 0.1, 0)
var camera=$"/root/Main/XROrigin3D/XRCamera3D" var camera=$"/root/Main/XROrigin3D/XRCamera3D"
var camera_position=camera.global_position var camera_position=camera.global_position
@ -92,10 +96,10 @@ func _ready():
var target_position=camera_position + camera_direction.normalized() * 0.2 var target_position=camera_position + camera_direction.normalized() * 0.2
var new_position=target_position - center * 0.1 var new_position=target_position - center * 0.1
tween.tween_property(model, "scale", Vector3(0.1, 0.1, 0.1), 0.5) tween.tween_property(small_node, "scale", Vector3(0.1, 0.1, 0.1), 0.5)
tween.tween_property(body, "position", new_position, 0.5) tween.tween_property(body, "position", new_position, 0.5)
else: else:
tween.tween_property(model, "scale", Vector3.ONE, 0.5) tween.tween_property(small_node, "scale", Vector3.ONE, 0.5)
tween.tween_property(body, "position", Vector3.ZERO, 0.5) tween.tween_property(body, "position", Vector3.ZERO, 0.5)
tween.tween_property(body, "quaternion", Quaternion.IDENTITY, 0.5) tween.tween_property(body, "quaternion", Quaternion.IDENTITY, 0.5)
) )
@ -104,9 +108,8 @@ func _ready():
R.effect(func(_arg): R.effect(func(_arg):
var show_map=heatmap_type.value != HeatmapType.NONE var show_map=heatmap_type.value != HeatmapType.NONE
var show_small=small.value var show_small=small.value
for child in model.get_children(): model.visible=show_map||show_small
child.visible=show_map||show_small
) )
# Update Heatmap # Update Heatmap

View File

@ -1,7 +1,8 @@
[gd_scene load_steps=4 format=3 uid="uid://ds60i5n211hi3"] [gd_scene load_steps=5 format=3 uid="uid://ds60i5n211hi3"]
[ext_resource type="Script" path="res://content/system/house/mini/miniature.gd" id="1_b53yn"] [ext_resource type="Script" path="res://content/system/house/mini/miniature.gd" id="1_b53yn"]
[ext_resource type="Script" path="res://content/functions/movable.gd" id="2_x7oed"] [ext_resource type="Script" path="res://content/functions/movable.gd" id="2_x7oed"]
[ext_resource type="Script" path="res://content/system/house/mini/Entity.gd" id="3_tgpny"]
[sub_resource type="BoxShape3D" id="BoxShape3D_bckw3"] [sub_resource type="BoxShape3D" id="BoxShape3D_bckw3"]
@ -15,5 +16,15 @@ shape = SubResource("BoxShape3D_bckw3")
[node name="Movable" type="Node" parent="Body"] [node name="Movable" type="Node" parent="Body"]
script = ExtResource("2_x7oed") script = ExtResource("2_x7oed")
restricted = true
[node name="Model" type="Node3D" parent="Body"] [node name="Small" type="Node3D" parent="Body"]
[node name="Model" type="Node3D" parent="Body/Small"]
[node name="Dots" type="Node3D" parent="Body/Small"]
[node name="EntitySelect" type="Marker3D" parent="Body"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.757576, 0)
gizmo_extents = 0.1
script = ExtResource("3_tgpny")

View File

@ -10,7 +10,7 @@ cull_mode = 2
shading_mode = 0 shading_mode = 0
albedo_color = Color(0.109804, 0.721569, 0.262745, 1) albedo_color = Color(0.109804, 0.721569, 0.262745, 1)
[sub_resource type="ArrayMesh" id="ArrayMesh_raxtd"] [sub_resource type="ArrayMesh" id="ArrayMesh_25da5"]
_surfaces = [{ _surfaces = [{
"aabb": AABB(-0.000587015, -0.000596339, 0.0005, 0.501171, 0.301189, 1e-05), "aabb": AABB(-0.000587015, -0.000596339, 0.0005, 0.501171, 0.301189, 1e-05),
"format": 34359742465, "format": 34359742465,
@ -43,7 +43,7 @@ script = ExtResource("1_n7fu8")
[node name="Line" type="MeshInstance3D" parent="."] [node name="Line" type="MeshInstance3D" parent="."]
material_override = SubResource("StandardMaterial3D_20gpn") material_override = SubResource("StandardMaterial3D_20gpn")
mesh = SubResource("ArrayMesh_raxtd") mesh = SubResource("ArrayMesh_25da5")
[node name="Plane" type="MeshInstance3D" parent="."] [node name="Plane" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.25, 0.15, -0.001) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.25, 0.15, -0.001)

View File

@ -1,28 +1,49 @@
extends Node3D extends Node3D
const Notification = preload("res://content/ui/components/notification/notification.tscn") const Notification = preload ("res://content/ui/components/notification/notification.tscn")
@onready var animation_player = $AnimationPlayer @onready var animation_player = $AnimationPlayer
@onready var notify_place = $AnimationContainer/NotifyPlace @onready var notify_place = $AnimationContainer/NotifyPlace
@onready var main = $"/root/Main"
var show_menu := false: var show_menu = R.state(false)
set(value):
show_menu = value func _ready():
if value: await main.ready
main.remove_child(self)
R.effect(func(_arg):
if show_menu.value:
main.add_child(self)
move_into_view()
animation_player.play_backwards("hide_menu") animation_player.play_backwards("hide_menu")
AudioPlayer.play_effect("open_menu") AudioPlayer.play_effect("open_menu")
else: else:
animation_player.play("hide_menu") animation_player.play("hide_menu")
AudioPlayer.play_effect("close_menu") AudioPlayer.play_effect("close_menu")
)
animation_player.animation_finished.connect(func(_animation):
if show_menu.value == false:
main.remove_child(self)
)
func _ready():
EventSystem.on_notify.connect(func(event: EventNotify): EventSystem.on_notify.connect(func(event: EventNotify):
var notification_node = Notification.instantiate() var notification_node=Notification.instantiate()
notification_node.text = event.message notification_node.text=event.message
notification_node.type = event.type notification_node.type=event.type
for child in notify_place.get_children(): for child in notify_place.get_children():
child.position += Vector3(0, 0, -0.06) child.position += Vector3(0, 0, -0.06)
notify_place.add_child(notification_node) notify_place.add_child(notification_node)
) )
func move_into_view():
var camera_transform = main.camera.global_transform
camera_transform.origin -= camera_transform.basis.z * 0.5
camera_transform.basis = camera_transform.basis.rotated(camera_transform.basis.x, deg_to_rad(90))
global_transform = camera_transform

View File

@ -18,10 +18,10 @@ size = Vector3(0.38, 0.0128076, 0.32)
[sub_resource type="BoxShape3D" id="BoxShape3D_6xn1i"] [sub_resource type="BoxShape3D" id="BoxShape3D_6xn1i"]
size = Vector3(0.3, 0.0264844, 0.3) size = Vector3(0.3, 0.0264844, 0.3)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ti5t2"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_01s1g"]
[sub_resource type="BoxMesh" id="BoxMesh_08du6"] [sub_resource type="BoxMesh" id="BoxMesh_08du6"]
material = SubResource("StandardMaterial3D_ti5t2") material = SubResource("StandardMaterial3D_01s1g")
size = Vector3(0.3, 0.01, 0.3) size = Vector3(0.3, 0.01, 0.3)
[sub_resource type="Animation" id="Animation_61md4"] [sub_resource type="Animation" id="Animation_61md4"]

View File

@ -0,0 +1 @@
extends Node3D

View File

@ -0,0 +1,42 @@
[gd_scene load_steps=6 format=3 uid="uid://cmtp5kof0ah2b"]
[ext_resource type="Material" uid="uid://bnwimm214q67g" path="res://assets/materials/sec-500.material" id="1_mxydb"]
[ext_resource type="Script" path="res://content/ui/sub_menu/sub_menu.gd" id="1_xpjuw"]
[ext_resource type="PackedScene" uid="uid://blrhy2uccrdn4" path="res://content/ui/components/input/input.tscn" id="2_64uue"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ti5t2"]
[sub_resource type="BoxMesh" id="BoxMesh_aisgf"]
material = SubResource("StandardMaterial3D_ti5t2")
size = Vector3(0.3, 0.01, 0.3)
[node name="SubMenu" type="Node3D"]
script = ExtResource("1_xpjuw")
[node name="Background" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.15, 0, 0.15)
material_override = ExtResource("1_mxydb")
mesh = SubResource("BoxMesh_aisgf")
skeleton = NodePath("../..")
[node name="Content" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.006, 0)
[node name="Label3D" type="Label3D" parent="Content"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.01, 0, 0.02)
pixel_size = 0.001
text = "Entity Name"
font_size = 24
outline_size = 0
horizontal_alignment = 0
[node name="Label3D2" type="Label3D" parent="Content"]
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.01, 0, 0.06)
pixel_size = 0.001
text = "ID:"
font_size = 18
outline_size = 0
horizontal_alignment = 0
[node name="Input" parent="Content" instance=ExtResource("2_64uue")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.12, 0, 0.06)

View File

@ -2,6 +2,7 @@ extends Node
## Manages the connection to the home automation system and provides a unified interface to the different home automation systems. ## Manages the connection to the home automation system and provides a unified interface to the different home automation systems.
const Hass = preload ("res://lib/home_apis/hass/hass.gd") const Hass = preload ("res://lib/home_apis/hass/hass.gd")
const EntityGroups = preload ("res://lib/utils/entity_group.gd")
const HassWebSocket = preload ("res://lib/home_apis/hass_ws/hass.gd") const HassWebSocket = preload ("res://lib/home_apis/hass_ws/hass.gd")
const VoiceAssistant = preload ("res://lib/home_apis/voice_handler.gd") const VoiceAssistant = preload ("res://lib/home_apis/voice_handler.gd")
@ -18,6 +19,8 @@ const methods = [
"watch_state" "watch_state"
] ]
var groups = EntityGroups.new()
## Emitted when the connection to the home automation system is established ## Emitted when the connection to the home automation system is established
signal on_connect() signal on_connect()
@ -86,16 +89,37 @@ func get_device(id: String):
## Returns the current state of an entity ## Returns the current state of an entity
func get_state(entity: String): func get_state(entity: String):
assert(has_connected(), "Not connected") assert(has_connected(), "Not connected")
var group = groups.get_group(entity)
if group != null:
return await api.get_state(group[0])
return await api.get_state(entity) return await api.get_state(entity)
## Updates the state of the entity and returns the resulting state ## Updates the state of the entity and returns the resulting state
func set_state(entity: String, state: Variant, attributes: Dictionary={}): func set_state(entity: String, state: Variant, attributes: Dictionary={}):
assert(has_connected(), "Not connected") assert(has_connected(), "Not connected")
var group = groups.get_group(entity)
if group != null:
for group_entity in group:
api.set_state(group_entity, state, attributes)
return null
return await api.set_state(entity, state, attributes) 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 ## 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): func watch_state(entity: String, callback: Callable):
assert(has_connected(), "Not connected") assert(has_connected(), "Not connected")
var group = groups.get_group(entity)
if group != null:
api.watch_state(group[0], callback)
return api.watch_state(entity, callback) return api.watch_state(entity, callback)
## Returns true if the adapter has an integration in the home automation system ## Returns true if the adapter has an integration in the home automation system
@ -128,4 +152,7 @@ func get_history(entity_id, start, end=null):
if api.has_method("get_history") == false: if api.has_method("get_history") == false:
return null return null
if groups.is_group(entity_id):
return null
return await api.get_history(entity_id, start, end) return await api.get_history(entity_id, start, end)

View File

@ -0,0 +1,44 @@
var groups = {}
var counter = 0
func create(entities):
var index = str(counter)
groups[index] = entities
counter += 1
return "group.%s" % index
func add_entity(id: String, entity):
if is_group(id) == false:
return false
groups[id.replace("group.", "")].append(entity)
return true
func update_entities(id: String, entities):
if is_group(id) == false:
return false
groups[id.replace("group.", "")] = entities
return true
func remove_entity(id: String, entity):
if is_group(id) == false:
return false
groups[id.replace("group.", "")].erase(entity)
return true
func remove(id: String):
if is_group(id) == false:
return false
return groups.erase(id.replace("group.", ""))
func is_group(id: String):
return id.begins_with("group.")
func get_group(id: String):
if is_group(id) == false:
return null
return groups[id.replace("group.", "")]