diff --git a/node/node_modules/macfromip/.npmignore b/node/node_modules/macfromip/.npmignore new file mode 100644 index 0000000..c8f50f7 --- /dev/null +++ b/node/node_modules/macfromip/.npmignore @@ -0,0 +1 @@ +npm-debug.log diff --git a/node/node_modules/macfromip/README.md b/node/node_modules/macfromip/README.md new file mode 100644 index 0000000..c27ef9e --- /dev/null +++ b/node/node_modules/macfromip/README.md @@ -0,0 +1,30 @@ +macfromip +========= + +## Synopsis + +* Nodejs script; +* Gets a MAC address from a LAN IP address; +* Only works on linux, OSX and win32 platforms; + +## Code Example + +``` +var macfromip = require('macfromip'); + +macfromip.getMac('192.168.2.169', function(err, data){ + if(err){ + console.log(err); + } + console.log(data); +}); +``` + +## Installation + +``` +npm install macfromip +``` + +## TODO List: +Complete list on [Trello](https://trello.com/b/B1WM4gbZ/macfromip) \ No newline at end of file diff --git a/node/node_modules/macfromip/example.js b/node/node_modules/macfromip/example.js new file mode 100644 index 0000000..b30fe4a --- /dev/null +++ b/node/node_modules/macfromip/example.js @@ -0,0 +1,10 @@ +var macfromip = require('./macfromip.js'); + +macfromip.getMac('192.168.2.57', function(err, data){ + if(err){ + console.log(err); + } + else{ + console.log(data); + } +}); diff --git a/node/node_modules/macfromip/macfromip.js b/node/node_modules/macfromip/macfromip.js new file mode 100644 index 0000000..0599c23 --- /dev/null +++ b/node/node_modules/macfromip/macfromip.js @@ -0,0 +1,160 @@ +/* jshint node: true */ +'use strict'; + +var macfromip = exports; + +var cp = require('child_process'); +var os = require('os'); + +var MACADDRESS_LENGTH = 17; + +macfromip.isEmpty = function(value){ + return ((value === null) || (typeof value === 'undefined') || 0 === value.length); +}; + +macfromip.isString = function(value){ + if(macfromip.isEmpty(value)){ + throw new Error('Expected a not null value'); + } + + if (typeof value === 'string') { + return true; + } + + return false; +}; + +macfromip.isIpAddress = function(ipaddress){ + if(!macfromip.isString(ipaddress)){ + throw new Error('Expected a string'); + } + + /* Thanks to http://www.w3resource.com/javascript/form/ip-address-validation.php#sthash.kBJql3HS.dpuf */ + if (/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ipaddress.trim())){ + return (true); + } + return (false); +}; + +macfromip.ipIsSelf = function(ipaddress){ + var ifaces = os.networkInterfaces(); + var selfIps = new Array(); + + Object.keys(ifaces).forEach(function (ifname) { + var alias = 0; + ifaces[ifname].forEach(function (iface) { + if ('IPv4' !== iface.family) { + // skip over internal (i.e. 127.0.0.1) and non-ipv4 addresses + return; + } + selfIps.push(iface.address); + }); + }); + + var index; + for (index = 0; index < selfIps.length; ++index) { + if(selfIps[index] === ipaddress){ + return true; + } + } + + return false; +}; + +macfromip.getMacInLinux = function(ipAddress, callback){ + // OSX requires -c switch first + var ls = cp.exec('ping -c 1 ' + ipAddress, + function(error, stdout, stderr) { + if (error !== null) { + callback('IP address unreachable', 'exec error: ' + error); + return; + } + if (stderr !== null && stderr !== '') { + callback('IP address unreachable', 'stderr: ' + stderr); + return; + } + + var ls2 = cp.exec('arp -a', + function(error2, stdout2, stderr2) { + if (error2 !== null) { + callback('IP address unreachable', 'exec error: ' + error2); + return; + } + if (stderr2 !== null && stderr2 !== '') { + callback('IP address unreachable', 'stderr: ' + stderr2); + return; + } + + stdout2 = (stdout2.substring(stdout2.indexOf(ipAddress) + (ipAddress.length + 5))).substring(MACADDRESS_LENGTH, 0); + callback(false, stdout2); + return; + }); + }); +}; + +macfromip.getMacInWin32 = function(ipAddress, callback){ + var ls = cp.exec('ping ' + ipAddress + ' -n 1', + function(error, stdout, stderr) { + if (error !== null) { + callback('IP address unreachable', 'exec error: ' + error); + return; + } + if (stderr !== null && stderr !== '') { + callback('IP address unreachable', 'stderr: ' + stderr); + return; + } + + var ls2 = cp.exec('arp -a', + function(error2, stdout2, stderr2) { + if (error2 !== null) { + callback('IP address unreachable', 'exec error: ' + error2); + return; + } + if (stderr2 !== null && stderr2 !== '') { + callback('IP address unreachable', 'stderr: ' + stderr2); + return; + } + + var offset = 22 - ipAddress.length; + + stdout2 = (stdout2.substring(stdout2.indexOf(ipAddress) + (ipAddress.length + offset))).substring(MACADDRESS_LENGTH, 0); + callback(false, stdout2); + return; + }); + }); +}; + +macfromip.getMac = function(ipAddress, callback) { + + if(!macfromip.isIpAddress(ipAddress)) { + throw new Error("The value you entered is not a valid IP address"); + } + + if(macfromip.ipIsSelf(ipAddress)){ + throw new Error("The IP address cannot be self"); + } + + switch(os.platform()){ + case 'linux': + macfromip.getMacInLinux(ipAddress, function(err, mac){ + callback(err, mac); + }); + break; + + case 'win32': + macfromip.getMacInWin32(ipAddress, function(err, mac){ + callback(err, mac); + }); + break; + // OSX + case 'darwin': + macfromip.getMacInLinux(ipAddress, function(err, mac){ + callback(err, mac); + }); + break; + + default: + callback('Unsupported platform: ' + os.platform(), null); + break; + } +}; diff --git a/node/node_modules/macfromip/package.json b/node/node_modules/macfromip/package.json new file mode 100644 index 0000000..88a20ef --- /dev/null +++ b/node/node_modules/macfromip/package.json @@ -0,0 +1,62 @@ +{ + "_from": "macfromip", + "_id": "macfromip@1.1.1", + "_inBundle": false, + "_integrity": "sha1-uy9GiBDMOm0ZFxabj4InHuMOTd0=", + "_location": "/macfromip", + "_phantomChildren": {}, + "_requested": { + "type": "tag", + "registry": true, + "raw": "macfromip", + "name": "macfromip", + "escapedName": "macfromip", + "rawSpec": "", + "saveSpec": null, + "fetchSpec": "latest" + }, + "_requiredBy": [ + "#USER", + "/" + ], + "_resolved": "https://registry.npmjs.org/macfromip/-/macfromip-1.1.1.tgz", + "_shasum": "bb2f468810cc3a6d1917169b8f82271ee30e4ddd", + "_spec": "macfromip", + "_where": "E:\\Arduino_project\\wIoT\\node", + "author": { + "name": "bcamarneiro", + "email": "camarneirobruno@gmail.com" + }, + "bugs": { + "url": "https://github.com/bcamarneiro/macfromip/issues" + }, + "bundleDependencies": false, + "contributors": [ + { + "name": "Paul Cook" + }, + { + "name": "Sean Nessworthy", + "email": "sean@nessworthy.me" + } + ], + "deprecated": false, + "description": "On given an IP Address, will attempt to identify that IP's MAC address.", + "directories": { + "test": "test" + }, + "homepage": "https://github.com/bcamarneiro/macfromip", + "keywords": [ + "MAC", + "IP", + "Address" + ], + "license": "MIT", + "main": "macfromip.js", + "name": "macfromip", + "repository": { + "type": "git", + "url": "git+https://github.com/bcamarneiro/macfromip.git" + }, + "version": "1.1.1" +} diff --git a/node/node_modules/macfromip/test/test-macfromip.js b/node/node_modules/macfromip/test/test-macfromip.js new file mode 100644 index 0000000..8424856 --- /dev/null +++ b/node/node_modules/macfromip/test/test-macfromip.js @@ -0,0 +1,22 @@ +var macfromip = require('../macfromip.js'); + +exports['isIpAddress'] = function (test) { + test.equal(macfromip.isEmpty('0'), false); + test.equal(macfromip.isEmpty(' '), false); + test.equal(macfromip.isEmpty(''), true); + test.equal(macfromip.isEmpty(null), true); + test.equal(macfromip.isEmpty(), true); + + test.equal(macfromip.isString(false), false); + test.equal(macfromip.isString(1233536), false); + test.equal(macfromip.isString('1233536'), true); + test.equal(macfromip.isString('#$%&asda3445'), true); + + test.equal(macfromip.isIpAddress('127.0.0.1'), true); + test.equal(macfromip.isIpAddress('255.255.255.255'), true); + test.equal(macfromip.isIpAddress('0.0.0.0'), true); + test.equal(macfromip.isIpAddress('asdasdasdghdsgsdg'), false); + test.equal(macfromip.isIpAddress('192.168.2.5a'), false); + + test.done(); +}; \ No newline at end of file diff --git a/node/package-lock.json b/node/package-lock.json index 1e963d8..8a2c432 100644 --- a/node/package-lock.json +++ b/node/package-lock.json @@ -7,6 +7,11 @@ "@network-utils/arp-lookup": { "version": "https://registry.npm.taobao.org/@network-utils/arp-lookup/download/@network-utils/arp-lookup-1.0.3.tgz" }, + "macfromip": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/macfromip/-/macfromip-1.1.1.tgz", + "integrity": "sha1-uy9GiBDMOm0ZFxabj4InHuMOTd0=" + }, "node-arp": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/node-arp/-/node-arp-1.0.6.tgz", diff --git a/node/package.json b/node/package.json index 2e1fd77..2eebe33 100644 --- a/node/package.json +++ b/node/package.json @@ -1,6 +1,6 @@ { "name": "wiot", - "version": "0.0.4", + "version": "0.0.5", "description": "An awesome iot system for web developers~", "main": "wiot.js", "scripts": { @@ -25,7 +25,7 @@ "homepage": "https://github.com/IoTcat/wIoT-nodeJS#readme", "dependencies": { "@network-utils/arp-lookup": "^1.0.3", - "node-arp": "^1.0.6", + "macfromip": "^1.1.1", "ping": "^0.2.2" } } diff --git a/node/wiot.js b/node/wiot.js index 36b81e5..fc6720b 100644 --- a/node/wiot.js +++ b/node/wiot.js @@ -2,443 +2,464 @@ * @Author: IoTcat (https://iotcat.me) * @Date: 2019-05-04 18:59:49 * @Last Modified by: - * @Last Modified time: 2019-05-05 02:31:52 + * @Last Modified time: 2019-05-05 03:28:11 */ - var wiot = function (o_params) { - var o = { - MAC: "", - pin: { - D1: 0, - D2: 0, - D3: 0, - D4: 0, - D5: 0, - D6: 0, - D7: 0, - D8: 0 - }, - hint: true, - debug: false, - on: () => {}, - OUTPUT: 1, - INPUT: 0, - INPUT_PULLUP: 2, - HIGH: 1, - LOW: 0, - data: {}, - ip: "default", - ip_range: "192.168.4", - version: "", - errDelayTime: 2000, - okDelayTime: 30, - resetDelayTime: 4500, - noTryMaxTime: 60000, - IntervalTime: 2000, - MaxToReScanTime: 180000, - MinResearchTime: 5000, - IpScanTimeOut: 300, - pingTimeout: 2, - LastConnectTime: Date.parse(new Date()), - isConnected: false, - LastTryTime: Date.parse(new Date()), - firstReady: 0, - pinCmd: { - D1: 0, - D2: 0, - D3: 0, - D4: 0, - D5: 0, - D6: 0, - D7: 0, - D8: 0 - } - }; - - /* merge paras */ - if (typeof o_params.pin != undefined) { - o_params.pin = Object.assign(o.pin, o_params.pin); - } - Object.assign(o, o_params); - - /* require packages */ - var http = require('http'); - var net = require('net'); - var arp = require('@network-utils/arp-lookup'); - var ping = require('ping'); - var nodeArp = require('node-arp'); - - /* tmp global var */ - var ip_point = 0; - - /* tools */ - var IsJsonString = (str) => { - try { - JSON.parse(str); - } catch (e) { - return false; - } - return true; - }; - - - var ip_scan = function () { - var socket = new net.Socket(); - socket.setTimeout(o.IpScanTimeOut); - socket.on('connect', function () { - socket.end(); - check_MAC(); - }); - socket.on('timeout', function () { - socket.destroy(); - next_IP(); - }); - socket.on('error', function (err) { - next_IP(); - }); - socket.on('close', function (err) {}); - socket.connect(80, generate_IP()); - }; - - var check_MAC = () => { - o.LastConnectTime = Date.parse(new Date()); - nodeArp.getMAC(generate_IP(), (err, mac) => { - if (!err) { - if (o.debug) console.log('Searched IP: ' + generate_IP()); - if (mac.toUpperCase() == o.MAC.toUpperCase()) { - if (o.hint) console.log('wiot - ' + o.MAC + ': Found MAC from ' + o.ip + ' :: Method: node-arp'); - setTimeout(reCheck_MAC, o.IpScanTimeOut*2); - return; - } - next_IP(); - return; - } - next_IP(); - }); - }; - - var reCheck_MAC = () => { - nodeArp.getMAC(generate_IP(), (err, mac) => { - if(!err){ - if(o.debug) console.log('Checking IP: '+generate_IP()); - if(mac.toUpperCase() == o.MAC.toUpperCase()){ + +var wiot = function (o_params) { + var o = { + MAC: "", + pin: { + D1: 0, + D2: 0, + D3: 0, + D4: 0, + D5: 0, + D6: 0, + D7: 0, + D8: 0 + }, + hint: true, + debug: false, + on: () => {}, + OUTPUT: 1, + INPUT: 0, + INPUT_PULLUP: 2, + HIGH: 1, + LOW: 0, + data: {}, + ip: "default", + ip_range: "192.168.0", + localIP: "127.0.0.1", + version: "", + errDelayTime: 2000, + okDelayTime: 30, + resetDelayTime: 4500, + noTryMaxTime: 60000, + IntervalTime: 2000, + MaxToReScanTime: 180000, + MinResearchTime: 5000, + IpScanTimeOut: 1, + pingTimeout: 2, + LastConnectTime: Date.parse(new Date()), + isConnected: false, + LastTryTime: Date.parse(new Date()), + firstReady: 0, + pinCmd: { + D1: 0, + D2: 0, + D3: 0, + D4: 0, + D5: 0, + D6: 0, + D7: 0, + D8: 0 + } + }; + + /* merge paras */ + if (typeof o_params.pin != undefined) { + o_params.pin = Object.assign(o.pin, o_params.pin); + } + Object.assign(o, o_params); + + /* require packages */ + var http = require('http'); + var arp = require('@network-utils/arp-lookup'); + var ping = require('ping'); + var os = require('os'); + var nodeArp = require('macfromip'); + + /* tmp global var */ + var ip_point = 0; + + /* tools */ + var IsJsonString = (str) => { + try { + JSON.parse(str); + } catch (e) { + return false; + } + return true; + }; + + + var getLocalIp = () => { + var ifaces = os.networkInterfaces(); + + for (var dev in ifaces) { + ifaces[dev].forEach((details) => { + if ((details.family == 'IPv4') && (details.internal == false)) { + o.localIP = details.address; + var ipParts = []; + ipParts = o.localIP.split("."); + o.ip_range = ipParts[0] + '.' + ipParts[1] + '.' + ipParts[2]; + } + }); + } + }; + + var ip_scan = function () { + ping.promise.probe(generate_IP(), { + timeout: o.IpScanTimeOut + }).then(function (res) { + if (res.alive == true) { + check_MAC(); + return; + } + next_IP(); + }); + + }; + + var check_MAC = () => { + o.LastConnectTime = Date.parse(new Date()); + if (generate_IP() == o.localIP) { + next_IP(); + return; + } + nodeArp.getMac(generate_IP(), (err, mac) => { + mac = mac.replace(/-/g, ":"); + if (!err) { + + if (o.debug) console.log('Searched IP: ' + generate_IP()); + if (mac.toUpperCase() == o.MAC.toUpperCase()) { + if (o.hint) console.log('wiot - ' + o.MAC + ': Found MAC from ' + o.ip + ' :: Method: macfromip'); + setTimeout(reCheck_MAC, o.IpScanTimeOut * 2); + return; + } + next_IP(); + return; + } + next_IP(); + }); + }; + + var reCheck_MAC = () => { + + nodeArp.getMac(generate_IP(), (err, mac) => { + mac = mac.replace(/-/g, ":"); + if (!err) { + if (o.debug) console.log('Checking IP: ' + generate_IP()); + if (mac.toUpperCase() == o.MAC.toUpperCase()) { o.ip = generate_IP(); - if (o.hint) console.log('wiot - ' + o.MAC + ': Confirm MAC from ' + o.ip + ' :: Method: node-arp'); + if (o.hint) console.log('wiot - ' + o.MAC + ': Confirm MAC from ' + o.ip + ' :: Method: macfromip'); lstn(); setup(); return; } next_IP(); return; - } - next_IP(); - }); - } - - var generate_IP = () => { - return o.ip_range + '.' + ip_point; - }; - - var next_IP = () => { - if (ip_point >= 255) { - ip_point = 0; - setTimeout(ip_scan, o.MinResearchTime); - return; - } - ip_point++; - ip_scan(); - } - - var get_sync_url = () => { - var s = 'http://' + o.ip + '/sync?D1='; - s += o.pinCmd.D1; - s += '&D2='; - s += o.pinCmd.D2; - s += '&D3='; - s += o.pinCmd.D3; - s += '&D4='; - s += o.pinCmd.D4; - s += '&D5='; - s += o.pinCmd.D5; - s += '&D6='; - s += o.pinCmd.D6; - s += '&D7='; - s += o.pinCmd.D7; - s += '&D8='; - s += o.pinCmd.D8; - - return s; - }; - - var getVersion = () => { - if (o.isConnected) { - http_request('http://' + o.ip + '/getVersion', (res) => { - o.version = res.version; - if (o.hint) { - console.log('wiot - ' + o.MAC + ': Version: ' + o.version); - } - }, getVersion); - return; - } - setTimeout(getVersion, o.errDelayTime); - }; - - - async function getMAC() { - await arp.toIP(o.MAC).then((val) => { - - if (val != null) { - o.ip = val; - } else if (ip == "default") { - ip_scan(); - } - o.ip = val; - - if (o.debug) console.log('Found MAC: ' + o.MAC + ' from IP: ' + val + ' :: Method: arp-lookup'); - lstn(); - setup(); - }, (err) => { - - if (o.debug) console.log(err); - setTimeout(getMAC, o.errDelayTime); - }); - } - - - /* http functions */ - var http_error_callback = (callback = () => {}) => { - callback(); - }; - - var http_connected_callback = (callback = () => {}) => { - callback(); - }; - - - var http_ok = () => { - setTimeout(core, o.okDelayTime); - }; - - var http_error = () => { - setTimeout(core, o.errDelayTime); - }; - - - var http_update = () => { - http_request(get_sync_url(), http_update_success, http_update_err); - }; - - var http_update_success = (res) => { - o.data = res; - http_ok(); - }; - - var http_update_err = () => { - http_error(); - }; - - var http_request = (url, callback = () => {}, err = () => {}) => { - - if (o.isConnected) { - o.LastTryTime = Date.parse(new Date()); - http.get(url, (res) => { - res.setEncoding('utf8'); - res.on('data', function (data) { - if (IsJsonString(data)) { - var dataObj = JSON.parse(data); - callback(dataObj); - } else { - err(e); - if (o.hint) console.log('wIoT - ' + o.MAC + ": err_" + o.ip + " - Not Stadnard JSON Response!!"); - } - o.LastConnectTime = Date.parse(new Date()); - }); - }).on('error', function (e) { - err(e); - if (o.hint) console.log('wIoT - ' + o.MAC + ": err_" + o.ip + " - Lost Connection!!"); - }).end(); - - } else { - http_error(); - } - }; - - - /* pin Mode */ - var setPinMode = (pin, mode) => { - if (pin < 1 || pin > 8) throw "Illegal Pin Number!!"; - if (mode == o.INPUT_PULLUP || mode == 2) { - mode = "INPUT_PULLUP"; - } else if (mode == o.OUTPUT || mode == 1) { - mode = "OUTPUT"; - } else { - mode = "INPUT"; - } - http_request('http://' + o.ip + '/pinMode?pin=' + pin + '&mode=' + mode); - - }; - - - var http_update_pin = () => { - if (o.isConnected) { - http_request('http://' + o.ip + '/getPinMode', (res) => { - if (JSON.stringify(o.pin) != JSON.stringify(res)) { - for (var i in o.pin) { - if (i.substr(0, 1) == "D") { - setPinMode(i.substr(1, 1), o.pin[i]); - } else if (i.length == 1) { - setPinMode(i, o.pin[i]); - } - - } - setTimeout(() => { - http_request('http://' + o.ip + '/reset'); - }, o.resetDelayTime); - setTimeout(() => { - core(); - }, o.resetDelayTime + o.errDelayTime); - if (o.hint) console.log('wIoT - ' + o.MAC + ": Seting Pin Mode!! reset..."); - } - - setTimeout(() => { - core(); - }, o.resetDelayTime + o.errDelayTime); - }, () => { - setTimeout(http_update_pin, o.errDelayTime); - }); - - } else { - setTimeout(http_update_pin, o.errDelayTime); - } - }; - - /* pin write */ - o.analogWrite = (pin, out, callback = () => {}, err = () => {}) => { - if (!isNaN(pin)) pin = 'D' + pin; - if (isNaN(out)) out = 0; - if (out > 255 || out == "HIGH" || out == o.HIGH) out = 255; - if (out < 0 || out == "LOW" || out == o.LOW) out = 0; - - if (o.hint && o.pinCmd[pin] != out) console.log('wIoT - ' + o.MAC + ': Write Value ' + out + ' to ' + pin); - o.pinCmd[pin] = out; - }; - - o.digitalWrite = (pin, out, callback = () => {}, err = () => {}) => { - if (out == o.HIGH || out == "HIGH" || out == 1) { - out = 255; - } else { - out = 0; - } - o.analogWrite(pin, out, callback, err); - }; - - /* pin read and write */ - o.digitalRead = (pin) => { - if (!isNaN(pin)) pin = 'D' + pin; - return o.data[pin]; - }; - - o.analogRead = (pin = "A0") => { - if (!isNaN(pin)) pin = 'A' + pin; - return o.data.A0; - }; - - o.read = function (pin) { - if (isNaN(pin)) { - if (pin.substr(0, 1) == "D") { - return o.digitalRead(pin); - } else { - return o.analogRead(pin); - } - } else { - if (pin > 0) { - return o.digitalRead(pin); - } else { - return o.analogRead(pin); - } - } - }; - - o.write = (pin, out, callback = () => {}, err = () => {}) => { - o.analogWrite(pin, out, callback, err); - }; - o.ready = function () { - if (!o.isConnected || JSON.stringify(o.data) == JSON.stringify({})) { - return false; - } - return true; - }; - - /* exc functions */ - var ini = function () { - if (o.hint) console.log('wiot - ' + o.MAC + ': init...'); - //getMAC(); - ip_scan(); - }; - - async function lstn() { - setInterval(async () => { - if (o.LastConnectTime + o.errDelayTime > Date.parse(new Date())) { - o.isConnected = true; - http_connected_callback(); - return; - } - ping.promise.probe(o.ip, { - timeout: o.pingTimeout - }).then(function (res) { - if (o.isConnected != res.alive) { - if (res.alive == true) { - o.LastConnectTime = Date.parse(new Date()); - http_connected_callback(); - } else { - http_error_callback(); - } - } - if (!res.alive && o.LastConnectTime + o.MaxToReScanTime < Date.parse(new Date())) { - ini(); - } else if (res.alive && o.LastTryTime + o.noTryMaxTime < Date.parse(new Date())) { - core(); - } - o.isConnected = res.alive; - if (o.debug) console.log('Exist: ' + res.alive + ' From IP: ' + o.ip); - - - }); - - }, o.IntervalTime); - - }; - - - var setup = () => { - - if (o.isConnected) { - - getVersion(); - http_update_pin(); - return; - } - - setTimeout(setup, o.errDelayTime); - }; - - - var core = () => { - - http_update(); - - if (!o.firstReady && o.ready()) { - o.on(); - o.firstReady = 1; - if (o.hint) console.log('wIoT - ' + o.MAC + ': Connected!!'); - } - if (o.debug) console.log(o.data); - }; - - /* exc cmd */ - ini(); - - return o; - - }; - - exports.client = wiot; + } + next_IP(); + }); + }; + + var generate_IP = () => { + return o.ip_range + '.' + ip_point; + }; + + var next_IP = () => { + if (ip_point >= 255) { + ip_point = 0; + setTimeout(ip_scan, o.MinResearchTime); + return; + } + ip_point++; + ip_scan(); + }; + + var get_sync_url = () => { + var s = 'http://' + o.ip + '/sync?D1='; + s += o.pinCmd.D1; + s += '&D2='; + s += o.pinCmd.D2; + s += '&D3='; + s += o.pinCmd.D3; + s += '&D4='; + s += o.pinCmd.D4; + s += '&D5='; + s += o.pinCmd.D5; + s += '&D6='; + s += o.pinCmd.D6; + s += '&D7='; + s += o.pinCmd.D7; + s += '&D8='; + s += o.pinCmd.D8; + + return s; + }; + + var getVersion = () => { + if (o.isConnected) { + http_request('http://' + o.ip + '/getVersion', (res) => { + o.version = res.version; + if (o.hint) { + console.log('wiot - ' + o.MAC + ': Version: ' + o.version); + } + }, getVersion); + return; + } + setTimeout(getVersion, o.errDelayTime); + }; + + + async function getMAC() { + await arp.toIP(o.MAC).then((val) => { + + if (val != null) { + o.ip = val; + } else if (ip == "default") { + ip_scan(); + return; + } + + if (o.debug) console.log('Found MAC: ' + o.MAC + ' from IP: ' + o.ip + ' :: Method: arp-lookup'); + lstn(); + setup(); + }, (err) => { + + if (o.debug) console.log(err); + setTimeout(getMAC, o.errDelayTime); + }); + } + + + /* http functions */ + var http_error_callback = (callback = () => {}) => { + callback(); + }; + + var http_connected_callback = (callback = () => {}) => { + callback(); + }; + + + var http_ok = () => { + setTimeout(core, o.okDelayTime); + }; + + var http_error = () => { + setTimeout(core, o.errDelayTime); + }; + + + var http_update = () => { + http_request(get_sync_url(), http_update_success, http_update_err); + }; + + var http_update_success = (res) => { + o.data = res; + http_ok(); + }; + + var http_update_err = () => { + http_error(); + }; + + var http_request = (url, callback = () => {}, err = () => {}) => { + + if (o.isConnected) { + o.LastTryTime = Date.parse(new Date()); + http.get(url, (res) => { + res.setEncoding('utf8'); + res.on('data', function (data) { + if (IsJsonString(data)) { + var dataObj = JSON.parse(data); + callback(dataObj); + } else { + err(e); + if (o.hint) console.log('wIoT - ' + o.MAC + ": err_" + o.ip + " - Not Stadnard JSON Response!!"); + } + o.LastConnectTime = Date.parse(new Date()); + }); + }).on('error', function (e) { + err(e); + if (o.hint) console.log('wIoT - ' + o.MAC + ": err_" + o.ip + " - Lost Connection!!"); + }).end(); + + } else { + http_error(); + } + }; + + + /* pin Mode */ + var setPinMode = (pin, mode) => { + if (pin < 1 || pin > 8) throw "Illegal Pin Number!!"; + if (mode == o.INPUT_PULLUP || mode == 2) { + mode = "INPUT_PULLUP"; + } else if (mode == o.OUTPUT || mode == 1) { + mode = "OUTPUT"; + } else { + mode = "INPUT"; + } + http_request('http://' + o.ip + '/pinMode?pin=' + pin + '&mode=' + mode); + + }; + + + var http_update_pin = () => { + if (o.isConnected) { + http_request('http://' + o.ip + '/getPinMode', (res) => { + if (JSON.stringify(o.pin) != JSON.stringify(res)) { + for (var i in o.pin) { + if (i.substr(0, 1) == "D") { + setPinMode(i.substr(1, 1), o.pin[i]); + } else if (i.length == 1) { + setPinMode(i, o.pin[i]); + } + + } + setTimeout(() => { + http_request('http://' + o.ip + '/reset'); + }, o.resetDelayTime); + setTimeout(() => { + core(); + }, o.resetDelayTime + o.errDelayTime); + if (o.hint) console.log('wIoT - ' + o.MAC + ": Seting Pin Mode!! reset..."); + } + + setTimeout(() => { + core(); + }, o.resetDelayTime + o.errDelayTime); + }, () => { + setTimeout(http_update_pin, o.errDelayTime); + }); + + } else { + setTimeout(http_update_pin, o.errDelayTime); + } + }; + + /* pin write */ + o.analogWrite = (pin, out, callback = () => {}, err = () => {}) => { + if (!isNaN(pin)) pin = 'D' + pin; + if (isNaN(out)) out = 0; + if (out > 255 || out == "HIGH" || out == o.HIGH) out = 255; + if (out < 0 || out == "LOW" || out == o.LOW) out = 0; + + if (o.hint && o.pinCmd[pin] != out) console.log('wIoT - ' + o.MAC + ': Write Value ' + out + ' to ' + pin); + o.pinCmd[pin] = out; + }; + + o.digitalWrite = (pin, out, callback = () => {}, err = () => {}) => { + if (out == o.HIGH || out == "HIGH" || out == 1) { + out = 255; + } else { + out = 0; + } + o.analogWrite(pin, out, callback, err); + }; + + /* pin read and write */ + o.digitalRead = (pin) => { + if (!isNaN(pin)) pin = 'D' + pin; + return o.data[pin]; + }; + + o.analogRead = (pin = "A0") => { + if (!isNaN(pin)) pin = 'A' + pin; + return o.data.A0; + }; + + o.read = function (pin) { + if (isNaN(pin)) { + if (pin.substr(0, 1) == "D") { + return o.digitalRead(pin); + } else { + return o.analogRead(pin); + } + } else { + if (pin > 0) { + return o.digitalRead(pin); + } else { + return o.analogRead(pin); + } + } + }; + + o.write = (pin, out, callback = () => {}, err = () => {}) => { + o.analogWrite(pin, out, callback, err); + }; + o.ready = function () { + if (!o.isConnected || JSON.stringify(o.data) == JSON.stringify({})) { + return false; + } + return true; + }; + + /* exc functions */ + var ini = function () { + if (o.hint) console.log('wiot - ' + o.MAC + ': init...'); + getLocalIp(); + getMAC(); + //ip_scan(); + }; + + async function lstn() { + setInterval(async () => { + if (o.LastConnectTime + o.errDelayTime > Date.parse(new Date())) { + o.isConnected = true; + http_connected_callback(); + return; + } + ping.promise.probe(o.ip, { + timeout: o.pingTimeout + }).then(function (res) { + if (o.isConnected != res.alive) { + if (res.alive == true) { + o.LastConnectTime = Date.parse(new Date()); + http_connected_callback(); + } else { + http_error_callback(); + } + } + if (!res.alive && o.LastConnectTime + o.MaxToReScanTime < Date.parse(new Date())) { + ini(); + } else if (res.alive && o.LastTryTime + o.noTryMaxTime < Date.parse(new Date())) { + core(); + } + o.isConnected = res.alive; + if (o.debug) console.log('Exist: ' + res.alive + ' From IP: ' + o.ip); + + + }); + + }, o.IntervalTime); + + }; + + + var setup = () => { + + if (o.isConnected) { + + getVersion(); + http_update_pin(); + return; + } + + setTimeout(setup, o.errDelayTime); + }; + + + var core = () => { + + http_update(); + + if (!o.firstReady && o.ready()) { + o.on(); + o.firstReady = 1; + if (o.hint) console.log('wIoT - ' + o.MAC + ': Connected!!'); + } + if (o.debug) console.log(o.data); + }; + + /* exc cmd */ + ini(); + + return o; + +}; + +exports.client = wiot;