From 3ad8714932f4a66198658d40d1e11b7f435b1f55 Mon Sep 17 00:00:00 2001 From: Thomas Kluge Date: Tue, 7 Mar 2017 19:18:29 +0100 Subject: [PATCH] all changes for npm distribution --- install_raspberrymatic.sh | 1 + lib/HomematicLogicLayer.js | 35 +- lib/HomematicVirtualPlatform.js | 7 + lib/Installer.js | 11 + lib/Localization.js | 14 + lib/Server.js | 416 +++++++++++++++--- lib/VirtualDevicePlugin.js | 11 +- package.json | 5 +- plugins/Alexa/AlexaPlatform.js | 15 +- plugins/Alexa/package.json | 23 +- .../service/AlexaHarmonyActivityService.js | 2 +- .../service/AlexaHarmonyDeviceService.js | 2 +- .../service/AlexaHomematicDimmerService.js | 2 +- .../AlexaHomematicHMIPDimmerService.js | 2 +- .../AlexaHomematicHMIPSwitchService.js | 2 +- .../AlexaHomematicHMIPThermostatService.js | 2 +- .../service/AlexaHomematicProgramService.js | 2 +- .../service/AlexaHomematicSwitchService.js | 2 +- .../AlexaHomematicThermostatService.js | 2 +- .../AlexaHomematicWiredDimmerService.js | 2 +- .../AlexaHomematicWiredSwitchService.js | 2 +- plugins/Alexa/service/AlexaHueSceneService.js | 2 +- plugins/Alexa/service/AlexaHueService.js | 2 +- plugins/Alexa/service/AlexaLogicService.js | 2 +- plugins/Alexa/service/AlexaSonosService.js | 2 +- plugins/Alexa/service/GenericService.js | 3 +- plugins/CCUDutyCycle/package.json | 6 +- plugins/HttpPlugin/HttpPlatform.js | 4 + plugins/HttpPlugin/package.json | 2 +- plugins/HuePlugin/HueColorDevice.js | 1 - plugins/HuePlugin/HueEffectServer.js | 21 +- plugins/HuePlugin/HuePlatform.js | 36 +- plugins/HuePlugin/HueSFXDevice.js | 11 +- plugins/HuePlugin/package.json | 4 +- plugins/LogicPlugin/LogicalPlatform.js | 31 +- plugins/LogicPlugin/package.json | 21 +- plugins/LogitechHarmony/package.json | 4 +- plugins/NetAtmoPlugin/package.json | 17 +- plugins/SonosPlugin/SonosPlatform.js | 5 +- plugins/SonosPlugin/package.json | 2 +- plugins/SonosPlugin/www/de-de/index.html | 2 +- plugins/SonosPlugin/www/index.html | 60 ++- rc.d/hvl | 19 +- www/de-de/index.html | 19 +- www/de-de/plugin_item.html | 18 + www/de-de/plugins.html | 164 +++++++ www/index.html | 22 +- www/plugin_item.html | 18 + www/plugins.html | 172 ++++++++ 49 files changed, 1068 insertions(+), 162 deletions(-) create mode 100644 www/de-de/plugin_item.html create mode 100644 www/de-de/plugins.html create mode 100644 www/plugin_item.html create mode 100644 www/plugins.html diff --git a/install_raspberrymatic.sh b/install_raspberrymatic.sh index 22eea59..dec1b78 100644 --- a/install_raspberrymatic.sh +++ b/install_raspberrymatic.sh @@ -88,6 +88,7 @@ cat > /usr/local/etc/config/hvl/config.json <-1) { + logger.info("My Interface Name at your CCU is %s",ipcelement.name[0]) + that.ccuInterfaceName = ipcelement.name[0]; + } + }) + + } else { + logger.error("Cannot fetch my Name from CCU .. %s",JSON.stringify(xmlresult[0])) + } + } + }); +}); + +} HomematicLogicalLayer.prototype.getIPAddress = function() { var interfaces = require("os").networkInterfaces(); diff --git a/lib/HomematicVirtualPlatform.js b/lib/HomematicVirtualPlatform.js index 29c020d..d4bf289 100644 --- a/lib/HomematicVirtualPlatform.js +++ b/lib/HomematicVirtualPlatform.js @@ -38,4 +38,11 @@ HomematicVirtualPlatform.prototype.restart = function() { } + +HomematicVirtualPlatform.prototype.getPluginVersion = function() { + var pjPath = path.join(__dirname, './package.json'); + var pj = JSON.parse(fs.readFileSync(pjPath)); + return pj.version; +} + module.exports = HomematicVirtualPlatform; diff --git a/lib/Installer.js b/lib/Installer.js index 5299c78..60b83d2 100644 --- a/lib/Installer.js +++ b/lib/Installer.js @@ -4,6 +4,7 @@ var path = require('path'); var Installer = function(rootpath,main) { var pjson = null; this.rootPath = rootpath; + this.isNPM = false var pjsonPath = path.join(rootpath, "package.json"); if (fs.existsSync(pjsonPath)) { try { @@ -12,6 +13,14 @@ var Installer = function(rootpath,main) { } catch (e) { throw new Error("Path " + rootpath + " contains an invalid package.json. Error: " + err); } + // check if we run as npm module + + if (pjson._npmVersion) { + this.isNPM = true + this.needsInstall = [] + this.dependencies = {} + return + } if (!main) { if (pjson != null) { @@ -49,6 +58,7 @@ var Installer = function(rootpath,main) { Installer.prototype.checkVersions = function() { var that = this + if (this.dependencies) { Object.keys(this.dependencies).forEach(function (dependency) { try { var buffer = fs.readFileSync(path.join(that.rootPath , "node_modules" , dependency ,"package.json")); @@ -61,6 +71,7 @@ Installer.prototype.checkVersions = function() { console.error(e) } }); + } } Installer.prototype.installDependencies = function() { diff --git a/lib/Localization.js b/lib/Localization.js index fd495c7..55387ff 100644 --- a/lib/Localization.js +++ b/lib/Localization.js @@ -32,6 +32,20 @@ module.exports = function (strings) { this.language = dispatched_request.language; } + + module.getLanguage = function () { + return this.language; + } + + module.getLocalizedStringFromModuleJSON = function (element) { + if (element[this.language]) { + return element[this.language] + } else { + return element['en-en'] + } + } + + module.localize = function (input) { var result = input; if (module.string_obj) { diff --git a/lib/Server.js b/lib/Server.js index cad6ddf..e154319 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -42,19 +42,19 @@ Server.prototype.init = function() { if (this.configuration.getValue('enable_debug') === true) { require(__dirname + '/logger.js').setDebugEnabled(true) } - + + this.configuratedPlugins = [] this.configServer = new ConfigServer(this.configuration) this.homematicChannel = HomematicChannel this.homematicDevice = HomematicDevice - this.configuratedPlugins = [] - this.activePlugins = [] this.updateResult this.myPathHandler=['/','/index.html','/index/','/settings/','/install/','/device/','/plugins/'] - + this.npmCommand = this.configuration.getValueWithDefault("npm_command","npm"); this.localization = require(__dirname + '/Localization.js')(__dirname + '/Localizable.strings') this.hm_layer = new HomematicLogicalLayer(this.configuration) this.hm_layer.init() - this.plugins = this._loadPlugins() + this.cachedPluginList = [] + this.reloadPlugins() this.configServer.on('config_server_http_event' , function (dispatched_request) { var requesturl = dispatched_request.request.url @@ -84,6 +84,19 @@ Server.prototype.init = function() { }, 3600000) } +Server.prototype.reloadPlugins = function() { + logger.info('Reload .. shutdown all plugins') + this.configuratedPlugins.forEach(function (plugin){ + + plugin.platform.shutdown() + + }) + + this.activePlugins = [] + this.configuratedPlugins = [] + this.plugins = this._loadPlugins() +} + Server.prototype.cleanLog = function() { var LoggerQuery = require(__dirname + '/logger.js').LoggerQuery new LoggerQuery("").clean(5) @@ -163,7 +176,9 @@ Server.prototype.handleConfigurationRequest = function(dispatched_request) { this.configuratedPlugins.forEach(function (plugin){ pluginString = pluginString + '
  • ' + plugin.name + '
  • ' - var hazSettings = (typeof(plugin.platform.showSettings) === 'function') + //var hazSettings = (typeof(plugin.platform.showSettings) === 'function') + + var hazSettings = true var pversion = that.getVersion(plugin) pluginSettings = pluginSettings + dispatched_request.fillTemplate((hazSettings === true) ? plugin_settings_template:plugin_no_settings_template, {'plugin.name':plugin.name, @@ -252,16 +267,18 @@ Server.prototype.handleConfigurationRequest = function(dispatched_request) { break case '/index/?enabledebug': - this.configuration.aetValue('enable_debug',true) + this.configuration.setValue('enable_debug',true) break case '/index/?disabledebug': - this.configuration.aetValue('enable_debug',false) + this.configuration.setValue('enable_debug',false) break case '/index/?restart': - this.restart() + setTimeout(function(){ + that.restart() + }, 2000); dispatched_request.dispatchFile(null,'restart.html',this.addDefaultIndexAttributes({'message':'Rebooting','link':'#'})) cfg_handled = true break @@ -295,7 +312,6 @@ Server.prototype.handleConfigurationRequest = function(dispatched_request) { var plugin = parsed.query['plugin'] try { this.installPlugin(plugin,function(error){ - that.plugins = that._loadPlugins() dispatched_request.dispatchMessage('{"result":'+(error)?'true':'false'+'}') }) } catch (e) { @@ -307,21 +323,87 @@ Server.prototype.handleConfigurationRequest = function(dispatched_request) { if (parsed.pathname === '/plugins/') { - + if ((parsed.query['do']) && (parsed.query['plugin'])) { + + var plgtp = parsed.query['plugin'] + + switch (parsed.query['do']) { + + case "activate": + that.activatePlugin(plgtp) + dispatched_request.dispatchMessage('{"result":"true"}') + break; + + case "deactivate": + that.deactivatePlugin(plgtp) + dispatched_request.dispatchMessage('{"result":"true"}') + break; + + case "refresh": + that.refreshPluginList(); + dispatched_request.dispatchMessage('{"result":"true"}') + break; + + case "update": + var updateList = [] + + if (plgtp!='all') { + logger.info("Updating %s",plgtp) + var pobj = that.pluginWithType(plgtp); + if (pobj) { + pobj.npm = plgtp + updateList.push(pobj) + that.doNPMUpdate(updateList) + that.reloadPlugins() + } else { + logger.error("Update Object for %s not found",plgtp) + } + dispatched_request.dispatchMessage('{"result":"true"}') + } else { + logger.info("Updating all plugins") + this.fetchPluginList(function(error,lresult) { + logger.debug("Plugin list %s",lresult) + lresult.some(function (pluginObject){ + if (pluginObject.installed) { + updateList.push(pluginObject) + } + }) + that.doNPMUpdate(updateList) + that.reloadPlugins() + dispatched_request.dispatchMessage('{"result":"true"}') + }) + } + + + + break; + + case "version": + that.fetch_npmVersion(plgtp,function (centralVersion){ + logger.debug("Get Version for %s result %s",plgtp,centralVersion) + dispatched_request.dispatchMessage('{"result":"'+ centralVersion +'"}') + }) + break; + } + cfg_handled = true + } else { + // generate a List var plugin_template = dispatched_request.getTemplate(null , 'plugin_item.html',null) var result = '' this.fetchPluginList(function(error,lresult) { if (error==null) { + that.cachedPluginList = lresult lresult.some(function (pluginObject){ + var description = that.localization.getLocalizedStringFromModuleJSON(pluginObject.description) result = result + dispatched_request.fillTemplate(plugin_template, {'plugin.type':pluginObject.name, 'plugin.installed':(pluginObject.installed)?'[X]':'[ ]', 'plugin.active':(pluginObject.active)?'[X]':'[ ]', - 'plugin.description':(pluginObject.description.de) || '', + 'plugin.description': description || '', 'plugin.installbutton':(pluginObject.installed)? 'disabled="disabled"':'', - 'plugin.activatebutton':(pluginObject.active)? 'disabled="disabled"':'', + 'plugin.activatebutton':((pluginObject.active) || (!pluginObject.installed)) ? 'disabled="disabled"':'', 'plugin.version':(pluginObject.version) || 'unknow version', 'plugin.removebutton':(pluginObject.active)? '':'disabled="disabled"', 'plugin.npm':pluginObject.npm }) @@ -332,6 +414,8 @@ Server.prototype.handleConfigurationRequest = function(dispatched_request) { dispatched_request.dispatchFile(null,'plugins.html',that.addDefaultIndexAttributes({'plugins':result})) }) cfg_handled = true + } + } @@ -389,17 +473,31 @@ Server.prototype.handleConfigurationRequest = function(dispatched_request) { Server.prototype.handlePluginSettingsRequest = function(dispatched_request,plugin) { - var fields = plugin.platform.showSettings(dispatched_request) - + var fields = (typeof plugin.platform.showSettings == 'function') ? plugin.platform.showSettings(dispatched_request) : [] + var dep = this.configuration.getValueForPluginWithDefault(plugin.name,"dependencies",[]) + var dplist = dep.join() + + fields.push({"control":"text", + "name":"dependencies", + "label":this.localization.localize("Dependencies"), + "value":dplist || "", + "description":this.localization.localize("Plugins that need to launch befrore this. (, separated)") + }); + if (dispatched_request.post != undefined) { var newSettings = {} var operation = dispatched_request.post['op'] fields.some(function (field){ newSettings[field.name] = dispatched_request.post[field.name] }) - plugin.platform.saveSettings(newSettings) + + if (typeof plugin.platform.saveSettings == 'function') { + plugin.platform.saveSettings(newSettings) + } + dispatched_request.redirectTo('/') return undefined + } else { var settings_text_template = dispatched_request.getTemplate(null , 'settings_text.html',null) var settings_option_template = dispatched_request.getTemplate(null , 'settings_option.html',null) @@ -459,6 +557,15 @@ Server.prototype.pluginWithName = function(name) { return result } +Server.prototype.pluginWithType = function(type) { + var result = undefined + this.configuratedPlugins.some(function (plugin){ + if (type === plugin.pluginType) { + result = plugin + } + }) + return result +} Server.prototype.isPluginConfigured = function(type) { var result = false @@ -478,6 +585,59 @@ Server.prototype.isPluginActive = function(type) { return (this.activePlugins.indexOf(type)>-1) } +Server.prototype.deactivatePlugin = function(type) { + logger.info("Trying to disable %s ",type) + var that = this + var success = false + var configuredPlugins = this.configuration.getValue('plugins') + if (configuredPlugins!=undefined) { + configuredPlugins.forEach(function (pdef){ + if (pdef['type'] === type) { + logger.info("Found %s set disable to true",type) + pdef['disabled']=true + success = true + } + }) + } + + if (success==true) { + this.configuration.setValue('plugins',configuredPlugins) + this.reloadPlugins() + } +} + +Server.prototype.activatePlugin = function(type) { + var configuredPlugins = this.configuration.getValue('plugins') + var found = false + if (configuredPlugins!=undefined) { + configuredPlugins.forEach(function (pdef){ + if (pdef['type'] === type) { + logger.info("Found %s set disable to false",type) + pdef['disabled']=false + found = true + } + }) + } + + if (!found) { + // Generate new Entry + var defs = this.getPluginDefaults(type) + if (defs) { + var newPluginEntry = { + "type":type, + "name":defs.syname, + "disabled":false + } + logger.info("Have to build new entry for %s",type) + configuredPlugins.push(newPluginEntry) + } + } + + this.configuration.setValue('plugins',configuredPlugins) + this.reloadPlugins() +} + + Server.prototype.allPlugins = function() { var result = [] var that = this @@ -504,15 +664,49 @@ Server.prototype.isPluginTypeInstalled = function(type) { return result } +Server.prototype.getVersionForPluginWithType = function(type) { + var that = this + var result = false + Plugin.installed().forEach(function(plugin) { + if (type == plugin.type()) { + result = plugin.version + } + }) + return result +} + +Server.prototype.getPluginPath = function(type) { + var that = this + var result = false + Plugin.installed().forEach(function(plugin) { + if (type == plugin.type()) { + result = plugin.pluginPath + } + }) + return result +} + + + +Server.prototype.getPluginDefaults = function(type) { + var result = {} + this.cachedPluginList.some(function (pobj){ + if (pobj.npm==type) { + result = pobj + } + }) + return result +} + Server.prototype.installPlugin = function(type,callback) { var that = this this.fetchPluginList(function (error,list){ if (error==null) { list.some(function (pobj){ - logger.debug("%s vs %s",JSON.stringify(pobj),type) if (pobj.npm==type) { - that.installNPM(pobj.npm,path.normalize(path.join(appRoot,'..'))) - + // should be outside of /usr/local/node_modules/homematic-virtual blafasel + that.installNPM(pobj.npm,path.normalize(path.join(appRoot,'..','..','..'))) + that.reloadPlugins() } }) if(callback) {callback(null)} @@ -522,35 +716,65 @@ Server.prototype.installPlugin = function(type,callback) { }) } -Server.prototype.fetchPluginList = function(callback) { +Server.prototype.refreshPluginList = function(callback) { var request = require('request') - var url = 'https://raw.githubusercontent.com/thkl/Homematic-Virtual-Interface/master/plugins/plugins.json' + var url = 'https://raw.githubusercontent.com/thkl/Homematic-Virtual-Interface/master/plugins/plugins.json?'+new Date() var that = this var result = []; try { request({url: url,json: true}, function (error, response, body) { if (!error && response.statusCode === 200) { - if ((body) && (body['plugins'])) { - result = body['plugins'] - logger.debug("S %s",JSON.stringify(result)) - result.some(function (aPlugin){ - aPlugin.installed = that.isPluginTypeInstalled(aPlugin.npm) - aPlugin.active = that.isPluginActive(aPlugin.npm) - }); - if (callback) {callback(null,result)} - } else { - if (callback) {callback(null,result)} - } - } else { - logger.error("Fetch Error %s",error) - if (callback) {callback(error,[])} + var pluginFile = that.configuration.storagePath() + "/plugins.json"; + logger.info("save plugin file : %s",pluginFile); + var buffer = JSON.stringify(body,null, 2); + fs.writeFileSync(pluginFile, buffer) + if (callback) {callback(null,[])} } - }) - } catch (e) { + }) + + } catch (e) { logger.error('Fetch Plugins Error %s',e.stack) if (callback) {callback(error,[])} - } + } +} + + +Server.prototype.fetchPluginList = function(callback) { + var pluginFile = this.configuration.storagePath() + "/plugins.json"; + var that = this + if (fs.existsSync(pluginFile)) { + var buffer = fs.readFileSync(pluginFile); + var result = JSON.parse(buffer.toString()); + this.buildPluginList(result,callback); + } else { + this.refreshPluginList(function(){ + var buffer = fs.readFileSync(pluginFile); + var result = JSON.parse(buffer.toString()); + that.buildPluginList(result,callback); + }) + } +} + + +Server.prototype.buildPluginList = function(body,callback) { + var that = this; + if ((body) && (body['plugins'])) { + var result = body['plugins'] + result.some(function (aPlugin){ + aPlugin.installed = that.isPluginTypeInstalled(aPlugin.npm) + aPlugin.active = that.isPluginActive(aPlugin.npm) + aPlugin.version = that.getVersionForPluginWithType(aPlugin.npm) + aPlugin.pluginPath = that.getPluginPath(aPlugin.npm) + }); + + if (callback) { + callback(null,result) + } + + } else { + if (callback) {callback(null,result)} + } } @@ -601,19 +825,24 @@ Server.prototype._loadPlugins = function() { //logger.debug('Plugin Config %s',JSON.stringify(pluginConfig)) var pluginType = pluginConfig['type'] var pluginName = pluginConfig['name'] - var pluginDissabled = pluginConfig['dissabled'] || false + var pluginDisabled = pluginConfig['disabled'] || false var plg = plugins[pluginType] - if ((plg!=undefined) && (pluginDissabled===false)) { - // call the plugin's initializer and pass it the API instance - var pluginLogger = require(__dirname + '/logger.js').logger(pluginType + ' - ' + pluginName) - var plg_instance = new plg.initializer(this,pluginName,pluginLogger,plg.instance) - plg_instance.pluginPath = plg.pluginPath - logger.info(plg_instance.name +' initialized. Document Path is %s Plugin Instance: %s',plg_instance.pluginPath,plg.instance) - this.configuratedPlugins.push(plg_instance) - this.activePlugins.push(pluginType) - plg.instance = plg.instance + 1 - foundOnePlugin = true + if ((plg!=undefined) && (pluginDisabled===false)) { + try { + // call the plugin's initializer and pass it the API instance + var pluginLogger = require(__dirname + '/logger.js').logger(pluginType + ' - ' + pluginName) + var plg_instance = new plg.initializer(this,pluginName,pluginLogger,plg.instance) + plg_instance.pluginPath = plg.pluginPath + plg_instance.pluginType = pluginType + logger.info(plg_instance.name +' initialized. Document Path is %s Plugin Instance: %s',plg_instance.pluginPath,plg.instance) + this.configuratedPlugins.push(plg_instance) + this.activePlugins.push(pluginType) + plg.instance = plg.instance + 1 + foundOnePlugin = true + } catch (loadError) { + logger.error("Cannot initialize %s - %s",pluginName,loadError.stack) + } } else { logger.error('%s Plugin is not active.',pluginType) } @@ -644,40 +873,109 @@ Server.prototype.checkUpdate = function() { var pos = status.indexOf('up-to-date') result = pos } catch (e) { - logger.error(e) + logger.error("Core Check update error %s",e.stack) result = 0 } return result } Server.prototype.doUpdate = function() { - try { - require('child_process').execSync('cd ' + appRoot + '/..;git pull') + var npmName = 'homematic-virtual-interface'; + var systemPath = path.normalize(path.join(appRoot,'..','..')) + if (this.isNPM(npmName,path.normalize(path.join(appRoot,'..')))) { + var exec = require('child_process').exec; + var cmd = 'cd ' + systemPath + ';' + this.npmCommand + ' install ' + npmName + ' --production --prefix "' + systemPath + '"'; + require('child_process').execSync(cmd); return 'please Restart .....' - } catch (e) { - logger.error(e) - return 'non git version' + } else { + try { + require('child_process').execSync('cd ' + path.join(appRoot,'..').normalize()+';git pull') + return 'please Restart .....' + } catch (e) { + logger.error("Core Update Error %s",e.stack) + return 'non git version' + } } } + +Server.prototype.doNPMUpdate = function(packageNames) { + var that = this + packageNames.some(function (pluginObject){ + try { + var npmName = pluginObject.npm + // destination is one above the plugin path + var destPath = path.normalize(path.join(pluginObject.pluginPath,'..','..')) + logger.info("Updateing %s in %s",npmName,destPath) + var exec = require('child_process').exec; + var cmd = 'cd ' + destPath + ';' + that.npmCommand + ' install ' + npmName + ' --production --prefix "' + destPath + '"'; + require('child_process').execSync(cmd); + } + catch (err) { + logger.error("Update error for %s - %s",npmName,err) + } + }); +} + + Server.prototype.installNPM = function(npmName,destPath) { + logger.info("Installing %s to %s",npmName,destPath) var exec = require('child_process').exec; - var cmd = 'npm install ' + npmName + ' --production --prefix "' + destPath + '/"'; + var cmd = 'cd ' + destPath + ';' + this.npmCommand + ' install ' + npmName + ' --production --prefix "' + destPath + '"'; require('child_process').execSync(cmd); } + +Server.prototype.isNPM = function(npmName,destPath) { + var pjsonPath = path.join(destPath, "package.json"); + logger.debug("Checking NPM on %s",pjsonPath) + try { + var pjson = JSON.parse(fs.readFileSync(pjsonPath)); + return (pjson['_id']!=undefined) + } + catch (err) { + logger.error("Check NPM Error %s",err.stack) + return false + } +} + Server.prototype.restart = function() { try { - var cmd = appRoot + '/../bin/hmviservice restart' - logger.info('Rebooting (%s)',cmd) + var cmd = this.configuration.getValueWithDefault("restart_command",appRoot + '/../bin/hmviservice restart'); + logger.info('Restart (%s)',cmd) var exec = require('child_process').exec var child = exec(cmd) logger.info('done ') } catch (e) { - logger.error('Error while trying to reboot ',e) + logger.error('Error while trying to reboot %s',e) } } + + + +Server.prototype.fetch_npmVersion = function(pck, callback) { + var httpUtil = require(path.join(__dirname, 'Util.js')); + httpUtil.httpCall("GET","https://registry.npmjs.org/" + pck + "/",[],function (data,error){ + try { + if (data) { + var registry = JSON.parse(data); + if (registry) { + if (callback) {callback(registry['dist-tags']['latest'])} + } else { + if (callback) {callback("unknow")} + } + } else { + if (callback) {callback("unknow")} + } + } catch (err){ + logger.error("Error while checking NPM Version of %s - %s",pck,e.stack) + if (callback) {callback("unknow")} + } + }) +} + + Server.prototype.getVersion = function(plugin) { try { var pfile = appRoot + '/../package.json' diff --git a/lib/VirtualDevicePlugin.js b/lib/VirtualDevicePlugin.js index 1537d20..e06742a 100644 --- a/lib/VirtualDevicePlugin.js +++ b/lib/VirtualDevicePlugin.js @@ -34,6 +34,7 @@ function VirtualDevicePlugin(pluginPath) { this.instance = 0; this.initialized = true; this.platform = undefined; + this.version = undefined; } VirtualDevicePlugin.prototype.type = function() { @@ -87,7 +88,7 @@ VirtualDevicePlugin.loadPackageJSON = function(pluginPath) { pjson = JSON.parse(fs.readFileSync(pjsonPath)); } catch (err) { - logger.debug("Plugin " + pluginPath + " contains an invalid package.json. Error: " + err); + // logger.debug("Plugin " + pluginPath + " contains an invalid package.json. Error: " + err); throw new Error("Plugin " + pluginPath + " contains an invalid package.json. Error: " + err); } @@ -153,7 +154,7 @@ VirtualDevicePlugin.installed = function() { var searchedPaths = {}; // don't search the same paths twice // search for plugins among all known paths, in order - logger.debug("Plugin Paths : %s", JSON.stringify(VirtualDevicePlugin.paths)); + //logger.debug("Plugin Paths : %s", JSON.stringify(VirtualDevicePlugin.paths)); for (var index in VirtualDevicePlugin.paths) { var requirePath = VirtualDevicePlugin.paths[index]; @@ -193,7 +194,7 @@ VirtualDevicePlugin.installed = function() { catch (err) { // is this "trying" to be a homematic-virtual plugin? if so let you know what went wrong. if (!type || type.indexOf('homematic-virtual-') == 0) { - logger.error(err.message); + // logger.error(err.message); } // skip this module @@ -206,7 +207,9 @@ VirtualDevicePlugin.installed = function() { // add it to the return list if (!pluginsByName[type]) { pluginsByName[type] = pluginPath; - plugins.push(new VirtualDevicePlugin(pluginPath)); + var plgObject = new VirtualDevicePlugin(pluginPath) + plgObject.version = pjson.version + plugins.push(plgObject); } else { logger.warn("Warning: skipping plugin found at '" + pluginPath + "' since we already loaded the same plugin from '" + pluginsByName[type] + "'."); diff --git a/package.json b/package.json index c76afff..806aa20 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "homematic-virtual-interface", - "version": "0.2.12", + "version": "0.2.34", "description": "Homematic Virtual Interface", "license": "ISC", "scripts": { @@ -29,7 +29,8 @@ "moment":"2.17.1", "group-array":"0.3.1", "nedb-logger":"0.1.0", - "qs":"6.3.1" + "qs":"6.3.1", + "xml2js":"0.4.17" }, "files": [ diff --git a/plugins/Alexa/AlexaPlatform.js b/plugins/Alexa/AlexaPlatform.js index 3392974..ba66377 100644 --- a/plugins/Alexa/AlexaPlatform.js +++ b/plugins/Alexa/AlexaPlatform.js @@ -192,8 +192,13 @@ AlexaPlatform.prototype.init = function() { AlexaPlatform.prototype.shutdown = function() { + this.log.debug("Alexa Plugin Shutdown"); - this.socket.disconnect(); + try { + this.socket.disconnect(); + } catch (e){ + + } } AlexaPlatform.prototype.processAlexaMessage = function(alx_message) { @@ -308,8 +313,10 @@ AlexaPlatform.prototype.reconnect = function() { alexaLogger.info("Reconnecting to Cloud Service"); var last = this.api_key.slice(-4); alexaLogger.info("using API-Key : XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX" + last); - this.socket.disconnect(); - this.socket.connect(); + if (this.socket) { + this.socket.disconnect(); + this.socket.connect(); + } } else { alexaLogger.info("No API Key found. Get one at https://console.ksquare.de/alexa \r\n"); } @@ -372,7 +379,7 @@ AlexaPlatform.prototype.add_appliance = function(id,name,hmService,virtual) { var service = require ('./service/' + hmService); // Switch RPC Client - var hms = new service(id,this.log,this.hm_layer); + var hms = new service(id,this.log,this.hm_layer,this.name); hms.alexaname = name; hms.server = this.server; diff --git a/plugins/Alexa/package.json b/plugins/Alexa/package.json index 6ef0d3b..5b01900 100644 --- a/plugins/Alexa/package.json +++ b/plugins/Alexa/package.json @@ -1,6 +1,6 @@ { - "name": "homematic-virtual-huedevice", - "version": "0.0.7", + "name": "homematic-virtual-alexa", + "version": "0.0.11", "description": "Virtual Alexa Bridge", "license": "ISC", "keywords": [ @@ -8,10 +8,10 @@ ], "repository": { "type": "git", - "url": "git://github.com/" + "url": "https://github.com/thkl/Homematic-Virtual-Interface/tree/master/plugins/Alexa" }, "bugs": { - "url": "http://" + "url": "https://github.com/thkl/Homematic-Virtual-Interface/issues" }, "engines": { "node": ">=0.12.0", @@ -20,6 +20,17 @@ "dependencies": { "socket.io-client": "^1.5.0", - "uuid":"latest" - } + "uuid":"latest", + "nedb-logger":"0.1.0", + "nedb" : "1.8.0" + }, + + "files": [ + "AlexaPlatform.js", + "service/", + "README.md", + "Localizable.strings", + "index.js", + "www/" + ] } \ No newline at end of file diff --git a/plugins/Alexa/service/AlexaHarmonyActivityService.js b/plugins/Alexa/service/AlexaHarmonyActivityService.js index 9ab942f..e86fd5a 100644 --- a/plugins/Alexa/service/AlexaHarmonyActivityService.js +++ b/plugins/Alexa/service/AlexaHarmonyActivityService.js @@ -4,7 +4,7 @@ var GenericAlexaHomematicService = require('./GenericService.js').GenericAlexaHo var util = require("util"); -function AlexaHarmonyActivityService(homematicDevice,log,hmlayer) { +function AlexaHarmonyActivityService(homematicDevice,log,hmlayer,name) { AlexaHarmonyActivityService.super_.apply(this,arguments); } diff --git a/plugins/Alexa/service/AlexaHarmonyDeviceService.js b/plugins/Alexa/service/AlexaHarmonyDeviceService.js index 5133f27..b8fecb6 100644 --- a/plugins/Alexa/service/AlexaHarmonyDeviceService.js +++ b/plugins/Alexa/service/AlexaHarmonyDeviceService.js @@ -4,7 +4,7 @@ var GenericAlexaHomematicService = require('./GenericService.js').GenericAlexaHo var util = require("util"); -function AlexaHarmonyDeviceService(homematicDevice,log,hmlayer) { +function AlexaHarmonyDeviceService(homematicDevice,log,hmlayer,name) { AlexaHarmonyDeviceService.super_.apply(this,arguments); } diff --git a/plugins/Alexa/service/AlexaHomematicDimmerService.js b/plugins/Alexa/service/AlexaHomematicDimmerService.js index 815e63e..2866ce7 100644 --- a/plugins/Alexa/service/AlexaHomematicDimmerService.js +++ b/plugins/Alexa/service/AlexaHomematicDimmerService.js @@ -4,7 +4,7 @@ var GenericAlexaHomematicService = require('./GenericService.js').GenericAlexaHo var util = require("util"); -function AlexaHomematicDimmerService(homematicDevice,log,hmlayer) { +function AlexaHomematicDimmerService(homematicDevice,log,hmlayer,name) { AlexaHomematicDimmerService.super_.apply(this,arguments); this.ccuInterface = "BidCos-RF"; } diff --git a/plugins/Alexa/service/AlexaHomematicHMIPDimmerService.js b/plugins/Alexa/service/AlexaHomematicHMIPDimmerService.js index 7e2108c..ff1e139 100644 --- a/plugins/Alexa/service/AlexaHomematicHMIPDimmerService.js +++ b/plugins/Alexa/service/AlexaHomematicHMIPDimmerService.js @@ -4,7 +4,7 @@ var GenericAlexaHomematicService = require('./GenericService.js').GenericAlexaHo var util = require("util"); -function AlexaHomematicHMIPDimmerService(homematicDevice,log,hmlayer) { +function AlexaHomematicHMIPDimmerService(homematicDevice,log,hmlayer,name) { AlexaHomematicHMIPDimmerService.super_.apply(this,arguments); this.ccuInterface = "HmIP-RF"; } diff --git a/plugins/Alexa/service/AlexaHomematicHMIPSwitchService.js b/plugins/Alexa/service/AlexaHomematicHMIPSwitchService.js index 927005b..2a33b90 100644 --- a/plugins/Alexa/service/AlexaHomematicHMIPSwitchService.js +++ b/plugins/Alexa/service/AlexaHomematicHMIPSwitchService.js @@ -4,7 +4,7 @@ var GenericAlexaHomematicService = require('./GenericService.js').GenericAlexaHo var util = require("util"); -function AlexaHomematicHMIPSwitchService(homematicDevice,log,hmlayer) { +function AlexaHomematicHMIPSwitchService(homematicDevice,log,hmlayer,name) { AlexaHomematicHMIPSwitchService.super_.apply(this,arguments); this.ccuInterface = "HmIP-RF"; } diff --git a/plugins/Alexa/service/AlexaHomematicHMIPThermostatService.js b/plugins/Alexa/service/AlexaHomematicHMIPThermostatService.js index 2a3f0f4..f2cfa4a 100644 --- a/plugins/Alexa/service/AlexaHomematicHMIPThermostatService.js +++ b/plugins/Alexa/service/AlexaHomematicHMIPThermostatService.js @@ -4,7 +4,7 @@ var GenericAlexaHomematicService = require('./GenericService.js').GenericAlexaHo var util = require("util"); -function AlexaHomematicHMIPThermostatService(homematicDevice,log,hmlayer) { +function AlexaHomematicHMIPThermostatService(homematicDevice,log,hmlayer,name) { AlexaHomematicHMIPThermostatService.super_.apply(this,arguments); this.ccuInterface = "HmIP-RF"; } diff --git a/plugins/Alexa/service/AlexaHomematicProgramService.js b/plugins/Alexa/service/AlexaHomematicProgramService.js index 6040699..e6b5e2f 100644 --- a/plugins/Alexa/service/AlexaHomematicProgramService.js +++ b/plugins/Alexa/service/AlexaHomematicProgramService.js @@ -4,7 +4,7 @@ var GenericAlexaHomematicService = require('./GenericService.js').GenericAlexaHo var util = require("util"); -function AlexaHomematicProgramService(homematicDevice,log,hmlayer) { +function AlexaHomematicProgramService(homematicDevice,log,hmlayer,name) { AlexaHomematicProgramService.super_.apply(this,arguments); } diff --git a/plugins/Alexa/service/AlexaHomematicSwitchService.js b/plugins/Alexa/service/AlexaHomematicSwitchService.js index fb357e0..5c02501 100644 --- a/plugins/Alexa/service/AlexaHomematicSwitchService.js +++ b/plugins/Alexa/service/AlexaHomematicSwitchService.js @@ -4,7 +4,7 @@ var GenericAlexaHomematicService = require('./GenericService.js').GenericAlexaHo var util = require("util"); -function AlexaHomematicSwitchService(homematicDevice,log,hmlayer) { +function AlexaHomematicSwitchService(homematicDevice,log,hmlayer,name) { AlexaHomematicSwitchService.super_.apply(this,arguments); this.ccuInterface = "BidCos-RF"; } diff --git a/plugins/Alexa/service/AlexaHomematicThermostatService.js b/plugins/Alexa/service/AlexaHomematicThermostatService.js index 1ca5105..1711888 100644 --- a/plugins/Alexa/service/AlexaHomematicThermostatService.js +++ b/plugins/Alexa/service/AlexaHomematicThermostatService.js @@ -4,7 +4,7 @@ var GenericAlexaHomematicService = require('./GenericService.js').GenericAlexaHo var util = require("util"); -function AlexaHomematicThermostatService(homematicDevice,log,hmlayer) { +function AlexaHomematicThermostatService(homematicDevice,log,hmlayer,name) { AlexaHomematicThermostatService.super_.apply(this,arguments); this.ccuInterface = "BidCos-RF"; } diff --git a/plugins/Alexa/service/AlexaHomematicWiredDimmerService.js b/plugins/Alexa/service/AlexaHomematicWiredDimmerService.js index 484b1e4..35c77e6 100644 --- a/plugins/Alexa/service/AlexaHomematicWiredDimmerService.js +++ b/plugins/Alexa/service/AlexaHomematicWiredDimmerService.js @@ -4,7 +4,7 @@ var GenericAlexaHomematicService = require('./GenericService.js').GenericAlexaHo var util = require("util"); -function AlexaHomematicWiredDimmerService(homematicDevice,log,hmlayer) { +function AlexaHomematicWiredDimmerService(homematicDevice,log,hmlayer,name) { AlexaHomematicWiredDimmerService.super_.apply(this,arguments); this.ccuInterface = "BidCos-Wired"; } diff --git a/plugins/Alexa/service/AlexaHomematicWiredSwitchService.js b/plugins/Alexa/service/AlexaHomematicWiredSwitchService.js index 6f65557..80ec569 100644 --- a/plugins/Alexa/service/AlexaHomematicWiredSwitchService.js +++ b/plugins/Alexa/service/AlexaHomematicWiredSwitchService.js @@ -4,7 +4,7 @@ var GenericAlexaHomematicService = require('./GenericService.js').GenericAlexaHo var util = require("util"); -function AlexaHomematicWiredSwitchService(homematicDevice,log,hmlayer) { +function AlexaHomematicWiredSwitchService(homematicDevice,log,hmlayer,name) { AlexaHomematicWiredSwitchService.super_.apply(this,arguments); this.ccuInterface = "BidCos-Wired"; } diff --git a/plugins/Alexa/service/AlexaHueSceneService.js b/plugins/Alexa/service/AlexaHueSceneService.js index d0f95ca..65ccf96 100644 --- a/plugins/Alexa/service/AlexaHueSceneService.js +++ b/plugins/Alexa/service/AlexaHueSceneService.js @@ -4,7 +4,7 @@ var GenericAlexaHomematicService = require('./GenericService.js').GenericAlexaHo var util = require("util"); -function AlexaHueSceneService(homematicDevice,log,hmlayer) { +function AlexaHueSceneService(homematicDevice,log,hmlayer,name) { AlexaHueSceneService.super_.apply(this,arguments); } diff --git a/plugins/Alexa/service/AlexaHueService.js b/plugins/Alexa/service/AlexaHueService.js index 9065a2c..3901551 100644 --- a/plugins/Alexa/service/AlexaHueService.js +++ b/plugins/Alexa/service/AlexaHueService.js @@ -4,7 +4,7 @@ var GenericAlexaHomematicService = require('./GenericService.js').GenericAlexaHo var util = require("util"); -function AlexaHueService(homematicDevice,log,hmlayer) { +function AlexaHueService(homematicDevice,log,hmlayer,name) { AlexaHueService.super_.apply(this,arguments); } diff --git a/plugins/Alexa/service/AlexaLogicService.js b/plugins/Alexa/service/AlexaLogicService.js index bff0dde..52310f9 100644 --- a/plugins/Alexa/service/AlexaLogicService.js +++ b/plugins/Alexa/service/AlexaLogicService.js @@ -4,7 +4,7 @@ var GenericAlexaHomematicService = require('./GenericService.js').GenericAlexaHo var util = require("util"); -function AlexaLogicService(homematicDevice,log,hmlayer) { +function AlexaLogicService(homematicDevice,log,hmlayer,name) { AlexaLogicService.super_.apply(this,arguments); } diff --git a/plugins/Alexa/service/AlexaSonosService.js b/plugins/Alexa/service/AlexaSonosService.js index b3b852f..c2a2df7 100644 --- a/plugins/Alexa/service/AlexaSonosService.js +++ b/plugins/Alexa/service/AlexaSonosService.js @@ -4,7 +4,7 @@ var GenericAlexaHomematicService = require('./GenericService.js').GenericAlexaHo var util = require("util"); -function AlexaSonosService(homematicDevice,log,hmlayer) { +function AlexaSonosService(homematicDevice,log,hmlayer,name) { AlexaSonosService.super_.apply(this,arguments); } diff --git a/plugins/Alexa/service/GenericService.js b/plugins/Alexa/service/GenericService.js index ccf6c7a..55a4396 100644 --- a/plugins/Alexa/service/GenericService.js +++ b/plugins/Alexa/service/GenericService.js @@ -18,12 +18,13 @@ if (appRoot.endsWith("node_modules/daemonize2/lib")) {appRoot = appRoot+"/../.. var regarequest = require(appRoot + "/HomematicReqaRequest.js"); -function GenericAlexaHomematicService (homematicDevice,log,hmlayer) { +function GenericAlexaHomematicService (homematicDevice,log,hmlayer,name) { this.homematicDevice = homematicDevice; this.log = log; this.hm_layer = hmlayer; this.alexaname = "unknow"; this.ccuInterface = undefined; + this.name = name; } diff --git a/plugins/CCUDutyCycle/package.json b/plugins/CCUDutyCycle/package.json index a49f0c6..fea646f 100644 --- a/plugins/CCUDutyCycle/package.json +++ b/plugins/CCUDutyCycle/package.json @@ -1,6 +1,6 @@ { "name": "homematic-virtual-ccudutycylcle", - "version": "0.0.2", + "version": "0.0.5", "description": "Virtual Plugin - CCUDutyCycle", "license": "ISC", "keywords": [ @@ -19,5 +19,9 @@ }, "dependencies": { + "group-array":"0.3.2", + "moment":"2.17.1", + "nedb-logger":"0.1.0", + "nedb" : "1.8.0" } } \ No newline at end of file diff --git a/plugins/HttpPlugin/HttpPlatform.js b/plugins/HttpPlugin/HttpPlatform.js index 28bd38c..ef9b6e4 100644 --- a/plugins/HttpPlugin/HttpPlatform.js +++ b/plugins/HttpPlugin/HttpPlatform.js @@ -35,6 +35,10 @@ HttpPlatform.prototype.init = function() { this.log.info("initialization completed %s",this.plugin.initialized); } +HttpPlatform.prototype.shutdown = function() { + this.log.info("Shutdown"); + this.bridge.deleteDevicesByOwner(this.name) +} HttpPlatform.prototype.initRemote=function(rmIndex) { var that = this; diff --git a/plugins/HttpPlugin/package.json b/plugins/HttpPlugin/package.json index fd37c0f..56ad930 100644 --- a/plugins/HttpPlugin/package.json +++ b/plugins/HttpPlugin/package.json @@ -1,6 +1,6 @@ { "name": "homematic-virtual-httpdevice", - "version": "0.0.1", + "version": "0.0.3", "description": "Virtual Plugin - HttpPlatform", "license": "ISC", "keywords": [ diff --git a/plugins/HuePlugin/HueColorDevice.js b/plugins/HuePlugin/HueColorDevice.js index 3541514..f449bf1 100644 --- a/plugins/HuePlugin/HueColorDevice.js +++ b/plugins/HuePlugin/HueColorDevice.js @@ -62,7 +62,6 @@ var HueColorDevice = function(plugin, hueApi ,light,serialprefix) { this.bridge.addDevice(this.hmDevice,false); } - this.hmDevice.on('device_channel_value_change', function(parameter){ diff --git a/plugins/HuePlugin/HueEffectServer.js b/plugins/HuePlugin/HueEffectServer.js index ab90d84..147cfc3 100644 --- a/plugins/HuePlugin/HueEffectServer.js +++ b/plugins/HuePlugin/HueEffectServer.js @@ -11,13 +11,12 @@ var fs = require('fs'); var path = require('path'); -var logger = require(__dirname + "/../../lib/logger.js").logger("HueEffectServer"); var HueEffectServer = function (platform,name) { this.name = name; this.lights = []; this.platform = platform; - logger.debug("Platform : %s Server %s" , platform,name); + this.platform.log.debug("Platform : %s Server %s" , platform,name); this.configuration = platform.server.configuration; } @@ -37,7 +36,7 @@ HueEffectServer.prototype.stopSceneWithLight = function(light) { if (this.isRunning==true) { var index = this.lights.indexOf(light); if (index > -1) { - logger.debug("Stop Scene"); + this.platform.log.debug("Stop Scene"); this.stopScene(true); } } @@ -50,7 +49,7 @@ HueEffectServer.prototype.stopScene = function(playStopFrame) { clearTimeout(this.timer); this.isRunning = false; if ((this.offFrame) && (playStopFrame==true)) { - logger.debug("Running the stop frame"); + this.platform.log.debug("Running the stop frame"); this.runStaticScene(this.offFrame); } } @@ -77,7 +76,7 @@ HueEffectServer.prototype.listScenes = function() { }); } catch (e) { - logger.error("Error while loading Sceneslist %s",e); + this.platform.log.error("Error while loading Sceneslist %s",e); } return list; } @@ -97,14 +96,14 @@ HueEffectServer.prototype.persinstentData = function() { HueEffectServer.prototype.sceneData = function(sceneName) { var sceneFile = __dirname +"/scenes/"+sceneName + ".json"; - logger.info("try to load scene : %s",sceneFile); + this.platform.log.info("try to load scene : %s",sceneFile); if (fs.existsSync(sceneFile)) { return fs.readFileSync(sceneFile); } var privateSceneDir = this.configuration.storagePath() + "/scenes/"; sceneFile = privateSceneDir + sceneName + ".json"; - logger.info("try to load scene : %s",sceneFile); + this.platform.log.info("try to load scene : %s",sceneFile); if (fs.existsSync(sceneFile)) { return fs.readFileSync(sceneFile); @@ -124,8 +123,6 @@ HueEffectServer.prototype.runScene = function(sceneName) { if (buffer) { var scene_settings = JSON.parse(buffer.toString()); if (scene_settings) { - logger.debug(JSON.stringify(scene_settings)); - if ((scene_settings) && (scene_settings.mode)){ var mode = scene_settings.mode; var frames = scene_settings.frames; @@ -140,11 +137,11 @@ HueEffectServer.prototype.runScene = function(sceneName) { } } } else { - logger.error("Scene not found %s",sceneName); + this.platform.log.error("Scene not found %s",sceneName); } } catch (e) { - logger.warn("Error while reading scene", e); + this.platform.log.warn("Error while reading scene", e); } // Wait 2 seconds and refresh setTimeout(function(){ @@ -187,7 +184,7 @@ HueEffectServer.prototype.runStaticScene = function(frame) { var isOn = (bri==0)?false:true; var transition = this.getArgument(frame.transition) || 5; var lightstate = {"transitiontime":transition,"bri":bri,"sat":sat,"hue":hue,"on":isOn}; - logger.debug(lightstate); + this.platform.log.debug(lightstate); this.lights.forEach(function (light) { light.setLightData(lightstate); }); diff --git a/plugins/HuePlugin/HuePlatform.js b/plugins/HuePlugin/HuePlatform.js index 34b4d7f..f423410 100644 --- a/plugins/HuePlugin/HuePlatform.js +++ b/plugins/HuePlugin/HuePlatform.js @@ -84,6 +84,16 @@ HuePlatform.prototype.init = function() { } } +HuePlatform.prototype.shutdown = function() { + this.log.info("Shutdown"); + this.hm_layer.deleteDevicesByOwner(this.name) + this.lights = []; + this.groups = []; + this.effectServers={}; + clearTimeout(this.refreshTimer) + clearTimeout(this.userTimer) +} + HuePlatform.prototype.myDevices = function() { // return my Devices here var result = []; @@ -118,6 +128,9 @@ HuePlatform.prototype.showSettings = function(dispatched_request) { var user = this.configuration.getValueForPlugin(this.name,"hue_username") result.push({"control":"text","name":"hue_bridge_ip","label":"Bridge-IP","value":this.hue_ipAdress}); result.push({"control":"text","name":"hue_username","label":"Hue User","value":user}); + var refreshrate = this.configuration.getValueForPluginWithDefault(this.plugin.name,"refresh",60) + + result.push({"control":"text","name":"refresh","label":"Refresh","value": refreshrate || 30}); return result; } @@ -125,10 +138,25 @@ HuePlatform.prototype.saveSettings = function(settings) { var that = this var hue_bridge_ip = settings.hue_bridge_ip; var hue_username = settings.hue_username; - if ((hue_bridge_ip) && (hue_username)) { + if (hue_bridge_ip) { this.hue_ipAdress = hue_bridge_ip; this.configuration.setValueForPlugin(this.name,"hue_bridge_ip",hue_bridge_ip); } + + if (hue_username) { + this.hue_username = hue_username; + this.configuration.setValueForPlugin(this.name,"hue_username",hue_username); + } + + if (settings.refresh) { + this.configuration.setValueForPlugin(this.name,"refresh",settings.refresh); + } + + clearTimeout(this.userTimer) + clearTimeout(this.refreshTimer) + if (that.checkUsername()==true) { + that.queryBridgeAndMapDevices() + } } @@ -167,7 +195,7 @@ HuePlatform.prototype.checkUsername = function() { if (err && err.message == "link button not pressed") { that.authorized = false; that.log.warn("Please press the link button on your Philips Hue bridge within 30 seconds."); - setTimeout(function() {that.checkUsername();}, 10000); + that.userTimer = setTimeout(function() {that.checkUsername();}, 10000); } else { that.authorized = true; that.configuration.setValueForPlugin(that.name,"hue_username",user); @@ -312,8 +340,6 @@ HuePlatform.prototype.queryLights = function() { break; } - console.log(light); - that.lights.push(light); that.mappedDevices.push(hd); }); @@ -435,7 +461,7 @@ HuePlatform.prototype.refreshAll = function() { } }); - setTimeout(function() { + this.refreshTimer = setTimeout(function() { that.refreshAll(); }, refreshrate); this.log.debug("Refreshed Lights Next in %s ms.",refreshrate); diff --git a/plugins/HuePlugin/HueSFXDevice.js b/plugins/HuePlugin/HueSFXDevice.js index 0f85602..2754cbe 100644 --- a/plugins/HuePlugin/HueSFXDevice.js +++ b/plugins/HuePlugin/HueSFXDevice.js @@ -1,30 +1,29 @@ "use strict"; var HomematicDevice; -var logger = require(__dirname + "/../../lib/logger.js").logger("HueSFXDevice"); var HueSFXDevice = function(plugin) { this.plugin = plugin; this.bridge = plugin.server.getBridge(); - var that = this; + var that = this HomematicDevice = plugin.server.homematicDevice; - logger.info("Create one SFX Remote"); + this.plugin.log.info("Create one SFX Remote"); var serial = "HUEFX001"; this.hmDevice = new HomematicDevice(this.plugin.getName()); var data = this.bridge.deviceDataWithSerial(serial); if (data!=undefined) { - logger.info("SFX Remote Data found"); + this.plugin.log.info("SFX Remote Data found"); this.hmDevice.initWithStoredData(data); } if (this.hmDevice.initialized == false) { - logger.info("Build a new"); + this.plugin.log.info("Build a new"); this.hmDevice.initWithType("HM-RC-Key4-2", serial); this.bridge.addDevice(this.hmDevice,true); - logger.info("Done with the new"); + this.plugin.log.info("Done with the new"); } else { this.bridge.addDevice(this.hmDevice,false); } diff --git a/plugins/HuePlugin/package.json b/plugins/HuePlugin/package.json index 152222a..6642f3d 100644 --- a/plugins/HuePlugin/package.json +++ b/plugins/HuePlugin/package.json @@ -1,9 +1,9 @@ { "name": "homematic-virtual-huedevice", - "version": "0.0.9", + "version": "0.0.17", "description": "Virtual Hue Device", "license": "ISC", - "keywords": [ + "keywords":[ "homematic-virtual-plugin" ], "repository": { diff --git a/plugins/LogicPlugin/LogicalPlatform.js b/plugins/LogicPlugin/LogicalPlatform.js index 2f13992..4e15547 100644 --- a/plugins/LogicPlugin/LogicalPlatform.js +++ b/plugins/LogicPlugin/LogicalPlatform.js @@ -85,8 +85,8 @@ LogicalPlatform.prototype.init = function() { // Check Path var spath = path.join(this.configuration.storagePath() , 'scripts'); - var util = require(path.join(appRoot, 'Util.js')); - util.createPathIfNotExists(spath) + var myutil = require(path.join(appRoot, 'Util.js')); + myutil.createPathIfNotExists(spath) this.calculateSunTimes(); this.reInitScripts(); @@ -305,7 +305,7 @@ LogicalPlatform.prototype.fetchMessages = function(callback) { var obj = JSON.parse(result); callback(obj); } catch (e) { - that.error(e); + that.log.error(e); } }); } @@ -322,7 +322,7 @@ LogicalPlatform.prototype.confirmMessages = function(messages,callback) { try { callback(); } catch (e) { - that.error(e); + that.log.error(e); } }); } @@ -505,8 +505,8 @@ LogicalPlatform.prototype.httpCall = function(method,aUrl,parameter,callback) { this.log.debug("HTTP CALL : %s %s %s",method,aUrl,parameter); try { - var util = require(path.join(appRoot, "Util.js")); - util.httpCall(method,aUrl,parameter,callback) + var myutil = require(path.join(appRoot, "Util.js")); + myutil.httpCall(method,aUrl,parameter,callback) } catch (err) { that.log.error(err.stack) } @@ -680,13 +680,11 @@ LogicalPlatform.prototype.runScript = function(script_object, name) { var tmp = source.split('.'); // Check first Value for hmvirtual - that.log.debug("Source is %s",JSON.stringify(tmp)); - if ((tmp.length>2) && (tmp[0].toLowerCase()=="hmvirtual")) { - + if ((tmp.length>2) && (that.isVirtualPlatformDevice(tmp[0]))) { var channel = tmp[1]; // Bind to channel change events that.processLogicalBinding(channel); - } + } var fn = path.basename(name) that.subscriptions.push({file:fn, source: source, options: options, callback: (typeof callback === 'function') && scriptDomain.bind(callback)}); @@ -804,7 +802,7 @@ LogicalPlatform.prototype.runScript = function(script_object, name) { // third the Datapoint if (tmp.length>2) { - if (tmp[0].toLowerCase()=="hmvirtual") { + if (that.isVirtualPlatformDevice(tmp[0])) { var adress = tmp[1]; var datapointName = tmp[2]; var channel = that.hm_layer.channelWithAdress(adress); @@ -844,7 +842,7 @@ LogicalPlatform.prototype.runScript = function(script_object, name) { // third the Datapoint if (tmp.length>2) { - if (tmp[0].toLowerCase()=="hmvirtual") { + if (that.isVirtualPlatformDevice(tmp[0])) { var adress = tmp[1]; var datapointName = tmp[2]; var channel = that.hm_layer.channelWithAdress(adress); @@ -878,7 +876,7 @@ LogicalPlatform.prototype.runScript = function(script_object, name) { // third the Datapoint if (tmp.length>2) { - if (tmp[0].toLowerCase()=="hmvirtual") { + if (that.isVirtualPlatformDevice(tmp[0])) { var adress = tmp[1]; var datapointName = tmp[2]; var channel = that.hm_layer.channelWithAdress(adress); @@ -1051,8 +1049,8 @@ LogicalPlatform.prototype.processLogicalBinding = function(source_adress) { channel.on('logicevent_channel_value_change', function(parameter){ parameter.parameters.forEach(function (pp){ - that.log.debug("Channel was updated processing subscription ","HMVirtual."+parameter.channel,pp.name,pp.value); that.processSubscriptions("HMVirtual."+parameter.channel,pp.name,pp.value); + that.processSubscriptions(that.hm_layer.getCcuInterfaceName()+"."+parameter.channel,pp.name,pp.value); }); }); @@ -1100,6 +1098,11 @@ try { } } + +LogicalPlatform.prototype.isVirtualPlatformDevice=function(interfaceName) { + return ((interfaceName.toLowerCase() == "hmvirtual") || (interfaceName.toLowerCase() == this.bridge.getCcuInterfaceName().toLowerCase())); +} + LogicalPlatform.prototype.saveScript=function(data,filename) { try { fs.writeFileSync(filename, data) diff --git a/plugins/LogicPlugin/package.json b/plugins/LogicPlugin/package.json index 27bdd6f..00f9c30 100644 --- a/plugins/LogicPlugin/package.json +++ b/plugins/LogicPlugin/package.json @@ -1,6 +1,6 @@ { "name": "homematic-virtual-logicmanager", - "version": "0.0.5", + "version": "0.0.9", "description": "Virtual Logic Manager", "license": "ISC", "keywords": [ @@ -8,10 +8,10 @@ ], "repository": { "type": "git", - "url": "git://github.com/" + "url": "https://github.com/thkl/Homematic-Virtual-Interface/tree/master/plugins/LogicPlugin" }, "bugs": { - "url": "http://" + "url": "https://github.com/thkl/Homematic-Virtual-Interface/issues" }, "engines": { "node": ">=0.12.0", @@ -21,6 +21,17 @@ "dependencies": { "node-schedule":"latest", "suncalc":"1.8.0", - "promise":"latest" - } + "promise":"latest", + "moment":"2.17.1", + "nedb-logger":"0.1.0", + "nedb" : "1.8.0" + }, + + "files": [ + "LogicalPlatform.js", + "README.md", + "index.js", + "www/" + ] + } \ No newline at end of file diff --git a/plugins/LogitechHarmony/package.json b/plugins/LogitechHarmony/package.json index 7dda674..5e393e1 100644 --- a/plugins/LogitechHarmony/package.json +++ b/plugins/LogitechHarmony/package.json @@ -8,10 +8,10 @@ ], "repository": { "type": "git", - "url": "git://github.com/" + "url": "https://github.com/thkl/Homematic-Virtual-Interface/tree/master/plugins/LogitechHarmony" }, "bugs": { - "url": "http://" + "url": "https://github.com/thkl/Homematic-Virtual-Interface/issues" }, "engines": { "node": ">=0.12.0", diff --git a/plugins/NetAtmoPlugin/package.json b/plugins/NetAtmoPlugin/package.json index 389b948..cd76362 100644 --- a/plugins/NetAtmoPlugin/package.json +++ b/plugins/NetAtmoPlugin/package.json @@ -1,6 +1,6 @@ { "name": "homematic-virtual-netatmodevice", - "version": "0.0.4", + "version": "0.0.5", "description": "Virtual Netatmo Device", "license": "ISC", "keywords": [ @@ -8,10 +8,10 @@ ], "repository": { "type": "git", - "url": "git://github.com/" + "url": "https://github.com/thkl/Homematic-Virtual-Interface/tree/master/plugins/NetAtmoPlugin" }, "bugs": { - "url": "http://" + "url": "https://github.com/thkl/Homematic-Virtual-Interface/issues" }, "engines": { "node": ">=0.12.0", @@ -20,5 +20,14 @@ "dependencies": { "netatmo":"latest" - } + }, + + "files": [ + "NetAtmoDevice.js", + "NetAtmoPlatform.js", + "README.md", + "index.js", + "www/" + ] + } \ No newline at end of file diff --git a/plugins/SonosPlugin/SonosPlatform.js b/plugins/SonosPlugin/SonosPlatform.js index 2b8ab03..dcc8c8b 100644 --- a/plugins/SonosPlugin/SonosPlatform.js +++ b/plugins/SonosPlugin/SonosPlatform.js @@ -47,7 +47,7 @@ SonosPlatform.prototype.init = function() { var that = this; this.configuration = this.server.configuration; this.hm_layer = this.server.getBridge(); - this.maxVolume = this.configuration.getValueForPlugin(this.name,"max_volume",20); + this.maxVolume = this.configuration.getValueForPlugin(this.name,"max_volume",undefined) || 20; this.volumeTable = this.configuration.getValueForPlugin(this.name,"volume_table",undefined); // Add Coordinator Device this.coordinator = new SonosCoordinator(this) @@ -190,10 +190,11 @@ SonosPlatform.prototype.addZonePlayer = function(host,cname,callback) { var name = cname || data.roomName; var sdevice = new SonosDevice(that ,host,1400,"SONOS_" + name); var puuid = data.UDN.substring(5) - that.log.info("Add RINCON %s",puuid) + that.log.info("Add RINCON %s max volume is %s",puuid,that.maxVolume) sdevice.rincon = puuid; sdevice.zonename = name; + sdevice.maxVolume = that.maxVolume; that.devices.push(sdevice); that.coordinator.addZonePlayer(sdevice) if (callback) { diff --git a/plugins/SonosPlugin/package.json b/plugins/SonosPlugin/package.json index 82209eb..f9fa97c 100644 --- a/plugins/SonosPlugin/package.json +++ b/plugins/SonosPlugin/package.json @@ -1,6 +1,6 @@ { "name": "homematic-virtual-sonosdevice", - "version": "0.0.6", + "version": "0.0.9", "description": "Virtual Sonos Device", "license": "ISC", "keywords": [ diff --git a/plugins/SonosPlugin/www/de-de/index.html b/plugins/SonosPlugin/www/de-de/index.html index 8cbe7b4..b400176 100644 --- a/plugins/SonosPlugin/www/de-de/index.html +++ b/plugins/SonosPlugin/www/de-de/index.html @@ -108,7 +108,7 @@

    SONOS_ - +
    diff --git a/plugins/SonosPlugin/www/index.html b/plugins/SonosPlugin/www/index.html index 77d9493..de47313 100644 --- a/plugins/SonosPlugin/www/index.html +++ b/plugins/SonosPlugin/www/index.html @@ -55,6 +55,7 @@
  • Sonos Plugin +
  • Start search
  • @@ -75,11 +76,26 @@

    Sonos Plugin

    - Geräte + Devices

    $listDevices$ +

    new devices

    + $newDevices$ + +
    + + + +
    + SONOS_ + + + +
    +
    +
    @@ -87,6 +103,48 @@

    + + + diff --git a/rc.d/hvl b/rc.d/hvl index 4a0b72b..e18b56d 100644 --- a/rc.d/hvl +++ b/rc.d/hvl @@ -1,9 +1,10 @@ #!/bin/sh HVLDIR=/usr/local/addons/hvl -CONFIG_URL=/addons/hvl/www/ +CONFIG_URL=/addons/hvl/index.html CONFIG_DIR=/usr/local/etc/config PIDFILE=/var/run/hvl.pid STARTRC=/etc/init.d/S51hvl +VER=0.0.1 PSPID=`ps -o pid,comm,args | awk '{if ($2=="node" && $3 ~ /hvl/){print $1}}'` case "$1" in @@ -14,6 +15,10 @@ case "$1" in ln -sf $CONFIG_DIR/rc.d/hvl $STARTRC mount -o remount,ro / fi + + #run postinstall if necessary + $HVLDIR/etc/postinstall.sh + if [ "$PSPID" = "" ] then $HVLDIR/node/bin/node $HVLDIR/node_modules/homematic-virtual-interface/lib/index.js -C $CONFIG_DIR/hvl/ >>/dev/null & @@ -57,13 +62,21 @@ case "$1" in echo "Info:
    Homematic Virtual Layer
    " echo "Name: HVL" echo "Version: $VER" - echo "Operations: uninstall restart" + echo "Operations: uninstall" echo "Config-Url: $CONFIG_URL" - echo "Update: " ;; uninstall) logger -t homematic -p user.info "removing homematic virtual layer" + kill -KILL $PSPID 2>/dev/null + /usr/local/addons/hvl/etc/update_addon hvl + rm -R /usr/local/addons/hvl + rm /usr/local/etc/config/rc.d/hvl + mount -o remount,rw / + rm /etc/init.d/S51hvl + sed -i /etc/config_templates/InterfacesList.xml -e "s/HVL<\/name>xmlrpc:\/\/127.0.0.1:8301<\/url>HVL<\/info><\/ipc>//" + sed -i /usr/local/etc/config/InterfacesList.xml -e "s/HVL<\/name>xmlrpc:\/\/127.0.0.1:8301<\/url>HVL<\/info><\/ipc>//" + mount -o remount,ro / ;; *) diff --git a/www/de-de/index.html b/www/de-de/index.html index 9ed39c1..b3554a6 100644 --- a/www/de-de/index.html +++ b/www/de-de/index.html @@ -91,7 +91,7 @@

    Verschiedenes

    -
    Version $system.version$
    +
    Version $system.version$
    @@ -101,6 +101,8 @@

    + + - - diff --git a/www/de-de/plugin_item.html b/www/de-de/plugin_item.html new file mode 100644 index 0000000..e0cd97e --- /dev/null +++ b/www/de-de/plugin_item.html @@ -0,0 +1,18 @@ +
    +
    + $plugin.installed$ + $plugin.active$ + $plugin.type$
    Lokal $plugin.version$ - Zentral: ...
    + + + +
    +
    + + + $plugin.description$ +
    +
    + \ No newline at end of file diff --git a/www/de-de/plugins.html b/www/de-de/plugins.html new file mode 100644 index 0000000..311ddd5 --- /dev/null +++ b/www/de-de/plugins.html @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + Homematic Virtual Layer Core + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    +
    +
    Homematic Virtual Layer
    +

    Core

    +
    +
    + +
    + +
    + +
    +

    Plugins

    + + Installiert + Aktiv + Type + + $plugins$ + + + + +
    + +
    +
    +
    + +
    + + + + + diff --git a/www/index.html b/www/index.html index d39025c..bbadaa9 100644 --- a/www/index.html +++ b/www/index.html @@ -93,7 +93,7 @@

    Misc

    -
    $system.version$
    +
    $system.version$
    @@ -104,6 +104,9 @@

    + + + - - - diff --git a/www/plugin_item.html b/www/plugin_item.html new file mode 100644 index 0000000..7899c63 --- /dev/null +++ b/www/plugin_item.html @@ -0,0 +1,18 @@ +
    +
    + $plugin.installed$ + $plugin.active$ + $plugin.type$
    Local $plugin.version$ - Central: ...
    + + + +
    +
    + + + $plugin.description$ +
    +
    + \ No newline at end of file diff --git a/www/plugins.html b/www/plugins.html new file mode 100644 index 0000000..40f8dfa --- /dev/null +++ b/www/plugins.html @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + Homematic Virtual Layer Core + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    +
    +
    Homematic Virtual Layer
    +

    Core

    +
    +
    + +
    + +
    + +
    +

    Plugins

    + + Installed + Active + Type + + $plugins$ + + + + + + +
    + +
    +
    +
    + +
    + + + + +