Ajax alarm system

Unfortunately I don’t have experience on this. But may what says Gemini could help. Does it makes sense ti you? Here it is:
To allow a user to use this function for the entities of your integration, you need to ensure two main things are implemented in your code:

1. Assign a Unique ID

This is the most crucial element. Every entity your integration creates must have a unique and persistent identifier. Home Assistant uses this ID to save the entity in the entity registry (entity_registry) and allow it to be modified in the UI (like manually changing the ID or using the “Recreate entity IDs” function).

  • Implementation: In your entity class (which inherits from the base entity class, e.g., homeassistant.components.sensor.SensorEntity), you must define the _attr_unique_id attribute.`Python# Example for a Sensor entity
    from homeassistant.components.sensor import SensorEntity
class MyEntity(SensorEntity):
    def __init__(self, ...):
        # ... (other initializations)

        # The unique ID must be a stable string, 
        # specific to the physical or logical entity/device.
        self._attr_unique_id = f"{self.device_id}_my_unique_sensor" 
        # self.device_id would be the unique ID of the device
    # Alternatively, you can use the `Entity.async_set_unique_id` method 
    # when adding the entity, but setting the attribute is common.`

Important Note: The unique ID must not change over time or between Home Assistant restarts.

2. Link Entities to a Device

For the “Recreate entity IDs” function to appear on the device page, all entities must be correctly linked to a Device in the Home Assistant device registry (device_registry).

  • Implementation: Define the _attr_device_info attribute of your entity. This tells Home Assistant which Device (represented by a DeviceEntry) this entity belongs to.`Pythonfrom homeassistant.helpers.entity import DeviceInfo
# In your entity class
self._attr_device_info = DeviceInfo(
    # The unique identifier of the device
    identifiers={(DOMAIN, self.device_id)}, 
    name="My Device Name",
    # Optional: manufacturer, model, sw_version, etc.
)`The `DeviceEntry` should be created (if necessary) during your integration's setup (often via a `ConfigEntry`).

In Summary:

The “Recreate entity IDs” function is a built-in feature of Home Assistant. You don’t need to add specific code to “activate” the button itself. You only need to follow best integration development practices by providing a unique_id for every entity and linking them to a device via device_info.

From time to time, almost as soon as I click Arm or Disarm press button this error message is displayed
" Failed to connect to https://external_address_of_jeedom_instance:port_number"
I’m sure it is 100% of the time online.

You can enable debug for Ajax plugin in jeedom. Then in Analysis->logs every request will be displayed.

Every outgoing call start from ha_direct_call

Is request present in Jeedom log, after you saw “failed to connect” message? What HA log say, maybe there is more info?

When your ARM already armed system - api will not send any answer. So I add ARM switch, wich follows current arm status. It’s better to use switches, instead of buttons.

Sorry to answer you a bit late, I’ve been quite busy and I wanted to have a clear picture of what is going on.

From time to time, when an action is set (arm, disarm, arm night) there is no result at the end of the process. It is never due to the communication between your integration and Jeedom, since each time a message is indeed logged in ajax Jeedom. It is more a problem between Jeedom and Ajax API that I already noticed.

Recreate id’s: as a matter of fact as of now it does not recreate id’s because the new creation is based on the serial number. Let me try to be clear and take the hub as an example. All hub entity_id’s are based on serial numbers. When it is asked to recreate id’s it should be based on the name that is given to the hub. But currently, your integration recreate id’s based on the serial number so obviously when it is asked to recreate id’s it can’t.

It seems there is a bug in the zone state management. I have four zones. When a single zone is armed, some time after or right away the related zone is set to armed and the three other zones are set to armed as well (that is switch.zone_id_arm). But only the wanted zone is indeed armed (I know it either by monitoring Ajax app or with SIA alarm integration).

Here is the code to define the Alarm control panel. It shall be noticed that current states are based on SIA integration this gives a kind of double check that everything is set correctly.

  - platform: template
    panels:
      alarm_id_new:
        unique_id: alarm_id_new
        name: Alarme new
        code_arm_required: false
        code_format: no_code
        value_template: >
          {% if 
            is_state("alarm_control_panel.5656_ccc_zone_1_alarm", "armed_away") and
            is_state("alarm_control_panel.5656_ccc_zone_2_alarm", "armed_away") and
            is_state("alarm_control_panel.5656_ccc_zone_3_alarm", "armed_away") and
            is_state("alarm_control_panel.5656_ccc_zone_4_alarm", "armed_away")
          %}
            armed_away
          {% elif
            is_state("alarm_control_panel.5656_ccc_zone_1_alarm", "disarmed") and
            is_state("alarm_control_panel.5656_ccc_zone_2_alarm", "disarmed") and
            is_state("alarm_control_panel.5656_ccc_zone_3_alarm", "disarmed") and
            is_state("alarm_control_panel.5656_ccc_zone_4_alarm", "disarmed")
            %}
            disarmed
          {% elif
            is_state("alarm_control_panel.5656_ccc_zone_1_alarm", "armed_night") and
            is_state("alarm_control_panel.5656_ccc_zone_2_alarm", "armed_night") and
            is_state("alarm_control_panel.5656_ccc_zone_4_alarm", "armed_night")
          %}
            armed_night
          {% elif
            is_state("alarm_control_panel.5656_ccc_zone_1_alarm", "triggered") or
            is_state("alarm_control_panel.5656_ccc_zone_2_alarm", "triggered") or
            is_state("alarm_control_panel.5656_ccc_zone_3_alarm", "triggered") or
            is_state("alarm_control_panel.5656_ccc_zone_4_alarm", "triggered")
            %}
            triggered
          {% elif
            is_state("alarm_control_panel.5656_ccc_zone_1_alarm", "armed_away") or
            is_state("alarm_control_panel.5656_ccc_zone_2_alarm", "armed_away") or
            is_state("alarm_control_panel.5656_ccc_zone_3_alarm", "armed_away") or
            is_state("alarm_control_panel.5656_ccc_zone_4_alarm", "armed_away")
            %}
            armed_home
          {% else %}
            unavailable
          {% endif %}
        arm_away:
          - action: button.press
            target:
              entity_id: button.hubid_arm
        arm_night:
          - action: button.press
            target:
              entity_id: button.hubid_night_mode_on       
        disarm:
          - action: button.press
            target:
              entity_id: button.hubid_disarm

and the code for the card

type: custom:vertical-stack-in-card
cards:
  - type: alarm-panel
    states:
      - arm_night
      - arm_away
    entity: alarm_control_panel.alarm_id_new
    card_mod:
      style:
        .: |
          ha-card {
          border-radius: 20px 20px 20px 20px;
          border-bottom: hidden;
          }
        ha-assist-chip:
          $: |
            div > md-ripple {
              {% if is_state("alarm_control_panel.alarm_id_new", "disarmed") %}
                background-color: green;
              {% elif is_state("alarm_control_panel.alarm_id_new", "armed_away") %}
                background-color: chocolate
              {% elif is_state("alarm_control_panel.alarm_id_new", "armed_night") %}
                background-color: chocolate
              {% elif is_state("alarm_control_panel.alarm_id_new", "triggered") %}
                background-color: darkred
              {% endif %}         
            }        
  - square: false
    type: grid
    cards:
      - show_name: true
        show_icon: true
        type: button
        tap_action:
          action: toggle
        entity: switch.00000003_arm
        name: Petite maison
        icon_height: 35px
      - show_name: true
        show_icon: true
        type: button
        tap_action:
          action: toggle
        entity: switch.00000002_arm
        name: Grande maison
        icon_height: 35px
      - show_name: true
        show_icon: true
        type: button
        tap_action:
          action: toggle
        entity: switch.00000001_arm
        name: Café François
        icon_height: 35px
      - show_name: true
        show_icon: true
        name: Extérieur
        type: button
        tap_action:
          action: toggle
        entity: switch.00000004_arm
        icon_height: 35px
    columns: 2

I will play with id later.

Let’s fix this first.


This is from from jeedom log. There are two messages after each arm/disarm event. In my example I do disarm / arm to take log.

First one for GROUP state and second, starting from recipient, is Hub SECURITY event. I take armed/disarmed information from both of them.

To understand what is going wrong I need to look on them. I do not need hub id, user if, tokes, etc. But need groups id (it’s just number from 0000001 to 0000004). My hub model is Hub Plus, maybe it has different information for other models

Fair enough;)

My hub is a hub plus as well. I opened an issue on GitHub it will ease follow up on various issues. It’s better to have one thread per issue instead of having everything mixed in the current thread. Let me know whether that suits you.

(post deleted by author)

1 Like

I will, just give me a few days before feedback.
I have hub plus, range extender, door protect plus, door protect, motion protect, space control, transmitter, street siren, socket, fire protect.

1 Like

finally a proper implementation that does not need Jeedom! Thank you! I have installed it and I am testing it with 15 different Ajax devices! So far everything was recognized and seems to be working fine. This is what I have:

  • 4 Smoke detectors
  • 4 door contacts
    • 2 motion detectors
  • a keyfob
  • a keypad
  • an internal siren
  • an external siren
    Everything has been recognized and so far the sensors look goo. I’ll keep on reporting here!

Great great job! I will even try to contribute with code! I had my own python implementation of a separate daemon using MQTT (a python hack I coded quite fast) but your integration looks much more stable.
/Nacho

2 Likes

Ajax Security via Jeedom v 0.4 is released. I done everything I need. It’s stable, fast and easy to extend with new devices.

Maybe in the future I will replace Jeedom Installation to HA addon (for instant events) and add direct login with login/password from Jeedom Marketplace. Or maybe switch to direct Ajax integration :slight_smile: It depends on users feedback and how everything will work in long term.

Ajax was last my smart device, without HA support. Now we have 2 fully functional integrations!

One has disappeared…what happened?

1 Like

I don’t know, i actually donated to him couple days ago and he refunded the donation and removed the ajax-hass repository?

What happened @foXaCe ?

I would not be surprised that the way the dev is done without prior contentment of Ajax lead to a breach in Ajax legal rules. If it is true, it is a real shame on Ajax side. They can explain all they want, they’re none willingness to give us access to there API is not in their Favour, despite their excellent line of products. I’ve been using jeedom integration, the least I can say it is not very reliable. I may have to fallback to the really great integration Ajax to jeedom, despite the fact that jeedom integration is not very reliable.

1 Like

I have about 18 Ajax devices on a Hub 2 Plus and it works beautifully, very reliable, easy installation.

Except i won’t be buying any more Ajax products without them opening up their API and allowing HA integration because their Scenario’s are extremely limited in the app.

we all know that their attitude is, to say the least, no customer friendly. Very disappointed as well.