2727const { createLogger, format } = require ( 'winston' ) ;
2828const logform = require ( 'logform' ) ;
2929const { combine, timestamp, label, printf } = logform . format ;
30+
3031var winston = require ( 'winston' ) ,
3132 daily = require ( 'winston-daily-rotate-file' ) ,
3233 express = require ( 'express' ) ,
@@ -43,20 +44,10 @@ var winston = require('winston'),
4344 mqttWildcard = require ( 'mqtt-wildcard' ) ,
4445 request = require ( 'request' ) ,
4546 path = require ( 'path' ) ,
47+
4648 CONFIG_DIR = process . env . CONFIG_DIR || path . join ( __dirname , 'config' ) ,
4749 SAMPLE_FILE = path . join ( CONFIG_DIR , '_config.yml' ) ,
48- CONFIG_FILE = path . join ( CONFIG_DIR , 'config.yml' ) ;
49-
50- function loadConfiguration ( ) {
51- if ( ! fs . existsSync ( CONFIG_FILE ) ) {
52- console . log ( 'No previous configuration found, creating one' ) ;
53- fs . writeFileSync ( CONFIG_FILE , fs . readFileSync ( SAMPLE_FILE ) ) ;
54- }
55-
56- return yaml . safeLoad ( fs . readFileSync ( CONFIG_FILE ) ) ;
57- }
58-
59- var config = loadConfiguration ( ) ,
50+ CONFIG_FILE = path . join ( CONFIG_DIR , 'config.yml' ) ,
6051 DEVICE_CONFIG_FILE = path . join ( CONFIG_DIR , 'devices.yml' ) ,
6152 STATE_FILE = path . join ( CONFIG_DIR , 'data' , 'state.json' ) ,
6253 STATE_SUMMARY_FILE = path . join ( CONFIG_DIR , 'data' , 'state.summary.json' ) ,
@@ -71,20 +62,21 @@ var config = loadConfiguration(),
7162 TOPIC_WRITE_STATE = 'set_state' ,
7263 SUFFIX_WRITE_STATE = 'state_write_suffix' ,
7364 RETAIN = 'retain' ,
74- LOGGING_LEVEL = config . loglevel ;
65+ config = loadConfiguration ( ) ,
66+ LOGGING_LEVEL = config . loglevel ,
7567
76- var app = express ( ) ,
68+ app = express ( ) ,
7769 client ,
7870 subscriptions = [ ] ,
7971 publications = { } ,
8072 subscribe = { } ,
8173 callback = '' ,
8274 devices = { } ,
8375 st_request = { } ,
84- history = { } ;
76+ history = { } ,
8577
86- // winston transports
87- var consoleLog = new winston . transports . Console ( ) ,
78+ // winston transports
79+ consoleLog = new winston . transports . Console ( ) ,
8880 eventsLog = new ( winston . transports . DailyRotateFile ) ( {
8981 filename : path . join ( CONFIG_DIR , 'log' , 'events-%DATE%.log' ) ,
9082 datePattern : 'YYYY-MM-DD' ,
@@ -109,10 +101,6 @@ var consoleLog = new winston.transports.Console(),
109101 logFormat = combine ( format . splat ( ) ,
110102 timestamp ( { format :( new Date ( ) ) . toLocaleString ( 'en-US' ) , format : 'YYYY-MM-DD HH:mm:ss A' } ) ,
111103 printf ( nfo => { return `${ nfo . timestamp } ${ nfo . level } : ${ nfo . message } ` ; } )
112- ) ,
113- appFormat = combine ( format . splat ( ) , format . json ( ) ,
114- timestamp ( { format :( new Date ( ) ) . toLocaleString ( 'en-US' ) , format : 'YYYY-MM-DD HH:mm:ss A' } ) ,
115- printf ( nfo => { return `${ nfo . timestamp } ${ nfo . level } : ${ JSON . stringify ( nfo . meta ) } )` ; } )
116104 ) ;
117105
118106
@@ -123,6 +111,15 @@ winston = createLogger({
123111 transports : [ eventsLog , consoleLog ]
124112} ) ;
125113
114+
115+ function loadConfiguration ( ) {
116+ if ( ! fs . existsSync ( CONFIG_FILE ) ) {
117+ console . log ( 'No previous configuration found, creating one' ) ;
118+ fs . writeFileSync ( CONFIG_FILE , fs . readFileSync ( SAMPLE_FILE ) ) ;
119+ }
120+ return yaml . safeLoad ( fs . readFileSync ( CONFIG_FILE ) ) ;
121+ }
122+
126123/**
127124 * Load device configuration if it exists
128125 * @method loadDeviceConfiguration
@@ -136,14 +133,14 @@ function loadDeviceConfiguration () {
136133 output = yaml . safeLoad ( fs . readFileSync ( DEVICE_CONFIG_FILE ) ) ;
137134 } catch ( ex ) {
138135 winston . error ( ex ) ;
139- winston . info ( 'No external device configurations found , continuing' ) ;
136+ winston . info ( 'ERROR loading external device configurations, continuing' ) ;
140137 return ;
141138 }
142139 Object . keys ( output ) . forEach ( function ( device ) {
143140 winston . debug ( "Loading config for Device " , device ) ;
144141 Object . keys ( output [ device ] [ "subscribe" ] ) . forEach ( function ( attribute ) {
145142 Object . keys ( output [ device ] [ "subscribe" ] [ attribute ] ) . forEach ( function ( sub ) {
146- var data = { } ;
143+ let data = { } ;
147144 data [ 'device' ] = device ;
148145 data [ 'attribute' ] = attribute ;
149146 if ( ( ! ! output [ device ] [ "subscribe" ] [ attribute ] [ sub ] ) && ( ! ! output [ device ] [ "subscribe" ] [ attribute ] [ sub ] [ 'command' ] ) )
@@ -316,13 +313,13 @@ function handlePushEvent (req, res) {
316313function mqttPublish ( device , attribute , topic , value , retain , res ) {
317314 history [ topic ] = value ;
318315 if ( ( ! ! publications ) && ( ! publications [ topic ] ) ) {
319- var data = { } ;
316+ let data = { } ;
320317 data [ 'device' ] = device ;
321318 data [ 'attribute' ] = attribute ;
322319 data [ 'command' ] = value ;
323320 publications [ topic ] = { } ;
324321 publications [ topic ] [ device ] = data ;
325- }
322+ } else if ( ! ! publications [ topic ] [ device ] ) publications [ topic ] [ device ] [ 'command' ] = value ;
326323 var sub = isSubscribed ( topic ) ;
327324 if ( ( ! ! subscribe ) && ( ! ! subscribe [ sub ] ) && ( ! ! subscribe [ sub ] [ device ] ) && ( ! ! subscribe [ sub ] [ device ] [ attribute ] ) ) {
328325 winston . warn ( 'POSSIBLE LOOP. Device[Attribute] %s[%s] is publishing to Topic %s while subscribed to Topic %s' , device , attribute , topic , sub ) ;
@@ -348,14 +345,14 @@ function mqttPublish(device, attribute, topic, value, retain, res){
348345 */
349346function handleSubscribeEvent ( req , res ) {
350347 // Subscribe to all events
351- var oldsubscriptions = subscriptions ;
348+ let oldsubscriptions = subscriptions ;
352349 st_request = req . body . devices ;
353350 processSubscriptions ( st_request ) ;
354351 // Store callback
355352 callback = req . body . callback ;
356353 // Store current state on disk
357354 saveState ( ) ;
358- var unsubs = comparearrays ( subscriptions , oldsubscriptions ) ,
355+ let unsubs = comparearrays ( subscriptions , oldsubscriptions ) ,
359356 subs = comparearrays ( oldsubscriptions , subscriptions ) ;
360357 if ( ( ! ! unsubs ) && ( unsubs . length > 0 ) ) client . unsubscribe ( unsubs ) ;
361358 if ( ( ! ! subs ) && ( subs . length > 0 ) ) {
@@ -379,18 +376,18 @@ function processSubscriptions(req){
379376 req [ property ] . forEach ( function ( device ) {
380377 winston . debug ( ' %s - %s ' , property , device ) ;
381378 // CRITICAL - if device in DEVICE_CONFIG_FILE, file sub/pub info will supercedes
382- if ( ( ! ! devices [ device ] ) ) {
379+ if ( ! ! devices && ( ! ! devices [ device ] ) ) {
383380 if ( ( ! ! devices [ device ] [ "subscribe" ] ) && ( ! ! devices [ device ] [ "subscribe" ] [ property ] ) ) {
384381 Object . keys ( devices [ device ] [ "subscribe" ] [ property ] ) . forEach ( function ( sub ) {
385382 if ( ! subscriptions . includes ( sub ) ) subscriptions . push ( sub ) ;
386383 winston . debug ( 'Subscribing[CUSTOM] ' , sub ) ;
387384 } ) ;
388385 }
389386 } else {
390- var data = { } ;
387+ let data = { } ;
391388 data [ 'device' ] = device ;
392389 data [ 'attribute' ] = property ;
393- var sub = getTopicFor ( device , property , TOPIC_COMMAND ) ;
390+ let sub = getTopicFor ( device , property , TOPIC_COMMAND ) ;
394391 if ( ! subscriptions . includes ( sub ) ) subscriptions . push ( sub ) ;
395392 if ( ! subscribe [ sub ] ) subscribe [ sub ] = { } ;
396393 if ( ! subscribe [ sub ] [ device ] ) subscribe [ sub ] [ device ] = { } ;
@@ -413,7 +410,7 @@ function processSubscriptions(req){
413410function comparearrays ( arr1 , arr2 ) {
414411 if ( ! arr2 ) return null ;
415412 if ( ! arr1 ) return arr2 ;
416- var newarray = [ ] ;
413+ let newarray = [ ] ;
417414 arr2 . forEach ( function ( sub ) {
418415 if ( ! arr1 . includes ( sub ) ) newarray . push ( sub ) ;
419416 } ) ;
@@ -456,9 +453,8 @@ function getTopicFor (device, property, type) {
456453 */
457454function isSubscribed ( topic ) {
458455 if ( ! subscriptions ) return null ;
459- var topics = [ ]
460- var i ;
461- for ( i = 0 ; i < subscriptions . length ; i ++ ) {
456+ var topics = [ ] ;
457+ for ( let i = 0 ; i < subscriptions . length ; i ++ ) {
462458 if ( subscriptions [ i ] == topic ) {
463459 topics . push ( subscriptions [ i ] ) ;
464460 } else if ( mqttWildcard ( topic , subscriptions [ i ] ) != null ) topics . push ( subscriptions [ i ] ) ;
@@ -576,7 +572,6 @@ function postRequest(topic, contents, device, property, value, cmd, incoming){
576572async . series ( [
577573 function loadFromDisk ( next ) {
578574 var state ;
579-
580575 winston . info ( 'Starting SmartThings MQTT Bridge - v%s' , CURRENT_VERSION ) ;
581576 winston . info ( 'Configuration Directory - %s' , CONFIG_DIR ) ;
582577 winston . info ( 'Loading configuration' ) ;
@@ -589,8 +584,14 @@ async.series([
589584 st_request = state . st_request ;
590585 history = state . history ;
591586 if ( ! ! st_request ) {
592- winston . info ( 'request object - %s' , st_request ) ;
593- processSubscriptions ( st_request ) ;
587+ try {
588+ winston . info ( 'Last Request from ST - %s' , JSON . stringify ( st_request ) ) ;
589+ processSubscriptions ( st_request ) ;
590+ } catch ( ex ) {
591+ winston . error ( ex ) ;
592+ winston . info ( 'Could not restore subscriptions. Please rebuscribe in IDE, continuing' ) ;
593+ return ;
594+ }
594595 }
595596 saveState ( ) ;
596597 process . nextTick ( next ) ;
@@ -628,11 +629,12 @@ async.series([
628629 app . use ( bodyparser . json ( ) ) ;
629630
630631 // Log all requests to disk
631- app . use ( expressWinston . logger ( createLogger ( {
632- format : appFormat ,
632+ app . use ( expressWinston . logger ( {
633+ format : logFormat ,
634+ msg : "HTTP /{{req.method}} {{req.url}} host={{req.hostname}} --> Status Code={{res.statusCode}} ResponseTime={{res.responseTime}}ms" ,
633635 transports : [ accessLog ]
634- } ) ) ) ;
635-
636+ } ) ) ;
637+
636638 // Push event from SmartThings
637639 app . post ( '/push' ,
638640 expressJoi . body ( joi . object ( {
@@ -652,10 +654,11 @@ async.series([
652654 } ) ) , handleSubscribeEvent ) ;
653655
654656 // Log all errors to disk
655- app . use ( expressWinston . errorLogger ( createLogger ( {
656- format : appFormat ,
657- transports : [ errorLog ]
658- } ) ) ) ;
657+ app . use ( expressWinston . errorLogger ( {
658+ format : logFormat ,
659+ msg : " [{{res.statusCode}} {{req.method}}] {{err.message}}\n{{err.stack}}" ,
660+ transports : [ errorLog , consoleLog ]
661+ } ) ) ;
659662
660663 // Proper error messages with Joi
661664 app . use ( function ( err , req , res , next ) {
0 commit comments