gicamm / homeassistant-comelit

With Comelit Hub/Vedo integration, you can connect your Home Assistant instance to Comelit Simple Home and Vedo systems.
Apache License 2.0
23 stars 7 forks source link

Enable vedo sensors #81

Closed pbartolome closed 4 months ago

pbartolome commented 5 months ago

Hi!, I've just integrated this plugin with my HomeAssitant connected to my new Comelit home system. I haven't played a lot yet with all the options, but with a couple changes I was able to see all VEDO sensors in my HASS system.

Result:

Captura de pantalla 2024-05-31 a las 13 21 40

This works with my system, when opening the door, or enabling the motion sensors, the status changes in Home Assistant. Although it's true that a smaller refresh time its needed to properly detect motion.

I've changed also a couple things that I've find useful for testing:

Let me know if more testing is needed or there are scenarios not covered here, or why did the check was if value > 1 and the status 0011.

Thanks

gicamm commented 5 months ago

Hi, thank you for your work. Below is the response to the 'zone_desc' call.

{
   "logged":1,
   "rt_stat":9,
   "vedo_auth":[
      0,
      1
   ],
   "life":0,
   "present": "1010101010101010101010.......",
   "in_area":[
      146,
      0,
      210,
      0,
      128,
      0,
      146,
      0,
      .......
   ],
   "description":[
      "Zona 24H",
      "",
      "Camera1",
      "",
      "Ingresso P0",
      "",
      "Salotto",
      "",
  .....
   ]
}

That's why we have >1 when we look at the 'in_area'.

Also below is the 'zone_stat' when a sensor triggers a movement.

{
"logged": 1,
"rt_stat": 9,
"vedo_auth": [0,1],
"life": 0,
"status": "0000,0200,0000,0200,0000,0200,0011,0200,......."
}

What kind of sensors do you use?

I have a branch: 42-add-video-sensors with some improvements and the ability to enable/disable sensors.

pbartolome commented 5 months ago

I have different type of sensors, movement, fire, water...

Here are the responses I have in "zone_desc"

{
    "logged": 1,
    "rt_stat": 9,
    "vedo_auth": [
        1,
        1
    ],
    "life": 0,
    "present": "1111110000000000000000000000000000000000000000000000000000000000",
    "in_area": [
        1,
        1,
        1,
        1,
        1,
        1,
        0,
        0,
        0,
        0,
        0,
       ...
    ],
    "description": [
        "Zona 24H",
        "Fuego cocina",
        "Inundación",
        "Puerta entrada",
        "Salón",
        "Pasillo",
        "",
        "",
        ....
    ]
}

And zone_stat when the sensors are off

{
  "logged": 1,
  "rt_stat": 9,
  "vedo_auth": [
    1,
    1
  ],
  "life": 1,
  "status": "0020,0020,0020,0000,0000,0000,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200"
}

And when one sensor is ON

{
  "logged": 1,
  "rt_stat": 9,
  "vedo_auth": [
    1,
    1
  ],
  "life": 0,
  "status": "0020,0020,0020,0000,0001,0000,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200"
}

It seems that more debugging is needed here, I will try to check the logic of the VEDO web panel, as it is showing there correctly the sensors and the status. It seems that the "area" is a numeric identifier (which doesn't need to be > 1), and the status can have more codes that "0011"

gicamm commented 5 months ago

What firmware are you running on the VedoIP component? You can check this on the WebUI page.

pbartolome commented 5 months ago

Firmware: apv=v2.8.1

This seems the JS code related to the status check, first there is a parseInt in base 16 and then a bitwise operation, so neither the "0011" or the "0001" string check that I did is enough

for (var zone_num = 0; zone_num < vedo_zone_data.present.length; zone_num++) {
    var zone_status = parseInt(vedo_zone_data.status[zone_num], 16);

    if ($('#zone_list_' + zone_num)) {
        $('#zone_list_' + zone_num + ' .zone_status.state').removeClass('ok fault sabotage alarm');
        if ((zone_status & 2) != 0) {
            $('#zone_list_' + zone_num + ' .zone_status.state').addClass('alarm');
        } else if ((zone_status & 8) != 0) {
            $('#zone_list_' + zone_num + ' .zone_status.state').addClass('sabotage');
        } else if ((zone_status & 4) != 0) {
            $('#zone_list_' + zone_num + ' .zone_status.state').addClass('fault');
        } else if ((zone_status & 1) == 0) {
            $('#zone_list_' + zone_num + ' .zone_status.state').addClass('ok');
        }

        $('#zone_list_' + zone_num + ' .zone_status.open').css('visibility', 'hidden');
        if ((zone_status & 1) != 0) {
            $('#zone_list_' + zone_num + ' .zone_status.open').css('visibility', '');
        }

        $('#zone_list_' + zone_num + ' .zone_status.presence').removeClass('isolated excluded inhibited');
        if ((zone_status & 128) != 0) {
            $('#zone_list_' + zone_num + ' .zone_status.presence').addClass('excluded');
        } else if ((zone_status & 256) != 0) {
            $('#zone_list_' + zone_num + ' .zone_status.presence').addClass('isolated');
        } else if ((zone_status & 32768) != 0) {
            $('#zone_list_' + zone_num + ' .zone_status.presence').addClass('inhibited');
        }
    }
}

The same with the "in_area" check, neither the ">1" or "==1" seem correct, the check the the web is doing is more complex:

for (var zone_num = 0; zone_num < vedo_zone_data.present.length; zone_num++) {
    if (vedo_zone_data.present[zone_num] != '0') {
        var area_class = '';
        for (var i = 0; i < num_aree; i++) {
            if ((vedo_zone_data.in_area[zone_num] & (1 << i)) != 0) {
                area_class += ' area_' + i;
            }
        }
        html += '<div class="zone_list' + area_class + '" id="zone_list_' + zone_num + '" style="display:none">';
        html += '<div class="icons zone_status state">&nbsp;</div>';
        html += '<div class="icons zone_status open">&nbsp;</div>';
        html += '<div class="icons zone_status presence">&nbsp;</div>';
        html += '<div class="zone_desc" id="zone_' + zone_num + '">' + vedo_zone_data.description[zone_num] + '</div>';
        html += '</div><div class=clear></div>';
    }
}
gicamm commented 5 months ago

I'm running firmware v2.7.3, so something must have changed.

pbartolome commented 5 months ago

can you access the JS of the VEDO website and compare the old logic with the new? maybe we can find a common place that works with both versions?

gicamm commented 5 months ago
for (var zone_num = 0; zone_num < vedo_zone_data.present.length; zone_num++) {
    var zone_status = parseInt(vedo_zone_data.status[zone_num], 16);

    if ($('#zone_list_' + zone_num)) {
        $('#zone_list_' + zone_num + ' .zone_status.state').removeClass('ok fault sabotage alarm');
        if ((zone_status & 2) != 0) {
            $('#zone_list_' + zone_num + ' .zone_status.state').addClass('alarm');
        } else if ((zone_status & 8) != 0) {
            $('#zone_list_' + zone_num + ' .zone_status.state').addClass('sabotage');
        } else if ((zone_status & 4) != 0) {
            $('#zone_list_' + zone_num + ' .zone_status.state').addClass('fault');
        } else if ((zone_status & 1) == 0) {
            $('#zone_list_' + zone_num + ' .zone_status.state').addClass('ok');
        }

        $('#zone_list_' + zone_num + ' .zone_status.open').css('visibility', 'hidden');
        if ((zone_status & 1) != 0) {
            $('#zone_list_' + zone_num + ' .zone_status.open').css('visibility', '');
        }

        $('#zone_list_' + zone_num + ' .zone_status.presence').removeClass('isolated excluded inhibited');
        if ((zone_status & 128) != 0) {
            $('#zone_list_' + zone_num + ' .zone_status.presence').addClass('excluded');
        } else if ((zone_status & 256) != 0) {
            $('#zone_list_' + zone_num + ' .zone_status.presence').addClass('isolated');
        } else if ((zone_status & 32768) != 0) {
            $('#zone_list_' + zone_num + ' .zone_status.presence').addClass('inhibited');
        }
    }
}
for (var zone_num = 0; zone_num < vedo_zone_data.present.length; zone_num++) {
    if (vedo_zone_data.present[zone_num] != '0') {
        var area_class = '';
        for (var i = 0; i < num_aree; i++) {
            if ((vedo_zone_data.in_area[zone_num] & (1 << i)) != 0) {
                area_class += ' area_' + i;
            }
        }
        html += '<div class="zone_list' + area_class + '" id="zone_list_' + zone_num + '" style="display:none">';
        html += '<div class="icons zone_status state">&nbsp;</div>';
        html += '<div class="icons zone_status open">&nbsp;</div>';
        html += '<div class="icons zone_status presence">&nbsp;</div>';
        html += '<div class="zone_desc" id="zone_' + zone_num + '">' + vedo_zone_data.description[zone_num] + '</div>';
        html += '</div><div class=clear></div>';
    }
}

we have the same code

pbartolome commented 4 months ago

closing this PR, I think the proper implementation here is to mimic the logic of the VEDO javascript to cover all cases