UNPKG

pimatic-gpio

Version:

Provides Actuators and Sensors for the Raspberry Pi GPIO Pins.

166 lines (128 loc) 4.63 kB
module.exports = (env) -> # pimatic imports. Promise = env.require 'bluebird' assert = env.require 'cassert' _ = env.require 'lodash' Gpio = require('onoff').Gpio class GpioPlugin extends env.plugins.Plugin init: (app, @framework, @config) -> deviceConfigDef = require("./device-config-schema") @framework.deviceManager.registerDeviceClass("GpioPresence", { configDef: deviceConfigDef.GpioPresence, createCallback: (config, lastState) => new GpioPresence(config, lastState) }) @framework.deviceManager.registerDeviceClass("GpioContact", { configDef: deviceConfigDef.GpioContact, createCallback: (config, lastState) => new GpioContact(config, lastState) }) @framework.deviceManager.registerDeviceClass("GpioSwitch", { configDef: deviceConfigDef.GpioSwitch, createCallback: (config, lastState) => new GpioSwitch(config, lastState) }) plugin = new GpioPlugin class GpioSwitch extends env.devices.PowerSwitch constructor: (@config, lastState) -> @name = @config.name @id = @config.id if @config.defaultState? @_state = @config.defaultState else @_state = lastState?.state?.value or false stateToSet = (if @config.inverted then not @_state else @_state) options = debounceTimeout: @config.debounceTimeout if @config.debounceTimeout? @gpio = new Gpio @config.gpio, (if stateToSet then "high" else "low"), options super() destroy: () -> @gpio.unwatchAll() @gpio.unexport() super() getState: () -> if @_state? then Promise.resolve @_state @gpio.read().then( (value) => _state = (if value is 1 then yes else no) if @config.inverted then @_state = not _state else @_state = _state return @_state ) changeStateTo: (state) -> assert state is on or state is off if @config.inverted then _state = not state else _state = state @gpio.write(if _state then 1 else 0).then( () => @_setState(state) ) # ##GpioContact Sensor class GpioContact extends env.devices.ContactSensor constructor: (@config, lastState) -> @id = @config.id @name = @config.name options = debounceTimeout: @config.debounceTimeout if @config.debounceTimeout? @gpio = new Gpio(@config.gpio, 'in', 'both', options) @_contact = lastState?.contact?.value or false @_readContactValue().catch( (error) => env.logger.error error.message env.logger.debug error.stack ) @gpio.watch (err, value) => if err? env.logger.error err.message env.logger.debug err.stack else @_setContactValue value super() destroy: () -> @gpio.unwatchAll() @gpio.unexport() super() _setContactValue: (value) -> assert value is 1 or value is 0 state = (if value is 1 then yes else no) if @config.inverted then state = not state @_setContact state _readContactValue: -> @gpio.read().then( (value) => @_setContactValue value return @_contact ) getContact: () -> if @_contact? then Promise.resolve(@_contact) else @_readContactValue() # ##GpioPresence Sensor class GpioPresence extends env.devices.PresenceSensor constructor: (@config, lastState) -> @id = @config.id @name = @config.name options = debounceTimeout: @config.debounceTimeout if @config.debounceTimeout? @gpio = new Gpio(@config.gpio, 'in', 'both', options) @_presence = lastState?.presence?.value or false @_readPresenceValue().catch( (error) => env.logger.error error.message env.logger.debug error.stack ) @gpio.watch (err, value) => if err? env.logger.error err.message env.logger.debug err.stack else @_setPresenceValue value super() destroy: () -> @gpio.unwatchAll() @gpio.unexport() super() _setPresenceValue: (value) -> assert value is 1 or value is 0 state = (if value is 1 then yes else no) if @config.inverted then state = not state @_setPresence state _readPresenceValue: -> @gpio.read().then( (value) => @_setPresenceValue value return @_presence ) getPresence: () -> if @_presence? then Promise.resolve(@_presence) else @_readPresenceValue() # For testing... plugin.GpioSwitch = GpioSwitch plugin.GpioPresence = GpioPresence return plugin