HueStreamMessage.js
2.64 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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
'use strict';
const ApiError = require('../../ApiError')
;
const HEADER_BYTE_LENGTH = 16
, LIGHT_SLOT_DATA_BYTE_LENGTH = 9
;
const PROTOCOL = Buffer.from('HueStream', 'ascii');
module.exports = class HueStreamMessage {
constructor() {
}
rgbMessage(lightToRGB) {
const data = [getRGBHeader()];
let lightCount = 0;
Object.keys(lightToRGB).forEach(id => {
data.push(mapLightsToRGB(id, lightToRGB[id]));
lightCount++;
});
const length = HEADER_BYTE_LENGTH + (LIGHT_SLOT_DATA_BYTE_LENGTH * lightCount)
, result = Buffer.concat(data, length)
;
console.log(result);
return result;
}
//TODO
// xyMessage(lightToXY) {
//
// }
};
function convert(num) {
const arr = new ArrayBuffer(9)
, view = new DataView(arr);
view.setUint16(0, num, false);
return arr;
}
function mapLightsToRGB(id, rgb) {
const arr = new ArrayBuffer(9)
, view = new DataView(arr)
;
let offset = 0;
// 0 byte is 0x00 = Light
view.setUint8(offset, 0);
offset += 1;
// 2 byte is the light id
view.setUint16(offset, id);
offset += 2;
// 3x 2 byte representation of rgb
view.setUint16(offset, convertRGBValue(rgb[0]));
offset += 2;
view.setUint16(offset, convertRGBValue(rgb[1]));
offset += 2;
view.setUint16(offset, convertRGBValue(rgb[2]));
return Buffer.from(arr);
}
function convertRGBValue(val) {
if (val < 0 || val > 255) {
throw new ApiError(`Invalid RGB value: ${val}`);
}
if (val === 0) {
return 0;
} else {
return parseInt((val / 255) * 65535);
}
}
function convertXYValue(val) {
if (val < 0 || val > 1) {
throw new ApiError(`Invalid XY value: ${val}`);
}
if (val === 0) {
return 0;
} else if (val === 1) {
return 65535;
} else {
return parseInt(65535 * val);
}
}
function convertBrightness(val) {
if (val < 1 || val > 254) {
throw new ApiError(`Invalid Brightness value: ${val}`);
}
return parseInt((val / 254) * 65535);
}
function getRGBHeader() {
return getHeader(0x00);
}
function getXYHeader() {
return getHeader(0x01);
}
function getHeader(colorSpaceByte) {
const headerPayload = Buffer.from([
// Version
0x01,
0x00,
// Sequence ID (ignored)
0x07,
// Reserved
0x00,
0x00,
// Color Space
colorSpaceByte,
// Reserved
0x00,
]);
return Buffer.concat([PROTOCOL, headerPayload], HEADER_BYTE_LENGTH);
}
function getColorSpaceByte(colorSpace) {
if (colorSpace === 'RGB' || colorSpace === 'rgb') {
return 0x00;
} else if (colorSpace === 'xy' || 'XY') {
return 0x01;
} else {
throw new ApiError(`Invalid colorSpace type provided: ${colorSpace}`);
}
}