mirror of
https://github.com/node-red/node-red-nodes.git
synced 2025-12-26 23:16:47 +01:00
bump gpiod nodes to fix initial timing
and include base libs
This commit is contained in:
12
hardware/pigpiod/js-pigpio/LICENCE.txt
Normal file
12
hardware/pigpiod/js-pigpio/LICENCE.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
Initial code Copyright (c) 2014, Tobbe Lundberg <tobbe@tlundberg.com>
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
Further developments
|
||||||
|
|
||||||
|
Copyright 2016 js-pigpiod - Mike Trebilcock ( and @dduransseau )
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
415
hardware/pigpiod/js-pigpio/_callback.js
Normal file
415
hardware/pigpiod/js-pigpio/_callback.js
Normal file
@@ -0,0 +1,415 @@
|
|||||||
|
/* eslint-env node */
|
||||||
|
const net = require('net');
|
||||||
|
const _pi_gpio_command = require('./utils.js')._pi_gpio_command;
|
||||||
|
const _socklock = require('./utils.js')._socklock;
|
||||||
|
const def = require('./definitions.js');
|
||||||
|
const reverse_string = require('./utils.js').reverse_string;
|
||||||
|
const reverse_string_and_clean = require('./utils.js').reverse_string_and_clean;
|
||||||
|
|
||||||
|
|
||||||
|
const TIMEOUT = 2;
|
||||||
|
|
||||||
|
//notification flags
|
||||||
|
const NTFY_FLAGS_EVENT = (1 << 7);
|
||||||
|
//const NTFY_FLAGS_ALIVE = (1 << 6);
|
||||||
|
const NTFY_FLAGS_WDOG = (1 << 5);
|
||||||
|
const NTFY_FLAGS_GPIO = 31;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An ADT class to hold event callback information.
|
||||||
|
*
|
||||||
|
* @param {number} event - The event id.
|
||||||
|
* @param {callback} func - A user function taking one argument, the event id.
|
||||||
|
* @private
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
NOT USED YET
|
||||||
|
class _event_ADT {
|
||||||
|
constructor(event, func) {
|
||||||
|
"use strict";
|
||||||
|
this.event = event;
|
||||||
|
this.func = func;
|
||||||
|
this.bit = 1 << event;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An ADT class to hold callback information.
|
||||||
|
*
|
||||||
|
* @param {number} gpio - Broadcom GPIO number.
|
||||||
|
* @param {number} edge - Either EITHER_EDGE, RISING_EDGE or FALLING_EDGE.
|
||||||
|
* @param {callback} func - A user function taking three arguments (GPIO, level, tick).
|
||||||
|
* @private
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class _callback_ADT {
|
||||||
|
constructor (gpio, edge, func) {
|
||||||
|
"use strict";
|
||||||
|
this.gpio = gpio;
|
||||||
|
this.edge = edge;
|
||||||
|
this.func = func;
|
||||||
|
this.bit = 1 << gpio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class to provide GPIO level change callbacks.
|
||||||
|
*/
|
||||||
|
class _callback {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Set} notify - Set of callbacks current registered.
|
||||||
|
* @param {number} userGpio - Broadcom GPIO number.
|
||||||
|
* @param {number} edge - Either EITHER_EDGE, RISING_EDGE or FALLING_EDGE.
|
||||||
|
* @param {callback} cb - A user function taking three arguments (GPIO, level, tick).
|
||||||
|
*/
|
||||||
|
constructor(notify, userGpio, edge, cb) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
this._notify = notify;
|
||||||
|
this.count = 0;
|
||||||
|
this._reset = false;
|
||||||
|
if (cb === undefined) {
|
||||||
|
cb = this._tally;
|
||||||
|
}
|
||||||
|
this._callback = new _callback_ADT(userGpio, edge, cb);
|
||||||
|
this._notify.append(this._callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels a callback by removing it from the notification thread.
|
||||||
|
*/
|
||||||
|
cancel () {
|
||||||
|
"use strict";
|
||||||
|
this._notify.remove(this._callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the callback called count.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_tally () {
|
||||||
|
"use strict";
|
||||||
|
if (this._reset) {
|
||||||
|
this._reset = false;
|
||||||
|
this.count = 0;
|
||||||
|
}
|
||||||
|
this.count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a count of how many times the default tally
|
||||||
|
* callback has triggered.
|
||||||
|
* The count will be zero if the user has supplied their own
|
||||||
|
* callback function.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
tally() {
|
||||||
|
"use strict";
|
||||||
|
return this.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
reset_tally() {
|
||||||
|
"use strict";
|
||||||
|
this._reset = true;
|
||||||
|
this.count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports._callback = _callback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class to provide event callbacks.
|
||||||
|
*
|
||||||
|
* @param notify
|
||||||
|
* @param event
|
||||||
|
* @param cb
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
NOT USED YET
|
||||||
|
|
||||||
|
class _event {
|
||||||
|
constructor (notify, event, cb) {
|
||||||
|
"use strict";
|
||||||
|
this._notify = notify;
|
||||||
|
this.count = 0;
|
||||||
|
this._reset = false;
|
||||||
|
if (cb === undefined) {
|
||||||
|
cb = this._tally;
|
||||||
|
}
|
||||||
|
this.callback = new _event_ADT(event, cb);
|
||||||
|
this._notify.append_event(this.callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels a event callback by removing it from the
|
||||||
|
* notification thread.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
cancel (){
|
||||||
|
"use strict";
|
||||||
|
this._notify.remove_event(this.callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the event callback called count.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
_tally () {
|
||||||
|
"use strict";
|
||||||
|
if (this._reset) {
|
||||||
|
this._reset = false;
|
||||||
|
this.count = 0;
|
||||||
|
}
|
||||||
|
this.count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a count of how many times the default tally
|
||||||
|
* callback has triggered.
|
||||||
|
*
|
||||||
|
* The count will be zero if the user has supplied their own
|
||||||
|
* callback function.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
tally () {
|
||||||
|
"use strict";
|
||||||
|
return this.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
reset_tally () {
|
||||||
|
"use strict";
|
||||||
|
this._reset = true;
|
||||||
|
this.count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encapsulates waiting for GPIO edges.
|
||||||
|
*
|
||||||
|
* @param notify
|
||||||
|
* @param gpio
|
||||||
|
* @param edge
|
||||||
|
* @param timeout
|
||||||
|
* @private
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
NOT NEEDED YET
|
||||||
|
class _wait_for_edge {
|
||||||
|
constructor (notify, gpio, edge, timeout) {
|
||||||
|
"use strict";
|
||||||
|
this._notify = notify;
|
||||||
|
this.callback = _callback_ADT(gpio, edge, this.func);
|
||||||
|
this.trigger = false;
|
||||||
|
this._notify.append(this.callback);
|
||||||
|
const d = new Date();
|
||||||
|
this.start = d.getTime();
|
||||||
|
while (this.trigger === false && (d.getTime() - this.start) < timeout) {
|
||||||
|
|
||||||
|
}
|
||||||
|
this._notify.remove(this.callback);
|
||||||
|
}
|
||||||
|
func () {
|
||||||
|
"use strict";
|
||||||
|
this.trigger = true;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encapsulates waiting for an event.
|
||||||
|
*
|
||||||
|
* @param notify
|
||||||
|
* @param gpio
|
||||||
|
* @param edge
|
||||||
|
* @param timeout
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
NOT NEEDED YET
|
||||||
|
class _wait_for_event {
|
||||||
|
constructor (notify, event, timeout) {
|
||||||
|
"use strict";
|
||||||
|
this._notify = notify;
|
||||||
|
this.callback = new _event_ADT(event, this.func);
|
||||||
|
this.trigger = false;
|
||||||
|
this._notify.append(this.callback);
|
||||||
|
const d = new Date();
|
||||||
|
this.start = d.getTime();
|
||||||
|
while (this.trigger === false && (d.getTime() - this.start) < timeout) {
|
||||||
|
}
|
||||||
|
this._notify.remove(this.callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
func () {
|
||||||
|
"use strict";
|
||||||
|
this.trigger = true;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
class _callback_thread {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to manage the notifications from remote gpio.
|
||||||
|
*
|
||||||
|
* @param {Object} control - Socketlock for main socket.
|
||||||
|
* @param {string} host - Remote Server name.
|
||||||
|
* @param {number} port - Remote Server port.
|
||||||
|
* @param {callback} cb - User function to be run after callback initialised.
|
||||||
|
*/
|
||||||
|
constructor (control, host, port, cb) {
|
||||||
|
"use strict";
|
||||||
|
const that = this;
|
||||||
|
this.control = control;
|
||||||
|
this.callbacks = new Set();
|
||||||
|
this.events = new Set();
|
||||||
|
this.monitor = 0;
|
||||||
|
this.sl = new _socklock(host, port);
|
||||||
|
this.sl.s = net.connect({host, port});
|
||||||
|
this.sl.s.on('connect', () => {
|
||||||
|
_pi_gpio_command(that.sl, def.PI_CMD_NOIB, 0, 0, (err, data)=> {
|
||||||
|
data = reverse_string_and_clean(data.toString('hex'));
|
||||||
|
that.handle = data;
|
||||||
|
cb();
|
||||||
|
}, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.sl.s.on("data", (data) => {
|
||||||
|
const command = parseInt(data.toString('hex').substr(0,2),16);
|
||||||
|
|
||||||
|
if (that.sl._next[command] !== undefined) {
|
||||||
|
if(command === 99 && that.sl._next[command] !== undefined) {
|
||||||
|
that.sl._next[command](undefined, data);
|
||||||
|
that.sl._next[command] = undefined;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//const seq = reverse_string(data.toString('hex').substr(0,4));
|
||||||
|
const flags = reverse_string(data.toString('hex').substr(4,4));
|
||||||
|
const tick = reverse_string(data.toString('hex').substr(8,8));
|
||||||
|
const level = reverse_string(data.toString('hex').substr(16,8));
|
||||||
|
|
||||||
|
if (flags === 0) {
|
||||||
|
const changed = level ^ that.lastLevel;
|
||||||
|
that.lastLevel = level;
|
||||||
|
that.callbacks.forEach( (cb)=> {
|
||||||
|
if (cb.bit & changed) {
|
||||||
|
let newLevel = 0;
|
||||||
|
if (cb.bit & level) {
|
||||||
|
newLevel = 1;
|
||||||
|
}
|
||||||
|
if (cb.edge ^ newLevel) {
|
||||||
|
cb.func(cb.gpio, newLevel, tick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (flags & NTFY_FLAGS_WDOG) {
|
||||||
|
const gpio = flags & NTFY_FLAGS_GPIO;
|
||||||
|
that.callbacks.forEach((cb) => {
|
||||||
|
if (cb.gpio === gpio) {
|
||||||
|
cb.func(gpio, TIMEOUT, tick);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (flags & NTFY_FLAGS_EVENT) {
|
||||||
|
const event = flags & NTFY_FLAGS_GPIO;
|
||||||
|
that.events.forEach((cb) => {
|
||||||
|
if (cb.event === event) {
|
||||||
|
cb.func(event, tick)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.sl.s.on('error', (e) => {
|
||||||
|
cb(e);
|
||||||
|
});
|
||||||
|
this.run();
|
||||||
|
}
|
||||||
|
stop () {
|
||||||
|
const cmd = Buffer.alloc(16); // Crée un tampon de 16 octets
|
||||||
|
cmd.writeUInt32LE(def.PI_CMD_NC, 0);
|
||||||
|
cmd.writeUInt32LE(this.handle, 4);
|
||||||
|
cmd.writeUInt32LE(0, 8);
|
||||||
|
cmd.writeUInt32LE(0, 12);
|
||||||
|
this.sl.s.write(cmd);
|
||||||
|
this.sl.s.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a callback to the notification thread.
|
||||||
|
*
|
||||||
|
* @param {callback} callb - Function to be run.
|
||||||
|
*/
|
||||||
|
append(callb) {
|
||||||
|
this.callbacks.add(callb);
|
||||||
|
this.monitor = this.monitor | callb.bit;
|
||||||
|
_pi_gpio_command(this.control, def.PI_CMD_NB, this.handle, this.monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a callback from the notification thread.
|
||||||
|
*
|
||||||
|
* @param {callback} callb - Function to be run.
|
||||||
|
*/
|
||||||
|
remove(callb) {
|
||||||
|
if (this.callbacks.has(callb)) {
|
||||||
|
this.callbacks.delete(callb);
|
||||||
|
let newMonitor = 0;
|
||||||
|
this.callbacks.forEach( (cb) => {
|
||||||
|
newMonitor |= cb.bit
|
||||||
|
});
|
||||||
|
if (newMonitor !== this.monitor) {
|
||||||
|
this.monitor = newMonitor;
|
||||||
|
_pi_gpio_command(this.control, def.PI_CMD_NB, this.handle, this.monitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an event callback to the notification thread.
|
||||||
|
*
|
||||||
|
* @param {callback} callb - Function to be run.
|
||||||
|
*/
|
||||||
|
append_event(callb) {
|
||||||
|
this.events.append(callb);
|
||||||
|
this.event_bits = this.event_bits | callb.bit;
|
||||||
|
_pi_gpio_command(this.control, def.PI_CMD_EVM, this.handle, this.event_bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an event callback from the notification thread.
|
||||||
|
*
|
||||||
|
* @param {callback} callb - Function to be run.
|
||||||
|
*/
|
||||||
|
remove_event(callb) {
|
||||||
|
if (this.events.has(callb)) {
|
||||||
|
this.events.remove(callb);
|
||||||
|
let new_event_bits = 0;
|
||||||
|
this.events.forEach( (c) => {
|
||||||
|
new_event_bits |= c.bit;
|
||||||
|
});
|
||||||
|
if (new_event_bits !== this.event_bits) {
|
||||||
|
this.event_bits = new_event_bits;
|
||||||
|
_pi_gpio_command(this.control, def.PI_CMD_EVM, this.handle, this.event_bits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run() {
|
||||||
|
const that = this;
|
||||||
|
_pi_gpio_command(this.control, def.PI_CMD_BR1, 0, 0, (err, data) => {
|
||||||
|
if(data !== undefined) {
|
||||||
|
that.lastLevel = data;
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports._callback_thread = _callback_thread;
|
||||||
299
hardware/pigpiod/js-pigpio/definitions.js
Normal file
299
hardware/pigpiod/js-pigpio/definitions.js
Normal file
@@ -0,0 +1,299 @@
|
|||||||
|
/**
|
||||||
|
* Translated from https://github.com/joan2937/pigpio/blob/master/pigpio.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = Object.freeze({
|
||||||
|
PI_CMD_MODES : 0,
|
||||||
|
PI_CMD_MODEG : 1,
|
||||||
|
PI_CMD_PUD : 2,
|
||||||
|
PI_CMD_READ : 3,
|
||||||
|
PI_CMD_WRITE : 4,
|
||||||
|
PI_CMD_PWM : 5,
|
||||||
|
PI_CMD_PRS : 6,
|
||||||
|
PI_CMD_PFS : 7,
|
||||||
|
PI_CMD_SERVO : 8,
|
||||||
|
PI_CMD_WDOG : 9,
|
||||||
|
PI_CMD_BR1 : 10,
|
||||||
|
PI_CMD_BR2 : 11,
|
||||||
|
PI_CMD_BC1 : 12,
|
||||||
|
PI_CMD_BC2 : 13,
|
||||||
|
PI_CMD_BS1 : 14,
|
||||||
|
PI_CMD_BS2 : 15,
|
||||||
|
PI_CMD_TICK : 16,
|
||||||
|
PI_CMD_HWVER: 17,
|
||||||
|
PI_CMD_NO : 18,
|
||||||
|
PI_CMD_NB : 19,
|
||||||
|
PI_CMD_NP : 20,
|
||||||
|
PI_CMD_NC : 21,
|
||||||
|
PI_CMD_PRG : 22,
|
||||||
|
PI_CMD_PFG : 23,
|
||||||
|
PI_CMD_PRRG : 24,
|
||||||
|
PI_CMD_HELP : 25,
|
||||||
|
PI_CMD_PIGPV: 26,
|
||||||
|
PI_CMD_WVCLR: 27,
|
||||||
|
PI_CMD_WVAG : 28,
|
||||||
|
PI_CMD_WVAS : 29,
|
||||||
|
PI_CMD_WVGO : 30,
|
||||||
|
PI_CMD_WVGOR: 31,
|
||||||
|
PI_CMD_WVBSY: 32,
|
||||||
|
PI_CMD_WVHLT: 33,
|
||||||
|
PI_CMD_WVSM : 34,
|
||||||
|
PI_CMD_WVSP : 35,
|
||||||
|
PI_CMD_WVSC : 36,
|
||||||
|
PI_CMD_TRIG : 37,
|
||||||
|
PI_CMD_PROC : 38,
|
||||||
|
PI_CMD_PROCD: 39,
|
||||||
|
PI_CMD_PROCR: 40,
|
||||||
|
PI_CMD_PROCS: 41,
|
||||||
|
PI_CMD_SLRO : 42,
|
||||||
|
PI_CMD_SLR : 43,
|
||||||
|
PI_CMD_SLRC : 44,
|
||||||
|
PI_CMD_PROCP: 45,
|
||||||
|
PI_CMD_MICS : 46,
|
||||||
|
PI_CMD_MILS : 47,
|
||||||
|
PI_CMD_PARSE: 48,
|
||||||
|
PI_CMD_WVCRE: 49,
|
||||||
|
PI_CMD_WVDEL: 50,
|
||||||
|
PI_CMD_WVTX : 51,
|
||||||
|
PI_CMD_WVTXR: 52,
|
||||||
|
PI_CMD_WVNEW: 53,
|
||||||
|
|
||||||
|
PI_CMD_I2CO : 54,
|
||||||
|
PI_CMD_I2CC : 55,
|
||||||
|
PI_CMD_I2CRD: 56,
|
||||||
|
PI_CMD_I2CWD: 57,
|
||||||
|
PI_CMD_I2CWQ: 58,
|
||||||
|
PI_CMD_I2CRS: 59,
|
||||||
|
PI_CMD_I2CWS: 60,
|
||||||
|
PI_CMD_I2CRB: 61,
|
||||||
|
PI_CMD_I2CWB: 62,
|
||||||
|
PI_CMD_I2CRW: 63,
|
||||||
|
PI_CMD_I2CWW: 64,
|
||||||
|
PI_CMD_I2CRK: 65,
|
||||||
|
PI_CMD_I2CWK: 66,
|
||||||
|
PI_CMD_I2CRI: 67,
|
||||||
|
PI_CMD_I2CWI: 68,
|
||||||
|
PI_CMD_I2CPC: 69,
|
||||||
|
PI_CMD_I2CPK: 70,
|
||||||
|
|
||||||
|
PI_CMD_SPIO : 71,
|
||||||
|
PI_CMD_SPIC : 72,
|
||||||
|
PI_CMD_SPIR : 73,
|
||||||
|
PI_CMD_SPIW : 74,
|
||||||
|
PI_CMD_SPIX : 75,
|
||||||
|
|
||||||
|
PI_CMD_SERO : 76,
|
||||||
|
PI_CMD_SERC : 77,
|
||||||
|
PI_CMD_SERRB: 78,
|
||||||
|
PI_CMD_SERWB: 79,
|
||||||
|
PI_CMD_SERR : 80,
|
||||||
|
PI_CMD_SERW : 81,
|
||||||
|
PI_CMD_SERDA: 82,
|
||||||
|
|
||||||
|
PI_CMD_GDC : 83,
|
||||||
|
PI_CMD_GPW : 84,
|
||||||
|
|
||||||
|
PI_CMD_HC : 85,
|
||||||
|
PI_CMD_HP : 86,
|
||||||
|
|
||||||
|
PI_CMD_CF1 : 87,
|
||||||
|
PI_CMD_CF2 : 88,
|
||||||
|
|
||||||
|
PI_CMD_BI2CC: 89,
|
||||||
|
PI_CMD_BI2CO: 90,
|
||||||
|
PI_CMD_BI2CZ: 91,
|
||||||
|
|
||||||
|
PI_CMD_I2CZ : 92,
|
||||||
|
|
||||||
|
PI_CMD_WVCHA: 93,
|
||||||
|
|
||||||
|
PI_CMD_SLRI : 94,
|
||||||
|
|
||||||
|
PI_CMD_CGI : 95,
|
||||||
|
PI_CMD_CSI : 96,
|
||||||
|
|
||||||
|
PI_CMD_FG : 97,
|
||||||
|
PI_CMD_FN : 98,
|
||||||
|
|
||||||
|
PI_CMD_NOIB : 99,
|
||||||
|
|
||||||
|
PI_CMD_WVTXM: 100,
|
||||||
|
PI_CMD_WVTAT: 101,
|
||||||
|
|
||||||
|
PI_CMD_PADS : 102,
|
||||||
|
PI_CMD_PADG : 103,
|
||||||
|
|
||||||
|
PI_CMD_FO : 104,
|
||||||
|
PI_CMD_FC : 105,
|
||||||
|
PI_CMD_FR : 106,
|
||||||
|
PI_CMD_FW : 107,
|
||||||
|
PI_CMD_FS : 108,
|
||||||
|
PI_CMD_FL : 109,
|
||||||
|
|
||||||
|
PI_CMD_SHELL: 110,
|
||||||
|
|
||||||
|
PI_CMD_BSPIC: 111,
|
||||||
|
|
||||||
|
|
||||||
|
PI_CMD_BSPIO : 112,
|
||||||
|
PI_CMD_BSPIX : 113,
|
||||||
|
|
||||||
|
PI_CMD_BSCX : 114,
|
||||||
|
|
||||||
|
PI_CMD_EVM : 115,
|
||||||
|
PI_CMD_EVT : 116,
|
||||||
|
|
||||||
|
/*DEF_S Error Codes*/
|
||||||
|
PI_INIT_FAILED : -1, // gpioInitialise failed
|
||||||
|
PI_BAD_USER_GPIO : -2, // GPIO not 0-31
|
||||||
|
PI_BAD_GPIO : -3, // GPIO not 0-53
|
||||||
|
PI_BAD_MODE : -4, // mode not 0-7
|
||||||
|
PI_BAD_LEVEL : -5, // level not 0-1
|
||||||
|
PI_BAD_PUD : -6, // pud not 0-2
|
||||||
|
PI_BAD_PULSEWIDTH : -7, // pulsewidth not 0 or 500-2500
|
||||||
|
PI_BAD_DUTYCYCLE : -8, // dutycycle outside set range
|
||||||
|
PI_BAD_TIMER : -9, // timer not 0-9
|
||||||
|
PI_BAD_MS : -10, // ms not 10-60000
|
||||||
|
PI_BAD_TIMETYPE : -11, // timetype not 0-1
|
||||||
|
PI_BAD_SECONDS : -12, // seconds < 0
|
||||||
|
PI_BAD_MICROS : -13, // micros not 0-999999
|
||||||
|
PI_TIMER_FAILED : -14, // gpioSetTimerFunc failed
|
||||||
|
PI_BAD_WDOG_TIMEOUT : -15, // timeout not 0-60000
|
||||||
|
PI_NO_ALERT_FUNC : -16, // DEPRECATED
|
||||||
|
PI_BAD_CLK_PERIPH : -17, // clock peripheral not 0-1
|
||||||
|
PI_BAD_CLK_SOURCE : -18, // DEPRECATED
|
||||||
|
PI_BAD_CLK_MICROS : -19, // clock micros not 1, 2, 4, 5, 8, or 10
|
||||||
|
PI_BAD_BUF_MILLIS : -20, // buf millis not 100-10000
|
||||||
|
PI_BAD_DUTYRANGE : -21, // dutycycle range not 25-40000
|
||||||
|
PI_BAD_DUTY_RANGE : -21, // DEPRECATED (use PI_BAD_DUTYRANGE)
|
||||||
|
PI_BAD_SIGNUM : -22, // signum not 0-63
|
||||||
|
PI_BAD_PATHNAME : -23, // can't open pathname
|
||||||
|
PI_NO_HANDLE : -24, // no handle available
|
||||||
|
PI_BAD_HANDLE : -25, // unknown handle
|
||||||
|
PI_BAD_IF_FLAGS : -26, // ifFlags > 3
|
||||||
|
PI_BAD_CHANNEL : -27, // DMA channel not 0-14
|
||||||
|
PI_BAD_PRIM_CHANNEL : -27, // DMA primary channel not 0-14
|
||||||
|
PI_BAD_SOCKET_PORT : -28, // socket port not 1024-32000
|
||||||
|
PI_BAD_FIFO_COMMAND : -29, // unrecognized fifo command
|
||||||
|
PI_BAD_SECO_CHANNEL : -30, // DMA secondary channel not 0-6
|
||||||
|
PI_NOT_INITIALISED : -31, // function called before gpioInitialise
|
||||||
|
PI_INITIALISED : -32, // function called after gpioInitialise
|
||||||
|
PI_BAD_WAVE_MODE : -33, // waveform mode not 0-3
|
||||||
|
PI_BAD_CFG_INTERNAL : -34, // bad parameter in gpioCfgInternals call
|
||||||
|
PI_BAD_WAVE_BAUD : -35, // baud rate not 50-250K(RX)/50-1M(TX)
|
||||||
|
PI_TOO_MANY_PULSES : -36, // waveform has too many pulses
|
||||||
|
PI_TOO_MANY_CHARS : -37, // waveform has too many chars
|
||||||
|
PI_NOT_SERIAL_GPIO : -38, // no bit bang serial read on GPIO
|
||||||
|
PI_BAD_SERIAL_STRUC : -39, // bad (null) serial structure parameter
|
||||||
|
PI_BAD_SERIAL_BUF : -40, // bad (null) serial buf parameter
|
||||||
|
PI_NOT_PERMITTED : -41, // GPIO operation not permitted
|
||||||
|
PI_SOME_PERMITTED : -42, // one or more GPIO not permitted
|
||||||
|
PI_BAD_WVSC_COMMND : -43, // bad WVSC subcommand
|
||||||
|
PI_BAD_WVSM_COMMND : -44, // bad WVSM subcommand
|
||||||
|
PI_BAD_WVSP_COMMND : -45, // bad WVSP subcommand
|
||||||
|
PI_BAD_PULSELEN : -46, // trigger pulse length not 1-100
|
||||||
|
PI_BAD_SCRIPT : -47, // invalid script
|
||||||
|
PI_BAD_SCRIPT_ID : -48, // unknown script id
|
||||||
|
PI_BAD_SER_OFFSET : -49, // add serial data offset > 30 minutes
|
||||||
|
PI_GPIO_IN_USE : -50, // GPIO already in use
|
||||||
|
PI_BAD_SERIAL_COUNT : -51, // must read at least a byte at a time
|
||||||
|
PI_BAD_PARAM_NUM : -52, // script parameter id not 0-9
|
||||||
|
PI_DUP_TAG : -53, // script has duplicate tag
|
||||||
|
PI_TOO_MANY_TAGS : -54, // script has too many tags
|
||||||
|
PI_BAD_SCRIPT_CMD : -55, // illegal script command
|
||||||
|
PI_BAD_VAR_NUM : -56, // script variable id not 0-149
|
||||||
|
PI_NO_SCRIPT_ROOM : -57, // no more room for scripts
|
||||||
|
PI_NO_MEMORY : -58, // can't allocate temporary memory
|
||||||
|
PI_SOCK_READ_FAILED : -59, // socket read failed
|
||||||
|
PI_SOCK_WRIT_FAILED : -60, // socket write failed
|
||||||
|
PI_TOO_MANY_PARAM : -61, // too many script parameters (> 10)
|
||||||
|
PI_NOT_HALTED : -62, // DEPRECATED
|
||||||
|
PI_SCRIPT_NOT_READY : -62, // script initialising
|
||||||
|
PI_BAD_TAG : -63, // script has unresolved tag
|
||||||
|
PI_BAD_MICS_DELAY : -64, // bad MICS delay (too large)
|
||||||
|
PI_BAD_MILS_DELAY : -65, // bad MILS delay (too large)
|
||||||
|
PI_BAD_WAVE_ID : -66, // non existent wave id
|
||||||
|
PI_TOO_MANY_CBS : -67, // No more CBs for waveform
|
||||||
|
PI_TOO_MANY_OOL : -68, // No more OOL for waveform
|
||||||
|
PI_EMPTY_WAVEFORM : -69, // attempt to create an empty waveform
|
||||||
|
PI_NO_WAVEFORM_ID : -70, // no more waveforms
|
||||||
|
PI_I2C_OPEN_FAILED : -71, // can't open I2C device
|
||||||
|
PI_SER_OPEN_FAILED : -72, // can't open serial device
|
||||||
|
PI_SPI_OPEN_FAILED : -73, // can't open SPI device
|
||||||
|
PI_BAD_I2C_BUS : -74, // bad I2C bus
|
||||||
|
PI_BAD_I2C_ADDR : -75, // bad I2C address
|
||||||
|
PI_BAD_SPI_CHANNEL : -76, // bad SPI channel
|
||||||
|
PI_BAD_FLAGS : -77, // bad i2c/spi/ser open flags
|
||||||
|
PI_BAD_SPI_SPEED : -78, // bad SPI speed
|
||||||
|
PI_BAD_SER_DEVICE : -79, // bad serial device name
|
||||||
|
PI_BAD_SER_SPEED : -80, // bad serial baud rate
|
||||||
|
PI_BAD_PARAM : -81, // bad i2c/spi/ser parameter
|
||||||
|
PI_I2C_WRITE_FAILED : -82, // i2c write failed
|
||||||
|
PI_I2C_READ_FAILED : -83, // i2c read failed
|
||||||
|
PI_BAD_SPI_COUNT : -84, // bad SPI count
|
||||||
|
PI_SER_WRITE_FAILED : -85, // ser write failed
|
||||||
|
PI_SER_READ_FAILED : -86, // ser read failed
|
||||||
|
PI_SER_READ_NO_DATA : -87, // ser read no data available
|
||||||
|
PI_UNKNOWN_COMMAND : -88, // unknown command
|
||||||
|
PI_SPI_XFER_FAILED : -89, // spi xfer/read/write failed
|
||||||
|
PI_BAD_POINTER : -90, // bad (NULL) pointer
|
||||||
|
PI_NO_AUX_SPI : -91, // no auxiliary SPI on Pi A or B
|
||||||
|
PI_NOT_PWM_GPIO : -92, // GPIO is not in use for PWM
|
||||||
|
PI_NOT_SERVO_GPIO : -93, // GPIO is not in use for servo pulses
|
||||||
|
PI_NOT_HCLK_GPIO : -94, // GPIO has no hardware clock
|
||||||
|
PI_NOT_HPWM_GPIO : -95, // GPIO has no hardware PWM
|
||||||
|
PI_BAD_HPWM_FREQ : -96, // hardware PWM frequency not 1-125M
|
||||||
|
PI_BAD_HPWM_DUTY : -97, // hardware PWM dutycycle not 0-1M
|
||||||
|
PI_BAD_HCLK_FREQ : -98, // hardware clock frequency not 4689-250M
|
||||||
|
PI_BAD_HCLK_PASS : -99, // need password to use hardware clock 1
|
||||||
|
PI_HPWM_ILLEGAL : -100, // illegal, PWM in use for main clock
|
||||||
|
PI_BAD_DATABITS : -101, // serial data bits not 1-32
|
||||||
|
PI_BAD_STOPBITS : -102, // serial (half) stop bits not 2-8
|
||||||
|
PI_MSG_TOOBIG : -103, // socket/pipe message too big
|
||||||
|
PI_BAD_MALLOC_MODE : -104, // bad memory allocation mode
|
||||||
|
PI_TOO_MANY_SEGS : -105, // too many I2C transaction segments
|
||||||
|
PI_BAD_I2C_SEG : -106, // an I2C transaction segment failed
|
||||||
|
PI_BAD_SMBUS_CMD : -107, // SMBus command not supported by driver
|
||||||
|
PI_NOT_I2C_GPIO : -108, // no bit bang I2C in progress on GPIO
|
||||||
|
PI_BAD_I2C_WLEN : -109, // bad I2C write length
|
||||||
|
PI_BAD_I2C_RLEN : -110, // bad I2C read length
|
||||||
|
PI_BAD_I2C_CMD : -111, // bad I2C command
|
||||||
|
PI_BAD_I2C_BAUD : -112, // bad I2C baud rate, not 50-500k
|
||||||
|
PI_CHAIN_LOOP_CNT : -113, // bad chain loop count
|
||||||
|
PI_BAD_CHAIN_LOOP : -114, // empty chain loop
|
||||||
|
PI_CHAIN_COUNTER : -115, // too many chain counters
|
||||||
|
PI_BAD_CHAIN_CMD : -116, // bad chain command
|
||||||
|
PI_BAD_CHAIN_DELAY : -117, // bad chain delay micros
|
||||||
|
PI_CHAIN_NESTING : -118, // chain counters nested too deeply
|
||||||
|
PI_CHAIN_TOO_BIG : -119, // chain is too long
|
||||||
|
PI_DEPRECATED : -120, // deprecated function removed
|
||||||
|
PI_BAD_SER_INVERT : -121, // bit bang serial invert not 0 or 1
|
||||||
|
PI_BAD_EDGE : -122, // bad ISR edge value, not 0-2
|
||||||
|
PI_BAD_ISR_INIT : -123, // bad ISR initialisation
|
||||||
|
PI_BAD_FOREVER : -124, // loop forever must be last command
|
||||||
|
PI_BAD_FILTER : -125, // bad filter parameter
|
||||||
|
PI_BAD_PAD : -126, // bad pad number
|
||||||
|
PI_BAD_STRENGTH : -127, // bad pad drive strength
|
||||||
|
PI_FIL_OPEN_FAILED : -128, // file open failed
|
||||||
|
PI_BAD_FILE_MODE : -129, // bad file mode
|
||||||
|
PI_BAD_FILE_FLAG : -130, // bad file flag
|
||||||
|
PI_BAD_FILE_READ : -131, // bad file read
|
||||||
|
PI_BAD_FILE_WRITE : -132, // bad file write
|
||||||
|
PI_FILE_NOT_ROPEN : -133, // file not open for read
|
||||||
|
PI_FILE_NOT_WOPEN : -134, // file not open for write
|
||||||
|
PI_BAD_FILE_SEEK : -135, // bad file seek
|
||||||
|
PI_NO_FILE_MATCH : -136, // no files match pattern
|
||||||
|
PI_NO_FILE_ACCESS : -137, // no permission to access file
|
||||||
|
PI_FILE_IS_A_DIR : -138, // file is a directory
|
||||||
|
PI_BAD_SHELL_STATUS : -139, // bad shell return status
|
||||||
|
PI_BAD_SCRIPT_NAME : -140, // bad script name
|
||||||
|
PI_BAD_SPI_BAUD : -141, // bad SPI baud rate, not 50-500k
|
||||||
|
PI_NOT_SPI_GPIO : -142, // no bit bang SPI in progress on GPIO
|
||||||
|
PI_BAD_EVENT_ID : -143, // bad event id
|
||||||
|
|
||||||
|
PI_PIGIF_ERR_0 : -2000,
|
||||||
|
PI_PIGIF_ERR_99 : -2099,
|
||||||
|
|
||||||
|
PI_CUSTOM_ERR_0 : -3000,
|
||||||
|
PI_CUSTOM_ERR_999 : -3999
|
||||||
|
});
|
||||||
440
hardware/pigpiod/js-pigpio/index.js
Normal file
440
hardware/pigpiod/js-pigpio/index.js
Normal file
@@ -0,0 +1,440 @@
|
|||||||
|
/* eslint-env node */
|
||||||
|
|
||||||
|
const def = require('./definitions.js');
|
||||||
|
const net = require('net');
|
||||||
|
const assert = require('assert');
|
||||||
|
const reverse_string_and_clean = require('./utils.js').reverse_string_and_clean;
|
||||||
|
const _pi_gpio_command = require('./utils.js')._pi_gpio_command;
|
||||||
|
const _socklock = require('./utils.js')._socklock;
|
||||||
|
const _callback = require ('./_callback.js')._callback;
|
||||||
|
const _callback_thread = require ('./_callback.js')._callback_thread;
|
||||||
|
|
||||||
|
/** @class */
|
||||||
|
function pigpio() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pigpio.prototype = {
|
||||||
|
// GPIO levels
|
||||||
|
OFF: 0,
|
||||||
|
LOW: 0,
|
||||||
|
CLEAR: 0,
|
||||||
|
|
||||||
|
ON: 1,
|
||||||
|
HIGH: 1,
|
||||||
|
SET: 1,
|
||||||
|
|
||||||
|
TIMEOUT: 2,
|
||||||
|
|
||||||
|
// GPIO edges
|
||||||
|
|
||||||
|
RISING_EDGE: 0,
|
||||||
|
FALLING_EDGE: 1,
|
||||||
|
EITHER_EDGE: 2,
|
||||||
|
|
||||||
|
// GPIO modes
|
||||||
|
|
||||||
|
INPUT: 0,
|
||||||
|
OUTPUT: 1,
|
||||||
|
ALT0: 4,
|
||||||
|
ALT1: 5,
|
||||||
|
ALT2: 6,
|
||||||
|
ALT3: 7,
|
||||||
|
ALT4: 3,
|
||||||
|
ALT5: 2,
|
||||||
|
|
||||||
|
// GPIO Pull Up Down
|
||||||
|
|
||||||
|
PUD_OFF: 0,
|
||||||
|
PUD_DOWN: 1,
|
||||||
|
PUD_UP: 2
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Connects to the pigpio daemon.
|
||||||
|
*
|
||||||
|
* This method has to be called before it's possible to do anything with
|
||||||
|
* the GPIO pins.
|
||||||
|
*
|
||||||
|
* The callback will be called when the connection has been established or
|
||||||
|
* if an error occurs.
|
||||||
|
*
|
||||||
|
* @param {string} [host] - The host to connect to.
|
||||||
|
* @param {number} [port] - The port on the host to connect to.
|
||||||
|
* @param {Object} [cb] - Callback function.
|
||||||
|
*/
|
||||||
|
pigpio.prototype.pi = function(host, port, cb) {
|
||||||
|
"use strict";
|
||||||
|
const that = this;
|
||||||
|
if (host === undefined) {
|
||||||
|
host = process.env.PIGPIO_ADDR || 'localhost';
|
||||||
|
}
|
||||||
|
if (port === undefined) {
|
||||||
|
port = process.env.PIGPIO_PORT || '8888';
|
||||||
|
}
|
||||||
|
this._notify = null;
|
||||||
|
this.sl = new _socklock(host, port);
|
||||||
|
this.sl.s = net.connect({host, port});
|
||||||
|
|
||||||
|
this.sl.s.on('connect', () => {
|
||||||
|
// Disable the Nagle algoritm
|
||||||
|
that.sl.s.setNoDelay(true);
|
||||||
|
that._notify = new _callback_thread(that.sl,host, port, (e)=>{
|
||||||
|
cb(e);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.sl.s.on("data", (data) => {
|
||||||
|
const command = parseInt(data.toString('hex').substr(0,2),16);
|
||||||
|
if (that.sl._next[command] !== undefined) {
|
||||||
|
that.sl._next[command](undefined, reverse_string_and_clean(data.toString('hex')));
|
||||||
|
}
|
||||||
|
that.sl._releaseLock();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.sl.s.on('error', (e) => {
|
||||||
|
cb(e);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Half-closes the connection. We might still get some data from the server.
|
||||||
|
*/
|
||||||
|
pigpio.prototype.close = function() {
|
||||||
|
"use strict";
|
||||||
|
this.sl.s.end();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Starts (500-2500) or stops (0) servo pulses on the given gpio pin.
|
||||||
|
*
|
||||||
|
* The selected pulsewidth will continue to be transmitted until
|
||||||
|
* changed by a subsequent call to set_servo_pulsewidth.
|
||||||
|
*
|
||||||
|
* The pulsewidths supported by servos varies and should probably
|
||||||
|
* be determined by experiment. A value of 1500 should always be
|
||||||
|
* safe and represents the mid-point of rotation.
|
||||||
|
*
|
||||||
|
* You can DAMAGE a servo if you command it to move beyond its
|
||||||
|
* limits.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* gpio.setServoPulsewidth(17, 0) # off
|
||||||
|
* gpio.setServoPulsewidth(17, 1000) # safe anti-clockwise
|
||||||
|
* gpio.setServoPulsewidth(17, 1500) # centre
|
||||||
|
* gpio.setServoPulsewidth(17, 2000) # safe clockwise
|
||||||
|
*
|
||||||
|
* @param {number} userGpio - The number of the gpio to address. 0-31.
|
||||||
|
* @param {number} pulseWidth - The servo pulsewidth to generate
|
||||||
|
* 0 (off),
|
||||||
|
* 500 (most anti-clockwise) - 2500 (most clockwise).
|
||||||
|
*/
|
||||||
|
pigpio.prototype.setServoPulsewidth = function(userGpio, pulseWidth) {
|
||||||
|
"use strict";
|
||||||
|
assert_gpio_pin_in_range(userGpio,0,31);
|
||||||
|
assert(pulseWidth>=0 && pulseWidth <=2500, "pulsWidth must be in the range 0-2500");
|
||||||
|
_pi_gpio_command(this.sl,def.PI_CMD_SERVO, userGpio, pulseWidth);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the GPIO level.
|
||||||
|
*
|
||||||
|
* @param {number} userGpio - The number of the gpio to address. 0-31.
|
||||||
|
* @param {callback} cb - The function to be called with the result.
|
||||||
|
*/
|
||||||
|
pigpio.prototype.read = function (userGpio, cb) {
|
||||||
|
"use strict";
|
||||||
|
assert_gpio_pin_in_range(userGpio,0,31);
|
||||||
|
_pi_gpio_command(this.sl,def.PI_CMD_READ, userGpio, 0, cb, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the GPIO level.
|
||||||
|
*
|
||||||
|
* @param {number} userGpio - The number of the gpio to address. 0-31.
|
||||||
|
* @param {number} level - The output level 0 or 1.
|
||||||
|
* @param {callback} cb - The function to be called with the result.
|
||||||
|
*/
|
||||||
|
pigpio.prototype.write = function (userGpio, level, cb) {
|
||||||
|
"use strict";
|
||||||
|
assert_gpio_pin_in_range(userGpio,0,31);
|
||||||
|
assert(level===0 || level ===1, "level must be 0 or 1.");
|
||||||
|
_pi_gpio_command(this.sl,def.PI_CMD_WRITE, userGpio, level, cb, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts (non-zero dutycycle) or stops (0) PWM pulses on the gpio.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* pi.set_PWM_dutycycle(4, 0) # PWM off
|
||||||
|
* pi.set_PWM_dutycycle(4, 64) # PWM 1/4 on
|
||||||
|
* pi.set_PWM_dutycycle(4, 128) # PWM 1/2 on
|
||||||
|
* pi.set_PWM_dutycycle(4, 192) # PWM 3/4 on
|
||||||
|
* pi.set_PWM_dutycycle(4, 255) # PWM full on
|
||||||
|
*
|
||||||
|
* @param {number} userGpio - The number of the gpio to address (0-31).
|
||||||
|
* @param {number} dutycycle - The pwm dutycycle to use:
|
||||||
|
* 0 (off),
|
||||||
|
* 255 (full on).
|
||||||
|
*/
|
||||||
|
pigpio.prototype.set_PWM_dutycycle = function(userGpio, dutycycle) {
|
||||||
|
"use strict";
|
||||||
|
assert_gpio_pin_in_range(userGpio,0,31);
|
||||||
|
assert(dutycycle>=0 && dutycycle <=255, "dutycycle must be in the range 0-255");
|
||||||
|
_pi_gpio_command(this.sl,def.PI_CMD_PWM, userGpio, dutycycle, undefined, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the PWM dutycycle being used on the GPIO.
|
||||||
|
*
|
||||||
|
* For normal PWM the dutycycle will be out of the defined range
|
||||||
|
* for the GPIO (see [*get_PWM_range*]).
|
||||||
|
* If a hardware clock is active on the GPIO the reported
|
||||||
|
* dutycycle will be 500000 (500k) out of 1000000 (1M).
|
||||||
|
* If hardware PWM is active on the GPIO the reported dutycycle
|
||||||
|
* will be out of a 1000000 (1M).
|
||||||
|
*
|
||||||
|
* @param {number} userGpio - The number of the gpio to address (0-31).
|
||||||
|
* @param {callback} cb - Function that the value will be passed back to in form function(err, data).
|
||||||
|
*/
|
||||||
|
pigpio.prototype.get_PWM_dutycycle = function(userGpio, cb) {
|
||||||
|
"use strict";
|
||||||
|
assert_gpio_pin_in_range(userGpio,0,31);
|
||||||
|
_pi_gpio_command(this.sl,def.PI_CMD_GDC, userGpio, 0, cb, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the range of PWM values to be used on the GPIO.
|
||||||
|
*
|
||||||
|
* @param {number} userGpio - The number of the gpio to address (0-31).
|
||||||
|
* @param {number} range - A number in the range 25-40000.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* pi.set_PWM_range(9, 100) // now 25 1/4, 50 1/2, 75 3/4 on
|
||||||
|
* pi.set_PWM_range(9, 500) // now 125 1/4, 250 1/2, 375 3/4 on
|
||||||
|
* pi.set_PWM_range(9, 3000) // now 750 1/4, 1500 1/2, 2250 3/4 on
|
||||||
|
*/
|
||||||
|
pigpio.prototype.set_PWM_range = function (userGpio, range) {
|
||||||
|
"use strict";
|
||||||
|
assert_gpio_pin_in_range(userGpio,0,31);
|
||||||
|
assert(range>=25 && range <=40000, "range must be in the range 25-40000.");
|
||||||
|
_pi_gpio_command(this.sl,def.PI_CMD_PRS, userGpio, range, undefined, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the range of PWM values being used on the GPIO.
|
||||||
|
* If a hardware clock or hardware PWM is active on the GPIO the reported range will be 1000000 (1M).
|
||||||
|
*
|
||||||
|
* @param {number} userGpio - The number of the gpio to address (0-31).
|
||||||
|
* @param {callback} cb - Function that the value will be passed back to in form function(err, data).
|
||||||
|
*/
|
||||||
|
pigpio.prototype.get_PWM_range = function(userGpio, cb) {
|
||||||
|
"use strict";
|
||||||
|
assert_gpio_pin_in_range(userGpio,0,31);
|
||||||
|
_pi_gpio_command(this.sl,def.PI_CMD_PRG, userGpio, 0, cb, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the real (underlying) range of PWM values being used on the GPIO.
|
||||||
|
*
|
||||||
|
* If a hardware clock is active on the GPIO the reported real range will be 1000000 (1M).
|
||||||
|
* If hardware PWM is active on the GPIO the reported real range
|
||||||
|
* will be approximately 250M divided by the set PWM frequency.
|
||||||
|
*
|
||||||
|
* @param {number} userGpio - The number of the gpio to address (0-31).
|
||||||
|
* @param {callback} cb - Function that the value will be passed back to in form function(err, data).
|
||||||
|
*/
|
||||||
|
pigpio.prototype.get_PWM_real_range = function(userGpio, cb) {
|
||||||
|
"use strict";
|
||||||
|
assert_gpio_pin_in_range(userGpio,0,31);
|
||||||
|
_pi_gpio_command(this.sl,def.PI_CMD_PRRG, userGpio, 0, cb, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the frequency (in Hz) of the PWM to be used on the GPIO.
|
||||||
|
*
|
||||||
|
* If PWM is currently active on the GPIO it will be switched
|
||||||
|
* off and then back on at the new frequency.
|
||||||
|
* Each GPIO can be independently set to one of 18 different PWM frequencies.
|
||||||
|
* The selectable frequencies depend upon the sample rate which
|
||||||
|
* may be 1, 2, 4, 5, 8, or 10 microseconds (default 5).
|
||||||
|
* The sample rate is set when the pigpio daemon is started.
|
||||||
|
*
|
||||||
|
* The frequencies for each sample rate are:
|
||||||
|
* hertz
|
||||||
|
* 1: 40000 20000 10000 8000 5000 4000 2500 2000 1600
|
||||||
|
* 1250 1000 800 500 400 250 200 100 50
|
||||||
|
* 2: 20000 10000 5000 4000 2500 2000 1250 1000 800
|
||||||
|
* 625 500 400 250 200 125 100 50 25
|
||||||
|
* 4: 10000 5000 2500 2000 1250 1000 625 500 400
|
||||||
|
* 313 250 200 125 100 63 50 25 13
|
||||||
|
* sample
|
||||||
|
* rate
|
||||||
|
* (us) 5: 8000 4000 2000 1600 1000 800 500 400 320
|
||||||
|
* 250 200 160 100 80 50 40 20 10
|
||||||
|
* 8: 5000 2500 1250 1000 625 500 313 250 200
|
||||||
|
* 156 125 100 63 50 31 25 13 6
|
||||||
|
* 10: 4000 2000 1000 800 500 400 250 200 160
|
||||||
|
* 125 100 80 50 40 25 20 10 5.
|
||||||
|
*
|
||||||
|
* @param {number} userGpio - The number of the gpio to address (0-31).
|
||||||
|
* @param {number} frequency - Frequency >=0 Hz.
|
||||||
|
*/
|
||||||
|
pigpio.prototype.set_PWM_frequency = function (userGpio, frequency) {
|
||||||
|
"use strict";
|
||||||
|
assert_gpio_pin_in_range(userGpio,0,31);
|
||||||
|
assert(frequency>=0, "frequency must be greater than or equal to 0");
|
||||||
|
_pi_gpio_command(this.sl,def.PI_CMD_PFS, userGpio, frequency);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the frequency of PWM being used on the GPIO.
|
||||||
|
*
|
||||||
|
* @param {number} userGpio - The number of the gpio to address (0-31).
|
||||||
|
* @param {callback} cb - Function that the value will be passed back to in form function(err, data).
|
||||||
|
*/
|
||||||
|
pigpio.prototype.get_PWM_frequency = function(userGpio, cb) {
|
||||||
|
"use strict";
|
||||||
|
assert_gpio_pin_in_range(userGpio,0,31);
|
||||||
|
_pi_gpio_command(this.sl,def.PI_CMD_PFG, userGpio, 0, cb, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls a user supplied function (a callback) whenever the specified GPIO edge is detected.
|
||||||
|
*
|
||||||
|
* The user supplied callback receives three parameters, the GPIO, the level, and the tick.
|
||||||
|
*
|
||||||
|
* If a user callback is not specified a default tally callback is
|
||||||
|
* provided which simply counts edges. The count may be retrieved
|
||||||
|
* by calling the tally function. The count may be reset to zero
|
||||||
|
* by calling the reset_tally function.
|
||||||
|
*
|
||||||
|
* The callback may be cancelled by calling the cancel function.
|
||||||
|
*
|
||||||
|
* A GPIO may have multiple callbacks (although I can't think of
|
||||||
|
* a reason to do so).
|
||||||
|
*
|
||||||
|
* @param {number} userGpio - The number of the gpio to address (0-31).
|
||||||
|
* @param {number} edge - Indicate the edge to detect.
|
||||||
|
* @param {callback} cb - Callback to be run.
|
||||||
|
*/
|
||||||
|
pigpio.prototype.callback = function (userGpio, edge, cb) {
|
||||||
|
"use strict";
|
||||||
|
assert_gpio_pin_in_range(userGpio,0,31);
|
||||||
|
return new _callback (this._notify, userGpio, edge, cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Returns the Pi's hardware revision number.
|
||||||
|
*
|
||||||
|
* The hardware revision is the last few characters on the Revision line of /proc/cpuinfo.
|
||||||
|
* The revision number can be used to determine the assignment of GPIO to pins (see [*gpio*]).
|
||||||
|
* There are at least three types of board.
|
||||||
|
* * Type 1 boards have hardware revision numbers of 2 and 3.
|
||||||
|
* * Type 2 boards have hardware revision numbers of 4, 5, 6, and 15.
|
||||||
|
* * Type 3 boards have hardware revision numbers of 16 or greater.
|
||||||
|
* * If the hardware revision can not be found or is not a valid hexadecimal number the function returns 0.
|
||||||
|
*
|
||||||
|
* @param {callback} cb - Callback that will receive the result in form of function (err, data).
|
||||||
|
*/
|
||||||
|
pigpio.prototype.getHardwareRevision = function(cb) {
|
||||||
|
"use strict";
|
||||||
|
_pi_gpio_command(this.sl,def.PI_CMD_HWVER, 0, 0, cb, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the GPIO mode.
|
||||||
|
*
|
||||||
|
* @param {number} gpio - Port 0-53.
|
||||||
|
* @param {string} mode - Must be either INPUT, OUTPUT, ALT0, ALT1, ALT2, ALT3, ALT4 or ALT5.
|
||||||
|
*/
|
||||||
|
pigpio.prototype.set_mode = function (gpio, mode) {
|
||||||
|
"use strict";
|
||||||
|
assert_gpio_pin_in_range(gpio,0,53);
|
||||||
|
assert([this.INPUT, this.OUTPUT, this.ALT0, this.ALT1, this.ALT2, this.ALT3, this.ALT4, this.ALT5].includes(mode), "Mode must be INPUT, OUTPUT, ALT0, ALT1, ALT2, ALT3, ALT4, ALT5");
|
||||||
|
_pi_gpio_command(this.sl,def.PI_CMD_MODES, gpio, mode);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the GPIO mode.
|
||||||
|
*
|
||||||
|
* @param {number} gpio - Port 0-53.
|
||||||
|
* @param {callback} callback - Function to be run when the data has been received.
|
||||||
|
*/
|
||||||
|
pigpio.prototype.get_mode = function (gpio, callback) {
|
||||||
|
"use strict";
|
||||||
|
assert_gpio_pin_in_range(gpio,0,53);
|
||||||
|
_pi_gpio_command(this.sl,def.PI_CMD_MODEG, gpio, 0, callback, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets or clears the internal GPIO pull-up/down resistor.
|
||||||
|
*
|
||||||
|
* @param {number} gpio - Port 0-53.
|
||||||
|
* @param {string} pud - Must be either PUD_UP, PUD_DOWN, PUD_OFF.
|
||||||
|
*/
|
||||||
|
pigpio.prototype.set_pull_up_down = function (gpio, pud) {
|
||||||
|
"use strict";
|
||||||
|
assert_gpio_pin_in_range(gpio,0,53);
|
||||||
|
assert([this.PUD_DOWN, this.PUD_OFF, this.PUD_UP].includes(pud), "pud must be PUD_UP, PUD_DOWN, PUD_OFF");
|
||||||
|
_pi_gpio_command(this.sl,def.PI_CMD_PUD, gpio, pud);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a glitch filter on a GPIO.
|
||||||
|
*
|
||||||
|
* Level changes on the GPIO are not reported unless the level
|
||||||
|
* has been stable for at least [*steady*] microseconds. The
|
||||||
|
* level is then reported. Level changes of less than [*steady*]
|
||||||
|
* microseconds are ignored.
|
||||||
|
*
|
||||||
|
* @param {number} gpio - Port 0-31.
|
||||||
|
* @param {number} steady - Number of setmicroseconds after detection before a change is confirmed.
|
||||||
|
*/
|
||||||
|
pigpio.prototype.set_glitch_filter = function (gpio, steady) {
|
||||||
|
"use strict";
|
||||||
|
assert_gpio_pin_in_range(gpio,0,31);
|
||||||
|
assert(steady>=0 && steady<=300000, "steady must be in the range 0 - 30000");
|
||||||
|
_pi_gpio_command(this.sl,def.PI_CMD_FG, gpio, steady);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls a user supplied function (a callback) whenever the
|
||||||
|
* specified GPIO edge is detected.
|
||||||
|
*
|
||||||
|
* If a user callback is not specified a default tally callback is
|
||||||
|
* provided which simply counts edges. The count may be retrieved
|
||||||
|
* by calling the tally function. The count may be reset to zero
|
||||||
|
* by calling the reset_tally function.
|
||||||
|
*
|
||||||
|
* The callback may be cancelled by calling the cancel function.
|
||||||
|
*
|
||||||
|
* A GPIO may have multiple callbacks (although I can't think of
|
||||||
|
* a reason to do so).
|
||||||
|
*
|
||||||
|
* @param {number} userGpio - Port 0-31.
|
||||||
|
* @param {number} edge - Must be EITHER_EDGE, RISING_EDGE (default), or FALLING_EDGE.
|
||||||
|
* @param {callback} func - User supplied callback function.
|
||||||
|
* The user supplied callback receives three parameters, the GPIO, the level, and the tick.
|
||||||
|
*/
|
||||||
|
pigpio.prototype.callback = function (userGpio, edge, func) {
|
||||||
|
"use strict";
|
||||||
|
assert_gpio_pin_in_range(userGpio,0,31);
|
||||||
|
if (edge === undefined || edge === null) {
|
||||||
|
edge = this.RISING_EDGE;
|
||||||
|
}
|
||||||
|
assert (edge === this.EITHER_EDGE || edge === this.RISING_EDGE || edge === this.FALLING_EDGE);
|
||||||
|
return new _callback(this._notify, userGpio, edge, func)
|
||||||
|
}
|
||||||
|
|
||||||
|
function assert_gpio_pin_in_range (gpio, low , high) {
|
||||||
|
"use strict";
|
||||||
|
assert(gpio >= low && gpio <= high, 'userGpio must be in the range ' + low + '-' + high + '31');
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = pigpio;
|
||||||
89
hardware/pigpiod/js-pigpio/utils.js
Normal file
89
hardware/pigpiod/js-pigpio/utils.js
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
|
exports.reverse_string_and_clean = function (str) {
|
||||||
|
var result='';
|
||||||
|
var i = str.length-1;
|
||||||
|
while (i>str.length-9) {
|
||||||
|
result +=str [i-1] + str[i] ;
|
||||||
|
i -=2;
|
||||||
|
}
|
||||||
|
return parseInt(result,'16');
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.reverse_string = function (str) {
|
||||||
|
var result='';
|
||||||
|
var i = str.length-1;
|
||||||
|
while (i>0) {
|
||||||
|
result +=str [i-1] + str[i] ;
|
||||||
|
i -=2;
|
||||||
|
}
|
||||||
|
return parseInt(result,'16');
|
||||||
|
};
|
||||||
|
|
||||||
|
const _LOCKS = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class to store socket and lock.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
class _socklock {
|
||||||
|
constructor(host, port) {
|
||||||
|
this.s = null;
|
||||||
|
this.host = host;
|
||||||
|
this.port = port;
|
||||||
|
this._next = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* eslint: no-unmodified-loop-condition */
|
||||||
|
_acquireLock() {
|
||||||
|
"use strict";
|
||||||
|
let timeout = false;
|
||||||
|
setTimeout(() => {
|
||||||
|
timeout = true
|
||||||
|
}, 500);
|
||||||
|
/* eslint-disable no-unmodified-loop-condition */
|
||||||
|
while (!timeout && _LOCKS[this.host + ':' + this.port] !== undefined) {
|
||||||
|
if (_LOCKS[this.host + ':' + this.port] === undefined) {
|
||||||
|
_LOCKS[this.host + ':' + this.port] = 'Locked';
|
||||||
|
} else {
|
||||||
|
throw new Error('Can not acquire Lock');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* eslint-disable no-unmodified-loop-condition */
|
||||||
|
}
|
||||||
|
|
||||||
|
_releaseLock() {
|
||||||
|
"use strict";
|
||||||
|
if (_LOCKS[this.host + ':' + this.port] !== undefined) {
|
||||||
|
_LOCKS[this.host + ':' + this.port] = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports._socklock = _socklock;
|
||||||
|
|
||||||
|
exports._pi_gpio_command = function(socketlock, command, parameter1, parameter2, next, wait_for_response) {
|
||||||
|
"use strict";
|
||||||
|
assert(command !== undefined, "No command specified");
|
||||||
|
// console.log("Receviced _pi_gpio_command "+command+" | "+parameter1+" | "+parameter2)
|
||||||
|
const cmd = Buffer.alloc(16); // Crée un tampon de 16 octets
|
||||||
|
cmd.writeUInt32LE(command, 0);
|
||||||
|
cmd.writeUInt32LE(parameter1, 4);
|
||||||
|
cmd.writeUInt32LE(parameter2, 8);
|
||||||
|
cmd.writeUInt32LE(0, 12);
|
||||||
|
|
||||||
|
socketlock._acquireLock();
|
||||||
|
|
||||||
|
if (next !== undefined) {
|
||||||
|
socketlock._next[command] = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!socketlock.s.write(cmd)) {
|
||||||
|
next(new Error("Error Sending Command to Pi: "+command));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!wait_for_response) {
|
||||||
|
socketlock._releaseLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "node-red-node-pi-gpiod",
|
"name": "node-red-node-pi-gpiod",
|
||||||
"version": "0.4.0",
|
"version": "0.5.0",
|
||||||
"description": "A node-red node for PiGPIOd",
|
"description": "A node-red node for PiGPIOd",
|
||||||
"dependencies" : {
|
"dependencies" : {
|
||||||
"js-pigpio": "*"
|
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
@@ -18,7 +17,7 @@
|
|||||||
],
|
],
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Dave Conway-Jones",
|
"name": "Dave Conway-Jones",
|
||||||
"email": "ceejay@vnet.ibm.com",
|
"email": "dceejay@gmail.com",
|
||||||
"url": "http://nodered.org"
|
"url": "http://nodered.org"
|
||||||
},
|
},
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
module.exports = function(RED) {
|
module.exports = function(RED) {
|
||||||
"use strict";
|
"use strict";
|
||||||
var Pigpio = require('js-pigpio');
|
var Pigpio = require('./js-pigpio/index.js');
|
||||||
|
|
||||||
var bcm2pin = {
|
var bcm2pin = {
|
||||||
"2":"3", "3":"5", "4":"7", "14":"8", "15":"10", "17":"11", "18":"12", "27":"13", "22":"15",
|
"2":"3", "3":"5", "4":"7", "14":"8", "15":"10", "17":"11", "18":"12", "27":"13", "22":"15",
|
||||||
@@ -50,12 +50,13 @@ module.exports = function(RED) {
|
|||||||
node.status({fill:"green",shape:"dot",text:level});
|
node.status({fill:"green",shape:"dot",text:level});
|
||||||
});
|
});
|
||||||
if (node.read) {
|
if (node.read) {
|
||||||
setTimeout(function() {
|
var loop = setInterval(function() {
|
||||||
PiGPIO.read(node.pin, function(err, level) {
|
PiGPIO.read(node.pin, function(err, level) {
|
||||||
node.send({ topic:"pi/"+node.pio, payload:Number(level), host:node.host });
|
node.send({ topic:"pi/"+node.pio, payload:Number(level), host:node.host });
|
||||||
node.status({fill:"green",shape:"dot",text:level});
|
node.status({fill:"green",shape:"dot",text:level});
|
||||||
|
clearInterval(loop)
|
||||||
});
|
});
|
||||||
}, 20);
|
}, 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
25
package.json
25
package.json
@@ -40,16 +40,16 @@
|
|||||||
"grunt-lint-inline": "^1.0.0",
|
"grunt-lint-inline": "^1.0.0",
|
||||||
"grunt-simple-mocha": "^0.4.1",
|
"grunt-simple-mocha": "^0.4.1",
|
||||||
"imap": "^0.8.19",
|
"imap": "^0.8.19",
|
||||||
"mailparser": "^3.7.2",
|
"mailparser": "^3.7.5",
|
||||||
"markdown-it": "^14.1.0",
|
"markdown-it": "^14.1.0",
|
||||||
"mocha": "~6.2.3",
|
"mocha": "~6.2.3",
|
||||||
"msgpack-lite": "^0.1.26",
|
"msgpack-lite": "^0.1.26",
|
||||||
"multilang-sentiment": "^1.2.0",
|
"multilang-sentiment": "^1.2.0",
|
||||||
"ngeohash": "^0.6.3",
|
"ngeohash": "^0.6.3",
|
||||||
"node-pop3": "^0.9.1",
|
"node-pop3": "^0.10.0",
|
||||||
"node-red": "^4.0.9",
|
"node-red": "^4.1.1",
|
||||||
"node-red-node-test-helper": "^0.3.2",
|
"node-red-node-test-helper": "^0.3.2",
|
||||||
"nodemailer": "^7.0.5",
|
"nodemailer": "^7.0.9",
|
||||||
"proxyquire": "^2.1.3",
|
"proxyquire": "^2.1.3",
|
||||||
"pushbullet": "^2.4.0",
|
"pushbullet": "^2.4.0",
|
||||||
"sentiment": "^2.1.0",
|
"sentiment": "^2.1.0",
|
||||||
@@ -59,8 +59,23 @@
|
|||||||
"supertest": "^4.0.2",
|
"supertest": "^4.0.2",
|
||||||
"when": "^3.7.8"
|
"when": "^3.7.8"
|
||||||
},
|
},
|
||||||
|
"overrides": {
|
||||||
|
"utf7": {
|
||||||
|
"semver": "^5.7.2"
|
||||||
|
},
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"grunt-jscs": {
|
||||||
|
"jscs": {
|
||||||
|
"jsonlint": {
|
||||||
|
"nomnom": {
|
||||||
|
"underscore": "1.13.7"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=20"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jshint": "~2.13.6",
|
"jshint": "~2.13.6",
|
||||||
|
|||||||
Reference in New Issue
Block a user