Code: Alles auswählen
[
{
"id": "0ea2818262334c44",
"type": "template",
"z": "2ab1de6847dd7ea2",
"name": "RedMatic aufräumen",
"field": "payload",
"fieldType": "msg",
"format": "markdown",
"syntax": "plain",
"template": "#!/bin/sh\ncd /usr/local/addons/redmatic/var\nsource /usr/local/addons/redmatic/home/.profile\nmkdir -m a+rwx -p /usr/local/lib/node_modules\nmkdir -m a+rwx -p /usr/local/bin\n# npm config set cache=/tmp/npm-cache\n\nrm /usr/local/addons/redmatic/etc/npmrc 2>/dev/null\n# rm /usr/local/addons/redmatic/bin/jq 2>/dev/null\n# rm /usr/local/addons/redmatic/bin/jo 2>/dev/null\nrm /usr/local/addons/redmatic/bin/deviceTypes 2>/dev/null\nrm /usr/local/addons/redmatic/bin/.nobackup 2>/dev/null\nrm /usr/local/addons/redmatic/include/.nobackup 2>/dev/null\nrm /usr/local/addons/redmatic/lib/.nobackup 2>/dev/null\nrm /usr/local/addons/redmatic/libexec/.nobackup 2>/dev/null\nrm /usr/local/addons/redmatic/share/.nobackup 2>/dev/null\nrm /usr/local/addons/redmatic/tmp/.nobackup 2>/dev/null\nrm /usr/local/addons/redmatic/var/node_modules/.nobackup 2>/dev/null\nrm /usr/local/addons/redmatic/www/.nobackup 2>/dev/null\n\nrm /usr/local/addons/redmatic/lib/pkg-repo.json 2> /dev/null\nrm /usr/local/addons/redmatic/CHANGELOG.md 2> /dev/null\nrm /usr/local/addons/redmatic/LICENSE 2> /dev/null\nrm /usr/local/addons/redmatic/README.md 2> /dev/null\n\nrm /usr/local/addons/redmatic/bin/corepack 2> /dev/null\nrm /usr/local/addons/redmatic/bin/node 2> /dev/null\nrm /usr/local/addons/redmatic/bin/npm 2> /dev/null\nrm /usr/local/addons/redmatic/bin/npx 2> /dev/null\nrm -r /usr/local/addons/redmatic/lib/node_modules/npm 2> /dev/null\nrm -r /usr/local/addons/redmatic/lib/node_modules/corepack 2> /dev/null\nrm -r /usr/local/addons/redmatic/lib/node_modules/ain2 2> /dev/null\nexit 0",
"output": "str",
"x": 480,
"y": 480,
"wires": [
[
"2d6177b5c2a97ca9"
]
]
},
{
"id": "fa72f43dd0a8948b",
"type": "template",
"z": "2ab1de6847dd7ea2",
"name": "logger.js",
"field": "payload",
"fieldType": "msg",
"format": "javascript",
"syntax": "plain",
"template": "// Henke Version 1.2\n\nvar dgram = require('dgram');\n//var iconvLite= require('iconv-lite');\n//var exec = require('child_process').exec;\n\nmodule.exports = {\n logging: {\n // console: {\n // level: \"error\",\n // metrics: false,\n // audit: false\n // },\n ain: {\n // level: 'debug',\n // metrics: false,\n // audit: false,\n handler: function (conf) {\n //console.log(\"----\");\n //console.log(conf);\n //console.log(\"----\");\n\n // Return the function that will do the actual logging\n return function (mg) {\n const levelNames = {\n 10: { s: 2, t: 'crit' }, // fatal\n 20: { s: 3, t: 'err' },\n 30: { s: 4, t: 'warn' },\n 40: { s: 6, t: 'info' },\n 50: { s: 7, t: 'debug' },\n 60: { s: 7, t: 'trace' }, // trace\n 98: { s: 7, t: 'audit' }, // audit\n 99: { s: 7, t: 'metric' } // metric\n };\n\n if (mg && typeof mg.msg != 'string') {\n mg.msg = JSON.stringify(mg.msg);\n }\n let tagStr = \"NodeRed\";\n // let b = Buffer.from(_msg.msg);\n // _msg.msg = Buffer.from(b.toString('utf8')).toString('ascii');\n // _msg.msg =iconvLite.decode(iconvLite.decode(_msg.msg , 'utf8'), 'latin1');\n if (mg.type) {\n let mName = (mg.name || mg.id);\n // mName = mName.replaceAll(/\\W/g, \"_\");\n // mName = mName.replaceAll(/[\\s><\\[\\]]/g, \"_\");\n\n let patt = new RegExp(\"[\\\\s><\\\\[\\\\]]\", \"g\");\n mName = mName.replace(patt, \"_\");\n tagStr = mg.type + '[' + mName + ']';\n }\n let patt = new RegExp(\"\\n\", \"g\");\n mg.msg = mg.msg.replace(patt, \"\");\n // _msg.msg = _msg.msg.replaceAll(/\\n/g, \"\");\n\n // const Out = 'logger -t ' + tagStr + ' -p daemon.' + levelNames[_msg.level].t + ' ' + _msg.msg;\n // exec(Out);\n // return;\n\n // Alternativ über Socket, dann die oberen 3 Zeilen auskommentieren\n // converts number to two-digit string\n function twoDigits(n) {\n return ('0' + n).slice(-2);\n }\n\n let time = new Date(mg.timestamp);\n const MONTHS = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec'\n ];\n\n // format time\n let month = MONTHS[time.getMonth()];\n let date = twoDigits(time.getDate());\n let hours = twoDigits(time.getHours());\n let minutes = twoDigits(time.getMinutes());\n let seconds = twoDigits(time.getSeconds());\n\n // format('%s %s %s:%s:%s'\n let timeStr = month + ' ' + date + ' ' + hours + \":\" + minutes + \":\" + seconds;\n // console.log(\"---> \" + _msg.level + \" \" + levelNames[_msg.level].s + \" \" + levelNames[_msg.level].t + \" \" + _msg.msg);\n\n let PRI = (1 * 8) + levelNames[mg.level].s ;\n// console.log( \"Err Level: \" + mg.level + \" \" + levelNames[mg.level].s + \" \" + mg.msg);\n\n let message = \"<\" + PRI + \">\" + timeStr + \" NodeRed\" + \" \" + tagStr + \": \" + mg.msg;\n try {\n var port = 514;\n if (mg.level < 30)\n console.log(mg.msg);\n\n var Udp = dgram.createSocket('udp4');\n const out = Buffer.from(message);\n Udp.connect(port, '127.0.0.1', (err) => {\n Udp.send(out, (err) => {\n Udp.close();\n });\n });\n\n // console.log(\"Logger connected\");\n // console.log(message);\n // console.log(JSON.stringify(msg));\n } catch (err) { console.log( \"catch: \" + err); }\n }\n }\n }\n }\n};\n",
"output": "str",
"x": 440,
"y": 220,
"wires": [
[
"21eee2220ba31f6a"
]
]
},
{
"id": "21eee2220ba31f6a",
"type": "file",
"z": "2ab1de6847dd7ea2",
"name": "lib/logger.js",
"filename": "/usr/local/addons/redmatic/lib/logger.js",
"filenameType": "str",
"appendNewline": false,
"createDir": true,
"overwriteFile": "true",
"encoding": "none",
"x": 690,
"y": 220,
"wires": [
[
"b4e4431204918796"
]
]
},
{
"id": "b4e4431204918796",
"type": "template",
"z": "2ab1de6847dd7ea2",
"name": "service.cgi",
"field": "payload",
"fieldType": "msg",
"format": "markdown",
"syntax": "plain",
"template": "# Henke Version 1.0\n#!/bin/tclsh\n\nsource ../lib/querystring.tcl\n\nputs -nonewline \"Content-Type: text/plain; charset=utf-8\\r\\n\\r\\n\"\n\nif {[info exists cmd]} {\n\n if {$cmd == \"stop\" || $cmd == \"start\" || $cmd == \"restart\"} {\n\n source ../lib/session.tcl\n\n if {[info exists sid] && [check_session $sid]} {\n catch {exec /usr/local/etc/config/rc.d/redmatic $cmd} result\n puts $result\n exit 0\n } else {\n puts {error: invalid session}\n exit 1\n }\n }\n\n # No session checks for following commands to reduce costs of periodic calls, exposed information is uncritical imho\n\n if {$cmd == \"ps\"} {\n# puts [exec ps -o vsz,rss,comm,args | grep \"node\\\\|redmatic\"]\n# Henke Anpassung an neuere Node\n puts [exec ps -o vsz,rss,comm,args | grep \"node-red\\\\|node-red\" ]\n exit 0\n }\n if {$cmd == \"cpu\"} {\n puts [exec top -b -n 1 | grep \"% node-red$\" | awk \"\\{print \\$7\\}\"]\n# puts [exec ps -o vsz,rss,comm,args | grep \"node\\\\|redmatic\" ]\n exit 0\n }\n if {$cmd == \"uptime\"} {\n puts [exec /usr/local/addons/redmatic/bin/uptime.sh]\n exit 0\n }\n}\n\nputs {error: invalid command}\nexit 1\n",
"output": "str",
"x": 970,
"y": 220,
"wires": [
[
"a0554d8f2b842c0b"
]
]
},
{
"id": "a0554d8f2b842c0b",
"type": "file",
"z": "2ab1de6847dd7ea2",
"name": "www/service.cgi",
"filename": "/usr/local/addons/redmatic/www/service.cgi",
"filenameType": "str",
"appendNewline": false,
"createDir": true,
"overwriteFile": "true",
"encoding": "none",
"x": 1180,
"y": 220,
"wires": [
[
"a0ee823d1b868b33"
]
]
},
{
"id": "3d2fc855a49dc0ab",
"type": "template",
"z": "2ab1de6847dd7ea2",
"name": "script.js",
"field": "payload",
"fieldType": "msg",
"format": "javascript",
"syntax": "plain",
"template": "// Henke Version 1.2\n$(document).ready(() => {\n const bcrypt = dcodeIO.bcrypt;\n\n const $loglevel = $('#loglevel');\n const $contextStorageDefault = $('#context-storage-default');\n const $contextStorageFilePath = $('#context-storage-file-path');\n const $contextStorageFileInterval = $('#context-storage-file-interval');\n\n const $adminauthType = $('#adminauth-type');\n const $adminauthCreds = $('#adminauth-credentials');\n const $adminauthExpiry = $('#adminauth-expiry');\n const $adminauthSessionExpiryTime = $('#adminauth-sessionExpiryTime');\n const $adminauthUser = $('#adminauth-user');\n const $adminauthPass1 = $('#adminauth-pass1');\n const $adminauthPass2 = $('#adminauth-pass2');\n const $adminauthSet = $('#adminauth-set');\n\n const $nodeauthType = $('#nodeauth-type');\n const $nodeauthCreds = $('#nodeauth-credentials');\n const $nodeauthUser = $('#nodeauth-user');\n const $nodeauthPass1 = $('#nodeauth-pass1');\n const $nodeauthPass2 = $('#nodeauth-pass2');\n const $nodeauthSet = $('#nodeauth-set');\n\n const $staticauthType = $('#staticauth-type');\n const $staticauthCreds = $('#staticauth-credentials');\n const $staticauthUser = $('#staticauth-user');\n const $staticauthPass1 = $('#staticauth-pass1');\n const $staticauthPass2 = $('#staticauth-pass2');\n const $staticauthSet = $('#staticauth-set');\n\n const $projects = $('#projects');\n const $theme = $('#theme');\n const $backup = $('#backup');\n\n const $alertSaved = $('#alert-saved');\n const $alertError = $('#alert-error');\n const $alertExec = $('#alert-exec');\n\n const $status = $('#node-red-status');\n const $memory = $('#node-red-memory');\n const $cpu = $('#node-red-cpu');\n\n $alertSaved.hide();\n $alertError.hide();\n $alertExec.hide();\n\n const $restart = $('#restart');\n const $restartSafe = $('#restartSafe');\n const $dropdownRestart = $('#dropdownRestart');\n const $start = $('#start');\n const $startSafe = $('#startSafe');\n const $dropdownStart = $('#dropdownStart');\n const $stop = $('#stop');\n\n const $linkRed = $('#link-red');\n const $linkUi = $('#link-ui');\n\n const $packageTable = $('#package-table');\n\n let config;\n\n let noderedState;\n\n const qs = location.search;\n let sid = '';\n let tmp = qs.match(/sid=(@[0-9a-zA-Z]{10}@)/);\n if (tmp) {\n sid = tmp[1];\n $('#backup').removeClass('disabled').attr('href', 'backup.cgi?sid=' + sid);\n }\n\n $('a[href=\"' + (location.hash || '#configuration') + '\"]').tab('show');\n if (location.hash === '#licenses' && !$('#licenses iframe').attr('src')) {\n $('#licenses iframe').attr('src', 'licenses.html');\n }\n\n $('a[data-toggle=\"tab\"]').on('shown.bs.tab', function (e) {\n if (history.pushState) {\n history.pushState(null, null, '#' + $(e.target).attr('href').substr(1));\n } else {\n location.hash = '#' + $(e.target).attr('href').substr(1);\n }\n if ($(e.target).attr('href') === '#licenses' && !$('#licenses iframe').attr('src')) {\n $('#licenses iframe').attr('src', 'licenses.html');\n }\n });\n\n let psTimeout;\n let psInterval = 5000;\n\n function checkUpdate() {\n $.getJSON(`update_check.cgi?cmd=versions&sid=${sid}`, (current, success) => {\n $('#redmatic-version').html('RedMatic Version ' + current.redmatic);\n $.get(`update_check.cgi?sid=${sid}`, (available, success) => {\n available = $.trim(available);\n if (available !== 'n/a' && current.redmatic !== available) {\n $('#update-link').html(`<a href=\"https://github.com/rdmtc/RedMatic/releases/latest\" target=\"_blank\">Download Version ${available}</a>`);\n $('#update-notify').show();\n }\n });\n });\n }\n\n // checkUpdate();\n\n function pkg() {\n let packages;\n $.get(`pkg.cgi?sid=${sid}&cmd=repo`, data => {\n packages = data;\n $.get(`pkg.cgi?sid=${sid}&cmd=ls`, data => {\n $('#pkg-spinner').hide();\n data.split('\\n').forEach(line => {\n const [name, currentVersion] = line.split(' ');\n if (name && packages[name]) {\n packages[name].installed = true;\n packages[name].currentVersion = currentVersion;\n }\n });\n $packageTable.html('');\n Object.keys(packages).sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())).forEach(name => {\n const installed = packages[name].installed ?\n (packages[name].version === packages[name].currentVersion ? '✅' : `⚠${packages[name].currentVersion}`) :\n ' ';\n\n let url = packages[name].homepage || (packages[name].repository && packages[name].repository.url) || packages[name].repository;\n if (url) {\n url = url.replace(/^git\\+/, '').replace(/\\.git$/, '');\n }\n\n $packageTable.append(`<tr><td><a href=\"${url}\" target=\"_blank\">${name}</a><br><span class=\"pkg-desc\">${packages[name].description || ''}</span></td><td>${packages[name].version}</td><td style=\"text-align: center;\">${installed}</td><td><button data-pkg=\"${name}\" type=\"button\" class=\"btn btn-primary btn-sm pkg-install\" ${packages[name].installed ? 'disabled' : ''}><span class=\"spinner-install spinner-border spinner-border-sm\" role=\"status\" aria-hidden=\"true\" hidden></span>\n install</button> <button data-pkg=\"${name}\" type=\"button\" class=\"btn btn-danger btn-sm pkg-remove\" ${packages[name].installed ? '' : 'disabled'}><span class=\"spinner-remove spinner-border spinner-border-sm\" role=\"status\" aria-hidden=\"true\" hidden></span>\n remove</button></td></tr>`)\n });\n $('.pkg-install').click(function () {\n $(this).attr('disabled', true);\n $(this).find('.spinner-install').removeAttr('hidden');\n $.get(`pkg.cgi?sid=${sid}&cmd=install&package=${$(this).data('pkg')}`, (data, success) => {\n $(this).find('.spinner-install').attr('hidden', true);\n if (data.includes('Done.')) {\n alert($alertExec);\n } else {\n alert($alertError);\n }\n pkg();\n });\n });\n $('.pkg-remove').click(function () {\n $(this).attr('disabled', true);\n $(this).find('.spinner-remove').removeAttr('hidden');\n $.get(`pkg.cgi?sid=${sid}&cmd=remove&package=${$(this).data('pkg')}`, (data, success) => {\n $(this).find('.spinner-remove').attr('hidden', true);\n if (data.includes('Done.')) {\n alert($alertExec);\n } else {\n alert($alertError);\n }\n pkg();\n });\n })\n });\n });\n }\n\n pkg();\n\n function refresh() {\n // checkUpdate();\n // pkg();\n }\n\n function cpu() {\n $.get(`service.cgi?sid=${sid}&cmd=cpu`, (data, success) => {\n data = $.trim(data);\n $cpu.html((data ? 'cpu ' + data + ', ' : ''));\n });\n }\n\n function ps() {\n clearTimeout(psTimeout);\n $.get(`service.cgi?sid=${sid}&cmd=ps`, (data, success) => {\n cpu();\n const lines = data.split('\\n');\n let found = false;\n lines.forEach(line => {\n if (found) {\n return;\n }\n let match;\n match = line.match(/([0-9]+[a-z]?)\\s+([0-9]+[a-z]?)\\s+node\\s+node-red/);\n // Henke - Anpassung an neuere Node Versionen\n if (!match)\n match = line.match(/([0-9]+[a-z]?)\\s+([0-9]+[a-z]?)\\s+node-red\\s+node-red/);\n if (match) {\n let [vsz, rss] = line.split(\" \");\n vsz = vsz.replace('m', 'MB').replace('g', 'GB');\n rss = rss.replace('m', 'MB').replace('g', 'GB');\n if (!vsz.endsWith('B')) {\n vsz += 'kB';\n }\n if (!rss.endsWith('B')) {\n rss += 'kB';\n }\n $('#status-spinner').hide();\n if (noderedState !== 'running') {\n $status.html('<span class=\"status-running\">running</span>');\n noderedState = 'running';\n refresh();\n $.get(`service.cgi?sid=${sid}&cmd=uptime`, (uptime, success) => {\n $status.html('<span class=\"status-running\">running</span> <span id=\"uptime\">(' + $.trim(uptime) + ')');\n });\n }\n $memory.html(`rss ${rss}, vsz ${vsz},`);\n // $memory.html(line.split(\" \"));\n\n found = true;\n $dropdownRestart.removeClass('disabled');\n $stop.removeClass('disabled');\n $linkRed.removeClass('disabled');\n $linkUi.removeClass('disabled');\n $dropdownStart.addClass('disabled');\n psInterval = 5000;\n return;\n }\n match = line.match(/([0-9]+[a-z]?)\\s+([0-9]+[a-z]?)\\s+.*red.js/);\n if (match) {\n noderedState = 'starting';\n $('#status-spinner').show();\n let [, vsz, rss] = match;\n vsz = vsz.replace('m', 'MB').replace('g', 'GB');\n rss = rss.replace('m', 'MB').replace('g', 'GB');\n if (!vsz.endsWith('B')) {\n vsz += 'kB';\n }\n if (!rss.endsWith('B')) {\n rss += 'kB';\n }\n $status.html('<span class=\"status-starting\">starting</span>');\n $memory.html(`rss ${rss}, vsz ${vsz}`);\n found = true;\n $dropdownRestart.addClass('disabled');\n $stop.addClass('disabled');\n $dropdownStart.addClass('disabled');\n $linkRed.addClass('disabled');\n $linkUi.addClass('disabled');\n psInterval = 2500;\n return;\n }\n\n /* match = line.match(/redmatic-pkg install ([^\\s]+)/);\n if (match) {\n noderedState = 'upgrading';\n $('#status-spinner').show();\n $status.html('<span class=\"status-upgrade\">Upgrading ' + match[1] + '</span>');\n $memory.html('');\n found = true;\n $dropdownRestart.addClass('disabled');\n $stop.addClass('disabled');\n $dropdownStart.addClass('disabled');\n $linkRed.addClass('disabled');\n $linkUi.addClass('disabled');\n psInterval = 5000;\n return;\n }*/\n });\n if (!found) {\n noderedState = 'stopped';\n $('#status-spinner').hide();\n $status.html('<span class=\"status-stopped\">stopped</span>');\n $memory.html('');\n $dropdownRestart.addClass('disabled');\n $stop.addClass('disabled');\n $dropdownStart.removeClass('disabled');\n $linkRed.addClass('disabled');\n $linkUi.addClass('disabled');\n psInterval = 5000;\n }\n psTimeout = setTimeout(ps, psInterval);\n });\n }\n\n ps();\n\n function alert($elem, timeout = 1600) {\n $elem.show();\n $elem.addClass('show');\n setTimeout(() => {\n $elem.removeClass('show');\n setTimeout(() => {\n $elem.hide();\n }, 200);\n }, timeout);\n }\n\n function invalidSession() {\n $('#invalidSession').show();\n clearTimeout(psTimeout);\n }\n\n function save() {\n console.log('save', config)\n $.post({\n url: 'setconfig.cgi' + location.search,\n data: JSON.stringify(config, null, ' '),\n success: function (data) {\n if ($.trim(data) === 'ok') {\n alert($alertSaved);\n } else {\n if ($.trim(data) === 'error: invalid session') {\n invalidSession();\n return;\n }\n alert($alertError);\n }\n }\n }).fail(() => {\n alert($alertError);\n });\n }\n\n $.get('getnick.cgi' + location.search, (data, success) => {\n if ($.trim(data) === 'error: invalid session') {\n invalidSession();\n return;\n }\n const nick = $.trim(data);\n if (nick) {\n $('#nickname').val(nick);\n $('#log-upload').removeClass('disabled');\n }\n });\n\n $('#nickname').change(() => {\n const nick = $.trim($('#nickname').val());\n if (nick) {\n $('#log-upload').removeClass('disabled');\n } else {\n $('#log-upload').addClass('disabled');\n }\n });\n\n $.get('getconfig.cgi' + location.search, (data, success) => {\n if ($.trim(data) === 'error: invalid session') {\n invalidSession();\n return;\n }\n config = JSON.parse(data);\n $loglevel.val(config.logging.ain.level);\n\n if (config.adminAuth) {\n $adminauthSessionExpiryTime.val(config.adminAuth.sessionExpiryTime || '604800');\n $adminauthType.val(config.adminAuth.type);\n if (config.adminAuth.type === 'credentials') {\n $adminauthCreds.show();\n $adminauthExpiry.show();\n $adminauthUser.val(config.adminAuth.users[0].username);\n\n }\n /* else if (config.adminAuth.type === 'rega') {\n $adminauthExpiry.show();\n }*/\n }\n\n if (config.httpNodeAuth) {\n $nodeauthType.val('basic');\n $nodeauthCreds.show();\n $nodeauthUser.val(config.httpNodeAuth.user);\n }\n\n if (config.httpStaticAuth) {\n $staticauthType.val('basic');\n $staticauthCreds.show();\n $staticauthUser.val(config.httpStaticAuth.user);\n }\n\n if (!config.contextStorage) {\n config.contextStorage = {};\n }\n if (!config.contextStorage.default || !config.contextStorage.default.module) {\n config.contextStorage.default = { module: 'memory' };\n }\n if (!config.contextStorage.memory) {\n config.contextStorage.memory = {\n 'module': 'memory'\n };\n }\n if (!config.contextStorage.file) {\n config.contextStorage.file = {\n 'module': 'localfilesystem'\n };\n }\n\n if (!config.contextStorage.file.config) {\n config.contextStorage.file.config = {\n dir: '/usr/local/addons/redmatic/var',\n flushInterval: 30\n }\n }\n\n if (!config.editorTheme) {\n config.editorTheme = {};\n }\n if (!config.editorTheme.projects) {\n config.editorTheme.projects = {};\n }\n config.editorTheme.projects.enabled = config.editorTheme.projects.enabled || false;\n\n $projects.val(String(config.editorTheme.projects.enabled));\n\n if (config.editorTheme.projects.enabled) {\n $projects.prop('disabled', true);\n }\n\n if (config.editorTheme.theme) {\n $theme.val(config.editorTheme.theme);\n }\n\n // Migration from 1.x to 2.x\n if (config.contextStorage.default && config.contextStorage.default.module === 'localfilesystem') {\n config.contextStorage.default.module = 'file';\n }\n\n config.contextStorage.default.module = config.contextStorage.default.module || 'memory';\n\n updateContextTitle();\n\n $contextStorageDefault.val(config.contextStorage.default.module);\n\n $contextStorageFilePath.val(config.contextStorage.file.config.dir);\n $contextStorageFileInterval.val(config.contextStorage.file.config.flushInterval);\n\n $('#autorestart').val(config.restartOnCrash);\n $('#backup').val(config.ccuBackup || 'full');\n });\n\n $loglevel.change(() => {\n config.logging.ain.level = $loglevel.val();\n save();\n });\n\n function updateContextTitle() {\n switch (config.contextStorage.default.module) {\n case 'memory':\n $('#context-file-title').html('file');\n $('#context-memory-title').html('default');\n break;\n case 'file':\n $('#context-file-title').html('default');\n $('#context-memory-title').html('memory');\n break;\n default:\n }\n }\n\n $projects.change(() => {\n config.editorTheme.projects.enabled = $projects.val() === 'true';\n save();\n if (config.editorTheme.projects.enabled) {\n $projects.prop('disabled', true)\n }\n });\n\n $theme.change(() => {\n switch ($theme.val()) {\n case '':\n case 'default':\n delete config.editorTheme.theme;\n break;\n\n default:\n config.editorTheme.theme = $theme.val();\n break;\n }\n delete config.editorTheme.page;\n save();\n });\n\n $contextStorageDefault.change(() => {\n if (!config.contextStorage) {\n config.contextStorage = {};\n }\n if (!config.contextStorage.default) {\n config.contextStorage.default = {};\n }\n\n config.contextStorage.default.module = $contextStorageDefault.val();\n updateContextTitle();\n\n save();\n });\n\n $contextStorageFilePath.change(() => {\n config.contextStorage.file.config.dir = $contextStorageFilePath.val();\n save();\n });\n\n $contextStorageFileInterval.change(() => {\n config.contextStorage.file.config.flushInterval = parseInt($contextStorageFileInterval.val(), 10);\n save();\n });\n\n $adminauthSessionExpiryTime.change(() => {\n if (!config.adminAuth) {\n config.adminAuth = {};\n }\n const time = parseInt($adminauthSessionExpiryTime.val(), 10) || 604800;\n if (config.adminAuth.sessionExpiryTime !== time) {\n config.adminAuth.sessionExpiryTime = time;\n save();\n }\n });\n\n $adminauthType.change(() => {\n switch ($adminauthType.val()) {\n case 'credentials':\n $adminauthCreds.show();\n break;\n /* case 'rega':\n $adminauthExpiry.show();\n $adminauthCreds.hide();\n $adminauthUser.val('');\n if (!config.adminAuth) {\n config.adminAuth = {};\n }\n delete config.adminAuth.users;\n config.adminAuth.type = 'rega';\n config.adminAuth.sessionExpiryTime = parseInt($adminauthSessionExpiryTime.val(), 10) || 604800;\n save();\n break;*/\n default:\n $adminauthExpiry.hide();\n $adminauthCreds.hide();\n $adminauthUser.val('');\n delete config.adminAuth;\n save();\n }\n });\n\n $nodeauthType.change(() => {\n switch ($nodeauthType.val()) {\n case 'basic':\n $nodeauthCreds.show();\n break;\n default:\n $nodeauthCreds.hide();\n $nodeauthUser.val('');\n delete config.httpNodeAuth;\n save();\n }\n });\n\n $staticauthType.change(() => {\n switch ($staticauthType.val()) {\n case 'basic':\n $staticauthCreds.show();\n break;\n default:\n $staticauthCreds.hide();\n $staticauthUser.val('');\n delete config.httpStaticAuth;\n save();\n }\n });\n\n $adminauthSet.click(() => {\n const user = $.trim($adminauthUser.val());\n const pw1 = $adminauthPass1.val();\n const pw2 = $adminauthPass2.val();\n\n let valid = true;\n\n if (!user) {\n $adminauthUser.addClass('is-invalid');\n valid = false;\n } else {\n $adminauthUser.removeClass('is-invalid');\n }\n\n if (!pw1 || pw1 !== pw2) {\n $adminauthPass1.addClass('is-invalid');\n $adminauthPass2.addClass('is-invalid');\n valid = false;\n } else {\n $adminauthPass1.removeClass('is-invalid');\n $adminauthPass2.removeClass('is-invalid');\n }\n\n if (valid) {\n config = Object.assign(config, {\n adminAuth: {\n type: 'credentials',\n sessionExpiryTime: parseInt($adminauthSessionExpiryTime.val(), 10) || 604800,\n users: [{\n username: user,\n password: bcrypt.hashSync(pw1, 8),\n permissions: '*'\n }]\n }\n });\n save();\n }\n });\n\n $staticauthSet.click(() => {\n const user = $.trim($staticauthUser.val());\n const pw1 = $staticauthPass1.val();\n const pw2 = $staticauthPass2.val();\n\n let valid = true;\n\n if (!user) {\n $staticauthUser.addClass('is-invalid');\n valid = false;\n } else {\n $staticauthUser.removeClass('is-invalid');\n }\n\n if (!pw1 || pw1 !== pw2) {\n $staticauthPass1.addClass('is-invalid');\n $staticauthPass2.addClass('is-invalid');\n valid = false;\n } else {\n $staticauthPass1.removeClass('is-invalid');\n $staticauthPass2.removeClass('is-invalid');\n }\n\n if (valid) {\n config = Object.assign(config, {\n httpStaticAuth: {\n user,\n pass: bcrypt.hashSync(pw1, 8),\n }\n });\n save();\n }\n });\n\n $nodeauthSet.click(() => {\n const user = $.trim($nodeauthUser.val());\n const pw1 = $nodeauthPass1.val();\n const pw2 = $nodeauthPass2.val();\n\n let valid = true;\n\n if (!user) {\n $nodeauthUser.addClass('is-invalid');\n valid = false;\n } else {\n $nodeauthUser.removeClass('is-invalid');\n }\n\n if (!pw1 || pw1 !== pw2) {\n $nodeauthPass1.addClass('is-invalid');\n $nodeauthPass2.addClass('is-invalid');\n valid = false;\n } else {\n $nodeauthPass1.removeClass('is-invalid');\n $nodeauthPass2.removeClass('is-invalid');\n }\n\n if (valid) {\n config = Object.assign(config, {\n httpNodeAuth: {\n user,\n pass: bcrypt.hashSync(pw1, 8),\n }\n });\n save();\n }\n });\n\n function restart() {\n clearTimeout(psTimeout);\n $dropdownRestart.addClass('disabled');\n $stop.addClass('disabled');\n $dropdownStart.addClass('disabled');\n $('#status-spinner').show();\n $status.html('<span class=\"status-starting\">stopping</span>');\n $memory.html('');\n $cpu.html('');\n $.get({\n url: `service.cgi?sid=${sid}&cmd=restart`,\n success: data => {\n if (data.match(/Starting Node-RED: OK/)) {\n alert($alertExec);\n } else if ($.trim(data) === 'error: invalid session') {\n invalidSession();\n return;\n } else {\n alert($alertError);\n }\n psInterval = 1000;\n setTimeout(() => {\n ps();\n }, 1000);\n }\n });\n setTimeout(() => {\n ps();\n }, 10000);\n\n }\n\n $restart.click(() => {\n restart();\n });\n\n function safeMode(cb) {\n $.get({\n url: `safemode.cgi?sid=${sid}`,\n success: cb\n });\n }\n\n $restartSafe.click(() => {\n safeMode(restart);\n });\n\n function start() {\n $dropdownRestart.addClass('disabled');\n $stop.addClass('disabled');\n $dropdownStart.addClass('disabled');\n $status.html('<span class=\"status-starting\">starting</span>');\n $memory.html('');\n $.get({\n url: `service.cgi?sid=${sid}&cmd=start`,\n success: data => {\n if ($.trim(data) === 'error: invalid session') {\n invalidSession();\n return;\n }\n\n if (data.match(/Starting Node-RED: OK/)) {\n psInterval = 2000;\n setTimeout(() => {\n ps();\n }, 6000);\n alert($alertExec);\n } else {\n alert($alertError);\n }\n }\n });\n }\n\n $start.click(() => {\n start();\n });\n\n $startSafe.click(() => {\n safeMode(start);\n });\n\n $stop.click(() => {\n clearTimeout(psTimeout);\n $dropdownRestart.addClass('disabled');\n $stop.addClass('disabled');\n $dropdownStart.addClass('disabled');\n $status.html('<span class=\"status-starting\">stopping</span>');\n $memory.html('');\n $.get({\n url: `service.cgi?sid=${sid}&cmd=stop`,\n success: data => {\n if ($.trim(data) === 'error: invalid session') {\n invalidSession();\n return;\n }\n if (data.match(/Stopping Node-RED: OK/)) {\n alert($alertExec);\n psInterval = 2000;\n setTimeout(() => {\n ps();\n }, 6000);\n } else {\n alert($alertError);\n }\n }\n });\n });\n\n function setHeader(xhr) {\n xhr.setRequestHeader('accept', 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*');\n }\n\n $.get('restart_count', data => {\n $('#restarts').html(data || 'keine');\n });\n\n function download(filename, dataUrl) {\n let link = document.createElement(\"a\");\n link.download = filename;\n link.target = \"_blank\";\n\n link.href = dataUrl;\n document.body.appendChild(link);\n link.click();\n\n document.body.removeChild(link);\n }\n\n $('#log').on('click', () => {\n download('redmatic.' + (new Date()).toISOString() + '.log', 'log.cgi' + location.search);\n });\n\n function logUpload() {\n $('#log-upload-spinner').show();\n $('#log-upload').addClass('disabled');\n $.post({\n url: 'setnick.cgi' + location.search,\n data: $.trim($('#nickname').val().toLowerCase()),\n success: function (data) {\n if ($.trim(data) === 'ok') {\n $.get({\n url: 'logupload.cgi?sid=' + sid,\n success: data => {\n $('#log-upload-spinner').hide();\n $('#log-upload').removeClass('disabled');\n $('#log-name').html(data);\n $('#modal-upload').modal('show')\n }\n }).fail(() => {\n $('#log-upload').removeClass('disabled');\n $('#log-upload-spinner').hide();\n alert($alertError);\n });\n } else {\n $('#log-upload').removeClass('disabled');\n $('#log-upload-spinner').hide();\n if ($.trim(data) === 'error: invalid session') {\n invalidSession();\n return;\n }\n alert($alertError);\n }\n }\n }).fail(() => {\n alert($alertError);\n $('#log-upload').removeClass('disabled');\n $('#log-upload-spinner').hide();\n });\n }\n\n $('#log-upload').on('click', () => {\n $('#modal-nickname').modal('show');\n });\n\n $('#upgrade-log').on('click', () => {\n download('redmatic-pkg-upgrade.' + (new Date()).toISOString() + '.log', 'log.cgi' + location.search + '&cmd=upgrade');\n });\n\n $('#autorestart').on('change', event => {\n config.restartOnCrash = parseInt(event.target.value, 10);\n save();\n });\n\n $backup.on('change', () => {\n config.ccuBackup = $backup.val();\n save();\n });\n\n $('#discard-package-hint').on('click', () => {\n localStorage.setItem('package-hint', 'discarded');\n $('#package-hint').hide();\n });\n if (localStorage.getItem('package-hint') !== 'discarded') {\n $('#package-hint').show();\n }\n\n $('#package-filter').on('keyup', () => {\n const filter = $('#package-filter').val();\n $packageTable.find('tr').each(function () {\n const name = $(this).find('td').html().toLowerCase();\n if (name.includes(filter.toLowerCase())) {\n $(this).show();\n } else {\n $(this).hide();\n }\n });\n });\n\n});\n\n",
"output": "str",
"x": 440,
"y": 300,
"wires": [
[
"07089cae74365102"
]
]
},
{
"id": "07089cae74365102",
"type": "file",
"z": "2ab1de6847dd7ea2",
"name": "www/js/script.js",
"filename": "/usr/local/addons/redmatic/www/js/script.js",
"filenameType": "str",
"appendNewline": false,
"createDir": true,
"overwriteFile": "true",
"encoding": "none",
"x": 700,
"y": 300,
"wires": [
[
"aecdcf17e967759b"
]
]
},
{
"id": "3b213cd16eeb1a66",
"type": "template",
"z": "2ab1de6847dd7ea2",
"name": "redmaticLoader",
"field": "payload",
"fieldType": "msg",
"format": "markdown",
"syntax": "plain",
"template": "# Henke Version 1.2\n#!/bin/sh\n\nlogger -t redmatic -p daemon.warn \"Henke Script redmaticLoader\"\n\nCONF_DIR=/usr/local/etc/config\nADDON_DIR=/usr/local/addons/redmatic\nWWW_DIR=/usr/local/etc/config/addons/www/redmatic\n\ncd $ADDON_DIR/bin\n# Henke\nif [ -f /usr/bin/node ]; then\n\tNODE=/usr/bin/node\nfi\nif [ -f /usr/local/bin/node ]; then\n\tNODE=/usr/local/bin/node\nfi\n\n# NODE=$ADDON_DIR/bin/node\n\nexport PATH=$ADDON_DIR/bin:$PATH\nexport LD_LIBRARY_PATH=$ADDON_DIR/lib:$LD_LIBRARY_PATH\nexport HOME=$ADDON_DIR/home\n\nexport NO_UPDATE_NOTIFIER=true\n\nRED_DIR=$ADDON_DIR/lib/node_modules/node-red\nRED=$RED_DIR/red.js\n\nSETTINGS=$ADDON_DIR/lib/settings.js\n\nstatus=1\nrestarts=0\n\nlogger -t redmatic -p daemon.warn \"Henke checkNR start - $NODE\"\nnode checkNR.js\nsource /tmp/red-settings\nlogger -t redmatic -p daemon.warn \"Henke checkNR done $RedSettings_NodeRedUpdate\"\n#logger -t redmatic -p daemon.warn \"NodeRedUpdate$RedSettings_NodeRedUpdate\"\nif [[ $RedSettings_NodeRedUpdate != \"false\" ]]; then\n logger -t redmatic -p daemon.warn \"Update NodeRed\"\n$ADDON_DIR/bin/updateNodeRed.sh\nfi\n\n#echo \"RR $RedSettings_RestartOnCrash\"\n#echo \"BB $RedSettings_Test\"\n#limit=`jq '.restartOnCrash' $ADDON_DIR/etc/settings.json`\n\nif [[ -z $RedSettings_RestartOnCrash ]]; then\n RedSettings_RestartOnCrash = 0\nfi\n\nwhile [[ $status != 0 ]]; do\n echo $restarts > $ADDON_DIR/var/restart_count\n if [[ $restarts -gt 0 ]]; then\n echo \"Restarting Node-RED ($restarts/$RedSettings_RestartOnCrash)\" | logger -p daemon.warn -t redmatic\n else\n echo \"Starting Node-RED\" | logger -p daemon.info -t redmatic\n fi\n if [[ -f $ADDON_DIR/var/safe_mode ]]; then\n SAFE=\"--safe\"\n rm $ADDON_DIR/var/safe_mode\n fi\n set -o pipefail\n# Henke add --max-old-space-size=256 --max-semi-space-size=8 --trace-deprecation --trace-warnings \n $NODE $RED $SAFE -s $SETTINGS 2>&1 | logger -p daemon.err -t node-red\n status=$?\n if [[ $status != 0 ]]; then\n echo \"Node-RED exited with non-zero exit status $status\" | logger -p daemon.err -t node-red\n let \"restarts=restarts+1\"\n if [[ $restarts -gt $RedSettings_RestartOnCrash ]]; then\n if [[ $RedSettings_RestartOnCrash -gt 0 ]]; then\n echo \"Maximum Node-RED restarts exceeded\" | logger -p daemon.err -t redmatic\n fi\n status=0\n fi\n fi\ndone\n",
"output": "str",
"x": 980,
"y": 180,
"wires": [
[
"19200cbb67cc50b9"
]
]
},
{
"id": "19200cbb67cc50b9",
"type": "file",
"z": "2ab1de6847dd7ea2",
"name": "bin/redmaticLoader",
"filename": "/usr/local/addons/redmatic/bin/redmaticLoader",
"filenameType": "str",
"appendNewline": false,
"createDir": true,
"overwriteFile": "true",
"encoding": "none",
"x": 1190,
"y": 180,
"wires": [
[
"fa72f43dd0a8948b"
]
]
},
{
"id": "e435bc41d8c9739d",
"type": "template",
"z": "2ab1de6847dd7ea2",
"name": "redmatic",
"field": "payload",
"fieldType": "msg",
"format": "markdown",
"syntax": "plain",
"template": "#!/bin/sh\n\n# Henke\nlogger -t redmatic -p daemon.info \"Henke Script redmatic $1\"\n\nCONF_DIR=/usr/local/etc/config\nADDON_DIR=/usr/local/addons/redmatic\nWWW_DIR=/usr/local/etc/config/addons/www/redmatic\n\n# Henke NODE=$ADDON_DIR/bin/node\n\nSETTINGS=$ADDON_DIR/lib/settings.js\nRED_DIR=$ADDON_DIR/lib/node_modules/node-red\nRED=$RED_DIR/red.js\n\nLIGHTTPD_CONF=/etc/lighttpd/lighttpd.conf\nLIGHTTPD_SSL_CONF=/etc/lighttpd/lighttpd_ssl.conf\n#BACKUP_CGI=/www/config/cp_security.cgi\n\nexport PATH=$ADDON_DIR/bin:$PATH\nexport LD_LIBRARY_PATH=/usr/local/addons/redmatic/lib:/usr/lib:/usr/local/lib\nexport GIT_EXEC_PATH=/usr/local/addons/redmatic/libexec/git-core\nexport NO_UPDATE_NOTIFIER=true\n\nStop () {\n if [ -f /usr/bin/monit ]; then\n /usr/bin/monit -g redmatic unmonitor\n fi\n\n PSPID=`ps -o pid,comm,args | awk '{if($3 == \"node-red\" || $4 ~ /node-red/){print $1}}'`\n if [ \"$PSPID\" != \"\" ]; then\n echo -n \"Stopping Node-RED: \"\n logger -t redmatic -p daemon.info \"Stopping Node-RED\"\n\n killall redmaticLoader 2>/dev/null\n kill -SIGINT $PSPID 2>/dev/null\n sleep 2\n if kill -0 $PSPID 2> /dev/null\n then\n sleep 4\n if kill -0 $PSPID 2> /dev/null\n then\n logger -t redmatic -p daemon.warn \"Killing Node-RED\"\n kill -SIGKILL $PSPID 2>/dev/null\n fi\n fi\n echo \"OK\"\n logger -t redmatic -p daemon.info \"Node-RED stopped\"\n return 0\n else\n echo \"Node-RED not running\"\n return 1\n fi\n}\n\nStart () {\n# if [ `$ADDON_DIR/bin/jq -r '.ccuBackup' $ADDON_DIR/etc/settings.json` = \"full\" ]; then\nrm $ADDON_DIR/etc/.nobackup 2>/dev/null\nrm $ADDON_DIR/bin/.nobackup 2>/dev/null\nrm $ADDON_DIR/include/.nobackup 2>/dev/null\nrm $ADDON_DIR/lib/.nobackup 2>/dev/null\nrm $ADDON_DIR/libexec/.nobackup 2>/dev/null\nrm $ADDON_DIR/share/.nobackup 2>/dev/null\nrm $ADDON_DIR/tmp/.nobackup 2>/dev/null\nrm $ADDON_DIR/var/node_modules/.nobackup 2>/dev/null\nrm $ADDON_DIR/www/.nobackup 2>/dev/null\n# else\n# touch $ADDON_DIR/bin/.nobackup\n# touch $ADDON_DIR/include/.nobackup\n# touch $ADDON_DIR/lib/.nobackup\n# touch $ADDON_DIR/libexec/.nobackup\n# touch $ADDON_DIR/share/.nobackup\n# touch $ADDON_DIR/tmp/.nobackup\n# touch $ADDON_DIR/var/node_modules/.nobackup\n# touch $ADDON_DIR/www/.nobackup\n# fi\n\n# if [ -f $ADDON_DIR/var/do_pkg_upgrade ]; then\n# echo \"Updating Packages\"\n# date +\"%b %d %H:%M:%S\" >> $ADDON_DIR/var/pkg-upgrade.log\n# set -o pipefail\n# $ADDON_DIR/bin/redmatic-pkg upgrade 2>&1 | tee -a $ADDON_DIR/var/pkg-upgrade.log | logger -t redmatic-pkg -p daemon.info && rm $ADDON_DIR/var/do_pkg_upgrade\n# echo \"\" >> $ADDON_DIR/var/pkg-upgrade.log\n# sleep 1\n# fi\n\n if ! grep -Fq \"/etc/config/lighttpd/\" $LIGHTTPD_CONF\n then\n echo \"patching $LIGHTTPD_CONF\"\n mount -o remount,rw /\n cp $LIGHTTPD_CONF $LIGHTTPD_CONF.orig\n echo \"include_shell \\\"test -d /etc/config/lighttpd && cat /etc/config/lighttpd/*.conf\\\"\" >> $LIGHTTPD_CONF\n mount -o remount,ro /\n /etc/init.d/S50lighttpd restart\n fi\n\n if [ -f $LIGHTTPD_SSL_CONF ]\n then\n if ! grep -Fq \"/etc/config/lighttpd/\" $LIGHTTPD_SSL_CONF\n then\n echo \"patching $LIGHTTPD_SSL_CONF\"\n mount -o remount,rw /\n cp $LIGHTTPD_SSL_CONF $LIGHTTPD_SSL_CONF.orig\n echo \"include_shell \\\"test -d /etc/config/lighttpd && cat /etc/config/lighttpd/*.conf\\\"\" >> $LIGHTTPD_SSL_CONF\n mount -o remount,ro /\n /etc/init.d/S50lighttpd restart\n fi\n fi\n\n# if ! grep -Fq \"exclude-tag=.nobackup\" $BACKUP_CGI\n# then\n# echo \"patching $BACKUP_CGI\"\n# mount -o remount,rw /\n# cp $BACKUP_CGI $BACKUP_CGI.orig\n# sed \"s/exec tar czf \\/tmp\\/usr_local.tar.gz usr\\/local/exec tar --exclude-tag=.nobackup -czf \\/tmp\\/usr_local.tar.gz usr\\/local/\" $BACKUP_CGI > $BACKUP_CGI.tmp && mv $BACKUP_CGI.tmp $BACKUP_CGI\n# chmod 755 $BACKUP_CGI\n# mount -o remount,ro /\n# fi\n\n if [ ! -f /etc/config/rdmtc.uuid ]; then\n /usr/bin/uuidgen > /etc/config/rdmtc.uuid\n fi\n LD_LIBRARY_PATH=/usr/lib:/usr/local/lib:/usr/local/addons/redmatic/lib ; /usr/local/addons/redmatic/bin/redmaticVersions | /usr/bin/curl -H \"Content-Type: application/json\" -H \"X-RedMatic-uuid: `cat /etc/config/rdmtc.uuid`\" --data @- -s --max-time 3 https://telemetry.redmatic.de\n\n PSPID=`ps -o pid,comm,args | awk '{if($3 == \"node-red\" || $4 ~ /node-red/){print $1}}'`\n if [ \"$PSPID\" != \"\" ]; then\n echo \"Node-RED already running\"\n logger -t redmatic -p daemon.error \"cant start - already running\"\n exit 1\n else\n upSeconds=\"$(cat /proc/uptime | grep -o '^[0-9]\\+')\"\n if [ \"${upSeconds}\" -lt \"120\" ]; then\n logger -t redmatic -p daemon.info \"Starting Node-RED after reboot ... waiting 30 seconds...\"\n echo \"Starting Node-RED ... waiting 30 seconds...\"\n sleep 30\n fi\n echo -n \"Starting Node-RED: \"\n source $ADDON_DIR/versions\n logger -t redmatic -p daemon.info \"RedMatic v$VERSION_ADDON (c) Sebastian Raff https://github.com/rdmtc/RedMatic - Patch Henke\"\n start-stop-daemon -S -q -b --exec $ADDON_DIR/bin/redmaticLoader\n echo \"OK\"\n fi\n\n if [ -f /usr/bin/monit ]; then\n nohup $ADDON_DIR/bin/monit-start > /dev/null 2>&1 &\n fi\n}\n\ncase \"$1\" in\n\n stop)\n Stop || exit 1\n ;;\n\n start)\n Start\n ;;\n\n restart)\n Stop\n sleep 10\n Start\n ;;\n\n info)\n source $ADDON_DIR/versions\n echo \"Info: <div><a target=\\\"_blank\\\" href=\\\"https://github.com/rdmtc/RedMatic\\\"><img src=\\\"/addons/redmatic/redmatic5-wide.png\\\" height=\\\"48\\\"/></a></div>\"\n echo \"Name: RedMatic\"\n echo \"Version: $VERSION_ADDON\"\n# echo \"Update: /addons/redmatic/update_check.cgi\"\n echo \"Config-Url: /addons/redmatic/settings.cgi\"\n echo \"Operations: restart uninstall\"\n ;;\n\n uninstall)\n Stop\n\n $ADDON_DIR/bin/update_addon redmatic\n rm -r $ADDON_DIR\n rm -r $WWW_DIR\n rm $CONF_DIR/lighttpd/redmatic.conf\n rm $CONF_DIR/rc.d/redmatic\n\n if [ -f /usr/local/etc/monit-redmatic.cfg ]; then\n rm /usr/local/etc/monit-redmatic.cfg\n /usr/bin/monit reload\n fi\n\n mount -o remount,rw /\n if [ -f $LIGHTTPD_CONF.orig ]; then\n mv $LIGHTTPD_CONF.orig $LIGHTTPD_CONF\n fi\n if [ -f $LIGHTTPD_SSL_CONF.orig ]; then\n mv $LIGHTTPD_SSL_CONF.orig $LIGHTTPD_SSL_CONF\n fi\n# if [ -f $BACKUP_CGI.orig ]; then\n# mv $BACKUP_CGI.orig $BACKUP_CGI\n# fi\n mount -o remount,ro /\n\n logger -t redmatic -p daemon.info \"Uninstalled RedMatic\"\n ;;\n\n *)\n echo \"Usage: node-red {start|stop|restart|info|uninstall}\" >&2\n exit 1\n ;;\n\nesac\n\nexit 0\n",
"output": "str",
"x": 440,
"y": 180,
"wires": [
[
"7def8072ba56d9d1"
]
]
},
{
"id": "7def8072ba56d9d1",
"type": "file",
"z": "2ab1de6847dd7ea2",
"name": "bin/redmatic",
"filename": "/usr/local/addons/redmatic/bin/redmatic",
"filenameType": "str",
"appendNewline": false,
"createDir": true,
"overwriteFile": "true",
"encoding": "none",
"x": 690,
"y": 180,
"wires": [
[
"3b213cd16eeb1a66"
]
]
},
{
"id": "a0ee823d1b868b33",
"type": "template",
"z": "2ab1de6847dd7ea2",
"name": "settings.js",
"field": "payload",
"fieldType": "msg",
"format": "javascript",
"syntax": "plain",
"template": "const fs = require('fs');\n\nconst addOn = '/usr/local/addons/redmatic/';\nconst etcSettings = addOn + 'etc/settings.json';\n\nconst defaults = require(addOn + 'lib/node_modules/node-red/settings.js');\nconst settings = require(etcSettings);\nconst logging = require(addOn + 'lib/logger.js');\n\n// Migration\nif (settings.logging.console) {\n settings.logging.ain = settings.logging.console;\n delete settings.logging.console;\n fs.writeFileSync(etcSettings, JSON.stringify(settings, null, ' '));\n}\n\n// Credentials encryption key\nif (fs.existsSync(addOn + 'etc/credentials.key')) {\n settings.credentialSecret = fs.readFileSync(addOn + 'etc/credentials.key').toString();\n}\n\n// Logging\ndelete defaults.logging.console;\nObject.assign(logging.logging.ain, settings.logging.ain);\n\n// Enable Projects Feature\nif (!defaults.editorTheme) {\n defaults.editorTheme = {};\n}\nif (!defaults.editorTheme.projects) {\n defaults.editorTheme.projects = {};\n}\ndefaults.editorTheme.projects.enabled = defaults.editorTheme.projects.enabled || false;\n\n// Auskommentiert, M. Henke\n// Inject sessionExpiryTime to Rega Authentication\nif (settings.adminAuth && settings.adminAuth.type === 'rega') {\n // const regaAuth = require(addOn + 'lib/rega-auth.js');\n delete settings.adminAuth;\n console.log(\"ReGa Passworte nicht mehr unterstützt\");\n /* if (settings.adminAuth.sessionExpiryTime) {\n regaAuth.sessionExpiryTime = settings.adminAuth.sessionExpiryTime;\n }\n settings.adminAuth = regaAuth;*/\n}\n\n// M. Henke\nif (settings.httpRoot) {\n settings.httpAdminRoot = settings.httpRoot;\n settings.httpNodeRoot = settings.httpRoot;\n delete settings.httpRoot;\n}\nif (!settings.runtimeState)\n settings.runtimeState = {};\nif (settings.runtimeState) {\n// settings.runtimeState.enabled = true;\n settings.runtimeState.ui = true;\n}\n\n// Context Storage\nif (!settings.contextStorage) {\n settings.contextStorage = {};\n}\nif (!settings.contextStorage.default) {\n settings.contextStorage.default = {};\n}\nif (!settings.contextStorage.default.module) {\n settings.contextStorage.default.module = 'memory';\n}\nif (settings.contextStorage.default.module === 'localfilesystem') {\n settings.contextStorage.default.module = 'file';\n}\n\nif (settings.contextStorage.default.module !== 'file' && settings.contextStorage.default.module !== 'memory') {\n settings.contextStorage.default.module = 'memory';\n}\n\nif (!settings.contextStorage.memory) {\n settings.contextStorage.memory = {\n 'module': 'memory'\n }\n}\nif (!settings.contextStorage.file) {\n settings.contextStorage.file = {\n 'module': 'localfilesystem',\n config: {\n dir: addOn + 'var',\n flushInterval: 300\n }\n }\n}\n\nconst defaultContextStorage = Object.assign({}, settings.contextStorage[settings.contextStorage.default.module]);\ndelete settings.contextStorage[settings.contextStorage.default.module];\nsettings.contextStorage.default = defaultContextStorage;\n\nconst result = Object.assign(\n defaults,\n settings,\n logging\n);\n\nfs.writeFileSync('/tmp/red-settings.json', JSON.stringify(result));\n\nmodule.exports = result;\n",
"output": "str",
"x": 440,
"y": 260,
"wires": [
[
"773c8ac10017ce00"
]
]
},
{
"id": "773c8ac10017ce00",
"type": "file",
"z": "2ab1de6847dd7ea2",
"name": "lib/settings.js",
"filename": "/usr/local/addons/redmatic/lib/settings.js",
"filenameType": "str",
"appendNewline": false,
"createDir": true,
"overwriteFile": "true",
"encoding": "none",
"x": 690,
"y": 260,
"wires": [
[
"775f2a96c0c5bcc3"
]
]
},
{
"id": "775f2a96c0c5bcc3",
"type": "template",
"z": "2ab1de6847dd7ea2",
"name": "versions",
"field": "payload",
"fieldType": "msg",
"format": "markdown",
"syntax": "mustache",
"template": "# Henke\nexport VERSION_ADDON={{VersionAddOn}}\n",
"output": "str",
"x": 960,
"y": 260,
"wires": [
[
"ef6f947e639c52b9"
]
]
},
{
"id": "ef6f947e639c52b9",
"type": "file",
"z": "2ab1de6847dd7ea2",
"name": "versions",
"filename": "/usr/local/addons/redmatic/versions",
"filenameType": "str",
"appendNewline": false,
"createDir": true,
"overwriteFile": "true",
"encoding": "none",
"x": 1160,
"y": 260,
"wires": [
[
"3d2fc855a49dc0ab"
]
]
},
{
"id": "aecdcf17e967759b",
"type": "template",
"z": "2ab1de6847dd7ea2",
"name": "settings.html",
"field": "payload",
"fieldType": "msg",
"format": "html",
"syntax": "plain",
"template": "<!DOCTYPE html>\n<meta charset=\"UTF-8\">\n\n<title>RedMatic</title>\n\n<script src=\"node_modules/jquery/dist/jquery.min.js\"></script>\n<script src=\"node_modules/bcryptjs/dist/bcrypt.min.js\"></script>\n<script src=\"node_modules/bootstrap/dist/js/bootstrap.bundle.min.js\"></script>\n\n<link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"apple-icon-180x180.png\">\n<link rel=\"icon\" type=\"image/png\" sizes=\"96x96\" href=\"favicon-96x96.png\">\n\n<link rel=\"stylesheet\" href=\"node_modules/bootstrap/dist/css/bootstrap.min.css\">\n<link rel=\"stylesheet\" href=\"node_modules/@fortawesome/fontawesome-free/css/all.css\">\n<link rel=\"stylesheet\" href=\"css/style.css\">\n\n<div id=\"invalidSession\">\n Sitzung ungültig. Bitte diese Seite schließen.\n</div>\n\n<nav class=\"navbar sticky-top navbar-light bg-light mb-4\">\n <a href=\"https://github.com/rdmtc/RedMatic\" target=\"_blank\"><img src=\"redmatic5-compact.png\"\n style=\"height: 42px; \"></a>\n\n <ul class=\"nav navbar-nav mr-auto d-flex flex-row mt-2\" role=\"tablist\" id=\"myTab\">\n <li class=\"nav-item ml-3\">\n <a class=\"nav-link pb-0\" id=\"configuration-tab\" data-toggle=\"tab\" role=\"tab\" aria-controls=\"configuration\"\n aria-selected href=\"#configuration\">Konfiguration</a>\n </li>\n<!-- Henke\n <li class=\"nav-item ml-3\">\n <a class=\"nav-link pb-0\" id=\"packages-tab\" data-toggle=\"tab\" role=\"tab\" aria-controls=\"packages\" aria-selected href=\"#packages\">Pakete</a>\n </li>\n//-->\n <li class=\"nav-item ml-3\">\n <a class=\"nav-link pb-0\" id=\"versions-tab\" data-toggle=\"tab\" role=\"tab\" aria-controls=\"versions\"\n aria-selected href=\"#versions\">Debug</a>\n </li>\n <li class=\"nav-item ml-3\">\n <a class=\"nav-link pb-0\" id=\"licenses-tab\" data-toggle=\"tab\" role=\"tab\" aria-controls=\"licenses\"\n href=\"#licenses\">Lizenzen</a>\n </li>\n </ul>\n <div class=\"ml-3 mr-2 pl-2\">\n <a id=\"link-red\" role=\"button\" class=\"btn btn-sm btn-outline-info\" target=\"_blank\" href=\"/addons/red/\"><i\n class=\"fa fa-external-link-alt\"></i> Node-RED</a>\n <a id=\"link-ui\" role=\"button\" class=\"btn btn-sm btn-outline-info mr-3\" target=\"_blank\" href=\"/addons/red/ui/\"><i\n class=\"fa fa-external-link-alt\"></i> Dashboard</a>\n </div>\n <div style=\"min-width: 130px\" id=\"redmatic-version\"></div>\n</nav>\n\n<div id=\"container\" class=\"container\">\n\n <div id=\"alert-saved\" style=\"display: none;\" class=\"fixed-top mx-auto alert alert-success alert-dismissible fade\"\n role=\"alert\">\n <strong>Settings gespeichert, Node-RED Neustart notwendig.</strong>\n </div>\n\n <div id=\"alert-error\" style=\"display: none;\" class=\"fixed-top mx-auto alert alert-error alert-dismissible fade\"\n role=\"alert\">\n <strong>Ein Fehler ist aufgetreten</strong>\n </div>\n\n <div id=\"alert-exec\" style=\"display: none;\" class=\"fixed-top mx-auto alert alert-success alert-dismissible fade\"\n role=\"alert\">\n <strong>Kommando ausgeführt</strong>\n </div>\n\n <div id=\"modal-upload\" class=\"modal\" tabindex=\"-1\" role=\"dialog\">\n <div class=\"modal-dialog\" role=\"document\">\n <div class=\"modal-content\">\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Log Datei erfolgreich hochgeladen</h5>\n <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\">\n <span aria-hidden=\"true\">×</span>\n </button>\n </div>\n <div class=\"modal-body\">\n <p>Log Datei <strong><span id=\"log-name\"></span></strong> hochgeladen</p>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-secondary\" data-dismiss=\"modal\">Schliessen</button>\n </div>\n </div>\n </div>\n </div>\n\n <div id=\"modal-nickname\" class=\"modal\" tabindex=\"-1\" role=\"dialog\">\n <div class=\"modal-dialog\" role=\"document\">\n <div class=\"modal-content\">\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Log Versand</h5>\n <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\">\n <span aria-hidden=\"true\">×</span>\n </button>\n </div>\n <div class=\"modal-body\">\n <input id=\"nickname\" placeholder=\"Nickname\" type=\"text\" class=\"form-control\" style=\"width: 240px;\">\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-secondary\" data-dismiss=\"modal\">Abbrechen</button>\n <button type=\"button\" class=\"btn btn-primary\" id=\"log-upload-do\">Log versenden</button>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"tab-content\" id=\"myTabContent\">\n <div class=\"tab-pane fade show\" id=\"configuration\" role=\"tabpanel\" aria-labelledby=\"configuration-tab\">\n\n<!-- Henke\n <div id=\"update-notify\" class=\"card mb-4\" style=\"border-color: orange; display: none;\">\n <div class=\"card-body\">\n RedMatic Update steht zur Verfügung: <span id=\"update-link\"></span> (siehe <a\n href=\"https://github.com/rdmtc/RedMatic/wiki/Update\" target=\"_blank\">Installationsanleitung\n im RedMatic Wiki</a>)\n </div>\n </div>\n//-->\n\n <div class=\"card mb-4\">\n\n <div class=\"card-body\">\n <label style=\"display: block\">Node-RED Prozess</label>\n <!--<a id=\"backup\" role=\"button\" class=\"btn btn-sm btn-primary mr-3 disabled\">Backup</a>-->\n <div class=\"dropdown\" style=\"display: inline-block\">\n <button type=\"button\" class=\"btn btn-sm btn-warning dropdown-toggle\" id=\"dropdownRestart\"\n data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\">\n <i class=\"fa fa-sync-alt\"></i> Neustart\n </button>\n\n <div class=\"dropdown-menu\" aria-labelledby=\"dropdownMenuButton\">\n <a id=\"restart\" class=\"dropdown-item\" href=\"#\">Normal</a>\n <a id=\"restartSafe\" class=\"dropdown-item\" href=\"#\">Safe Mode</a>\n </div>\n </div>\n\n <button id=\"stop\" type=\"button\" class=\"btn btn-sm btn-warning\"><i class=\"fa fa-stop\"></i>\n Stop</button>\n\n <div class=\"dropdown\" style=\"display: inline-block\">\n <button type=\"button\" class=\"btn btn-sm btn-warning dropdown-toggle\" id=\"dropdownStart\"\n data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\">\n <i class=\"fa fa-play\"></i> Start\n </button>\n\n <div class=\"dropdown-menu\" aria-labelledby=\"dropdownMenuButton\">\n <a id=\"start\" class=\"dropdown-item\" href=\"#\">Normal</a>\n <a id=\"startSafe\" class=\"dropdown-item\" href=\"#\">Safe Mode</a>\n </div>\n </div>\n\n <div style=\"width: 30px; display: inline-block\">\n <div id=\"status-spinner\" class=\"spinner-border spinner-border-sm ml-2 mr-2\" role=\"status\"\n style=\"color: #6a737d; display: inline-block;\">\n <span class=\"sr-only\">Please wait...</span>\n </div>\n </div>\n\n <div style=\"vertical-align: middle; display: inline-block; width: 210px; font-size: 11px; color: grey;\"\n class=\"\">\n <div><span id=\"node-red-status\" style=\"font-weight: bold;\"></span></div>\n <div>\n <span id=\"node-red-cpu\" style=\"font-weight: bold;\"></span><span id=\"node-red-memory\"\n style=\"font-weight: bold;\"></span>\n </div>\n </div>\n </div>\n </div>\n\n<!-- Henke\n <div class=\"card mb-4 pr-4\">\n <div class=\"card-body\">\n <div class=\"form-group\">\n <label for=\"projects\">Backup <a href=\"https://github.com/rdmtc/RedMatic/wiki/Backup\"\n class=\"help-link\" target=\"_blank\"><i class=\"far fa-question-circle\"></i></a></label>\n <select class=\"form-control\" id=\"backup\">\n <option value=\"reduce\">Reduziere Backupgröße - nur relevante Daten inkludieren\n </option>\n <option value=\"full\">Alles im Backup inkludieren - Warnung: das kann u.U. zu Problemen\n mit dem Backup/Restore führen!</option>\n </select>\n </div>\n </div>\n </div>\n//-->\n\n <div class=\"card mb-4 pr-4\">\n <div class=\"card-body\">\n <div class=\"form-group\">\n <label>Context Storage <a href=\"https://github.com/rdmtc/RedMatic/wiki/Context-Storage\"\n class=\"help-link\" target=\"_blank\"><i class=\"far fa-question-circle\"></i></a></label>\n <div class=\"row mb-2\">\n <div class=\"col-sm-3\" style=\"line-height: 38px;\">\n default\n </div>\n <div class=\"col-sm-9\">\n <select class=\"form-control\" id=\"context-storage-default\">\n <option>memory</option>\n <option>file</option>\n </select>\n </div>\n </div>\n <div class=\"row mb-2\">\n <div class=\"col-sm-3\" style=\"line-height: 38px;\">\n <code id=\"context-memory-title\">memory</code>\n </div>\n <div class=\"col-sm-9\"\n style=\"min-height: 26px; padding: 6px 22px; vertical-align: middle; color: grey; font-style: italic;\">\n memory\n </div>\n </div>\n\n <div class=\"row mb-2\">\n <div class=\"col-sm-3\" style=\"line-height: 38px;\">\n <code id=\"context-file-title\">file</code>\n </div>\n <div class=\"col-sm-6\">\n <input class=\"form-control\" id=\"context-storage-file-path\" placeholder=\"Path\" required>\n </div>\n <div class=\"col-sm-3\">\n <input class=\"form-control\" type=\"number\" id=\"context-storage-file-interval\"\n placeholder=\"Schreibintervall\">\n </div>\n </div>\n\n </div>\n </div>\n </div>\n\n <div class=\"card mb-4 pr-4\">\n <div class=\"card-body\">\n <div class=\"form-group\">\n <label for=\"projects\">Projekte <a href=\"https://github.com/rdmtc/RedMatic/wiki/Projekte\"\n class=\"help-link\" target=\"_blank\"><i class=\"far fa-question-circle\"></i></a></label>\n <select class=\"form-control\" id=\"projects\">\n <option value=\"false\">Nicht verwenden</option>\n <option value=\"true\">Aktiv</option>\n </select>\n </div>\n </div>\n </div>\n\n <div class=\"card mb-4 pr-4\">\n <div class=\"card-body\">\n <div class=\"form-group\">\n <label for=\"theme\">Theme</label>\n <select class=\"form-control\" id=\"theme\">\n <option value=\"default\">standard</option>\n <option value=\"midnight-red\">midnight-red</option>\n <option value=\"totallyinformation\">totallyinformation</option>\n </select>\n </div>\n </div>\n </div>\n\n <div class=\"card mb-4\">\n <div class=\"card-body\">\n <div class=\"form-group\">\n <label>Authentifizierung <a href=\"https://github.com/rdmtc/RedMatic/wiki/Passwort\"\n class=\"help-link\" target=\"_blank\"><i class=\"far fa-question-circle\"></i></a></label>\n <div class=\"row mb-3\">\n <div class=\"col-sm-3\" style=\"line-height: 38px;\">\n Admin\n </div>\n <div class=\"col-sm-9\">\n <div class=\"row mb-2 col-sm-12\">\n <select class=\"form-control\" id=\"adminauth-type\">\n <option value=\"none\">Keine Authentifizierung</option>\n <option value=\"credentials\">Username/Passwort individuell</option>\n <!-- <option value=\"rega\">ReGaHSS (CCU WebUI User nutzen)</option> -->\n </select>\n </div>\n <div id=\"adminauth-expiry\" class=\"col-sm-12 row mb-1\" style=\"display: none\">\n <label class=\"col-sm-6 mt-2\" for=\"adminauth-sessionExpiryTime\">Session Timeout\n (Sekunden)</label>\n <input class=\"col-sm-6 form-control\" id=\"adminauth-sessionExpiryTime\" placeholder=\"\"\n type=\"number\">\n </div>\n <div id=\"adminauth-credentials\" class=\"col-sm-12 row pl-0 pr-0\" style=\"display: none\">\n <div class=\"col-sm\">\n <input class=\"form-control\" id=\"adminauth-user\" placeholder=\"User\" required>\n </div>\n <div class=\"col-sm\">\n <input class=\"form-control\" type=\"password\" id=\"adminauth-pass1\"\n placeholder=\"Passwort\">\n </div>\n <div class=\"col-sm\">\n <input class=\"form-control\" type=\"password\" id=\"adminauth-pass2\"\n placeholder=\"Passwort wiederholen\">\n </div>\n <div class=\"col-md-auto\">\n <button id=\"adminauth-set\" type=\"button\"\n class=\"btn btn-primary\">Übernehmen</button>\n </div>\n </div>\n </div>\n </div>\n <div class=\"row mb-3\">\n <div class=\"col-sm-3\" style=\"line-height: 38px;\">\n Node\n </div>\n <div class=\"col-sm-9\">\n <div class=\"row mb-1 col-sm-12\">\n <select class=\"form-control\" id=\"nodeauth-type\">\n <option value=\"none\">Keine Authentifizierung</option>\n <option value=\"basic\">Username/Passwort individuell</option>\n </select>\n </div>\n <div id=\"nodeauth-credentials\" class=\"col-sm-12 row pl-0 pr-0\" style=\"display: none\">\n <div class=\"col-sm\">\n <input class=\"form-control\" id=\"nodeauth-user\" placeholder=\"User\">\n </div>\n <div class=\"col-sm\">\n <input class=\"form-control\" type=\"password\" id=\"nodeauth-pass1\"\n placeholder=\"Passwort\">\n </div>\n <div class=\"col-sm\">\n <input class=\"form-control\" type=\"password\" id=\"nodeauth-pass2\"\n placeholder=\"Passwort wiederholen\">\n </div>\n <div class=\"col-md-auto\">\n <button id=\"nodeauth-set\" type=\"button\"\n class=\"btn btn-primary\">Übernehmen</button>\n </div>\n </div>\n </div>\n </div>\n <div class=\"row mb-3\">\n <div class=\"col-sm-3\" style=\"line-height: 38px;\">\n Static\n </div>\n <div class=\"col-sm-9\">\n <div class=\"row mb-1 col-sm-12\">\n <select class=\"form-control\" id=\"staticauth-type\">\n <option value=\"none\">Keine Authentifizierung</option>\n <option value=\"basic\">Username/Passwort individuell</option>\n </select>\n </div>\n <div id=\"staticauth-credentials\" class=\"col-sm-12 row pl-0 pr-0\" style=\"display: none\">\n <div class=\"col-sm\">\n <input class=\"form-control\" id=\"staticauth-user\" placeholder=\"User\">\n </div>\n <div class=\"col-sm\">\n <input class=\"form-control\" type=\"password\" id=\"staticauth-pass1\"\n placeholder=\"Passwort\">\n </div>\n <div class=\"col-sm\">\n <input class=\"form-control\" type=\"password\" id=\"staticauth-pass2\"\n placeholder=\"Passwort wiederholen\">\n </div>\n <div class=\"col-md-auto\">\n <button id=\"staticauth-set\" type=\"button\"\n class=\"btn btn-primary\">Übernehmen</button>\n </div>\n </div>\n </div>\n </div>\n\n </div>\n\n </div>\n </div>\n\n </div>\n\n<!-- Henke\n <div class=\"tab-pane fade show\" id=\"packages\" role=\"tabpanel\" aria-labelledby=\"packages-tab\">\n\n <div id=\"package-hint\" class=\"card mb-4\" style=\"border-color: blue; display: none;\">\n <div class=\"card-body\">\n <button type=\"button\" class=\"btn btn-mini btn-info\" id=\"discard-package-hint\" style=\"padding: 0px 8px 2px; margin-top: -4px;\">x</button>\n <b>Tipp:</b> Nicht-verwendete Pakete deinstallieren, das spart Speicher und reduziert den RAM-Bedarf und die Startzeit von Node-RED.\n </div>\n </div>\n\n <table id=\"table-packages\" class=\"table\">\n <thead>\n <tr>\n <th scope=\"col\" style=\"min-width: 300px;\">Paket</th>\n <th scope=\"col\" style=\"min-width: 120px;\">Version</th>\n <th scope=\"col\" style=\"min-width: 80px; width: 80px;\">Installiert</th>\n <th scope=\"col\" style=\"min-width: 300px;\"></th>\n </tr>\n <tr>\n <th scope=\"col\"><input class=\"form-control form-control-sm\" id=\"package-filter\"></th>\n <th scope=\"col\"></th>\n <th scope=\"col\"></th>\n <th scope=\"col\"></th>\n </tr>\n </thead>\n <tbody id=\"package-table\">\n\n </tbody>\n </table>\n <div id=\"pkg-spinner\" class=\"text-center\">\n <div class=\"spinner-border text-center\" role=\"status\">\n <span class=\"sr-only\">Lade...</span>\n </div>\n </div>\n </div>\n//-->\n\n <div class=\"tab-pane fade show\" id=\"versions\" role=\"tabpanel\" aria-labelledby=\"versions-tab\">\n\n <div class=\"card mb-4\">\n <div class=\"card-body\">\n <div class=\"form-group\">\n <label for=\"loglevel\">Log Level</label>\n <select class=\"form-control\" id=\"loglevel\">\n <option>fatal</option>\n <option>error</option>\n <option>warn</option>\n <option>info</option>\n <option>debug</option>\n <option>trace</option>\n </select>\n </div>\n\n </div>\n </div>\n\n <div class=\"card mb-4\">\n <div class=\"card-body\">\n <div class=\"form-group\">\n <button id=\"log\" type=\"button\" class=\"btn btn-sm btn-info\"><i class=\"fa fa-download\"></i>\n Log herunterladen</button>\n\n\n <button id=\"log-upload\" type=\"button\" class=\"btn btn-sm btn-info\" style=\"display:none;\"><i\n class=\"fa fa-upload\"></i> Log versenden</button>\n <div id=\"log-upload-spinner\" class=\"spinner-border spinner-border-sm ml-2 mr-2\" role=\"status\"\n style=\"color: #6a737d; display: none;\">\n <span class=\"sr-only\">Please wait...</span>\n </div>\n\n\n </div>\n </div>\n </div>\n\n\n <div class=\"card mb-4\">\n <div class=\"card-body\">\n <div class=\"form-group\">\n <label for=\"autorestart\">Node-RED im Falle eines Absturzes neu starten</label>\n <select class=\"form-control\" id=\"autorestart\">\n <option value=\"0\">Deaktiviert</option>\n <option value=\"1\">Einmal</option>\n <option value=\"2\">Zweimal</option>\n <option value=\"3\">Dreimal</option>\n <option value=\"4\">Viermal</option>\n <option value=\"5\">Fünfmal</option>\n <option value=\"2147483647\">Unbegrenzt</option>\n </select>\n </div>\n <p>Node-RED Abstürze seit letztem RedMatic-Start: <span id=\"restarts\">keine</span></p>\n </div>\n </div>\n\n </div>\n\n <div class=\"tab-pane fade show\" id=\"licenses\" role=\"tabpanel\" aria-labelledby=\"licenses-tab\">\n <iframe></iframe>\n </div>\n\n\n </div>\n</div>\n\n<script src=\"js/script.js\"></script>",
"output": "str",
"x": 970,
"y": 300,
"wires": [
[
"eb41e227ba32cd94"
]
]
},
{
"id": "eb41e227ba32cd94",
"type": "file",
"z": "2ab1de6847dd7ea2",
"name": "www/settings.html",
"filename": "/usr/local/addons/redmatic/www/settings.html",
"filenameType": "str",
"appendNewline": false,
"createDir": true,
"overwriteFile": "true",
"encoding": "none",
"x": 1190,
"y": 300,
"wires": [
[
"001c9a1b2a7e8e2e"
]
]
},
{
"id": "001c9a1b2a7e8e2e",
"type": "template",
"z": "2ab1de6847dd7ea2",
"name": "default-settings.json",
"field": "payload",
"fieldType": "msg",
"format": "json",
"syntax": "plain",
"template": "{\n \"uiPort\": 1880,\n \"uiHost\": \"127.0.0.1\",\n \"flowFile\": \"flows.json\",\n \"userDir\": \"/usr/local/addons/redmatic/var\",\n \"httpRoot\": \"/addons/red\",\n \"logging\": {\n \"ain\": {\n \"level\": \"info\",\n \"metrics\": false,\n \"audit\": false\n }\n },\n \"contextStorage\": {\n \"default\": {\n \"module\": \"memory\"\n },\n \"memory\": {\n \"module\": \"memory\"\n },\n \"file\": {\n \"module\": \"localfilesystem\",\n \"config\": {\n \"dir\": \"/usr/local/addons/redmatic/var\",\n \"flushInterval\": 300\n }\n }\n },\n \"editorTheme\": {\n \"projects\": {\n \"enabled\": false\n }\n },\n \"adminAuth\": {\n \"sessionExpiryTime\": 86400\n },\n \"restartOnCrash\": 0\n}",
"output": "str",
"x": 480,
"y": 340,
"wires": [
[
"5b8172939d7a1e26"
]
]
},
{
"id": "5b8172939d7a1e26",
"type": "file",
"z": "2ab1de6847dd7ea2",
"name": "etc/default-settings.json",
"filename": "/usr/local/addons/redmatic/etc/default-settings.json",
"filenameType": "str",
"appendNewline": false,
"createDir": true,
"overwriteFile": "true",
"encoding": "none",
"x": 730,
"y": 340,
"wires": [
[
"70bdbbad9e26b78d"
]
]
},
{
"id": "4c6951d8ab085736",
"type": "template",
"z": "2ab1de6847dd7ea2",
"name": "mount",
"field": "payload",
"fieldType": "msg",
"format": "markdown",
"syntax": "mustache",
"template": "#!/bin/sh\nmount -o rw,remount /\nsleep 10\nchmod -R a+rwx /usr/local/addons/redmatic",
"output": "str",
"x": 950,
"y": 140,
"wires": [
[
"f1c29c21b7b7338a"
]
]
},
{
"id": "1900d9b72af1a2d8",
"type": "template",
"z": "2ab1de6847dd7ea2",
"name": "mount",
"field": "payload",
"fieldType": "msg",
"format": "markdown",
"syntax": "mustache",
"template": "#!/bin/sh\nchmod -R a+rwx /usr/local/addons/redmatic\nmount -o ro,remount /",
"output": "str",
"x": 1090,
"y": 480,
"wires": [
[
"eda7f0ecc302657e"
]
]
},
{
"id": "8abba785cac84dc4",
"type": "file in",
"z": "2ab1de6847dd7ea2",
"name": "versions",
"filename": "/usr/local/addons/redmatic/versions",
"filenameType": "str",
"format": "utf8",
"chunk": false,
"sendError": false,
"encoding": "none",
"allProps": false,
"x": 140,
"y": 280,
"wires": [
[
"82abbf82a75e4ea3"
]
]
},
{
"id": "82abbf82a75e4ea3",
"type": "function",
"z": "2ab1de6847dd7ea2",
"name": "check",
"func": "const key = \"VERSION_ADDON=\";\nlet ist = msg.payload.substring(msg.payload.indexOf(key) + key.length);\nist = ist.substring(0, ist.indexOf(\"\\n\"));\n// msg.ist = ist;\nlet ref = msg.VersionAddOn;\nlet cmp = cmpVersion(ist, ref);\nmsg.AddOn_ok = (cmp >= 0);\nif (!msg.AddOn_ok)\n return msg;\nreturn [null,msg];\n\nfunction cmpVersion(aa, bb) {\n const aArr = aa.split(\".\");\n const bArr = bb.split(\".\");\n const min = Math.min(aArr.length, bArr.length);\n for (let index = 0; index < min; index++) {\n if (aArr[index] != bArr[index])\n return (aArr[index] - bArr[index]);\n }\n return 0;\n}",
"outputs": 2,
"timeout": "",
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 270,
"y": 280,
"wires": [
[
"85fa60362bb04a1a"
],
[
"33e539048f9a09f1"
]
]
},
{
"id": "3b8d7efc8f41e5f5",
"type": "inject",
"z": "2ab1de6847dd7ea2",
"name": "erzwungen Patch 7.3.5",
"props": [
{
"p": "topic",
"vt": "str"
},
{
"p": "VersionAddOn",
"v": "7.3.5",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "Patch,einmal bei neuem Flow",
"x": 180,
"y": 380,
"wires": [
[
"85fa60362bb04a1a"
]
],
"icon": "font-awesome/fa-play-circle"
},
{
"id": "33e539048f9a09f1",
"type": "debug",
"z": "2ab1de6847dd7ea2",
"name": "Patch aktuell",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "\"Patch aktuell\"",
"targetType": "jsonata",
"statusVal": "msg.Process.NodeVersion",
"statusType": "auto",
"x": 150,
"y": 320,
"wires": []
},
{
"id": "7d35a6579c0a2026",
"type": "template",
"z": "2ab1de6847dd7ea2",
"name": ".profile",
"field": "payload",
"fieldType": "msg",
"format": "markdown",
"syntax": "plain",
"template": "export PATH=/usr/local/addons/redmatic/bin:/usr/local/bin:/usr/bin:$PATH\nexport LD_LIBRARY_PATH=/usr/local/addons/redmatic/lib:/usr/local/lib:/usr/lib\nexport HOME=/usr/local/addons/redmatic/home\nexport GIT_EXEC_PATH=/usr/local/addons/redmatic/libexec/git-core\nexport GIT_TEMPLATE_DIR=/usr/local/addons/redmatic/share/git-core/templates\nexport NO_UPDATE_NOTIFIER=true",
"output": "str",
"x": 430,
"y": 380,
"wires": [
[
"dee60a8eb7a86f2b"
]
]
},
{
"id": "6de4e13207fb3de5",
"type": "template",
"z": "2ab1de6847dd7ea2",
"name": ".profileRoot",
"field": "payload",
"fieldType": "msg",
"format": "markdown",
"syntax": "plain",
"template": "export PATH=/usr/local/bin\nexport LD_LIBRARY_PATH=/usr/local/lib:/usr/lib\nexport HOME=/usr/local/addons/redmatic/home\nexport GIT_EXEC_PATH=/usr/local/addons/redmatic/libexec/git-core\nexport GIT_TEMPLATE_DIR=/usr/local/addons/redmatic/share/git-core/templates\nexport NO_UPDATE_NOTIFIER=true",
"output": "str",
"x": 970,
"y": 380,
"wires": [
[
"f96c2071a00c11a3"
]
]
},
{
"id": "70bdbbad9e26b78d",
"type": "template",
"z": "2ab1de6847dd7ea2",
"name": "Update node-red",
"field": "payload",
"fieldType": "msg",
"format": "handlebars",
"syntax": "mustache",
"template": "#!/bin/sh\ncd /usr/local/addons/redmatic/lib\nsource /usr/local/addons/redmatic/home/.profile\n\nlogger -t redmatic -p daemon.info \"Henke Script updateNodeRed.sh\"\n\nVersionWeb=cat npm view node-red version\nnpm install node-red@$VersionWeb\nlogger -t redmatic -p daemon.info \"Henke Script updateNodeRed.sh node-red done\"\nnpm install @node-red-contrib-themes/theme-collection\nlogger -t redmatic -p daemon.info \"Henke Script updateNodeRed.sh theme-collection done\"\n",
"output": "str",
"x": 990,
"y": 340,
"wires": [
[
"9f4a6594386fabb9"
]
]
},
{
"id": "9f4a6594386fabb9",
"type": "file",
"z": "2ab1de6847dd7ea2",
"name": "bin/updateNodeRed.sh",
"filename": "/usr/local/addons/redmatic/bin/updateNodeRed.sh",
"filenameType": "str",
"appendNewline": false,
"createDir": true,
"overwriteFile": "true",
"encoding": "none",
"x": 1200,
"y": 340,
"wires": [
[
"7d35a6579c0a2026"
]
]
},
{
"id": "85fa60362bb04a1a",
"type": "file in",
"z": "2ab1de6847dd7ea2",
"name": "",
"filename": "/boot/VERSION",
"filenameType": "str",
"format": "utf8",
"chunk": false,
"sendError": false,
"encoding": "none",
"allProps": false,
"x": 460,
"y": 140,
"wires": [
[
"aec8a9833a7f477a"
]
]
},
{
"id": "aec8a9833a7f477a",
"type": "function",
"z": "2ab1de6847dd7ea2",
"name": "RasberryMatic?",
"func": "if ( msg.payload.indexOf(\"PRODUCT=raspmatic\") < 0 )\n{\n node.warn(\"Kein RasberryMatic\");\n return;\n}\n\nconst key = \"VERSION=\";\nlet ist = msg.payload.substring(msg.payload.indexOf(key) + key.length);\nist = ist.substring ( 0, ist.indexOf(\"\\n\"));\n// msg.ist = ist;\nlet ref = \"3.71.12.20231013\";\nlet cmp = cmpVersion(ist, ref);\nmsg.node_js_ok = (cmp >=0);\nreturn msg;\n\nfunction cmpVersion(aa, bb) {\n const aArr = aa.split(\".\");\n const bArr = bb.split(\".\");\n const min = Math.min(aArr.length, bArr.length);\n for (let index = 0; index < min; index++) {\n if (aArr[index] != bArr[index])\n return (aArr[index] - bArr[index]);\n }\n return 0;\n}",
"outputs": 1,
"timeout": "",
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 700,
"y": 140,
"wires": [
[
"4c6951d8ab085736"
]
]
},
{
"id": "f1c29c21b7b7338a",
"type": "file",
"z": "2ab1de6847dd7ea2",
"name": "Schreibe Script",
"filename": "/usr/local/update/_run.sh",
"filenameType": "str",
"appendNewline": false,
"createDir": true,
"overwriteFile": "true",
"encoding": "none",
"x": 1180,
"y": 140,
"wires": [
[
"0f65a59c71d5cefe"
]
]
},
{
"id": "0f65a59c71d5cefe",
"type": "exec",
"z": "2ab1de6847dd7ea2",
"command": "sh /usr/local/update/_run.sh",
"addpay": "",
"append": "",
"useSpawn": "false",
"timer": "",
"winHide": false,
"oldrc": false,
"name": "Ausführen",
"x": 1410,
"y": 140,
"wires": [
[],
[
"ffa53e6eff89319c"
],
[
"e435bc41d8c9739d"
]
]
},
{
"id": "ffa53e6eff89319c",
"type": "debug",
"z": "2ab1de6847dd7ea2",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "counter",
"x": 1525,
"y": 140,
"wires": [],
"l": false
},
{
"id": "2d6177b5c2a97ca9",
"type": "file",
"z": "2ab1de6847dd7ea2",
"name": "Schreibe Script",
"filename": "/usr/local/update/_run.sh",
"filenameType": "str",
"appendNewline": false,
"createDir": true,
"overwriteFile": "true",
"encoding": "none",
"x": 700,
"y": 480,
"wires": [
[
"9e84ed95b487240c"
]
]
},
{
"id": "9e84ed95b487240c",
"type": "exec",
"z": "2ab1de6847dd7ea2",
"command": "sh /usr/local/update/_run.sh",
"addpay": "",
"append": "",
"useSpawn": "false",
"timer": "",
"winHide": false,
"oldrc": false,
"name": "Ausführen",
"x": 870,
"y": 480,
"wires": [
[],
[
"7d14f0f429c0f826"
],
[
"1900d9b72af1a2d8"
]
]
},
{
"id": "7d14f0f429c0f826",
"type": "debug",
"z": "2ab1de6847dd7ea2",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "counter",
"x": 975,
"y": 480,
"wires": [],
"l": false
},
{
"id": "eda7f0ecc302657e",
"type": "file",
"z": "2ab1de6847dd7ea2",
"name": "Schreibe Script",
"filename": "/usr/local/update/_run.sh",
"filenameType": "str",
"appendNewline": false,
"createDir": true,
"overwriteFile": "true",
"encoding": "none",
"x": 1240,
"y": 480,
"wires": [
[
"591f97800f8e5ab6"
]
]
},
{
"id": "591f97800f8e5ab6",
"type": "exec",
"z": "2ab1de6847dd7ea2",
"command": "sh /usr/local/update/_run.sh",
"addpay": "",
"append": "",
"useSpawn": "false",
"timer": "",
"winHide": false,
"oldrc": false,
"name": "Ausführen",
"x": 1410,
"y": 480,
"wires": [
[],
[
"abb099706360873f"
],
[
"42584b3b89350e87"
]
]
},
{
"id": "abb099706360873f",
"type": "debug",
"z": "2ab1de6847dd7ea2",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "counter",
"x": 1535,
"y": 480,
"wires": [],
"l": false
},
{
"id": "dee60a8eb7a86f2b",
"type": "file",
"z": "2ab1de6847dd7ea2",
"name": "home/.profile",
"filename": "/usr/local/addons/redmatic/home/.profile",
"filenameType": "str",
"appendNewline": false,
"createDir": true,
"overwriteFile": "true",
"encoding": "none",
"x": 690,
"y": 380,
"wires": [
[
"6de4e13207fb3de5"
]
]
},
{
"id": "f96c2071a00c11a3",
"type": "file",
"z": "2ab1de6847dd7ea2",
"name": "home/.profileRoot",
"filename": "/usr/local/addons/redmatic/home/.profileRoot",
"filenameType": "str",
"appendNewline": false,
"createDir": true,
"overwriteFile": "true",
"encoding": "none",
"x": 1190,
"y": 380,
"wires": [
[
"0aa2148e71e010d7"
]
]
},
{
"id": "9d7cfabd2bbf2be3",
"type": "template",
"z": "2ab1de6847dd7ea2",
"name": "checkNR.js",
"field": "payload",
"fieldType": "msg",
"format": "javascript",
"syntax": "plain",
"template": "const fs = require('fs');\n\nconst addOn = '/usr/local/addons/redmatic/';\nconst settings = addOn + '/etc/settings.json';\nconst restartOnCrash = require(settings).restartOnCrash;\n// console.log(\"RedMatic settings.js NodeRed: \" + restartOnCrash );\nlet out = \"\";\n\nlet runUpdateNodeRed = false;\n{\n let msg = {};\n\n try {\n const nodeRed = addOn + 'lib/node_modules/node-red/package.json';\n const nodeRedVersion = require(nodeRed).version;\n// console.info(\"RedMatic checkNR.js NodeRed: \" + nodeRedVersion);\n msg.payload = nodeRedVersion;\n msg.AddOn_ok = (cmpVersion(nodeRedVersion, \"3.0.0\") >= 0);\n if (!msg.AddOn_ok)\n runUpdateNodeRed = true;\n }\n catch\n {\n// console.error(\"RedMatic checkNR.js Error NodeRed fehlt?\");\n runUpdateNodeRed = true;\n }\n\n function cmpVersion(aa, bb) {\n const aArr = aa.split(\".\");\n const bArr = bb.split(\".\");\n const min = Math.min(aArr.length, bArr.length);\n for (let index = 0; index < min; index++) {\n if (aArr[index] != bArr[index])\n return (aArr[index] - bArr[index]);\n }\n return 0;\n }\n\n const prefix = \"RedSettings_\";\n out += prefix + \"RestartOnCrash\" + \"=\" + restartOnCrash + \"\\n\";\n out += prefix + \"NodeRedUpdate\" + \"=\" + runUpdateNodeRed + \"\\n\";\n\n fs.writeFileSync('/tmp/red-settings', out);\n}\n\n//process.stdout.write(out);",
"output": "str",
"x": 450,
"y": 420,
"wires": [
[
"227744a2ca3ffd24"
]
]
},
{
"id": "227744a2ca3ffd24",
"type": "file",
"z": "2ab1de6847dd7ea2",
"name": "bin/checkNR.js",
"filename": "/usr/local/addons/redmatic/bin/checkNR.js",
"filenameType": "str",
"appendNewline": false,
"createDir": true,
"overwriteFile": "true",
"encoding": "none",
"x": 700,
"y": 420,
"wires": [
[
"372b8ef8e105c0ba"
]
]
},
{
"id": "61fccb767b94a8ac",
"type": "inject",
"z": "2ab1de6847dd7ea2",
"name": "Patch 7.3.5",
"props": [
{
"p": "topic",
"vt": "str"
},
{
"p": "VersionAddOn",
"v": "7.3.5",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "Patch,einmal bei neuem Flow",
"x": 270,
"y": 220,
"wires": [
[
"8abba785cac84dc4"
]
],
"icon": "font-awesome/fa-play-circle"
},
{
"id": "1e9fdeab1ba13c95",
"type": "comment",
"z": "2ab1de6847dd7ea2",
"name": "Hit me...",
"info": "",
"x": 100,
"y": 220,
"wires": []
},
{
"id": "5ada11e830a3b224",
"type": "comment",
"z": "2ab1de6847dd7ea2",
"name": "Warnung: NodeRed wird neu gestartet!",
"info": "",
"x": 190,
"y": 180,
"wires": []
},
{
"id": "372b8ef8e105c0ba",
"type": "template",
"z": "2ab1de6847dd7ea2",
"name": "redmaticVersions",
"field": "payload",
"fieldType": "msg",
"format": "markdown",
"syntax": "plain",
"template": "#!/bin/sh\n\n# Henke Version 1.1\nlogger -t redmatic -p daemon.info \"Henke Script redmaticVersions $1\"\n\nADDON_DIR=/usr/local/addons/redmatic\nGLOBAL_MODULES=$ADDON_DIR/lib/node_modules\nLOCAL_MODULES=$ADDON_DIR/var/node_modules\n\n#NODE=$ADDON_DIR/bin/node\n\nexport PATH=$ADDON_DIR/bin:$PATH\nexport LD_LIBRARY_PATH=$ADDON_DIR/lib:$LD_LIBRARY_PATH\nexport NO_UPDATE_NOTIFIER=true\n\nsource $ADDON_DIR/versions\n\nJO_ARGS=\"\"\n\n#scan_dir()\n#{\n# for dir in $1/*\n# do\n# dir=${dir%*/}\n# PKG=${dir##*/}\n# PKGJSON=$1/$PKG/package.json\n# if [[ -f \"$PKGJSON\" ]]; then\n# JO_ARGS=\"$JO_ARGS `jq -r '.name' $1/$PKG/package.json`=`jq -r '.version' $1/$PKG/package.json`\"\n# fi\n# case $PKG in @*)\n# scan_dir \"$1/$PKG\"\n# esac\n# done\n#}\n\n#scan_dir $GLOBAL_MODULES\n#scan_dir $LOCAL_MODULES\n\nsource /VERSION\n\nif [ -d /etc/piVCCU3 ]; then\n PRODUCT=\"pivccu3\"\nfi\n\nPLATFORM=\"$PLATFORM-`uname -m`\"\nnodejs=`node --version | cut -c 2-`\necho '{\"ccu\": {\"VERSION\": \"'$VERSION'\", \"PRODUCT\": \"'$PRODUCT'\",\"PLATFORM\": \"'$PLATFORM'\"},\"redmatic\": \"'$VERSION_ADDON'\",\"nodejs\": \"'$nodejs'\"}'\n\n#jo -p ccu=`(echo \"VERSION=$VERSION\"; echo \"PRODUCT=$PRODUCT\"; echo \"PLATFORM=$PLATFORM\" && echo -n \"deviceTypes=\" && $ADDON_DIR/bin/deviceTypes) | jo` \\\n#jo -p ccu=`(echo \"VERSION=$VERSION\"; echo \"PRODUCT=$PRODUCT\"; echo \"PLATFORM=$PLATFORM\" ) | jo` \\\n# redmatic=$VERSION_ADDON \\\n# nodejs=`node --version | cut -c 2-` \\\n# $JO_ARGS\n\n",
"output": "str",
"x": 990,
"y": 420,
"wires": [
[
"40d4e066a89307f4"
]
]
},
{
"id": "40d4e066a89307f4",
"type": "file",
"z": "2ab1de6847dd7ea2",
"name": "bin/redmaticVersions",
"filename": "/usr/local/addons/redmatic/bin/redmaticVersions",
"filenameType": "str",
"appendNewline": false,
"createDir": true,
"overwriteFile": "true",
"encoding": "none",
"x": 1200,
"y": 420,
"wires": [
[
"0ea2818262334c44"
]
]
},
{
"id": "0aa2148e71e010d7",
"type": "template",
"z": "2ab1de6847dd7ea2",
"name": ".npmrc",
"field": "payload",
"fieldType": "msg",
"format": "markdown",
"syntax": "plain",
"template": "prefix=/usr/local\ncache=/tmp/npm-cache\n",
"output": "str",
"x": 1390,
"y": 380,
"wires": [
[
"c1fc15dc666dfe56"
]
]
},
{
"id": "c1fc15dc666dfe56",
"type": "file",
"z": "2ab1de6847dd7ea2",
"name": "home/.profileRoot",
"filename": "/usr/local/addons/redmatic/home/.npmrc",
"filenameType": "str",
"appendNewline": false,
"createDir": true,
"overwriteFile": "true",
"encoding": "none",
"x": 1550,
"y": 380,
"wires": [
[
"0ea2818262334c44"
]
]
},
{
"id": "665899be2814dfb7",
"type": "group",
"z": "2ab1de6847dd7ea2",
"style": {
"stroke": "#2e333a",
"stroke-opacity": "1",
"fill": "#2e333a",
"fill-opacity": "0.75",
"label": true,
"label-position": "nw",
"color": "#a4a4a4"
},
"nodes": [
"e28522bbbf4ccec3",
"62227816a2ee54e2",
"42584b3b89350e87",
"0270d062629f4e2c"
],
"x": 1494,
"y": 619,
"w": 452,
"h": 122
},
{
"id": "e28522bbbf4ccec3",
"type": "inject",
"z": "2ab1de6847dd7ea2",
"g": "665899be2814dfb7",
"name": "Warnung: NodeRed wird neu gestartet!",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "true",
"payloadType": "bool",
"x": 1690,
"y": 660,
"wires": [
[
"42584b3b89350e87"
]
]
},
{
"id": "62227816a2ee54e2",
"type": "http request",
"z": "2ab1de6847dd7ea2",
"g": "665899be2814dfb7",
"name": "Local",
"method": "POST",
"ret": "txt",
"paytoqs": "ignore",
"url": "http://127.0.0.0:8181/a.exe",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [],
"x": 1790,
"y": 700,
"wires": [
[
"0270d062629f4e2c"
]
]
},
{
"id": "42584b3b89350e87",
"type": "template",
"z": "2ab1de6847dd7ea2",
"g": "665899be2814dfb7",
"name": "Restart NodeRed",
"field": "payload",
"fieldType": "msg",
"format": "handlebars",
"syntax": "mustache",
"template": "system.Exec(\"/usr/local/addons/redmatic/bin/redmatic restart &\");",
"output": "str",
"x": 1630,
"y": 700,
"wires": [
[
"62227816a2ee54e2"
]
]
},
{
"id": "0270d062629f4e2c",
"type": "debug",
"z": "2ab1de6847dd7ea2",
"g": "665899be2814dfb7",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": true,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "counter",
"x": 1885,
"y": 700,
"wires": [],
"l": false
}
]