ELV MAX! Protocol-Reader in PHP

Forum about the home automation suites by ELV etc

Moderator: jrkalf

Post Reply
User avatar
mega
Starting Member
Starting Member
Posts: 16
Joined: Fri Oct 28, 2011 10:44 pm
Location: Münster
Contact:

ELV MAX! Protocol-Reader in PHP

Post by mega »

Hello,
since 2 Days I have this Max-System and worked on a PHP-based-decoder.

To use this script, change the IP to your Cube-IP and get it run on a NAS, HomeServer or XAMPP.
It may also work with portforwarding from the Internet. but that is not tested.

Maybe we get our own webinterface that also can be used on a NAS/Homeserver or so.
To use this script, change the IP to your Cube-IP and get it run on your NAS, HomeServer or XAMPP.
Or use it online, open/forward a port to the cube.

The Script:
http://mega-nas.de/max/
Max! 1 x Cube, 4 x Thermostat, 1 x Wandthermostat,1 x Fensterkontakt
User avatar
mega
Starting Member
Starting Member
Posts: 16
Joined: Fri Oct 28, 2011 10:44 pm
Location: Münster
Contact:

Re: ELV MAX! Protocol-Reader in PHP

Post by mega »

It should now read and decode all known data and puts them in arrays.
Next step is a webinterface to present the data.
Is anyone else working with/on this?
Max! 1 x Cube, 4 x Thermostat, 1 x Wandthermostat,1 x Fensterkontakt
wwolkers
Member
Member
Posts: 273
Joined: Tue Sep 23, 2008 10:10 am
Location: Netherlands
Contact:

Re: ELV MAX! Protocol-Reader in PHP

Post by wwolkers »

I've instlled it on my local server to take a look at it. Works for me, but I haven't had any chance to do anything more with it.
User avatar
mega
Starting Member
Starting Member
Posts: 16
Joined: Fri Oct 28, 2011 10:44 pm
Location: Münster
Contact:

Re: ELV MAX! Protocol-Reader in PHP

Post by mega »

Script is changed to also read the wall-thermostat.
Max! 1 x Cube, 4 x Thermostat, 1 x Wandthermostat,1 x Fensterkontakt
Petr
Starting Member
Starting Member
Posts: 1
Joined: Tue Nov 22, 2011 12:34 am

Re: ELV MAX! Protocol-Reader in PHP

Post by Petr »

Hi,
I am thinking about the Max! Cube for my new central heating.
I really like the concept and the thermo-heads with big display and buttons.
But I see all (almost negative or embarrassed) postings here and on the ELV forum and I am little bit sceptical about the functionality.
I have following questions:
  • what is the main goal of the "Max! Cube <=> ELV server" communication protocol recognition (I mean do you think it is possible to use the protocol for our own application to control the Max!Cube?)
  • what about the "Max! Cube <=> EQ3 thermo head" wireless protocol. Are there any attempts to decode and understand it (so it is possible to control it via CUL or CUN see http://www.busware.de for example)?
  • are there any attempts to integrate the Max! with fhem? http://fhem.de/
Regards

Petr
User avatar
mega
Starting Member
Starting Member
Posts: 16
Joined: Fri Oct 28, 2011 10:44 pm
Location: Münster
Contact:

Re: ELV MAX! Protocol-Reader in PHP

Post by mega »

1. With the communication protocol recognition it will be possible to make a own interface or integrate to other interfaces/apps/....
2. this seems to not be needed because the Cube can be used with LAN .
3. not by me, but it should be possible.

You may buy and test the system. some users have problems, others not.
Max! 1 x Cube, 4 x Thermostat, 1 x Wandthermostat,1 x Fensterkontakt
Rainer
Starting Member
Starting Member
Posts: 1
Joined: Wed Oct 17, 2012 5:51 pm

Re: ELV MAX! Protocol-Reader in PHP

Post by Rainer »

I have installed this on my local webserver and it works.
I use firmware 1.3.5 on my max! cube.
The port is not 80 anymore but 62910 works fine.

Has anybody worked a bit on this?
Does anyone know about changing values?

Rainer
User avatar
mega
Starting Member
Starting Member
Posts: 16
Joined: Fri Oct 28, 2011 10:44 pm
Location: Münster
Contact:

Re: ELV MAX! Protocol-Reader in PHP

Post by mega »

Here is the complete interface, includes sending:
http://www.mega-nas.de/max/max.zip

This is discontinued! It may not work on newer firmware.
Max! 1 x Cube, 4 x Thermostat, 1 x Wandthermostat,1 x Fensterkontakt
ceemjay
Starting Member
Starting Member
Posts: 8
Joined: Tue Jan 01, 2013 4:43 pm

Re: ELV MAX! Protocol-Reader in PHP

Post by ceemjay »

Hi Mega

Thanks for your contributions.

I have only just got my MAX! stuff, found this thread yesterday and downloaded your code, so am a real beginner. But what does "This is discontinued!" mean exactly? You are no longer developing it or MAX! has changed in some way??

Thanks
ceemjay
User avatar
mega
Starting Member
Starting Member
Posts: 16
Joined: Fri Oct 28, 2011 10:44 pm
Location: Münster
Contact:

Re: ELV MAX! Protocol-Reader in PHP

Post by mega »

I do not devolop more for that.
Max is too scrap, i now have homematic (since some months)
Max! 1 x Cube, 4 x Thermostat, 1 x Wandthermostat,1 x Fensterkontakt
pjakobs
Starting Member
Starting Member
Posts: 1
Joined: Mon Nov 10, 2014 12:44 am

Re: ELV MAX! Protocol-Reader in PHP

Post by pjakobs »

I see that I'm late to the party, but I just bought the Max! stuff. So far, no complaints, but not being able to access it from the shell / through an API was not acceptable. This is why I searched for a scripted solution and found this code. I have started to refactor the reader.php script to ultimately turn it into a RESTful API. Here's my first take on it:

Code: Select all

<?php
// 
// All Max! Commands
//
/*
    DEVICE_LIST = 'L';
    CONFIGURATION = 'C';
    METADATA = 'M';
    
	SET_CREDENTIALS = 'B';
    GET_CREDENTIALS = 'G';
    SET_REMOTEACCESS = 'J';
    SET_USER_DATA = 'P';
    GET_USER_DATA = 'O';
	
    INCOMING_HELLO = "H:";
    INCOMING_FAILURE = "F:";
    INCOMING_DEVICE_LIST = "L:";
    INCOMING_CONFIGURATION = "C:";
    INCOMING_METADATA = "M:";
    INOMING_NEW_DEVICE = "N:";
    INCOMING_ACKNOWLEDGE = "A:";
    INCOMING_ENCRYPTION = "E:";
    INCOMING_DECRYPTION = "D:";
    INCOMING_SET_CREDENTIALS = "b:";
    INCOMING_GET_CREDENTIALS = "g:";
    INCOMING_SET_REMOTEACCESS = "j:";
    INCOMING_SET_USER_DATA = "p:";
    INCOMING_GET_USER_DATA = "o:";
    INCOMING_SEND_DEVICE_CMD = "S:";

    OUTGOING_URL = "u:";
    OUTGOING_INTERVAL = "i:";
    OUTGOING_SEND = "s:";
    OUTGOING_METADATA = "m:";
    OUTGOING_INCLUSION_MODE = "n:";
    OUTGOING_CANCEL_INCLUSION_MODE = "x:";
    OUTGOING_MORE_DATA = "g:";
    OUTGOING_QUIT = "q:";
    OUTGOING_ENCRYPTION = "e:";
    OUTGOING_DECRYPTION = "d:";
    OUTGOING_SET_CREDENTIALS = "B:";
    OUTGOING_GET_CREDENTIALS = "G:";
    OUTGOING_SET_REMOTEACCESS = "J:";
    OUTGOING_SET_USER_DATA = "P:";
    OUTGOING_GET_USER_DATA = "O:";
    OUTGOING_SEND_DEVICE_CMD = "s:";
    OUTGOING_RESET = "a:";
    OUTGOING_RESET_ERROR = "r:";
    OUTGOING_DELETE_DEVICES = "t:";
    OUTGOING_SET_PUSHBUTTON_CONFIG = "w:";
    OUTGOING_GET_DEVICE_LIST = "l:";
    OUTGOING_SET_URL = "u:";
    OUTGOING_GET_CONFIGURATION = "c:";
    OUTGOING_TIME_CONFIG = "v:";
    OUTGOING_SEND_WAKEUP = "z:";
*/

//
// Max! Date encoding
//
/*
    9D0B    1001110100001011
            MMMDDDDDM YYYYYY
            100     0        = 1000b  = 8d  = month
               11101         = 11101b = 29d = day
                      001011 = 1011b  = 11d = year-2000                   

    868B    1000011010001011
            MMMDDDDDM YYYYYY
            100     1         1001b = 9d  = month
               00110           110b = 6d  = day
                      001011  1011b = 11d = year-2000
*/
echo "<pre>";

// Uncomment the follwing 2 lines
$host = "192.168.35.64"; // Your Cube-IP or hostame Here!
$port = "62910";


//
// open connection
//
$fp = @fsockopen($host, $port, $errno, $errstr, 5);

if (!$fp)
{
	switch($errno)
	{
		case 111:
			die("Local software running - ".$errstr);
			break;
		case 113:
			die("No Connection - ".$errstr);
			break;
		default:
			die("Connection error - ".$errno." - ".$errstr);
			break;
	}
}

socket_set_blocking($fp,false);
sleep(1);
$finished = 0;
$now = time();

//
// read from cube
//
$buff = "";
while (!feof($fp) && time() < $now+20 && $finished == 0)
{
	$line = fgets($fp);
	if (strpos($line,"L:") !== false) $finished = 1;
	if ($line != "")  $buff .= $line."\n";
	//sleep(1);
}
fclose($fp);

//
// fail 
//
if ($finished != 1) die("Could not find an L record");

ob_start();

$arr = explode("\n\n",$buff);
print_r($arr);
echo '<hr />';
foreach ($arr as $v)
{
	$p_type=substr($v,0,2); //packet type
	switch($p_type)
	{
		case "H:":
		/*
			Initial "Hello"
			
			H:KHA0008979,0744a8,0113,00000000,576c1768,18,32,0e0b09,0a08,03,0000
			
			IEQ0123456  Serial number
			00b3b4      RF address, hexadecimal
			0102        Firmware version, 1.0.2
			00000000    ?
			355df98a    ?
			03          ?
			32          ?
		*/
			$arr2 = explode(',',substr($v,2,strlen($v)));
			//$str = base64_decode($arr2[2]);
		
			$data["sys"]["SerialNumber"] = $arr2[0];
			$data["sys"]["RFAdress"] = $arr2[1];
			$data["sys"]["Firmware"] = $arr2[2];
			$data["sys"]["1?"] = $arr2[3]; //00000000
			$data["sys"]["HTTP-ConnID"] = $arr2[4];
			$data["sys"]["2?"] = $arr2[5];
			$data["sys"]["3?"] = $arr2[6]; //31 
			$data["sys"]["Date"] = hexdec(substr($arr2[7],4,2)).".".hexdec(substr($arr2[7],2,2)).".".hexdec(substr($arr2[7],0,2));
			$data["sys"]["Time"] = hexdec(substr($arr2[8],0,2)).":".hexdec(substr($arr2[8],2,2));
			$data["sys"]["Timestamp"] = mktime(hexdec(substr($arr2[8],0,2)),hexdec(substr($arr2[8],2,2)),0,hexdec(substr($arr2[7],2,2)),hexdec(substr($arr2[7],4,2)),hexdec(substr($arr2[7],0,2)));
		break;
		
		case "M:":
		/*
			Metadata
			
			M:00,01,VgICAQVCw7xybwx6FQIKV29obnppbW1lcgx6PgUDDM8AS0VRMDgwODIzOBBXYW5kdGhlcm1vc3RhdCAxAQEMehVLRVEwNzIwMDA4EkhlaXprw7ZycGVyIHJlY2h0cwEBDHo+S0VRMDcxOTk2OAtIZWl6a8O2cnBlcgIEDK83S0VRMDg0MTI2NA5GZW5zdGVyIHJlY2h0cwEEDLI1S0VRMDg0MjExMgdGZW5zdGVyAgE=
			
			00000000  56 02 02 01 05 42 c3 bc  72 6f 0c 7a 15 02 0a 57  |V....B..ro.z...W|
			00000010  6f 68 6e 7a 69 6d 6d 65  72 0c 7a 3e 05 03 0c cf  |ohnzimmer.z>....|
			00000020  00 4b 45 51 30 38 30 38  32 33 38 10 57 61 6e 64  |.KEQ0808238.Wand|
			00000030  74 68 65 72 6d 6f 73 74  61 74 20 31 01 01 0c 7a  |thermostat 1...z|
			00000040  15 4b 45 51 30 37 32 30  30 30 38 12 48 65 69 7a  |.KEQ0720008.Heiz|
			00000050  6b c3 b6 72 70 65 72 20  72 65 63 68 74 73 01 01  |k..rper rechts..|
			00000060  0c 7a 3e 4b 45 51 30 37  31 39 39 36 38 0b 48 65  |.z>KEQ0719968.He|
			00000070  69 7a 6b c3 b6 72 70 65  72 02 04 0c af 37 4b 45  |izk..rper....7KE|
			00000080  51 30 38 34 31 32 36 34  0e 46 65 6e 73 74 65 72  |Q0841264.Fenster|
			00000090  20 72 65 63 68 74 73 01  04 0c b2 35 4b 45 51 30  | rechts....5KEQ0|
			000000a0  38 34 32 31 31 32 07 46  65 6e 73 74 65 72 02 01  |842112.Fenster..|
			000000b0

			0001 56 -> ?
			0002 02 -> ?
			0003 02 -> RoomCount
		
			0004 01 -> RoomID
			0005 05 -> RoomNameLength
			0006 42 C3 BC 72 6F -> RoomName
			000A 0C 7A 15 -> RF Address
			
			000D 02 -> RoomID
			000E 0A -> RoomNameLength
			000F 57 6F 68 6E 7A 69 6D 6D 65 72 -> RoomName
			0018 0C 7A 3E -> RF Address
			
			OO1B 05
			
			Room:
			Description        Startpos    Length      Example Value
			=====================================================================
			Room id            00          1           1
			Room name length   01          1           0A
			Room name          02          variable    Hobbykamer
			Address(?)                     3           003508
			
			Device:
			Description        Startpos    Length      Example Value
			=====================================================================
			Device type        00          1           1
			Address            01          3           003508
			Serial Number      04          10          IEQ0109125
			Name length        0E          1           0C
			Name               0F          variable    Thermostat 1
			Room id                        1           01
		*/
			
			 $arr2 = explode(',',$v);
			 $str = base64_decode($arr2[2]);

			echo $arr2[0].','.$arr2[1]."\n".htmlentities($str)."\n";
			for($i = 0 ; $i <= strlen($str) ; $i++) 
			{
				echo dechex(ord(substr($str,$i,1)))." ";
			}
			echo "\n";

			$pos = 0;
			$readlen =  1; 
			$data["meta"]["?1"] = dechex(ord(substr($str,$pos,$readlen)))."";  
			$pos += $readlen;
			
			$readlen =  1; 
			$data["meta"]["?2"] = dechex(ord(substr($str,$pos,$readlen)))."";  
			$pos += $readlen; 
			
			$readlen =  1; 
			$data["meta"]["RoomCount"] = dechex(ord(substr($str,$pos,$readlen)))."";  
			$pos += $readlen;

			for($j = 1 ; $j <= $data["meta"]["RoomCount"] ; $j++)
			{
				$readlen = 1;
				$RoomID = dechex(ord(substr($str,$pos,$readlen)))."";
				$data["rooms"][$RoomID]["RoomID"] = $RoomID;  
				$pos += $readlen;
				
				$readlen = 1;
				$data["rooms"][$RoomID]["RoomNameLength"] = ord(substr($str,$pos,$readlen)).""; 
				$pos += $readlen;
				
				$readlen = $data["rooms"][$RoomID]["RoomNameLength"]; 
				$data["rooms"][$RoomID]["RoomName"] = htmlentities(substr($str,$pos,$readlen))."";
				$pos += $readlen;
				
				$readlen = 3;
				for($i = $pos; $i < $readlen+$pos ; $i++)
				{
					$data["rooms"][$RoomID]["RFAdress(?)"] .= str_pad(dechex(ord(substr($str,$i,1))),2,"0",STR_PAD_LEFT).""; 
				}
				$pos += $readlen;
			}
			
			$readlen = 1; 
			$data["meta"]["DevCount"] = dechex(ord(substr($str,$pos,$readlen))).""; 
			$pos += $readlen;
			/*
			00000010  6f 68 6e 7a 69 6d 6d 65  72 0c 7a 3e 05 03 0c cf  |ohnzimmer.z>....|
			00000020  00 4b 45 51 30 38 30 38  32 33 38 10 57 61 6e 64  |.KEQ0808238.Wand|
			00000030  74 68 65 72 6d 6f 73 74  61 74 20 31 01 01 0c 7a  |thermostat 1...z|
			00000040  15 4b 45 51 30 37 32 30  30 30 38 12 48 65 69 7a  |.KEQ0720008.Heiz|
			00000050  6b c3 b6 72 70 65 72 20  72 65 63 68 74 73 01 01  |k..rper rechts..|
			00000060  0c 7a 3e 4b 45 51 30 37  31 39 39 36 38 0b 48 65  |.z>KEQ0719968.He|
			00000070  69 7a 6b c3 b6 72 70 65  72 02 04 0c af 37 4b 45  |izk..rper....7KE|
			00000080  51 30 38 34 31 32 36 34  0e 46 65 6e 73 74 65 72  |Q0841264.Fenster|
			00000090  20 72 65 63 68 74 73 01  04 0c b2 35 4b 45 51 30  | rechts....5KEQ0|
			000000a0  38 34 32 31 31 32 07 46  65 6e 73 74 65 72 02 01  |842112.Fenster..|
			
			
			0C  05 -> DevCount
			0D  03 -> DevType
			0E  0C CF 00 -> RFAddress
			21  4B 45 51 30 38 30 38 32 33 38 -> SerialNumber
			2B  10 -> NameLength
			2C  57 61 6E 64 74 68 65 72 6D 6F 73 74 61 74 20 31 -> DeviceName
			3C  01 -> RoomID
			
			*/
			
			for($j = 1 ; $j <= $data["meta"]["DevCount"]; $j++)
			{
				unset($hilf);
				
				$readlen = 1; 
				$hilf["DeviceType"] = dechex(ord(substr($str,$pos,$readlen))).""; 
				$pos += $readlen;
				
				$readlen = 3; 
				for($i = $pos; $i < $readlen+$pos ; $i++) 
				{
					$hilf["RFAdress"] .= str_pad(dechex(ord(substr($str,$i,1))),2,"0",STR_PAD_LEFT).""; 
				}
				$pos += $readlen; 
				
				$readlen = 10; 
				$hilf["SerialNumber"] .= htmlentities(substr($str,$pos,$readlen)).""; 
				$pos += $readlen;
				
				$readlen = 1; 
				$hilf["NameLength"] = ord(substr($str,$pos,$readlen)).""; 
				$pos += $readlen; 
				//echo "debug === Device Name Length:".$hilf["NameLength"]."\n";
				
				$readlen = $hilf["NameLength"]; 
				$hilf["Name"] = htmlentities(substr($str,$pos,$readlen))."";
				$pos += $readlen;
				//echo "debug === Device Name:".$hilf["Name"]."\n";
				
				$readlen = 1; 
				$hilf["RoomID"] = dechex(ord(substr($str,$pos,1))).""; 
				$pos += $readlen;

				$data["rooms"][$hilf["RoomID"]]["Devices"][$j]["DeviceType"] = $hilf["DeviceType"];
				$data["rooms"][$hilf["RoomID"]]["Devices"][$j]["RFAdress"] = $hilf["RFAdress"];
				$data["rooms"][$hilf["RoomID"]]["Devices"][$j]["SerialNumber"] = $hilf["SerialNumber"];
				$data["rooms"][$hilf["RoomID"]]["Devices"][$j]["NameLength"] = $hilf["NameLength"];
				$data["rooms"][$hilf["RoomID"]]["Devices"][$j]["Name"] = $hilf["Name"];
				$data["rooms"][$hilf["RoomID"]]["Devices"][$j]["RoomID"] = $hilf["RoomID"];
			}
		break;		
		case "C:":
		/*
			Configuration
			
			C:0744a8,7QdEqAATAQBLSEEwMDA4OTc5AAsABEAAAAAAAAAAAP///////////////////////////wsABEAAAAAAAAAAQf///////////////////////////2h0dHA6Ly9tYXgtcG9ydGFsLmVxLTMuZGU6ODAvbG9va3VwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAENFVAAACgADAAAOEENFU1QAAwACAAAcIA==
			
			00000000  ed 07 44 a8 00 13 01 00  4b 48 41 30 30 30 38 39  |..D.....KHA00089|
			00000010  37 39 00 0b 00 04 40 00  00 00 00 00 00 00 00 ff  |79....@.........|
			00000020  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
			00000030  ff ff ff ff 0b 00 04 40  00 00 00 00 00 00 00 41  |.......@.......A|
			00000040  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
			00000050  ff ff ff ff ff 68 74 74  70 3a 2f 2f 6d 61 78 2d  |.....http://max-|
			00000060  70 6f 72 74 61 6c 2e 65  71 2d 33 2e 64 65 3a 38  |portal.eq-3.de:8|
			00000070  30 2f 6c 6f 6f 6b 75 70  00 00 00 00 00 00 00 00  |0/lookup........|
			00000080  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
			*
			000000d0  00 00 00 00 00 00 43 45  54 00 00 0a 00 03 00 00  |......CET.......|
			000000e0  0e 10 43 45 53 54 00 03  00 02 00 00 1c 20        |..CEST....... |
			000000ee
			
			003508        RF address of the device
			
			Start Length  Value       Description
			==================================================================
			00         1  D2          Length of data: D2 = 210(decimal) = 210 bytes
			01         3  003508      RF address
			04         1  01          Device Type
			05         3  0114FF      ?
			08        10  IEQ0109125  Serial Number       
			12         1  28          Comfort Temperature     
			13         1  28          Eco Temperature         
			14         1  3D          MaxSetPointTemperature 
			15         1  09          MinSetPointTemperature 
			16         1  07          Temperature Offset * 2
									  The default value is 3,5, which means the offset = 0 degrees.
									  The offset is adjustable between -3,5 and +3,5 degrees,
									  which results in a value in this response between 0 and 7 (decoded already)       
			17         1  28          Window Open Temperature   
			18         1  03          Window  Open Duration     
			19         1  30          Boost Duration and Boost Valve Value
									  The 3 MSB bits gives the duration, the 5 LSB bits the Valve Value%.
									  Duration: With 3 bits, the possible values (Dec) are 0 to 7, 0 is not used.
									  The duration in Minutes is: if Dec value = 7, then 30 minutes, else Dec value * 5 minutes
									  Valve Value: dec value 5 LSB bits * 5 gives Valve Value in %
			1A         1  0C          Decalcification: Day of week and Time
									  In bits: DDDHHHHH
									  The three most significant bits (MSB) are presenting the day, Saturday = 1, Friday = 7
									  The five least significant bits (LSB) are presenting the time (in hours)     
			1B         1  FF          Maximum Valve setting; *(100/255) to get in %
			1C         1  00          Valve Offset ; *(100/255) to get in %
			1D         ?  44 48 ...   Weekly program (see The weekly program)
		*/


			$arr2 = explode(',',$v);
			$str = base64_decode($arr2[1]);
			echo $arr2[0]."\n".htmlentities($str)."\n";
			for($i = 0 ; $i <= strlen($str) ; $i++) echo dechex(ord(substr($str,$i,1)))." ";
			echo "\n";
			echo "\n";
			echo strlen($str)."\n";

			unset($hilf);

			$pos = 0;
			$readlen = 1; 
			$hilf["?1"] = dechex(ord(substr($str,$pos,1)))."";  
			$pos += $readlen;
			
			$readlen = 3; 
			for($i = $pos; $i < $readlen+$pos ; $i++) 
			{
				$hilf["RFAdress"] .= str_pad(dechex(ord(substr($str,$i,1))),2,"0",STR_PAD_LEFT)."";  
			}
			$pos += $readlen;
			
			$readlen = 1; 
			$hilf["DeviceType"] = dechex(ord(substr($str,$pos,1)))."";  
			$pos += $readlen;
			
			$readlen = 3; 
			for($i = $pos; $i < $readlen+$pos ; $i++) 
			{
				$hilf["?2"] .= dechex(ord(substr($str,$i,1)))." ";  
			}
			$pos += $readlen;
			
			$readlen = 10; 
			$hilf["SerialNumber"] = htmlentities(substr($str,$pos,$readlen))."";  
			$pos += $readlen;

			$deviceconf[$hilf["RFAdress"]]["?1"] = $hilf["?1"];
			$deviceconf[$hilf["RFAdress"]]["RFAdress"] = $hilf["RFAdress"];
			$deviceconf[$hilf["RFAdress"]]["DeviceType"] = $hilf["DeviceType"];
			$deviceconf[$hilf["RFAdress"]]["?2"] = $hilf["?2"];
			$deviceconf[$hilf["RFAdress"]]["SerialNumber"] = $hilf["SerialNumber"];


			switch($deviceconf[$hilf["RFAdress"]]["DeviceType"])
			{
				case "0":
					// Cube
					$readlen = 1;
					$deviceconf[$hilf["RFAdress"]]["PortalEnabled"] = ord(substr($str,$i,$readlen))."";  
					$pos += $readlen;
					
					$readlen =  4; 
					for($i = $pos; $i < $readlen+$pos ; $i++) 
					{
						$deviceconf[$hilf["RFAdress"]]["?3"] .= dechex(ord(substr($str,$i,1)))." ";
					}
					$pos += $readlen;
					
					$readlen =  8; 
					for($i = $pos; $i < $readlen+$pos ; $i++) 
					{
						$deviceconf[$hilf["RFAdress"]]["?4"] .= dechex(ord(substr($str,$i,1)))." ";  
					}
					$pos += $readlen;
					
					$readlen = 21; 
					for($i = $pos; $i < $readlen+$pos ; $i++) 
					{
						$deviceconf[$hilf["RFAdress"]]["?5"] .= dechex(ord(substr($str,$i,1)))." ";  
					}
					$pos += $readlen;
					
					$readlen = 4; 
					for($i = $pos; $i < $readlen+$pos ; $i++)
					{
						$deviceconf[$hilf["RFAdress"]]["?6"] .= dechex(ord(substr($str,$i,1)))." ";  
					}
					$pos += $readlen;
					
					$readlen =  8; 
					for($i = $pos; $i < $readlen+$pos ; $i++) 
					{
						$deviceconf[$hilf["RFAdress"]]["?7"] .= dechex(ord(substr($str,$i,1)))." ";  
					}
					$pos += $readlen;
					
					$readlen = 21; 
					for($i = $pos; $i < $readlen+$pos ; $i++) 
					{
						$deviceconf[$hilf["RFAdress"]]["?8"] .= dechex(ord(substr($str,$i,1)))." ";  
					}
					$pos += $readlen;

					$readlen = 36; 
					$deviceconf[$hilf["RFAdress"]]["PortalURL"] .= htmlentities(substr($str,$i,$readlen))."";
					$pos += $readlen;

					$readlen = 60; for($i = $pos; $i < $readlen+$pos ; $i++) $deviceconf[$hilf["RFAdress"]]["?9"] .= ord(substr($str,$i,1))." ";  $pos += $readlen;
					$readlen = 33; for($i = $pos; $i < $readlen+$pos ; $i++) $deviceconf[$hilf["RFAdress"]]["?A"] .= ord(substr($str,$i,1))." ";  $pos += $readlen;
					$readlen =  3; for($i = $pos; $i < $readlen+$pos ; $i++) $deviceconf[$hilf["RFAdress"]]["StandardTimeZone"] .= htmlentities(substr($str,$i,1))."";  $pos += $readlen;
					$readlen =  9; for($i = $pos; $i < $readlen+$pos ; $i++) $deviceconf[$hilf["RFAdress"]]["?C"] .= ord(substr($str,$i,1))." ";  $pos += $readlen;
					$readlen =  4; for($i = $pos; $i < $readlen+$pos ; $i++) $deviceconf[$hilf["RFAdress"]]["DSTTimeZone"] .= htmlentities(substr($str,$i,1))."";  $pos += $readlen;
					$readlen =  9; for($i = $pos; $i < $readlen+$pos ; $i++) $deviceconf[$hilf["RFAdress"]]["?E"] .= ord(substr($str,$i,1))." ";  $pos += $readlen;
				break;
				case "1":
					// Thermostat
					$readlen =  1; $deviceconf[$hilf["RFAdress"]]["ComfortTemperature"] = (ord(substr($str,$pos,$readlen))/2)."";  $pos += $readlen; 
					$readlen =  1; $deviceconf[$hilf["RFAdress"]]["EcoTemperature"] = (ord(substr($str,$pos,$readlen))/2)."";  $pos += $readlen;
					$readlen =  1; $deviceconf[$hilf["RFAdress"]]["MaxSetPointTemperature"] = (ord(substr($str,$pos,$readlen))/2)."";  $pos += $readlen;
					$readlen =  1; $deviceconf[$hilf["RFAdress"]]["MinSetPointTemperature"] = (ord(substr($str,$pos,$readlen))/2)."";  $pos += $readlen;
					$readlen =  1; $deviceconf[$hilf["RFAdress"]]["TemperatureOffset"] = (ord(substr($str,$pos,$readlen)))/2-3.5."";  $pos += $readlen;
					$readlen =  1; $deviceconf[$hilf["RFAdress"]]["WindowOpenTemperature"] = (ord(substr($str,$pos,$readlen))/2)."";  $pos += $readlen;
					$readlen =  1; $deviceconf[$hilf["RFAdress"]]["WindowOpenDuration"] = dechex(ord(substr($str,$pos,$readlen)))."";  $pos += $readlen;
					$readlen =  1; $deviceconf[$hilf["RFAdress"]]["Boost"] = str_pad(decbin(ord(substr($str,$pos,$readlen))),8,"0",STR_PAD_LEFT)."";  $pos += $readlen;
					$deviceconf[$hilf["RFAdress"]]["BoostDuration"] = bindec(substr($deviceconf[$hilf["RFAdress"]]["Boost"],0,3))*5;
					$deviceconf[$hilf["RFAdress"]]["BoostValue"] = bindec(substr($deviceconf[$hilf["RFAdress"]]["Boost"],3,5))*5;

					$readlen =  1; $deviceconf[$hilf["RFAdress"]]["Decalc"] = str_pad(decbin(ord(substr($str,$pos,$readlen))),8,"0",STR_PAD_LEFT)."";  $pos += $readlen;
					$deviceconf[$hilf["RFAdress"]]["DecalcDay"] = bindec(substr($deviceconf[$hilf["RFAdress"]]["Decalc"],0,3));
					$deviceconf[$hilf["RFAdress"]]["DecalcTime"] = bindec(substr($deviceconf[$hilf["RFAdress"]]["Decalc"],3,5));
					$readlen =  1; $deviceconf[$hilf["RFAdress"]]["MaximumValveSetting"] = dechex(ord(substr($str,$pos,$readlen)))*(100/255)."";  $pos += $readlen;
					$readlen =  1; $deviceconf[$hilf["RFAdress"]]["ValveOffset"] = dechex(ord(substr($str,$pos,$readlen)))*(100/255)."";  $pos += $readlen;

					for ($j = 1 ; $j <= 7 ; $j++)
					{
						$readlen = 26;// Sat, Sun, Mon, Tue, Weg, Thu, Fri
						for($i = $pos; $i < $readlen+$pos ; $i+=2)
						{
							$bin  = str_pad(decbin(hexdec(dechex(ord(substr($str,$i,1))))),8,"0",STR_PAD_LEFT).str_pad(decbin(hexdec(dechex(ord(substr($str,$i+1,1))))),8,"0",STR_PAD_LEFT);
							//echo $bin."  ";
							$deg = bindec(substr($bin,0,7));
							//$deviceconf[$hilf["RFAdress"]]["WeeklyProgramm".$j.""] .= ($deg/2)."^C ";
							$min = bindec(substr($bin,7,9));
							//$deviceconf[$hilf["RFAdress"]]["WeeklyProgramm".$j.""] .= number_format(($min*5/60),2)."hr | ";
							$deviceconf[$hilf["RFAdress"]]["WeeklyProgramm".$j."deg"][] = ($deg/2);
							$deviceconf[$hilf["RFAdress"]]["WeeklyProgramm".$j."time"][] = number_format(($min*5/60),2);
						}
					$pos += $readlen;
					}
				break;
				case "4":
					// Fensterkontakt
					echo "======debug======";echo $hilf["?2"];
					$deviceconf[$hilf["RFAdress"]]["WindowOpen"] = $hilf["?2"]&&0b00000010;
				break;
			}
		break;
		
		case "L:":
		/*
			Device List
			
			L:DAzPAPkSGAQqAAAA1gsMehX5EhgAKgAAAAsMej7sEhgKKgAAAAYMrzfsEhAGDLI1bBIQ
			
			00000000  0c 0c cf 00 f9 12 18 04  2a 00 00 00 d6 0b 0c 7a  |........*......z|
			00000010  15 f9 12 18 00 2a 00 00  00 0b 0c 7a 3e ec 12 18  |.....*.....z>...|
			00000020  0a 2a 00 00 00 06 0c af  37 ec 12 10 06 0c b2 35  |.*......7......5|
			00000030  6c 12 10                                          |l..|
			00000033
			
			Start Length  Value       Description
			==================================================================
			0          1  0B          Length of data: 0B = 11(decimal) = 11 bytes
			1          3  003508      RF address
			4          1  00          ?
			5          1  12          bit 4     Valid              0=invalid;1=information provided is valid
									  bit 3     Error              0=no; 1=Error occurred
									  bit 2     Answer             0=an answer to a command,1=not an answer to a command
									  bit 1     Status initialized 0=not initialized, 1=yes
										   
									  12  = 00010010b
										  = Valid, Initialized
									 
			6       1     1A          bit 7     Battery       1=Low
									  bit 6     Linkstatus    0=OK,1=error
									  bit 5     Panel         0=unlocked,1=locked
									  bit 4     Gateway       0=unknown,1=known
									  bit 3     DST setting   0=inactive,1=active
									  bit 2     Not used
									  bit 1,0   Mode         00=auto/week schedule
															 01=Manual
															 10=Vacation
															 11=Boost   
									  1A  = 00011010b
										  = Battery OK, Linkstatus OK, Panel unlocked, Gateway known, DST active, Mode Vacation.
			7       1     20          Valve position in %
			8       1     2C          Temperature setpoint, 2Ch = 44d; 44/2=22 deg. C
			9       2     858B        Date until (05-09-2011) (see Encoding/Decoding date/time)
			B       1     2E          Time until (23:00) (see Encoding/Decoding date/time)
		*/
			$v = substr($v,2,strlen($v));
			$str = base64_decode($v);

			//echo htmlentities($str)."\n";
			//$buff = "";
			//for($i = 0 ; $i <= strlen($str) ; $i++) $buff .= dechex(ord(substr($str,$i,1)))." ";
			//$buff .= "\n";
			//echo $buff;

			$pos = 0;

			for($j = 1 ; $j <= $data["meta"]["DevCount"]; $j++)
			{
				unset($hilf);
				$readlen =              1; $hilf["ReadLength"] = htmlentities(ord(substr($str,$pos,1))).""; $pos += $readlen;
				$readlen =              3; for($i = $pos; $i < $readlen+$pos ; $i++) $hilf["RFAdress"] .= str_pad(dechex(ord(substr($str,$i,1))),2,"0",STR_PAD_LEFT).""; $pos += $readlen;
				$readlen =              1; $hilf["?1"] = dechex(ord(substr($str,$pos,1))).""; $pos += $readlen;
				$readlen =              1; $hilf["Data1"] .= str_pad(decbin(ord(substr($str,$pos,1))),8,"0",STR_PAD_LEFT).""; $pos += $readlen;
				$readlen =              1; $hilf["Data2"] .= str_pad(decbin(ord(substr($str,$pos,1))),8,"0",STR_PAD_LEFT).""; $pos += $readlen;
				if($hilf["ReadLength"] == 11)	
				{
					$readlen =              1; $hilf["?2"] = dechex(ord(substr($str,$pos,1))).""; $pos += $readlen;
					$readlen =              1; $hilf["Temperature"] = (ord(substr($str,$pos,1))/2).""; $pos += $readlen;
					$readlen =              2; for($i = $pos; $i < $readlen+$pos ; $i++) $hilf["DateUntil"] .= str_pad(decbin(ord(substr($str,$i,1))),8,"0",STR_PAD_LEFT).""; $pos += $readlen;
					$readlen =              1; $hilf["TimeUntil"] = (ord(substr($str,$pos,1))*0.5).""; $pos += $readlen;
				}

				$deviceconf[$hilf["RFAdress"]]["LiveReadLength"] = $hilf["ReadLengt	h"];
				$deviceconf[$hilf["RFAdress"]]["LiveRFAdress"] = $hilf["RFAdress"];
				$deviceconf[$hilf["RFAdress"]]["Live?1"] = $hilf["?1"];
				if($hilf["ReadLength"] == 11)
				{
					$deviceconf[$hilf["RFAdress"]]["Live?2"] = $hilf["?2"];
					$deviceconf[$hilf["RFAdress"]]["Temperature"] = $hilf["Temperature"];
					$deviceconf[$hilf["RFAdress"]]["DateUntil"] = $hilf["DateUntil"];
					$year = substr($hilf["DateUntil"],-6,6);
					$month = substr($hilf["DateUntil"],0,3).substr($hilf["DateUntil"],8,1);
					$day = substr($hilf["DateUntil"],3,5);
					$deviceconf[$hilf["RFAdress"]]["DateUntil"] = bindec($day).".".bindec($month).".".bindec($year);
					$deviceconf[$hilf["RFAdress"]]["TimeUntil"] = $hilf["TimeUntil"];
					$deviceconf[$hilf["RFAdress"]]["TimestampUntil"] = mktime(floor($hilf["TimeUntil"]),($hilf["TimeUntil"]-floor($hilf["TimeUntil"]))*60,0,bindec($month),bindec($day),bindec($year));
				}

				$deviceconf[$hilf["RFAdress"]]["valid"] = substr($hilf["Data1"],3,1);
				$deviceconf[$hilf["RFAdress"]]["Error"] = substr($hilf["Data1"],4,1);
				$deviceconf[$hilf["RFAdress"]]["isAnswer"] = substr($hilf["Data1"],5,1);
				$deviceconf[$hilf["RFAdress"]]["initialized"] = substr($hilf["Data1"],6,1);
				$deviceconf[$hilf["RFAdress"]]["LiveData7"] = substr($hilf["Data1"],7,1);

				$deviceconf[$hilf["RFAdress"]]["LowBatt"] = substr($hilf["Data2"],0,1);
				$deviceconf[$hilf["RFAdress"]]["LinkError"] = substr($hilf["Data2"],1,1);
				$deviceconf[$hilf["RFAdress"]]["PanelLock"] = substr($hilf["Data2"],2,1);
				$deviceconf[$hilf["RFAdress"]]["GatewayOK"] = substr($hilf["Data2"],3,1);
				$deviceconf[$hilf["RFAdress"]]["DST"] = substr($hilf["Data2"],4,1);
				$deviceconf[$hilf["RFAdress"]]["Not used"] = substr($hilf["Data2"],5,1);
				switch (substr($hilf["Data2"],6,2))
				{
					case "00" : $deviceconf[$hilf["RFAdress"]]["Mode"] = "auto"; break;
					case "01" : $deviceconf[$hilf["RFAdress"]]["Mode"] = "manu"; break;
					case "10" : $deviceconf[$hilf["RFAdress"]]["Mode"] = "vacation"; break;
					case "11" : $deviceconf[$hilf["RFAdress"]]["Mode"] = "boost"; break;
				}
				$deviceconf[$hilf["RFAdress"]]["LiveDataX"] = $hilf["Data3"];
				echo "\n";
			}
		break;
	}
}

if (basename($_SERVER['SCRIPT_FILENAME']) != "interface.php")
{
$ob = ob_get_contents(); 
ob_end_clean();
echo $ob;
print_r($data);
echo "\n<hr />\n";
print_r($deviceconf);
}
ob_end_clean();

echo "</pre>";
?>
Post Reply

Return to “Homematic, FS20, FHT, ESA and ELV”