1<!-- 2Copyright 2022 Google LLC 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 https://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15--> 16 17<link rel="preconnect" href="https://fonts.googleapis.com" /> 18<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> 19<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;700&display=swap" rel="stylesheet" /> 20 21<style> 22 body { 23 margin: 0; 24 background: var(--background); 25 font-family: "Montserrat", sans-serif; 26 } 27 28 main { 29 display: flex; 30 flex-direction: row; 31 width: 100vw; 32 height: 100vh; 33 } 34 35 #map { 36 width: var(--map-size); 37 } 38 39 #info { 40 width: 400px; 41 background: var(--sidebar-color); 42 box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23); 43 } 44 45 :root { 46 --map-size: calc(100vw - 400px); 47 --background: #cbd5e1; 48 --grid-line-color: #fbbf24; 49 --grid-background-color: #f8fafc; 50 --sidebar-color: #ea8ca8; 51 --selection-color: #f0abfc; 52 } 53</style> 54<main> 55 <pika-map id="map"></pika-map> 56 <pika-device-info id="info"></pika-device-info> 57</main> 58 59<script type="importmap"> 60 { 61 "imports": { 62 "lit": "https://cdn.jsdelivr.net/gh/lit/dist@2/core/lit-core.min.js" 63 } 64 } 65</script> 66 67<script type="module"> 68 import { LitElement, html } from "lit"; 69 70 import "./src/components/Map.js"; 71 import "./src/components/DeviceInfo.js"; 72 73 const map = document.getElementById("map"); 74 const info = document.getElementById("info"); 75 76 map.addEventListener( 77 "select", 78 (event) => (info.device = event.detail.device) 79 ); 80 81 map.addEventListener("move", () => info.update()); 82 83 function set_position({ 84 mac_address, 85 position: { x, y, z }, 86 yaw, 87 pitch, 88 roll, 89 }) { 90 const path = "/set-position/" + mac_address; 91 fetch(path, { 92 method: "POST", 93 headers: { 94 "content-type": "application/json", 95 }, 96 body: JSON.stringify({ 97 x, 98 y, 99 z, 100 yaw, 101 pitch, 102 roll, 103 }), 104 }); 105 } 106 107 map.addEventListener("end-move", (event) => { 108 set_position(event.detail.device); 109 }); 110 111 info.addEventListener("orientation-change", () => { 112 console.log("Orientation change"); 113 set_position(info.device); 114 }); 115 116 const events = new EventSource("/events"); 117 118 events.addEventListener("device-added", (event) => { 119 const data = JSON.parse(event.data); 120 console.log("Device Added", data); 121 122 const { 123 mac_address, x, y, z, yaw, pitch, roll, 124 } = data; 125 map.devices = [ 126 ...map.devices, 127 { 128 mac_address, 129 position: { x, y, z }, 130 yaw, 131 pitch, 132 roll, 133 neighbors: [], 134 }, 135 ]; 136 }); 137 138 events.addEventListener("device-removed", (event) => { 139 const data = JSON.parse(event.data); 140 console.log("Device Removed", data); 141 142 const { 143 mac_address, 144 } = data; 145 if (info.device?.mac_address === mac_address) { 146 info.device = null; 147 } 148 149 map.devices = map.devices.filter( 150 (device) => device.mac_address !== mac_address 151 ); 152 153 map.devices.forEach((device) => { 154 device.neighbors = device.neighbors.filter( 155 (neighbor) => neighbor.mac_address !== mac_address 156 ); 157 }); 158 }); 159 160 events.addEventListener("device-updated", (event) => { 161 const data = JSON.parse(event.data); 162 console.log("Position updated", data); 163 164 const { 165 mac_address, x, y, z, yaw, pitch, roll, 166 } = data; 167 168 const device = map.devices.find( 169 (device) => device.mac_address === mac_address 170 ); 171 172 device.position = { x, y, z }; 173 device.yaw = yaw; 174 device.pitch = pitch; 175 device.roll = roll; 176 177 map.update(); 178 info.update(); 179 }); 180 181 events.addEventListener("neighbor-updated", (event) => { 182 const data = JSON.parse(event.data); 183 console.log("Neighbor updated", data); 184 185 const { 186 source_mac_address, 187 destination_mac_address, 188 distance, 189 azimuth, 190 elevation, 191 } = data; 192 193 const device = map.devices.find( 194 (device) => device.mac_address === source_mac_address 195 ); 196 197 const neighbor = device.neighbors.find( 198 (device) => device.mac_address == destination_mac_address 199 ) || { mac_address: destination_mac_address }; 200 201 neighbor.distance = distance; 202 neighbor.azimuth = azimuth; 203 neighbor.elevation = elevation; 204 205 if (!device.neighbors.includes(neighbor)) device.neighbors.push(neighbor); 206 207 info.update(); 208 }); 209</script>