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:
parent
d0e1026c7a
commit
b307567a51
|
@ -1,2 +1,3 @@
|
||||||
node_modules
|
node_modules
|
||||||
run_dev.sh
|
run_dev.sh
|
||||||
|
state
|
|
@ -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>
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
Loading…
Reference in New Issue