Melhorando a confiabilidade do controlador de casa inteligente no Majordomo (MQTT)

Então, minha casa inteligente está pronta, ouve vozes, controla o clima, carrega bateria no país (https://habr.com/ru/post/538896/).





Além disso, os dispositivos inteligentes agora estão tanto no campo quanto em casa, na cidade. Além disso, devido às peculiaridades da compatibilidade do ecossistema com o Yandex, alguns dos dispositivos em casa (fitas RGB) são controlados por meio de um servidor no Majordomo (dacha).





E aqui surgem várias questões lógicas:





  • Onde o servidor deve estar localizado - em casa ou no país?





  • A perda de controle de quais dispositivos sacrificar quando a conexão entre a casa e a cabana é quebrada?





  • Como não carregar o canal GSM antes da transferência dos gráficos no layout HTML do site?





É fácil adivinhar que a resposta é reserva :





  1. Os servidores devem estar lá e lá





  2. Os servidores devem ser capazes de gerenciar todos os dispositivos





  3. Os servidores devem ter um conjunto de dados completo





Como os sensores se comunicam com o servidor principalmente por meio do protocolo MQTT, o broker MQTT também se torna um ponto de falha.





Redundância de servidor

Vamos começar com o broker MQTT. Exceto por mensagens como LWT ("última vontade do dispositivo") e Retain (armazenada no servidor), a maioria das mensagens é enviada simultaneamente e apenas para aqueles que estão atualmente conectados ao broker. Ou seja, "enviado - esquecido".





, mosquitto – , , . « ». raspbian/armbian – /etc/mosquito/mosquito.conf:





#connection bridge-01
connection bridge-01
address mqtt.mydomain.ru:1883
topic # out 0
topic # in 0
      
      



, , ( ).





, Majordomo. Orange pi one plus (1Gb RAM) – 2 Raspberry Pi4, - , . , ( , 2 – , , , ).





MQTT, MQTT. , 2 ( ) 2 – , . 10 MQTT – (ThisComputer.cycle_mqttRun). (time()). 10 – , , MQTT . MQTT ( MQTT). 20 , – , . , MQTT – . , :





$val=getGlobal("ThisComputer.cycle_mqttRun");
$locval=time()-$val;
$this->setProperty("LocValue",$val);
$this->setProperty("LocDeltaT",$locval);
if($locval>10)
	$locstate=1;
else
  $locstate=0;
$tmp=$this->getProperty("Status");
if(is_null($tmp))
	$tmp=10;
if($tmp!=$locstate)
	$this->setProperty("Status",$locstate);
$remval=time()-$this->getProperty("RemValue");
$newstate=($remval<20)?0:1;
$this->setProperty("RemStatus",$newstate);
$ot = $this->object_title;
$currBroker=$this->getProperty("MQTT_broker");
$sA=$this->getProperty("selfAddress");
if($sA!=$currBroker)
	$this->setProperty("isController",0);
setTimeOut($ot . "_checkCycle",'callMethod("'.$ot.'.checkCycle");',10);
if(
	(!$locstate&&($newstate||($this->getProperty("LinkedRoom")=="Energoblok")))&&
	($sA!=$currBroker)
)// remote failed local good or local is good and is not local server
{
	debMes('Switch to '.$this->getProperty("selfAddress"),0);
	$cnt=0;
	for($i=40;$i<90;$i++)
	{
		if(ping('192.168.3.'.number_format($i,0)))
    {
			getURL('http://192.168.3.'.number_format($i,0).'/cm?cmnd=MqttHost%20'.$this->getProperty("selfAddress"));
			debMEs('http://192.168.3.'.number_format($i,0).' is online',0);
			$cnt++;
			$this->setProperty("LocValue",time());
		}
	}
	if($cnt>10)
	{
		$this->setProperty("MQTT_broker",$this->getProperty("selfAddress"));
		$this->setProperty("isController",1);
	}
}
      
      



Aqui está um widget, embora desajeitado, mas informativo
, ,

Tasmota (IP c 192.168.3.40 192.168.3.90), URL MQTT . , – MQTT . – , 10 , . . .





. 1 2, . , , / – . 1200 .





, . , Majordomo Raspberry , ( 1, orange pi zero c 512 - 300 ). , , , ( !). – .





– , . :





  • ( , java )





  • ( – getProperty\setProperty ).





– , , :





if((($temp2Floor=getGlobal("sTemp2Floor.value"))<'21')&&
	gg("remote_mqtt_updated.isController")) // if remote failed
{
		if ($temp2Floor < '21' && !getGlobal("rConserveSW.status") && timeBetween('2:00', '8:00')) 
		{
  		if (!getGlobal("rDieselHome.status")) 
			{
   	 		callMethod("rDieselHome.turnOn");
  		}
		} else if ($temp2Floor > '23') 
		{
  		if (getGlobal("rDieselHome.status")) 
			{
    		callMethod("rDieselHome.turnOff");
  		}
		}
}
      
      



, , (gg("remote_mqtt_updated.isController")). remote_mqtt_updated – .





380 , 1200.





Então, ao adicionar um servidor de 2.500 rublos, recebi redundância total de um corretor de mensagens, um servidor de gerenciamento de dispositivo (lógica), e você pode receber gráficos com dados atualizados de um servidor doméstico sem carregar um servidor que funciona via um modem GSM.








All Articles