/**
* For working with switches
* @module j5e/switch
* @requires module:j5e/event
* @requires module:j5e/fn
*/
import { Emitter } from "j5e/event";
import { normalizeDevice, normalizeIO, getProvider } from "j5e/fn";
/**
* Class representing a switch
* @classdesc The Switch class allows for control of digital switches
* @async
* @extends module:j5e/event.Emitter
* @fires Switch#open
* @fires Switch#close
*/
class Switch extends Emitter {
#state = {
isPullup: null,
normallyClosed: null
};
/**
* Instantiate a switch
* @param {number|string|object} io - Pin identifier or IO Options (See {@tutorial C-INSTANTIATING})
* @param {number|string} [io.mode=Input] - Device configuration options. If a number, a valid value based on the Provider's constants. If a string, one of "Input", "InputPullUp", or "InputPullDown"
* @example
* <caption>Use a switch to control an LED</caption>
* import Switch from "j5e/switch";
* import LED from "j5e/led";
*
* const mySwitch = await new Switch(12);
* const led = await new LED(13);
*
* mySwitch.on("open", function() {
* led.off();
* });
*
* mySwitch.on("close", function() {
* led.on();
* });
*/
constructor(io) {
return (async() => {
io = normalizeIO(io);
super();
const Provider = await getProvider(io, "Digital");
let mode = Provider.Input;
if (typeof io.mode !== "undefined") {
if (typeof io.mode === "string") {
mode = Provider[io.mode];
} else {
mode = io.mode;
}
}
this.#state.isPullup = mode === Provider.InputPullUp;
this.io = new Provider({
pin: io.pin,
mode,
edge: Provider.Rising | Provider.Falling,
onReadable: () => {
this.emit(this.isOpen ? "open" : "close");
}
});
this.configure();
return this;
})();
}
/**
* True if the switch is closed (current is flowing)
* @returns {boolean}
* @readonly
*/
get isClosed() {
return (Boolean(this.io.read()) ^ this.#state.isPullup);
}
/**
* True if the switch is open (current is not flowing)
* @returns {boolean}
* @readonly
*/
get isOpen() {
return !(Boolean(this.io.read()) ^ this.#state.isPullup);
}
/**
* Configure a switch - Noop
* @returns {Switch} The instance on which the method was called
* @param {object} options - Device configuration options
* @private
* @example
* import Button from "j5e/button";
* import LED from "j5e/led";
*
* const button = await new Button(14);
* button.configure();
*
* button.on("open", function() {
* led.off();
* });
*
* button.on("close", function() {
* led.on();
* });
*/
configure(options = {}) {
return this;
}
}
export default Switch;