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]) || 115200 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() { console.log('opening ', tty) scon = new osc.SerialPort({ devicePath: tty, bitrate: baudrate, 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.close() } }) scon.on('close', e => { console.warn('serial connection closed, restarting in 1 second') }) // Arduino OSC gre v web scon.on('message', msg => { // Debug incoming osc if (DEBUG) { console.log('osc msg', msg) } sendAll(msg, null, null, osclients) }) if (scon._closeCode) { scon = null setTimeout(openSerial, 1000) } } if (tty) { openSerial(baudrate) } 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 }) // Relay multicast to websockets // @TODO still sends to supercollider? Do we need two sockets? var dgram = require('dgram'); var sss = dgram.createSocket('udp4'); sss.on('listening', () => { sss.addMembership('224.0.1.9'); }) sss.bind(6696, '224.0.1.9'); const scudp = new osc.UDPPort({ remotePort: 6698, metadata: true, socket: sss }) scudp.on('open', () => { console.log("UDP to OSC open") }) scudp.on('message', (msg) => { console.log('got UDP msg', msg); osclients.forEach( client => { if (client) { //console.log("sending", msg, info) client.send(msg) } }) }) 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) => { // 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) })