@@ -3,6 +3,14 @@ const Gpio = require('onoff').Gpio;
3
3
const http = require ( 'http' ) ;
4
4
const fork = require ( 'child_process' ) . fork ;
5
5
const path = require ( 'path' ) ;
6
+ const storage = require ( 'node-persist' ) ;
7
+ const {
8
+ bridgeIp,
9
+ userId,
10
+ aPin, bPin, togglePin
11
+ } = require ( './config.json' ) ;
12
+
13
+ const FIELDS = { 'bri' : 8 , 'hue' : 1024 , 'sat' : 8 } ;
6
14
7
15
class RotaryEncoder extends EventEmitter {
8
16
constructor ( { a, b, toggle} ) {
@@ -189,101 +197,131 @@ class Worker {
189
197
}
190
198
}
191
199
192
- let groupState = null ;
193
-
194
-
195
200
class LightGroupController {
196
201
constructor ( groupId , api , worker ) {
197
202
this . groupId = groupId ;
198
203
this . api = api ;
199
204
this . worker = worker ;
200
205
this . groupState = null ;
206
+ this . fieldIndex = 0 ;
201
207
}
202
208
203
- refresh ( ) {
204
- return this . api . getGroup ( this . groupId ) . then ( ( { statusCode, body} ) => {
205
- this . groupState = body . action ;
206
- this . worker . send ( 'lightgroup_control' , body . action ) ;
207
- return this . groupState ;
208
- } ) ;
209
+ async init ( ) {
210
+ const { statusCode, body} = await this . api . getGroup ( this . groupId ) ;
211
+ this . groupState = body . action ;
212
+ this . worker . send ( 'lightgroup_control' , body . action ) ;
213
+ return this . groupState ;
209
214
}
210
- update ( change ) {
211
- if ( this . groupState ) {
212
- Object . keys ( change ) . forEach ( k => {
213
- if ( typeof change [ k ] === 'number' ) {
214
- this . groupState [ k ] += change [ k ]
215
- } else {
216
- this . groupState [ k ] = change [ k ]
217
- }
218
- } ) ;
219
- this . worker . send ( 'lightgroup_control' , this . groupState ) ;
220
- }
221
215
222
- return this . api . putGroup ( this . groupId , Object . keys ( change ) . reduce ( ( prev , next ) => {
223
- const value = change [ next ] ;
224
- prev [ next + ( typeof value === 'number' ? '_inc' : '' ) ] = value ;
225
- return prev ;
226
- } , { } ) ) . then ( response => {
227
- this . refresh ( ) ;
228
- } ) ;
216
+ async onEvent ( event , args ) {
217
+ switch ( event ) {
218
+ case 'rotation' : {
219
+ const field = Object . keys ( FIELDS ) [ this . fieldIndex ] ;
220
+ const change = {
221
+ [ field ] : FIELDS [ field ] * args ,
222
+ 'on' : true
223
+ } ;
224
+ if ( this . groupState ) {
225
+ Object . keys ( change ) . forEach ( k => {
226
+ if ( typeof change [ k ] === 'number' ) {
227
+ this . groupState [ k ] += change [ k ]
228
+ } else {
229
+ this . groupState [ k ] = change [ k ]
230
+ }
231
+ } ) ;
232
+ this . worker . send ( 'lightgroup_control' , this . groupState ) ;
233
+ }
234
+
235
+ const response = await this . api . putGroup ( this . groupId , Object . keys ( change ) . reduce ( ( prev , next ) => {
236
+ const value = change [ next ] ;
237
+ prev [ next + ( typeof value === 'number' ? '_inc' : '' ) ] = value ;
238
+ return prev ;
239
+ } , { } ) ) ;
240
+ await this . init ( ) ;
241
+ break ;
242
+ }
243
+
244
+ case 'toggle' : {
245
+ this . fieldIndex ++ ;
246
+ if ( this . fieldIndex >= Object . keys ( FIELDS ) . length ) {
247
+ this . fieldIndex = 0 ;
248
+ }
249
+ break ;
250
+ }
251
+ }
229
252
}
230
253
}
231
254
232
- const BRIDGE = '192.168.0.4' ;
233
- const USER_ID = 'O7nK3Cv1WUSGeOtiuzWbPCsxbjxCdIwmRFWPo72Z' ;
234
- const GROUP_ID = 8 ;
235
- const FIELDS = { 'bri' : 8 , 'hue' : 1024 , 'sat' : 8 } ;
236
-
237
- const api = new HueAPI ( BRIDGE , USER_ID ) ;
255
+ class LightGroupSelector {
256
+ constructor ( api , uiWorker ) {
257
+ this . api = api ;
258
+ this . worker = uiWorker ;
259
+ this . selected = 0 ;
238
260
239
- const uiWorker = new Worker ( ) ;
261
+ }
262
+ async init ( ) {
263
+ const response = await this . api . getGroups ( ) ;
264
+ this . options = Object . keys ( response . body ) . map ( i => ( { key : parseInt ( i , 10 ) , value : response . body [ i ] . name } ) ) ;
265
+ this . worker . send ( 'lightgroup_select' , {
266
+ selected : this . selected ,
267
+ options : this . options
268
+ } ) ;
269
+ }
240
270
241
- api . getGroups ( ) . then ( ( response ) => uiWorker . send ( 'lightgroup_select' , {
242
- selected : 0 ,
243
- options : Object . keys ( response . body ) . map ( i => response . body [ i ] . name )
244
- } ) ) ;
245
- /**
271
+ async onEvent ( event , args ) {
272
+ switch ( event ) {
273
+ case 'rotation' : {
274
+ this . selected += ( args > 0 ? 1 : - 1 ) ;
275
+ if ( this . selected >= this . options . length ) {
276
+ this . selected = this . options . length - 1 ;
277
+ } else if ( this . selected < 0 ) {
278
+ this . selected = 0 ;
279
+ }
280
+ this . worker . send ( 'lightgroup_select' , {
281
+ selected : this . selected ,
282
+ options : this . options
283
+ } ) ;
284
+ break ;
285
+ }
246
286
287
+ case 'toggle' : {
288
+ const groupId = this . options [ this . selected ] . key ;
289
+ console . log ( 'Selected groupId: ' + groupId ) ;
290
+ await storage . setItem ( 'groupId' , groupId ) ;
291
+ const newController = new LightGroupController ( groupId , this . api , this . worker ) ;
292
+ await newController . init ( ) ;
293
+ controller = newController ;
294
+ break ;
295
+ }
296
+ }
297
+ }
298
+ }
247
299
248
- const controller = new LightGroupController(GROUP_ID, api, uiWorker) ;
300
+ let controller = null ;
249
301
250
- controller.refresh().then((state) => {
251
- let fieldIndex = 0;
302
+ storage . init ( ) . then ( async ( ) => {
303
+ const api = new HueAPI ( bridgeIp , userId ) ;
304
+ const uiWorker = new Worker ( ) ;
305
+ const encoder = new RotaryEncoder ( {
306
+ a : aPin ,
307
+ b : bPin ,
308
+ toggle : togglePin
309
+ } ) ;
252
310
253
- const encoder = new RotaryEncoder({
254
- a: 17,
255
- b: 18,
256
- toggle: 27,
257
- inc: 32
258
- });
311
+ const groupId = await storage . getItem ( 'groupId' ) ;
312
+ if ( ! groupId ) {
313
+ controller = new LightGroupSelector ( api , uiWorker ) ;
314
+ } else {
315
+ console . log ( 'Controlling groupId: ' + groupId ) ;
316
+ controller = new LightGroupController ( groupId , api , uiWorker ) ;
317
+ }
318
+ await controller . init ( ) ;
259
319
260
- encoder.on('rotation', throttlePromise((value) => {
261
- const field = Object.keys(FIELDS)[fieldIndex];
262
- const change = FIELDS[field] * value;
263
- return controller.update({
264
- [field]: change,
265
- 'on': true
266
- });
267
- }, {
268
- debounce: 10,
320
+ encoder . on ( 'rotation' , throttlePromise ( ( value ) => controller . onEvent ( 'rotation' , value ) , {
321
+ debounce : 100 ,
269
322
delay : 500 ,
270
323
reduce : ( prev , next ) => [ prev [ 0 ] + next [ 0 ] ]
271
324
} ) ) ;
272
325
273
- encoder.on('toggle',() => {// throttlePromise(() => {
274
- fieldIndex++;
275
- if (fieldIndex >= Object.keys(FIELDS).length) {
276
- fieldIndex = 0;
277
- }
278
- console.log('Selected ' + Object.keys(FIELDS)[fieldIndex]);
279
- /**
280
- on = !on;
281
- return api.putGroup(GROUP_ID, {
282
- on: on
283
- }).then(response => {
284
- console.log(response.body);
285
- return updateGroupUI();
286
- });
287
- });
326
+ encoder . on ( 'toggle' , ( ) => controller . onEvent ( 'toggle' ) ) ;
288
327
} ) ;
289
- */
0 commit comments