UNPKG

js-gpiozero

Version:

A simple interface to GPIO devices with Raspberry Pi using nodejs

156 lines (139 loc) 4.62 kB
const Device = require ('./Device.js').Device; const inherit = require('../tools.js').inherit; const wiringpi = require('../pins/wiringpi.js').WiringPiPin; const ReadWriteLock = require('rwlock'); const exc = require('../exc.js'); const _PINS = new Set(); const _PINS_LOCK = new ReadWriteLock(); //Yes, this needs to be re-entrant /* /*if(name == undefined) { name=process.env.GPIOZERO_PIN_FACTORY; } var group = 'gpiozero_pin_factories' if (name == undefined) { /*# If no factory is explicitly specified, try various names in # "preferred" order. Note that in this case we only select from # gpiozero distribution so without explicitly specifying a name (via # the environment) it's impossible to auto-select a factory from # outside the base distribution # # We prefer RPi.GPIO here as it supports PWM, and all Pi revisions. If # no third-party libraries are available, however, we fall back to a # pure Python implementation which supports platforms like PyPy dist = pkg_resources.get_distribution('gpiozero') for name in ('RPiGPIOPin', 'RPIOPin', 'PiGPIOPin', 'NativePin'): try: return pkg_resources.load_entry_point(dist, group, name) except ImportError: pass raise BadPinFactory('Unable to locate any default pin factory!') } else { for factory in pkg_resources.iter_entry_points(group, name): return factory.load() raise BadPinFactory('Unable to locate pin factory "%s"' % name) }*/ //} //var pin_factory = _default_pin_factory(); /** * Represents a generic GPIO device and provides the services common to all single-pin GPIO devices * (like ensuring two GPIO devices do no share a {@link Pin}). * * @param {(int | Pin)} pin - The GPIO pin (in BCM numbering) or a instance of {@link Pin} that the device is connected to. * * @throws {GPIOPinMissing} - If pin is 'undefined' * @throws {GPIOPinInUse} - If the pin is already in use by another device * @class * @augments Device */ function GPIODevice(pin) { Device.call(this); this._pin = undefined; if (pin === undefined) { throw new exc.GPIOPinMissing('No pin given'); } if (Number.isInteger(pin)) { pin = new wiringpi(pin); } _PINS_LOCK.readLock((release) => { if (_PINS.has(pin)) { throw new exc.GPIOPinInUse('pin ' + pin.toString() + ' is already in use by another gpiozero object'); } _PINS.add(pin); release(); }); this._pin = pin; this._active_state = true; this._inactive_state = false; } GPIODevice.prototype = inherit(Device.prototype); GPIODevice.prototype.constructor = GPIODevice; /** * Close the device and remove the pin allocation allowing it to be reused. */ GPIODevice.prototype.close = function() { const that = this; _PINS_LOCK.readLock((release) => { const pin = that._pin; if (_PINS.has(pin)) { _PINS.delete(pin); that._pin.close(); } that._pin = undefined; release(); }); }; /** * * @returns {boolean} - Is ``true`` is no pin is allocated. */ GPIODevice.prototype.closed = function() { return (this._pin === undefined); }; /** * * @returns {undefined|*|int|Pin} - The {@link Pin} that the device is connected to. This will be ``undefined`` * if the device has been closed (see the :meth:`close` method). When dealing with GPIO pins, query ``pin.number`` * to discover the GPIO pin (in BCM numbering) that the device is connected to. */ GPIODevice.prototype.pin = function() { return this._pin; }; /** * @returns {int|Boolean} - Current value of the pin. */ GPIODevice.prototype.value = function() { return this._read(); }; /** * Internal method to read the pin value. * * @private */ GPIODevice.prototype._read = function() { this._check_open(); return this._state_to_value(this.pin().state()); }; /** * Internal method to apply active state high and convert the actual value to a logical value. * * @param {boolean|float} state - The value to be converted. * @returns {boolean} - The logical value of the pin. * @private */ GPIODevice.prototype._state_to_value = function(state) { return Boolean(state === this._active_state); }; /** * * @returns {boolean} - Is true is the device value is currently set. */ GPIODevice.prototype.is_active = function() { return Boolean(this.value()); }; /** * * @returns {string} - Description of the device. */ GPIODevice.prototype.toString = function() { return "<gpiozero.GPIODevice object on pin " + this._pin._number.toString() + ", is_active=" + this.is_active() + ">"; }; exports.GPIODevice = GPIODevice;