Improving the reliability of the smart home controller on Majordomo (MQTT)

So, my smart home is ready, listens to voices, controls the climate, battery charging in the country (https://habr.com/ru/post/538896/).





Moreover, smart devices now stand both in the country and at home, in the city. Moreover, due to the peculiarities of ecosystem compatibility with Yandex, some of the devices at home (RGB tapes) are controlled through a server on Majordomo (dacha).





And here a number of logical questions arise:





  • Where should the server be located - at home or in the country?





  • The loss of control of what devices to sacrifice when the connection between the house and the cottage is broken?





  • How not to load the GSM channel before the transfer of graphs in the HTML layout of the site?





It's easy to guess that the answer is reservation :





  1. Servers must be there and there





  2. Servers must be able to manage all devices





  3. Servers must have a complete dataset





Since the sensors communicate with the server mainly through the MQTT protocol, the MQTT broker also becomes a point of failure.





Server redundancy

Let's start with the MQTT broker. Except for messages such as LWT ("last will of the device") and Retain (stored on the server), most messages are sent simultaneously and only to those who are currently connected to the broker. That is, "sent - forgot".





, 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);
	}
}
      
      



Here is such a widget, while clumsy, but informative
, ,

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.





So, by adding a server for 2500 rubles, I received full redundancy of a message broker, a device management server (logic), and you can receive graphs with up-to-date data from a home server without loading a server that works via a GSM modem.








All Articles