-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
196 lines (167 loc) · 5.92 KB
/
index.js
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/*
TERMS OF USE
Open source under the MIT License.
Copyright 2016 Matthijs Logemann All rights reserved.
*/
module.exports = init;
var superagent = require('superagent');
var Service = null;
var Characteristic = null;
function init(homebridge) {
Service = homebridge.hap.Service;
Characteristic = homebridge.hap.Characteristic;
homebridge.registerAccessory('homebridge-thinkingcleaner', 'Roomba', ThinkingCleaner);
}
function ThinkingCleaner(log, config) {
this.log = log;
var that = this;
this.name = config.name;
this.ip_address = config.ip_address;
this.dock_on_stop = (typeof config.dock_on_stop === 'undefined' || config.dock_on_stop === "true");
this.informationService = new Service.AccessoryInformation();
this.informationService.setCharacteristic(Characteristic.Name, this.name)
.setCharacteristic(Characteristic.Manufacturer, "Thinking Bits")
.setCharacteristic(Characteristic.Model, "Thinking Cleaner")
.setCharacteristic(Characteristic.SerialNumber, "Unknown")
.setCharacteristic(Characteristic.FirmwareRevision, "Unknown");
if (!this.ip_address) {
locateTC.call(this, function(err, cleaner) {
if (err) throw err;
// TODO: Find a way to persist this
that.ip_address = cleaner.local_ip;
that.cleaner = cleaner;
that.log("Save the Thinking Cleaner IP address " + cleaner.local_ip + " to your config to skip discovery.");
getSWVersion.call(that);
});
}else {
getSWVersion.call(this);
}
}
var getSWVersion = function() {
var that = this;
// that.informationService.setCharacteristic(Characteristic.SerialNumber, "Loading!");
superagent.get("http://"+that.ip_address+"/full_status.json").timeout(60000).end(function(error, response) {
if (error) {
that.log("Could not load full_status: %s", error.message);
// that.informationService.setCharacteristic(Characteristic.SerialNumber, "Unknown!");
} else {
var tcObj = JSON.parse(response.text);
that.log(tcObj.firmware.version);
// that.informationService.setCharacteristic(Characteristic.SerialNumber, "Loaded!");
}
});
}
var locateTC = function(callback) {
var that = this;
// Report the results of the scan to the user
var getIp = function(err, cleaners) {
if (!cleaners || cleaners.length === 0) {
that.log("No Thinking Cleaner devices found.");
callback(err || new Error("No Thinking Cleaner found"));
return;
}
if (cleaners.length > 1) {
that.log("Warning: Multiple Thinking Cleaner devices detected. The first Thinking Cleaner will be used automatically. To use a different Thinking Cleaner, set the `ip_address` manually in the configuration.");
}
that.log("Thinking Cleaners found:" + (cleaners.map(function(cleaner) {
// Bridge name is only returned from meethue.com so use id instead if it isn't there
return " " + cleaner.local_ip + ' - ' + cleaner.name;
})).join(" "));
callback(null, cleaners[0]);
};
superagent.get("http://tc.thinkingsync.com/api/v1/discover/devices").timeout(60000).end(function(error, response) {
if (error) {
this.log("Could not find Thinking Cleaners: %s", error.message);
getIp(new Error(error));
} else {
that.log("Scan complete");
var tcArr = response.body;
getIp(null, tcArr);
}
});
};
ThinkingCleaner.prototype = {
setPowerState: function(powerOn, callback) {
if (powerOn) {
this.log(this.name + ": Start cleaning");
superagent.get(this.ip_address + "/command.json?command=clean").end(function(error, response) {
if (error) {
this.log("Could not send clean command to Thinking Cleaner: %s", error.message);
callback(error);
} else {
callback();
}
});
} else {
var that = this;
if (!this.dock_on_stop){
superagent.get(this.ip_address + "/status.json").end(function(error, response) {
if (error) {
that.log("Could not send request status of Thinking Cleaner: %s", error.message);
callback(error);
} else {
var tcObj = JSON.parse(response.text);
if (tcObj.status.cleaning === "1"){
that.log(that.name + ": Cleaning, now stopping");
superagent.get(that.ip_address + "/command.json?command=clean").end(function(error, response) {
if (error) {
that.log("Could not send clean command (to stop) to Thinking Cleaner: %s", error.message);
callback(error);
} else {
callback();
}
});
}else{
that.log(that.name + ": Not cleaning, doing nothing extra");
callback();
}
}
});
}else {
this.log(this.name + ": Start docking");
superagent.get(this.ip_address + "/command.json?command=dock").end(function(error, response) {
if (error) {
this.log("Could not send clean command to Thinking Cleaner: %s", error.message);
callback(error);
} else {
callback();
}
});
}
}
},
getPowerState: function(callback) {
var url = this.ip_address + "/status.json";
superagent.get(url).end(function(error, response) {
if (error) {
callback(error);
} else {
var tcObj = JSON.parse(response.text);
callback(null, tcObj.status.cleaning === "1");
}
});
},
identify: function(callback) {
this.log("Identify requested!");
superagent.get(this.ip_address + "/command.json?command=find_me").end(function(error, response) {
if (error) {
this.log("Could not send command to Thinking Cleaner: %s", error.message);
callback(error);
} else {
callback();
}
});
},
getServices: function() {
// the default values for things like serial number, model, etc.
var that = this;
var switchService = new Service.Switch(this.name);
switchService.getCharacteristic(Characteristic.On).on('set', this.setPowerState.bind(this));
switchService.getCharacteristic(Characteristic.On).on('get', this.getPowerState.bind(this));
//setTimeout(function () {
// that.log("Hey");
// that.informationService.setCharacteristic(Characteristic.SerialNumber, "Hi there!");
//}, 10)
return [this.informationService, switchService];
}
};