const express = require('express') const http = require('http') const WebSocket = require('ws') const osc = require('osc') const readline = require('readline') const fs = require('fs') const port = 6676 // Vzemi iz argumenta const tty = process.argv[2] const baudrate = parseInt(process.argv[3]) const include_files = [ '/anim.js', '/control.js', '/osctl.js', '/test.js', '/node_modules/three/build/three.min.js', '/node_modules/nouislider/distribute/nouislider.min.js', '/node_modules/nouislider/distribute/nouislider.min.css', '/node_modules/osc/dist/osc-browser.js' ]; const app = express(); const server = http.Server(app); // Odprti serijski OSC link let scon = null function getArgs(parts) { console.log('split to parts', parts) switch (parts[1]) { case 'quaternion': return parts.splice(2).map((num) => ({ type: 'f', value: parseFloat(num) })) } // Default return [] } function getMsg(line) { return null } function openSerial(bitrate) { console.log('opening ', tty) if (!bitrate) { bitrate = 115200 } scon = new osc.SerialPort({ devicePath: tty, bitrate: bitrate, autoOpen: true, useSLIP: true }) scon.open() scon.on('open', e => { console.log('serial connection opened') //console.log(scon) }) scon.on('error', e => { console.error('tty error', e) /* if (e.match(/cannot open/)) { scon = null setTimeout(openSerial, 1000) } */ }) scon.on('close', e => { console.warn('serial connection closed, restarting in 1 second') setTimeout(openSerial, 1000) scon = null }) // Arduino OSC gre v web scon.on('message', msg => { console.log('osc msg', msg) // Debug incoming osc if (msg.address.indexOf('quaternion') > -1) { console.log('tty osc', msg.address, ...msg.args.map(val => Math.round(val * 1000) / 1000)) } sendAll(msg, null, null, osclients) }) if (scon._closeCode) { scon = null setTimeout(openSerial, 1000) } } function openBT() { console.log('opening bluetooth', tty) const rl = readline.createInterface({ input: fs.createReadStream(tty) }) rl.on('line', (line) => { // Convert line to byte array var enc = new TextEncoder(); // always utf-8 const arr = enc.encode(line); try { const msg = osc.readMessage(arr) console.log(msg) sendAll(msg, null, null, osclients) } catch (e) { console.warn("msg error", e) } }) } if (baudrate) { openSerial(baudrate) } else { openBT() } app.get('/', (req, res) => { res.sendFile(__dirname + '/index.html'); }); app.get('/ctl', (req, res) => { res.sendFile(__dirname + '/control.html'); }); app.get('/test', (req, res) => { res.sendFile(__dirname + '/test.html'); }); let settings = {}; app.get('/settings', function(req, res) { res.send(settings); }); include_files.map(function(file) { app.get(file, function(req, res){ res.sendFile(__dirname + file); }); }); server.listen(port, () => console.log('listening on *:' + port)) // Websocket init const wss = new WebSocket.Server({ server }) const scudp = new osc.UDPPort({ remoteAddr: '127.0.0.1', remotePort: 57120 }) scudp.on('open', () => { console.log("UDP to OSC open") }) scudp.open() const sendAll = (msg, info, oscWS, osclients) => { osclients.forEach( client => { if (client && oscWS != client) { //console.log("sending", msg, info) client.send(msg) } }) if (scudp) { scudp.send(msg) } } const osclients = [] wss.on('connection', function (ws) { console.log('client connection', ws) const oscWS = new osc.WebSocketPort({ socket: ws, metadata: false }); // Vsi OSC sem grejo naprej na kliente OSC oscWS.on('packet', (packet, info) => { //console.log('got msg', msg) // Broadcast adjust msg const [address, args] = packet sendAll({ address, args}, info, oscWS, osclients) }) oscWS.on('error', error => { console.warn('Ignoring invalid OSC') console.warn(error) }) osclients.push(oscWS) })