-
Notifications
You must be signed in to change notification settings - Fork 0
/
dooya.coffee
137 lines (117 loc) · 3.49 KB
/
dooya.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
module.exports = (env) ->
# Require the bluebird promise library
Promise = env.require 'bluebird'
# Require the [cassert library](https://github.com/rhoot/cassert).
assert = env.require 'cassert'
t = env.require('decl-api').types
M = env.matcher
rpio = require 'rpio'
class Dooya extends env.plugins.Plugin
# ####init()
# The `init` function is called by the framework to ask your plugin to initialise.
#
# #####params:
# * `app` is the [express] instance the framework is using.
# * `framework` the framework itself
# * `config` the properties the user specified as config for your plugin in the `plugins`
# section of the config.json file
#
#
init: (app, @framework, @config) =>
deviceConf = require './device-config-schema'
@framework.deviceManager.registerDeviceClass('DooyaRemote', {
configDef: deviceConf.DooyaRemote,
createCallback: (config) => new DooyaRemoteDevice(config, @, deviceConf.DooyaRemote)
})
class DooyaRemoteDevice extends env.devices.ShutterController
constructor: (@config, @plugin, @deviceConf) ->
@id = @config.id
@name = @config.name
@remoteId = @config.remoteId || @deviceConf.remoteId
@pin = @plugin.config.pin
# keep the state of the pin so that devices
# do not hog the GPIO unnecesseraly
@opened = false
# codes for supported commands
@cmd = {
wakeup: 17,
up: 30,
wakedown: 51,
down: 60,
stop: 85
}
# latency for different pulses
@lut = {
HSTART: 4830,
LSTART: 1535,
LSHORT: 415,
HSHORT: 340,
LLONG: 750,
HLONG: 685,
CMDDELAY: 9,
DELAY: 15
}
rpio.open(@pin, rpio.OUTPUT)
rpio.usleep(10) #first call has lag
@opened = true
super()
moveToPosition: (position) ->
moveUp = () ->
return new Promise (resolve, reject) =>
@send(@cmd.wakeup, 3)
rpio.msleep(@lut.DELAY)
@send(@cmd.up, 3)
resolve()
moveDown = () ->
return new Promise (resolve, reject) =>
@send(@cmd.wakedown, 3)
rpio.msleep(@lut.DELAY)
@send(@cmd.down, 3)
resolve()
if position == 'up'
return moveUp()
else if position == 'down'
return moveDown()
else
throw new Error('unsupported position ' + position)
stop: () ->
return new Promise (resolve, reject) =>
@send(@cmd.stop, 3)
resolve()
destroy: () ->
rpio.close(@pin)
@opened = false
super()
_pulse: (cmd, bit) ->
level = cmd & (1 << bit)
if level
rpio.write(@pin, 1)
rpio.usleep(@lut.HLONG)
rpio.write(@pin, 0)
rpio.usleep(@lut.LSHORT)
else
rpio.write(@pin, 1)
rpio.usleep(@lut.HSHORT)
rpio.write(@pin, 0)
rpio.usleep(@lut.LLONG)
send: (cmd, repeat) ->
if not @opened
rpio.open(@pin, rpio.OUTPUT)
rpio.usleep(10) #first call has lag
rpio.write(@pin, 1)
rpio.usleep(@lut.HSTART)
rpio.write(@pin, 0)
rpio.usleep(@lut.LSTART)
# send remote id
@_pulse @remoteId, bit for bit in [31..0]
# send command
@_pulse cmd, bit for bit in [7..0]
repeat--
if repeat
rpio.msleep(@lut.CMDDELAY)
@send(cmd, repeat)
# ###Finally
# Create a instance of my plugin
dooya = new Dooya
# and return it to the framework.
return dooya