Skip to content

FabInfra/FabAccess-esphome-components

Repository files navigation

API Resource Status Component for ESPHome

This custom ESPHome component allows integration with an Attraccess API to monitor the status of resources in real-time. It uses Server-Sent Events (SSE) to establish a persistent connection to your API and receive real-time updates when the resource status changes.

Features

  • Real-time updates using Server-Sent Events (SSE)
  • Persistent connection to your API (no polling)
  • Automatic reconnection if connection is lost
  • Works with public API endpoints (no authentication needed)
  • Exposes a sensor to monitor resource status values
  • Provides a binary sensor for API connectivity
  • Allows ESPHome automations to be triggered based on status changes

Installation

To use this component, add it to your ESPHome configuration as an external component:

external_components:
  - source:
      type: git
      url: https://github.com/jappyjan/Attraccess-esphome-components.git
    components: [api_resource_status]

You can also use a specific reference (tag, branch, or commit):

external_components:
  - source:
      type: git
      url: https://github.com/jappyjan/Attraccess-esphome-components.git
      ref: main
    components: [api_resource_status]

Make sure to place the component files in a components/api_resource_status directory in your ESPHome configuration directory.

Configuration

Component Configuration

# Configure the component
api_resource_status:
  api_url: http://your-api-url.example.com/api
  resource_id: "12345" # Always use quotes for numeric resource_id values
  refresh_interval: 30s # Used for reconnect attempts, not polling
  # Authentication is not needed for public resources
  # username: not_needed
  # password: not_needed

Configuration Options

  • api_url (Required, string): The base URL of your API (must use HTTP, not HTTPS)
  • resource_id (Required, string): The numeric ID of the resource to monitor. While this is configured as a string in YAML, it should be a numeric value as the API expects a number (e.g., use "12345" in your configuration for resource ID 12345)
  • refresh_interval (Optional, time): How often to attempt reconnection if the connection is lost, defaults to 60s
  • username (Optional, string): Username for authentication (not needed for public resources)
  • password (Optional, string): Password for authentication (not needed for public resources)

Sensor Configuration

# Add a sensor to display the status
sensor:
  - platform: api_resource_status
    name: "Resource Status"
    id: resource_status
    unit_of_measurement: "%"
    accuracy_decimals: 1
    # Other standard sensor options are supported

Binary Sensor Configuration

# Add a binary sensor to show API availability
binary_sensor:
  - platform: api_resource_status
    name: "API Availability"
    id: api_availability
    # Other standard binary sensor options are supported

Server API Requirements

Your API needs to support Server-Sent Events (SSE) at the endpoint:

http://your-api-url.example.com/api/resources/{resource_id}/events

The API should send updates in the SSE format:

data: {"status": 0.75}

The value should be a number that represents the status of the resource. This value will be published to the sensor.

Example Implementation for Your API Server

Here's a simple example of how to implement SSE for public resources on your server using Node.js and Express:

const express = require("express");
const app = express();

// Store connected clients for each resource
const clients = {};

// SSE endpoint - public access, no auth required
app.get("/api/resources/:resourceId/events", (req, res) => {
  const resourceId = req.params.resourceId;

  // Set SSE headers
  res.setHeader("Content-Type", "text/event-stream");
  res.setHeader("Cache-Control", "no-cache");
  res.setHeader("Connection", "keep-alive");

  // Send initial status
  const currentStatus = getResourceStatus(resourceId);
  res.write(`data: ${JSON.stringify({ status: currentStatus })}\n\n`);

  // Add this client to the clients for this resource
  if (!clients[resourceId]) {
    clients[resourceId] = [];
  }
  clients[resourceId].push(res);

  // Handle client disconnect
  req.on("close", () => {
    clients[resourceId] = clients[resourceId].filter(
      (client) => client !== res
    );
  });
});

// Function to get current resource status
function getResourceStatus(resourceId) {
  // Implementation to fetch resource status
  return 0.75; // Example value
}

// Function to update all connected clients for a resource
function updateResourceClients(resourceId, status) {
  if (clients[resourceId]) {
    clients[resourceId].forEach((client) => {
      client.write(`data: ${JSON.stringify({ status })}\n\n`);
    });
  }
}

// Example of updating a resource status
// This would be called whenever the resource status changes
function updateResource(resourceId, newStatus) {
  // Update the status in your database or system
  // ...

  // Then notify all connected clients
  updateResourceClients(resourceId, newStatus);
}

app.listen(3000, () => {
  console.log("Server is running on port 3000");
});

Example Automations

You can use the sensor value to trigger automations:

automation:
  - id: resource_status_critical
    description: "Trigger when resource status is critical"
    trigger:
      - platform: numeric_state
        entity_id: sensor.resource_status
        below: 10 # Trigger when status below 10%
    action:
      - logger.log:
          format: "Resource status is critically low: %.1f%%"
          args: ["id(resource_status).state"]

Complete Example

See example_config.yaml for a complete configuration example. The example already uses Git as the source, showing how to properly integrate this component using the repository URL.

About

ESPHome components for easily integrating the FabAccess Access Contorl Software into your IOT devices

Resources

Stars

Watchers

Forks

Packages

No packages published