From 781586e5d8e8652e6dcbf7ea437c51053af6a156 Mon Sep 17 00:00:00 2001 From: Peter Hajas Date: Sun, 8 May 2022 00:24:12 -0600 Subject: [PATCH] flash rooms when things change --- script.js | 71 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 8 deletions(-) diff --git a/script.js b/script.js index 15cf14a..f749ca9 100644 --- a/script.js +++ b/script.js @@ -9,12 +9,14 @@ homeContainer.add(home) var areaNames = [ ] +var areasWithEntitiesToUpdate = { } + const renderer = new THREE.WebGLRenderer() renderer.setSize( window.innerWidth, window.innerHeight ) document.body.appendChild( renderer.domElement ) const light = new THREE.AmbientLight(0xFFAAAA, 1) -// light.position.z = 100 +light.position.z = 100 scene.add(light) scene.background = new THREE.Color("white") @@ -27,8 +29,44 @@ home.rotation.x = Math.PI // Rotate container a bit for comfort homeContainer.rotation.x = 0.6 * (-Math.PI / 2) +// Returns the first child (or container) whose name matches +function childWithName(container, name) { + if (container.userData.name == name) { + return container; + } + for (var child of container.children) { + let childMatches = childWithName(child, name) + if (childMatches != null) { + return childMatches + } + } + return null +} + function animate() { requestAnimationFrame( animate ) + TWEEN.update() + + var areasToUpdate = new Set() + for (var area of Object.keys(areasWithEntitiesToUpdate)) { + let updatedEntities = areasWithEntitiesToUpdate[area] + if (updatedEntities.length > 0) { + areasToUpdate.add(area) + } + } + for (var area of areasToUpdate) { + let areaContainer = childWithName(scene, area) + let box = childWithName(areaContainer, "box") + + let fadeIn = new TWEEN.Tween(box.material) + .to( { opacity: 1.0 }, 1000) + + let fadeOut = new TWEEN.Tween(box.material) + .to( { opacity: 0.1 }, 1000) + + fadeIn.chain(fadeOut) + fadeIn.start() + } homeContainer.rotation.z += 0.005 @@ -62,11 +100,14 @@ function createTextMesh(text, colorName) { return mesh } +var lastUpdateTime = new Date() function updateWithHAData(data) { // `data` is an array of entities. loop through and group by area var areasToEntities = { } + var areasToUpdatedEntities = { } for (var area of areaNames) { areasToEntities[area] = new Array() + areasToUpdatedEntities[area] = new Array() } let sortedAreaNames = areaNames @@ -88,10 +129,19 @@ function updateWithHAData(data) { let areaEntities = areasToEntities[area] areaEntities.push(entity) areasToEntities[area] = areaEntities - break + + let lastUpdate = new Date(entity.last_changed) + if (lastUpdate > lastUpdateTime) { + let areaUpdatedEntities = areasToUpdatedEntities[area] + areaUpdatedEntities.push(entity) + areasToUpdatedEntities[area] = areaUpdatedEntities + } } } } + + lastUpdateTime = new Date() + areasWithEntitiesToUpdate = areasToUpdatedEntities } async function loadHAData() { @@ -102,6 +152,10 @@ async function loadHAData() { }) .then(json => { updateWithHAData(json) + new Promise(resolve => setTimeout(resolve, 250)) + .then(_ => { + loadHAData() + }) }) } @@ -127,25 +181,26 @@ function configureScene(data) { for (var room of data.rooms) { areaNames.push(room.name) let roomContainer = new THREE.Group() - roomContainer.userData = room.name + roomContainer.userData.name = room.name let roomGeo = new THREE.BoxGeometry(room.w, room.h, room.d) let roomColor = new THREE.Color(room.color) let roomBoxMaterial = new THREE.MeshPhysicalMaterial({ color: roomColor }) roomBoxMaterial.transparent = true - roomBoxMaterial.opacity = 0.3 + roomBoxMaterial.opacity = 0.1 let roomMesh = new THREE.Mesh(roomGeo, roomBoxMaterial) - roomMesh.userData = "box" + roomMesh.userData.name = "box" roomContainer.add(roomMesh) let roomEdgesGeo = new THREE.EdgesGeometry(roomGeo) let roomLinesMaterial = new THREE.LineBasicMaterial({ color: roomColor }) + roomLinesMaterial.linewidth = 3 let roomLines = new THREE.LineSegments(roomEdgesGeo, roomLinesMaterial) - roomLines.userData = "lines" + roomLines.userData.name = "lines" roomContainer.add(roomLines) - let roomLabel = createTextMesh("test", "red") - roomLabel.userData = "label" + let roomLabel = createTextMesh("A test or something", "red") + roomLabel.userData.name = "label" roomContainer.add(roomLabel) setPosition(roomContainer, room.x, room.y, room.z || 0, room.w, room.h, room.d)