re-write progress, changing platforms
This commit is contained in:
parent
af5e493980
commit
26655ea0a7
|
@ -173,7 +173,7 @@ class BLE {
|
|||
bleno.on('stateChange', state => {
|
||||
log.info('stateChange', { state : state })
|
||||
if (state === 'poweredOn') {
|
||||
log.info('Starting advertising', { DEVICE_NAME: DEVICE_NAME, DEVICE_ID : process.env.BLENO_DEVICE_NAME })
|
||||
log.info('Starting advertising', { DEVICE_NAME, DEVICE_ID : process.env.BLENO_DEVICE_NAME })
|
||||
bleno.startAdvertising(DEVICE_NAME, [CHAR_ID])
|
||||
} else {
|
||||
bleno.stopAdvertising()
|
||||
|
|
|
@ -1,423 +1,461 @@
|
|||
'use strict'
|
||||
|
||||
const db = require('../db')
|
||||
const log = require('../log')('intval')
|
||||
const storage = require('node-persist')
|
||||
const fs = require('fs')
|
||||
|
||||
let Gpio
|
||||
'use strict';
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
||||
result["default"] = mod;
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const db = require('../db');
|
||||
const log = require('../log')('intval');
|
||||
const storage = __importStar(require("node-persist"));
|
||||
const fs_extra_1 = require("fs-extra");
|
||||
require("../delay");
|
||||
let Gpio;
|
||||
try {
|
||||
Gpio = require('onoff').Gpio
|
||||
} catch (e) {
|
||||
log.warn('Failed including Gpio, using sim')
|
||||
Gpio = require('../../lib/onoffsim').Gpio
|
||||
Gpio = require('onoff').Gpio;
|
||||
}
|
||||
catch (e) {
|
||||
log.warn('Failed including Gpio, using sim');
|
||||
Gpio = require('../../lib/onoffsim').Gpio;
|
||||
}
|
||||
|
||||
|
||||
const PINS = {
|
||||
fwd : {
|
||||
pin : 13,
|
||||
dir : 'out'
|
||||
fwd: {
|
||||
pin: 13,
|
||||
dir: 'out'
|
||||
},
|
||||
bwd : {
|
||||
pin : 19,
|
||||
dir : 'out'
|
||||
bwd: {
|
||||
pin: 19,
|
||||
dir: 'out'
|
||||
},
|
||||
micro : {
|
||||
pin : 5,
|
||||
dir : 'in',
|
||||
edge : 'both'
|
||||
micro: {
|
||||
pin: 5,
|
||||
dir: 'in',
|
||||
edge: 'both'
|
||||
},
|
||||
release : {
|
||||
pin : 6,
|
||||
dir : 'in',
|
||||
edge : 'both'
|
||||
release: {
|
||||
pin: 6,
|
||||
dir: 'in',
|
||||
edge: 'both'
|
||||
}
|
||||
}
|
||||
|
||||
/** Object representing the intval3 features */
|
||||
const intval = {}
|
||||
|
||||
intval._frame = {
|
||||
open : 250, //delay before pausing frame in open state
|
||||
openBwd : 400,
|
||||
closed : 100, //time that frame actually remains closed for
|
||||
expected : 530 //expected length of frame, in ms
|
||||
}
|
||||
intval._release = {
|
||||
min : 20,
|
||||
seq : 1000
|
||||
}
|
||||
intval._microDelay = 10 // delay after stop signal before stopping motors
|
||||
intval._pin = {}
|
||||
|
||||
/**
|
||||
*
|
||||
};
|
||||
/** class representing the intval3 features */
|
||||
class Intval {
|
||||
constructor() {
|
||||
this.STATE_DIR = '~/state';
|
||||
this._frame = {
|
||||
open: 250,
|
||||
openBwd: 400,
|
||||
closed: 100,
|
||||
expected: 530 //expected length of frame, in ms
|
||||
};
|
||||
this._release = {
|
||||
min: 20,
|
||||
seq: 1000
|
||||
};
|
||||
this._microDelay = 10; // delay after stop signal before stopping motors
|
||||
this._pin = {};
|
||||
this._state = {};
|
||||
this._init();
|
||||
}
|
||||
/**
|
||||
* Initialize the storage object and bind functions to process events.
|
||||
*/
|
||||
|
||||
intval.init = function () {
|
||||
if (!fs.existsSync('./state')) fs.mkdirSync('./state')
|
||||
async _init() {
|
||||
let dirExists;
|
||||
try {
|
||||
dirExists = await fs_extra_1.exists(this.STATE_DIR);
|
||||
}
|
||||
catch (err) {
|
||||
log.error('init', `Error locating state directory ${this.STATE_DIR}`);
|
||||
}
|
||||
if (!dirExists) {
|
||||
try {
|
||||
await fs_extra_1.mkdir(this.STATE_DIR);
|
||||
}
|
||||
catch (err) {
|
||||
log.error('init', `Error creating state directory ${this.STATE_DIR}`);
|
||||
}
|
||||
}
|
||||
storage.init({
|
||||
dir: './state',
|
||||
dir: this.STATE_DIR,
|
||||
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(intval._restoreState).catch((err) => {
|
||||
log.warn('init', err)
|
||||
intval.reset()
|
||||
intval._declarePins()
|
||||
})
|
||||
|
||||
process.on('SIGINT', intval._undeclarePins)
|
||||
process.on('uncaughtException', intval._undeclarePins)
|
||||
}
|
||||
|
||||
intval._restoreState = function (res) {
|
||||
storage.getItem('_state', 'test').then(intval._setState).catch((err) => {
|
||||
intval._setState(undefined)
|
||||
log.error('_restoreState', err)
|
||||
})
|
||||
intval._declarePins()
|
||||
}
|
||||
|
||||
intval._setState = function (data) {
|
||||
logging: false,
|
||||
continuous: true,
|
||||
interval: false,
|
||||
ttl: false,
|
||||
}).then(this._restoreState).catch((err) => {
|
||||
log.warn('init', err);
|
||||
this.reset();
|
||||
this._declarePins();
|
||||
});
|
||||
process.on('SIGINT', this._undeclarePins);
|
||||
process.on('uncaughtException', this._undeclarePins);
|
||||
}
|
||||
/**
|
||||
* Restore the state from the storage object
|
||||
*/
|
||||
_restoreState() {
|
||||
storage.getItem('_state', 'test').then(this._setState).catch((err) => {
|
||||
this._setState();
|
||||
log.error('_restoreState', err);
|
||||
});
|
||||
this._declarePins();
|
||||
}
|
||||
/**
|
||||
* Creating the state object.
|
||||
*/
|
||||
_setState(data = undefined) {
|
||||
if (typeof data !== 'undefined') {
|
||||
intval._state = data
|
||||
intval._state.frame.cb = () => {}
|
||||
log.info('_setState', 'Restored intval state from disk')
|
||||
return true
|
||||
this._state = data;
|
||||
this._state.frame.cb = () => { };
|
||||
log.info('_setState', 'Restored intval state from disk');
|
||||
return true;
|
||||
}
|
||||
log.info('_setState', 'Setting state from defaults')
|
||||
intval._state = {
|
||||
frame : {
|
||||
dir : true, //forward
|
||||
start : 0, //time frame started, timestamp
|
||||
active : false, //should frame be running
|
||||
paused : false,
|
||||
exposure : 0, //length of frame exposure, in ms
|
||||
delay : 0, //delay before start of frame, in ms
|
||||
current : {}, //current settings
|
||||
cb : () => {}
|
||||
log.info('_setState', 'Setting state from defaults');
|
||||
this._state = {
|
||||
frame: {
|
||||
dir: true,
|
||||
start: 0,
|
||||
active: false,
|
||||
paused: false,
|
||||
exposure: 0,
|
||||
delay: 0,
|
||||
current: {},
|
||||
cb: () => { }
|
||||
},
|
||||
release : {
|
||||
release: {
|
||||
time: 0,
|
||||
active : false //is pressed
|
||||
active: false //is pressed
|
||||
},
|
||||
micro : {
|
||||
time : 0,
|
||||
primed : false //is ready to stop frame
|
||||
micro: {
|
||||
time: 0,
|
||||
primed: false //is ready to stop frame
|
||||
},
|
||||
counter : 0,
|
||||
sequence : false
|
||||
counter: 0,
|
||||
sequence: false
|
||||
};
|
||||
this._storeState();
|
||||
}
|
||||
intval._storeState()
|
||||
}
|
||||
|
||||
intval._storeState = function () {
|
||||
storage.setItem('_state', intval._state)
|
||||
.then(() => {})
|
||||
/**
|
||||
* Store the state object.
|
||||
*/
|
||||
_storeState() {
|
||||
storage.setItem('_state', this._state)
|
||||
.then(() => { })
|
||||
.catch((err) => {
|
||||
log.error('_storeState', err)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* (internal function) Declares all Gpio pins that will be used
|
||||
*
|
||||
*/
|
||||
intval._declarePins = function () {
|
||||
let pin
|
||||
log.error('_storeState', err);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* (internal function) Declares all Gpio pins that will be used.
|
||||
*/
|
||||
_declarePins() {
|
||||
let pin;
|
||||
for (let p in PINS) {
|
||||
pin = PINS[p]
|
||||
if (pin.edge) intval._pin[p] = new Gpio(pin.pin, pin.dir, pin.edge)
|
||||
if (!pin.edge) intval._pin[p] = new Gpio(pin.pin, pin.dir)
|
||||
log.info('_declarePins', { pin : pin.pin, dir : pin.dir, edge : pin.edge })
|
||||
pin = PINS[p];
|
||||
if (pin.edge)
|
||||
this._pin[p] = new Gpio(pin.pin, pin.dir, pin.edge);
|
||||
if (!pin.edge)
|
||||
this._pin[p] = new Gpio(pin.pin, pin.dir);
|
||||
log.info('_declarePins', { pin: pin.pin, dir: pin.dir, edge: pin.edge });
|
||||
}
|
||||
intval._pin.release.watch(intval._watchRelease)
|
||||
}
|
||||
/**
|
||||
* (internal function) Undeclares all Gpio in event of uncaught error
|
||||
* that interupts the node process
|
||||
*
|
||||
*/
|
||||
intval._undeclarePins = function (e) {
|
||||
log.error(e)
|
||||
if (!intval._pin) {
|
||||
log.warn('_undeclarePins', { reason : 'No pins'})
|
||||
return process.exit()
|
||||
this._pin.release.watch(this._watchRelease);
|
||||
}
|
||||
log.warn('_undeclarePins', { pin : PINS.fwd.pin, val : 0, reason : 'exiting'})
|
||||
intval._pin.fwd.writeSync(0)
|
||||
log.warn('_undeclarePins', { pin : PINS.bwd.pin, val : 0, reason : 'exiting'})
|
||||
intval._pin.bwd.writeSync(0)
|
||||
intval._pin.fwd.unexport()
|
||||
intval._pin.bwd.unexport()
|
||||
intval._pin.micro.unexport()
|
||||
intval._pin.release.unexport()
|
||||
process.exit()
|
||||
}
|
||||
/**
|
||||
* Start motor in forward direction by setting correct pins in h-bridge
|
||||
*
|
||||
*/
|
||||
intval._startFwd = function () {
|
||||
intval._pin.fwd.writeSync(1)
|
||||
intval._pin.bwd.writeSync(0)
|
||||
}
|
||||
/**
|
||||
* Start motor in backward direction by setting correct pins in h-bridge
|
||||
*
|
||||
*/
|
||||
intval._startBwd = function () {
|
||||
intval._pin.fwd.writeSync(0)
|
||||
intval._pin.bwd.writeSync(1)
|
||||
}
|
||||
|
||||
intval._pause = function () {
|
||||
intval._pin.fwd.writeSync(0)
|
||||
intval._pin.bwd.writeSync(0)
|
||||
/**
|
||||
* (internal function) Undeclares all Gpio in event of uncaught error
|
||||
* that interupts the node process.
|
||||
*/
|
||||
_undeclarePins(e) {
|
||||
log.error('_undeclarePins', e);
|
||||
if (!this._pin) {
|
||||
log.warn('_undeclarePins', { reason: 'No pins' });
|
||||
return process.exit();
|
||||
}
|
||||
log.warn('_undeclarePins', { pin: PINS.fwd.pin, val: 0, reason: 'exiting' });
|
||||
this._pin.fwd.writeSync(0);
|
||||
log.warn('_undeclarePins', { pin: PINS.bwd.pin, val: 0, reason: 'exiting' });
|
||||
this._pin.bwd.writeSync(0);
|
||||
this._pin.fwd.unexport();
|
||||
this._pin.bwd.unexport();
|
||||
this._pin.micro.unexport();
|
||||
this._pin.release.unexport();
|
||||
process.exit();
|
||||
}
|
||||
/**
|
||||
* Start motor in forward direction by setting correct pins in h-bridge
|
||||
*/
|
||||
_startFwd() {
|
||||
this._pin.fwd.writeSync(1);
|
||||
this._pin.bwd.writeSync(0);
|
||||
}
|
||||
/**
|
||||
* Start motor in backward direction by setting correct pins in h-bridge
|
||||
*/
|
||||
_startBwd() {
|
||||
this._pin.fwd.writeSync(0);
|
||||
this._pin.bwd.writeSync(1);
|
||||
}
|
||||
/**
|
||||
* Turn off all directions
|
||||
*/
|
||||
_pause() {
|
||||
this._pin.fwd.writeSync(0);
|
||||
this._pin.bwd.writeSync(0);
|
||||
//log.info('_pause', 'frame paused')
|
||||
}
|
||||
/**
|
||||
* Stop motor by setting both motor pins to 0 (LOW)
|
||||
*
|
||||
*/
|
||||
intval._stop = function () {
|
||||
const entry = {}
|
||||
const now = +new Date()
|
||||
const len = now - intval._state.frame.start
|
||||
|
||||
intval._pin.fwd.writeSync(0)
|
||||
intval._pin.bwd.writeSync(0)
|
||||
|
||||
log.info(`_stop`, { frame : len })
|
||||
|
||||
intval._pin.micro.unwatch()
|
||||
intval._state.frame.active = false
|
||||
|
||||
if (intval._state.frame.cb) intval._state.frame.cb(len)
|
||||
|
||||
entry.start = intval._state.frame.start
|
||||
entry.stop = now
|
||||
entry.len = len
|
||||
entry.dir = intval._state.frame.current.dir ? 1 : 0
|
||||
entry.exposure = intval._state.frame.current.exposure
|
||||
entry.counter = intval._state.counter
|
||||
entry.sequence = intval._state.sequence ? 1 : 0
|
||||
|
||||
db.insert(entry)
|
||||
|
||||
intval._state.frame.current = {}
|
||||
}
|
||||
/**
|
||||
* Callback for watching relese switch state changes.
|
||||
* Using GPIO 06 on Raspberry Pi Zero W.
|
||||
*
|
||||
* 1) If closed AND frame active, start timer, set state primed to `true`.
|
||||
* 1) If opened AND frame active, stop frame
|
||||
*
|
||||
* Microswitch + 10K ohm resistor
|
||||
* * 1 === open
|
||||
* * 0 === closed
|
||||
*
|
||||
*
|
||||
* @param {object} err Error object present if problem reading pin
|
||||
* @param {integer} val Current value of the pin
|
||||
*
|
||||
*/
|
||||
intval._watchMicro = function (err, val) {
|
||||
const now = +new Date()
|
||||
}
|
||||
/**
|
||||
* Stop motor by setting both motor pins to 0 (LOW)
|
||||
*/
|
||||
_stop() {
|
||||
const entry = {};
|
||||
const now = +new Date();
|
||||
const len = now - this._state.frame.start;
|
||||
this._pin.fwd.writeSync(0);
|
||||
this._pin.bwd.writeSync(0);
|
||||
log.info(`_stop`, { frame: len });
|
||||
this._pin.micro.unwatch();
|
||||
this._state.frame.active = false;
|
||||
if (this._state.frame.cb)
|
||||
this._state.frame.cb(len);
|
||||
entry.start = this._state.frame.start;
|
||||
entry.stop = now;
|
||||
entry.len = len;
|
||||
entry.dir = this._state.frame.current.dir ? 1 : 0;
|
||||
entry.exposure = this._state.frame.current.exposure;
|
||||
entry.counter = this._state.counter;
|
||||
entry.sequence = this._state.sequence ? 1 : 0;
|
||||
db.insert(entry);
|
||||
this._state.frame.current = {};
|
||||
}
|
||||
/**
|
||||
* Callback for watching relese switch state changes.
|
||||
* Using GPIO 06 on Raspberry Pi Zero W.
|
||||
*
|
||||
* 1) If closed AND frame active, start timer, set state primed to `true`.
|
||||
* 1) If opened AND frame active, stop frame
|
||||
*
|
||||
* Microswitch + 10K ohm resistor
|
||||
* * 1 === open
|
||||
* * 0 === closed
|
||||
*
|
||||
*
|
||||
* @param {object} err Error object present if problem reading pin
|
||||
* @param {integer} val Current value of the pin
|
||||
*
|
||||
*/
|
||||
_watchMicro(err, val) {
|
||||
const now = +new Date();
|
||||
if (err) {
|
||||
log.error('_watchMicro', err)
|
||||
log.error('_watchMicro', err);
|
||||
}
|
||||
//log.info(`Microswitch val: ${val}`)
|
||||
//determine when to stop
|
||||
if (val === 0 && intval._state.frame.active) {
|
||||
if (!intval._state.micro.primed) {
|
||||
intval._state.micro.primed = true
|
||||
intval._state.micro.time = now
|
||||
log.info('Microswitch primed to stop motor')
|
||||
}
|
||||
} else if (val === 1 && intval._state.frame.active) {
|
||||
if (intval._state.micro.primed && !intval._state.micro.paused && (now - intval._state.frame.start) > intval._frame.open) {
|
||||
intval._state.micro.primed = false
|
||||
intval._state.micro.time = 0
|
||||
setTimeout( () => {
|
||||
intval._stop()
|
||||
}, intval._microDelay)
|
||||
if (val === 0 && this._state.frame.active) {
|
||||
if (!this._state.micro.primed) {
|
||||
this._state.micro.primed = true;
|
||||
this._state.micro.time = now;
|
||||
log.info('Microswitch primed to stop motor');
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Callback for watching relese switch state changes.
|
||||
* Using GPIO 05 on Raspberry Pi Zero W.
|
||||
*
|
||||
* 1) If closed, start timer.
|
||||
* 2) If opened, check timer AND
|
||||
* 3) If `press` (`now - intval._state.release.time`) greater than minimum and less than `intval._release.seq`, start frame
|
||||
* 4) If `press` greater than `intval._release.seq`, start sequence
|
||||
*
|
||||
* Button + 10K ohm resistor
|
||||
* * 1 === open
|
||||
* * 0 === closed
|
||||
*
|
||||
* @param {object} err Error object present if problem reading pin
|
||||
* @param {integer} val Current value of the pin
|
||||
*
|
||||
*/
|
||||
intval._watchRelease = function (err, val) {
|
||||
const now = +new Date()
|
||||
let press = 0
|
||||
else if (val === 1 && this._state.frame.active) {
|
||||
if (this._state.micro.primed && !this._state.micro.paused && (now - this._state.frame.start) > this._frame.open) {
|
||||
this._state.micro.primed = false;
|
||||
this._state.micro.time = 0;
|
||||
setTimeout(() => {
|
||||
this._stop();
|
||||
}, this._microDelay);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Callback for watching relese switch state changes.
|
||||
* Using GPIO 05 on Raspberry Pi Zero W.
|
||||
*
|
||||
* 1) If closed, start timer.
|
||||
* 2) If opened, check timer AND
|
||||
* 3) If `press` (`now - this._state.release.time`) greater than minimum and less than `this._release.seq`, start frame
|
||||
* 4) If `press` greater than `this._release.seq`, start sequence
|
||||
*
|
||||
* Button + 10K ohm resistor
|
||||
* * 1 === open
|
||||
* * 0 === closed
|
||||
*
|
||||
* @param {object} err Error object present if problem reading pin
|
||||
* @param {integer} val Current value of the pin
|
||||
*
|
||||
*/
|
||||
_watchRelease(err, val) {
|
||||
const now = +new Date();
|
||||
let press = 0;
|
||||
if (err) {
|
||||
return log.error(err)
|
||||
return log.error(err);
|
||||
}
|
||||
//log.info(`Release switch val: ${val}`)
|
||||
if (val === 0) {
|
||||
//closed
|
||||
if (intval._releaseClosedState(now)) {
|
||||
intval._state.release.time = now
|
||||
intval._state.release.active = true //maybe unncecessary
|
||||
if (this._releaseClosedState(now)) {
|
||||
this._state.release.time = now;
|
||||
this._state.release.active = true; //maybe unncecessary
|
||||
}
|
||||
} else if (val === 1) {
|
||||
}
|
||||
else if (val === 1) {
|
||||
//opened
|
||||
if (intval._state.release.active) {
|
||||
press = now - intval._state.release.time
|
||||
if (press > intval._release.min && press < intval._release.seq) {
|
||||
intval.frame()
|
||||
} else if (press >= intval._release.seq) {
|
||||
intval.sequence()
|
||||
if (this._state.release.active) {
|
||||
press = now - this._state.release.time;
|
||||
if (press > this._release.min && press < this._release.seq) {
|
||||
this.frame();
|
||||
}
|
||||
else if (press >= this._release.seq) {
|
||||
this.sequence();
|
||||
}
|
||||
//log.info(`Release closed for ${press}ms`)
|
||||
intval._state.release.time = 0
|
||||
intval._state.release.active = false
|
||||
this._state.release.time = 0;
|
||||
this._state.release.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
intval._releaseClosedState = function (now) {
|
||||
if (!intval._state.release.active && intval._state.release.time === 0) {
|
||||
return true
|
||||
}
|
||||
if (intval._state.release.active && (now - intval._state.release.time) > (intval._release.seq * 10)) {
|
||||
return true
|
||||
/**
|
||||
*
|
||||
*/
|
||||
_releaseClosedState(now) {
|
||||
if (!this._state.release.active && this._state.release.time === 0) {
|
||||
return true;
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
intval.reset = function () {
|
||||
intval._setState()
|
||||
intval._storeState()
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default direction of the camera.
|
||||
* * forward = true
|
||||
* * backward = false
|
||||
*
|
||||
* @param {boolean} [dir=true] Direction of the camera
|
||||
*
|
||||
*/
|
||||
intval.setDir = function (val = true) {
|
||||
if (this._state.release.active && (now - this._state.release.time) > (this._release.seq * 10)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Reset the state and store it.
|
||||
*/
|
||||
reset() {
|
||||
this._setState();
|
||||
this._storeState();
|
||||
}
|
||||
/**
|
||||
* Set the default direction of the camera.
|
||||
* * forward = true
|
||||
* * backward = false
|
||||
*
|
||||
* @param {boolean} [dir=true] Direction of the camera
|
||||
*/
|
||||
setDir(val = true) {
|
||||
if (typeof val !== 'boolean') {
|
||||
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._storeState()
|
||||
log.info('setDir', { direction : val ? 'forward' : 'backward' })
|
||||
}
|
||||
|
||||
intval.setExposure = function (val = 0) {
|
||||
intval._state.frame.exposure = val
|
||||
intval._storeState()
|
||||
log.info('setExposure', { exposure : val })
|
||||
}
|
||||
|
||||
intval.setDelay = function (val = 0) {
|
||||
intval._state.frame.delay = val
|
||||
intval._storeState()
|
||||
log.info('setDelay', { delay : val })
|
||||
}
|
||||
intval.setCounter = function (val = 0) {
|
||||
intval._state.counter = val
|
||||
intval._storeState()
|
||||
log.info('setCounter', { counter : val })
|
||||
}
|
||||
/**
|
||||
* Begin a single frame with set variables or defaults
|
||||
*
|
||||
* @param {?boolean} [dir="null"] (optional) Direction of the frame
|
||||
* @param {?integer} [exposure="null"] (optional) Exposure time, 0 = minimum
|
||||
*
|
||||
*/
|
||||
intval.frame = function (dir = null, exposure = null, cb = () => {}) {
|
||||
if (dir === true || (dir === null && intval._state.frame.dir === true) ) {
|
||||
dir = true
|
||||
} else {
|
||||
dir = false
|
||||
this._state.frame.dir = val;
|
||||
this._storeState();
|
||||
log.info('setDir', { direction: val ? 'forward' : 'backward' });
|
||||
}
|
||||
|
||||
if (exposure === null && intval._state.frame.exposure !== 0) {
|
||||
exposure = intval._state.frame.exposure
|
||||
} else if (exposure === null) {
|
||||
exposure = 0 //default speed
|
||||
/**
|
||||
* Set the exposure value for a single frame.
|
||||
*
|
||||
* @param {integer} val Length in milliseconds
|
||||
*/
|
||||
setExposure(val = 0) {
|
||||
this._state.frame.exposure = val;
|
||||
this._storeState();
|
||||
log.info('setExposure', { exposure: val });
|
||||
}
|
||||
|
||||
intval._state.frame.start = +new Date()
|
||||
intval._state.frame.active = true
|
||||
intval._pin.micro.watch(intval._watchMicro)
|
||||
|
||||
log.info('frame', {dir : dir ? 'forward' : 'backward', exposure : exposure})
|
||||
|
||||
/**
|
||||
* Set the delay time between each frame.
|
||||
*
|
||||
* @param {integer} val Length in milliseconds
|
||||
*/
|
||||
setDelay(val = 0) {
|
||||
this._state.frame.delay = val;
|
||||
this._storeState();
|
||||
log.info('setDelay', { delay: val });
|
||||
}
|
||||
/**
|
||||
* Set the counter to the value.
|
||||
*
|
||||
* @param {integer} val Frame number
|
||||
*/
|
||||
setCounter(val = 0) {
|
||||
this._state.counter = val;
|
||||
this._storeState();
|
||||
log.info('setCounter', { counter: val });
|
||||
}
|
||||
/**
|
||||
* Begin a single frame with set variables or defaults
|
||||
*
|
||||
* @param {?boolean} [dir="null"] (optional) Direction of the frame
|
||||
* @param {?integer} [exposure="null"] (optional) Exposure time, 0 = minimum
|
||||
*
|
||||
*/
|
||||
frame(dir = null, exposure = null, cb = () => { }) {
|
||||
if (dir === true || (dir === null && this._state.frame.dir === true)) {
|
||||
dir = true;
|
||||
}
|
||||
else {
|
||||
dir = false;
|
||||
}
|
||||
if (exposure === null && this._state.frame.exposure !== 0) {
|
||||
exposure = this._state.frame.exposure;
|
||||
}
|
||||
else if (exposure === null) {
|
||||
exposure = 0; //default speed
|
||||
}
|
||||
this._state.frame.start = +new Date();
|
||||
this._state.frame.active = true;
|
||||
this._pin.micro.watch(this._watchMicro);
|
||||
log.info('frame', { dir: dir ? 'forward' : 'backward', exposure: exposure });
|
||||
if (dir) {
|
||||
intval._startFwd()
|
||||
} else {
|
||||
intval._startBwd()
|
||||
this._startFwd();
|
||||
}
|
||||
else {
|
||||
this._startBwd();
|
||||
}
|
||||
if (exposure !== 0) {
|
||||
intval._state.frame.paused = true
|
||||
this._state.frame.paused = true;
|
||||
if (dir) {
|
||||
setTimeout(intval._pause, intval._frame.open)
|
||||
//log.info('frame', { pausing : time + intval._frame.open })
|
||||
setTimeout( () => {
|
||||
intval._state.frame.paused = false
|
||||
intval._startFwd()
|
||||
}, exposure + intval._frame.closed)
|
||||
} else {
|
||||
setTimeout(intval._pause, intval._frame.openBwd)
|
||||
setTimeout( () => {
|
||||
setTimeout(this._pause, this._frame.open);
|
||||
//log.info('frame', { pausing : time + this._frame.open })
|
||||
setTimeout(() => {
|
||||
this._state.frame.paused = false;
|
||||
this._startFwd();
|
||||
}, exposure + this._frame.closed);
|
||||
}
|
||||
else {
|
||||
setTimeout(this._pause, this._frame.openBwd);
|
||||
setTimeout(() => {
|
||||
//log.info('frame', 'restarting')
|
||||
intval._state.frame.paused = false
|
||||
intval._startBwd()
|
||||
}, exposure + intval._frame.closed)
|
||||
this._state.frame.paused = false;
|
||||
this._startBwd();
|
||||
}, exposure + this._frame.closed);
|
||||
}
|
||||
}
|
||||
if (dir) {
|
||||
intval._state.frame.cb = (len) => {
|
||||
intval._state.counter++
|
||||
intval._storeState()
|
||||
cb(len)
|
||||
this._state.frame.cb = (len) => {
|
||||
this._state.counter++;
|
||||
this._storeState();
|
||||
cb(len);
|
||||
};
|
||||
}
|
||||
} else {
|
||||
intval._state.frame.cb = (len) => {
|
||||
intval._state.counter--
|
||||
intval._storeState()
|
||||
cb(len)
|
||||
else {
|
||||
this._state.frame.cb = (len) => {
|
||||
this._state.counter--;
|
||||
this._storeState();
|
||||
cb(len);
|
||||
};
|
||||
}
|
||||
}
|
||||
intval._state.frame.current = {
|
||||
this._state.frame.current = {
|
||||
dir: dir,
|
||||
exposure: exposure
|
||||
};
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
status() {
|
||||
return this._state;
|
||||
}
|
||||
}
|
||||
|
||||
intval.status = function () {
|
||||
return intval._state
|
||||
}
|
||||
|
||||
module.exports = intval
|
||||
module.exports = new Intval();
|
||||
//# sourceMappingURL=index.js.map
|
File diff suppressed because one or more lines are too long
|
@ -1,43 +1,50 @@
|
|||
'use strict';
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const uuid = require('uuid').v4;
|
||||
const v4_1 = __importDefault(require("uuid/v4"));
|
||||
const log = require('../log')('seq');
|
||||
require("../delay");
|
||||
/** Object sequence features */
|
||||
class Sequence {
|
||||
constructor() {
|
||||
this._state = {
|
||||
arr: [],
|
||||
active: false,
|
||||
paused: false,
|
||||
frame: false,
|
||||
delay: false,
|
||||
count: 0,
|
||||
stop: null
|
||||
arr: []
|
||||
};
|
||||
this.active = false;
|
||||
this.paused = false;
|
||||
this.frame = false;
|
||||
this.delay = false;
|
||||
this.count = 0;
|
||||
this._stop = null;
|
||||
this._loop = {
|
||||
arr: [],
|
||||
count: 0,
|
||||
max: 0
|
||||
};
|
||||
this.stop = function () {
|
||||
this._state.active = false;
|
||||
this._state.count = 0;
|
||||
this.active = false;
|
||||
this.count = 0;
|
||||
this._state.arr = [];
|
||||
this._loop.count = 0;
|
||||
this._loop.max = 0;
|
||||
this._loop.arr = [];
|
||||
if (this._state.stop)
|
||||
this._state.stop();
|
||||
this._state.stop = null;
|
||||
if (this._stop)
|
||||
this._stop();
|
||||
this._stop = null;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Start running a "sequence" of frames. Shoots a continuous sequence
|
||||
* of single frames with a delay in between each one.
|
||||
**/
|
||||
start(options, cb) {
|
||||
if (this._state.active) {
|
||||
return false;
|
||||
}
|
||||
this._state.active = true;
|
||||
this._state.count = 0;
|
||||
this.active = true;
|
||||
this.count = 0;
|
||||
if (options.arr) {
|
||||
this._state.arr = options.arr;
|
||||
}
|
||||
|
@ -51,44 +58,44 @@ class Sequence {
|
|||
else {
|
||||
this._loop.max = 0;
|
||||
}
|
||||
this._state.stop = cb;
|
||||
this._stop = cb;
|
||||
this.step();
|
||||
this._state.id = uuid();
|
||||
return this._state.id;
|
||||
this.id = v4_1.default();
|
||||
return this.id;
|
||||
}
|
||||
setStop() {
|
||||
this._state.active = false;
|
||||
this.active = false;
|
||||
}
|
||||
pause() {
|
||||
this._state.paused = true;
|
||||
this.paused = true;
|
||||
}
|
||||
resume() {
|
||||
this._state.paused = false;
|
||||
this.paused = false;
|
||||
this.step();
|
||||
}
|
||||
step() {
|
||||
if (this._state.active && !this._state.paused) {
|
||||
if (this.active && !this.paused) {
|
||||
if (this._state.arr.length > 0) {
|
||||
if (this._state.count > this._state.arr.length - 1) {
|
||||
if (this.count > this._state.arr.length - 1) {
|
||||
return this.stop();
|
||||
}
|
||||
log.info('step', { count: this._state.count, id: this._state.id });
|
||||
return this._state.arr[this._state.count](() => {
|
||||
this._state.count++;
|
||||
log.info('step', { count: this.count, id: this._state.id });
|
||||
return this._state.arr[this.count](() => {
|
||||
this.count++;
|
||||
this.step();
|
||||
});
|
||||
}
|
||||
else if (this._loop.arr.length > 0) {
|
||||
if (this._state.count > this._loop.arr.length - 1) {
|
||||
this._state.count = 0;
|
||||
if (this.count > this._loop.arr.length - 1) {
|
||||
this.count = 0;
|
||||
this._loop.count++;
|
||||
}
|
||||
if (this._loop.max > 0 && this._loop.count > this._loop.max) {
|
||||
return this.stop();
|
||||
}
|
||||
log.info('step', { count: this._state.count, id: this._state.id });
|
||||
return this._loop.arr[this._state.count](() => {
|
||||
this._state.count++;
|
||||
log.info('step', { count: this.count, id: this.id });
|
||||
return this._loop.arr[this.count](() => {
|
||||
this.count++;
|
||||
this.step();
|
||||
});
|
||||
}
|
||||
|
@ -96,11 +103,11 @@ class Sequence {
|
|||
return this.stop();
|
||||
}
|
||||
}
|
||||
else if (this._state.paused) {
|
||||
log.info('step', 'Sequence paused', { loop: this._loop.count, count: this._state.count });
|
||||
else if (this.paused) {
|
||||
log.info('step', 'Sequence paused', { loop: this._loop.count, count: this.count });
|
||||
}
|
||||
else if (!this._state.active) {
|
||||
log.info('step', 'Sequence stopped', { loop: this._loop.count, count: this._state.count });
|
||||
else if (!this.active) {
|
||||
log.info('step', 'Sequence stopped', { loop: this._loop.count, count: this.count });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sequence/index.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sequence/index.ts"],"names":[],"mappings":"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"}
|
File diff suppressed because it is too large
Load Diff
|
@ -27,6 +27,7 @@
|
|||
"dependencies": {
|
||||
"bleno": "^0.5.0",
|
||||
"cron": "^1.7.2",
|
||||
"fs-extra": "^8.1.0",
|
||||
"node-ipc": "^9.1.1",
|
||||
"node-persist": "^3.0.5",
|
||||
"onoff": "^5.0.0",
|
||||
|
@ -37,7 +38,10 @@
|
|||
"winston": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "^8.0.0",
|
||||
"@types/node": "^12.7.12",
|
||||
"@types/node-persist": "0.0.33",
|
||||
"@types/uuid": "^3.4.5",
|
||||
"jsdoc-to-markdown": "^5.0.2",
|
||||
"qunit": "^2.9.3",
|
||||
"typescript": "^3.6.4"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
sudo -u pi -i<< EOF
|
||||
cd /home/pi/intval3 && git pull
|
||||
cd /home/pi/intval3 && git reset --hard && git pull && npm i
|
||||
EOF
|
|
@ -0,0 +1,519 @@
|
|||
'use strict'
|
||||
|
||||
const db = require('../db');
|
||||
const log = require('../log')('intval');
|
||||
import * as storage from 'node-persist';
|
||||
import { exists, mkdir } from 'fs-extra';
|
||||
import '../delay';
|
||||
|
||||
let Gpio : any
|
||||
try {
|
||||
Gpio = require('onoff').Gpio
|
||||
} catch (e) {
|
||||
log.warn('Failed including Gpio, using sim')
|
||||
Gpio = require('../../lib/onoffsim').Gpio
|
||||
}
|
||||
|
||||
|
||||
const PINS = {
|
||||
fwd : {
|
||||
pin : 13,
|
||||
dir : 'out'
|
||||
},
|
||||
bwd : {
|
||||
pin : 19,
|
||||
dir : 'out'
|
||||
},
|
||||
micro : {
|
||||
pin : 5,
|
||||
dir : 'in',
|
||||
edge : 'both'
|
||||
},
|
||||
release : {
|
||||
pin : 6,
|
||||
dir : 'in',
|
||||
edge : 'both'
|
||||
}
|
||||
}
|
||||
|
||||
interface State {
|
||||
|
||||
}
|
||||
|
||||
interface Entry {
|
||||
start : number;
|
||||
stop : number;
|
||||
len : number;
|
||||
dir : number;
|
||||
exposure : number;
|
||||
counter : number;
|
||||
sequence : number;
|
||||
}
|
||||
|
||||
/** class representing the intval3 features */
|
||||
class Intval {
|
||||
private STATE_DIR : string = '~/state';
|
||||
|
||||
private _frame : any = {
|
||||
open : 250, //delay before pausing frame in open state
|
||||
openBwd : 400,
|
||||
closed : 100, //time that frame actually remains closed for
|
||||
expected : 530 //expected length of frame, in ms
|
||||
}
|
||||
private _release : any = {
|
||||
min : 20,
|
||||
seq : 1000
|
||||
}
|
||||
private _microDelay : number = 10; // delay after stop signal before stopping motors
|
||||
private _pin : any = {};
|
||||
private _state : any = {};
|
||||
|
||||
|
||||
constructor() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the storage object and bind functions to process events.
|
||||
*/
|
||||
|
||||
private async _init () {
|
||||
let dirExists : boolean;
|
||||
|
||||
try {
|
||||
dirExists = await exists(this.STATE_DIR);
|
||||
} catch (err) {
|
||||
log.error('init', `Error locating state directory ${this.STATE_DIR}`);
|
||||
}
|
||||
|
||||
if (!dirExists) {
|
||||
try {
|
||||
await mkdir(this.STATE_DIR);
|
||||
} catch (err) {
|
||||
log.error('init', `Error creating state directory ${this.STATE_DIR}`)
|
||||
}
|
||||
}
|
||||
|
||||
storage.init({
|
||||
dir: this.STATE_DIR,
|
||||
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(this._restoreState).catch((err) => {
|
||||
log.warn('init', err)
|
||||
this.reset();
|
||||
this._declarePins();
|
||||
})
|
||||
|
||||
process.on('SIGINT', this._undeclarePins);
|
||||
process.on('uncaughtException', this._undeclarePins);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the state from the storage object
|
||||
*/
|
||||
|
||||
private _restoreState () {
|
||||
storage.getItem('_state', 'test').then(this._setState).catch((err) => {
|
||||
this._setState();
|
||||
log.error('_restoreState', err);
|
||||
})
|
||||
this._declarePins();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creating the state object.
|
||||
*/
|
||||
|
||||
private _setState (data : any = undefined) {
|
||||
if (typeof data !== 'undefined') {
|
||||
this._state = data;
|
||||
this._state.frame.cb = () => {};
|
||||
log.info('_setState', 'Restored intval state from disk');
|
||||
return true;
|
||||
}
|
||||
log.info('_setState', 'Setting state from defaults');
|
||||
this._state = {
|
||||
frame : {
|
||||
dir : true, //forward
|
||||
start : 0, //time frame started, timestamp
|
||||
active : false, //should frame be running
|
||||
paused : false,
|
||||
exposure : 0, //length of frame exposure, in ms
|
||||
delay : 0, //delay before start of frame, in ms
|
||||
current : {}, //current settings
|
||||
cb : () => {}
|
||||
},
|
||||
release : {
|
||||
time: 0,
|
||||
active : false //is pressed
|
||||
},
|
||||
micro : {
|
||||
time : 0,
|
||||
primed : false //is ready to stop frame
|
||||
},
|
||||
counter : 0,
|
||||
sequence : false
|
||||
}
|
||||
this._storeState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the state object.
|
||||
*/
|
||||
|
||||
private _storeState () {
|
||||
storage.setItem('_state', this._state)
|
||||
.then(() => {})
|
||||
.catch((err) => {
|
||||
log.error('_storeState', err);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* (internal function) Declares all Gpio pins that will be used.
|
||||
*/
|
||||
|
||||
private _declarePins () {
|
||||
let pin;
|
||||
for (let p in PINS) {
|
||||
pin = PINS[p];
|
||||
if (pin.edge) this._pin[p] = new Gpio(pin.pin, pin.dir, pin.edge);
|
||||
if (!pin.edge) this._pin[p] = new Gpio(pin.pin, pin.dir);
|
||||
log.info('_declarePins', { pin : pin.pin, dir : pin.dir, edge : pin.edge });
|
||||
}
|
||||
this._pin.release.watch(this._watchRelease);
|
||||
}
|
||||
|
||||
/**
|
||||
* (internal function) Undeclares all Gpio in event of uncaught error
|
||||
* that interupts the node process.
|
||||
*/
|
||||
|
||||
private _undeclarePins (e : Error) {
|
||||
log.error('_undeclarePins', e);
|
||||
if (!this._pin) {
|
||||
log.warn('_undeclarePins', { reason : 'No pins'});
|
||||
return process.exit();
|
||||
}
|
||||
log.warn('_undeclarePins', { pin : PINS.fwd.pin, val : 0, reason : 'exiting'});
|
||||
this._pin.fwd.writeSync(0);
|
||||
log.warn('_undeclarePins', { pin : PINS.bwd.pin, val : 0, reason : 'exiting'});
|
||||
this._pin.bwd.writeSync(0);
|
||||
this._pin.fwd.unexport();
|
||||
this._pin.bwd.unexport();
|
||||
this._pin.micro.unexport();
|
||||
this._pin.release.unexport();
|
||||
process.exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start motor in forward direction by setting correct pins in h-bridge
|
||||
*/
|
||||
|
||||
private _startFwd () {
|
||||
this._pin.fwd.writeSync(1);
|
||||
this._pin.bwd.writeSync(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start motor in backward direction by setting correct pins in h-bridge
|
||||
*/
|
||||
|
||||
private _startBwd () {
|
||||
this._pin.fwd.writeSync(0);
|
||||
this._pin.bwd.writeSync(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn off all directions
|
||||
*/
|
||||
|
||||
private _pause () {
|
||||
this._pin.fwd.writeSync(0);
|
||||
this._pin.bwd.writeSync(0);
|
||||
//log.info('_pause', 'frame paused')
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop motor by setting both motor pins to 0 (LOW)
|
||||
*/
|
||||
|
||||
private _stop () {
|
||||
const entry : any = {};
|
||||
const now : number = +new Date();
|
||||
const len : number = now - this._state.frame.start;
|
||||
|
||||
this._pin.fwd.writeSync(0);
|
||||
this._pin.bwd.writeSync(0);
|
||||
|
||||
log.info(`_stop`, { frame : len });
|
||||
|
||||
this._pin.micro.unwatch();
|
||||
this._state.frame.active = false;
|
||||
|
||||
if (this._state.frame.cb) this._state.frame.cb(len);
|
||||
|
||||
entry.start = this._state.frame.start;
|
||||
entry.stop = now;
|
||||
entry.len = len;
|
||||
entry.dir = this._state.frame.current.dir ? 1 : 0;
|
||||
entry.exposure = this._state.frame.current.exposure;
|
||||
entry.counter = this._state.counter;
|
||||
entry.sequence = this._state.sequence ? 1 : 0;
|
||||
|
||||
db.insert(entry);
|
||||
|
||||
this._state.frame.current = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for watching relese switch state changes.
|
||||
* Using GPIO 06 on Raspberry Pi Zero W.
|
||||
*
|
||||
* 1) If closed AND frame active, start timer, set state primed to `true`.
|
||||
* 1) If opened AND frame active, stop frame
|
||||
*
|
||||
* Microswitch + 10K ohm resistor
|
||||
* * 1 === open
|
||||
* * 0 === closed
|
||||
*
|
||||
*
|
||||
* @param {object} err Error object present if problem reading pin
|
||||
* @param {integer} val Current value of the pin
|
||||
*
|
||||
*/
|
||||
|
||||
private _watchMicro (err : Error, val : number) {
|
||||
const now : number = +new Date();
|
||||
if (err) {
|
||||
log.error('_watchMicro', err);
|
||||
}
|
||||
//log.info(`Microswitch val: ${val}`)
|
||||
//determine when to stop
|
||||
if (val === 0 && this._state.frame.active) {
|
||||
if (!this._state.micro.primed) {
|
||||
this._state.micro.primed = true;
|
||||
this._state.micro.time = now;
|
||||
log.info('Microswitch primed to stop motor');
|
||||
}
|
||||
} else if (val === 1 && this._state.frame.active) {
|
||||
if (this._state.micro.primed && !this._state.micro.paused && (now - this._state.frame.start) > this._frame.open) {
|
||||
this._state.micro.primed = false;
|
||||
this._state.micro.time = 0;
|
||||
setTimeout( () => {
|
||||
this._stop();
|
||||
}, this._microDelay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for watching relese switch state changes.
|
||||
* Using GPIO 05 on Raspberry Pi Zero W.
|
||||
*
|
||||
* 1) If closed, start timer.
|
||||
* 2) If opened, check timer AND
|
||||
* 3) If `press` (`now - this._state.release.time`) greater than minimum and less than `this._release.seq`, start frame
|
||||
* 4) If `press` greater than `this._release.seq`, start sequence
|
||||
*
|
||||
* Button + 10K ohm resistor
|
||||
* * 1 === open
|
||||
* * 0 === closed
|
||||
*
|
||||
* @param {object} err Error object present if problem reading pin
|
||||
* @param {integer} val Current value of the pin
|
||||
*
|
||||
*/
|
||||
|
||||
private _watchRelease (err : Error, val : number) {
|
||||
const now : number = +new Date();
|
||||
let press : number = 0;
|
||||
if (err) {
|
||||
return log.error(err);
|
||||
}
|
||||
//log.info(`Release switch val: ${val}`)
|
||||
if (val === 0) {
|
||||
//closed
|
||||
if (this._releaseClosedState(now)) {
|
||||
this._state.release.time = now;
|
||||
this._state.release.active = true; //maybe unncecessary
|
||||
}
|
||||
} else if (val === 1) {
|
||||
//opened
|
||||
if (this._state.release.active) {
|
||||
press = now - this._state.release.time;
|
||||
if (press > this._release.min && press < this._release.seq) {
|
||||
this.frame();
|
||||
} else if (press >= this._release.seq) {
|
||||
this.sequence();
|
||||
}
|
||||
//log.info(`Release closed for ${press}ms`)
|
||||
this._state.release.time = 0;
|
||||
this._state.release.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
private _releaseClosedState (now : number) {
|
||||
if (!this._state.release.active && this._state.release.time === 0) {
|
||||
return true;
|
||||
}
|
||||
if (this._state.release.active && (now - this._state.release.time) > (this._release.seq * 10)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the state and store it.
|
||||
*/
|
||||
|
||||
public reset () {
|
||||
this._setState();
|
||||
this._storeState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default direction of the camera.
|
||||
* * forward = true
|
||||
* * backward = false
|
||||
*
|
||||
* @param {boolean} [dir=true] Direction of the camera
|
||||
*/
|
||||
|
||||
public setDir (val : boolean = true) {
|
||||
if (typeof val !== 'boolean') {
|
||||
return log.warn('Direction must be represented as either true or false');
|
||||
}
|
||||
this._state.frame.dir = val;
|
||||
this._storeState();
|
||||
log.info('setDir', { direction : val ? 'forward' : 'backward' });
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the exposure value for a single frame.
|
||||
*
|
||||
* @param {integer} val Length in milliseconds
|
||||
*/
|
||||
|
||||
public setExposure (val : number = 0) {
|
||||
this._state.frame.exposure = val;
|
||||
this._storeState();
|
||||
log.info('setExposure', { exposure : val });
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the delay time between each frame.
|
||||
*
|
||||
* @param {integer} val Length in milliseconds
|
||||
*/
|
||||
|
||||
public setDelay (val : number = 0) {
|
||||
this._state.frame.delay = val;
|
||||
this._storeState();
|
||||
log.info('setDelay', { delay : val });
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the counter to the value.
|
||||
*
|
||||
* @param {integer} val Frame number
|
||||
*/
|
||||
|
||||
public setCounter (val : number = 0) {
|
||||
this._state.counter = val;
|
||||
this._storeState();
|
||||
log.info('setCounter', { counter : val });
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin a single frame with set variables or defaults
|
||||
*
|
||||
* @param {?boolean} [dir="null"] (optional) Direction of the frame
|
||||
* @param {?integer} [exposure="null"] (optional) Exposure time, 0 = minimum
|
||||
*
|
||||
*/
|
||||
|
||||
public frame (dir : boolean = null, exposure : number = null, cb : Function = () => {}) {
|
||||
if (dir === true || (dir === null && this._state.frame.dir === true) ) {
|
||||
dir = true;
|
||||
} else {
|
||||
dir = false;
|
||||
}
|
||||
|
||||
if (exposure === null && this._state.frame.exposure !== 0) {
|
||||
exposure = this._state.frame.exposure;
|
||||
} else if (exposure === null) {
|
||||
exposure = 0; //default speed
|
||||
}
|
||||
|
||||
this._state.frame.current.exposure = exposure;
|
||||
this._state.frame.current.dir = dir;
|
||||
|
||||
this._state.frame.start = +new Date();
|
||||
this._state.frame.active = true;
|
||||
this._pin.micro.watch(this._watchMicro);
|
||||
|
||||
log.info('frame', {dir : dir ? 'forward' : 'backward', exposure : exposure});
|
||||
|
||||
if (dir) {
|
||||
this._startFwd();
|
||||
} else {
|
||||
this._startBwd();
|
||||
}
|
||||
if (exposure !== 0) {
|
||||
this._state.frame.paused = true;
|
||||
if (dir) {
|
||||
setTimeout(this._pause, this._frame.open);
|
||||
//log.info('frame', { pausing : time + this._frame.open })
|
||||
setTimeout( () => {
|
||||
this._state.frame.paused = false;
|
||||
this._startFwd();
|
||||
}, exposure + this._frame.closed);
|
||||
} else {
|
||||
setTimeout(this._pause, this._frame.openBwd);
|
||||
setTimeout( () => {
|
||||
//log.info('frame', 'restarting')
|
||||
this._state.frame.paused = false;
|
||||
this._startBwd();
|
||||
}, exposure + this._frame.closed);
|
||||
}
|
||||
}
|
||||
if (dir) {
|
||||
this._state.frame.cb = (len : number) => {
|
||||
this._state.counter++;
|
||||
this._storeState();
|
||||
cb(len);
|
||||
}
|
||||
} else {
|
||||
this._state.frame.cb = (len : number) => {
|
||||
this._state.counter--;
|
||||
this._storeState();
|
||||
cb(len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state of the
|
||||
*/
|
||||
|
||||
public status () {
|
||||
return this._state;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new Intval();
|
||||
|
||||
export default Intval;
|
|
@ -1,20 +1,30 @@
|
|||
'use strict'
|
||||
|
||||
const uuid = require('uuid').v4
|
||||
const log = require('../log')('seq')
|
||||
import '../delay'
|
||||
import uuid from 'uuid/v4';
|
||||
const log = require('../log')('seq');
|
||||
import '../delay';
|
||||
|
||||
const MAX_INTEGER = 2147483647;
|
||||
|
||||
interface Options {
|
||||
len? : number;
|
||||
}
|
||||
|
||||
/** Object sequence features */
|
||||
class Sequence {
|
||||
public _state : any = {
|
||||
arr : [],
|
||||
active : false,
|
||||
paused : false,
|
||||
frame: false,
|
||||
delay : false,
|
||||
count : 0,
|
||||
stop : null
|
||||
arr : []
|
||||
}
|
||||
private id : string;
|
||||
|
||||
private active : boolean = false;
|
||||
private paused : boolean = false;
|
||||
|
||||
private frame : boolean = false;
|
||||
private delay : boolean = false;
|
||||
private count : number = 0;
|
||||
|
||||
private _stop : Function = null;
|
||||
|
||||
public _loop : any = {
|
||||
arr : [],
|
||||
|
@ -22,17 +32,20 @@ class Sequence {
|
|||
max : 0
|
||||
}
|
||||
|
||||
constructor () {
|
||||
constructor (intval : Intval) {
|
||||
|
||||
}
|
||||
|
||||
public start (options : any, cb : Function) {
|
||||
/**
|
||||
* Start running a "sequence" of frames. Shoots a continuous sequence
|
||||
* of single frames with a delay in between each one.
|
||||
**/
|
||||
public startOld (options : any, cb : Function) {
|
||||
if (this._state.active) {
|
||||
return false
|
||||
}
|
||||
|
||||
this._state.active = true
|
||||
this._state.count = 0
|
||||
this.active = true
|
||||
this.count = 0
|
||||
|
||||
if (options.arr) {
|
||||
this._state.arr = options.arr
|
||||
|
@ -48,70 +61,74 @@ class Sequence {
|
|||
} else {
|
||||
this._loop.max = 0
|
||||
}
|
||||
this._state.stop = cb
|
||||
this._stop = cb
|
||||
this.step()
|
||||
this._state.id = uuid()
|
||||
return this._state.id
|
||||
this.id = uuid()
|
||||
return this.id
|
||||
}
|
||||
|
||||
public async start (options : Options) {
|
||||
|
||||
}
|
||||
|
||||
public setStop () {
|
||||
this._state.active = false
|
||||
this.active = false
|
||||
}
|
||||
|
||||
public stop = function () {
|
||||
this._state.active = false
|
||||
this._state.count = 0
|
||||
this.active = false
|
||||
this.count = 0
|
||||
this._state.arr = []
|
||||
|
||||
this._loop.count = 0
|
||||
this._loop.max = 0
|
||||
this._loop.arr = []
|
||||
|
||||
if (this._state.stop) this._state.stop()
|
||||
if (this._stop) this._stop()
|
||||
|
||||
this._state.stop = null
|
||||
this._stop = null
|
||||
}
|
||||
|
||||
public pause () {
|
||||
this._state.paused = true
|
||||
this.paused = true
|
||||
}
|
||||
|
||||
public resume () {
|
||||
this._state.paused = false
|
||||
this.paused = false
|
||||
this.step()
|
||||
}
|
||||
|
||||
public step () {
|
||||
if (this._state.active && !this._state.paused) {
|
||||
if (this.active && !this.paused) {
|
||||
if (this._state.arr.length > 0) {
|
||||
if (this._state.count > this._state.arr.length - 1) {
|
||||
if (this.count > this._state.arr.length - 1) {
|
||||
return this.stop()
|
||||
}
|
||||
log.info('step', { count : this._state.count, id : this._state.id })
|
||||
return this._state.arr[this._state.count](() => {
|
||||
this._state.count++
|
||||
log.info('step', { count : this.count, id : this._state.id })
|
||||
return this._state.arr[this.count](() => {
|
||||
this.count++
|
||||
this.step()
|
||||
})
|
||||
} else if (this._loop.arr.length > 0) {
|
||||
if (this._state.count > this._loop.arr.length - 1) {
|
||||
this._state.count = 0
|
||||
if (this.count > this._loop.arr.length - 1) {
|
||||
this.count = 0
|
||||
this._loop.count++
|
||||
}
|
||||
if (this._loop.max > 0 && this._loop.count > this._loop.max) {
|
||||
return this.stop()
|
||||
}
|
||||
log.info('step', { count : this._state.count, id : this._state.id })
|
||||
return this._loop.arr[this._state.count](() => {
|
||||
this._state.count++
|
||||
log.info('step', { count : this.count, id : this.id })
|
||||
return this._loop.arr[this.count](() => {
|
||||
this.count++
|
||||
this.step()
|
||||
})
|
||||
} else{
|
||||
return this.stop()
|
||||
}
|
||||
} else if (this._state.paused) {
|
||||
log.info('step', 'Sequence paused', { loop : this._loop.count, count : this._state.count })
|
||||
} else if (!this._state.active) {
|
||||
log.info('step', 'Sequence stopped', { loop : this._loop.count, count : this._state.count })
|
||||
} else if (this.paused) {
|
||||
log.info('step', 'Sequence paused', { loop : this._loop.count, count : this.count })
|
||||
} else if (!this.active) {
|
||||
log.info('step', 'Sequence stopped', { loop : this._loop.count, count : this.count })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
"esModuleInterop": true,
|
||||
"target": "ES2017",
|
||||
"noImplicitAny": true,
|
||||
"allowSyntheticDefaultImports" : true,
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"removeComments" : false,
|
||||
|
|
Loading…
Reference in New Issue