Skip to content
This repository was archived by the owner on Jun 25, 2020. It is now read-only.

Commit e267669

Browse files
committed
Add a bridge example
Check BridgedCore.js for HAP Bridge Example Add a thermostat example that response with logic
1 parent 3151616 commit e267669

7 files changed

+406
-3
lines changed

AccessoryController.js

+29-1
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,26 @@ AccessoryController.prototype = {
1616
};
1717
}
1818
},
19+
accessoryJsonPresentation: function accessoryJsonPresentation() {
20+
var servicesObjects = [];
21+
for (var i = 0; i < this.services.length; i++) {
22+
var service = this.services[i];
23+
servicesObjects.push(service.objectsPresentation());
24+
};
25+
var accessory = {
26+
aid: this.accessoryID,
27+
services: servicesObjects
28+
}
29+
return accessory;
30+
},
1931
jsonPresentation: function jsonPresentation() {
2032
var servicesObjects = [];
2133
for (var i = 0; i < this.services.length; i++) {
2234
var service = this.services[i];
2335
servicesObjects.push(service.objectsPresentation());
2436
};
2537
var accessory = {
26-
aid: 1,
38+
aid: this.accessoryID,
2739
services: servicesObjects
2840
}
2941
var dict = {
@@ -45,6 +57,19 @@ AccessoryController.prototype = {
4557
}
4658
return JSON.stringify(respDict);
4759
},
60+
processSingleCharacteristicsValueWrite: function processSingleCharacteristicsValueWrite(update, peer) {
61+
var update_char = update;
62+
var update_char_iid = update_char["iid"];
63+
var update_char_value = update_char["value"];
64+
var update_char_event = update_char["ev"];
65+
var charObject = this.objects[update_char_iid];
66+
if (update_char_value !== undefined) {
67+
charObject.updateCharacteristicValue(update_char_value, peer);
68+
}
69+
if (update_char_event !== undefined) {
70+
charObject.updateCharacteristicEvent(update_char_event, peer);
71+
}
72+
},
4873
processCharacteristicsValueWrite: function processCharacteristicsValueWrite(updates, peer) {
4974
var updates_objects = JSON.parse(updates.toString());
5075
console.log(updates_objects);
@@ -66,6 +91,8 @@ AccessoryController.prototype = {
6691
broadcastEvent: function broadcastEvent(data, subscribedPeers, peer) {
6792
if (this.tcpServer !== undefined) {
6893
this.tcpServer.broadcastEvent(data, subscribedPeers, peer);
94+
} else if (this.bridgeController !== undefined) {
95+
this.bridgeController.broadcastEvent(data, subscribedPeers, peer);
6996
}
7097
}
7198
}
@@ -74,6 +101,7 @@ function AccessoryController() {
74101
if (!(this instanceof AccessoryController)) {
75102
return new AccessoryController();
76103
}
104+
this.accessoryID = 1;
77105
this.instanceID = 1;
78106
this.objects = {};
79107
this.services = [];

BridgedAccessoryController.js

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
BridgedAccessoryController.prototype = {
2+
addAccessory: function addAccessory(accessory) {
3+
var that = this;
4+
accessory.bridgeController = that;
5+
accessory.accessoryID = that.accessoryID;
6+
that.accessories.push(accessory);
7+
that.accessoryID += 1;
8+
},
9+
jsonPresentation: function jsonPresentation() {
10+
var accessoryObjects = [];
11+
for (var i = 0; i < this.accessories.length; i++) {
12+
var accessory = this.accessories[i];
13+
accessoryObjects.push(accessory.accessoryJsonPresentation());
14+
};
15+
var dict = {
16+
accessories: accessoryObjects
17+
}
18+
return JSON.stringify(dict);
19+
},
20+
jsonForCharacteristicUpdate: function jsonForCharacteristicUpdate(aid, iid) {
21+
var accessory = this.accessories[aid - 1];
22+
return accessory.jsonForCharacteristicUpdate(aid,iid);
23+
},
24+
processCharacteristicsValueWrite: function processCharacteristicsValueWrite(updates, peer) {
25+
var updates_objects = JSON.parse(updates.toString());
26+
var update_characteristics = updates_objects["characteristics"];
27+
for (var i = 0; i < update_characteristics.length; i++) {
28+
var update_char = update_characteristics[i];
29+
var update_char_aid = update_char["aid"];
30+
var accessory = this.accessories[update_char_aid - 1];
31+
accessory.processSingleCharacteristicsValueWrite(update_char, peer);
32+
}
33+
},
34+
broadcastEvent: function broadcastEvent(data, subscribedPeers, peer) {
35+
if (this.tcpServer !== undefined) {
36+
this.tcpServer.broadcastEvent(data, subscribedPeers, peer);
37+
}
38+
}
39+
}
40+
41+
function BridgedAccessoryController() {
42+
if (!(this instanceof BridgedAccessoryController)) {
43+
return new BridgedAccessoryController();
44+
}
45+
this.accessoryID = 1;
46+
this.accessories = [];
47+
}
48+
49+
module.exports = {
50+
BridgedAccessoryController: BridgedAccessoryController
51+
};

BridgedCore.js

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
var storage = require('node-persist');
2+
3+
var accessory_Factor = new require("./Accessory.js");
4+
var accessoryController_Factor = new require("./AccessoryController.js");
5+
var service_Factor = new require("./Service.js");
6+
var characteristic_Factor = new require("./Characteristic.js");
7+
var bridge_Factor = new require("./BridgedAccessoryController.js");
8+
9+
var targetPort = 51826;
10+
11+
// Get the accessories data
12+
var fs = require('fs');
13+
var path = require('path');
14+
15+
var accessoriesJSON = []
16+
17+
18+
// Get user defined accessories from the accessories folder
19+
// - user defined accessory filenames must end with "_accessory.js"
20+
fs.readdirSync(path.join(__dirname, "accessories")).forEach(function(file) {
21+
if (file.split('_').pop()==="accessory.js") {
22+
accessoriesJSON.push(require("./accessories/" + file).accessory);
23+
};
24+
});
25+
26+
27+
console.log("HAP-NodeJS starting...");
28+
storage.initSync();
29+
30+
var bridgeController = new bridge_Factor.BridgedAccessoryController();
31+
32+
//loop through accessories
33+
for (var i = 0; i < accessoriesJSON.length; i++) {
34+
var accessoryController = new accessoryController_Factor.AccessoryController();
35+
36+
//loop through services
37+
for (var j = 0; j < accessoriesJSON[i].services.length; j++) {
38+
var service = new service_Factor.Service(accessoriesJSON[i].services[j].sType);
39+
40+
//loop through characteristics
41+
for (var k = 0; k < accessoriesJSON[i].services[j].characteristics.length; k++) {
42+
var options = {
43+
type: accessoriesJSON[i].services[j].characteristics[k].cType,
44+
perms: accessoriesJSON[i].services[j].characteristics[k].perms,
45+
format: accessoriesJSON[i].services[j].characteristics[k].format,
46+
initialValue: accessoriesJSON[i].services[j].characteristics[k].initialValue,
47+
supportEvents: accessoriesJSON[i].services[j].characteristics[k].supportEvents,
48+
supportBonjour: accessoriesJSON[i].services[j].characteristics[k].supportBonjour,
49+
manfDescription: accessoriesJSON[i].services[j].characteristics[k].manfDescription,
50+
designedMaxLength: accessoriesJSON[i].services[j].characteristics[k].designedMaxLength,
51+
designedMinValue: accessoriesJSON[i].services[j].characteristics[k].designedMinValue,
52+
designedMaxValue: accessoriesJSON[i].services[j].characteristics[k].designedMaxValue,
53+
designedMinStep: accessoriesJSON[i].services[j].characteristics[k].designedMinStep,
54+
unit: accessoriesJSON[i].services[j].characteristics[k].unit,
55+
}
56+
57+
var characteristic = new characteristic_Factor.Characteristic(options, accessoriesJSON[i].services[j].characteristics[k].onUpdate);
58+
59+
service.addCharacteristic(characteristic);
60+
};
61+
accessoryController.addService(service);
62+
};
63+
bridgeController.addAccessory(accessoryController);
64+
};
65+
66+
var accessory = new accessory_Factor.Accessory("Node Bridge", "CC:22:3D:E3:CE:F1", storage, parseInt(targetPort), "031-45-154", bridgeController);
67+
accessory.publishAccessory();

Characteristic.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ Characteristic.prototype = {
8383
var eventDict = {
8484
characteristics: [
8585
{
86-
aid: this.accessoryID,
86+
aid: this.accessoryController.accessoryID,
8787
iid: this.instanceID,
8888
value: this.value
8989
}

Thermostat_Logical.js

+194
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
var storage = require('node-persist');
2+
var types = require("./accessories/types.js")
3+
4+
var accessory_Factor = new require("./Accessory.js");
5+
var accessoryController_Factor = new require("./AccessoryController.js");
6+
var service_Factor = new require("./Service.js");
7+
var characteristic_Factor = new require("./Characteristic.js");
8+
9+
var targetPort = 51826;
10+
11+
console.log("HAP-NodeJS starting...");
12+
storage.initSync();
13+
14+
var execute = function(accessory,characteristic,value){ console.log("executed accessory: " + accessory + ", and characteristic: " + characteristic + ", with value: " + value + "."); }
15+
16+
var accessoryController = new accessoryController_Factor.AccessoryController();
17+
var infoService = new service_Factor.Service(types.ACCESSORY_INFORMATION_STYPE);
18+
var infoChars = [{
19+
cType: types.NAME_CTYPE,
20+
onUpdate: null,
21+
perms: ["pr"],
22+
format: "string",
23+
initialValue: "Thermostat 1",
24+
supportEvents: false,
25+
supportBonjour: false,
26+
manfDescription: "Bla",
27+
designedMaxLength: 255
28+
},{
29+
cType: types.MANUFACTURER_CTYPE,
30+
onUpdate: null,
31+
perms: ["pr"],
32+
format: "string",
33+
initialValue: "Oltica",
34+
supportEvents: false,
35+
supportBonjour: false,
36+
manfDescription: "Bla",
37+
designedMaxLength: 255
38+
},{
39+
cType: types.MODEL_CTYPE,
40+
onUpdate: null,
41+
perms: ["pr"],
42+
format: "string",
43+
initialValue: "Rev-1",
44+
supportEvents: false,
45+
supportBonjour: false,
46+
manfDescription: "Bla",
47+
designedMaxLength: 255
48+
},{
49+
cType: types.SERIAL_NUMBER_CTYPE,
50+
onUpdate: null,
51+
perms: ["pr"],
52+
format: "string",
53+
initialValue: "A1S2NASF88EW",
54+
supportEvents: false,
55+
supportBonjour: false,
56+
manfDescription: "Bla",
57+
designedMaxLength: 255
58+
},{
59+
cType: types.IDENTIFY_CTYPE,
60+
onUpdate: null,
61+
perms: ["pw"],
62+
format: "bool",
63+
initialValue: false,
64+
supportEvents: false,
65+
supportBonjour: false,
66+
manfDescription: "Identify Accessory",
67+
designedMaxLength: 1
68+
}];
69+
70+
for (var k = 0; k < infoChars.length; k++) {
71+
var options = {
72+
type: infoChars[k].cType,
73+
perms: infoChars[k].perms,
74+
format: infoChars[k].format,
75+
initialValue: infoChars[k].initialValue,
76+
supportEvents: infoChars[k].supportEvents,
77+
supportBonjour: infoChars[k].supportBonjour,
78+
manfDescription: infoChars[k].manfDescription,
79+
designedMaxLength: infoChars[k].designedMaxLength,
80+
designedMinValue: infoChars[k].designedMinValue,
81+
designedMaxValue: infoChars[k].designedMaxValue,
82+
designedMinStep: infoChars[k].designedMinStep,
83+
unit: infoChars[k].unit,
84+
}
85+
86+
var characteristic = new characteristic_Factor.Characteristic(options, null);
87+
88+
infoService.addCharacteristic(characteristic);
89+
};
90+
91+
accessoryController.addService(infoService);
92+
93+
var thermostatService = new service_Factor.Service(types.THERMOSTAT_STYPE);
94+
var thermoNameChar = new characteristic_Factor.Characteristic({
95+
type: types.NAME_CTYPE,
96+
onUpdate: null,
97+
perms: ["pr"],
98+
format: "string",
99+
initialValue: "Thermostat Control",
100+
supportEvents: false,
101+
supportBonjour: false,
102+
manfDescription: "Bla",
103+
designedMaxLength: 255
104+
}, null);
105+
thermostatService.addCharacteristic(thermoNameChar);
106+
107+
var thermoCMChar = new characteristic_Factor.Characteristic({
108+
type: types.CURRENTHEATINGCOOLING_CTYPE,
109+
perms: ["pr","ev"],
110+
format: "int",
111+
initialValue: 0,
112+
supportEvents: false,
113+
supportBonjour: false,
114+
manfDescription: "Current Mode",
115+
designedMaxLength: 1,
116+
designedMinValue: 0,
117+
designedMaxValue: 2,
118+
designedMinStep: 1,
119+
}, null);
120+
thermostatService.addCharacteristic(thermoCMChar);
121+
122+
var thermoTMChar = new characteristic_Factor.Characteristic({
123+
type: types.TARGETHEATINGCOOLING_CTYPE,
124+
perms: ["pw","pr","ev"],
125+
format: "int",
126+
initialValue: 0,
127+
supportEvents: false,
128+
supportBonjour: false,
129+
manfDescription: "Target Mode",
130+
designedMinValue: 0,
131+
designedMaxValue: 3,
132+
designedMinStep: 1,
133+
}, function(value) { console.log("Change:",value); execute("Thermostat", "Target HC", value);
134+
if (value < 3) {thermoCMChar.updateValue(value);} else {thermoCMChar.updateValue(1);};
135+
});
136+
thermostatService.addCharacteristic(thermoTMChar);
137+
138+
var restThermo = [{
139+
cType: types.CURRENT_TEMPERATURE_CTYPE,
140+
onUpdate: function(value) { console.log("Change:",value); execute("Thermostat", "Current Temperature", value); },
141+
perms: ["pr","ev"],
142+
format: "int",
143+
initialValue: 20,
144+
supportEvents: false,
145+
supportBonjour: false,
146+
manfDescription: "Current Temperature",
147+
unit: "celsius"
148+
},{
149+
cType: types.TARGET_TEMPERATURE_CTYPE,
150+
onUpdate: function(value) { console.log("Change:",value); execute("Thermostat", "Target Temperature", value); },
151+
perms: ["pw","pr","ev"],
152+
format: "int",
153+
initialValue: 20,
154+
supportEvents: false,
155+
supportBonjour: false,
156+
manfDescription: "Target Temperature",
157+
designedMinValue: 16,
158+
designedMaxValue: 38,
159+
designedMinStep: 1,
160+
unit: "celsius"
161+
},{
162+
cType: types.TEMPERATURE_UNITS_CTYPE,
163+
onUpdate: function(value) { console.log("Change:",value); execute("Thermostat", "Unit", value); },
164+
perms: ["pr","ev"],
165+
format: "int",
166+
initialValue: 0,
167+
supportEvents: false,
168+
supportBonjour: false,
169+
manfDescription: "Unit",
170+
}];
171+
for (var k = 0; k < restThermo.length; k++) {
172+
var options = {
173+
type: restThermo[k].cType,
174+
perms: restThermo[k].perms,
175+
format: restThermo[k].format,
176+
initialValue: restThermo[k].initialValue,
177+
supportEvents: restThermo[k].supportEvents,
178+
supportBonjour: restThermo[k].supportBonjour,
179+
manfDescription: restThermo[k].manfDescription,
180+
designedMaxLength: restThermo[k].designedMaxLength,
181+
designedMinValue: restThermo[k].designedMinValue,
182+
designedMaxValue: restThermo[k].designedMaxValue,
183+
designedMinStep: restThermo[k].designedMinStep,
184+
unit: restThermo[k].unit,
185+
}
186+
187+
var characteristic = new characteristic_Factor.Characteristic(options, restThermo[k].onUpdate);
188+
189+
thermostatService.addCharacteristic(characteristic);
190+
};
191+
192+
accessoryController.addService(thermostatService);
193+
var accessory = new accessory_Factor.Accessory("Thermostat 1", "CA:3E:BC:4D:5E:FF", storage, parseInt(targetPort), "031-45-154", accessoryController);
194+
accessory.publishAccessory();

0 commit comments

Comments
 (0)