Persist device state with node-persist. This allows multiple controllers to share state, and for device to maintain settings between shutdowns.

This commit is contained in:
mmcw-dev 2017-10-23 12:58:37 -04:00
parent d0e1026c7a
commit b307567a51
5 changed files with 123 additions and 19 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
node_modules node_modules
run_dev.sh run_dev.sh
state

View File

@ -265,12 +265,15 @@
<option value="33">2</option> <option value="33">2</option>
</select> </select>
</div> </div>
<h2>BLUETOOTH</h2>
<select id="bluetooth">
<option>N/A</option>
</select>
<h2>WIFI</h2>
<div> <div>
<div class="label">Wifi SSID</div>
<input type="text" id="ssid" placeholder="Wifi SSID" /> <input type="text" id="ssid" placeholder="Wifi SSID" />
</div> </div>
<div> <div>
<div class="label">Wifi Password</div>
<input type="password" id="password" placeholder="Wifi Password" /> <input type="password" id="password" placeholder="Wifi Password" />
</div> </div>
</div> </div>

View File

@ -1,10 +1,12 @@
'use strict' 'use strict'
const log = require('../log')('intval') const log = require('../log')('intval')
const storage = require('node-persist')
const fs = require('fs')
let Gpio let Gpio
try { try {
Gpio = require('onoff').Gpio //Gpio = require('onoff').Gpio
} catch (e) { } catch (e) {
log.warn('Failed including Gpio, using sim') log.warn('Failed including Gpio, using sim')
Gpio = require('../../lib/onoffsim').Gpio Gpio = require('../../lib/onoffsim').Gpio
@ -36,7 +38,53 @@ const PINS = {
const intval = {} const intval = {}
intval.init = function () { intval.init = function () {
if (!fs.existsSync('./state')) fs.mkdirSync('./state')
storage.init({
dir: './state',
stringify: JSON.stringify,
parse: JSON.parse,
encoding: 'utf8',
logging: false, // can also be custom logging function
continuous: true, // continously persist to disk
interval: false, // milliseconds, persist to disk on an interval
ttl: false, // ttl* [NEW], can be true for 24h default or a number in MILLISECONDS
expiredInterval: 2 * 60 * 1000, // [NEW] every 2 minutes the process will clean-up the expired cache
forgiveParseErrors: false // [NEW]
}).then((res) => {
//console.dir(res)
storage.getItem('_state', 'test').then(intval._setState).catch((err) => {
intval._setState(undefined)
log.error('init', err)
})
}).catch((err) => {
log.error('init', err)
})
intval._frame = {
open : 250, //delay before pausing frame in open state
openBwd : 400,
closed : 100, //time that frame actually remains closed for
expected : 630 //expected length of frame, in ms
}
intval._release = {
min : 20,
seq : 1000
}
intval._microDelay = 10 // delay after stop signal before stopping motors
intval._pin = {} intval._pin = {}
intval._declarePins()
process.on('SIGINT', intval._undeclarePins)
process.on('uncaughtException', intval._undeclarePins)
}
intval._setState = function (data) {
if (typeof data !== 'undefined') {
intval._state = data
intval._state.frame.cb = () => {}
log.info('_setState', 'Restored intval state from disk')
return true
}
intval._state = { intval._state = {
frame : { frame : {
dir : true, //forward dir : true, //forward
@ -57,22 +105,17 @@ intval.init = function () {
}, },
counter : 0 counter : 0
} }
intval._frame = { intval._storeState()
open : 250, //delay before pausing frame in open state
openBwd : 400,
closed : 100, //time that frame actually remains closed for
expected : 630 //expected length of frame, in ms
}
intval._release = {
min : 20,
seq : 1000
}
intval._microDelay = 10 // delay after stop signal before stopping motors
intval._declarePins()
process.on('SIGINT', intval._undeclarePins)
process.on('uncaughtException', intval._undeclarePins)
} }
intval._storeState = function () {
setItem('_state', intval._state)
.then(() => {})
.catch((err) => {
log.error('_storeState', err)
})
}
/** /**
* (internal function) Declares all Gpio pins that will be used * (internal function) Declares all Gpio pins that will be used
* *
@ -253,20 +296,24 @@ intval.setDir = function (val = true) {
return log.warn('Direction must be represented as either true or false') return log.warn('Direction must be represented as either true or false')
} }
intval._state.frame.dir = val intval._state.frame.dir = val
intval._storeState()
log.info('setDir', { direction : val ? 'forward' : 'backward' }) log.info('setDir', { direction : val ? 'forward' : 'backward' })
} }
intval.setExposure = function (val = 0) { intval.setExposure = function (val = 0) {
intval._state.frame.exposure = val intval._state.frame.exposure = val
intval._storeState()
log.info('setExposure', { exposure : val }) log.info('setExposure', { exposure : val })
} }
intval.setDelay = function (val = 0) { intval.setDelay = function (val = 0) {
intval._state.frame.delay = val intval._state.frame.delay = val
intval._storeState()
log.info('setDelay', { delay : val }) log.info('setDelay', { delay : val })
} }
intval.setCounter = function (val = 0) { intval.setCounter = function (val = 0) {
intval._state.counter = val intval._state.counter = val
intval._storeState()
log.info('setCounter', { counter : val }) log.info('setCounter', { counter : val })
} }
/** /**
@ -321,11 +368,13 @@ intval.frame = function (dir = null, time = null, cb = () => {}) {
if (dir) { if (dir) {
intval._state.frame.cb = (len) => { intval._state.frame.cb = (len) => {
intval._state.counter++ intval._state.counter++
intval._storeState()
cb(len) cb(len)
} }
} else { } else {
intval._state.frame.cb = (len) => { intval._state.frame.cb = (len) => {
intval._state.counter-- intval._state.counter--
intval._storeState()
cb(len) cb(len)
} }
} }

50
package-lock.json generated
View File

@ -607,16 +607,46 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
}, },
"is-absolute": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz",
"integrity": "sha1-IN5p89uULvLYe5wto28XIjWxtes=",
"requires": {
"is-relative": "0.2.1",
"is-windows": "0.2.0"
}
},
"is-regexp": { "is-regexp": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
"integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=" "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk="
}, },
"is-relative": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz",
"integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=",
"requires": {
"is-unc-path": "0.1.2"
}
},
"is-supported-regexp-flag": { "is-supported-regexp-flag": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-supported-regexp-flag/-/is-supported-regexp-flag-1.0.0.tgz", "resolved": "https://registry.npmjs.org/is-supported-regexp-flag/-/is-supported-regexp-flag-1.0.0.tgz",
"integrity": "sha1-i1IMhfrnolM4LUsCZS4EVXbhO7g=" "integrity": "sha1-i1IMhfrnolM4LUsCZS4EVXbhO7g="
}, },
"is-unc-path": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz",
"integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=",
"requires": {
"unc-path-regex": "0.1.2"
}
},
"is-windows": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz",
"integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw="
},
"isarray": { "isarray": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
@ -888,6 +918,16 @@
"js-queue": "2.0.0" "js-queue": "2.0.0"
} }
}, },
"node-persist": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/node-persist/-/node-persist-2.1.0.tgz",
"integrity": "sha1-5lK784haBNrWo1PXQXYXfIORRwc=",
"requires": {
"is-absolute": "0.2.6",
"mkdirp": "0.5.1",
"q": "1.1.2"
}
},
"object-get": { "object-get": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/object-get/-/object-get-2.1.0.tgz", "resolved": "https://registry.npmjs.org/object-get/-/object-get-2.1.0.tgz",
@ -946,6 +986,11 @@
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
}, },
"q": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/q/-/q-1.1.2.tgz",
"integrity": "sha1-Y1fikSBnAdmfGXq4TlforRlvKok="
},
"qs": { "qs": {
"version": "6.5.0", "version": "6.5.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.0.tgz", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.0.tgz",
@ -1312,6 +1357,11 @@
} }
} }
}, },
"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="
},
"underscore": { "underscore": {
"version": "1.8.3", "version": "1.8.3",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",

View File

@ -28,6 +28,7 @@
"cron": "^1.2.1", "cron": "^1.2.1",
"gpio": "^0.2.7", "gpio": "^0.2.7",
"node-ipc": "^9.1.0", "node-ipc": "^9.1.0",
"node-persist": "^2.1.0",
"onoff": "^1.1.5", "onoff": "^1.1.5",
"restify": "^5.2.0", "restify": "^5.2.0",
"uuid": "^3.1.0", "uuid": "^3.1.0",