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"
type="CompressedTexture2D"
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={
"vram_texture": false
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
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]
compress/mode=0
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=false
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
@ -31,4 +33,4 @@ process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
detect_3d/compress_to=0

View File

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

View File

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

View File

@ -8,11 +8,12 @@ const Entity = preload("../entity.gd")
@onready var http_request = $HTTPRequest
@onready var mesh = $MeshInstance3D
# Called when the node enters the scene tree for the first time.
func _ready():
super()
icon.value = "photo_camera"
var stateInfo = await HomeApi.get_state(entity_id)
set_state(stateInfo)
@ -37,7 +38,6 @@ func set_state(stateInfo):
if stateInfo["attributes"].has("entity_picture"):
load_image(stateInfo["attributes"]["entity_picture"])
func load_image(url: String):
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"]
size = Vector3(0.15, 0.15, 0.01)
[node name="Camera" type="StaticBody3D" groups=["entity"]]
[node name="Camera" type="StaticBody3D" ]
script = ExtResource("1_htxq3")
[node name="View" type="Sprite3D" parent="."]

View File

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

View File

@ -6,7 +6,7 @@ const color_wheel_img := preload("res://assets/canvas.png")
@export var color_off = Color(0.23, 0.23, 0.23)
@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 color_wheel = $ColorWheel
@onready var color_puck = $ColorWheel/Puck
@ -17,13 +17,16 @@ const color_wheel_img := preload("res://assets/canvas.png")
var state = true
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.
func _ready():
super()
icon.value = "lightbulb"
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["attributes"].has("effect")&&stateInfo["attributes"]["effect"] != null:
@ -55,7 +58,6 @@ func _ready():
else:
remove_child(modes)
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):
var target_point=color_wheel.to_local(event.ray.get_collision_point())
@ -64,8 +66,12 @@ func _ready():
if delta.length() > 1:
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)
print("color", color)
color_puck.material_override.albedo_color=color
color_puck.position=Vector3(target_point.x, color_puck.position.y, target_point.z)
@ -74,41 +80,48 @@ func _ready():
}
HomeApi.set_state(entity_id, "on", attributes)
set_state(state, attributes)
)
color_supported = true
else:
remove_child(color_wheel)
await HomeApi.watch_state(entity_id, func(new_state):
if (new_state["state"] == "on") == state:
return
set_state(new_state["state"] == "on")
set_state(new_state["state"] == "on", new_state["attributes"])
)
slider.on_value_changed.connect(func(new_value):
var value=new_value / 100 * 255
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:
return
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 brightness == null:
animation.speed_scale = 1
animation.play_backwards("light")
target_color = color if color_supported else color_on
else:
var duration = animation.get_animation("light").length
animation.speed_scale = 0
animation.seek(lerpf(0, duration, 1 - (brightness / 255.0)), true)
else:
animation.speed_scale = 1
animation.play("light")
target_color = color_off.lerp(color if color_supported else color_on, brightness / 255.0)
icon_color.value = target_color
tween.tween_property(lightbulb, "material_override:albedo_color", target_color, 0.3)
func _on_click(event):
if event.target == self:
@ -118,4 +131,4 @@ func _on_click(event):
attributes["brightness"] = int(brightness)
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/functions/movable.gd" id="4_4sfxb"]
@ -12,43 +12,6 @@
[sub_resource type="SphereShape3D" id="SphereShape3D_ukj14"]
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"]
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
height = 0.005
[node name="Light" type="StaticBody3D" groups=["entity"]]
[node name="Light" type="StaticBody3D"]
collision_mask = 0
script = ExtResource("1_ykxy3")
@ -80,26 +43,21 @@ script = ExtResource("5_oh4jg")
[node name="Movable" type="Node" parent="."]
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)
material_override = ExtResource("5_50gph")
[node name="CSGSphere3D" type="CSGSphere3D" parent="CSGCombiner3D"]
[node name="CSGSphere3D" type="CSGSphere3D" parent="Lightbulb"]
radius = 0.05
radial_segments = 36
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)
radius = 0.02
height = 0.03
sides = 36
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
libraries = {
"": SubResource("AnimationLibrary_8a76q")
}
[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)
max = 100.0

View File

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

View File

@ -9,6 +9,8 @@ const Entity = preload ("../entity.gd")
func _ready():
super()
icon.value = "finance"
label.text = entity_id
if HomeApi.has_connected() == false:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,7 +7,6 @@ const Entity = preload("../entity.gd")
# Called when the node enters the scene tree for the first time.
func _ready():
super()
var stateInfo = await HomeApi.get_state(entity_id)
if stateInfo == null:
return
@ -17,13 +16,16 @@ func _ready():
else:
sprite.set_frame(1)
icon.value = "toggle_" + stateInfo["state"]
await HomeApi.watch_state(entity_id, func(new_state):
if new_state["state"] == "on":
sprite.set_frame(0)
else:
sprite.set_frame(1)
)
icon.value="toggle_" + new_state["state"]
)
func _on_click(event):
HomeApi.set_state(entity_id, "off" if sprite.get_frame() == 0 else "on")

View File

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

View File

@ -40,7 +40,6 @@ func _ready():
_emit_action(name, false, true)
)
remove_child(menu)
remove_child(keyboard)
EventSystem.on_action_down.connect(func(action):
@ -81,13 +80,7 @@ func create_voice_assistant():
)
func toggle_menu():
if menu.show_menu == false:
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)
menu.show_menu.value = !menu.show_menu.value
func _emit_action(name: String, value, right_controller: bool=true):
var event = EventAction.new()
@ -126,14 +119,6 @@ func _input(event):
if event is InputEventKey and Input.is_key_pressed(KEY_M):
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):
var x = 0
var y = 0

View File

@ -1,5 +1,7 @@
extends XRController3D
const Entity = preload ("res://content/entities/entity.gd")
@onready var area = $trash_bin/Area3D
@onready var trash_bin = $trash_bin
@onready var animation = $AnimationPlayer
@ -35,14 +37,14 @@ func _ready():
trash_bin_visible = false
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):
if !trash_bin_visible:
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):
to_delete.append(event.target)
trash_bin_large=true

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 editing_room: RoomType = null
var loaded = R.state(false)
func _ready():
Store.house.on_loaded.connect(func():
@ -19,6 +20,7 @@ func _ready():
)
func update_house():
loaded.value = false
for old_room in get_rooms(0):
old_room.queue_free()
await old_room.tree_exited
@ -46,6 +48,8 @@ func update_house():
entity_instance.global_position = entity.position
entity_instance.global_rotation = entity.rotation
loaded.value = true
func create_room(room_name: String, level: int) -> RoomType:
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 wall_material = preload ("./mini_wall.tres")
const humidity_gradient = preload ("./humid_gradient.tres")
const temperature_gradient = preload ("./temp_gradient.tres")
@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 toggle_heatmap = $Body/HeatmapButton
@onready var entity_select = $Body/EntitySelect
enum HeatmapType {
NONE = 0,
@ -75,12 +76,15 @@ func _ready():
if small.value:
var aabb=House.body.get_level_aabb(0)
var height=aabb.size.y
aabb.position.y=- 0.03
aabb.size.y=0.06
var center=aabb.position + aabb.size / 2
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_position=camera.global_position
@ -92,10 +96,10 @@ func _ready():
var target_position=camera_position + camera_direction.normalized() * 0.2
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)
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, "quaternion", Quaternion.IDENTITY, 0.5)
)
@ -105,8 +109,7 @@ func _ready():
var show_map=heatmap_type.value != HeatmapType.NONE
var show_small=small.value
for child in model.get_children():
child.visible=show_map||show_small
model.visible=show_map||show_small
)
# 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/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"]
@ -15,5 +16,15 @@ shape = SubResource("BoxShape3D_bckw3")
[node name="Movable" type="Node" parent="Body"]
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
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 = [{
"aabb": AABB(-0.000587015, -0.000596339, 0.0005, 0.501171, 0.301189, 1e-05),
"format": 34359742465,
@ -43,7 +43,7 @@ script = ExtResource("1_n7fu8")
[node name="Line" type="MeshInstance3D" parent="."]
material_override = SubResource("StandardMaterial3D_20gpn")
mesh = SubResource("ArrayMesh_raxtd")
mesh = SubResource("ArrayMesh_25da5")
[node name="Plane" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.25, 0.15, -0.001)

View File

@ -4,18 +4,31 @@ const Notification = preload("res://content/ui/components/notification/notificat
@onready var animation_player = $AnimationPlayer
@onready var notify_place = $AnimationContainer/NotifyPlace
@onready var main = $"/root/Main"
var show_menu := false:
set(value):
show_menu = value
if value:
var show_menu = R.state(false)
func _ready():
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")
AudioPlayer.play_effect("open_menu")
else:
animation_player.play("hide_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):
var notification_node=Notification.instantiate()
notification_node.text=event.message
@ -26,3 +39,11 @@ func _ready():
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"]
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"]
material = SubResource("StandardMaterial3D_ti5t2")
material = SubResource("StandardMaterial3D_01s1g")
size = Vector3(0.3, 0.01, 0.3)
[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.
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 VoiceAssistant = preload ("res://lib/home_apis/voice_handler.gd")
@ -18,6 +19,8 @@ const methods = [
"watch_state"
]
var groups = EntityGroups.new()
## Emitted when the connection to the home automation system is established
signal on_connect()
@ -86,16 +89,37 @@ func get_device(id: String):
## Returns the current state of an entity
func get_state(entity: String):
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)
## Updates the state of the entity and returns the resulting state
func set_state(entity: String, state: Variant, attributes: Dictionary={}):
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)
## 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")
var group = groups.get_group(entity)
if group != null:
api.watch_state(group[0], callback)
return api.watch_state(entity, callback)
## 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:
return null
if groups.is_group(entity_id):
return null
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.", "")]