trap.js (6789B) download
1/*
2trap {
3 id: int
4 name: str?
5 status: str
6 offline: bool
7 locationSearch: bool
8 latitude: float?
9 longitude: float?
10 accuracy: float?
11 satellites: int?
12 activated: bool
13 owner: str
14 battery: int
15 charging: bool
16 temperature: bool
17 lastStatus: str
18 ownedDate: str
19}
20*/
21
22var map = L.map('trap-map'),
23 socket = io();
24
25let token = null,
26 remote = false,
27 traps = {},
28 markers = [];
29
30map.setView([52.283333, 5.666667], 7);
31L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
32 attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
33}).addTo(map);
34
35socket.on('trap-change', function (trap) {
36 var clone,
37 append = false;
38
39 if (traps[trap.id]) {
40 Object.assign(traps[trap.id], trap);
41
42 clone = traps[trap.id].element;
43 } else {
44 traps[trap.id] = trap;
45
46 clone = document.getElementById('trap-template').content.cloneNode(true).querySelector('article');
47 traps[trap.id].element = clone;
48 traps[trap.id].updating = false;
49 clone.id = `trap-${trap.id}`;
50 append = true;
51 }
52
53 if (!traps[trap.id].updating) {
54 var statusIcons = '',
55 statusString = '',
56 statusIcon,
57 batteryIcon,
58 tempIcon;
59
60 if (trap.offline) (statusIcon = 'moon'), (statusString += 'offline');
61 else if (trap.activated) (statusIcon = 'circle-exclamation'), (statusString += 'geactiveerd');
62 else (statusIcon = 'clock'), (statusString += 'wachtend');
63 statusIcons += `<i class='fas fa-${statusIcon}'></i>`;
64 // clone.style.background = '#bdecb6';
65 clone.style.background = '#ffffff';
66
67 if (!trap.offline) {
68 if (trap.activated) {
69 clone.style.background = '#aec6cf';
70 }
71 if (trap.charging) (batteryIcon = 'plug-circle-bolt'), (statusString += ', aan het opladen');
72 else if (trap.battery == 0) batteryIcon = 'battery-empty';
73 else if (trap.battery < 30) batteryIcon = 'battery-quarter';
74 else if (trap.battery < 55) batteryIcon = 'battery-half';
75 else if (trap.battery < 80) batteryIcon = 'battery-three-quarters';
76 else if (trap.battery < 100) batteryIcon = 'battery-full';
77 else (batteryIcon = 'plug-circle-xmark'), (statusString += ', problemen met batterij');
78 statusIcons += `<i class='fas fa-${batteryIcon}'></i>`;
79
80 if (trap.temperature > 50) (tempIcon = 'temperature-high'), (statusString += ', oververhit');
81 else if (trap.temperature < -10) (tempIcon = 'temperature-low'), (statusString += ', onderkoeld');
82 if (tempIcon) statusIcons += `<i class='fas fa-${tempIcon}'></i>`;
83
84 if (trap.locationSearching) (statusIcons += '<i class="fas fa-satellite"></i>'), (statusString += ', zoekt naar locatie');
85 } else {
86 clone.style.background = '#eeeeee';
87 }
88
89 clone.querySelector('a.update').onclick = function () {
90 var nameSpan = clone.querySelector('span.name'),
91 input = nameSpan.querySelector('input');
92 if (input) {
93 clone.querySelector('a.update').innerHTML = 'bewerken';
94 traps[trap.id].updating = false;
95 socket.emit('name', { id: trap.id, name: input.value });
96 } else {
97 nameSpan.innerHTML = `<input type="entry" value="${trap.name}" />`;
98 traps[trap.id].updating = true;
99 clone.querySelector('a.update').innerHTML = 'klaar';
100 }
101 };
102 clone.querySelector('a.delete').onclick = function () {
103 socket.emit('delete', { id: trap.id });
104 clone.remove();
105 delete traps[trap.id];
106 };
107 clone.querySelector('a.location').onclick = function () {
108 socket.emit('location-search', { id: trap.id, search: !trap.locationSearch });
109 };
110
111 clone.querySelector('span.location-button').innerHTML = trap.locationSearch ? 'locatie vastzetten' : 'locatie zoeken';
112 clone.querySelector('span.status-icons').innerHTML = statusIcons;
113 clone.querySelector('span.status').innerHTML = statusString;
114 clone.querySelector('span.name').innerHTML = trap.name;
115 clone.querySelector('span.owner').innerHTML = trap.owner;
116 clone.querySelector('span.accuracy').innerHTML = trap.accuracy;
117 clone.querySelector('span.satellites').innerHTML = trap.satellites;
118 clone.querySelector('span.temperature').innerHTML = trap.temperature;
119 clone.querySelector('span.last-status').innerHTML = trap.lastStatus;
120 clone.querySelector('span.owned-date').innerHTML = trap.ownedDate;
121 if (trap.battery < 100) {
122 clone.querySelector('p.battery').style.display = 'inherit';
123 clone.querySelector('span.battery').innerHTML = trap.battery;
124 } else {
125 clone.querySelector('p.battery').style.display = 'none';
126 }
127 if (trap.locationSearch) {
128 clone.querySelector('p.accuracy').style.display = 'inherit';
129 } else {
130 clone.querySelector('p.accuracy').style.display = 'none';
131 }
132 }
133
134 if (append) document.getElementById('trap-container').appendChild(clone);
135
136 if (trap.accuracy) {
137 if (traps[trap.id].marker) {
138 traps[trap.id].marker.setLatLng([trap.latitude, trap.longitude]);
139 } else {
140 traps[trap.id].marker = L.marker([trap.latitude, trap.longitude]).addTo(map).bindPopup(trap.name);
141 map.fitBounds(
142 Object.values(traps)
143 .filter((x) => x.accuracy)
144 .map((x) => [x.latitude, x.longitude])
145 );
146 }
147 } else if (traps[trap.id].marker) {
148 traps[trap.id].marker.remove();
149 traps[trap.id].marker = undefined;
150 }
151});
152
153socket.on('trap-remove', function (trap) {
154 if (traps[trap.id].marker) traps[trap.id].marker.remove();
155 traps[trap.id].element.remove();
156
157 delete traps[trap.id];
158});
159
160socket.on('statistics', function ({ table, months }) {
161 var chart = new CanvasJS.Chart('trap-chart', {
162 data: [
163 {
164 type: 'column',
165 dataPoints: [
166 { label: 'Januari', y: months[0] },
167 { label: 'Februari', y: months[1] },
168 { label: 'Maart', y: months[2] },
169 { label: 'April', y: months[3] },
170 { label: 'Mei', y: months[4] },
171 { label: 'Juni', y: months[5] },
172 { label: 'Juli', y: months[6] },
173 { label: 'Augustus', y: months[7] },
174 { label: 'September', y: months[8] },
175 { label: 'October', y: months[9] },
176 { label: 'November', y: months[10] },
177 { label: 'December', y: months[11] },
178 ],
179 },
180 ],
181 });
182 chart.render();
183 var tbl = document.getElementById('trap-table');
184 tbl.innerHTML =
185 '<tr><th>Muizenval</th><th>Datum</th><th></th></tr>' +
186 table.map(([id, name, date]) => `<tr><td>${name}</td><td>${date}</td><td><a href="javascript:deleteStc(${id})">verwijderen</a></td></tr>`).join('\n');
187});
188
189function deleteStc(id) {
190 socket.emit('delete-statistic', id);
191}
192
193function websocket() {
194 let ws = new WebSocket('ws://localhost:1612/');
195 ws.addEventListener('open', () => ws.send('token'));
196 ws.addEventListener('message', (evt) => (token = evt.data));
197 ws.addEventListener('close', () => {
198 if (token) {
199 socket.emit('token', token);
200 remote = true;
201 } else {
202 remote = false;
203 }
204 });
205 ws.addEventListener('error', () => {
206 token = null;
207 remote = false;
208 });
209}
210
211setInterval(websocket, 10000);
212
213websocket();