Skip to content

Custom Card "Senoro.Win Door/Window Sensor"

This is a custom card for the Senoro.Win door and window sensor that combines a reed contact with a handle position sensor. The card displays the current state with visual indicators and optional battery monitoring.

Senoro Win Card

Credits

Author: T1ppes - 2026

Features

  • Dual Sensor Display: Shows both the reed contact status (open/closed) and handle position (closed/tilted/open)
  • Smart State Detection:
    • Locked: Contact closed AND handle closed
    • Closed: Contact closed, handle tilted or open
    • Tilted: Contact open AND handle tilted
    • Open: Contact open AND handle open
    • Manipulated: Contact open BUT handle closed (security alert)
  • Visual Indicators:
    • Color-coded icon and background based on state
    • Lock/unlock badge icon on the sensor icon
    • Optional battery level monitoring with warning indicator
  • Customizable:
    • Custom name and icon
    • Optional background color highlighting
    • Configurable battery warning thresholds

Requirements

  • Senoro.Win Sensor: A door or window sensor from Senoro.de with both contact and handle position sensors
  • Home Assistant Entities:
    • Binary sensor for the reed contact (e.g., binary_sensor.door_contact)
    • Sensor for the handle position (e.g., sensor.door_handle) - states should be "Closed", "Tilted", or "Open"
    • Optional: Battery level sensor (e.g., sensor.door_battery)

Variables

Variable Default Required Notes
ulm_custom_card_senoro_win_handle yes Entity ID of the handle position sensor
ulm_custom_card_senoro_win_name entity.friendly_name no Custom name for the sensor
ulm_custom_card_senoro_win_icon entity.icon or mdi:window-closed no Custom icon
ulm_custom_card_senoro_win_color blue no Color for open/tilted states (blue, green, yellow, red, etc.)
ulm_custom_card_senoro_win_force_background_color false no Enable background color highlighting
ulm_custom_card_senoro_win_battery_level no Entity ID of the battery level sensor
ulm_custom_card_senoro_win_battery_warning 20 no Battery percentage for yellow warning
ulm_custom_card_senoro_win_battery_warning_low 5 no Battery percentage for red warning
ulm_show_last_changed false no Show last changed time instead of state

States and Icons

Contact Handle State Icon Color
OFF Closed Locked Lock Green
OFF Tilted/Open Closed Lock Default
ON Tilted Tilted Unlock Blue/Custom
ON Open Open Unlock Blue/Custom
ON Closed Manipulated Alert Red

Usage

Basic Configuration

- type: "custom:button-card"
  template: custom_card_senoro_win
  entity: binary_sensor.front_door_contact
  variables:
    ulm_custom_card_senoro_win_handle: sensor.front_door_handle

Full Configuration with All Options

- type: "custom:button-card"
  template: custom_card_senoro_win
  entity: binary_sensor.balcony_door_contact
  variables:
    ulm_custom_card_senoro_win_handle: sensor.balcony_door_handle
    ulm_custom_card_senoro_win_name: "Balcony Door"
    ulm_custom_card_senoro_win_icon: "mdi:door"
    ulm_custom_card_senoro_win_color: "yellow"
    ulm_custom_card_senoro_win_force_background_color: true
    ulm_custom_card_senoro_win_battery_level: sensor.balcony_door_battery
    ulm_custom_card_senoro_win_battery_warning: 25
    ulm_custom_card_senoro_win_battery_warning_low: 10

Multiple Windows in a Grid

- type: "grid"
  columns: 2
  cards:
    - type: "custom:button-card"
      template: custom_card_senoro_win
      entity: binary_sensor.bedroom_window_contact
      variables:
        ulm_custom_card_senoro_win_handle: sensor.bedroom_window_handle
        ulm_custom_card_senoro_win_name: "Bedroom"
        ulm_custom_card_senoro_win_battery_level: sensor.bedroom_window_battery

    - type: "custom:button-card"
      template: custom_card_senoro_win
      entity: binary_sensor.living_room_window_contact
      variables:
        ulm_custom_card_senoro_win_handle: sensor.living_room_window_handle
        ulm_custom_card_senoro_win_name: "Living Room"
        ulm_custom_card_senoro_win_battery_level: sensor.living_room_window_battery

Template Code

Template Code
---
### Custom Card Senoro Win ###
custom_card_senoro_win:
  template:
    - "icon_info_bg"
    - "ulm_language_variables"
    - "ulm_custom_card_senoro_win_language_variables"
  variables:
    ulm_custom_card_senoro_win_entity: "[[[ return entity.entity_id ]]]"
    ulm_custom_card_senoro_win_handle: ""
    ulm_custom_card_senoro_win_name: ""
    ulm_custom_card_senoro_win_icon: ""
    ulm_custom_card_senoro_win_color: "blue"
    ulm_custom_card_senoro_win_force_background_color: false
    ulm_custom_card_senoro_win_battery_level: ""
    ulm_custom_card_senoro_win_battery_warning: 20
    ulm_custom_card_senoro_win_battery_warning_low: 5
    ulm_show_last_changed: false
  triggers_update: "all"
  name: >
    [[[
      if (variables.ulm_custom_card_senoro_win_name) {
        return variables.ulm_custom_card_senoro_win_name;
      }
      return entity.attributes.friendly_name;
    ]]]
  icon: >
    [[[
      if (variables.ulm_custom_card_senoro_win_icon && variables.ulm_custom_card_senoro_win_icon !== "") {
        return variables.ulm_custom_card_senoro_win_icon;
      }
      return entity.attributes.icon;
    ]]]
  label: >
    [[[
      if (variables.ulm_show_last_changed) {
        return states[entity.entity_id].last_changed;
      }
      const contact = states[variables.ulm_custom_card_senoro_win_entity].state;
      const handle = states[variables.ulm_custom_card_senoro_win_handle].state;
      if (contact === "unavailable" || handle === "unavailable"){
        return variables.ulm_unavailable;
      } else if (contact === "off" && handle === "Closed"){
        return variables.ulm_custom_card_senoro_win_locked;
      } else if (contact === "off" && (handle === "Tilted" || handle === "Open")){
        return variables.ulm_custom_card_senoro_win_closed;
      } else if (contact === "on" && handle === "Tilted"){
        return variables.ulm_custom_card_senoro_win_tilted;
      } else if (contact === "on" && handle === "Open"){
        return variables.ulm_custom_card_senoro_win_open;
      } else if (contact === "on" && handle === "Closed"){
        return variables.ulm_custom_card_senoro_win_manipulated;
      }
      return "Unknown";
    ]]]
  state:
    - operator: "template"
      value: >
        [[[
          const contact = states[variables.ulm_custom_card_senoro_win_entity].state;
          return (contact === "on");
        ]]]
      styles:
        icon:
          - color: >
              [[[
                const contact = states[variables.ulm_custom_card_senoro_win_entity].state;
                const handle = states[variables.ulm_custom_card_senoro_win_handle].state;
                if (contact === "on"){
                  if (handle === "Closed"){
                    return 'rgba(var(--color-red), 1)';
                  } else {
                    var color = variables.ulm_custom_card_senoro_win_color;
                    return 'rgba(var(--color-' + color + '), 1)';
                  }
                }
              ]]]
        img_cell:
          - background-color: >
              [[[
                const contact = states[variables.ulm_custom_card_senoro_win_entity].state;
                const handle = states[variables.ulm_custom_card_senoro_win_handle].state;
                if (contact === "on"){
                  if (handle === "Closed"){
                    return 'rgba(var(--color-red), 0.2)';
                  } else {
                    var color = variables.ulm_custom_card_senoro_win_color;
                    return 'rgba(var(--color-' + color + '), 0.2)';
                  }
                }
              ]]]
        card:
          - background-color: >
              [[[
                const contact = states[variables.ulm_custom_card_senoro_win_entity].state;
                const handle = states[variables.ulm_custom_card_senoro_win_handle].state;
                if (variables.ulm_custom_card_senoro_win_force_background_color) {
                  if (contact === "on" && (handle === "Tilted" || handle === "Open")){
                    var color = variables.ulm_custom_card_senoro_win_color;
                    return 'rgba(var(--color-' + color + '),var(--opacity-bg))';
                  } else if (contact === "on" && handle === "Closed"){
                    return 'rgba(var(--color-red),var(--opacity-bg))';
                  }
                }
              ]]]
  custom_fields:
    notification: >
      [[[
        const contact = states[variables.ulm_custom_card_senoro_win_entity].state;
        const handle = states[variables.ulm_custom_card_senoro_win_handle].state;
        if (handle === "Tilted" || handle === "Open"){
           return `<ha-icon icon="mdi:lock-open-variant" style="width: 12px; height: 12px; color: var(--primary-background-color);"></ha-icon>`;
        } else if (contact === "off" && handle === "Closed"){
          return `<ha-icon icon="mdi:lock" style="width: 12px; height: 12px; color: var(--primary-background-color);"></ha-icon>`;
        } else if (contact === "on" && handle === "Closed"){
           return `<ha-icon icon="mdi:alert" style="width: 12px; height: 12px; color: var(--primary-background-color);"></ha-icon>`;
        }
      ]]]
    notification_battery: >
      [[[
        if (variables.ulm_custom_card_senoro_win_battery_level !== "") {
          if (states[variables.ulm_custom_card_senoro_win_battery_level].state <= variables.ulm_custom_card_senoro_win_battery_warning) {
            return `<ha-icon icon="mdi:battery-low" style="width: 12px; height: 12px; color: var(--primary-background-color);"></ha-icon>`;
          }
        }
      ]]]
  styles:
    grid:
      - position: "relative"
    custom_fields:
      notification:
        - border-radius: "50%"
        - position: "absolute"
        - left: "28px"
        - top: "-6px"
        - height: "16px"
        - width: "16px"
        - border: "2px solid var(--card-background-color)"
        - font-size: "12px"
        - line-height: "14px"
        - background-color: >
            [[[
              const contact = states[variables.ulm_custom_card_senoro_win_entity].state;
              const handle = states[variables.ulm_custom_card_senoro_win_handle].state;
              if (contact === "off" && handle === "Closed"){
                return "rgba(var(--color-green),1)";
              } else {
                return "rgba(var(--color-red),1)";
              }
            ]]]
      notification_battery:
        - border-radius: "50%"
        - position: "absolute"
        - left: "-6px"
        - top: "-6px"
        - height: "16px"
        - width: "16px"
        - border: "2px solid var(--card-background-color)"
        - font-size: "12px"
        - line-height: "14px"
        - background-color: >
            [[[
              if (variables.ulm_custom_card_senoro_win_battery_level !== "") {
                if (states[variables.ulm_custom_card_senoro_win_battery_level].state <= variables.ulm_custom_card_senoro_win_battery_warning_low) {
                  return "rgba(var(--color-red),1)";
                } else if (states[variables.ulm_custom_card_senoro_win_battery_level].state <= variables.ulm_custom_card_senoro_win_battery_warning) {
                  return "rgba(var(--color-yellow),1)";
                }
              }
            ]]]

Language Variables

The card supports multiple languages. Available translations:

English (EN)
---
### Custom Card Senoro Win - English Language Variables ###
ulm_custom_card_senoro_win_language_variables:
  variables:
    ulm_custom_card_senoro_win_open: "Open"
    ulm_custom_card_senoro_win_tilted: "Tilted"
    ulm_custom_card_senoro_win_closed: "Closed"
    ulm_custom_card_senoro_win_locked: "Locked"
    ulm_custom_card_senoro_win_manipulated: "Manipulated"
    ulm_custom_card_senoro_win_battery_is_at: "Battery is at"
German (DE)
---
### Custom Card Senoro Win - German Language Variables ###
ulm_custom_card_senoro_win_language_variables:
  variables:
    ulm_custom_card_senoro_win_open: "Offen"
    ulm_custom_card_senoro_win_tilted: "Gekippt"
    ulm_custom_card_senoro_win_closed: "Geschlossen"
    ulm_custom_card_senoro_win_locked: "Verschlossen"
    ulm_custom_card_senoro_win_manipulated: "Manipuliert"
    ulm_custom_card_senoro_win_battery_is_at: "Batterie ist an"

Note: Only include the language file you need. Delete the others to prevent loading order issues.

Troubleshooting

Handle States Not Working

Make sure your handle sensor reports states as "Closed", "Tilted", and "Open" (with capital first letters). If your sensor uses different values (like "closed", "tilted", "open" in lowercase), you'll need to adjust the card's label section or create a template sensor to convert the states.

Battery Icon Not Showing

Verify that:

  1. The battery sensor entity ID is correct
  2. The battery level is a number (percentage)
  3. The battery level is below your warning threshold

Icon Not Displaying

If you see a generic icon instead of your door/window icon, check that your contact sensor entity has an icon attribute set in Home Assistant.

Support

For issues, questions, or feature requests, please open an issue on the UI Lovelace Minimalist GitHub repository.