hanze/muizenval

server/static/trap.js in master
Repositories | Summary | Log | Files

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: '&copy; <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();