pimatic-gpio
Version:
Provides Actuators and Sensors for the Raspberry Pi GPIO Pins.
166 lines (128 loc) • 4.63 kB
text/coffeescript
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, , ) ->
deviceConfigDef = require("./device-config-schema")
.deviceManager.registerDeviceClass("GpioPresence", {
configDef: deviceConfigDef.GpioPresence,
createCallback: (config, lastState) => new GpioPresence(config, lastState)
})
.deviceManager.registerDeviceClass("GpioContact", {
configDef: deviceConfigDef.GpioContact,
createCallback: (config, lastState) => new GpioContact(config, lastState)
})
.deviceManager.registerDeviceClass("GpioSwitch", {
configDef: deviceConfigDef.GpioSwitch,
createCallback: (config, lastState) => new GpioSwitch(config, lastState)
})
plugin = new GpioPlugin
class GpioSwitch extends env.devices.PowerSwitch
constructor: (, lastState) ->
= .name
= .id
if .defaultState?
= .defaultState
else
= lastState?.state?.value or false
stateToSet = (if .inverted then not else )
options =
debounceTimeout: .debounceTimeout if .debounceTimeout?
= new Gpio .gpio, (if stateToSet then "high" else "low"), options
super()
destroy: () ->
.unwatchAll()
.unexport()
super()
getState: () ->
if ? then Promise.resolve
.read().then( (value) =>
_state = (if value is 1 then yes else no)
if .inverted then = not _state
else = _state
return
)
changeStateTo: (state) ->
assert state is on or state is off
if .inverted then _state = not state
else _state = state
.write(if _state then 1 else 0).then( () =>
)
# ##GpioContact Sensor
class GpioContact extends env.devices.ContactSensor
constructor: (, lastState) ->
= .id
= .name
options =
debounceTimeout: .debounceTimeout if .debounceTimeout?
= new Gpio(.gpio, 'in', 'both', options)
= lastState?.contact?.value or false
.catch( (error) =>
env.logger.error error.message
env.logger.debug error.stack
)
.watch (err, value) =>
if err?
env.logger.error err.message
env.logger.debug err.stack
else
value
super()
destroy: () ->
.unwatchAll()
.unexport()
super()
_setContactValue: (value) ->
assert value is 1 or value is 0
state = (if value is 1 then yes else no)
if .inverted then state = not state
state
_readContactValue: ->
.read().then( (value) =>
value
return
)
getContact: () -> if ? then Promise.resolve() else
# ##GpioPresence Sensor
class GpioPresence extends env.devices.PresenceSensor
constructor: (, lastState) ->
= .id
= .name
options =
debounceTimeout: .debounceTimeout if .debounceTimeout?
= new Gpio(.gpio, 'in', 'both', options)
= lastState?.presence?.value or false
.catch( (error) =>
env.logger.error error.message
env.logger.debug error.stack
)
.watch (err, value) =>
if err?
env.logger.error err.message
env.logger.debug err.stack
else
value
super()
destroy: () ->
.unwatchAll()
.unexport()
super()
_setPresenceValue: (value) ->
assert value is 1 or value is 0
state = (if value is 1 then yes else no)
if .inverted then state = not state
state
_readPresenceValue: ->
.read().then( (value) =>
value
return
)
getPresence: () -> if ? then Promise.resolve() else
# For testing...
plugin.GpioSwitch = GpioSwitch
plugin.GpioPresence = GpioPresence
return plugin