commit 05d8d05e15456eca17e0605a389024ee470d0265 Author: iotcat Date: Fri Aug 14 09:44:45 2020 +0800 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/func/actModel.js b/func/actModel.js new file mode 100644 index 0000000..7b3e3ef --- /dev/null +++ b/func/actModel.js @@ -0,0 +1,27 @@ +var actModel = (num) => { + + var o = 1; + + if(num < 15){ + o += num * .1 * .1; + return o; + } + if(num < 40){ + o += 1; + o += (num - 10) * (8.5 / 30) * .1; + return o; + } + + if(num < 100){ + o += 9; + o += (num - 40) * (10 / 60) * .3; + return o; + } + + o += 19; + o += Math.log(num - 100); + return o; +} + + +exports.actModel = actModel; diff --git a/index.js b/index.js new file mode 100644 index 0000000..fc902bc --- /dev/null +++ b/index.js @@ -0,0 +1,128 @@ +const mqtt = require('mqtt'); +const pir = require('./people/pir.js').pir; +const zoneObj = require('./people/zone.js').zone; +const lightObj = require('./mqtt/light.js').light +const matchObj = require('./match.js').match; +const interface = require('./people/interface.js').interface; +const lightCtlObj = require('./lightCtl/core.js').core; +const peo = require('./mqtt/peo.js').peo; +const isolatObj = require('./lightCtl/isolat.js').isolat; +process.setMaxListeners(0); + +var client = mqtt.connect('mqtt://127.0.0.1'); +var light = { + hall: lightObj(client, 'hall'), + din: lightObj(client, 'din'), + liv: lightObj(client, 'liv'), + kit: lightObj(client, 'kit') +}; + +var p = { + hall: [ + pir(client, 'hall', 0), + pir(client, 'hall', 1), + pir(client, 'hall', 2), + pir(client, 'hall', 3), + ], + din: [ + pir(client, 'din', 0), + pir(client, 'din', 1), + pir(client, 'din', 2), + pir(client, 'din', 3) + ], + liv: [ + pir(client, 'liv', 0), + pir(client, 'liv', 1), + pir(client, 'liv', 2), + pir(client, 'liv', 3) + ], + livb: [ + pir(client, 'livb', 0), + pir(client, 'livb', 1), + pir(client, 'livb', 2), + pir(client, 'livb', 3) + ], + kit: [ + pir(client, 'kit', 0), + pir(client, 'kit', 1), + pir(client, 'kit', 2), + pir(client, 'kit', 3) + ] +} + + + +var zone = { + hall: [ + zoneObj('h0', [p.hall[0], p.hall[1]]), + zoneObj('h1', [p.hall[2]]) + ], + din: [ + zoneObj('d0', [p.hall[3], p.kit[0], p.kit[1], p.din[0], p.din[1], p.livb[0]]), + zoneObj('d1', [p.din[2], p.din[3]]) + ], + kit: [ + zoneObj('k0', [/*p.kit[2],*/ p.kit[3]]) + ], + liv: [ + zoneObj('l0', [p.liv[0], p.livb[1]]), + zoneObj('l1', [p.livb[2], p.livb[3], p.liv[2], p.liv[3]]) + ] +}; + + +client.on('connect', ()=>{ + + + client.subscribe('hass/snsr/#', (err)=>{ + if(!err){ + client.publish('autoLight/state', 'online'); + console.log(new Date().toTimeString() + ' - MQTT Connected!!'); + } + }); +}); + + +//var match = matchObj(zone, light); + +var i = { + h: interface(zone.hall[0], zone.hall[1]), + hd: interface(zone.hall[1], zone.din[0]), + d: interface(zone.din[0], zone.din[1]), + dk: interface(zone.din[1], zone.kit[0]), + dl: interface(zone.din[0], zone.liv[1]), + l: interface(zone.liv[0], zone.liv[1]) +} + + +/* room reg */ +var room = { + hall: require('./room/hall.js').hall(zone, i), + din: require('./room/din.js').din(zone, i, p), + liv: require('./room/liv.js').liv(zone, i), + kit: require('./room/kit.js').kit(zone, i), +} + +/* lightCtl reg */ +var lightCtl = { + hall: lightCtlObj(room.hall, light.hall), + din: lightCtlObj(room.din, light.din), + liv: lightCtlObj(room.liv, light.liv), + kit: lightCtlObj(room.kit, light.kit) +} + + +/* peo mqtt */ +var peo_mqtt = { + hall: peo(client, room.hall), + din: peo(client, room.din), + liv: peo(client, room.liv), + kit: peo(client, room.kit) +} + +/* 走廊入口 */ +var isolat = { + hall: isolatObj(room.hall, light.hall, [p.hall[0], p.hall[1]], lightCtl.hall), + //door: isolatObj(room.din, light.din, [p.din[0], p.livb[0]], lightCtl.din), + +} diff --git a/lightCtl/core.js b/lightCtl/core.js new file mode 100644 index 0000000..30ae44f --- /dev/null +++ b/lightCtl/core.js @@ -0,0 +1,29 @@ +var core = (room, light) => { + var o = { + NoPeopleDelayTime: 1000 * 10, + LastOnTime: 0, + LastOffTime: 0, + }; + + room.on('peopleIn', ()=>{ + if(room.num == 1){ + light.on(); + o.LastOnTime = new Date().valueOf(); + } + }); + + room.on('peopleOut', ()=>{ + if(room.num == 0){ + setTimeout(()=>{ + if(room.num == 0){ + light.off(); + o.LastOffTime = new Date().valueOf(); + } + }, o.NoPeopleDelayTime); + } + }); + return o; +}; + + +exports.core = core; diff --git a/lightCtl/isolat.js b/lightCtl/isolat.js new file mode 100644 index 0000000..e1409e5 --- /dev/null +++ b/lightCtl/isolat.js @@ -0,0 +1,23 @@ +var isolat = (room, light, pir, lightCtl) => { + + /* reg */ + pir.forEach((item)=>{ + item.on('peopleIn', ()=>{ + if(!room.num){ + light.on(); + } + }); + + item.on('peopleOut', ()=>{ + if(!room.num && room.LastActTime + lightCtl.NoPeopleDelayTime < new Date().valueOf()){ + if(!pir.some((items)=>{ + return items.state; + })){ + light.off(); + } + } + }); + }); +} + +exports.isolat = isolat; diff --git a/match.js b/match.js new file mode 100644 index 0000000..5626a24 --- /dev/null +++ b/match.js @@ -0,0 +1,93 @@ +var match = (zone, light) => { + + + + var mObj = (zones) => { + + var o_O = { + LastActTime: new Date().valueOf(), + LastUnActTime: new Date().valueOf(), + state: false, + func: { + peopleIn: [], + peopleOut: [], + toggle: [] + }, + on: (event, handler) => { + if(event == "peopleIn"){ + o_O.func.peopleIn.push(handler); + } + if(event == "peopleOut"){ + o_O.func.peopleOut.push(handler); + } + if(event == "toggle"){ + o_O.func.toggle.push(handler); + } + } + }; + + zones.forEach((item, index)=>{ + item.on('peopleIn', ()=>{ + if(!o_O.state){ + o_O.state = true; + o_O.LastActTime = new Date().valueOf(); + } + o_O.func.peopleIn.forEach((item)=>{ + item(); + }); + o_O.func.toggle.forEach((item)=>{ + item(); + }); + }); + + item.on('peopleOut', ()=>{ + if(o_O.state){ + o_O.state = false; + o_O.LastUnActTime = new Date().valueOf(); + }; + o_O.func.peopleOut.forEach((item)=>{ + item(); + }); + o_O.func.toggle.forEach((item)=>{ + item(); + }); + }); + + }); + + return o_O; + } + + + + + zone.hall[0].on('peopleIn', ()=>{ + light.hall.on(); + }); + + + var hall = mObj([zone.hall[0], zone.hall[1]]); + + hall.on('peopleIn', ()=>{ + light.hall.on(); + }); + + hall.on('peopleOut', ()=>{ + light.hall.off(); + }); + + var liv = mObj([zone.liv[0], zone.liv[1]]); + + liv.on('peopleIn', ()=>{ + light.liv.on(); + }); + + liv.on('peopleOut', ()=>{ + light.liv.off(); + }); + + + +} + +exports.match = match; diff --git a/mqtt/light.js b/mqtt/light.js new file mode 100644 index 0000000..2a9f3a5 --- /dev/null +++ b/mqtt/light.js @@ -0,0 +1,28 @@ +var light = (client, clientId) => { + + var o = { + state: false, + LastOnTime: new Date().valueOf(), + LastOffTime: new Date().valueOf(), + on: ()=>{ + client.publish('hass/autoLight/'+clientId, '1'); + }, + off: ()=>{ + client.publish('hass/autoLight/'+clientId, '0'); + } + + }; + + + client.on('message', (subject, msg)=>{ + if(subject == 'hass/snsr/'+clientId+'/lightCtl'){ + if(msg == 1) o.state = true; + if(msg == 0) o.state = false; + } + }); + + return o; +} + + +exports.light = light; diff --git a/mqtt/peo.js b/mqtt/peo.js new file mode 100644 index 0000000..741c0ef --- /dev/null +++ b/mqtt/peo.js @@ -0,0 +1,29 @@ +var peo = (client, room)=>{ + + let lastAct = ''; + +setInterval(()=>{ + let act = ''; + if(typeof room.act != "undefined") act = (room.act.rate.toString().length>4?room.act.rate.toString().substring(0, 4):room.act.rate.toString()); + else act = room.num.toString(); + + if(act != lastAct){ + client.publish('peo/'+room.id, act); + lastAct = act; + } +}, 500); +/* + room.on('peopleIn', ()=>{ + client.publish('peo/'+room.id, room.num.toString()); + if(typeof room.act != "undefined") client.publish('act/'+room.id, (room.act.rate.toString().length>4?room.act.rate.toString().substring(0, 4):room.act.rate.toString())); + }); + + room.on('peopleOut', ()=>{ + client.publish('peo/'+room.id, room.num.toString()); + if(typeof room.act != "undefined") client.publish('act/'+room.id, (room.act.rate.toString().length>4?room.act.rate.toString().substring(0, 4):room.act.rate.toString())); + }); + +*/ +} + +exports.peo = peo; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..3364c21 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,621 @@ +{ + "name": "autolight", + "version": "0.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" + }, + "bl": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "callback-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/callback-stream/-/callback-stream-1.1.0.tgz", + "integrity": "sha1-RwGlEmbwbgbqpx/BcjOCLYdfSQg=", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "> 1.0.0 < 3.0.0" + } + }, + "commist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz", + "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==", + "requires": { + "leven": "^2.1.0", + "minimist": "^1.1.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-set": "~0.1.5", + "es6-symbol": "~3.1.1", + "event-emitter": "~0.3.5" + } + }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14", + "es6-iterator": "~2.0.1", + "es6-symbol": "3.1.1", + "event-emitter": "~0.3.5" + }, + "dependencies": { + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + } + } + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "ext": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", + "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "requires": { + "type": "^2.0.0" + }, + "dependencies": { + "type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz", + "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==" + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "glob-stream": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", + "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", + "requires": { + "extend": "^3.0.0", + "glob": "^7.1.1", + "glob-parent": "^3.1.0", + "is-negated-glob": "^1.0.0", + "ordered-read-streams": "^1.0.0", + "pumpify": "^1.3.5", + "readable-stream": "^2.1.5", + "remove-trailing-separator": "^1.0.1", + "to-absolute-glob": "^2.0.0", + "unique-stream": "^2.0.2" + } + }, + "help-me": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-1.1.0.tgz", + "integrity": "sha1-jy1QjQYAtKRW2i8IZVbn5cBWo8Y=", + "requires": { + "callback-stream": "^1.0.2", + "glob-stream": "^6.1.0", + "through2": "^2.0.1", + "xtend": "^4.0.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + }, + "is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=" + }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "requires": { + "is-unc-path": "^1.0.0" + } + }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "requires": { + "unc-path-regex": "^0.1.2" + } + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" + }, + "leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "mqtt": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-3.0.0.tgz", + "integrity": "sha512-0nKV6MAc1ibKZwaZQUTb3iIdT4NVpj541BsYrqrGBcQdQ7Jd0MnZD1/6/nj1UFdGTboK9ZEUXvkCu2nPCugHFA==", + "requires": { + "base64-js": "^1.3.0", + "commist": "^1.0.0", + "concat-stream": "^1.6.2", + "end-of-stream": "^1.4.1", + "es6-map": "^0.1.5", + "help-me": "^1.0.1", + "inherits": "^2.0.3", + "minimist": "^1.2.0", + "mqtt-packet": "^6.0.0", + "pump": "^3.0.0", + "readable-stream": "^2.3.6", + "reinterval": "^1.1.0", + "split2": "^3.1.0", + "websocket-stream": "^5.1.2", + "xtend": "^4.0.1" + } + }, + "mqtt-packet": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.3.2.tgz", + "integrity": "sha512-i56+2kN6F57KInGtjjfUXSl4xG8u/zOvfaXFLKFAbBXzWkXOmwcmjaSCBPayf2IQCkQU0+h+S2DizCo3CF6gQA==", + "requires": { + "bl": "^1.2.2", + "debug": "^4.1.1", + "inherits": "^2.0.3", + "process-nextick-args": "^2.0.0", + "safe-buffer": "^5.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "ordered-read-streams": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", + "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", + "requires": { + "readable-stream": "^2.0.1" + } + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "reinterval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", + "integrity": "sha1-M2Hs+jymwYKDOA3Qu5VG85D17Oc=" + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "split2": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.1.1.tgz", + "integrity": "sha512-emNzr1s7ruq4N+1993yht631/JH+jaj0NYBosuKmLcq+JkGQ9MmTw1RB1fGaTCzUuseRIClrlSLHRNYGwWQ58Q==", + "requires": { + "readable-stream": "^3.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "through2-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", + "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", + "requires": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + } + }, + "to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", + "requires": { + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" + } + }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=" + }, + "unique-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", + "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", + "requires": { + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "websocket-stream": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/websocket-stream/-/websocket-stream-5.5.2.tgz", + "integrity": "sha512-8z49MKIHbGk3C4HtuHWDtYX8mYej1wWabjthC/RupM9ngeukU4IWoM46dgth1UOS/T4/IqgEdCDJuMe2039OQQ==", + "requires": { + "duplexify": "^3.5.1", + "inherits": "^2.0.1", + "readable-stream": "^2.3.3", + "safe-buffer": "^5.1.2", + "ws": "^3.2.0", + "xtend": "^4.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..8ac2909 --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "autolight", + "version": "0.0.0", + "description": "Smart light decision-making part for sola proj.", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/iotcat/sola.git" + }, + "keywords": [ + "iot", + "smart", + "home", + "light" + ], + "author": "iotcat", + "license": "MIT", + "bugs": { + "url": "https://github.com/iotcat/sola/issues" + }, + "homepage": "https://github.com/iotcat/sola#readme", + "dependencies": { + "mqtt": "^3.0.0" + } +} diff --git a/people/interface.js b/people/interface.js new file mode 100644 index 0000000..b407b1e --- /dev/null +++ b/people/interface.js @@ -0,0 +1,59 @@ +var interface = (z0, z1) => { + var o = { + state: 'null', + func: { + forward: [], + backward: [], + }, + on: (event, handler)=>{ + if(event == 'forward'){ + o.func.forward.push(handler); + } + if(event == 'backward'){ + o.func.backward.push(handler); + } + }, + + }; + + + z0.on('peopleIn', ()=>{ + if(z1.state){ + o.state = "forward"; + console.log(new Date().toTimeString() + ' - ' + z1.tag + ' to ' + z0.tag); + o.func.backward.forEach((item)=>{ + item(); + }); + } + }); + + z1.on('peopleIn', ()=>{ + if(z0.state){ + o.state = "backward"; + console.log(new Date().toTimeString() + ' - ' + z0.tag + ' to ' + z1.tag); + o.func.forward.forEach((item)=>{ + item(); + }); + } + }) + + z1.on('peopleOut', ()=>{ + if(!z0.state){ + o.state = "null"; + } + }); + + z0.on('peopleOut', ()=>{ + if(!z1.state){ + o.state = "null"; + } + }); + + + + return o; +} + + + +exports.interface = interface; diff --git a/people/pir.js b/people/pir.js new file mode 100644 index 0000000..d91756a --- /dev/null +++ b/people/pir.js @@ -0,0 +1,60 @@ +var pir = (client, clientId, pirId) => { + var o = { + state: false, + LastActTime: new Date().valueOf(), + LastUnActTime: new Date().valueOf(), + topic: 'hass/snsr/'+clientId+'/p'+pirId, + func: { + peopleIn: [], + peopleOut: [], + toggle: [] + }, + on: (event, handler)=>{ + if(event == 'peopleIn'){ + o.func.peopleIn.push(handler); + } + if(event == 'peopleOut'){ + o.func.peopleOut.push(handler); + } + if(event == 'toggle'){ + o.func.toggle.push(handler); + } + }, + + }; + + client.on('connect', ()=>{ + client.subscribe(o.topic); + }); + + client.on('message', (topic, msg) => { + if(topic == o.topic){ + if(msg == 1){ + if(!o.state) { + o.state = true; + o.func.peopleIn.forEach((item)=>{ + item(); + }); + o.func.toggle.forEach((item)=>{ + item(); + }); + } + } + if(msg == 0){ + if(o.state){ + o.state = false + o.func.peopleOut.forEach((item)=>{ + item(); + }); + o.func.toggle.forEach((item)=>{ + item(); + }); + } + } + } + }); + + return o; +}; + +exports.pir = pir; diff --git a/people/zone.js b/people/zone.js new file mode 100644 index 0000000..cda8194 --- /dev/null +++ b/people/zone.js @@ -0,0 +1,96 @@ +const zone = (tag, pir) => { + var o = { + 'tag': tag, + state: false, + rate: 0, + fRate: 0, + "pir": pir, + num: pir.length, + actNum: 0, + threshold: 0, + LastActTime: new Date().valueOf(), + LastUnActTime: new Date().valueOf(), + LastChangeTime: new Date().valueOf(), + func: { + peopleIn: [], + peopleOut: [], + toggle: [] + }, + on: (event, handler)=>{ + if(event == "peopleIn"){ + o.func.peopleIn.push(handler); + } + if(event == "peopleOut"){ + o.func.peopleOut.push(handler); + } + if(event == "toggle"){ + o.func.toggle.push(handler); + } + }, + }; + + + var peopleIn = () => { + o.actNum ++; + refresh(); + + if(o.fRate <= o.threshold) {o.func.peopleIn.forEach((item)=>{ + item(); + }); + + o.func.toggle.forEach((item)=>{ + item(); + }); + o.LastActTime = new Date().valueOf(); + } + }; + + var peopleOut = () => { + o.actNum --; + refresh(); + + if(o.fRate > o.threshold && o.rate <= o.threshold) {o.func.peopleOut.forEach((item)=>{ + item(); + }); + + o.func.toggle.forEach((item)=>{ + item(); + }); + o.LastUnActTime = new Date().valueOf(); + } + }; + + var toggle = () => { + o.LastChangeTime = new Date().valueOf(); + }; + + var refresh = () => { + o.fRate = o.rate; + o.rate = o.actNum * 100 / o.num; + if(o.rate > o.threshold){ + o.state = true; + }else{ + o.state = false; + } + }; + + + + /* reg */ + o.pir.forEach((item, index)=>{ + item.on('peopleIn', ()=>{ + peopleIn(); + }); + item.on('peopleOut', ()=>{ + peopleOut(); + }); + item.on('toggle', ()=>{ + toggle(); + }); + }); + + return o; +} + + +exports.zone = zone; diff --git a/room/din.js b/room/din.js new file mode 100644 index 0000000..f847070 --- /dev/null +++ b/room/din.js @@ -0,0 +1,165 @@ +const actModel = require('../func/actModel.js').actModel; +var din = (zone, interface, p) => { + + var o = { + id: 'din', + num: 0, + numAct: 0, + MaxNum: 5, + LastActTime: new Date().valueOf(), + MaxSensitTime: 1000 * 60 * 2, + func: { + peopleIn: [], + peopleOut: [], + }, + on: (event, handler)=>{ + if(event == 'peopleIn'){ + o.func.peopleIn.push(handler); + } + if(event == 'peopleOut'){ + o.func.peopleOut.push(handler); + } + }, + act: { + rate: 0, + maxDetectTime: 1000 * 60 * 10, + actTimeArray: [] + }, + extTime: 0, + isNight: false + }; + + + var pLimiter = ()=>{ + if(o.num < 0) o.num = 0; + if(o.num > o.MaxNum) o.num = o.MaxNum; + o.LastActTime = new Date().valueOf(); + } + + + + var pIn = ()=>{ + o.num = 1; + pLimiter(); + console.log(new Date().toTimeString() + ' - din = ' + o.num + ' ++ ACT: '+o.act.rate); + o.func.peopleIn.forEach((item)=>{ + item(); + }); + } + + var pOut = ()=>{ + o.num = 0; + pLimiter(); + console.log(new Date().toTimeString() + ' - din = ' + o.num + ' -- ACT: '+o.act.rate); + o.func.peopleOut.forEach((item)=>{ + item(); + }); + } + + + + + + + interface.hd.on('forward', ()=>{ + //pIn(); + }); + /* + interface.dk.on('backward', ()=>{ + pIn(); + })*/ + interface.dl.on('backward', ()=>{ + //pIn(); + }) + + + interface.hd.on('backward', ()=>{ + //if(!o.isNight || o.num != 1 ) pOut(); + }) + + /* interface.dk.on('forward', ()=>{ + pOut(); + });*/ + interface.dl.on('forward', ()=>{ + //if(!o.isNight || o.num != 1 ) pOut(); + }); + + + + /* 超时衰减 */ + setInterval(()=>{ + if( new Date().getHours() >= 18 && new Date().getHours() <= 20 ) o.isNight = true; + else o.isNight = false; + + if((o.numAct && o.act.rate > .2) || o.act.rate > .4){ + if(!o.num) pIn(); + }else{ + if(o.num) pOut(); + } + + o.extTime = ((o.num == 1) && o.isNight)*1000*60*1; + if(o.num + && o.LastActTime + o.MaxSensitTime * o.act.rate + o.extTime < new Date().valueOf() + && zone.din[0].LastChangeTime + o.MaxSensitTime * o.act.rate < new Date().valueOf() + && zone.din[1].LastChangeTime + o.MaxSensitTime * o.act.rate < new Date().valueOf()){ + //pOut(); + } + }, 1000); + + + /* 意外触发 */ + p.din[2].on('peopleIn', ()=>{ + if(o.isNight && !o.num){ + if(o.LastActTime > new Date().valueOf() - o.MaxSensitTime * o.act.rate){ + //pIn(); + } + } + }); + p.din[3].on('peopleIn', ()=>{ + if(o.isNight && !o.num){ + if(o.LastActTime > new Date().valueOf() - o.MaxSensitTime * o.act.rate){ + //pIn(); + } + } + }); + + + /* 门进入人 */ + + + + /* 活跃度监测 */ + setInterval(()=>{ + if(zone.din[0].actNum || zone.din[1].actNum){ + o.act.actTimeArray.push(new Date().valueOf()); + o.numAct = 1; + }else{ + o.numAct = 0; + } + while(o.act.actTimeArray[0] < new Date().valueOf() - o.act.maxDetectTime){ + o.act.actTimeArray.shift(); + } + o.act.rate = o.act.actTimeArray.length * 1000 / o.act.maxDetectTime; + + }, 1000); + /*zone.din.forEach((item)=>{ + item.on('toggle', ()=>{ + o.act.actTimeArray.push(new Date().valueOf()); + }); + });*/ + /* + setInterval(()=>{ + while(o.act.actTimeArray[0] < new Date().valueOf() - o.act.maxDetectTime){ + o.act.actTimeArray.shift(); + } + o.act.rate = actModel(o.act.actTimeArray.length); + + }, 1000); +*/ + + + return o; + +} + +exports.din = din; diff --git a/room/hall.js b/room/hall.js new file mode 100644 index 0000000..3f0794d --- /dev/null +++ b/room/hall.js @@ -0,0 +1,105 @@ +var hall = (zone, interface) => { + + var o = { + id: 'hall', + num: 0, + MaxNum: 2, + LastActTime: new Date().valueOf(), + MaxSensitTime: 1000 * 60 * 1, + func: { + peopleIn: [], + peopleOut: [], + }, + on: (event, handler)=>{ + if(event == 'peopleIn'){ + o.func.peopleIn.push(handler); + } + if(event == 'peopleOut'){ + o.func.peopleOut.push(handler); + } + } + }; + + + var pLimiter = ()=>{ + if(o.num < 0) o.num = 0; + if(o.num > o.MaxNum) o.num = o.MaxNum; + o.LastActTime = new Date().valueOf(); + } + + + + var pIn = ()=>{ + o.num ++; + pLimiter(); + console.log(new Date().toTimeString() + ' - hall = ' + o.num + ' ++'); + o.func.peopleIn.forEach((item)=>{ + item(); + }); + } + + var pOut = ()=>{ + o.num --; + pLimiter(); + console.log(new Date().toTimeString() + ' - hall = ' + o.num + ' --'); + o.func.peopleOut.forEach((item)=>{ + item(); + }); + } + + + + + + + interface.h.on('forward', ()=>{ + pIn(); + }); + + interface.hd.on('backward', ()=>{ + pIn(); + }) + + interface.h.on('backward', ()=>{ + pOut(); + }) + + interface.hd.on('forward', ()=>{ + pOut(); + }); + + /* 超时衰减 */ + setInterval(()=>{ + if(o.num + && o.LastActTime + o.MaxSensitTime < new Date().valueOf() + && zone.hall[1].LastChangeTime + o.MaxSensitTime < new Date().valueOf()){ + pOut(); + } + }, 1000); + + + /* 意外触发 */ + zone.hall[1].on('peopleIn', ()=>{ + if(!o.num){ + if(o.LastActTime > new Date().valueOf() - o.MaxSensitTime){ + pIn(); + } + } + }); + /* 意外触发 */ + zone.hall[0].on('peopleIn', ()=>{ + if(!o.num){ + if(o.LastActTime > new Date().valueOf() - o.MaxSensitTime){ + pIn(); + } + } + }); + + + + return o; + + +} + +exports.hall = hall; diff --git a/room/kit.js b/room/kit.js new file mode 100644 index 0000000..ef7a946 --- /dev/null +++ b/room/kit.js @@ -0,0 +1,136 @@ +const actModel = require('../func/actModel.js').actModel; + +var kit = (zone, interface) => { + + var o = { + id: 'kit', + num: 0, + numAct: 0, + MaxNum: 3, + LastActTime: new Date().valueOf(), + MaxSensitTime: 1000 * 60 * 2, + func: { + peopleIn: [], + peopleOut: [], + }, + on: (event, handler)=>{ + if(event == 'peopleIn'){ + o.func.peopleIn.push(handler); + } + if(event == 'peopleOut'){ + o.func.peopleOut.push(handler); + } + }, + act: { + rate: 0, + maxDetectTime: 1000 * 60 * 7, + actTimeArray: [] + } + }; + + + var pLimiter = ()=>{ + if(o.num < 0) o.num = 0; + if(o.num > o.MaxNum) o.num = o.MaxNum; + o.LastActTime = new Date().valueOf(); + } + + + + var pIn = ()=>{ + o.num = 1; + pLimiter(); + console.log(new Date().toTimeString() + ' - kit = ' + o.num + ' ++ ACT: '+o.act.rate); + o.func.peopleIn.forEach((item)=>{ + item(); + }); + } + + var pOut = ()=>{ + o.num = 0; + pLimiter(); + console.log(new Date().toTimeString() + ' - kit = ' + o.num + ' -- ACT: '+o.act.rate); + o.func.peopleOut.forEach((item)=>{ + item(); + }); + } + + + + + + + interface.dk.on('forward', ()=>{ + //pIn(); + }); + + interface.dk.on('backward', ()=>{ + //pOut(); + }) + + /* 超时衰减 */ + setInterval(()=>{ + if((o.numAct && o.act.rate > .2) || o.act.rate > .3){ + if(!o.num) pIn(); + }else{ + if(o.num) pOut(); + } + /*if(o.num + && o.LastActTime + o.MaxSensitTime * o.act.rate < new Date().valueOf() + && zone.kit[0].LastChangeTime + o.MaxSensitTime * o.act.rate < new Date().valueOf()){ + //pOut(); + }*/ + }, 1000); + + + /* 意外触发 */ + zone.kit[0].on('peopleIn', ()=>{ + if(!o.num){ + if(o.LastActTime > new Date().valueOf() - o.MaxSensitTime * o.act.rate){ + //pIn(); + } + } + }); + + + + /* 活跃度监测 */ + setInterval(()=>{ + if(zone.kit[0].actNum){ + o.act.actTimeArray.push(new Date().valueOf()); + }; + while(o.act.actTimeArray[0] < new Date().valueOf() - o.act.maxDetectTime){ + o.act.actTimeArray.shift(); + } + o.act.rate = o.act.actTimeArray.length * 1000 / o.act.maxDetectTime; + + if(zone.kit[0].actNum){ + o.numAct = 1; + }else{ + o.numAct = 0; + } + }, 1000); + /*zone.din.forEach((item)=>{ + item.on('toggle', ()=>{ + o.act.actTimeArray.push(new Date().valueOf()); + }); + }); + */ + + /* + setInterval(()=>{ + while(o.act.actTimeArray[0] < new Date().valueOf() - o.act.maxDetectTime){ + o.act.actTimeArray.shift(); + } + o.act.rate = actModel(o.act.actTimeArray.length); + }, 1000); +*/ + + + + + return o; + +} + +exports.kit = kit; diff --git a/room/liv.js b/room/liv.js new file mode 100644 index 0000000..1d2e1ce --- /dev/null +++ b/room/liv.js @@ -0,0 +1,146 @@ +const actModel = require('../func/actModel.js').actModel; + +var liv = (zone, interface) => { + + var o = { + id: 'liv', + num: 0, + numAct: 0, + MaxNum: 5, + LastActTime: new Date().valueOf(), + MaxSensitTime: 1000 * 60 * 2, + extTime: 0, + isNight: false, + func: { + peopleIn: [], + peopleOut: [], + }, + on: (event, handler)=>{ + if(event == 'peopleIn'){ + o.func.peopleIn.push(handler); + } + if(event == 'peopleOut'){ + o.func.peopleOut.push(handler); + } + }, + act: { + rate: 0, + maxDetectTime: 1000 * 60 * 30, + actTimeArray: [] + } + }; + + + var pLimiter = ()=>{ + if(o.num < 0) o.num = 0; + if(o.num > o.MaxNum) o.num = o.MaxNum; + o.LastActTime = new Date().valueOf(); + } + + + + var pIn = ()=>{ + o.num = 1; + pLimiter(); + console.log(new Date().toTimeString() + ' - liv = ' + o.num + ' ++ ACT: '+o.act.rate); + o.func.peopleIn.forEach((item)=>{ + item(); + }); + } + + var pOut = ()=>{ + o.num = 0; + pLimiter(); + console.log(new Date().toTimeString() + ' - liv = ' + o.num + ' -- ACT: '+o.act.rate); + o.func.peopleOut.forEach((item)=>{ + item(); + }); + } + + + + + + /* 正常触发 */ + interface.dl.on('forward', ()=>{ + //pIn(); + }); + + interface.dl.on('backward', ()=>{ + //if(!o.isNight || o.num != 1 ) pOut(); + }) + + + /* 超时衰减 */ + setInterval(()=>{ + if( new Date().getHours() >= 19 && new Date().getHours() <= 21 ) o.isNight = true; + else o.isNight = false; + + + let r = 0.3; + + if(new Date().getHours() == 19) { + r = 0.1; + o.act.maxDetectTime = 1000 * 60 * 15; + }else if(new Date().getHours() == 20) { + r = 0.05; + o.act.maxDetectTime = 1000 * 60 * 30; + }else if(new Date().getHours() == 21) { + r = 0.05; + o.act.maxDetectTime = 1000 * 60 * 15; + }else{ + r = 0.3; + o.act.maxDetectTime = 1000 * 60 * 10; + } + + if(o.numAct || o.act.rate > r){ + if(!o.num) pIn(); + }else{ + if(o.num) pOut(); + } + + + o.extTime = ((o.num == 1) && o.isNight)*1000*60*12; + if(o.num + && o.LastActTime + o.MaxSensitTime * o.act.rate + o.extTime< new Date().valueOf()){ + //pOut(); + } + }, 1000); + + + /* 意外触发 */ + zone.liv[1].on('peopleIn', ()=>{ + if(o.isNight && !o.num){ + if(o.LastActTime > new Date().valueOf() - o.MaxSensitTime * o.act.rate){ + //pIn(); + //pIn(); + } + } + }); + + + /* 活跃度监测 */ + /*zone.liv.forEach((item)=>{ + item.on('toggle', ()=>{ + o.act.actTimeArray.push(new Date().valueOf()); + }); + });*/ + setInterval(()=>{ + if(zone.liv[0].actNum || zone.liv[1].actNum){ + o.act.actTimeArray.push(new Date().valueOf()); + o.numAct = 1; + }else{ + o.numAct = 0; + } + while(o.act.actTimeArray[0] < new Date().valueOf() - o.act.maxDetectTime){ + o.act.actTimeArray.shift(); + } + o.act.rate = o.act.actTimeArray.length * 1000 / o.act.maxDetectTime; + + }, 1000); + + return o; + +} + +exports.liv = liv;