2024-01-27 16:13:43 +02:00
|
|
|
extends Entity
|
|
|
|
|
2024-04-17 17:49:58 +03:00
|
|
|
const Entity = preload ("../entity.gd")
|
2023-12-10 00:47:17 +02:00
|
|
|
|
|
|
|
@export var view_width = 0.15
|
|
|
|
|
|
|
|
@onready var view = $View
|
|
|
|
@onready var http_request = $HTTPRequest
|
2023-12-10 02:48:39 +02:00
|
|
|
@onready var mesh = $MeshInstance3D
|
2024-05-10 02:00:31 +03:00
|
|
|
@onready var refresh_timer = $RefreshTimer
|
2024-05-27 13:35:43 +03:00
|
|
|
@onready var settings = $Settings
|
2024-05-10 02:00:31 +03:00
|
|
|
|
|
|
|
var cam_active = R.state(false)
|
|
|
|
var cam_fps = R.state(10)
|
2023-12-10 00:47:17 +02:00
|
|
|
|
|
|
|
# Called when the node enters the scene tree for the first time.
|
|
|
|
func _ready():
|
2024-01-27 16:13:43 +02:00
|
|
|
super()
|
|
|
|
|
2024-05-10 02:00:31 +03:00
|
|
|
R.effect(func(_arg):
|
|
|
|
refresh_timer.wait_time=1.0 / cam_fps.value
|
|
|
|
)
|
|
|
|
|
2024-05-27 13:35:43 +03:00
|
|
|
remove_child(settings)
|
|
|
|
|
|
|
|
R.effect(func(_arg):
|
|
|
|
if show_settings.value:
|
|
|
|
add_child(settings)
|
|
|
|
elif settings.is_inside_tree():
|
|
|
|
remove_child(settings)
|
|
|
|
camera_follower.reset()
|
|
|
|
App.house.save_all_entities()
|
|
|
|
)
|
|
|
|
|
2024-05-10 02:00:31 +03:00
|
|
|
R.effect(func(_arg):
|
|
|
|
if cam_active.value:
|
|
|
|
refresh_timer.start()
|
|
|
|
else:
|
|
|
|
refresh_timer.stop()
|
|
|
|
)
|
|
|
|
|
2024-04-17 17:49:58 +03:00
|
|
|
icon.value = "photo_camera"
|
|
|
|
|
2023-12-10 00:47:17 +02:00
|
|
|
var stateInfo = await HomeApi.get_state(entity_id)
|
|
|
|
|
|
|
|
set_state(stateInfo)
|
|
|
|
|
|
|
|
await HomeApi.watch_state(entity_id, func(new_state):
|
|
|
|
set_state(new_state)
|
|
|
|
)
|
|
|
|
|
|
|
|
func set_state(stateInfo):
|
|
|
|
if stateInfo == null:
|
|
|
|
view.texture = null
|
2023-12-10 02:48:39 +02:00
|
|
|
mesh.visible = true
|
2023-12-10 00:47:17 +02:00
|
|
|
return
|
|
|
|
|
|
|
|
var state = stateInfo["state"]
|
|
|
|
|
|
|
|
if state == "unavailable":
|
|
|
|
view.texture = null
|
2023-12-10 02:48:39 +02:00
|
|
|
mesh.visible = true
|
2023-12-10 00:47:17 +02:00
|
|
|
return
|
|
|
|
|
|
|
|
if stateInfo["attributes"].has("entity_picture"):
|
2024-05-10 02:00:31 +03:00
|
|
|
var url = stateInfo["attributes"]["entity_picture"]
|
|
|
|
load_image(url)
|
|
|
|
refresh_timer.timeout.disconnect(load_image.bind(url))
|
|
|
|
refresh_timer.timeout.connect(load_image.bind(url))
|
2023-12-10 00:47:17 +02:00
|
|
|
|
|
|
|
func load_image(url: String):
|
|
|
|
http_request.request("http://192.168.33.33:8123" + url)
|
|
|
|
|
|
|
|
var result = await http_request.request_completed
|
|
|
|
|
|
|
|
if result[0] != HTTPRequest.RESULT_SUCCESS:
|
|
|
|
print("Error loading image: ", result[0], " ", result[1])
|
|
|
|
return
|
|
|
|
|
2024-05-10 02:00:31 +03:00
|
|
|
var headers = Array(result[2]).reduce(func(acc, header):
|
|
|
|
var pair=header.split(":")
|
|
|
|
acc[pair[0]]=pair[1].trim_prefix(" ").trim_suffix(" ")
|
|
|
|
return acc
|
|
|
|
, {})
|
2023-12-10 00:47:17 +02:00
|
|
|
|
2024-05-10 02:00:31 +03:00
|
|
|
var content_type = headers["Content-Type"] if headers.has("Content-Type") else "image/png"
|
|
|
|
|
|
|
|
var image = Image.new()
|
|
|
|
var error
|
|
|
|
|
|
|
|
match content_type:
|
|
|
|
"image/png":
|
|
|
|
error = image.load_png_from_buffer(result[3])
|
|
|
|
"image/jpeg":
|
|
|
|
error = image.load_jpg_from_buffer(result[3])
|
|
|
|
"image/gif":
|
|
|
|
error = image.load_gif_from_buffer(result[3])
|
|
|
|
"image/bmp":
|
|
|
|
error = image.load_bmp_from_buffer(result[3])
|
|
|
|
"image/webp":
|
|
|
|
error = image.load_webp_from_buffer(result[3])
|
|
|
|
_:
|
|
|
|
print("Unsupported content type: ", content_type, " for image: ", url)
|
|
|
|
cam_active.value = false
|
|
|
|
return
|
2023-12-10 00:47:17 +02:00
|
|
|
|
|
|
|
if error != OK:
|
|
|
|
print("Error loading image: ", error)
|
|
|
|
return
|
|
|
|
|
2024-05-10 02:00:31 +03:00
|
|
|
var pixel_size = view_width / image.get_size().x
|
|
|
|
|
2023-12-10 00:47:17 +02:00
|
|
|
var texture = ImageTexture.create_from_image(image)
|
|
|
|
view.texture = texture
|
|
|
|
view.pixel_size = pixel_size
|
2024-05-27 18:22:20 +03:00
|
|
|
mesh.visible = false
|
|
|
|
|
|
|
|
func get_options():
|
|
|
|
return {
|
|
|
|
"cam_active": cam_active.value,
|
|
|
|
"cam_fps": cam_fps.value,
|
|
|
|
}
|
|
|
|
|
|
|
|
func set_options(options):
|
2024-05-27 19:16:45 +03:00
|
|
|
if options.has("cam_active"): cam_active.value = options["cam_active"]
|
|
|
|
if options.has("cam_fps"): cam_fps.value = options["cam_fps"]
|