From 7bdce37fd3f18e2712e18c4e2c64cac69af0aca1 Mon Sep 17 00:00:00 2001 From: Jakob Stendahl Date: Sun, 19 Sep 2021 19:43:11 +0200 Subject: :boom: Introduce new UI based on svelte, and rewrite a lot of the node app and the NeoRuntime --- app.js | 339 ++++++++++++++++++----------------------------------------------- 1 file changed, 92 insertions(+), 247 deletions(-) (limited to 'app.js') diff --git a/app.js b/app.js index a4d9651..0196645 100644 --- a/app.js +++ b/app.js @@ -1,264 +1,109 @@ let fse = require("fs-extra"); -let express = require("express"); -let http = require("http"); -let app = express(); -let server = http.createServer(app); -let io = require("socket.io").listen(server); +let events = require('events'); // Firstly we set up all globals, check that the usrData dir exists, if not, we run the setup -let srcDir = __dirname; -let installDir = "/home/lux-neo/" -if (process.argv.length >= 3) { installDir = process.argv[2]; } -let dataDir = installDir + "/userdata/"; -if (!fse.existsSync(dataDir)) { throw new Error("APPDIR not found! Exiting..."); } - -// Secondly we setup the logger, and the global access to "runtimeData"; a jSON-file containing some runtimeData -global.runtimeData = new (require("./src/runtimeData"))(dataDir); // This is a global registry that everyone can access data from, it is saved as JSON to file -global.log = (logString, logLevel) => { - let broadcastEntry = (rawEntry) => { io.sockets.emit("newLogEntry", rawEntry); }; - - fse.ensureFileSync(installDir + "/logs/logger.log"); - - let CDate = new Date(); - let timeStr = CDate.getDay() + "." + - CDate.getMonth() + "." + - CDate.getFullYear() + " " + - CDate.getHours().toString() + ":" + - CDate.getMinutes().toString() + ":" + - CDate.getSeconds().toString() + ":" + - CDate.getMilliseconds().toString(); - - try { - let logFileText = `\n[${timeStr}] ${logLevel.toUpperCase()} ${logString}`; - fse.appendFile(installDir + "/logs/logger.log", logFileText, (err) => { - if (err) throw err; - }); - } catch (e) { - let logFileText = `\n[${timeStr}] ERROR ${logString}; Additionally, something went wrong with the logger.`; - fse.appendFile(installDir + "/logs/logger.log", logFileText, (err) => { - if (err) throw err; - }); - } - broadcastEntry({ - time: timeStr, - type: logLevel.toUpperCase(), - details: logString - }); -}; - -global.log("Starting Luxcena-Neo...", "event"); - -// Generate all user-folders -fse.ensureDirSync(dataDir + "/"); -fse.ensureDirSync(dataDir + "/config/"); -fse.ensureDirSync(dataDir + "/usrCode/"); -fse.ensureDirSync(dataDir + "/remoteCode/"); -// Generate config-files -if (!fse.existsSync(dataDir + "/config/versionChecker.json")) { - fse.writeFileSync(dataDir + "/config/versionChecker.json", JSON.stringify({ - "branch": "dev", - "checkInterval": 5 - }, null, 4)); -} -if (!fse.existsSync(dataDir + "/config/strip.json")) { - fse.writeFileSync(dataDir + "/config/strip.json", JSON.stringify({ - "segments": [], - "matrix": [], - "segmentConfiguration": "snake", - "led_pin": 18, - "led_freq_hz": 800000, - "led_dma": 10, - "led_invert": false, - "led_channel": 0 - }, null, 4)); +let userDir = "/home/lux-neo"; +if (process.argv.length >= 3) { userDir = process.argv[2]; } +if (!fse.existsSync(userDir + "/userdata/")) { + console.log(`CRITICAL UserDir not found '${userDir}'! Exiting...`); + process.exit(1); } +// Global path variables +global.__basedir = __dirname + ""; +global.__datadir = userDir + "/userdata"; +global.__logdir = userDir + "/logs"; +// global eventEmitter +global.__event = new events.EventEmitter(); -// All the domain-things are now setup, we are ready to run our main program... -let versionChecker = require("./src/versionChecker")(dataDir + "/config/versionChecker.json", srcDir + "/package.json"); -let neoRuntime = require("./src/neoRuntime")(dataDir); - -// Setup static assets -app.use(express.static("public/assets")); -// Serve docs -app.use("/docs", express.static("docs/_book/")); -// Gave up using webpack to compile monaco, therefore, loading the already-compiled code. Probably the slowest way possible, but so it goes. -app.use("/monaco-editor", express.static("node_modules/monaco-editor/")); -// Setup all our custom middleware -app.use(require("./src/domain/middleware") ({ - srcDir: __dirname -})); +// Secondly we setup the logger, +let logger = require("./src/logger"); +logger.info("Starting Luxcena-Neo..."); -// SocketIo -io.on("connection", (client) => { +let neoModules = {}; +neoModules.userData = require("./src/UserData")(neoModules); +neoModules.SSLCert = require("./src/SSLCert")(neoModules); +neoModules.selfUpdater = require("./src/SelfUpdater")(neoModules); +neoModules.neoRuntimeManager = require("./src/NeoRuntimeManager")(neoModules); - client.on("UpdaterStatus", () => { - client.emit("updaterStatus", global.runtimeData.get("udpaterMessage")); - }); - - client.on("GetScripts", () => { - client.emit("updatedScriptList", neoRuntime.listScripts()); - client.emit("callback", { - success: true, - error: {}, - request: "GetScripts", - scriptList: neoRuntime.listScripts() - }); - }); +neoModules.neoRuntimeManager.mode.set(neoModules.userData.config.activeMode); - client.on("SelectScript", (arguments) => { - neoRuntime.selectScript(arguments["scriptPath"]); - client.emit("callback", { - success: true, - error: {}, - request: "SelectScript" - }); - }); - - client.on("DeleteScript", (arguments) => { - neoRuntime.deleteScript(arguments["scriptPath"]); - client.emit("callback", { - success: true, - error: {}, - request: "DeleteScript" - }); - }); - - client.on("CreateEmptyScript", (arguments) => { - neoRuntime.createEmptyScript(arguments["scriptName"]); - client.emit("callback", { - success: true, - error: {}, - request: "CreateEmptyScript" - }); - }); +// All the domain-things are now setup, we are ready to run our main program... +let express = require("express"); +let https = require("https"); +let app = express(); +let server = https.createServer({ + key: fse.readFileSync(__datadir + "/config/certs/privkey.pem"), + cert: fse.readFileSync(__datadir + "/config/certs/cert.pem") + }, + app +); +let io = require("socket.io")(server); +require("./src/SocketIO")(neoModules, io); +app.use("/", express.static(__basedir + "/public")); + +server.listen(neoModules.userData.config.HTTP.port, () => { + let host = server.address().address; + let port = server.address().port; + logger.info(`Webserver now listening at *:${port}`); +}); - client.on("NeoIde_GetScript", (arguments) => { - let script = neoRuntime.getScript(arguments["scriptPath"]); - if (!script) { - client.emit("callback", { - success: false, - error: {}, - request: "NeoIde_GetScript" - }); - } else { - client.emit("callback", { - success: true, - error: {}, - request: "NeoIde_GetScript", - data: { - script: script +/** + * Get a local network address + * + * @return {string} ip address + */ +function getNetworkAddress() { + const { networkInterfaces } = require('os'); + const nets = networkInterfaces(); + const results = Object.create(null); // Or just '{}', an empty object + for (const name of Object.keys(nets)) { + for (const net of nets[name]) { + // Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses + if (net.family === 'IPv4' && !net.internal) { + if (!results[name]) { + results[name] = []; } - }); - } - }); - - client.on("NeoIde_RunScript", (arguments) => { - neoRuntime.selectScript(arguments["scriptPath"]); - }); - - client.on("NeoIde_StopScript", (arguments) => { - let res = neoRuntime.stopScript(); - if (!res.success) { - client.emit("callback", { - success: false, - error: res.error, - request: "NeoIde_StopScript" - }) - } else { - client.emit("callback", { - success: true, - error: {}, - request: "NeoIde_StopScript" - }); + results[name].push(net.address); + } } - }); - - client.on("NeoIde_GetScriptOutput", (arguments) => { - let res = neoRuntime.getScriptOutput(arguments["scriptPath"]); - if (res.success) { - client.emit("callback", { - success: true, - request: "NeoIde_GetScriptOutput", - output: res.output - }) - } else { - client.emit("callback", { - success: false, - request: "NeoIde_GetScriptOutput", - error: res.error + } + if (Object.keys(results).length > 1) { + logger.info("Multiple network addresses found!!!") + } + return results[Object.keys(results)[0]][0] +} +function tryBroadcastSelf() { + if (neoModules.userData.config.DiscoveryServer.broadcastSelf) { + const data = JSON.stringify({ + address: `https://${getNetworkAddress()}:${neoModules.userData.config.HTTP.port}`, + name: neoModules.userData.config.instanceName, + widgetaddr: "/#/widget" }) - } - }); - - client.on("NeoIde_SaveScript", (arguments) => { - neoRuntime.saveScript(arguments.script, (res) => { - if (res.success) { - client.emit("callback", { - success : true, - error: {}, - request: "NeoIde_SaveScript" - }); - } else { - client.emit("callback", { - success : false, - error: res.error, - request: "NeoIde_SaveScript" - }); + const options = { + hostname: `${neoModules.userData.config.DiscoveryServer.address}`, + port: 443, + path: "/HEY", + method: "POST", + headers: { + "Content-Type": "application/json", + "Content-length": data.length } - }); - }); - - client.on("GetLog", (arguments) => { - let filter = null; - let reqEntryN = 10; - if (arguments.filter !== undefined) { filter = arguments.filter.split(' ').map(x => x.toUpperCase()); } - if (arguments.entryN !== undefined) { reqEntryN = arguments.entryN; } - - - fse.readFile(installDir + "/logs/logger.log", 'utf8', function (err, rawLog) { - if (err) { return global.log(err, "error"); } - - let logEntries = rawLog.split('\n').filter(n => n); - let collectedEntryN = 0; - let collectedEntries = []; - for (let i = logEntries.length - 1; i >= 0; i--) { - let entry = logEntries[i]; - if (entry === "") { continue; } - - let index1 = entry.indexOf("]"); - let time = entry.substring(1, index1 - 1); - let index2 = entry.indexOf(" ", index1 + 2); - let type = entry.substring(index1 + 2, index2); - let details = entry.substring(index2); - - if ( (filter == null) || filter.includes(type) ) { - collectedEntries.push({ - time : time, - type : type.toUpperCase(), - details : details - }); - - if ((collectedEntryN++) >= reqEntryN-1) { break; } - } - + }; + let req = https.request(options, res => { + if (res.statusCode != 200) { + res.on("data", (d) => logger.warning(d.toString())); + } else { + res.on("data", (d) => logger.info(d.toString())); + logger.info("Broadcasted self") } - - client.emit("lastLogEntries", collectedEntries); }); + req.on("error", (error) => logger.warning(error.toString())) + req.write(data); + req.end(); + } +} +// setInterval(tryBroadcastSelf, 30000); +// tryBroadcastSelf(); - }); - - client.on("GetGeneralInfo", () => { - client.emit("generalInfo", neoRuntime.status()); - }) - -}); - -server.listen(8080, () => { - let host = server.address().address; - let port = server.address().port; - global.log(`Webserver now listening at *:${port}`, "success"); -}); - -//setInterval(() => { global.log("I feel FANTASTIC, an I'm still alive. Uptime: " + neoRuntime.uptime(), "debug"); }, 5000); +// setInterval(() => { logger.notice("I feel FANTASTIC, an I'm still alive. Uptime: " + process.uptime()); }, 600000); -- cgit v1.2.3 From 8fe3b246a12d409b0819b574a050b64ca96ce251 Mon Sep 17 00:00:00 2001 From: jakobst1n Date: Sun, 3 Oct 2021 18:36:12 +0200 Subject: :boom: Change paths to be in normal linux locations --- app.js | 27 +++--- bin/install.sh | 142 +++++++------------------------- bin/luxcena-neo-cli.sh | 41 ++++++++- bin/luxcena-neo.service | 6 +- bin/luxcena-neo.sh | 4 +- src/NeoRuntimeManager/RuntimeProcess.js | 4 +- src/NeoRuntimeManager/index.js | 8 +- src/SSLCert/index.js | 6 +- src/SelfUpdater/index.js | 4 +- src/SocketIO/index.js | 4 +- src/UserData/index.js | 48 +++++------ 11 files changed, 124 insertions(+), 170 deletions(-) (limited to 'app.js') diff --git a/app.js b/app.js index 0196645..30146ea 100644 --- a/app.js +++ b/app.js @@ -2,22 +2,27 @@ let fse = require("fs-extra"); let events = require('events'); // Firstly we set up all globals, check that the usrData dir exists, if not, we run the setup -let userDir = "/home/lux-neo"; -if (process.argv.length >= 3) { userDir = process.argv[2]; } -if (!fse.existsSync(userDir + "/userdata/")) { +global.__appdir = "/opt/luxcena-neo"; +global.__configdir = "/etc/luxcena-neo"; +global.__datadir = "/var/luxcena-neo"; +global.__logdir = "/var/log/luxcena-neo"; + +if ((process.argv.length >= 3) && (process.argv[2] == "dev")) { + global.__appdir = __dirname; + global.__configdir = __dirname + "/tmp/config"; + global.__datadir = __dirname + "/tmp/userdata"; + global.__logdir = __dirname + "/tmp/logs"; +} +if (!fse.existsSync(global.__datadir)) { console.log(`CRITICAL UserDir not found '${userDir}'! Exiting...`); process.exit(1); } -// Global path variables -global.__basedir = __dirname + ""; -global.__datadir = userDir + "/userdata"; -global.__logdir = userDir + "/logs"; // global eventEmitter global.__event = new events.EventEmitter(); // Secondly we setup the logger, -let logger = require("./src/logger"); +let logger = require("./src/Logger"); logger.info("Starting Luxcena-Neo..."); let neoModules = {}; @@ -33,14 +38,14 @@ let express = require("express"); let https = require("https"); let app = express(); let server = https.createServer({ - key: fse.readFileSync(__datadir + "/config/certs/privkey.pem"), - cert: fse.readFileSync(__datadir + "/config/certs/cert.pem") + key: fse.readFileSync(__configdir + "/certs/privkey.pem"), + cert: fse.readFileSync(__configdir + "/certs/cert.pem") }, app ); let io = require("socket.io")(server); require("./src/SocketIO")(neoModules, io); -app.use("/", express.static(__basedir + "/public")); +app.use("/", express.static(__appdir + "/public")); server.listen(neoModules.userData.config.HTTP.port, () => { let host = server.address().address; diff --git a/bin/install.sh b/bin/install.sh index cd4f07b..a7b811b 100755 --- a/bin/install.sh +++ b/bin/install.sh @@ -5,9 +5,6 @@ printf '%s\n' "Luxcena-neo Installer" tput sgr0 printf '\e[93m%s\e[0m\n\n' "---------------------" -LOG="/tmp/luxcena-neo.install.log" -echo "Starting Luxcena-neo installer..." > $LOG - if [ "$EUID" -ne 0 ]; then echo "You need to run this script as root." echo "Try running with 'sudo ./bin/install.sh'" @@ -16,139 +13,56 @@ fi function die() { tput setaf 1 - printf "\n\nInstall failed.\n" - printf "Check the logfile at '/tmp/lucxena-neo.install.log'.\n" - printf "Use this command to see the last 30 lines of the file;\n" - printf " tail -n 30 /tmp/luxcena-neo.install.log" + printf "\n\nInstall failed, successfull steps not reversed.\n" tput sgr0 exit 1 } -function dlgYN() { - tput sc - tput setaf 4 - printf "$1 (y/n)? " - while : - do - read -n 1 -p "" YNQuestionAnswer - if [[ $YNQuestionAnswer == "y" ]]; then - tput rc; tput el - printf ". $1?: \e[0;32mYes\e[0m\n" - tput sc - eval $2=1 # Set parameter 2 of input to the return value - break - elif [[ $YNQuestionAnswer == "n" ]]; then - tput rc; tput el - printf ". $1?: \e[0;31mNo\e[0m\n" - eval $2=0 # Set parameter 2 of input to the return value - break - fi - done -} - -# Update system -dlgYN ". Update your system" res -if [ $res -eq 1 ]; then - tput sc - apt-get -y update &>> $LOG || die - apt-get -y upgrade &>> $LOG || die - tput rc; tput ed -fi - -# Install packages -dlgYN ". Install required packages" res -if [ $res -eq 1 ]; then - tput sc - apt-get -y install nodejs scons python-dev swig &>> $LOG || die - if [ $? -eq 0 ]; then - tput rc; tput ed - printf "✓" - else - printf "\nInstall failed.\n" - exit 1 - fi -else - tput setaf 2 - printf " We are now assuming that all the following packages exists on your system:\n" - printf " nodejs scons python-dev swig\n" - tput sgr0 -fi - -# Install led-library -dlgYN ". Install jgarff's rpi_ws281x library" res -if [ $res -eq 1 ]; then - tput sc - git clone https://github.com/jgarff/rpi_ws281x /tmp/rpi_ws281x # TODO CHANGE PATH - python /tmp/rpi_ws281x/python/setup.py install # TODO CHANGE PAHT - if [ $? -eq 0 ]; then - tput rc; tput ed - printf "✓" - else - printf "\nInstall failed.\n" - exit 1 - fi -fi - -tput setaf 4 -printf ". Installing the app itself...\n" -tput sgr0 - # Create user 'luxcena-neo' tput setaf 8 -printf '%s\n' " - Creating user 'lux-neo'..." +printf '%s\n' "- Creating user 'lux-neo'..." tput sgr0 username="lux-neo" egrep "^$username" /etc/passwd >/dev/null if [ $? -eq 0 ]; then - echo "User already exists, continuing..." + echo "User already exists, continuing..." else - #pass=$(perl -e 'print crypt($ARGV[0], "password")' $password) - useradd -m $username &>> $LOG || die + useradd -m $username || die fi +usermod -a -G gpio $username +usermod -a -G spi $username # First we make our directories tput setaf 8 -printf '%s\n' " - Making app-dir (/bin/luxcena-neo)..." -tput sgr0 -userDir=$(eval echo "~$username") -#mkdir -p "$userDir/install" &>> $LOG || die -#chown $username:$username "$userDir/install" &>> $LOG || die -mkdir -p "$userDir/src" &>> $LOG || die -chown $username:$username "$userDir/src" &>> $LOG || die -mkdir -p "$userDir/userdata" &>> $LOG || die -chown $username:$username "$userDir/userdata" &>> $LOG || die - -# Third we copy the source into the correct swap-folder -tput setaf 8 -printf '%s\n' " - Copying sourceCode to app-dir..." +printf '%s\n' "- Making directories..." tput sgr0 -cp -r . "$userDir/src" &>> $LOG || die -chown -R $username:$username "$userDir/src" &>> $LOG || die - -# fourth we run npm i -tput setaf 8 -printf '%s\n' " - Running npm i..." -tput sgr0 -tput sc -export NODE_ENV=production &>> $LOG || die -runuser -l $username -c 'npm --prefix ~/src install ~/src --only=production' &>> $LOG || die # This is probably a bit overkill to have --only=... but better safe than sorry? -tput rc; tput ed +[ -d "/opt/luxcena-neo/" ] && echo "Seems like luxcena-neo is already installed, please do update instead" && die +mkdir -p "/opt/luxcena-neo" || die +chown $username:$username "/opt/luxcena-neo" || die +mkdir -p "/var/luxcena-neo" || die +chown $username:$username "/var/luxcena-neo" || die +mkdir -p "/etc/luxcena-neo" || die +chown $username:$username "/etc/luxcena-neo" || die +mkdir -p "/var/log/luxcena-neo" || die +chown $username:$username "/var/log/luxcena-neo" || die + +printf '%s' "Which branch do you want to install (default: master)? " +read BRANCH +if [ -z "$BRANCH" ]; then + BRANCH="master" +fi -# fourth we copy the cli to our bin folder +# Get source code tput setaf 8 -printf '%s\n' " - Adding cli-script..." +printf '%s\n' "- Fetch source code..." tput sgr0 -cp bin/luxcena-neo-cli.sh /usr/bin/luxcena-neo-cli.sh &>> $LOG || die -ln -sf /usr/bin/luxcena-neo-cli.sh /usr/bin/lux-neo &>> $LOG || die -tput rc; tput ed +runuser -l $username -c "git clone -b $BRANCH https://github.com/jakobst1n/luxcena-neo /opt/luxcena-neo/" || die -# Fifth we add the service files +# Install all packages, build the app, and prepare everything tput setaf 8 -printf '%s\n' " - Adding service-file to systemd..." +printf '%s\n' "- Running installer (updater) from newly fetched source code..." tput sgr0 -cp bin/luxcena-neo.service /etc/systemd/system/luxcena-neo.service &>> $LOG || die -systemctl daemon-reload &>> $LOG || die +/opt/luxcena-neo/bin/luxcena-neo-cli.sh update || die # Installation is done! printf '\n\e[5m%s\e[0m\n' "🎉Luxcena-Neo is now installed🎉" -printf 'You can now delete this folder' diff --git a/bin/luxcena-neo-cli.sh b/bin/luxcena-neo-cli.sh index defb766..b3c6553 100755 --- a/bin/luxcena-neo-cli.sh +++ b/bin/luxcena-neo-cli.sh @@ -65,14 +65,49 @@ if [ "$action" == "update" ]; then exit 1 fi + # Stop the service if it is running already systemctl stop luxcena-neo - runuser -l 'lux-neo' -c 'git -C ~/src pull' + # Go to source code directory + WDIR="/opt/luxcena-neo" + #cd "$WDIR" + + # Fetch newest changes on branch + runuser -l 'lux-neo' -c "git -C $WDIR pull" || die + + # Add node repo + curl -fsSL https://deb.nodesource.com/setup_14.x | bash - || die + + # Make sure nodejs and prerequisites is installed + apt install nodejs python-pip || die + + # Make sure we have python virtualenv installed + pip3 install virtualenv || die + + # Create and configure python virtualenv + runuser -l 'lux-neo' -c "rm -rf $WDIR/NeoRuntime/Runtime/venv" || die + runuser -l 'lux-neo' -c "virtualenv -p /usr/bin/python3 $WDIR/NeoRuntime/Runtime/venv" || die + runuser -l 'lux-neo' -c "source $WDIR/NeoRuntime/Runtime/venv/bin/activate && pip install rpi_ws281x" || die + + # Build and run all npm scripts if [ "$2" != "skipNode" ]; then - runuser -l 'lux-neo' -c 'export NODE_ENV=production; npm --prefix ~/src install ~/src --only=production' + runuser -l 'lux-neo' -c "export NODE_ENV=development; npm --prefix $WDIR install $WDIR" || die fi + ##runuser -l 'lux-neo' -c "cd $WDIR && npm run build:frontend" || die + ##runuser -l 'lux-neo' -c "cd $WDIR && npm run build:fontawesome" || die + ##runuser -l 'lux-neo' -c "cd $WDIR && npm run build:dialog-polyfill" || die + runuser -l 'lux-neo' -c "npm --prefix \"$WDIR\" run build:frontend" || die + runuser -l 'lux-neo' -c "npm --prefix \"$WDIR\" run build:fontawesome" || die + runuser -l 'lux-neo' -c "npm --prefix \"$WDIR\" run build:dialog-polyfill" || die + + + # Install new cli script + cp /opt/luxcena-neo/bin/luxcena-neo-cli.sh /usr/bin/luxcena-neo-cli.sh || die + + # Install updated systemd script + cp /opt/luxcena-neo/bin/luxcena-neo.service /etc/systemd/system/luxcena-neo.service || die + systemctl daemon-reload || die - cp /home/lux-neo/src/bin/luxcena-neo-cli.sh /usr/bin/luxcena-neo-cli.sh printf "Update complete.\n" systemctl start luxcena-neo exit 0 diff --git a/bin/luxcena-neo.service b/bin/luxcena-neo.service index efea1ad..b4115be 100644 --- a/bin/luxcena-neo.service +++ b/bin/luxcena-neo.service @@ -2,13 +2,13 @@ Description=Luxcena Neo [Service] -ExecStart=/home/lux-neo/src/bin/luxcena-neo.sh +ExecStart=/opt/luxcena-neo/bin/luxcena-neo.sh Restart=always RestartSec=10 Environment=PATH=/usr/bin:/usr/local/bin -Environment=NODE_ENV=production -WorkingDirectory=/home/lux-neo/src/ +Environment=NODE_ENV=development +WorkingDirectory=/opt/luxcena-neo/ [Install] WantedBy=multi-user.target diff --git a/bin/luxcena-neo.sh b/bin/luxcena-neo.sh index fc41f75..a861d87 100755 --- a/bin/luxcena-neo.sh +++ b/bin/luxcena-neo.sh @@ -5,5 +5,5 @@ # the server needs root as well. #runuser -l pi -c "export NODE_ENV=production; node ~/luxcena-neo-install/src/app.js" -export NODE_ENV=production -node /home/lux-neo/src/app.js >> /home/lux-neo/logs/service.log +export NODE_ENV=development +node /opt/luxcena-neo/app.js >> /var/log/luxcena-neo/service.log diff --git a/src/NeoRuntimeManager/RuntimeProcess.js b/src/NeoRuntimeManager/RuntimeProcess.js index 60f6a28..0058382 100644 --- a/src/NeoRuntimeManager/RuntimeProcess.js +++ b/src/NeoRuntimeManager/RuntimeProcess.js @@ -32,8 +32,8 @@ class RuntimeProcess { "python3", [ "-u", // This makes us able to get real-time output - `${__basedir}/NeoRuntime/Runtime/neo_runtime.py`, - `--strip-config="${__datadir}/config/strip.ini"`, + `${__appdir}/NeoRuntime/Runtime/neo_runtime.py`, + `--strip-config="${__configdir}/strip.ini"`, `--mode-path="${this.modePath}"`, `--mode-entry=script` ] diff --git a/src/NeoRuntimeManager/index.js b/src/NeoRuntimeManager/index.js index 62acb8a..e4718e4 100644 --- a/src/NeoRuntimeManager/index.js +++ b/src/NeoRuntimeManager/index.js @@ -8,7 +8,7 @@ const fs = require("fs"); const fsPromises = fs.promises; const RuntimeProcess = require("./RuntimeProcess"); -let logger = require(__basedir + "/src/logger"); +let logger = require(__appdir + "/src/Logger"); const EventEmitter = require('events'); /** @type {object} this should be a pointer to a object referencing all neoModules (see app.js) */ @@ -51,7 +51,7 @@ function isMode(path) { */ function listModes() { let modeDirs = [ - ["builtin/", fs.readdirSync(__basedir + "/NeoRuntime/builtin")], + ["builtin/", fs.readdirSync(__appdir + "/NeoRuntime/builtin")], ["remote/", fs.readdirSync(__datadir + "/remoteCode")], ["user/", fs.readdirSync(__datadir + "/userCode")] ] @@ -167,7 +167,7 @@ function getModePath(modeId) { let location = path.splice(0, 1).toString(); if (location === "user") { path = __datadir + "/userCode/" + path.join("/"); } if (location === "remote") { path = __datadir + "/remoteCode/" + path.join("/"); } - if (location === "builtin") { path = __basedir + "/NeoRuntime/builtin/" + path.join("/"); } + if (location === "builtin") { path = __appdir + "/NeoRuntime/builtin/" + path.join("/"); } return path; } @@ -306,4 +306,4 @@ module.exports = (_neoModules) => { startDebugger, stopDebugger, saveModeCode, startMode, stopMode, restartMode } -}; \ No newline at end of file +}; diff --git a/src/SSLCert/index.js b/src/SSLCert/index.js index 6dad579..d235c9b 100644 --- a/src/SSLCert/index.js +++ b/src/SSLCert/index.js @@ -7,7 +7,7 @@ * @author jakobst1n. * @since 14.16.2019 */ - let logger = require(__basedir + "/src/logger"); + let logger = require(__appdir + "/src/Logger"); const fs = require("fs"); const { execSync } = require("child_process"); @@ -20,7 +20,7 @@ var neoModules; class CertMon { constructor(configPath, certPath, httpsConfig) { - this.certPath = __datadir + "/config/certs/"; + this.certPath = __configdir + "/certs/"; let valid = this.checkValidity(); if (!valid) { @@ -141,4 +141,4 @@ module.exports = (_neoModules) => { neoModules = _neoModules; return new CertMon(); }; - \ No newline at end of file + diff --git a/src/SelfUpdater/index.js b/src/SelfUpdater/index.js index 3c5546b..5a9baa3 100644 --- a/src/SelfUpdater/index.js +++ b/src/SelfUpdater/index.js @@ -2,14 +2,14 @@ let fs = require("fs-extra"); let url = require("url"); let request = require('request'); let exec = require("child_process").exec; -let logger = require(__basedir + "/src/logger"); +let logger = require(__appdir + "/src/Logger"); let neoModules; class VersionChecker { constructor() { - this.CPackageJson = JSON.parse(fs.readFileSync(__basedir + "/package.json")); + this.CPackageJson = JSON.parse(fs.readFileSync(__appdir + "/package.json")); this.version = this.CPackageJson["version"]; this.repoLink = this.CPackageJson["repository"]["url"]; diff --git a/src/SocketIO/index.js b/src/SocketIO/index.js index fdaad56..e20460d 100644 --- a/src/SocketIO/index.js +++ b/src/SocketIO/index.js @@ -8,7 +8,7 @@ * @since 19.12.2019 */ -let logger = require(__basedir + "/src/logger"); +let logger = require(__appdir + "/src/Logger"); var exec = require('child_process').exec; var CryptoJS = require("crypto-js"); let fs = require("fs"); @@ -350,4 +350,4 @@ module.exports = (_neoModules, io) => { authorizedNamespace: createAuthorizedNamespace(io) } }; - \ No newline at end of file + diff --git a/src/UserData/index.js b/src/UserData/index.js index e5318c9..4684a75 100644 --- a/src/UserData/index.js +++ b/src/UserData/index.js @@ -6,7 +6,7 @@ * @since 19.12.2019 */ -let logger = require(__basedir + "/src/logger"); +let logger = require(__appdir + "/src/Logger"); let fse = require("fs-extra"); let ini = require('ini'); @@ -16,7 +16,7 @@ let neoModules; * This method will ensure that all required fields are in config.ini */ function ensureMainConfig() { - var config = ini.decode(fse.readFileSync(__datadir + "/config/config.ini", 'utf-8')) + var config = ini.decode(fse.readFileSync(__configdir + "/config.ini", 'utf-8')) if (config.instanceName == null) { config.instanceName = "neoStrip"; } if (config.activeMode == null) { config.activeMode = "builtin/static"; } @@ -40,14 +40,14 @@ function ensureMainConfig() { if (config.DiscoveryServer.address == null) { config.DiscoveryServer.address = "https://erj46s.deta.dev"; } if (config.DiscoveryServer.broadcastSelf == null) { config.DiscoveryServer.broadcastSelf = false; } - fse.writeFileSync(__datadir + "/config/config.ini", ini.encode(config)) + fse.writeFileSync(__configdir + "/config.ini", ini.encode(config)) } /** * This method will ensure that all required fields are in config.ini */ function ensureStripConfig() { - var config = ini.decode(fse.readFileSync(__datadir + "/config/strip.ini", 'utf-8')) + var config = ini.decode(fse.readFileSync(__configdir + "/strip.ini", 'utf-8')) if (config.DEFAULT == null) { config.DEFAULT = {}; } if (config.DEFAULT.led_pin == null) { config.DEFAULT.led_pin = 18; } @@ -58,7 +58,7 @@ function ensureStripConfig() { if (config.DEFAULT.segments == null) { config.DEFAULT.segments = ""; } if (config.DEFAULT.matrix == null) { config.DEFAULT.matrix = ""; } - fse.writeFileSync(__datadir + "/config/strip.ini", ini.encode(config)) + fse.writeFileSync(__configdir + "/strip.ini", ini.encode(config)) } /** @@ -70,24 +70,24 @@ function init() { logger.info("Ensuring all folder in UserDir exists..."); fse.ensureDirSync(__datadir + "/"); - fse.ensureDirSync(__datadir + "/config/"); - fse.ensureDirSync(__datadir + "/config/certs"); + fse.ensureDirSync(__configdir); + fse.ensureDirSync(__configdir + "/certs"); fse.ensureDirSync(__datadir + "/userCode/"); fse.ensureDirSync(__datadir + "/remoteCode/"); // Generate config-files - if (!fse.existsSync(__datadir + "/config/config.ini")) { - fse.closeSync(fse.openSync(__datadir + "/config/config.ini", 'w')); + if (!fse.existsSync(__configdir + "/config.ini")) { + fse.closeSync(fse.openSync(__configdir + "/config.ini", 'w')); } ensureMainConfig(); - if (!fse.existsSync(__datadir + "/config/strip.ini")) { - fse.closeSync(fse.openSync(__datadir + "/config/strip.ini", 'w')); + if (!fse.existsSync(__configdir + "/strip.ini")) { + fse.closeSync(fse.openSync(__configdir + "/strip.ini", 'w')); } ensureStripConfig(); - if (!fse.existsSync(__datadir + "/config/users.ini")) { - fse.writeFileSync(__datadir + "/config/users.ini", ini.encode({ + if (!fse.existsSync(__configdir + "/users.ini")) { + fse.writeFileSync(__configdir + "/users.ini", ini.encode({ "neo": { "password": "5adbc90fb4716fff62d9cf634837e22f29b011803ba29cee51f921b920fa941651737bd15d00dc72e4cbeee5e64e06ec99cc50ea917285a029797a98740cce0f", "salt": "59b6de1040f3ae3c63de984ca5d61ef46f41dc6ecead3a9d5dab69f0bb3636aa49017e179b74dbcdb407f62bc139a7d55aa78fe2bbdd5327609ea124b2fa03b1" @@ -193,11 +193,11 @@ function getFullConfig(file, addSetters=true) { * @return {object} Standardform return object */ function saveUser(username, salt, password) { - let config = ini.decode(fse.readFileSync(__datadir + "/config/users.ini", 'utf-8')) + let config = ini.decode(fse.readFileSync(__configdir + "/users.ini", 'utf-8')) config[username] = {} config[username].salt = salt config[username].password = password - fse.writeFileSync(__datadir + "/config/users.ini", ini.encode(config)) + fse.writeFileSync(__configdir + "/users.ini", ini.encode(config)) return {success: true} } @@ -207,7 +207,7 @@ function getFullConfig(file, addSetters=true) { * @return {object} with username, salt and hash properties. */ function getUser(username) { - let config = ini.decode(fse.readFileSync(__datadir + "/config/users.ini", 'utf-8')) + let config = ini.decode(fse.readFileSync(__configdir + "/users.ini", 'utf-8')) if (Object.prototype.hasOwnProperty.call(config, username)) { return {...config[username], username: username} } @@ -220,7 +220,7 @@ function getUser(username) { * @return {array} usernames */ function getUsers() { - let config = ini.decode(fse.readFileSync(__datadir + "/config/users.ini", "utf-8")); + let config = ini.decode(fse.readFileSync(__configdir + "/users.ini", "utf-8")); let users = []; for (const username of Object.keys(config)) { users.push(username); @@ -234,11 +234,11 @@ function getUsers() { * @return {object} Standardform success object. */ function deleteUser(username) { - let config = ini.decode(fse.readFileSync(__datadir + "/config/users.ini", 'utf-8')) + let config = ini.decode(fse.readFileSync(__configdir + "/users.ini", 'utf-8')) if (config.length <= 1) { return {success: false, reason: "cannot delete only user"}; } if (!Object.prototype.hasOwnProperty.call(config, username)) { return {success: false, reason: "user not found", detail: username}; } delete config[username]; - fse.writeFileSync(__datadir + "/config/users.ini", ini.encode(config)); + fse.writeFileSync(__configdir + "/users.ini", ini.encode(config)); return {success: true} } @@ -254,7 +254,7 @@ function deleteUser(username) { function createNewUserMode(name, template) { source_script = null; if ((template === "template/base") || (template === "") || (template == null)) { - source_script = __basedir + "/NeoRuntime/special/template_base/"; + source_script = __appdir + "/NeoRuntime/special/template_base/"; } else { source_script = neoModules.neoRuntimeManager.getModePath(template); } @@ -310,7 +310,7 @@ module.exports = (_neoModules) => { }, strip: { get: () => { - let c = getFullConfig(`${__datadir}/config/strip.ini`, addSetters=false); + let c = getFullConfig(`${__configdir}/strip.ini`, addSetters=false); c.DEFAULT.matrix = JSON.parse(c.DEFAULT.matrix); c.DEFAULT.segments = c.DEFAULT.segments.split(" "); return c.DEFAULT; @@ -318,13 +318,13 @@ module.exports = (_neoModules) => { set: (c) => { c.segments = c.segments.join(" "); c.matrix = JSON.stringify(c.matrix); - return saveConfig(`${__datadir}/config/strip.ini`, {DEFAULT: c}, removeSetters=false); + return saveConfig(`${__configdir}/strip.ini`, {DEFAULT: c}, removeSetters=false); }, }, - config: getFullConfig(`${__datadir}/config/config.ini`), + config: getFullConfig(`${__configdir}/config.ini`), mode: { create: createNewUserMode, delete: deleteUserMode } } -}; \ No newline at end of file +}; -- cgit v1.2.3 From fd56c70ed709d770410b8f7de49dd18db5b3537e Mon Sep 17 00:00:00 2001 From: Jakob Stendahl Date: Wed, 6 Oct 2021 17:20:54 +0200 Subject: :hammer: Fix new path definition for dev env --- app.js | 2 +- runDev.js | 2 +- src/NeoRuntimeManager/IPC.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'app.js') diff --git a/app.js b/app.js index 30146ea..715108b 100644 --- a/app.js +++ b/app.js @@ -13,7 +13,7 @@ if ((process.argv.length >= 3) && (process.argv[2] == "dev")) { global.__datadir = __dirname + "/tmp/userdata"; global.__logdir = __dirname + "/tmp/logs"; } -if (!fse.existsSync(global.__datadir)) { +if (!fse.existsSync(global.__appdir)) { console.log(`CRITICAL UserDir not found '${userDir}'! Exiting...`); process.exit(1); } diff --git a/runDev.js b/runDev.js index 6fbd702..4fafa29 100644 --- a/runDev.js +++ b/runDev.js @@ -12,7 +12,7 @@ Tail = require('tail').Tail; */ webpackLaunchCommand = ["npm", "run", "dev:frontend"]; -nodejsLaunchCommand = ["node", "app.js", `"${__dirname}/tmp"`]; +nodejsLaunchCommand = ["node", "app.js", `dev`]; mkdocsLaunchCommand = ["mkdocs", "build"]; nodejsFileWatcherPaths = [ diff --git a/src/NeoRuntimeManager/IPC.js b/src/NeoRuntimeManager/IPC.js index 817c049..d50d335 100644 --- a/src/NeoRuntimeManager/IPC.js +++ b/src/NeoRuntimeManager/IPC.js @@ -6,7 +6,7 @@ */ const net = require("net"); -let logger = require(__basedir + "/src/logger"); +let logger = require(__appdir + "/src/logger"); /** @type {int} How long wait between each reconnection attempt */ const RECONNECT_INTERVAL = 1000; -- cgit v1.2.3 From 76cd8292c5b80749ece1ab6558f3ed410a618f0d Mon Sep 17 00:00:00 2001 From: Jakob Stendahl Date: Sun, 10 Oct 2021 23:27:32 +0200 Subject: :hammer: Update some of the builtin scripts --- NeoRuntime/Runtime/luxcena_neo/strip.py | 14 ++++++++----- NeoRuntime/builtin/static/script.py | 36 +++++++-------------------------- NeoRuntime/builtin/strandtest/script.py | 2 +- app.js | 21 ++++++++++++------- 4 files changed, 31 insertions(+), 42 deletions(-) (limited to 'app.js') diff --git a/NeoRuntime/Runtime/luxcena_neo/strip.py b/NeoRuntime/Runtime/luxcena_neo/strip.py index 32380da..e8bf476 100644 --- a/NeoRuntime/Runtime/luxcena_neo/strip.py +++ b/NeoRuntime/Runtime/luxcena_neo/strip.py @@ -1,6 +1,10 @@ import json from os import path +<<<<<<< Updated upstream import rpi_ws281x as ws +======= +# from .neopixel import * +>>>>>>> Stashed changes from .matrix import Matrix, get_segment_range from .power_calc import calcCurrent @@ -20,7 +24,7 @@ class Strip: if ("color_calibration" in strip_conf) and (strip_conf["color_calibration"] != ""): self.COLOR_CALIBRATION = strip_conf["led_calibration"] else: - self.COLOR_CALIBRATION = [(1,1,1) for x in range(self.LED_COUNT)] + self.COLOR_CALIBRATION = [0xffffffff for x in range(self.LED_COUNT)] self.TMPCOLORSTATE = [0 for x in range(self.LED_COUNT)] self.COLORSTATE = [0 for x in range(self.LED_COUNT)] @@ -70,14 +74,14 @@ class Strip: except: print("Could not load saved globvars...") - + def save_globvars(self): with open(self.__globvars_path, "w") as f: f.write(json.dumps({ "power_on": self.__power_on, "brightness": self.__brightness })) - + @property def power_on(self): return self.__power_on @@ -115,7 +119,7 @@ class Strip: def show(self): """Update the display with the data from the LED buffer.""" self.COLORSTATE = self.TMPCOLORSTATE - self.strip.show() + # self.strip.show() def set_pixel_color(self, n, *color): """Set LED at position n to the provided 24-bit color value (in RGB order). @@ -152,7 +156,7 @@ class Strip: def color_from_rgb(red, green, blue, white=0): - """ + """ Convert the provided red, green, blue color to a 24-bit color value. Each color component should be a value 0-255 where 0 is the lowest intensity and 255 is the highest intensity. diff --git a/NeoRuntime/builtin/static/script.py b/NeoRuntime/builtin/static/script.py index 505ab67..8916106 100644 --- a/NeoRuntime/builtin/static/script.py +++ b/NeoRuntime/builtin/static/script.py @@ -1,39 +1,17 @@ from luxcena_neo import NeoBehaviour, ColorVariable, utils -import time class Main(NeoBehaviour): - + def declare_variables(self): self.declare(ColorVariable("color", "#fafafa", on_change=self.set_color)) - self.declare(ColorVariable("color2", "#fafafa", on_change=self.set_color)) def on_start(self): - print(f"Script started, color: {self.var.color}") - self.set_color(self.var.color) - strip.power_on = True - self.current_color = self.var.color - + print("Script started, color: {}".format(self.var.color)) + def set_color(self, value): - print(f"Color var changed: {value}") - # transition_color(self.current_color, value, 1) - -def lerp(a, b, u): - return (1 - u) * a + u * b - -def transition_color(start_color, end_color, duration): - start_color = utils.hex_to_rgb(start_color) - end_color = utils.hex_to_rgb(end_color) - interval = 10 - steps = duration / interval - step_u = 1.0 / steps - u = 0 - - while u < 1: - r = round(lerp(start_color[0], end_color[0], u)) - g = round(lerp(start_color[1], end_color[1], u)) - b = round(lerp(start_color[2], end_color[2], u)) - for i in len(strip.LED_COUNT): - strip.set_pixel_color(i, (r, g, b)) + print("Color var changed: {}".format(value)) + print(utils.detect_format_convert_color(value)) + for i in range(strip.LED_COUNT): + strip.set_pixel_color(i, value) strip.show() - time.sleep(interval / 100) \ No newline at end of file diff --git a/NeoRuntime/builtin/strandtest/script.py b/NeoRuntime/builtin/strandtest/script.py index f7d013a..6d263ab 100644 --- a/NeoRuntime/builtin/strandtest/script.py +++ b/NeoRuntime/builtin/strandtest/script.py @@ -60,7 +60,7 @@ def theaterChaseRainbow(wait_ms=50): class Main(NeoBehaviour): - def onStart(self): + def on_start(self): # Do an endless loop with some default ixel test patterns while True: colorWipe(*(255, 0, 0)) # Red wipe diff --git a/app.js b/app.js index 715108b..044f68a 100644 --- a/app.js +++ b/app.js @@ -78,16 +78,24 @@ function getNetworkAddress() { } return results[Object.keys(results)[0]][0] } +let http = require("http"); function tryBroadcastSelf() { if (neoModules.userData.config.DiscoveryServer.broadcastSelf) { + let address = neoModules.userData.config.DiscoveryServer.address; + let port = 443; + if (address.includes(":")) { + address = address.split(":"); + port = parseInt(address[1]); + address = address[0]; + } const data = JSON.stringify({ address: `https://${getNetworkAddress()}:${neoModules.userData.config.HTTP.port}`, name: neoModules.userData.config.instanceName, widgetaddr: "/#/widget" }) const options = { - hostname: `${neoModules.userData.config.DiscoveryServer.address}`, - port: 443, + hostname: address, + port: port, path: "/HEY", method: "POST", headers: { @@ -95,12 +103,11 @@ function tryBroadcastSelf() { "Content-length": data.length } }; - let req = https.request(options, res => { + let req = http.request(options, res => { if (res.statusCode != 200) { res.on("data", (d) => logger.warning(d.toString())); } else { - res.on("data", (d) => logger.info(d.toString())); - logger.info("Broadcasted self") + // res.on("data", (d) => logger.info(d.toString())); } }); req.on("error", (error) => logger.warning(error.toString())) @@ -108,7 +115,7 @@ function tryBroadcastSelf() { req.end(); } } -// setInterval(tryBroadcastSelf, 30000); -// tryBroadcastSelf(); +setInterval(tryBroadcastSelf, 30000); +tryBroadcastSelf(); // setInterval(() => { logger.notice("I feel FANTASTIC, an I'm still alive. Uptime: " + process.uptime()); }, 600000); -- cgit v1.2.3