iobroker.amazon-dash
Advanced tools
| <html> | ||
| <link rel="stylesheet" type="text/css" href="../../css/adapter.css"/> | ||
| <link rel="stylesheet" type="text/css" href="../../lib/css/materialize.css"> | ||
| <script type="text/javascript" src="../../lib/js/jquery-3.2.1.min.js"></script> | ||
| <script type="text/javascript" src="../../socket.io/socket.io.js"></script> | ||
| <script type="text/javascript" src="../../js/translate.js"></script> | ||
| <script type="text/javascript" src="../../lib/js/materialize.js"></script> | ||
| <script type="text/javascript" src="../../js/adapter-settings.js"></script> | ||
| <script type="text/javascript" src="words.js"></script> | ||
| <style> | ||
| .table_header { | ||
| background-color: blue; | ||
| color: white; | ||
| } | ||
| .ip { | ||
| width: 150px; | ||
| text-align: right; | ||
| } | ||
| </style> | ||
| <!-- you have to define 2 functions in the global scope: --> | ||
| <script type="text/javascript"> | ||
| var devices = []; | ||
| // the function loadSettings has to exist ... | ||
| function load(settings, onChange) { | ||
| if (!settings) return; | ||
| devices = settings.devices || []; | ||
| for (var key in settings) { | ||
| setValue(key, settings[key], onChange); | ||
| } | ||
| if (typeof values2table === 'function') { | ||
| $('#devices').hide(); | ||
| $('#pager-devices').hide(); | ||
| values2table('values', devices, onChange); | ||
| } else { | ||
| editTable('devices', ['name', 'mac'], devices, 350); | ||
| $('#values').hide(); | ||
| } | ||
| onChange(false); | ||
| } | ||
| // ... and the function save has to exist. | ||
| // you have to make sure the callback is called with the settings object as first param! | ||
| function save(callback) { | ||
| // example: select elements with class=value and build settings object | ||
| var obj = {}; | ||
| $('.value').each(function () { | ||
| var $this = $(this); | ||
| obj[$this.attr('id')] = $this.val(); | ||
| }); | ||
| // Get edited table | ||
| if (typeof table2values === 'function') { | ||
| obj.devices = table2values('values'); | ||
| } else { | ||
| obj.devices = getTableResult('devices', ['name', 'mac']); | ||
| } | ||
| callback(obj); | ||
| } | ||
| function setValue(id, value, onChange) { | ||
| // example: select elements with id=key and class=value and insert value | ||
| $('#' + id + '.value').val(value).change(function () { | ||
| onChange(); | ||
| }).keyup(function () { | ||
| // Chack that only numbers entered | ||
| if ($(this).hasClass('number')) { | ||
| var val = $(this).val(); | ||
| if (val) { | ||
| var newVal = ''; | ||
| for (var i = 0; i < val.length; i++) { | ||
| if (val[i] >= '0' && val[i] <= '9') { | ||
| newVal += val[i]; | ||
| } | ||
| } | ||
| if (val != newVal) $(this).val(newVal); | ||
| } | ||
| } | ||
| onChange(); | ||
| }); | ||
| } | ||
| </script> | ||
| <style> | ||
| #settings tr { | ||
| line-height: 2.5em; | ||
| } | ||
| </style> | ||
| <!-- you have to put your config page in a div with id adapter-container --> | ||
| <div class="m adapter-container"> | ||
| <div class="row"> | ||
| <div class="input-field col s6"> | ||
| <img src="amazon-dash.png" class="logo"> | ||
| </div> | ||
| </div> | ||
| <!--table> | ||
| <tr> | ||
| <td class="translate">pcap</td> | ||
| <td><input type="text" id="interface" class="value"></td> | ||
| </tr> | ||
| </table--> | ||
| <table id="devices"></table> | ||
| <div id="pager-devices"></div> | ||
| <div id="values" style="width: 100%; height: calc(100% - 195px)"> | ||
| <div class="row"> | ||
| <a class="btn-floating waves-effect waves-light blue"><i class="material-icons table-button-add">add</i></a> | ||
| </div> | ||
| <div style="width: 100%; height: calc(100% - 30px); overflow: auto;"> | ||
| <table class="table-values" style="width: 100%;"> | ||
| <thead> | ||
| <tr> | ||
| <th data-name="_index" style="width: 40px" class="blue translate"></th> | ||
| <th data-name="name" style="width: 30%" class="blue translate">name</th> | ||
| <th data-name="mac" class="blue translate">mac</th> | ||
| <th data-buttons="delete" style="width: 40px" class="blue"></th> | ||
| </tr> | ||
| </thead> | ||
| </table> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </html> |
+6
-2
@@ -10,7 +10,11 @@ systemDictionary = { | ||
| "de": "PCAP Interface (lasse leer wenn default)", | ||
| "ru": "" | ||
| "ru": "Интерфейс PCAP (оставить пустыми по умолчанию)" | ||
| }, | ||
| "name": {"en": "Name", "de": "Name", "ru": "Имя"}, | ||
| "mac": {"en": "MAC Address format first xx:xx:xx", "de": "MAC Adresse die ersten xx:xx:xx", "ru": "MAC Адрес xx:xx:xx"}, | ||
| "mac": { | ||
| "en": "MAC Address format first xx:xx:xx", | ||
| "de": "MAC Adresse die ersten xx:xx:xx", | ||
| "ru": "MAC Адрес xx:xx:xx" | ||
| }, | ||
| }; |
+0
-0
@@ -0,0 +0,0 @@ // converts a numeric array: [ 143, 63, 32, 51, 84, 68 ] |
+11
-1
| { | ||
| "common": { | ||
| "name": "amazon-dash", | ||
| "version": "0.2.9", | ||
| "version": "0.3.1", | ||
| "title": "Amazon Dash-Button", | ||
@@ -11,2 +11,11 @@ "desc": { | ||
| }, | ||
| "authors": [ | ||
| "Patrick Arns <npm@patrick-arns.de>" | ||
| ], | ||
| "news": { | ||
| "0.3.0": { | ||
| "en": "materialize ui and minor fixes, dash buttons now of type device", | ||
| "de": "Materialize Oberfläche und kleine Änderungen, Dash Buttons sind nun vom Typ Device" | ||
| } | ||
| }, | ||
| "platform": "Javascript/Node.js", | ||
@@ -17,2 +26,3 @@ "license": "MIT", | ||
| "enabled": true, | ||
| "materialize": true, | ||
| "extIcon": "https://raw.githubusercontent.com/PArns/ioBroker.amazon-dash/master/admin/amazon-dash.png", | ||
@@ -19,0 +29,0 @@ "keywords": [ |
+66
-29
@@ -1,28 +0,45 @@ | ||
| var controllerDir; | ||
| 'use strict'; | ||
| // Get js-controller directory to load libs | ||
| const fs = require('fs'); | ||
| const path = require('path'); | ||
| let controllerDir; | ||
| let appName; | ||
| /** | ||
| * returns application name | ||
| * | ||
| * The name of the application can be different and this function finds it out. | ||
| * | ||
| * @returns {string} | ||
| */ | ||
| function getAppName() { | ||
| const parts = __dirname.replace(/\\/g, '/').split('/'); | ||
| return parts[parts.length - 2].split('.')[0]; | ||
| } | ||
| /** | ||
| * looks for js-controller home folder | ||
| * | ||
| * @param {boolean} isInstall | ||
| * @returns {string} | ||
| */ | ||
| function getControllerDir(isInstall) { | ||
| var fs = require('fs'); | ||
| // Find the js-controller location | ||
| var controllerDir = __dirname.replace(/\\/g, '/'); | ||
| controllerDir = controllerDir.split('/'); | ||
| if (controllerDir[controllerDir.length - 3] == 'adapter') { | ||
| controllerDir.splice(controllerDir.length - 3, 3); | ||
| controllerDir = controllerDir.join('/'); | ||
| } else if (controllerDir[controllerDir.length - 3] == 'node_modules') { | ||
| controllerDir.splice(controllerDir.length - 3, 3); | ||
| controllerDir = controllerDir.join('/'); | ||
| if (fs.existsSync(controllerDir + '/node_modules/iobroker.js-controller')) { | ||
| controllerDir += '/node_modules/iobroker.js-controller'; | ||
| } else if (fs.existsSync(controllerDir + '/node_modules/ioBroker.js-controller')) { | ||
| controllerDir += '/node_modules/ioBroker.js-controller'; | ||
| } else if (!fs.existsSync(controllerDir + '/controller.js')) { | ||
| if (!isInstall) { | ||
| console.log('Cannot find js-controller'); | ||
| process.exit(10); | ||
| } else { | ||
| process.exit(); | ||
| const possibilities = [ | ||
| 'iobroker.js-controller', | ||
| 'ioBroker.js-controller', | ||
| ]; | ||
| /** @type {string} */ | ||
| let controllerPath; | ||
| for (const pkg of possibilities) { | ||
| try { | ||
| const possiblePath = require.resolve(pkg); | ||
| if (fs.existsSync(possiblePath)) { | ||
| controllerPath = possiblePath; | ||
| break; | ||
| } | ||
| } | ||
| } else { | ||
| } catch (e) { /* not found */ } | ||
| } | ||
| if (controllerPath == null) { | ||
| if (!isInstall) { | ||
@@ -35,13 +52,33 @@ console.log('Cannot find js-controller'); | ||
| } | ||
| return controllerDir; | ||
| // we found the controller | ||
| return path.dirname(controllerPath); | ||
| } | ||
| // Read controller configuration file | ||
| function getConfig() { | ||
| return JSON.parse(fs.readFileSync(controllerDir + '/conf/iobroker.json')); | ||
| /** | ||
| * reads controller base settings | ||
| * | ||
| * @alias getConfig | ||
| * @returns {object} | ||
| */ | ||
| function getConfig() { | ||
| let configPath; | ||
| if (fs.existsSync( | ||
| configPath = path.join(controllerDir, 'conf', appName + '.json') | ||
| )) { | ||
| return JSON.parse(fs.readFileSync(configPath, 'utf8')); | ||
| } else if (fs.existsSync( | ||
| configPath = path.join(controllerDir, 'conf', + appName.toLowerCase() + '.json') | ||
| )) { | ||
| return JSON.parse(fs.readFileSync(configPath, 'utf8')); | ||
| } else { | ||
| throw new Error('Cannot find ' + controllerDir + '/conf/' + appName + '.json'); | ||
| } | ||
| } | ||
| controllerDir = getControllerDir(typeof process != 'undefined' && process.argv && process.argv.indexOf('--install') != -1); | ||
| appName = getAppName(); | ||
| controllerDir = getControllerDir(typeof process !== 'undefined' && process.argv && process.argv.indexOf('--install') !== -1); | ||
| const adapter = require(path.join(controllerDir, 'lib/adapter.js')); | ||
| exports.controllerDir = controllerDir; | ||
| exports.getConfig = getConfig; | ||
| exports.adapter = require(controllerDir + '/lib/adapter.js'); | ||
| exports.Adapter = adapter; | ||
| exports.appName = appName; |
+36
-24
@@ -5,8 +5,8 @@ /* jshint -W097 */// jshint strict:false | ||
| var utils = require(__dirname + '/lib/utils'); | ||
| var adapter = utils.adapter('amazon-dash'); | ||
| var int_array_to_hex = require('./helpers.js').int_array_to_hex; | ||
| var pcap = require('pcap'); | ||
| const utils = require(__dirname + '/lib/utils'); | ||
| const adapter = utils.Adapter('amazon-dash'); | ||
| const int_array_to_hex = require('./helpers.js').int_array_to_hex; | ||
| const pcap = require('pcap'); | ||
| var MACs = [ | ||
| let MACs = [ | ||
| "747548", | ||
@@ -33,7 +33,8 @@ "F0D2F1", | ||
| "2C3AE8", | ||
| "6C5697" | ||
| "6C5697", | ||
| "38F73D" | ||
| ]; | ||
| String.prototype.replaceAll = function (search, replacement) { | ||
| var target = this; | ||
| const target = this; | ||
| return target.replace(new RegExp(search, 'g'), replacement); | ||
@@ -48,3 +49,3 @@ }; | ||
| // is called when adapter shuts down - callback has to be called under any circumstances! | ||
| adapter.on('unload', function (callback) { | ||
| adapter.on('unload', (callback) => { | ||
| try { | ||
@@ -59,7 +60,6 @@ adapter.log.info('cleaned everything up...'); | ||
| function main() { | ||
| var k; | ||
| if (adapter.config.devices && adapter.config.devices.length) { | ||
| for (k = 0; k < adapter.config.devices.length; k++) { | ||
| var mac = adapter.config.devices[k].mac; | ||
| var macOK = mac.replaceAll(":", ""); | ||
| for (let k = 0; k < adapter.config.devices.length; k++) { | ||
| let mac = adapter.config.devices[k].mac; | ||
| let macOK = mac.replaceAll(":", ""); | ||
@@ -82,13 +82,13 @@ if (macOK.length > 5) { | ||
| var pcap_session = pcap.createSession(adapter.config.interface, "arp"); | ||
| let pcap_session = pcap.createSession(adapter.config.interface, "arp"); | ||
| pcap_session.on('packet', function (raw_packet) { | ||
| var packet = pcap.decode.packet(raw_packet); | ||
| const packet = pcap.decode.packet(raw_packet); | ||
| if (packet.payload.ethertype === 2054) { | ||
| var mac = packet.payload.payload.sender_ha.addr; | ||
| let mac = packet.payload.payload.sender_ha.addr; | ||
| mac = int_array_to_hex(mac); | ||
| var nice_mac = mac.replaceAll(":", "-"); | ||
| var needle = mac.slice(0, 8).toString().toUpperCase().split(':').join(''); | ||
| const nice_mac = mac.replaceAll(":", "-"); | ||
| const needle = mac.slice(0, 8).toString().toUpperCase().split(':').join(''); | ||
@@ -98,2 +98,14 @@ adapter.log.debug('needle MAC : ' + needle); | ||
| if (MACs.indexOf(needle) > -1) { | ||
| adapter.getObject(nice_mac, (err, obj) => { | ||
| // if non existent or not type device | ||
| if (!obj || obj.type !== 'device') { | ||
| adapter.setObject(nice_mac, { | ||
| type: "device", | ||
| common: {}, | ||
| native: {} | ||
| }); | ||
| } // endIf | ||
| }); | ||
| adapter.setObjectNotExists(nice_mac + ".pressed", { | ||
@@ -112,3 +124,3 @@ type: "state", | ||
| setTimeout(function () { | ||
| setTimeout(() => { | ||
| adapter.setState(nice_mac + ".pressed", {val: false, ack: true}); | ||
@@ -141,7 +153,7 @@ }, 5000); | ||
| adapter.getState(nice_mac + ".switch", function (err, state) { | ||
| adapter.getState(nice_mac + ".switch", (err, state) => { | ||
| if (!state || err) | ||
| adapter.setState(nice_mac + ".switch", {val: false, ack: true}); | ||
| else { | ||
| var now = new Date(); | ||
| const now = new Date(); | ||
| if (now.getTime() - state.lc > 5000) { | ||
@@ -158,8 +170,8 @@ adapter.setState(nice_mac + ".switch", {val: !state.val, ack: true}); | ||
| function remove_duplicates(arr) { | ||
| var obj = {}; | ||
| var ret_arr = []; | ||
| for (var i = 0; i < arr.length; i++) { | ||
| let obj = {}; | ||
| let ret_arr = []; | ||
| for (let i = 0; i < arr.length; i++) { | ||
| obj[arr[i]] = true; | ||
| } | ||
| for (var key in obj) { | ||
| for (let key in obj) { | ||
| ret_arr.push(key); | ||
@@ -166,0 +178,0 @@ } |
+40
-45
| { | ||
| "name": "iobroker.amazon-dash", | ||
| "version": "0.2.9", | ||
| "description": "ioBroker amazon-dash Adapter", | ||
| "author": { | ||
| "name": "Patrick Arns", | ||
| "email": "npm@patrick-arns.de" | ||
| }, | ||
| "contributors": [ | ||
| { | ||
| "name": "Patrick Arns", | ||
| "email": "npm@patrick-arns.de" | ||
| "name": "iobroker.amazon-dash", | ||
| "version": "0.3.1", | ||
| "description": "ioBroker amazon-dash Adapter", | ||
| "author": { | ||
| "name": "Patrick Arns", | ||
| "email": "npm@patrick-arns.de" | ||
| }, | ||
| "contributors": [ | ||
| { | ||
| "name": "Patrick Arns", | ||
| "email": "npm@patrick-arns.de" | ||
| } | ||
| ], | ||
| "homepage": "https://github.com/PArns/ioBroker.amazon-dash", | ||
| "license": "MIT", | ||
| "keywords": [ | ||
| "ioBroker", | ||
| "amazon-dash", | ||
| "Smart Home", | ||
| "home automation" | ||
| ], | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "https://github.com/PArns/ioBroker.amazon-dash" | ||
| }, | ||
| "dependencies": { | ||
| "pcap": "^2.1.0" | ||
| }, | ||
| "devDependencies": { | ||
| "gulp": "^3.9.1", | ||
| "mocha": "^4.1.0", | ||
| "chai": "^4.1.2" | ||
| }, | ||
| "bugs": { | ||
| "url": "https://github.com/PArns/ioBroker.amazon-dash/issues" | ||
| }, | ||
| "readmeFilename": "README.md", | ||
| "scripts": { | ||
| "preinstall": "apt install libpcap-dev -y || true", | ||
| "test": "node node_modules/mocha/bin/mocha --exit" | ||
| } | ||
| ], | ||
| "homepage": "https://github.com/PArns/ioBroker.amazon-dash", | ||
| "license": "MIT", | ||
| "keywords": [ | ||
| "ioBroker", | ||
| "amazon-dash", | ||
| "Smart Home", | ||
| "home automation" | ||
| ], | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "https://github.com/PArns/ioBroker.amazon-dash" | ||
| }, | ||
| "dependencies": { | ||
| "pcap": "https://github.com/mranney/node_pcap/tarball/master" | ||
| }, | ||
| "devDependencies": { | ||
| "grunt": "^0.4.5", | ||
| "grunt-replace": "^0.9.3", | ||
| "grunt-contrib-jshint": "^0.11.2", | ||
| "grunt-jscs": "^2.0.0", | ||
| "grunt-http": "^1.6.0", | ||
| "grunt-contrib-clean": "^0.6.0", | ||
| "grunt-contrib-compress": "^0.13.0", | ||
| "grunt-contrib-copy": "^0.8.0", | ||
| "grunt-exec": "^0.4.6" | ||
| }, | ||
| "bugs": { | ||
| "url": "https://github.com/PArns/ioBroker.amazon-dash/issues" | ||
| }, | ||
| "readmeFilename": "README.md", | ||
| "scripts": { | ||
| "preinstall": "apt-get install libpcap-dev -y || true" | ||
| } | ||
| } |
+12
-0
@@ -26,4 +26,16 @@  | ||
| ## HELP WANTED! | ||
| As this project is developed during my spare time, I*m actively looking for help to maintain and extend this lib! If you're willing to help, drop me a line! | ||
| ## Changelog | ||
| ### 0.3.1 | ||
| + (PArns) Added new Amazon MAC family | ||
| ### 0.3.0 | ||
| + (foxriver76) materialize ui | ||
| + (foxriver76) dash buttons are now of type device | ||
| ### 0.2.9 | ||
@@ -30,0 +42,0 @@ + (cernst1980) Ignore duplicate ARPs for 5 seconds |
Sorry, the diff of this file is not supported yet
Install scripts
Supply chain riskInstall scripts are run when the package is installed or built. Malicious packages often use scripts that run automatically to execute payloads or fetch additional code.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
HTTP dependency
Supply chain riskContains a dependency which resolves to a remote HTTP URL which could be used to inject untrusted code and reduce overall package reliability.
Found 1 instance in 1 package
Install scripts
Supply chain riskInstall scripts are run when the package is installed or built. Malicious packages often use scripts that run automatically to execute payloads or fetch additional code.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
57828
11.69%3
-66.67%253
23.41%122
10.91%1
-50%5
25%+ Added
+ Added
Updated