Modbus Ultraschall-Sensor auslesen (am liebsten über Regvar)

Hallo Zusammen,
ich habe zwischenzeitlich die Ultraschallsensoren an meinen Heizöltanks wechseln müssen, da die alten defekt waren.
Ich habe jetzt ein neues Fabrikat - auch aus CN, was über Modbus läuft.
Es gibt drei Sensoren mit den Adressen 01-03.

Bisher nutze ich ein Skript, welches diesen nacheinander einen Code zur Abfrage schickt:

<?php
$com =16778;
$reg=13446;
//$code = "\x24\x52\x4C\x30\x31\x32\x33\x0D\x0A";
//Tank02 //24 52 4C 30 32 32 34 0D 0A
//Tank03 //24 52 4C 30 33 32 35 0D 0A

for ($i = 1; $i <= 3; $i++) {   
    If ($i ==1) {
	$code ="\x01\x03\x01\x01\x00\x01\xD4\x36"; 
	COMPort_SetOpen($com, true);
	IPS_ApplyChanges($com);  

	CSCK_SendText($com, $code.chr(13)); 
 
 	IPS_Sleep(1500);
	COMPort_SetOpen($com, false);
	IPS_ApplyChanges($com);
	IPS_Sleep(1500);}  
	
	If ($i ==2) {
	$code = "\x02\x03\x01\x01\x00\x01\xD4\x05"; 
	COMPort_SetOpen($com, true);
	IPS_ApplyChanges($com);  

	CSCK_SendText($com, $code.chr(13)); 
 
 	IPS_Sleep(1500);
	COMPort_SetOpen($com, false);
	IPS_ApplyChanges($com);
	IPS_Sleep(1500);}  
	
	If ($i ==3) {
	$code = "\x03\x03\x01\x01\x00\x01\xD5\xD4";
	COMPort_SetOpen($com, true);
	IPS_ApplyChanges($com);  

	CSCK_SendText($com, $code.chr(13)); 
 
 	IPS_Sleep(1500);;
	COMPort_SetOpen($com, false);
	IPS_ApplyChanges($com);
	IPS_Sleep(1500);}  
	}

?>```


Dabei sende ich als Hex-Code folgendes (01… an Sensor 01 etc.)
01 03 01 01 00 01 D4 36
02 03 01 01 00 01 D4 05
03 03 01 01 00 01 D5 D4

Wie man sieht, ist nur die Adresse am Anfang unterschiedlich und die 4 Ziffern CRC-16 am Ende.
Das geht auch mit dem o.g. Skript (ich hatte nur die Abruf-Befehle geändert zu den alten Sensoren).

Was nicht geht, ist über eine RegVar Empfangen, zuordnen und den passenden Teil ausschneiden, Skript siehe hier:

<?php

if ($_IPS['SENDER'] == "RegisterVariable") {

    $data = $_IPS['VALUE'];

    

    var_dump ($data); 

    $hex = bin2hex($data);

    $tanknr=substr($hex, 1, 1); //Sensor ID aus String ausschneiden 

    settype($tanknr,"String"); 

    

#######################################################################################################################

If ($tanknr=="1"){          

    $data=substr($data, 5, 4); //relevanten Teil aus String ausschneiden

    var_dump ($data);

    settype($data,"Integer"); 

    SetValueInteger(58140, $data);

    settype($data,"Float");

    $liter=(2000/1500)*$data;

    SetValueFloat(50304, $liter);

    $tank_inv_1=100-(($data/1500)*100);

    round($tank_inv_1,0);

    settype($tank_inv_1,"Integer");     

    SetValueInteger(37583, $tank_inv_1);    

    Print $liter;}

####################################################################################################################### 

    If ($tanknr=="2"){          

    $data=substr($data, 5, 4); //relevanten Teil aus String ausschneiden

    var_dump ($data);

    settype($data,"Integer"); 

    SetValueInteger(27591, $data);

    settype($data,"Float");

    $liter2=(2000/1500)*$data;

    SetValueFloat(10374, $liter2);

    $tank_inv_1=100-(($data/1500)*100);

    round($tank_inv_1,0);

    settype($tank_inv_1,"Integer");     

    SetValueInteger(41889, $tank_inv_1);}   

    

####################################################################################################################### 

    If ($tanknr=="3"){          

    $data=substr($data, 5, 4); //relevanten Teil aus String ausschneiden

    var_dump ($data);

    settype($data,"Integer"); 

    SetValueInteger(47622, $data);

    SetValueInteger(58140, $data);

    settype($data,"Float");

    $liter3=(2000/1500)*$data;

    SetValueFloat(38232, $liter3);

    SetValueFloat(50304, $liter3);

    $tank_inv_1=100-(($data/1500)*100);

    round($tank_inv_1,0);

    settype($tank_inv_1,"Integer");     

    SetValueInteger(52415, $tank_inv_1);}

    }

?>```

Ich habe keine Ahnung wie ich das flicken kann, mit dem Modbus-Modul komme ich mal garnicht weiter. Ich weiß nicht genau wie ich das dazu brauchen kann.
Am liebsten wäre es, wenn ich die eingehenden Daten (welche laut Debug korrekt in Hex sind, aus dem ich auch gerne ausschneiden möchte), wieder so aufbereiten kann, dass mein Skript damit klarkommt.

Empfangen wird (Debug) 10.02.2021, 11:48:55 | PROCESSED | 01 03 02 12 6F F4 C8
(ich brauche das 12 6F und das ist der Abstand in 1/10mm).

Vergessen / Edit: Info vom CN-Sensor zum Protokoll…

1.Communications Protocol
The data rate defaults to 19.2 K baud. Each byte contains 10 bits that
include a start bit, 8 bit data, and1 stop bit and no parity bit. There are a total
of 6 bytes required to access the KUS550. The KUS550 will respond back
with 6 bytes that include status (range to target, temperature, target strength,
etc), Data Memory read requests, and sensor error messages on the RS-485
bus. Transmitted values are in binary.

Request command
SensorID - Function code - Data address - Data length - Check sum(CRC16)
1 byte - 1byte - 2 byte - 2 byte - 2 byte
Response
SensorID - Function code - Data length-  Data Check sum(CRC16)
1 byte - 1byte - 1 byte - (Data length)*2 byte - 2 byte

Kann jemand helfen?

Danke & Gruß,
Matthias

Antwort an mich selbst :grin: :upside_down_face:

Ist gelöst - siche rnicht allzu elegant - aber es kommen Werte raus!

<?php
if ($_IPS['SENDER'] == "RegisterVariable") {
    $data = $_IPS['VALUE'];
	
	//var_dump (bin2hex($data)); 
	$hex = bin2hex($data);
	$tanknr=substr($hex, 1, 1); //Sensor ID aus String ausschneiden 
    var_dump ($tanknr);
	settype($tanknr,"String"); 
	

#######################################################################################################################
If ($tanknr=="1"){ 			
	$data=substr($hex, 6, 4); 
    var_dump ($data);
	$data =hexdec ($data);
	settype($data,"Integer"); 
    $fuellhöhe= 1800-$data/10;
	SetValueInteger(58140, $fuellhöhe);
	settype($fuellhöhe,"Float");
	$liter=(2000/1500)*$fuellhöhe;
	SetValueFloat(50304, $liter);
	$tank_inv_1=100-(($fuellhöhe/1500)*100);
	round($tank_inv_1,0);
	settype($tank_inv_1,"Integer"); 	
	SetValueInteger(37583, $tank_inv_1);	
	}

#######################################################################################################################	
	If ($tanknr=="2"){ 			
	$data=substr($hex, 6, 4); 
	var_dump ($data);
    $data =hexdec ($data);
	settype($data,"Integer");
    $fuellhöhe= 1800-$data/10;
	SetValueInteger(27591, $fuellhöhe);
	settype($fuellhöhe,"Float");
	$liter2=(2000/1500)*$fuellhöhe;
	SetValueFloat(10374, $liter2);
	$tank_inv_1=100-(($fuellhöhe/1500)*100);
	round($tank_inv_1,0);
	settype($tank_inv_1,"Integer"); 	
	SetValueInteger(41889, $tank_inv_1);}	
	

#######################################################################################################################	
	If ($tanknr=="3"){ 			
	$data=substr($hex, 6, 4); 
	var_dump ($data);
    $data =hexdec ($data);
	settype($data,"Integer");
    $fuellhöhe= 1800-$data/10;
	SetValueInteger(47622, $fuellhöhe);
	settype($fuellhöhe,"Float");
	$liter3=(2000/1500)*$fuellhöhe;
	SetValueFloat(38232, $liter3);
	$tank_inv_1=100-(($fuellhöhe/1500)*100);
	round($tank_inv_1,0);
	settype($tank_inv_1,"Integer"); 	
	SetValueInteger(52415, $tank_inv_1);}
	}
?>