From e0257071e725b62bf42acfdca0edd2fb8a914532 Mon Sep 17 00:00:00 2001 From: skelbon Date: Sun, 7 Jul 2024 15:52:06 +0100 Subject: [PATCH] linked up the blitzortung ws --- index.html | 4 +- src/blitz.js | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/script.js | 59 ++++++++++++--------- styles.css | 4 +- 4 files changed, 182 insertions(+), 27 deletions(-) create mode 100644 src/blitz.js diff --git a/index.html b/index.html index 31ff11b..0664941 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ - Vertical Line Animation + Mishka Henner - Conductor @@ -17,6 +17,6 @@ id="time-indicator" > - + diff --git a/src/blitz.js b/src/blitz.js new file mode 100644 index 0000000..4f45895 --- /dev/null +++ b/src/blitz.js @@ -0,0 +1,142 @@ +class EventEmitter { + constructor() { + this.events = {}; + } + + on(event, listener) { + if (!this.events[event]) { + this.events[event] = []; + } + this.events[event].push(listener); + } + + emit(event, ...args) { + if (this.events[event]) { + this.events[event].forEach(listener => listener(...args)); + } + } + + removeAllListeners() { + this.events = {}; + } +} + +// Convert Node.js module system to ES6 module system +export class NotConnectedError extends Error { + constructor(client) { + super("Client not connected"); + this.client = client; + } +} + +export const Polarity = { + Negative: 0, + Positive: 1, +}; + +export const Region = { + Unknown: 0, + Europe: 1, + Oceania: 2, + NorthAmerica: 3, + Asia: 4, + SouthAmerica: 5, +}; + +export class Client extends EventEmitter { + constructor(socketFactory) { + super(); + this.socketFactory = socketFactory; + } + + getSocket() { + return this.socket; + } + + connect(url = this.generateRandomConnectionUrl()) { + const socket = (this.socket = this.socketFactory.make(url)); + socket.onmessage = (event) => { + const rawData = this.decode(event.data); + + this.emit("data", this.buildStrikeData(JSON.parse(rawData))); + }; + socket.onopen = () => { + this.sendJSON({ a: 111 }); + this.emit("connect", socket); + }; + socket.onerror = (err) => this.emit("error", err); + } + + close() { + if (!this.socket) { + throw new NotConnectedError(this); + } + this.socket.close(); + this.removeAllListeners(); + } + + processRawLocation(location) { + return { + latitude: location.lat, + longitude: location.lon, + altitude: location.alt, + }; + } + + buildStrikeData(strike) { + return { + location: this.processRawLocation(strike), + deviation: strike.mds, + delay: strike.delay, + time: new Date(Math.floor(strike.time / 1e6)), + detectors: strike.sig.map((rawDec) => ({ + id: rawDec.sta, + location: this.processRawLocation(rawDec), + status: rawDec.status, + delay: rawDec.time, + })), + polarity: strike.pol > 0 ? Polarity.Positive : Polarity.Negative, + maxDeviation: strike.mds, + maxCircularGap: strike.mcg, + region: 1 <= strike.region && strike.region <= 5 ? strike.region : Region.Unknown, + }; + } + + decode(b) { + let a, + e = {}, + d = b.split(""), + c = d[0], + f = c, + g = [c], + h = 256, + o = h; + + for (let i = 1; i < d.length; i++) { + let charCode = d[i].charCodeAt(0); + a = h > charCode ? d[i] : e[charCode] ? e[charCode] : f + c; + g.push(a); + c = a.charAt(0); + e[o] = f + c; + o++; + f = a; + } + + return g.join(""); + } + + sendJSON(data) { + this.socket.send(JSON.stringify(data)); + } + + generateRandomConnectionUrl() { + const knownServerIds = [1, 7, 8]; + return `wss://ws${knownServerIds[Math.floor(Math.random() * knownServerIds.length)]}.blitzortung.org:443/`; + } +} + +export class BrowserSocketFactory { + make(url) { + return new WebSocket(url); + } +} diff --git a/src/script.js b/src/script.js index 4600ddb..0fe3e69 100644 --- a/src/script.js +++ b/src/script.js @@ -1,4 +1,10 @@ +import { Client, BrowserSocketFactory } from './blitz.js'; + document.addEventListener('DOMContentLoaded', () => { + + const socketFactory = new BrowserSocketFactory(); + const client = new Client(socketFactory); + const svgFiles = [ { fileName: 'Gong.svg', yPos: '20%' }, { fileName: 'Orchestral Bass.svg', yPos: '10%' }, @@ -48,32 +54,37 @@ document.addEventListener('DOMContentLoaded', () => { }); }); - document.addEventListener('click', () => { + client.on('data', (strike) => { - const randomStaveNumber = Math.floor(Math.random() * numStaves + 1); - const randomFileNumber = Math.floor(Math.random() * numFiles + 1); - const rect = timeIndicator.getBoundingClientRect(); - const sheetLeft = sheetWindow.getBoundingClientRect().left; - const xPosition = rect.left + window.scrollX - sheetLeft; + if (strike.region > 1 ){ - console.log(`${svgFiles[randomStaveNumber].fileName}`); - - const newObject = document.createElement('div'); - newObject.classList.add('event-icon'); - newObject.style.position = 'absolute'; - newObject.style.left = `${xPosition}px`; - newObject.style.top = `${svgFiles[randomFileNumber].yPos}`; - const eventIcon = document.createElement('object'); - eventIcon.type = 'image/svg+xml'; - eventIcon.data = `assets/svg/${svgFiles[randomFileNumber].fileName}`; - eventIcon.style.width = '35px'; - eventIcon.style.height = '35px'; - // eventIcon.style.backgroundColor = 'red'; - - newObject.appendChild(eventIcon); - - const staveWrapper = document.getElementById(`stave-wrapper-${randomStaveNumber}`); - staveWrapper.appendChild(newObject); + const randomStaveNumber = Math.floor(Math.random() * numStaves + 1); + const randomFileNumber = Math.floor(Math.random() * numFiles + 1); + const rect = timeIndicator.getBoundingClientRect(); + const sheetLeft = sheetWindow.getBoundingClientRect().left; + const xPosition = rect.left + window.scrollX - sheetLeft; + + console.log(`${svgFiles[randomStaveNumber].fileName}`); + + const newObject = document.createElement('div'); + newObject.classList.add('event-icon'); + newObject.style.position = 'absolute'; + newObject.style.left = `${xPosition}px`; + newObject.style.top = `${svgFiles[randomFileNumber].yPos}`; + const eventIcon = document.createElement('object'); + eventIcon.type = 'image/svg+xml'; + eventIcon.data = `assets/svg/${svgFiles[randomFileNumber].fileName}`; + eventIcon.style.width = '35px'; + eventIcon.style.height = '35px'; + // eventIcon.style.backgroundColor = 'red'; + + newObject.appendChild(eventIcon); + + const staveWrapper = document.getElementById(`stave-wrapper-${randomStaveNumber}`); + staveWrapper.appendChild(newObject); + } }); + client.connect(); + }) \ No newline at end of file diff --git a/styles.css b/styles.css index fb2159a..7a57c41 100644 --- a/styles.css +++ b/styles.css @@ -19,7 +19,9 @@ body { } -.title { +.title { + align-content: center; + color: white; height: 20vh; position: relative; }