Page 1 of 1

Remeha control using RS232 port

Posted: Mon Oct 10, 2016 8:30 pm
by lifer
Hi,

It is possible to control a Remeha boiler (set point, status and so on) using the RS232 port? As far as I've read, everybody is using the OT port (by implementing a gateway). I don't have any OT thermostat (nor gateway) thus I want to control the boiler using an Arduino through a serial connection.

Is there any information available about the serial requests to get/set the boiler parameters? Thank you in advance for any help.

Re: Remeha control using RS232 port

Posted: Tue Oct 11, 2016 4:20 am
by lifer
Looks like all the scripts written for the Remeha RS232 port communications only read data from the boiler. I thought this serial port is a decoded OT interface (TTL compatible). Am I wrong? Is this serial interface made "read only" on purpose (by the manufacturer)?

The Recom software (which is using the same serial interface) could not write any settings to the boiler (not by the regular users but the Remeha professionals)?

Re: Remeha control using RS232 port

Posted: Tue Oct 11, 2016 6:51 pm
by lifer
I've tried to add a further comment to my first post but the messages was in "moderated" stage for a whole day then it just vanished.

Could anyone (mod) tell me why that message was censored? I was just asking if the communication through the RS232 port is "read only" on purpose (manufacturer) or the Recom software could also set/modify some boiler parameters (including the setpoint) if you have "admin" rights.

Also, I was wondering if the RS232 port is just a clone (TTL level) of the OpenTherm port.

Thank you very much for your time.

Re: Remeha control using RS232 port

Posted: Wed Oct 12, 2016 2:19 am
by lifer
Looks like I'll be walking alone (in this thread) for awhile thus I'm going to tell you a little story.

Back in the 2012, I've just discovered this forum (and @Digit blog for that matter) and I was very impressed by the possibilities of fully controlling a HVAC system (Remeha boiler). As I was in the market for a new boiler, I've searched the local dealers and finally bought a Remeha Quinta Pro 45. As a side note, this model is different from the old "Quinta" one, being an updated version (similar to Calenta/Avanta).

Well, I did't have enough time (at that time) to fulfill my dream (remote controlling my boiler over the internet). You may notice my first post back in that period when I was just testing the Recom software and played with the RS232 to TTL interface.

There were some professional changes in my life during that period too hence I was forced to abort this project. The Remeha walked alone through these years with an old "blind" (aka on/off) thermostat but it survived. ;)

Now I finally have the time to finish my project (along with an entire home automation diy system) so here I am, asking for guidance. After all, you guys owe me some help for the decision I've made four years ago! (j/k)

I've read a lot of threads on this matter but, like I've just said, I saw that everyone is using an OT thermostat and a commercially/diy OT gateway interface to do the job. I must confes that I was a little bit disappointed to find that things didn't changed a lot in the mean time and the (easier to build) RS232 interface seems an obsolete and useless option.

So I'm asking it again: is this interface a "read only" one? At least, I want to know if it worth trying to further investigate, based on your past experience.

The way I saw it, it supposed to be just a TTL clone of that Manchester coded OpenTherm interface (the former being more convenient for master/slave operations). Also, the OT port allow a 2-wire communication and a compatible interface with the dumb on/off thermostats while RS232 it's a 3-wire interface. But aren't those commands similar when using RS232 or OT (Manchester) interfaces?

Btw, I only have linux all around me for years thus I could not test/sniff Recom software for now (though a virtual machine could be an option).

Sorry for this long message but I just wanted to explain the time gap (2012 - 2016) between my posts. Thank you once again for your time.

Re: Remeha control using RS232 port

Posted: Fri Dec 09, 2016 2:30 pm
by rjblake
lifer wrote:....

So I'm asking it again: is this interface a "read only" one? At least, I want to know if it worth trying to further investigate, based on your past experience.

....
From what I have found out, it is for all intents and purposes read only. What you'd be wanting to do (change setpoint, temperature, etc.) is apparently not possible through this interface. Just go ahead and buy/build an OTGW and you'll be set to go.

Re: Remeha control using RS232 port

Posted: Fri Dec 09, 2016 7:20 pm
by D_Hailsham
rjblake wrote:From what I have found out, it is for all intents and purposes read only. What you'd be wanting to do (change setpoint, temperature, etc.) is apparently not possible through this interface. Just go ahead and buy/build an OTGW and you'll be set to go.
There are six parameters which can be changed:

1. Flow temperature setpoint
2. DHW setpoint (only useful if you have a sensor to measure the HW temperature).
3. Boiler control CH on/off; HW on/off)
4. Comfort DHW (preheat for combi boilers)
5. Anticipator on/off (mechanical stat with anticipator)
6. Display on/off

These are equivalent to Avanta parameters P1 to P6, but do not necessarily have OT ID's.

Re: Remeha control using RS232 port

Posted: Sat Dec 10, 2016 2:33 pm
by richard naninck
Just saw this thread. You are not alone.
I control an Avata and a Quinta through the RS232 TTL port. For both units I bought the serial interface but I could have built them myself as well since the hardware seems very easy to build.
I mainly read from the bus and used the Recom software to sniff all the messages. I use the FS20 system for all my radiators and control the units on and off using the thermostat overtime switch connected with two relais to my system.
I built somekind of proportional heat request system to control the quinta's output temperature. I many FS20 radiator valves are open, the units output is raised and vise versa ranging between 55 and 90 degrees C of output heat. That is about the only thing I write to the bus using these messages to the quinta:

Code: Select all

'-------------------------------------------------------
'- Set CV Max Aanvoer Temperatuur ----------------------
'-------------------------------------------------------
Sub Set_CVAanvoer(Data)

	Select Case Data
		Case "55": SetPropertyValue "Quinta.Send Data", "0A43A0403703415A50AE"
		Case "60": SetPropertyValue "Quinta.Send Data", "0A43A0403C03415A50A9"
		Case "65": SetPropertyValue "Quinta.Send Data", "0A43A0404103415A50A4"
		Case "70": SetPropertyValue "Quinta.Send Data", "0A43A0404603415A509F"
		Case "75": SetPropertyValue "Quinta.Send Data", "0A43A0404B03415A509A"
		Case "80": SetPropertyValue "Quinta.Send Data", "0A43A0405003415A5095"
		Case "85": SetPropertyValue "Quinta.Send Data", "0A43A0405503415A5090"
		Case "90": SetPropertyValue "Quinta.Send Data", "0A43A0405A03415A508B"
	End Select
	
	Sleep 500
	SetPropertyValue "Quinta.Send Data", "0741AE400000CA"
	Sleep 500
	SetPropertyValue "Quinta.Send Data", "0741AE400020AA"
	Sleep 500
	SetPropertyValue "Quinta.Send Data", "0742A04008408F"
End Sub

Re: Remeha control using RS232 port

Posted: Sun Dec 11, 2016 11:37 pm
by rjblake
While on the subject of the RS232 port, has anyone taken a look at the Remeha Smart Service Support tool? I see it has a WiFi interface and curious if it can be connected up to Domotica systems for even more control than Opentherm allows. Alternatively, I'm trying to come up with a device that'll provide a WiFi interface to my Remeha Calenta - just not sure exactly how best to do it

Re: Remeha control using RS232 port

Posted: Wed Dec 14, 2016 2:51 pm
by rjblake
rjblake wrote:While on the subject of the RS232 port, has anyone taken a look at the Remeha Smart Service Support tool? I see it has a WiFi interface and curious if it can be connected up to Domotica systems for even more control than Opentherm allows. Alternatively, I'm trying to come up with a device that'll provide a WiFi interface to my Remeha Calenta - just not sure exactly how best to do it
Some further investigation and I have now hooked up a simple ESP8266 (5V version) with the ESP-Link firmware to the RS232 port and using Realterm have managed to send/receive data to the Calenta. Now need to decipher & map the HEX responses and incorporate these into a script to make them all more humanly readable. If this all works, a cheap ($10.00) and simple solution for controlling my boiler :)

Re: Remeha control using RS232 port

Posted: Tue Jan 10, 2017 11:48 pm
by rjblake
So the long and the short of it is that the exercise was fairly simple in the end - at least to get the reported data from the Remeha Calenta - no need for fancy Remeha cables as a simple 5VDC ESP8266 will do the exact same job. Wire up to an RJ10 connector and you're in business. I found various resources that had bits of code and info to get a readout from the Calenta and ended up creating the PHP script below for those who want to do the same. There is some Domoticz related code in the script, but can easily be identified and stripped out/changed to update system of your choosing. There are also ID's that are not correct and I'm busy debugging as time allows. After that I'll start working on the counters/locking/blocking data from the Calenta.

Code: Select all

<?php
// Uncomment to report Errors for Debug purposes
// error_reporting(E_ALL);

function hex_dump($data, $newline="<br>")
{
	static $from = '';
	static $to = '';
	static $width = 16; # number of bytes per line
	static $pad = '.'; # padding for non-visible characters

	if ($from==='')
	{
	for ($i=0; $i<=0xFF; $i++)
		{
    		$from .= chr($i);
    		$to .= ($i >= 0x20 && $i <= 0x7E) ? chr($i) : $pad;
		}
	}

	$decode = str_split(bin2hex($data), 2);
	$hexstr = str_split(bin2hex($data), 148);
	
	echo "<br />Show result before decoding...<br />";
	echo "==========================<br />";	
  
	// Uncomment to show native response from Calenta
	// echo bin2hex($data);
	// echo "<br />"; 
	//
	// Uncomment to add full response to an Array 
	// print_r($hexstr);
	// echo "<br />"; 
	//
	// Uncomment to show array elements
	// print_r($decode);
	// echo "<br />";
	//
	
	echo "<br />Start decoding...<br /><br />";
  
	//Define variables and append correct bytes

	$flowtemperature ="";
	$flowtemperature .= $decode["8"];
	$flowtemperature .= $decode["7"];
	// More debug data display
	// echo "<br />";
	// echo $flowtemperature;
	// echo "<br />";  	
	// echo hexdec($decode["8"])*256;
	// echo "<br />"; 	  
	// echo hexdec($decode["7"]);
	// echo "<br />"; 	  
	   
	$returntemperature = "";
	$returntemperature .= $decode["10"];
	$returntemperature .= $decode["9"];

	$outsidetemperature = "";
	$outsidetemperature .= $decode["14"];
	$outsidetemperature .= $decode["13"];
	if ($outsidetemperature == 8000) {$outsidetemperature = 0.00;}
	else {$outsidetemperature == $outsidetemperature;} 	  
	   
	$roomtemperature = "";
	$roomtemperature .= $decode["22"];
	$roomtemperature .= $decode["21"];
  
	$controltemperature = "";
	$controltemperature .= $decode["59"];
	$controltemperature .= $decode["58"];

	$caloriftemperature = "";
	$caloriftemperature .= $decode["12"];
	$caloriftemperature .= $decode["11"];
	if ($caloriftemperature == 8000) {$caloriftemperature = 0.00;}
	else {$caloriftemperature == $caloriftemperature;} 	  
      
	$thermostat = "";
	$thermostat .= $decode["28"];
	$thermostat .= $decode["27"];
  
	$chsetpoint = "";
	$chsetpoint .= $decode ["24"];
	$chsetpoint .= $decode ["23"];
  
	$dhwsetpoint = "";
	$dhwsetpoint .= $decode ["26"];
	$dhwsetpoint .= $decode ["25"];
  
	$internalsetpoint = "";
	$internalsetpoint .= $decode ["35"];
	$internalsetpoint .= $decode ["34"];
  
	$boilerctrltemperature = "";
	$boilerctrltemperature .= $decode ["20"];
	$boilerctrltemperature .= $decode ["19"];

  	$fanspeed = "";
	$fanspeed .= $decode ["32"];
	$fanspeed .= $decode ["31"];
  
	$fanspeedsetpoint = "";
	$fanspeedsetpoint .= $decode ["30"];
	$fanspeedsetpoint .= $decode ["29"];
  
	$ionisationcurrent = "";
	$ionisationcurrent .= $decode ["33"];
  
	$pumppower = "";
	$pumppower .= $decode ["37"];
  
	$pressure = "";
	$pressure .= $decode ["56"];
  
	$dhwflowrate = "";
	$dhwflowrate .= $decode ["61"];
	$dhwflowrate .= $decode ["60"];	
  
	$actualpower = "";
	$actualpower .= $decode ["40"];
  
	$requiredoutput = "";
	$requiredoutput .= $decode ["39"];
    
	$availablepower = "";
	$availablepower .= $decode ["36"];
    
	$modrequest = "";
	$modrequest .= $decode ["43"];
  
	$ionisation = "";
	$ionisation .= $decode ["44"];
  
	$valves = "";
	$valves .= $decode ["45"];
  
	$pump = "";
	$pump .= $decode ["46"];
  
	$status = "";
	$status .= $decode ["47"];
  
//Convert Hex2Dec 
	$returntemperature = hexdec($returntemperature) / 100;
  	$flowtemperature = hexdec($flowtemperature) / 100;
	$outsidetemperature = hexdec($outsidetemperature) / 100;	
  	$roomtemperature = hexdec($roomtemperature) / 100;
  	$controltemperature = hexdec($controltemperature) / 100;
  	$caloriftemperature = hexdec($caloriftemperature) / 100;  
  	$boilerctrltemperature = hexdec($boilerctrltemperature) / 100;  		
  	$thermostat = hexdec($thermostat) /100;
  	$chsetpoint = hexdec($chsetpoint) /100;
  	$dhwsetpoint = hexdec($dhwsetpoint) /100;
  	$internalsetpoint = hexdec($internalsetpoint) /100;
  	$fanspeed = hexdec($fanspeed);
  	$fanspeedsetpoint = hexdec($fanspeedsetpoint);
  	$ionisationcurrent = hexdec($ionisationcurrent)/10;
  	$pumppower = hexdec($pumppower);
  	$pressure = hexdec($pressure)/10;
  	$dhwflowrate = hexdec($dhwflowrate)/100;
  	$actualpower = hexdec($actualpower);
  	$requiredoutput = hexdec($requiredoutput);
  	$availablepower = hexdec($availablepower);  	
  	
  	$modrequest = hexdec($modrequest);
  	if ($modrequest == 17) {$modulationdemand = "No"; $DHWRequest ="No"; $DHWEco = "No";}
  	elseif ($modrequest == 145) {$modulationdemand = "No"; $DHWRequest = "Yes"; $DHWEco = "No";}
  	elseif ($modrequest == 19) {$modulationdemand = "Yes"; $DHWRequest = "No"; $DHWEco = "No";}
  	elseif ($modrequest == 1) {$modulationdemand = "No"; $DHWRequest = "No"; $DHWEco = "Yes";}  	
  	elseif ($modrequest == 3) {$modulationdemand = "Yes"; $DHWRequest = "No"; $DHWEco = "Yes";}
  	elseif ($modrequest == 129) {$modulationdemand = "No"; $DHWRequest = "Yes"; $DHWEco = "Yes";}  	
  	elseif ($modrequest == 131) {$modulationdemand = "Yes"; $DHWRequest = "Yes"; $DHWEco = "Yes";}  	  	  	
  	else {$modulationdemand = "Unknown"; $DHWRequest = "Unknown"; $DHWEco = "Unknown";}  
  	
  	$ionisation = hexdec($ionisation);
  	if ($ionisation == 194) {$ionisation = "No";}
  	elseif ($ionisation == 198) {$ionisation = "Yes";}
  	else {$ionisation = "Unknown";}
  
  	$valves = hexdec($valves);
  	if ($valves == 64 ) {$threewayvalve = "CH"; $gas = "Open"; $ignition ="Off";}
  	elseif ($valves == 11 ) {$threewayvalve = "DHW"; $gas = "Closed"; $ignition ="Off";}
  	elseif ($valves == 3 ) {$threewayvalve = "CH"; $gas = "Open"; $ignition ="Off";}
  	elseif ($valves == 88 ) {$threewayvalve = "DHW"; $gas = "Open"; $ignition ="Off";}
  	else {$threewayvalve = "Unknown"; $gas = "Unknown"; $ignition ="Unknown";}
  
  	$pump = hexdec($pump);
  	if ($pump == 53) {$pump = "On";}
  	elseif ($pump == 16) {$pump = "Off";}
  	elseif ($pump == 21) {$pump = "Post circulation";}
  	else { $pump = "Unknown";}
  
  	$status = hexdec($status);
  	if ($status == 0) {$status = "0:Standby";}
  	elseif ($status == 1) {$status = "1:Boiler Start";}
  	elseif ($status == 2) {$status = "2:Burner Start";}
  	elseif ($status == 3) {$status = "3:Burning CH";}
  	elseif ($status == 4) {$status = "4:Burning DHW";}
  	elseif ($status == 5) {$status = "5:Burner Stop";}
  	elseif ($status == 6) {$status = "6:Boiler Stop";}
  	elseif ($status == 7) {$status = "7:-";}
  	elseif ($status == 8) {$status = "8:Controlled Stop";}
  	elseif ($status == 9) {$status = "9:Blocking Mode";}
  	elseif ($status == 10) {$status = "10:Locking Mode";}
  	elseif ($status == 11) {$status = "11:Chimney mode L";}
  	elseif ($status == 12) {$status = "12:Chimney mode h";}
  	elseif ($status == 13) {$status = "13:Chimney mode H";}
  	elseif ($status == 14) {$status = "14:-";}
  	elseif ($status == 15) {$status = "15:Manual Heat Demand";}
  	elseif ($status == 16) {$status = "16:Boiler Frost Protection";}
  	elseif ($status == 17) {$status = "17:De-airation";}
  	elseif ($status == 18) {$status = "18:Controller temp protection";}
  	elseif ($status == 19) {$status = "19:-";}
  	elseif ($status == 20) {$status = "20:-";}
  	else { $status = "Unknown"; }
// end Hex2Dec conversions
  
// Display Values - ordered in line with Remeha Recom software
	echo "Received values:<br />";
	echo "=================================<br />";
  	echo "Flow Temperature:       $flowtemperature &degC<br />";
  	echo "Return Temperature:     $returntemperature &degC<br />";
  	echo "Calorifier Temperature: $caloriftemperature &degC<br />";  	
  	echo "Outside Temperature:    $outsidetemperature &degC<br />";  	
  	echo "Control Temperature:    $controltemperature &degC<br />";
  	echo "Internal Setpoint:      $internalsetpoint &degC<br />";
  	echo "CH Setpoint:            $chsetpoint &degC<br />";
  	echo "DHW Setpoint:           $dhwsetpoint &degC<br />";
  	echo "Room Temperature:       $roomtemperature &degC<br />";
  	echo "Room Temp. Setpoint:    $thermostat &degC<br />";
  	echo "Boiler Control Temp.:   $boilerctrltemperature &degC<br />";
  	echo "<br />";
  	echo "Fan Speed setpoint:     $fanspeedsetpoint RPM<br />";
  	echo "Fan Speed:              $fanspeed RPM<br />";
  	echo "Ionisation Current:     $ionisationcurrent μA<br />";
  	echo "Pump:                   $pumppower %<br />";
  	echo "Hydrostatic Pressure:   $pressure bar<br />";
  	echo "DHW Flow rate:          $dhwflowrate litres/minute<br />";
  	echo "Required Output:        $requiredoutput %<br />";
  	echo "Available Power:        $availablepower %<br />";
  	echo "Actual Power:           $actualpower %<br />";
	echo "<br />";

  	echo "Mod. Heat Demand:       $modulationdemand<br />";
  	echo "Ignition:               $ignition<br />";
  	echo "Gas Valve:              $gas<br />";
  	echo "Ionisation:             $ionisation<br />";
  	echo "Pump:                   $pump<br />";
  	echo "3-Way Valve:            $threewayvalve<br />";
  	echo "DHW Demand:             $DHWRequest<br />";
  	echo "DHW Eco:                $DHWEco<br />";
  	echo "<br />";

  	echo "(Modrequest value: $modrequest)<br />";
  	echo "(Valves value: $valves)<br />";
  	echo "<br />";

  	echo "Status:                 $status<br />";
  	
// Update Domoticz Devices with collected values
  	
// DomoticZ Device ID's
  	$flowtemperatureIDX = 93;		#Temperature
	$returntemperatureIDX = 94;		#Temperature
  	$caloriftemperatureIDX = 95;	#Temperature
  	$outsidetemperatureIDX = 96;	#Temperature
  	$controltemperatureIDX = 97;	#Temperature
  	$internalsetpointIDX = 98;		#Temperature
	$chsetpointIDX = 99;			#Temperature
	$dhwsetpointIDX = 100; 			#Temperature
	$roomtemperatureIDX = 101;		#Temperature
	$thermostatIDX = 102; 			#Temperature
	$boilerctrltemperatureIDX = 103;#Temperature
	$fanspeedsetpointIDX = 104;		#Custom Sensor - Axis Label "RPM"
  	$fanspeedIDX = 105;				#Custom Sensor - Axis Label "RPM"
  	$ionisationcurrentIDX = 106;	#Custom Sensor - Axis Label "microamps"
  	$pumppowerIDX = 107;			#Percentage 
  	$pressureIDX = 108;				#Pressure (Bar)
  	$dhwflowrateIDX = 109;			#Waterflow
  	$requiredoutputIDX = 110;		#Percentage
  	$availablepowerIDX = 111;		#Percentage
  	$actualpowerIDX = 112;			#Percentage
	$modulationdemandIDX = 113;		#Text
	$ignitionIDX = 114;				#Text
	$gasIDX = 115;					#Text
	$ionisationIDX = 116;			#Text
	$pumpIDX = 117;					#Text
	$threewayvalveIDX = 118;		#Text
	$DHWRequestIDX = 119;			#Text
	$DHWEcoIDX = 120;				#Text
	$statusIDX = 121;				#Text
// end Device ID's

// Required for DOMOTICZ ONLY - Updates Values
// Set variables for cURL updates & call udevice function to update
	$DOMOflowtemperature = udevice($flowtemperatureIDX,0,$flowtemperature);
	$DOMOreturntemperature = udevice($returntemperatureIDX,0,$returntemperature);
  	$DOMOcaloriftemperature = udevice($caloriftemperatureIDX,0,$caloriftemperature);
  	$DOMOoutsidetemperature = udevice($outsidetemperatureIDX,0,$outsidetemperature);
  	$DOMOcontroltemperature = udevice($controltemperatureIDX,0,$controltemperature);
  	$DOMOinternalsetpoint = udevice($internalsetpointIDX,0,$internalsetpoint);
	$DOMOchsetpoint = udevice($chsetpointIDX,0,$chsetpoint);
	$DOMOdhwsetpoint = udevice($dhwsetpointIDX,0,$dhwsetpoint);
	$DOMOroomtemperature = udevice($roomtemperatureIDX,0,$roomtemperature);
	$DOMOthermostat = udevice($thermostatIDX,0,$thermostat);
	$DOMOboilerctrltemp = udevice($boilerctrltemperatureIDX,0,$boilerctrltemperature);
	$DOMOfanspeedsetpoint = udevice($fanspeedsetpointIDX,0,$fanspeedsetpoint);
	$DOMOfanSpeed = udevice($fanspeedIDX,0,$fanspeed);
	$DOMOionisationCurent = udevice($ionisationcurrentIDX,0,$ionisationcurrent);
  	$DOMOpumppower = udevice($pumppowerIDX,0,$pumppower);
  	$DOMOpressure = udevice($pressureIDX,0,$pressure);
	$DOMOdhwflowrate = udevice($dhwflowrateIDX,0,$dhwflowrate);
  	$DOMOrequiredoutput = udevice($requiredoutputIDX,0,$requiredoutput);
  	$DOMOavailablepower = udevice($availablepowerIDX,0,$availablepower);
  	$DOMOactualpower = udevice($actualpowerIDX,0,$actualpower);
	$DOMOmodulationdemand = udevice($modulationdemandIDX,0,$modulationdemand);
	$DOMOignition = udevice($ignitionIDX,0,$ignition);
	$DOMOgas = udevice($gasIDX,0,$gas);
	$DOMOionisation = udevice($ionisationIDX,0,$ionisation);
	$DOMOpump = udevice($pumpIDX,0,$pump);
	$DOMOthreewayvalve = udevice($threewayvalveIDX,0,$threewayvalve);
	$DOMODHWRequest = udevice($DHWRequestIDX,0,$DHWRequest);
	$DOMODHWEco = udevice($DHWEcoIDX,0,$DHWEco);
	$DOMOstatus = udevice($statusIDX,0,str_replace(' ', '%20', $status));
// end set variables for cURL updates

}

// Function to update Domoticz using cURL
//
function udevice($idx,$nvalue,$svalue) 
{
//IP Address & Port of Domoticz Server - NOT ESP8266 IP & Port	
	$DOMOIPAddress = "192.168.XXX.XXX";
	$DOMOPort = XXXX;

	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, "http://$DOMOIPAddress:$DOMOPort/json.htm?type=command&param=udevice&idx=$idx&nvalue=$nvalue&svalue=$svalue");
	// Debug cURL string
	echo "<br />http://$DOMOIPAddress:$DOMOPort/json.htm?type=command&param=udevice&idx=$idx&nvalue=$nvalue&svalue=$svalue<br />";

	curl_exec($ch);
	curl_close($ch);
	// Sleep for 1/4 sec - in case system stressed/slow
	// usleep(250000);
}

// Hex string to get data values from Calenta - 02 FE 01 05 08 02 01 69 AB 03 - does not include counters
// Change as required for specific model (Calenta, avanta, etc...)
//
$remeha1=chr(0x02).chr(0xFE).chr(0x01).chr(0x05).chr(0x08).chr(0x02).chr(0x01).chr(0x69).chr(0xAB).chr(0x03);

// Open connection to ESP connected to Calenta
// Change to your own IP Address and Port
//
$ESPIPAddress = "192.168.178.91";
$ESPPort = 23;
$fp=fsockopen($ESPIPAddress,$ESPPort, $errno, $errstr, 30);
if (!$fp) 
	{
	echo "ERROR opening port<br />";
	echo $errno;
	echo $errstr;
	} 
else 
	{
	echo "Connected to port<br />";
   	echo "Sending request...<br />";
   	// Send the Hex String to the Remeha
   	fputs($fp,$remeha1);
	echo "Request sent, reading answer...<br />";
   	
   	$data="";
   	$data=fread($fp, 180);
   
	echo "Answer read<br />";
	$output = hex_dump($data);
  
  	echo "<br />";
  	fclose($fp);
	echo "Connection closed<br /><br />";
	} 

?>

Re: Remeha control using RS232 port

Posted: Sun Feb 05, 2017 11:12 pm
by rjblake
Scrap the previous post's code - I've made quite some changes and updates and decided it better to maintain a current version on Github (https://github.com/rjblake/remeha)

Re: Remeha control using RS232 port

Posted: Sun Jan 07, 2018 2:33 pm
by lifer
Hello,

Does anyone have any plain C code to read/write the boiler status/parameters using an arduino board? Once again, I'm talking about the boiler serial port not the OT one.

I've tried to clean up the @rjblake php scripts above with no luck (as they have severe curl/network/domoticz influences).

I just need some basic serial read/write (and data decoding) functions to communicate with the boiler (Quinta Pro).

Thanks in advance for any help.

PS: I've searched the forum/internet but I didn't found anything (yet).

Re: Remeha control using RS232 port

Posted: Sun Jan 07, 2018 9:22 pm
by Menno
Code below is what I use for reading Remeha Calenta parameters.
Just try it, maybe you can modify it for your boiler.

Code: Select all

#include <SoftwareSerial.h>

String inString = String(35);
String InputString;
unsigned long previousMillis = 0;
unsigned int delay_interval = 10000;

byte remeha_data[] = {0x02, 0xfe, 0x01, 0x05, 0x08, 0x02, 0x01, 0x69, 0xAB, 0x03};
SoftwareSerial mySerial(8, 9); // RX, TX
bool ready_flag = 0;
int i = 0;
unsigned long serialIn; // Set and wipe variable
byte inbuffer[100];
float aanvoertemperatuur, retourtemperatuur, buitentemperatuur, ruimtetemperatuur, CVsetpoint, WWsetpoint, Ruimtesetpoint,
      ventilatortoeren, ionisatiestroom, pompvermogen, waterdruk, tapdebiet, geleverdvermogen;
String warmtevraag, ontsteking, gasklep, ionisatie, pomp, driewegklep, ww_warmtevraag, eco, ketelstatus;

void setup() {
   // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.println(F("start"));

  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);
  delay(500);

while (mySerial.available() > 0) {
mySerial.read();
}
  mySerial.write( (uint8_t*)remeha_data, sizeof(remeha_data) );
}


void decode_data() {
  aanvoertemperatuur = float((inbuffer[8] * 256 + inbuffer[7])) / 100 ;
  Serial.println("Aanvoertemperatuur: " + String(aanvoertemperatuur) + " °C");

  retourtemperatuur = float((inbuffer[10] * 256 + inbuffer[9])) / 100 ;
  Serial.print(F("Retourtemperatuur: "));
  Serial.println(String(retourtemperatuur) + " °C");

  buitentemperatuur = float((inbuffer[14] * 256 + inbuffer[13])) / 100 ;
  Serial.print(F("Buitentemperatuur: "));
  Serial.println(String(buitentemperatuur) + " °C");

  ruimtetemperatuur = float((inbuffer[22] * 256 + inbuffer[21])) / 100 ;
  Serial.print(F("Ruimtetemperatuur: "));
  Serial.println(String(ruimtetemperatuur) + " °C");

  CVsetpoint = float((inbuffer[24] * 256 + inbuffer[23])) / 100 ;
  Serial.print(F("CV-setpoint: "));
  Serial.println(String(CVsetpoint) + " °C");

  WWsetpoint = float((inbuffer[26] * 256 + inbuffer[25])) / 100 ;
  Serial.print(F("WW-setpoint: "));
  Serial.println(String(WWsetpoint) + " °C");

  Ruimtesetpoint = float((inbuffer[28] * 256 + inbuffer[27])) / 100 ;
  Serial.print(F("Ruimte-setpoint: "));
  Serial.println(String(Ruimtesetpoint) + " °C");

  ventilatortoeren = float((inbuffer[32] * 256 + inbuffer[31])) / 100 ;
  Serial.print(F("Ventilator toeren: "));
  Serial.println(String(ventilatortoeren) + " rpm");

  ionisatiestroom = float(inbuffer[33]) ;
  Serial.print(F("Ionisatiestroom: "));
  Serial.println(String(ionisatiestroom) + " uA");

  pompvermogen = float(inbuffer[37]) ;
  Serial.print(F("Pompvermogen: "));
  Serial.println(String(pompvermogen) + " %");

  waterdruk = float(inbuffer[56]) / 10 ;
  Serial.print(F("Waterdruk: "));
  Serial.println(String(waterdruk) + " Bar");

  tapdebiet = float(inbuffer[60]) / 10 ;
  Serial.print(F("Tapdebiet: "));
  Serial.println(String(tapdebiet) + " l/min");

  geleverdvermogen = float(inbuffer[40]) ;
  Serial.print(F("Geleverd vermogen: "));
  Serial.println(String(geleverdvermogen) + " %");

  if ((inbuffer[43] & 2) == 2) {
    warmtevraag = "ja";
  }
  else {
    warmtevraag = "nee";
  }
  Serial.print(F("Mod. Warmtevraag: "));
  Serial.println(warmtevraag);

  if ((inbuffer[45] & 4) == 4) {
    ontsteking = "aan";
  }
  else {
    ontsteking = "uit";
  }
  Serial.print(F("Ontsteking: "));
  Serial.println(ontsteking);

  if ((inbuffer[45] & 1) == 1) {
    gasklep = "dicht";
  }
  else {
    gasklep = "open";
  }
  Serial.print(F("Gasklep: "));
  Serial.println(gasklep);

  if ((inbuffer[44] & 4) == 4) {
    ionisatie = "ja";
  }
  else {
    ionisatie = "nee";
  }
  Serial.print(F("Ionisatie: "));
  Serial.println(ionisatie);

  if ((inbuffer[46] & 1) == 1) {
    pomp = "aan";
  }
  else {
    pomp = "uit";
  }
  Serial.print(F("Pomp: "));
  Serial.println(pomp);

  if ((inbuffer[45] & 8) == 8) {
    driewegklep = "ww";
  }
  else {
    driewegklep = "cv";
  }
  Serial.print(F("Driewegklep: "));
  Serial.println(driewegklep);

  if ((inbuffer[43] & 128) == 128) {
    ww_warmtevraag = "ja";
  }
  else {
    ww_warmtevraag = "nee";
  }
  Serial.print(F("WW-Warmtevraag: "));
  Serial.println(ww_warmtevraag);

  if ((inbuffer[43] & 16) == 16) {
    eco = "nee";
  }
  else {
    eco = "ja";
  }
  Serial.print(F("WW-eco: "));
  Serial.println(eco);

  switch (inbuffer[47]) {
    case 0:
      ketelstatus = "Rust";
      break;
    case 1:
      ketelstatus = "Warmtevraag";
      break;
    case 2:
      ketelstatus = "Brander start";
      break;
    case 3:
      ketelstatus = "Branden voor CV";
      break;
    case 4:
      ketelstatus = "Branden voor WW";
      break;
    case 5:
      ketelstatus = "Brander stop";
      break;
    case 6:
      ketelstatus = "Einde warmtevraag";
      break;
    case 7:
      ketelstatus = "-";
      break;
    case 8:
      ketelstatus = "Regelstop";
      break;
    case 9:
      ketelstatus = "Blokkering";
      break;
    case 10:
      ketelstatus = "Vergrendeling";
      break;
    case 11:
      ketelstatus = "Schoorsteenveger L";
      break;
    case 12:
      ketelstatus = "Schoorsteenveger h";
      break;
    case 13:
      ketelstatus = "Schoorsteenveger H";
      break;
    case 14:
      ketelstatus = "-";
      break;
    case 15:
      ketelstatus = "Handmatige warmtevraag";
      break;
    case 16:
      ketelstatus = "Ketel vorstbeveiliging";
      break;
    case 17:
      ketelstatus = "Ontluchting";
      break;
    default:
      ketelstatus = "Onbekende status";
      break;
  }

  Serial.print(F("Ketelstatus: "));
  Serial.println(ketelstatus);


}

void loop() { // run over and over
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= delay_interval) {
    previousMillis = currentMillis;
    while (mySerial.available() > 0) {
mySerial.read();
} //flush serial inbuffer


     mySerial.write( (uint8_t*)remeha_data, sizeof(remeha_data) ); //send remeha request
  }
  if (mySerial.available()) {
    serialIn = mySerial.read();
    inbuffer[i] = serialIn;
    i++;
  }

if (i == 74) {
  if (inbuffer[0] == 2 && inbuffer[1] == 1 && inbuffer[2] == 254)  {  //dataframe moet starten met 02 01 FE en moet 74 bytes lang zijn, anders wordt het niet processed
    Serial.println("Dataframe complete");
    i = 0;
    decode_data();

  }
}

}

Re: Remeha control using RS232 port

Posted: Sun Jan 07, 2018 11:21 pm
by lifer
Thank you very much for your quick reply!

Actually, I'm on a short vacation abroad hence I couldn't test the code on my boiler yet. In the mean time, I'll try to find the particular data IDs for Quinta Pro but as I only have a Linux notebook available I am unable to install/extract the Recom .msi application to read the Quinta Pro specific xml file.

Anyway, I've seen that you only send a single code ID to the boiler:

Code: Select all

byte remeha_data[] = {0x02, 0xfe, 0x01, 0x05, 0x08, 0x02, 0x01, 0x69, 0xAB, 0x03};
mySerial.write( (uint8_t*)remeha_data, sizeof(remeha_data) ); //send remeha request
Is that a typical request for "boiler status" or something? Is it possible to send any other requests like read/write boiler parameters?

Thanks again for your kind support.

Later edit:

I managed to extract the "RecomSetup.msi" archive files but now I'm not sure what's the corresponding Quinta Pro file, ie: quinta_p0.xml or quintav2_p0.xml ??