-
Notifications
You must be signed in to change notification settings - Fork 0
/
lirc.coffee
148 lines (116 loc) · 4.4 KB
/
lirc.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
138
139
140
141
142
143
144
145
146
147
148
# #Lirc plugin
# This plugin gives functionality to pimatic to control lirc (ir remotes).
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'
_ = require 'lodash'
M = env.matcher
# Require the [lirc_node](https://github.com/alexbain/lirc_node) library
lirc_node = require 'lirc_node'
fs = require "fs"
os = require "os"
# ###LircPlugin class
class LircPlugin extends env.plugins.Plugin
init: (app, @framework, @config) =>
lirc_node.init();
deviceConfigDef = require("./device-config-schema")
# I know this isn't optimal but the init function of node_lirc needs some time before it is done.
# This makes the pimatic rule engine fail, at launch and the rules to be disabled.
setTimeout ( ->
remoteList = lirc_node.remotes
fs.writeFile __("%s/cached_remotes_lirc.json", os.tmpdir()), JSON.stringify(lirc_node.remotes), (error) ->
env.logger.error("Error writing remote cache file.", error) if error
), 10000
Promise.promisifyAll(lirc_node)
@framework.ruleManager.addActionProvider(new LircActionProvider @framework, config)
@framework.deviceManager.registerDeviceClass("LircReceiver", {
configDef: deviceConfigDef.LircReceiver,
createCallback: (config) ->
device = new LircReceiver(config)
return device
})
class LircActionProvider extends env.actions.ActionProvider
constructor: (@framework, @config) ->
return
parseAction: (input, context) =>
# Load the cached remote file.
try remoteList = JSON.parse(fs.readFileSync(__("%s/cached_remotes_lirc.json", os.tmpdir()), "utf8"))
catch e then remoteList = {}
remote = ""
command = ""
match = null
m = M(input, context)
.match('set ', optional: yes)
.match(['lirc'])
m.match [' remote: '], (m) ->
m.match _.keys(remoteList), (next, r) ->
remote = r
next.match [' command: '], (m) ->
m.match _.valuesIn(remoteList[remote]), (m, c) ->
command = c
match = m.getFullMatch()
if match?
# either variable or color should be set
return {
token: match
nextInput: input.substring(match.length)
actionHandler: new LircActionHandler(
@framework, remote, command
)
}
class LircActionHandler extends env.actions.ActionHandler
constructor: (@framework, @remote, @command) ->
executeAction: (simulate, context) ->
if simulate
# just return a promise fulfilled with a description about what we would do.
return __(
"would send ir command \"%s\" with remote \"%s\"",
@command, @remote)
else
lirc_node.irsend.send_once(@remote, @command, -> return __("Sending command \"%s\" with remote \"%s\"",
@command, @remote))
return __("Sending command \"%s\" with remote \"%s\"", @command, @remote)
module.exports.LircActionHandler = LircActionHandler
class LircReceiver extends env.devices.Sensor
remote: null
command: null
idleTime = 0
attributes:
remote:
description: 'last remote used'
type: "string"
command:
description: 'last key pressed'
type: "string"
constructor: (@config) ->
@name = config.name
@id = config.id
super()
@listenForIR()
setInterval( ( => @resetLircOutput() ), 1000)
resetLircOutput: ->
if @command?
idleTime += 1
if idleTime > 60
@remote = null
@command = null
@emit "remote", @remote
@emit "command", @command
idleTime = 0
env.logger.debug("Resetting the lirc input to null")
listenForIR: () ->
lirc_node.addListener (data) =>
env.logger.debug("Data received remote %s, command %s", data.remote, data.key)
@remote = data.remote
@command = data.key
@emit "remote", @remote
@emit "command", @command
idleTime = 0
getRemote: -> Promise.resolve(@remote)
getCommand: -> Promise.resolve(@command)
# Create a instance of my plugin
lircPlugin = new LircPlugin()
# and return it to the framework.
return lircPlugin