maxill1 / node-ialarm

A node library to control iAlarm (https://www.antifurtocasa365.it/) or other chinese 'TCP IP' alarm system like Meian and Emooluxr
MIT License
3 stars 0 forks source link

[feature] meian tcp client protocol #2

Closed maxill1 closed 3 years ago

maxill1 commented 4 years ago

Right now the library use a web scraper to parse html web panel and grab data.

As suggested here we could use the protocol described in https://github.com/wildstray/meian-client/wiki to directly connect.

Actually i made a separate branch with basic implementation.

https://github.com/maxill1/node-ialarm/tree/feature/tcp-client

Most of the commands are working, I just need to cleanup the data and optimize the code which is pretty raw.

I don't have much spare time right now so any help would be appreciated.

stezak77 commented 4 years ago

I've tested setAlarmStatus and getAlarmStatus functions against my alarm system and they work great.

RyuzakiKK commented 3 years ago

I'm planning on doing the same in https://github.com/RyuzakiKK/pyialarm too.

The current problem that I'm facing is how to get the "triggered" status. Because "GetAlarmStatus" only gives you the info about armed, disarmed, armed away or clear, but it doesn't change when the alarm has been triggered.

I thought about iterating through the zones and check their status but "GetWlsStatus" doesn't work on my side, I'm always receiving empty responses.

@maxill1 Have you found a solution to this problem?

maxill1 commented 3 years ago

I'm planning on doing the same in https://github.com/RyuzakiKK/pyialarm too.

The current problem that I'm facing is how to get the "triggered" status. Because "GetAlarmStatus" only gives you the info about armed, disarmed, armed away or clear, but it doesn't change when the alarm has been triggered.

I thought about iterating through the zones and check their status but "GetWlsStatus" doesn't work on my side, I'm always receiving empty responses.

@maxill1 Have you found a solution to this problem?

Actually I never had a chance to test any further. I hope I can find the time next week. I will keep you posted.

RyuzakiKK commented 3 years ago

Okay thanks.

For your information, by the tests that I performed, the only place where I was able to get the triggered status was by looking at the log. So now I ask for the last entry of the log and check if it is a triggered event or not https://github.com/RyuzakiKK/pyialarm/blob/master/pyialarm/pyialarm.py#L88

stezak77 commented 3 years ago

For your information, by the tests that I performed, the only place where I was able to get the triggered status was by looking at the log.

Wouldn't it be better checking if there is at least an alarmed zone for the triggered status? The last log entry might be updated to something else, while the alarm is still triggered.

RyuzakiKK commented 3 years ago

Wouldn't it be better checking if there is at least an alarmed zone for the triggered status? The last log entry might be updated to something else, while the alarm is still triggered.

Sure, but the problem is that I was unable to get this information. '/Root/Host/GetZone' just returns which zones are in use and their name. No info about their current status.

stezak77 commented 3 years ago

Sure, but the problem is that I was unable to get this information. '/Root/Host/GetZone' just returns which zones are in use and their name. No info about their current status.

Alright. Can you get anything from '/Root/Host/GetWlsStatus' ? That should be the wireless device paired with the zone, could it include some status info?

stezak77 commented 3 years ago

@wildstray could you give some help based on your experience with the dissector?

maxill1 commented 3 years ago

@RyuzakiKK, I just remembered something that can be useful.

Calling /Root/Host/GetByWay results in something like this: <Err>ERR|00</Err><Root><Host><GetByWay><Total>S32,0,40|40</Total><Offset>S32,0,40|0</Offset><Ln>S32,0,40|16</Ln><L0>S32,1,255|9</L0><L1>S32,1,255|9</L1><L2>S32,1,255|9</L2><L3>S32,1,255|1</L3><L4>S32,1,255|1</L4><L5>S32,1,255|9</L5><L6>S32,1,255|1</L6><L7>S32,1,255|1</L7><L8>S32,1,255|1</L8><L9>S32,1,255|1</L9><L10>S32,1,255|1</L10><L11>S32,1,255|1</L11><L12>S32,1,255|1</L12><L13>S32,1,255|1</L13><L14>S32,1,255|1</L14><L15>S32,1,255|9</L15><Err></Err></GetByWay></Host></Root>

Let's consider Zone 2 (<L1>S32,1,255|9</L1>), the number 9 should mean that the sensor has some kind of fault (open). I also observed 1, 5, 13 and hardcoded them on "zoneStatus" property in https://github.com/maxill1/node-ialarm/blob/feature/tcp-client/src/constants.js to handle them with the same data structure I used with the scraper version .

I think that the value 9 after the pipe is the equivalent of 16 in the JS function used by the web admin javascript array to decode the current Zone state.

This is the JS function that produces the html at the bottom of the post.

function SystemStatus() {
    var data = new Array();
    var number = 1;

    var SysMsg = 0;
    var ZoneMsg = new Array(0, 16, 16, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0);

    data.push("<div class='table-responsive'><table class='table table-striped'>\
                                     <tr>\
                                        <th scope='col'>NO.</th>\
                                        <th scope='col'>ZONE/SYSTEM</th>\
                                        <th scope='col'>STATUS</th>\
                                    </tr>");

    if (SysMsg & 1) {
        data.push("<tr><th scope='row'>" + number + "</th><td>0</td><td>system AC power fault</td></tr>");
        number++;
    }
    if (SysMsg & 2) {
        data.push("<tr><th scope='row'>" + number + "</th><td>0</td><td>system battery fault</td></tr>");
        number++;
    }
    if (SysMsg & 4) {
        data.push("<tr><th scope='row'>" + number + "</th><td>0</td><td>system energency alarm</td></tr>");
        number++;
    }

    for (i = 1; i < 41; i++) {
        if (ZoneMsg[i - 1] & 3) {
            data.push("<tr style='color:#FF0000'><th scope='row'>" + number + "</th><td>" + i + "</td><td>zone alarm</td></tr>");
            number++;
        }
        if (ZoneMsg[i - 1] & 8) {
            data.push("<tr><th scope='row'>" + number + "</th><td >" + i + "</td><td>zone bypass</td></tr>");
            number++;
        }
        else if (ZoneMsg[i - 1] & 16) {
            data.push("<tr style='color:#FF6600'><th scope='row'>" + number + "</th><td>" + i + "</td><td>zone fault</td></tr>");
            number++;
        }
        if ((ZoneMsg[i - 1] & 32) && ((ZoneMsg[i - 1] & 8) == 0)) {
            data.push("<tr><th scope='row'>" + number + "</th><td>" + i + "</td><td>wireless detector low battery</td></tr>");
            number++;
        }
        if ((ZoneMsg[i - 1] & 64) && ((ZoneMsg[i - 1] & 8) == 0)) {
            data.push("<tr><th scope='row'>" + number + "</th><td>" + i + "</td><td>wireless detector loss</td></tr>");
            number++;
        }
    }

    data.push('</table></div>');

    document.getElementById('DisplayStatus').innerHTML = data.join('');
}

image

RyuzakiKK commented 3 years ago

@maxill1 You are absolutely right, when I did my testings last weekend I totally missed /Root/Host/GetByWay.

I just tested it and I confirm that this function returns the current status of all the zones. As soon as I have some free time I'll update my library to use that.

RyuzakiKK commented 3 years ago

@maxill1 I implemented it here https://github.com/RyuzakiKK/pyialarm/commit/f7c085f47d3caeb45bbad38ba97c4f87163f6255

With a couple of manual testing I gathered the information for all the common types of zone status.

stezak77 commented 3 years ago

@maxill1 I just created an improvement request in order to enable the Meian protocol implementation for the node-red iAlarm component (that is what I'm using to integrate the alarm system in home assistant) https://github.com/maxill1/node-red-contrib-ialarm/issues/4

maxill1 commented 3 years ago

node-ialarm 0.4.x is now using tcp implementation (for nodered i still need to update the plugin)

stezak77 commented 3 years ago

Thanks @maxill1 great job!