forked from mwittig/pimatic-lirc
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlirc.coffee
135 lines (102 loc) · 3.95 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
# #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 ( ->
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))
@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.
remoteList = {}
remoteList = require(__("%s/cached_remotes_lirc.json", os.tmpdir()))
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
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()
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
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