text: const GPIODevice = require('../devices/GPIODevice.js').GPIODevice;
  const Lock = require('rwlock');
  const inherit = require('../tools.js').inherit;
  
  exports.OutputDevice = OutputDevice;
  /**
   * Represents a generic GPIO output device.
   * Provides facilities common to GPIO output devices an {@link OutputDevice#on|on} method to switch the device on, a
   * corresponding {@link OutputDevice#off|off} method, and a {@link OutputDevice#toggle|toggle} method.
   *
   * @param {(int | Pin)} pin - The GPIO pin (in BCM numbering) or an instance of Pin that the device is connected to.
   * @param {boolean} [active_high] - If `true` (the default), the {@link OutputDevice#on|on} method will set the GPIO to HIGH.
   * If `false`, the :{@link OutputDevice#on|on} method will set the GPIO to LOW (the {@link OutputDevice#off|off} method always does the opposite).
   * @param {boolean} [initial_value] - If `false` (the default), the device will be off initially.
   * If `undefined`, the device will be left in whatever state the pin is found in when configured for output (warning: this can be on).  If `true`, the device will be switched on initially.
   *
   * @throws GPIOPinMissing - When pin is undefined.
   * @class
   * @augments GPIODevice
   */
  function OutputDevice(pin, active_high, initial_value) {
      GPIODevice.call(this, pin);
      this._lock = new Lock();
      this.active_high((active_high === undefined) ? true : active_high);
  
      if (initial_value === undefined) {
          this._pin.pin_function('output');
      } else {
          this._pin.output_with_state(this._value_to_state(initial_value));
      }
  }
  
  
  OutputDevice.prototype = inherit(GPIODevice.prototype);
  OutputDevice.prototype.constructor = OutputDevice;
  
  /**
   * Internal method to apply active state high and convert the actual value to a logical value.
   *
   * @param {boolean|float} value - The value to be converted.
   * @returns {boolean} - The logical value of the pin.
   * @private
   */
  OutputDevice.prototype._value_to_state = function(value) {
      return (value) ? this._active_state : this._inactive_state;
  };
  
  /**
   * Internal method used to write to the pin after mapping the request value.
   *
   * @param {float | boolean} value - The logical value that the pin should be changed to.
   * @private
   */
  OutputDevice.prototype._write = function(value) {
      this._check_open(this);
      this._pin.state(this._value_to_state(value));
  };
  
  /**
   * Turns the device on.
   **/
  OutputDevice.prototype.on = function() {
      this._pin._stop_blink();
      this._write(true);
  };
  
  /**
   * Turns the device off.
   */
  OutputDevice.prototype.off = function() {
      this._pin._stop_blink();
      this._write(false);
  };
  
  /**
   *
   * This property can be set after construction; be warned that changing it
   * will invert {@link OutputDevice#value|value} (i.e. changing this property doesn't change
   * the device's pin state - it just changes how that state is interpreted).
   *
   * @param {boolean} [value] - When ``true``, the {@link OutputDevice#value|value} property is ``true`` when the device's
   * {@link OutputDevice#pin|pin} is high. When ``false`` the {@link OutputDevice#value|value} property is
   * ``true`` when the device's pin is low (i.e. the value is inverted).
   *
   */
  OutputDevice.prototype.active_high = function(value) {
      if (value === undefined) {
          return this._active_state;
      }
      this._active_state = value;
      this._inactive_state = !value;
  };
  
  /**
   *
   * @param {boolean | float} [value] - When supplied the device output is changed to the value.
   * @returns {boolean | float} - When value is undefined, the function returns the current value of the device.
   */
  OutputDevice.prototype.value = function(value) {
      if (value === undefined) {
          return this._read();
      }
      this._pin._stop_blink();
      this._write(value);
  };
  
  /**
   * Reverse the state of the device. If it's on, turn it off; if it's off, turn it on.
   */
  OutputDevice.prototype.toggle = function() {
      const that = this;
      this._lock.readLock((release) => {
          if (that.is_active()) {
              that.off();
          } else {
              that.on();
          }
          release();
      });
  };
  