-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathindex.js
More file actions
136 lines (117 loc) · 4.82 KB
/
Copy pathindex.js
File metadata and controls
136 lines (117 loc) · 4.82 KB
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
var Service, Characteristic;
const request = require('request');
const DEF_INTERVAL = 2000; //2s
const URL = "https://api.tzevaadom.co.il/notifications";
const HTTP_METHOD = "GET";
const HEADERS = {
"Connection": "close",
"X-Requested-With": "XMLHttpRequest",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
};
module.exports = function (homebridge) {
Service = homebridge.hap.Service;
Characteristic = homebridge.hap.Characteristic;
homebridge.registerAccessory("homebridge-missiles-alert", "MissilesAlert", HttpMotion);
}
function HttpMotion(log, config) {
this.log = log;
this.lastNotificationId = null;
// Error counters
this.httpErrorResponseCount = 0;
this.jsonParseErrorCount = 0;
this.updateStateResponsePendingCount = 0;
// url info
this.url = URL;
this.http_method = HTTP_METHOD;
this.headers = HEADERS;
this.name = config["name"];
this.manufacturer = "Gal Mirkin";
this.model = "MissilesAlerts";
this.serial = "RVU729";
this.update_interval = Number(config["update_interval"] || DEF_INTERVAL);
this.cities = config["cities"] || ["all"];
// Internal variables
this.last_state = false;
this.waiting_response = false;
}
HttpMotion.prototype = {
updateState: function () {
if (this.waiting_response) {
this.updateStateResponsePendingCount++;
if (this.updateStateResponsePendingCount >= 20) {
this.updateStateResponsePendingCount = 0;
}
return;
}
this.updateStateResponsePendingCount = 0;
this.waiting_response = true;
var ops = {
uri: this.url,
method: this.http_method,
headers: this.headers
};
request(ops, (error, res, body) => {
var value = false;
var recentAlerts = [];
if (error) {
this.httpErrorResponseCount++;
if (this.httpErrorResponseCount >= 10) {
this.log('HTTP bad response (' + ops.uri + ') occurred 10 times in a row: ' + error.message);
this.httpErrorResponseCount = 0; // reset the counter
}
} else if (!body) {
error = true;
} else {
try {
var alerts = JSON.parse(body);
alerts.forEach(alert => {
// Check if the alert hasn't been processed before and contains the desired city
if (this.lastNotificationId !== alert.notificationId &&
(this.cities.includes("all") || alert.cities.some(city => this.cities.includes(city)))) {
value = true;
this.lastNotificationId = alert.notificationId;
this.log("Your city is under attack! Get to the shelters right now!");
}
});
this.httpErrorResponseCount = 0;
this.jsonParseErrorCount = 0;
} catch (parseErr) {
this.jsonParseErrorCount++;
if (this.jsonParseErrorCount >= 10) {
this.log('Error processing received information occurred 10 times in a row: ' + parseErr.message);
this.jsonParseErrorCount = 0;
}
error = parseErr;
}
}
this.motionService
.getCharacteristic(Characteristic.MotionDetected).updateValue(value, null, "updateState");
this.last_state = value;
this.waiting_response = false;
});
},
getState: function (callback) {
var state = this.last_state;
if (!this.waiting_response && this.update_interval === 0) {
this.log('Call to getState: last_state is "' + state + '", will update state now');
setImmediate(this.updateState.bind(this));
}
callback(null, state);
},
getServices: function () {
this.log("Cities are set to " + this.cities.join(", "));
this.informationService = new Service.AccessoryInformation();
this.informationService
.setCharacteristic(Characteristic.Manufacturer, this.manufacturer)
.setCharacteristic(Characteristic.Model, this.model)
.setCharacteristic(Characteristic.SerialNumber, this.serial);
this.motionService = new Service.MotionSensor(this.name);
this.motionService
.getCharacteristic(Characteristic.MotionDetected)
.on('get', this.getState.bind(this));
if (this.update_interval > 0) {
this.timer = setInterval(this.updateState.bind(this), this.update_interval);
}
return [this.informationService, this.motionService];
}
};