Zipato RGBW

Данный раздел предназначен для русскоязычных пользователей. Если вы владеете английским, рекомендуем также просмотреть общую ветку обсуждений на английском.
User avatar
PoltoS
Posts: 7565
Joined: 26 Jan 2011 19:36

Re: Zipato RGBW

Post by PoltoS »

Да, мы поправили много в интерфейсе, стало, вроде, лучше. Спасибо за потверждение.
alv1home
Posts: 91
Joined: 24 Jun 2015 22:04

Re: Zipato RGBW

Post by alv1home »

Чего я добился.

С одной лампой, log-level 4, с таким кодом

Code: Select all

// ----------------------------------------------------------------------------
// --- Class definition, inheritance and setup
// ----------------------------------------------------------------------------

function WhiteColor (id, controller) {
	WhiteColor.super_.call(this, id, controller);
}

inherits(WhiteColor, AutomationModule);

_module = WhiteColor;

// ----------------------------------------------------------------------------
// --- Module instance initialized
// ----------------------------------------------------------------------------

WhiteColor.prototype.init = function (config) {
	WhiteColor.super_.prototype.init.call(this, config); 
	
	var self = this;
	
	if (self.config.step < 0.01) self.config.step = 0.01;
	if (self.config.step > 1.00) self.config.step = 1.00;
	                
	this.timer = null;
	this.iHue = 0.0;   
	
    var defaultsWhite = {
        metrics: {
            title: 'RGBW device #' + this.id + ' (White)'
        }
    };
    var overlayWhite = {
            deviceType: "switchMultilevel",
            metrics: { level:0,icon:"multilevel" }      
    }; 	
	
    var defaultsColor = {
        metrics: {
            title: 'RGBW device #' + this.id + ' (Color)'
        }
    };
    var overlayColor = {
            deviceType: "switchMultilevel",
            metrics: { level:0,icon:"multilevel" }      
    }; 	
	
	this.vDevWhite = self.controller.devices.create({
		deviceId: "GroupRGBW_" + this.id + "_White",
        defaults: defaultsWhite,
        overlay: overlayWhite, 
		handler:  function (command,args) {
			var that = self;
			console.debug(" *** WhiteColor *** handler for White (\'command\':"+command+", \'args\':"+args+")");
			
			var valueWhiteOld = that.vDevWhite.get("metrics:level"),
				valueWhiteNew = 0,
				valueColorOld = that.vDevColor.get("metrics:level"),
				valueColorNew = valueColorOld;
			
			if ("on" === command) valueWhiteNew = 99;
			if ("off" === command) valueWhiteNew = 0;
			if ("exact" === command) {
				valueWhiteNew = parseInt(args.level,10);
				if (valueWhiteNew < 0) valueWhiteNew = 0;
				if (valueWhiteNew > 99) valueWhiteNew = 99;
			}
			
			that.HandlerWhiteColor(that,valueWhiteOld,valueWhiteNew,valueColorOld,valueColorNew);
			
			that.vDevWhite.set("metrics:level",valueWhiteNew);
		},
		moduleId: this.id
	}); // this.vDevWhite = self.controller.devices.create

	this.vDevColor = self.controller.devices.create({
		deviceId: "GroupRGBW_" + this.id + "_Color",
        defaults: defaultsColor,
        overlay: overlayColor, 
		handler:  function (command, args) {
			var that = self;
			console.debug(" *** WhiteColor *** handler for Color (\'command\':"+command+", \'args\':"+args+")");
			
			var valueWhiteOld = that.vDevWhite.get("metrics:level"),
				valueWhiteNew = valueWhiteOld,
				valueColorOld = that.vDevColor.get("metrics:level"),
				valueColorNew = 0;

			if ("on" === command) valueColorNew = 99;
			if ("off" === command) valueColorNew = 0;
			if ("exact" === command) {
				valueColorNew = parseInt(args.level,10);
				if (valueColorNew < 0) valueColorNew = 0;
				if (valueColorNew > 99) valueColorNew = 99;
			}
				
			that.HandlerWhiteColor(that,valueWhiteOld,valueWhiteNew,valueColorOld,valueColorNew);
			
			that.vDevColor.set("metrics:level",valueColorNew); 
		},
		moduleId: this.id
	}); // this.vDevColor = self.controller.devices.create
	
	self.HandlerWhiteColor(self,0,self.vDevWhite.get("metrics:level"),0,self.vDevColor.get("metrics:level"));
};

WhiteColor.prototype.stop = function () {        
	var self = this;
 
	self.HandlerWhiteColor(self,self.vDevWhite.get("metrics:level"),0,self.vDevColor.get("metrics:level"),0);

	if (self.vDevColor) {
		self.controller.devices.remove(self.vDevColor.id);
		self.vDevColor = null;
	} 
	if (self.vDevWhite) {
		self.controller.devices.remove(self.vDevWhite.id);
		self.vDevWhite = null;
	} 
	WhiteColor.super_.prototype.stop.call(this);
};

// ----------------------------------------------------------------------------
// --- Module methods
// ----------------------------------------------------------------------------

WhiteColor.prototype.HandlerWhiteColor = function(instance,valueWhiteOld,valueWhiteNew,valueColorOld,valueColorNew) {
	var self = instance;

	console.debug(" *** WhiteColor *** HandlerWhiteColor (\'valueWhite\':"+valueWhiteOld+">"+valueWhiteNew+", \'valueColor\':"+valueColorOld+">"+valueColorNew+")");
	
	var isChangeWhite = valueWhiteOld!=valueWhiteNew,
		isChangeColor = valueColorOld!=valueColorNew;

	console.debug(" *** WhiteColor *** HandlerWhiteColor (\'isChangeWhite\':"+isChangeWhite+", \'isChangeColor\':"+isChangeColor+")");
		
	if (!isChangeWhite && !isChangeColor) return;

	if ((valueWhiteNew > 0) || (valueColorNew === 0)) {
		self.TimerStop(self);	
	}
	
	self.config.devices.forEach(function(dev) {    
		if (dev.active) {
          	var dMaster = self.controller.devices.get(dev.dMaster);
           	var dWhite = self.controller.devices.get(dev.dWhite);
           	var dColor = self.controller.devices.get(dev.dColor);
			
			if ((valueWhiteOld === 0) && (valueWhiteNew > 0)) {
				dColor.performCommand("exact", {red:0,green:0,blue:0} );
				dWhite.performCommand("exact", {level:255} );
			}
			if (valueWhiteNew === 0) {
				dWhite.performCommand("exact", {level:0} );
				dColor.performCommand("exact", (valueColorNew > 0?self.HSBtoRGB(self.iHue,1.0,1.0):{red:0,green:0,blue:0}) );
			}

			dMaster.performCommand("exact", {level: (valueWhiteNew > 0?valueWhiteNew:valueColorNew) } );
		} // if (dev.active)
	}); // self.config.devices.forEach	
	
	if ((valueWhiteNew === 0) && (valueColorNew > 0)) {
		self.TimerStart(self);
	}
}

WhiteColor.prototype.TimerStart = function(instance) {
	var self = instance;

	console.debug(" *** WhiteColor *** TimerStart");
	if (self.timer == null) {   
		console.debug(" *** WhiteColor *** setInterval");
		self.timer = setInterval(function() {
				self.TimerNextStep(self);
		},
		self.config.frequency);
	}                   
};

WhiteColor.prototype.TimerStop = function(instance) {
	var self = instance;

	console.debug(" *** WhiteColor *** TimerStop");
	if (self.timer != null) {
		console.debug(" *** WhiteColor *** clearInterval");
		clearInterval(self.timer);
		self.timer = null;
	}   
};

WhiteColor.prototype.TimerNextStep = function(instance) {
    var self = instance,
        moduleName = "WhiteColor",
        langFile = self.controller.loadModuleLang(moduleName),
		vDev = null,
		rgbcolor = self.HSBtoRGB(self.iHue,1.0,1.0); 
	
	console.debug(" *** WhiteColor *** MyTime \'" + (new Date()).getTime() + "\':"); 
	self.config.devices.forEach(function(dev) {
		if (dev.active) {
           	vDevColor = self.controller.devices.get(dev.dColor);
			if (vDevColor) {           
				vDevColor.performCommand("exact", rgbcolor);
			}
		}
	});
	
	self.iHue += self.config.step;
		
	if (self.iHue > 1.0) self.iHue = 0.0;
};

WhiteColor.prototype.HSBtoRGB = function(h, s, b) {
                        h *= 360;
                        var R, G, B, X, C;
                        h = (h % 360) / 60;
                        C = b * s;
                        X = C * (1 - Math.abs(h % 2 - 1));
                        R = G = B = b - C;

                        h = ~~h;
                        R += [C, X, 0, 0, X, C][h];
                        G += [X, C, C, X, 0, 0][h];
                        B += [0, 0, X, C, C, X][h];
                        return {
                            red: Math.round(R * 255),
                            green: Math.round(G * 255),
                            blue: Math.round(B * 255)
                        };
};
и частотой 1000 нагрузка увеличивается на 20-30% (htop). Куда копать дальше - не знаю.

И, кстати: когда вызываю vDevWhite.set("metrics:level", что-то больше 0); в web-интерфейсе level отображается правильно, но при этом выкл. Перегружаешь страницу и становится вкл.
alv1home
Posts: 91
Joined: 24 Jun 2015 22:04

Re: Zipato RGBW

Post by alv1home »

УЖАС!

Подключил вторую лампу, нагрузка выросла до 90%. Грузит строчка

Code: Select all

vDevColor.performCommand("exact", rgbcolor);
.
Вопрос: можно эту команду заменить на что-то менее энергоемкое?
User avatar
PoltoS
Posts: 7565
Joined: 26 Jan 2011 19:36

Re: Zipato RGBW

Post by PoltoS »

А вы пробовали отладчик JS подключить? Также поставьте много console.log по коду чтоб понять, какие куски часто работают. Если загрузка большая, значит какой-то лишний код выполняется.

Учли, что у setInterval второй параметр в 0.001 сек, а не 1 сек?
alv1home
Posts: 91
Joined: 24 Jun 2015 22:04

Re: Zipato RGBW

Post by alv1home »

Нашел, быть может.

В performCommand есть вызов this.controller.loadMainLang(). У меня lang'ов не было, как и папки (ну не нужны мне они). На этом затыкалось. Пару дней погоняю, проверю.

Про setInterval - учел.
alv1home
Posts: 91
Joined: 24 Jun 2015 22:04

Re: Zipato RGBW

Post by alv1home »

Предложение (или просьба)

функцию

Code: Select all

    performCommand: function () {
        var langFile = this.controller.loadMainLang();

        console.log("--- ", this.id, "performCommand processing:", JSON.stringify(arguments));
        if (typeof this.handler === "function") {
            try {
                return this.handler.apply(this, arguments);
            } catch(e) {
                this.controller.addNotification("error", langFile.vd_err_virtual_dev + e.toString(), "module", "VirtualDevice");
                console.log(e.stack);
            }
        }
    },
переписать в таком виде (если возможно)

Code: Select all

    performCommand: function () {
        console.log("--- ", this.id, "performCommand processing:", JSON.stringify(arguments));
        if (typeof this.handler === "function") {
            try {
                return this.handler.apply(this, arguments);
            } catch(e) {
                var langFile = this.controller.loadMainLang();
                this.controller.addNotification("error", langFile.vd_err_virtual_dev + e.toString(), "module", "VirtualDevice");
                console.log(e.stack);
            }
        }
    },
User avatar
PoltoS
Posts: 7565
Joined: 26 Jan 2011 19:36

Re: Zipato RGBW

Post by PoltoS »

вы абсолютно правы. лучше в следующий раз сделать это через pull request на github. Уже поправил и войдёт в ближайший релиз
pofs
Posts: 688
Joined: 25 Mar 2011 19:03

Re: Zipato RGBW

Post by pofs »

Не забывайте убивать таймер в stop(), а то перезапуски модуля будут плодить лишние таймеры
alv1home
Posts: 91
Joined: 24 Jun 2015 22:04

Re: Zipato RGBW

Post by alv1home »

Я поторопился!
Нагрузка снизилась до 30%-40%. Т.е. при выполнении команды SetMulti... (чего-то там, не помню) скачок с 15% до 40%. Это замечательно по сравнению с тем, что было. Но 2 лампы - это 60%-70%.

ЗЫЖ Таймер "убиваю" (как мне кажется: clearInterval и timer=null).
alv1home
Posts: 91
Joined: 24 Jun 2015 22:04

Re: Zipato RGBW

Post by alv1home »

Побаловался с модулем Fibaro RGBW.
В настройках модуля настроил плавное изменение цвета за 8 сек (параметр 10). В 10 секундном цикле меняю цвет. Razberry "умирает".
Что выведал.
При любом изменении цвета (не крайних заданных значениях, а при любом промежуточном) модуль отправляет отчет в группу 5. В итоге: отчетов очень большое количество, контроллер (или скорей плата Razberry) захлебывается. Сейчас выкинул контроллер из группы - стало красиво (нагрузка растет до 50% при посылке команды, но это раз в 10 сек).
Post Reply