<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;700&display=swap"
rel="stylesheet"
/>
<style>
body {
margin: 0;
background: var(--background);
font-family: "Montserrat", sans-serif;
}
main {
display: flex;
flex-direction: row;
width: 100vw;
height: 100vh;
}
#map {
width: var(--map-size);
}
#info {
width: 400px;
background: var(--sidebar-color);
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
}
:root {
--map-size: calc(100vw - 400px);
--background: #cbd5e1;
--grid-line-color: #fbbf24;
--grid-background-color: #f8fafc;
--sidebar-color: #ea8ca8;
--selection-color: #f0abfc;
}
</style>
<main>
<pika-map id="map"></pika-map>
<pika-device-info id="info"></pika-device-info>
</main>
<script type="importmap">
{
"imports": {
"lit": "https://cdn.jsdelivr.net/gh/lit/dist@2/core/lit-core.min.js"
}
}
</script>
<script type="module">
import { LitElement, html } from "lit";
import "./src/components/Map.js";
import "./src/components/DeviceInfo.js";
const map = document.getElementById("map");
const info = document.getElementById("info");
map.addEventListener(
"select",
(event) => (info.device = event.detail.device)
);
map.addEventListener("move", () => info.update());
function set_position({
mac_address,
position: { x, y, z },
yaw,
pitch,
roll,
}) {
const path = "/set-position/" + mac_address;
fetch(path, {
method: "POST",
headers: {
"content-type": "application/json",
},
body: JSON.stringify({
x,
y,
z,
yaw,
pitch,
roll,
}),
});
}
map.addEventListener("end-move", (event) => {
set_position(event.detail.device);
});
info.addEventListener("orientation-change", () => {
console.log("Orientation change");
set_position(info.device);
});
const events = new EventSource("/events");
events.addEventListener("device-added", (event) => {
const data = JSON.parse(event.data);
console.log("Device Added", data);
const {
mac_address, x, y, z, yaw, pitch, roll,
} = data;
map.devices = [
...map.devices,
{
mac_address,
position: { x, y, z },
yaw,
pitch,
roll,
neighbors: [],
},
];
});
events.addEventListener("device-removed", (event) => {
const data = JSON.parse(event.data);
console.log("Device Removed", data);
const {
mac_address,
} = data;
if (info.device?.mac_address === mac_address) {
info.device = null;
}
map.devices = map.devices.filter(
(device) => device.mac_address !== mac_address
);
map.devices.forEach((device) => {
device.neighbors = device.neighbors.filter(
(neighbor) => neighbor.mac_address !== mac_address
);
});
});
events.addEventListener("device-updated", (event) => {
const data = JSON.parse(event.data);
console.log("Position updated", data);
const {
mac_address, x, y, z, yaw, pitch, roll,
} = data;
const device = map.devices.find(
(device) => device.mac_address === mac_address
);
device.position = { x, y, z };
device.yaw = yaw;
device.pitch = pitch;
device.roll = roll;
map.update();
info.update();
});
events.addEventListener("neighbor-updated", (event) => {
const data = JSON.parse(event.data);
console.log("Neighbor updated", data);
const {
source_mac_address,
destination_mac_address,
distance,
azimuth,
elevation,
} = data;
const device = map.devices.find(
(device) => device.mac_address === source_mac_address
);
const neighbor = device.neighbors.find(
(device) => device.mac_address == destination_mac_address
) || { mac_address: destination_mac_address };
neighbor.distance = distance;
neighbor.azimuth = azimuth;
neighbor.elevation = elevation;
if (!device.neighbors.includes(neighbor)) device.neighbors.push(neighbor);
info.update();
});
</script>