ZigbeeContactSwitch

About

The ZigbeeContactSwitch class provides a contact switch endpoint for Zigbee networks. This endpoint implements the Zigbee Home Automation (HA) standard for door/window contact sensors and other binary contact devices.

Features: * Contact state detection (open/closed) * Configurable application types * Automatic reporting capabilities * Integration with common endpoint features (binding, OTA, etc.) * Zigbee HA standard compliance

Use Cases: * Door and window sensors * Security system contacts * Cabinet and drawer sensors * Industrial contact monitoring * Smart home security applications

API Reference

Constructor

ZigbeeContactSwitch

Creates a new Zigbee contact switch endpoint.

ZigbeeContactSwitch(uint8_t endpoint);
  • endpoint - Endpoint number (1-254)

API Methods

setClosed

Sets the contact switch to closed state.

bool setClosed();

This function will return true if successful, false otherwise.

setOpen

Sets the contact switch to open state.

bool setOpen();

This function will return true if successful, false otherwise.

report

Manually reports the current contact state.

bool report();

This function will return true if successful, false otherwise.

setIASClientEndpoint

Sets the IAS Client endpoint number (default is 1).

void setIASClientEndpoint(uint8_t ep_number);
  • ep_number - IAS Client endpoint number

requestIASZoneEnroll

Requests a new IAS Zone enrollment. Can be called to enroll a new device or to re-enroll an already enrolled device.

bool requestIASZoneEnroll();

This function will return true if the enrollment request was sent successfully, false otherwise. The actual enrollment status should be checked using the enrolled() method after waiting for the enrollment response.

restoreIASZoneEnroll

Restores IAS Zone enrollment from stored attributes. This method should be called after rebooting an already enrolled device. It restores the enrollment information from flash memory, which is faster for sleepy devices compared to requesting a new enrollment.

bool restoreIASZoneEnroll();

This function will return true if the enrollment was successfully restored, false otherwise. The enrollment information (zone ID and IAS CIE address) must be available in the device’s stored attributes for this to succeed.

enrolled

Checks if the device is currently enrolled in the IAS Zone.

bool enrolled();

This function returns true if the device is enrolled, false otherwise. Use this method to check the enrollment status after calling requestIASZoneEnroll() or restoreIASZoneEnroll().

Example

Contact Switch Implementation

// Copyright 2024 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @brief This example demonstrates Zigbee contact switch (IAS Zone).
 *
 * The example demonstrates how to use Zigbee library to create a end device contact switch.
 * The contact switch is a Zigbee end device, which is reporting data to the Zigbee network.
 *
 * Proper Zigbee mode must be selected in Tools->Zigbee mode
 * and also the correct partition scheme must be selected in Tools->Partition Scheme.
 *
 * Please check the README.md for instructions and more detailed description.
 *
 * Created by Jan Procházka (https://github.com/P-R-O-C-H-Y/)
 */

#ifndef ZIGBEE_MODE_ED
#error "Zigbee end device mode is not selected in Tools->Zigbee mode"
#endif

#include "Zigbee.h"
#include <Preferences.h>

/* Zigbee contact sensor configuration */
#define CONTACT_SWITCH_ENDPOINT_NUMBER 1
uint8_t button = BOOT_PIN;
uint8_t sensor_pin = 4;

ZigbeeContactSwitch zbContactSwitch = ZigbeeContactSwitch(CONTACT_SWITCH_ENDPOINT_NUMBER);

/* Preferences for storing ENROLLED flag to persist across reboots */
Preferences preferences;

void setup() {
  Serial.begin(115200);

  preferences.begin("Zigbee", false);               // Save ENROLLED flag in flash so it persists across reboots
  bool enrolled = preferences.getBool("ENROLLED");  // Get ENROLLED flag from preferences
  preferences.end();

  // Init button + switch
  pinMode(button, INPUT_PULLUP);
  pinMode(sensor_pin, INPUT_PULLUP);

  // Optional: set Zigbee device name and model
  zbContactSwitch.setManufacturerAndModel("Espressif", "ZigbeeContactSwitch");

  // Add endpoint to Zigbee Core
  Zigbee.addEndpoint(&zbContactSwitch);

  Serial.println("Starting Zigbee...");
  // When all EPs are registered, start Zigbee in End Device mode
  if (!Zigbee.begin()) {
    Serial.println("Zigbee failed to start!");
    Serial.println("Rebooting...");
    ESP.restart();
  } else {
    Serial.println("Zigbee started successfully!");
  }
  Serial.println("Connecting to network");
  while (!Zigbee.connected()) {
    Serial.print(".");
    delay(100);
  }
  Serial.println();

  // Check if device has been enrolled before restarting - if so, restore IAS Zone enroll, otherwise request new IAS Zone enroll
  if (enrolled) {
    Serial.println("Device has been enrolled before - restoring IAS Zone enrollment");
    zbContactSwitch.restoreIASZoneEnroll();
  } else {
    Serial.println("Device is factory new - first time joining network - requesting new IAS Zone enrollment");
    zbContactSwitch.requestIASZoneEnroll();
  }

  while (!zbContactSwitch.enrolled()) {
    Serial.print(".");
    delay(100);
  }
  Serial.println();
  Serial.println("Zigbee enrolled successfully!");

  // Store ENROLLED flag only if this was a new enrollment (previous flag was false)
  // Skip writing if we just restored enrollment (flag was already true)
  if (!enrolled) {
    preferences.begin("Zigbee", false);
    preferences.putBool("ENROLLED", true);  // set ENROLLED flag to true
    preferences.end();
    Serial.println("ENROLLED flag saved to preferences");
  }
}

void loop() {
  // Checking pin for contact change
  static bool contact = false;
  if (digitalRead(sensor_pin) == HIGH && !contact) {
    // Update contact sensor value
    zbContactSwitch.setOpen();
    contact = true;
  } else if (digitalRead(sensor_pin) == LOW && contact) {
    zbContactSwitch.setClosed();
    contact = false;
  }

  // Checking button for factory reset
  if (digitalRead(button) == LOW) {  // Push button pressed
    // Key debounce handling
    delay(100);
    int startTime = millis();
    while (digitalRead(button) == LOW) {
      delay(50);
      if ((millis() - startTime) > 3000) {
        // If key pressed for more than 3secs, factory reset Zigbee and reboot
        Serial.println("Resetting Zigbee to factory and rebooting in 1s.");
        // Clear the ENROLLED flag from preferences
        preferences.begin("Zigbee", false);
        preferences.putBool("ENROLLED", false);  // set ENROLLED flag to false
        preferences.end();
        Serial.println("ENROLLED flag cleared from preferences");
        delay(1000);
        Zigbee.factoryReset();
      }
    }
  }
  delay(100);
}