ParadoxIP150v2 icon indicating copy to clipboard operation
ParadoxIP150v2 copied to clipboard

EVO compatibility

Open mnmn2 opened this issue 8 years ago • 151 comments

Hello, I've got an EVO192, and tried your great code, but of course, it won't work perfectly :) (Of course it works fine at a friend of mine, who has a MG5050)

I modified the config, to skip the label-readings, because it's not a big issue to enter them manually. I've concentrated on the events. I've got the programming documents, describing the event codes (which are totally different to the MG5050). Modified the eventGroupMap array, but it still seems to work bad, the "decoded" events are not the ones, that are really happening...

Do you have some kind of SDK or other info about the EVO192? Or only the Wireshark reverse-engineering could work?

thanks, MN

mnmn2 avatar Aug 22 '16 06:08 mnmn2

Hi

There seems to be quite a few differences between the EVO and MG series when it comes to register locations. I found the PGM registers to also not work. Best bet would be to play with wireshark and see it you can pick up a pattern. Must be honest I did give an EVO192 a go once before and I think the labels did work. Maybe also confirm that your firmware is up to date...?

Tertiush avatar Aug 22 '16 17:08 Tertiush

Hello, the Evo192 has firmaware 2.90, and the IP150 has 1.34.00 (Strange, but after 15 mins I gave up finding the latest firmware numbers... I don't know if these are the latest...)

I'm stepping ahead quite slowly. Or very slowly. :) It seems, that my EVO is not configured to put every event on the bus, but only the arm/disarm related events are showing up. But I'm not sure, because at the moment I'm just guessing...

It seems, that the EventGroup field is message[10], and subevent group is message[11]. The worst thing, is that there is no delimiter char between 2 messages. So if there comes a "multiple data" message, then it's not decoded. Maybe I could compare the lengths, and split by a predefined length.

I'm not a real fan of WinLoad (I guess, a UFO had defined it's functionality), but it seems, that I will have to learn it in depth...

mnmn2 avatar Aug 22 '16 17:08 mnmn2

Meanwhile it turned out, that message[10] and message[12] are the right fields. And also realized, that an incoming datagram can have 3 formats:

  1. simple 1 header (starts with \xaa, 16 bytes long) + 1 simple body (37 bytes long)
  2. simple 1 header (starts with \xaa, 16 bytes long) + more than 1 simple body (n*37 bytes long, no real delimiter)
  3. concatenation of the 1. and 2. type. So there can be 3 message bodies within a datagram, with 2 \xaa headers

Of course, the meanings of the event codes are totally different, but documented in Paradox tutorials.

It seems, that there are no events generated, on opening/closing Zones.

And it seems, that WinLoad also does not receive "special" datagrams. However, the keepalive message is different. It's multiplied. The sequence goes up to 16 (or 19 sometimes), and there are different values in the fields. And there are replies to these keepalive messages, sent by the IP module. The responses are almost the same (compared upon the sequences), if there is no change in the Zone/partition statuses, and there are varying fields, if there is movement for example. The "reverse engineering" of these fields and values is a nice task for the near future :)

mnmn2 avatar Aug 25 '16 19:08 mnmn2

That's awesome! Great work & good luck with the reverse engineering. There's a lot of guys wanting to integrate to the BW-only devices!

Tertiush avatar Aug 26 '16 08:08 Tertiush

Just let you know: I'm progressing, but slowly... Already identified the keepalive messages, which replies contains info about Zone status changes, and Partition Satuses, even about the bypassed zones. However the result-codes are not really obvious at this moment. Still need some Winload-Wireshark work...

mnmn2 avatar Aug 31 '16 05:08 mnmn2

Progress, great! Thanks for the update

Tertiush avatar Aug 31 '16 09:08 Tertiush

@mnmn2 Are you following the discussion at https://github.com/Tertiush/ParadoxIP150v2/issues/4 ?

Tertiush avatar Aug 31 '16 13:08 Tertiush

@mnmn2 Could you share with the code for EVO192?

varaslt avatar Oct 19 '16 19:10 varaslt

Tertiush - all good work. I wrote a web page scraper for Vera in Lua for the EVO given some of your inspiration: Scraper plugin I would have to say that the Paradox web page code is pretty poor. BabyWare is pretty sad too. Currently it seems I don't need to use any keep alives, which I also found strange. Maybe I'm polling sufficiently to keep it happy. However, I would prefer to use the 10,000 port as it has more control than the web page.

Few questions: I see that one can use the COM.ini file to control the encoding used by WinLoad. I tried this on BabyWare and failed. It has a COM.ini file located under folder In-Field. This ends up in a virtual store at C:\Users\user\AppData\Local\VirtualStore. In either case, making changes to this file of any of its variables has no effect. Since it's in folder In-Field, I suspect its only used by the in field firmware updating tool or maybe I'm doing it wrong.

So does any one know how to control the encoding used by BabyWare?

Does WinLoad require an account or is stand alone? Last thing I want is another account? But I might have to resort to that?

I had a go decrypting the IP150 login - thought it might be using similar methods to the web page login but have failed so far to decode. Get's tricky; the programmer could be using their home phone number for salt. Who knows? Regardless, it certainly returns some sort of session key, each time you login, to further frustrate things.

a-lurker avatar Oct 23 '16 06:10 a-lurker

Hi, I just popped a post here, have a look: https://community.openhab.org/t/help-build-binding-for-paradox-alarm-panel-with-ip150/1712/94?u=tertius_hyman

I've replicated paradox's rc4 and md5 hashing in code, by basically rewriting their functions (in commun.js i think) to python. The rev3 version should be able to do most functions however, not sure if you can use that via MQTT in micasaverde (I don't know the platform/framework).

Regarding the encryption, I haven't used babyware as I only have an MG5050. Winload can however perform bypasses and PGM (only 1->5) controls via winload, so I'm not too sure what babyware adds to the mix.

regards, Tertius

On Sun, 23 Oct 2016 at 08:30 a-lurker [email protected] wrote:

Tertiush - all good work. I wrote a web page scraper for Vera in Lua for the EVO given some of your inspiration: Scraper plugin http://forum.micasaverde.com/index.php/topic,38854.0.html I would have to say that the Paradox web page code is pretty poor. BabyWare is pretty sad too. Currently it seems I don't need to use any keep alives, which I also found strange. Maybe I'm polling sufficiently to keep it happy. However, I would prefer to use the 10,000 port as it has more control than the web page.

Few questions: I see that one can use the COM.ini file to control the encoding used by WinLoad. I tried this on BabyWare and failed. It has a COM.ini file located under folder In-Field. This ends up in a virtual store at C:\Users\user\AppData\Local\VirtualStore. In either case, making changes to this file of any of its variables has no effect. Since it's in folder In-Field, I suspect its only used by the in field firmware updating tool or maybe I'm doing it wrong.

So does any one know how to control the encoding used by BabyWare?

Does WinLoad require an account or is stand alone? Last thing I want is another account? But I might have to resort to that?

I had a go decrypting the IP150 login - thought it might be using similar methods to the web page login but have failed so far to decode. Get's tricky; the programmer could be using their home phone number for salt. Who knows? Regardless, it certainly returns some sort of session key, each time you login, to further frustrate things.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/Tertiush/ParadoxIP150v2/issues/5#issuecomment-255572226, or mute the thread https://github.com/notifications/unsubscribe-auth/ALGOjOz_Sr1wuQLXijeR-FqzFCmlsNIsks5q2v8ZgaJpZM4JpjXB .

Tertiush avatar Oct 25 '16 18:10 Tertiush

@varaslt of course, I can. BUT meanwhile I had to stop the development (for a while) so the current code is a "mess", and not a code, what I could be proud of... And only the status-reading is covered. The control processes (arm/disarm, etc) are not implemented yet.

if it still interests you, let me know, how can I send the code.

mnmn2 avatar Oct 28 '16 18:10 mnmn2

@mnmn2 Yes I'm interested in and I do not need arm/disarm functionality so far. So please share your code if you can :) Have you the code in some repository? If not and you do not want to show it in public please send it by mail - [email protected]

varaslt avatar Oct 31 '16 04:10 varaslt

@varaslt I have sent you the code by email best regards,

mnmn2 avatar Oct 31 '16 07:10 mnmn2

Hello, This weekend I started to implement openHAB (also my first practical mqtt experience), and since I have a Paradox EVO192, I came acros this project. Currently I'm running the http/v1/polling solution but would like to switch to v2 and use the direct connection. I can test and report if needed (depending on free time it can take a couple of days).

I tested the Arm/Disarm functionality with v1 and it seems to work, but the 'Disarmed' status is reported as 8 and 9. These states are switching every couple of minutes. Maybe it has something to do with a 'Low Battery' trouble in one of my wireless detectors. Any documentation where I can verify the available states?

Also I read somewhere there is a .Net SDK, I'm very familiar with (.net) managed code decompiling, anyone tried this path to reverse engineer the protocol?

andrasj avatar Nov 13 '16 19:11 andrasj

@andrasj I got these values for the EVO 192, via the IP150 web page decode. I don't have battery devices, so I'm interested in what 4 and 8 represent. I assume 'Stay' is the same thing as 'Sleep'?

[0] = 'Area not in use'
[1] = 'Instant'
[2] = 'Armed'
[3] = 'Alarm triggered'
[4] = '4'
[5] = 'Stay'
[6] = 'Entry Delay'
[7] = 'Exit delay'
[8] = '8'
[9] = 'Disarmed'

I also found that the Zone Status was not just a case of 0 or 1. That may be an issue for Tertius's code? It was for mine. I get this so far:

closed           0
open             1
bypass           ??
trouble          ??
in alarm         ??
memory & closed  5
memory & open    6
memory & open   & not an alarm trigger 2
memory & closed & not an alarm trigger 5

a-lurker avatar Nov 27 '16 05:11 a-lurker

@a-lurker I had a quick look at the Android app's code and got these for alarm states: 1 = Disarmed 2 = Armed 3 = In alarm 4 = Armed in sleep (not applicable to EVO) 5 = Armed in stay 6 = Entry delay 7 = Exit delay 8 = Ready to arm 9 = Not ready to arm 10 = Instant

And for zone statuses: 0 = Closed 1 = Opened 2 = In alarm 3 = Closed with trouble 4 = Open with trouble 5 = Closed with alarm in memory 6 = Open with alarm in memory 7 = Bypassed 8 = Closed with trouble (duplicate?) 9 = Open with trouble (duplicate?)

My plan is still to port the core code of the Alarmin app into a standalone nodejs script with MQTT support, much the same as for v2 but with support for everything the app can do. Just haven't got the time to do it yet...

Tertiush avatar Nov 27 '16 08:11 Tertiush

Alarm stades described by @a-lurker seem to be correct, but on my EVO I never see state '1-Disarmed', only 'Ready to arm' and 'Not ready to arm' (the last is shown when one of the motion sensors is 'open')

For zone status, I only get 0 and 1, the sensor with 'low battery trouble' just reports 0/1.

andrasj avatar Dec 10 '16 08:12 andrasj

My system when get armed after exit time countdown, I seen this message by script (may helps) I edited nothing yet on the script. this is a raw output just some dot lines deleted. I haven't got wireless devices

Larry = Username Building = Partition label

Attempting connection to MQTT Broker: 127.0.0.1:1883
1481738963: New connection from 127.0.0.1 on port 1883.
1481738963: New client connected from 127.0.0.1 as paho/0E81CF47655FD9F1FC (c1, k60).
MQTT client subscribed to control messages on topic: Paradox/C/#
Connected to MQTT broker with result code 0
Logging into alarm system...
Login to alarm panel successful
Updating all labels from alarm
Labels detected for wirelessKeypadLabel:
{1: '', 2: '', 3: '', 4: '', 5: '', 6: '', 7: '', 8: '\x14\x10\x0c\x0e\x12\t-\x05'}
Labels detected for wirelessSirenLabel:
{1: '', 2: '', 3: '', 4: ''}
Labels detected for siteNameLabel:
{1: ''}
Labels detected for partitionLabel:
{1: '', 2: ''}
Labels detected for wirelessRepeaterLabel:
{1: '', 2: ''}
Labels detected for outputLabel:
{1: '', 2: '', 3: '', 4: '', 5: '', 6: '', 7: '', 8: '', 9: '', 10: '', 11: '', 12: '', 13: '', 14: '', 15: '', 16: ''}
Labels detected for zoneLabel:
{1: '', 2: '', 3: '', 4: '', 5: '', 6: '', 7: '', 8: '', 9: '', 10: '', 11: '', 12: '', 13: '', 14: '', 15: '', 16: '', 17: '', 18: '', 19: '', 20: '', 21: '', 22: '', 23:                                                                  '', 24: '', 25: '', 26: '', 27: '', 28: '', 29: '', 30: '', 31: '', 32: '', 99: 'Any zone'}
Labels detected for userLabel:
{1: '', 2: '', 3: '', 4: '', 5: '', 6: '', 7: '', 8: '', 9: '', 10: '', 11: '', 12: '', 13: '', 14: '', 15: '', 16: '', 17: '', 18: '', 19: '', 20: '', 21: '', 22: '', 23:                                                                  '', 24: '', 25: '', 26: '', 27: '', 28: '', 29: '', 30: '', 31: '', 32: ''}
Labels detected for busModuleLabel:
{1: '', 2: '', 3: '', 4: '', 5: '', 6: '', 7: '', 8: '', 9: '', 10: '', 11: '', 12: '', 13: '', 14: '', 15: ''}
Listening for events...
.
Event:Bypass programming;SubEvent:
.
Event:Bypass programming;SubEvent:
.
Event:Bypass programming;SubEvent:
.
Event:Bypass programming;SubEvent:
.
Event:Bypass programming;SubEvent:
.
Multiple data: ['\xe0\xffWt\x14\x10\x0c\x0e\x12\r\x0c\x01\x04\x00\x00\x00\x00\x00\x04Buliding        \x00J\xe0\xffWu\x14\x10\x0c\x0e\x12\r\t\x01\x02\x00\x00\x00\x00\x00\x01                                                                 Larry           \x00\x7f', '\xe0\xffWs\x14\x10\x0c\x0e\x12\r\x04\x01\x03\x00\x00\x00\x00\x00\x04Buliding        \x00@']
Event:Bypass programming;SubEvent:
Event:Bypass programming;SubEvent:
.

if stay armed, and moving in a stay zone: Kitchen, Office (Z3,Z4), Warehouse (Z6), Upstair Corridor(Z5) is a Zone labels, strange thing is some zone names dosen't came trough.

Event:User code activated output (Partition 1);SubEvent:
.
Event:User code activated output (Partition 1);SubEvent:
.
Event:User code activated output (Partition 1);SubEvent:
.
Event:User code activated output (Partition 1);SubEvent:
.
Event:User code activated output (Partition 1);SubEvent:
.
Multiple data: ['\xe0\xffW\xc0\x14\x10\x0c\x0f\x01"\x01\x01\x04\x00\x00\x00\x00\x00\x02Kitchen         \x00F', '\xe0\xffW\xbf\x14\x10\x0c\x0f\x01"\x00\x01\x04\x00\x00\x00\x00\x00\x02Kitchen         \x00D']
Event:User code activated output (Partition 1);SubEvent:
Event:User code activated output (Partition 1);SubEvent:
.
Event:User code activated output (Partition 1);SubEvent:
.
Event:User code activated output (Partition 1);SubEvent:
.
Multiple data: ['\xe0\xffW\xc4\x14\x10\x0c\x0f\x01"\x00\x01\x04\x00\x00\x00\x00\x00\x02Kitchen         \x00I', '\xe0\xffW\xc3\x14\x10\x0c\x0f\x01"\x01\x01\x03\x00\x00\x00\x00\x00\x02Office          \x00\xee']
Event:User code activated output (Partition 1);SubEvent:
Event:User code activated output (Partition 1);SubEvent:
.
Multiple data: ['\xe0\xffW\xc6\x14\x10\x0c\x0f\x01"\x01\x01\x03\x00\x00\x00\x00\x00\x02Office          \x00\xf1', '\xe0\xffW\xc5\x14\x10\x0c\x0f\x01"\x00\x01\x03\x00\x00\x00\x00\x00\x02Office          \x00\xef']
.
Event:User code activated output (Partition 1);SubEvent:
.
Multiple data: ['\xe0\xffW\xd7\x14\x10\x0c\x0f\x01*\x00\x01\x07\x00\x00\x00\x00\x00\x02Warehouse       \x00\x14', '\xe0\xffW\xd6\x14\x10\x0c\x0f\x01*\x00\x01\x05\x00\x00\x00\x00\x00\x02Upstair Corridor\x00\xca']
Event:User code activated output (Partition 1);SubEvent:
Event:User code activated output (Partition 1);SubEvent:
.

larryl79 avatar Dec 15 '16 01:12 larryl79

@Tertiush Very big thank you for this project and all of your efforts! Of course I had and EVO192, that's why I interested to include your code into my project. Did you had a chance to work on "v3" based on NodeJS what you mentioned?

@mnmn2 Can you please inform us if any progress do you have recently? Or can you share with me also your current code?

and finaly @andrasj If I'm guessing correctly we are from a same country :) maybe we can help each other?

rferenc avatar Jan 23 '17 10:01 rferenc

Hi, unfortunately not yet. Life has become somewhat busy and I just haven't had the chance to finish it. It's still a very rough port of the Alarmin app's code and not yet in a running state. To be honest I probably won't get this done in the next few months. It's still something I want to complete as I also want to use it in that form, and decommission the other versions. So it will happen eventually.

Tertiush avatar Jan 23 '17 18:01 Tertiush

@Tertiush Any EVO specific code what you could share would be really appreciated!

From my perspective it can be Android, Python, NodeJS or any other language! :) My basic goal to "transfer" EVO events to MQ.

rferenc avatar Jan 24 '17 09:01 rferenc

@rferenc Sure we all can help each other. Even if you're not from Belgium ;-) Currently I'm busy too, but trying to reorganize to have more time for personal projects. If your goal is to publish your events to MQ, I can confirm that V1 (python) does work for EVO192. Just the translations of the error codes are not complete (but could be fixed with the descriptions of @a-lurker ) (I'm using it in openHAB through MQTT binding) However I agree, a more event driven solution would be preferred. (I think it is better to start describing the communication protocol, if that's clear, implementing will be easy)

andrasj avatar Jan 24 '17 14:01 andrasj

The problem with the EVO code is that it's not the same as for the MG/SP series, specifically the initial connection/startup code. In my app I have a branch in said code that splits into either of the two depending on the alarm type. I will share this (below).

Regarding events (zone and alarm changes), the V1 code is the most stable and interoperable, with v2 adding PGM and bypass (also working for EVO in the Alarmin app). The fact that PGM and bypass only work in the Alarmin app is still odd to me, but as pointed out before when both connections (web & software) is made at the same time it just works..... So all in all, its just a matter of merging V1 and V2. V1 does statuses and V2 the PGM and bypass. There's not much more code that I can contribute other than everything rewritten in nodeJS.

Here's the MG/SP and EVO code that branches:

  • pass = password (ip module - UTF8)

  • createSocket() is self explanatory

  • joinUint8Arrays simply concatenates the arrays and returns a new (longer) array

  • sendData() sends the data on the socket, the second parameters flags whether a response is needed before we can proceed. The response itself is in most cases irrelevant.

  • format37ByteMessage() same as for v2, just pads and adds a checksum

  • I'm again using a state machine, mostly as I need to resolve promises in an orderly fashion (something I had to learn the hard way starting with nodeJS).

  • Also note I'm not a programmer by day-job, so the code is written so that I understand it and not formatted to any known style. lol

  • Some comments are in Afrikaans. If I had a bit more time I would've translated it, Google will though. ` function loginStateMachine(_State, _lastReply) { var loginStateMachineDeferred = $q.defer();

      state = _State;
      lastReply = _lastReply
    
      console.log("Swp LoginStateMachine state = " + state)
    
      if (state == 0) {
    
          createSocket();
          header[0] = 0xAA;  //# First construct the 16 byte header, starting with 0xaa
    
          /*header[1] = pass.length.toString(16);
          var x = pass.length.toString(16);
          header[1] = x;
          header[1] = ('0' + (x & 0xFF));*/
          header[1] = pass.length
    
          header[2] = 0x00;   //# No idea what this is
          header[3] = 0x03;
          header[4] = 0x08;     //# Encryption off [default for now] else: header += "\x09"  # Encryption on
    
          header[5] = 0xF0; //# No idea what this is, although the fist byte seems like a sequence number
          header[6] = 0x00;
          header[7] = 0x0A;
    
    
          for (var i = 8; i < 16; i++)
              header[i] = 0xee;
    
          var message2 = new Uint8Array(16);
    
          for (var i = 0; i < (pass.length) ; i++) {
              message2[i] = pass.charCodeAt(i);
          }
    
          for (var i = (pass.length) ; i < 16; i++)
              message2[i] = 0xee;
    
          packet = joinUint8Arrays(header, message2)
    
    
          sendData(packet, 1).then(function (reply) {
              loginStateMachineDeferred.resolve(reply)
          })
      } else if (state == 1) {
    
          header[1] = 0x00
          header[5] = 0xf2
    
          //packet = joinUint8Arrays(header, message)
    
          sendData(header, 1).then(function (reply) {
              loginStateMachineDeferred.resolve(reply)
          })
    
      } else if (state == 2) {
    
          header[5] = 0xf3
    
          sendData(header, 1).then(function (reply) {
              loginStateMachineDeferred.resolve(reply)
          })
    
      } else if (state == 3) {
    
          header[1] = 0x25
          header[3] = 0x04
          header[5] = 0x00
          message2 = new Uint8Array([0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
    
          messageToSend = format37ByteMessage(message2)
          packet = joinUint8Arrays(header, messageToSend)
    
          sendData(packet, 1).then(function (reply) {
              var myString = new TextDecoder("utf-8").decode(reply);
              if (myString.indexOf("EVO") >= 0) {  // Changed to "EVO" only to process further (from "EVO192")
                  alarmType = 1;
                  console.log("!!!!!!!!!!!!EVO DETECTED!!!!!!!!!!!!!!!!!!!!!!!!")
              }
              else
              {
                  alarmType = 0;
              }
              loginStateMachineDeferred.resolve(reply)
          })
    
      } else if (state == 4) {
    
          //EVO Stuur eers dit vir state 4: aa 09 00 03 08 f8 00 0a  ee ee ee ee ee ee ee ee  0a 50 08 00 00 01 00 00  59 ee ee ee ee ee ee ee
          if (alarmType == 0) {
              header[1] = 0x26
              header[3] = 0x03
              header[5] = 0xf8
              message[0] = 0x50
              message[2] = 0x80
    
              messageToSend = format37ByteMessage(message)
              packet = joinUint8Arrays(header, messageToSend)
    
              sendData(packet, 1).then(function (reply) {
                  loginStateMachineDeferred.resolve(reply)
              })
    
          }
          else if (alarmType == 1) {
              var packet = new Uint8Array([0xaa, 0x09, 0x00, 0x03, 0x08, 0xf8, 0x00, 0x0a, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x0a, 0x50, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x59, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee])
              sendData(packet, 1).then(function (reply) {
                  loginStateMachineDeferred.resolve(reply)
              })
          }
    
      } else if (state == 5) {
    
          header[1] = 0x25    //EVO: Presies dieselfde
          header[3] = 0x04
          header[5] = 0x00
          message[0] = 0x5f
          message[1] = 0x20
          message[2] = 0x00
    
          messageToSend = format37ByteMessage(message)
          packet = joinUint8Arrays(header, messageToSend)
    
          sendData(packet, 1).then(function (reply) {
              loginStateMachineDeferred.resolve(reply)
          })
    
      } else if (state == 6) {
          header[1] = 0x25
          header[3] = 0x04
          header[5] = 0x00
          header[7] = 0x14
    
          for (i = 0; i < 10; i++)        //message = reply[16:26]
              message[i] = lastReply[i + 16];
    
          message[10] = lastReply[24 + 16]         //message += reply[24:26]
          message[11] = lastReply[25 + 16]
    
          if (alarmType == 0) {
              message[12] = 0x19          //EVO: 0x0a
              message[13] = 0x00          //EVO: 0x30
              message[14] = 0x00          //EVO: 0x02
          } else if (alarmType == 1) {
              message[12] = 0x0a          //EVO: 0x0a
              message[13] = 0x30          //EVO: 0x30
              message[14] = 0x02          //EVO: 0x02
          }
    
          for (i = 0; i < 9; i++)        //message += reply[31:39]
              message[i + 15] = lastReply[i + 31];
    
          for (i = 0; i < 13; i++)        //message += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00'
              message[i + 25] = 0x00;
    
          message[33] = 0x02              //Go back for the 0x02
    
          //message = self.format37ByteMessage(message) - But message > 37 ??????
    
          messageToSend = format37ByteMessage(message)
          packet = joinUint8Arrays(header, messageToSend)
    
          sendData(packet, 1).then(function (reply) {
              loginStateMachineDeferred.resolve(reply)
          })
    
      } else if (state == 7) {
    
          /* EVO is klaar, of stuur:
    
          00000120  aa 08 00 04 08 00 00 14  ee ee ee ee ee ee ee ee   ........ ........
          00000130  50 08 00 00 00 00 20 78  ee ee ee ee ee ee ee ee   P..... x ........
    
          en dan
    
          00000140  aa 08 00 04 08 00 00 14  ee ee ee ee ee ee ee ee   ........ ........
          00000150  50 08 80 00 00 01 40 19  ee ee ee ee ee ee ee ee   P.....@. ........
    
          */
          if (alarmType == 0) {
              header[1] = 0x25
              header[3] = 0x04
              header[5] = 0x00
              header[7] = 0x14
    
              message = new Uint8Array([0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
    
              messageToSend = format37ByteMessage(message)
              packet = joinUint8Arrays(header, messageToSend)
    
              sendData(packet, 0).then(function (reply) {
                  loginStateMachineDeferred.resolve(reply)
              })
          }
          else if (alarmType == 1)
          {
              var packet = new Uint8Array([0xaa, 0x08, 0x00, 0x04, 0x08, 0x00, 0x00, 0x14, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x50, 0x08, 0x00, 0x00, 0x00, 0x00, 0x20, 0x78, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee])
              sendData(packet, 1).then(function (reply) {
                  loginStateMachineDeferred.resolve(reply)
              })
          }
    
      } else if (state == 8) {
    
          if (alarmType == 0) {
              message = new Uint8Array([0x50, 0x00, 0x0e, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
    
              messageToSend = format37ByteMessage(message)
              packet = joinUint8Arrays(header, messageToSend)
    
              sendData(packet, 0).then(function (reply) {
                  loginStateMachineDeferred.resolve(reply)
              })
          }
          else if (alarmType == 1)
              var packet = new Uint8Array([0xaa, 0x08, 0x00, 0x04, 0x08, 0x00, 0x00, 0x14, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x50, 0x08, 0x80, 0x00, 0x00, 0x01, 0x40, 0x19, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee])
              sendData(packet, 1).then(function (reply) {
                  loginStateMachineDeferred.resolve(reply)
              })
      }
    
    
      return loginStateMachineDeferred.promise;
    

    }`

Tertiush avatar Jan 24 '17 19:01 Tertiush

Nice my Evo Alarm is now fully functional Arm Disarm all PIRs working Siren Exit delay and I've got 3 PGMS working all integrated into home Assistant Thanks for doing the ground work for this Took a lot of work for me to make it work for the EVO but couldn't comprehend the time the development took Thanks Guys

FigJam23 avatar Jul 12 '17 13:07 FigJam23

This is some real basic vidoeo operations on my test rig alarm panel I made using the v1 code modified. These test videos are running on my EVO48 With no PGM control as it just using the web interface did have some luck firing the Ip150 PGM but was not stable.

https://youtu.be/S2BSCECVr4w

https://youtu.be/_1TH44O2LhY

https://youtu.be/9rvtPuZD-vs

I will do some videos of the v2 code with both EVO48 and the 192 using PGMs as there are some small differences I've found

FigJam23 avatar Jul 14 '17 22:07 FigJam23

@mydakota, is there any chance you could share the modified v2 code you are using with V2? I'm desperate to get the same working and the latest firmware for the IP150 removes direct web control so V1 cannot work :-(

juzzmoore avatar Sep 16 '17 14:09 juzzmoore

@Tertiush: Do you have any time-frame for the V3 script? I'm only asking because I want to integrate my EVO192 and if your script will be released in the foreseeable future, I'll stay away from reverse engineering and implement it for V2 :) Thanks for your hard work to these great scripts!

@mydakota: If you could share the V2 code you have, compatible with the EVO192, would be a lifesaver for me.

MorpheusRO avatar Nov 10 '17 23:11 MorpheusRO

@MorpheusRO I'm afraid not. I really wish I had the time to work on it but its just not happening. If anyone want to do it please do. I will share whatever code is needed from the Alarmin app, just drop me a line. Sorry for this and taking so long to reply.

Tertiush avatar Nov 26 '17 16:11 Tertiush

@mydakota: could you please share your v2 code modified for EVO192? Thanks.

danbba1 avatar Jan 08 '18 10:01 danbba1

@mydakota Would you be able to share your v2 code for the EVO192? Thanks!

jphenning avatar Jan 12 '18 08:01 jphenning