Explorar el Código

chore: add documentation

master
Blaz Smehov hace 1 semana
padre
commit
cfab61e665
Se han modificado 3 ficheros con 2197 adiciones y 12 borrados
  1. +410
    -12
      README.md
  2. +748
    -0
      docs/API.md
  3. +1039
    -0
      docs/DEPLOYMENT.md

+ 410
- 12
README.md Ver fichero

@@ -1,23 +1,421 @@
# Project Overview
# AFA Systems Presence Detection

## Bridge
A comprehensive **Bluetooth Low Energy (BLE) presence detection system** that tracks beacon devices in real-time, calculates locations based on signal strength, and integrates with popular IoT platforms like Home Assistant and Node-RED.

Used for sending messages between MQTT broker and Kafka ... Initial config is done
## 🏗️ System Architecture

## Decoder
The system follows a **microservices architecture** with Apache Kafka as the central message bus:

Decoding BLE beacons -> generating notifications (batery, fall detection)
```
┌─────────────┐ MQTT ┌─────────────┐ Kafka ┌─────────────┐
│ MQTT │ ────────► │ Bridge │ ────────► │ Decoder │
│ Gateway │ │ Service │ │ Service │
└─────────────┘ └─────────────┘ └─────────────┘
┌─────────────┐ WebSocket ┌─────────────┐ Kafka ┌─────────────┐
│ Web UI │ ◄────────── │ Server │ ◄───────── │ Location │
│ Dashboard │ │ Service │ │ Algorithm │
└─────────────┘ └─────────────┘ └─────────────┘
```

Still needs to be reimplemented
### Core Components

## Locations algorithm
#### 🔌 **Bridge Service** (`cmd/bridge/`)
- **Purpose**: MQTT to Kafka message gateway
- **Function**: Subscribes to `publish_out/#` MQTT topics and forwards messages to Kafka `rawbeacons` topic
- **Features**: Configurable MQTT connection, automatic reconnection, error handling

Calculating location -> generating notifications
#### 🔍 **Decoder Service** (`cmd/decoder/`)
- **Purpose**: Processes raw BLE beacon advertisements
- **Supported Formats**: Ingics, Eddystone, Minew B7
- **Functions**:
- Battery level monitoring
- Fall detection events
- Button press detection
- Device telemetry extraction
- **Output**: Processed events to `alertbeacons` Kafka topic

still needs to be implemented
#### 📍 **Location Algorithm** (`cmd/location/`)
- **Purpose**: Calculates device locations based on RSSI and proximity
- **Features**:
- Weighted location calculation using RSSI values
- Confidence scoring system
- Location change notifications
- Configurable thresholds and parameters
- **Output**: Location events to `locevents` Kafka topic

## Server
#### 🌐 **Server Service** (`cmd/server/`)
- **Purpose**: HTTP API and WebSocket server
- **Features**:
- RESTful API for beacon management (CRUD operations)
- Real-time WebSocket communication
- Settings management interface
- CORS-enabled web interface
- Home Assistant integration endpoints

Publishing to front end and notifications
#### 📊 **Supporting Services**
- **Kafka 3.9.0**: Central message bus with automatic topic creation
- **Kafdrop**: Web-based Kafka monitoring and management UI
- **Node-RED**: IoT workflow automation with pre-configured flows
- **Redis**: Real-time data caching and WebSocket session management
- **BoltDB**: Embedded database for persistent storage

Still needs to be reimplemented
## 🚀 Quick Start

### Prerequisites

- Docker and Docker Compose
- Go 1.24+ (for local development)
- MQTT broker (compatible with BLE gateways)

### Installation

1. **Clone the repository**:
```bash
git clone https://github.com/AFASystems/presence.git
cd presence
```

2. **Start the system**:
```bash
cd build
docker-compose up -d
```

3. **Verify services**:
- **Web Interface**: http://localhost:8080
- **Kafdrop (Kafka UI)**: http://localhost:9000
- **Node-RED**: http://localhost:1880

### Configuration

Set the following environment variables:

```bash
# Web Server
HTTP_HOST_PATH=":8080"
HTTP_WS_HOST_PATH=":8081"

# MQTT Configuration
MQTT_HOST="tcp://mqtt-broker:1883"
MQTT_USERNAME="your_username"
MQTT_PASSWORD="your_password"

# Kafka Configuration
KAFKA_URL="kafka:29092"

# Database
DB_PATH="./volumes/presence.db"
```

## 📡 Supported Beacon Types

### Ingics Beacons
- Battery level monitoring
- Event detection (fall detection, button presses)
- Signal strength tracking

### Eddystone Beacons
- Eddystone-UID protocol support
- Battery telemetry (Eddystone-TLM)
- Proximity detection

### Minew B7 Beacons
- Vendor-specific format decoding
- Button counter tracking
- Battery status monitoring
- Multiple button modes

## 🔧 Configuration Options

### System Settings (`SettingsVal`)

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `location_confidence` | int64 | 80 | Minimum confidence level for location changes |
| `last_seen_threshold` | int64 | 300 | Time (seconds) before beacon considered offline |
| `beacon_metrics_size` | int | 10 | Number of RSSI measurements to keep for averaging |
| `ha_send_interval` | int64 | 60 | Home Assistant update interval (seconds) |
| `ha_send_changes_only` | bool | true | Send updates only on location changes |
| `rssi_min_threshold` | int64 | -90 | Minimum RSSI value for beacon detection |
| `enforce_rssi_threshold` | bool | true | Filter out weak signals |

### API Endpoints

#### Beacon Management
- `GET /api/beacons` - List all registered beacons
- `POST /api/beacons` - Register a new beacon
- `PUT /api/beacons/{id}` - Update beacon information
- `DELETE /api/beacons/{id}` - Remove a beacon

#### Settings
- `GET /api/settings` - Get current system settings
- `POST /api/settings` - Update system settings

#### WebSocket
- `/ws/broadcast` - Real-time beacon updates and notifications

## 🏠 Home Assistant Integration

### MQTT Auto-Discovery

The system automatically generates MQTT messages for Home Assistant:

```yaml
# Example device tracker configuration
device_tracker:
- platform: mqtt
devices:
beacon_001: "Presence/Beacons/beacon_001"
```

### Battery Monitoring

```yaml
# Battery level sensor
sensor:
- platform: mqtt
name: "Beacon Battery"
state_topic: "Presence/Beacons/beacon_001/battery"
unit_of_measurement: "%"
device_class: battery
```

### Button Detection

```yaml
# Button press sensor
binary_sensor:
- platform: mqtt
name: "Beacon Button"
state_topic: "Presence/Beacons/beacon_001/button"
device_class: "button"
```

## 📊 Data Models

### Core Entities

#### Beacon
```go
type Beacon struct {
Name string `json:"name"`
ID string `json:"beacon_id"`
BeaconType string `json:"beacon_type"`
BeaconLocation string `json:"beacon_location"`
LastSeen int64 `json:"last_seen"`
Distance float64 `json:"distance"`
LocationConfidence int64 `json:"location_confidence"`
HSButtonCounter int64 `json:"hs_button_counter"`
HSBattery int64 `json:"hs_button_battery"`
// ... additional fields
}
```

#### BeaconAdvertisement
```go
type BeaconAdvertisement struct {
Hostname string `json:"hostname"`
MAC string `json:"mac"`
RSSI int64 `json:"rssi"`
Data string `json:"data"`
BeaconType string `json:"beacon_type"`
UUID string `json:"uuid"`
Major string `json:"major"`
Minor string `json:"minor"`
// ... additional fields
}
```

#### LocationChange
```go
type LocationChange struct {
Method string `json:"method"`
BeaconRef Beacon `json:"beacon_info"`
Name string `json:"name"`
PreviousLocation string `json:"previous_location"`
NewLocation string `json:"new_location"`
Timestamp int64 `json:"timestamp"`
}
```

## 🐳 Docker Services

### Available Services

| Service | Image | Ports | Description |
|---------|-------|-------|-------------|
| kafka | apache/kafka:3.9.0 | 9092, 9093 | Apache Kafka message broker |
| kafdrop | obsidiandynamics/kafdrop | 9000 | Kafka monitoring UI |
| presence-bridge | local/build | - | MQTT to Kafka bridge |
| presence-decoder | local/build | - | BLE beacon decoder |
| presence-location | local/build | - | Location calculation service |
| presence-server | local/build | 8080, 8081 | HTTP API and WebSocket server |

### Volumes

- `./volumes/presence.db` - BoltDB database file
- `./volumes/node-red/` - Node-RED configuration and flows
- `./volumes/kafka-data/` - Kafka persistent data

## 🔧 Development

### Local Development Setup

1. **Install dependencies**:
```bash
go mod download
```

2. **Run individual services**:
```bash
# Run bridge service
go run cmd/bridge/main.go

# Run decoder service
go run cmd/decoder/main.go

# Run location algorithm
go run cmd/location/main.go

# Run API server
go run cmd/server/main.go
```

3. **Run tests**:
```bash
go test ./...
```

### Building Docker Images

```bash
# Build all services
docker build -t presence-system .

# Build individual service
docker build -f build/package/Dockerfile.bridge -t presence-bridge .
```

### Project Structure

```
/
├── cmd/ # Main application entry points
│ ├── server/ # HTTP API & WebSocket server
│ ├── bridge/ # MQTT to Kafka bridge
│ ├── decoder/ # BLE beacon decoder
│ ├── location/ # Location calculation algorithm
│ └── testbench/ # Testing/development utilities
├── internal/ # Private application code
│ ├── app/ # Application components
│ └── pkg/ # Shared internal packages
│ ├── model/ # Data structures and types
│ ├── kafkaclient/ # Kafka producer/consumer
│ ├── config/ # Configuration management
│ ├── persistence/ # BoltDB operations
│ ├── redis/ # Redis client
│ └── bridge/ # MQTT bridge logic
├── build/ # Build artifacts and Docker configs
│ ├── package/ # Dockerfile for each component
│ └── docker-compose.yaml # Complete system deployment
├── web/ # Web interface files
├── volumes/ # Persistent data and configurations
├── scripts/ # Utility scripts
└── docs/ # Documentation
```

## 📈 Monitoring and Debugging

### Kafka Topics

- `rawbeacons` - Raw BLE beacon advertisements
- `alertbeacons` - Processed beacon events (battery, buttons)
- `locevents` - Location change notifications

### Health Checks

- **Kafka**: Topic creation and broker connectivity
- **Services**: Automatic restart on failure
- **Database**: BoltDB integrity checks

### Logs

```bash
# View service logs
docker-compose logs -f [service-name]

# View all logs
docker-compose logs -f
```

## 🔌 Integrations

### Node-RED Flows

Pre-configured Node-RED flows are available in `/volumes/node-red/`:

- **Beacon monitoring dashboards**
- **Location-based automations**
- **Battery level alerts**
- **Notification systems**

### MQTT Topics

System publishes to the following MQTT topics:

- `Presence/Beacons/{beacon_id}/location` - Current beacon location
- `Presence/Beacons/{beacon_id}/battery` - Battery level
- `Presence/Beacons/{beacon_id}/button` - Button press events
- `Presence/Beacons/{beacon_id}/distance` - Distance from nearest gateway

## 🤝 Contributing

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

### Development Guidelines

- Follow Go conventions and best practices
- Write comprehensive tests for new features
- Update documentation for API changes
- Use meaningful commit messages

## 📄 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## 🆘 Support

- **Issues**: [GitHub Issues](https://github.com/AFASystems/presence/issues)
- **Documentation**: [Project Wiki](https://github.com/AFASystems/presence/wiki)
- **Discussions**: [GitHub Discussions](https://github.com/AFASystems/presence/discussions)

## 🔮 Roadmap

### Upcoming Features

- [ ] Enhanced location algorithms with machine learning
- [ ] Support for additional beacon types (iBeacon, AltBeacon)
- [ ] Mobile application for beacon management
- [ ] Advanced analytics and reporting dashboard
- [ ] Multi-tenant architecture
- [ ] Cloud deployment templates

### Current Development Status

- ✅ **Bridge Service**: Complete and stable
- ✅ **Decoder Service**: Core functionality implemented
- ✅ **Location Algorithm**: Basic algorithm functional
- ✅ **Server Service**: API and WebSocket implementation
- 🚧 **Web Interface**: Basic UI, enhancements in progress
- 🚧 **Documentation**: Comprehensive documentation being created
- 📋 **Testing**: Automated tests being expanded

---

**AFA Systems Presence Detection** - Real-time BLE beacon tracking and location intelligence for modern IoT environments.

+ 748
- 0
docs/API.md Ver fichero

@@ -0,0 +1,748 @@
# API Documentation

## Overview

The AFA Systems Presence Detection API provides RESTful endpoints for managing beacons, settings, and real-time WebSocket communication for live updates.

## Base URL

```
http://localhost:8080
```

## Authentication

Currently, the API does not implement authentication. This should be added for production deployments.

## REST API Endpoints

### Beacon Management

#### Get All Beacons
Retrieves a list of all registered beacons with their current status and location information.

```http
GET /api/beacons
```

**Response:**
```json
{
"beacons": [
{
"name": "Conference Room Beacon",
"beacon_id": "beacon_001",
"beacon_type": "ingics",
"beacon_location": "conference_room",
"last_seen": 1703078400,
"distance": 2.5,
"location_confidence": 85,
"hs_button_counter": 42,
"hs_button_battery": 85,
"hs_button_random": "abc123",
"hs_button_mode": "normal"
}
]
}
```

#### Create Beacon
Registers a new beacon in the system.

```http
POST /api/beacons
Content-Type: application/json
```

**Request Body:**
```json
{
"name": "Meeting Room Beacon",
"beacon_id": "beacon_002",
"beacon_type": "eddystone",
"beacon_location": "meeting_room",
"hs_button_counter": 0,
"hs_button_battery": 100
}
```

**Response:**
```json
{
"message": "Beacon created successfully",
"beacon": {
"name": "Meeting Room Beacon",
"beacon_id": "beacon_002",
"beacon_type": "eddystone",
"beacon_location": "meeting_room",
"last_seen": 0,
"distance": 0,
"location_confidence": 0,
"hs_button_counter": 0,
"hs_button_battery": 100
}
}
```

#### Update Beacon
Updates an existing beacon's information.

```http
PUT /api/beacons/{id}
Content-Type: application/json
```

**Path Parameters:**
- `id` (string): The beacon ID to update

**Request Body:**
```json
{
"name": "Updated Conference Room Beacon",
"beacon_location": "main_conference",
"location_confidence": 90
}
```

**Response:**
```json
{
"message": "Beacon updated successfully",
"beacon": {
"name": "Updated Conference Room Beacon",
"beacon_id": "beacon_001",
"beacon_type": "ingics",
"beacon_location": "main_conference",
"last_seen": 1703078400,
"distance": 2.5,
"location_confidence": 90,
"hs_button_counter": 42,
"hs_button_battery": 85
}
}
```

#### Delete Beacon
Removes a beacon from the system.

```http
DELETE /api/beacons/{id}
```

**Path Parameters:**
- `id` (string): The beacon ID to delete

**Response:**
```json
{
"message": "Beacon deleted successfully"
}
```

### Settings Management

#### Get System Settings
Retrieves current system configuration settings.

```http
GET /api/settings
```

**Response:**
```json
{
"settings": {
"location_confidence": 80,
"last_seen_threshold": 300,
"beacon_metrics_size": 10,
"ha_send_interval": 60,
"ha_send_changes_only": true,
"rssi_min_threshold": -90,
"enforce_rssi_threshold": true
}
}
```

#### Update System Settings
Updates system configuration settings.

```http
POST /api/settings
Content-Type: application/json
```

**Request Body:**
```json
{
"location_confidence": 85,
"last_seen_threshold": 600,
"beacon_metrics_size": 15,
"ha_send_interval": 30,
"rssi_min_threshold": -85
}
```

**Response:**
```json
{
"message": "Settings updated successfully",
"settings": {
"location_confidence": 85,
"last_seen_threshold": 600,
"beacon_metrics_size": 15,
"ha_send_interval": 30,
"ha_send_changes_only": true,
"rssi_min_threshold": -85,
"enforce_rssi_threshold": true
}
}
```

### Location Information

#### Get Beacon Locations
Retrieves current location information for all beacons.

```http
GET /api/locations
```

**Response:**
```json
{
"beacons": [
{
"method": "location_update",
"previous_confident_location": "reception",
"distance": 3.2,
"id": "beacon_001",
"location": "conference_room",
"last_seen": 1703078450
},
{
"method": "location_update",
"previous_confident_location": "office_a",
"distance": 1.8,
"id": "beacon_002",
"location": "meeting_room",
"last_seen": 1703078440
}
]
}
```

#### Get Specific Beacon Location
Retrieves location information for a specific beacon.

```http
GET /api/locations/{id}
```

**Path Parameters:**
- `id` (string): The beacon ID

**Response:**
```json
{
"method": "location_update",
"previous_confident_location": "reception",
"distance": 3.2,
"id": "beacon_001",
"location": "conference_room",
"last_seen": 1703078450
}
```

### Health Check

#### System Health
Check if the API server is running and basic systems are operational.

```http
GET /api/health
```

**Response:**
```json
{
"status": "healthy",
"timestamp": "2024-12-20T10:30:00Z",
"services": {
"database": "connected",
"kafka": "connected",
"redis": "connected"
}
}
```

## WebSocket API

### WebSocket Connection
Connect to the WebSocket endpoint for real-time updates.

```
ws://localhost:8080/ws/broadcast
```

### WebSocket Message Format

#### Beacon Update Notification
```json
{
"type": "beacon_update",
"data": {
"method": "location_update",
"beacon_info": {
"name": "Conference Room Beacon",
"beacon_id": "beacon_001",
"beacon_type": "ingics",
"distance": 2.5
},
"name": "conference_room",
"beacon_name": "Conference Room Beacon",
"previous_location": "reception",
"new_location": "conference_room",
"timestamp": 1703078450
}
}
```

#### Button Press Event
```json
{
"type": "button_event",
"data": {
"beacon_id": "beacon_001",
"button_counter": 43,
"button_mode": "normal",
"timestamp": 1703078460
}
}
```

#### Battery Alert
```json
{
"type": "battery_alert",
"data": {
"beacon_id": "beacon_002",
"battery_level": 15,
"alert_level": "warning",
"timestamp": 1703078470
}
}
```

#### Fall Detection Event
```json
{
"type": "fall_detection",
"data": {
"beacon_id": "beacon_001",
"event_type": "fall_detected",
"confidence": 92,
"timestamp": 1703078480
}
}
```

#### System Status Update
```json
{
"type": "system_status",
"data": {
"active_beacons": 12,
"total_locations": 8,
"kafka_status": "connected",
"redis_status": "connected",
"timestamp": 1703078490
}
}
```

## Data Models

### Beacon Model
```typescript
interface Beacon {
name: string;
beacon_id: string;
beacon_type: "ingics" | "eddystone" | "minew_b7" | "ibeacon";
beacon_location: string;
last_seen: number; // Unix timestamp
distance: number; // Distance in meters
previous_location?: string;
previous_confident_location?: string;
expired_location?: string;
location_confidence: number; // 0-100
location_history: string[];
beacon_metrics: BeaconMetric[];

// Handshake/Button specific fields
hs_button_counter: number;
hs_button_prev: number;
hs_button_battery: number;
hs_button_random: string;
hs_button_mode: string;
}
```

### BeaconMetric Model
```typescript
interface BeaconMetric {
location: string;
distance: number;
rssi: number;
timestamp: number;
}
```

### Settings Model
```typescript
interface Settings {
location_confidence: number; // Minimum confidence level (0-100)
last_seen_threshold: number; // Seconds before beacon considered offline
beacon_metrics_size: number; // Number of RSSI measurements to keep
ha_send_interval: number; // Home Assistant update interval (seconds)
ha_send_changes_only: boolean; // Only send updates on changes
rssi_min_threshold: number; // Minimum RSSI for detection
enforce_rssi_threshold: boolean; // Filter weak signals
}
```

### LocationChange Model
```typescript
interface LocationChange {
method: string; // "location_update" | "beacon_added" | "beacon_removed"
beacon_ref: Beacon; // Complete beacon information
name: string; // Beacon name
beacon_name: string; // Beacon name (duplicate)
previous_location: string; // Previous location
new_location: string; // New location
timestamp: number; // Unix timestamp
}
```

## Error Responses

### Standard Error Format
```json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request data",
"details": {
"field": "beacon_id",
"reason": "Beacon ID is required"
}
}
}
```

### Common Error Codes

| Code | HTTP Status | Description |
|------|-------------|-------------|
| `VALIDATION_ERROR` | 400 | Request data validation failed |
| `NOT_FOUND` | 404 | Resource not found |
| `CONFLICT` | 409 | Resource already exists |
| `INTERNAL_ERROR` | 500 | Internal server error |
| `SERVICE_UNAVAILABLE` | 503 | Required service is unavailable |

### Validation Error Example
```http
POST /api/beacons
Content-Type: application/json
```

**Invalid Request:**
```json
{
"name": "",
"beacon_type": "invalid_type"
}
```

**Response:**
```json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request data",
"details": {
"name": "Name cannot be empty",
"beacon_type": "Invalid beacon type. Must be one of: ingics, eddystone, minew_b7, ibeacon"
}
}
}
```

## Rate Limiting

Currently, the API does not implement rate limiting. Consider implementing rate limiting for production deployments:

- Suggested limits: 100 requests per minute per IP address
- WebSocket connections: Maximum 50 concurrent connections
- Consider authentication-based rate limiting

## CORS Configuration

The API server is configured with CORS enabled for development. Production deployments should restrict CORS origins to specific domains.

## Integration Examples

### JavaScript/TypeScript Client

```typescript
class PresenceAPIClient {
private baseURL: string;

constructor(baseURL: string = 'http://localhost:8080') {
this.baseURL = baseURL;
}

async getBeacons(): Promise<Beacon[]> {
const response = await fetch(`${this.baseURL}/api/beacons`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data.beacons;
}

async createBeacon(beacon: Partial<Beacon>): Promise<Beacon> {
const response = await fetch(`${this.baseURL}/api/beacons`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(beacon),
});

if (!response.ok) {
const error = await response.json();
throw new Error(error.error?.message || 'Failed to create beacon');
}

const data = await response.json();
return data.beacon;
}

connectWebSocket(onMessage: (message: any) => void): WebSocket {
const ws = new WebSocket(`${this.baseURL.replace('http', 'ws')}/ws/broadcast`);

ws.onmessage = (event) => {
try {
const message = JSON.parse(event.data);
onMessage(message);
} catch (error) {
console.error('Failed to parse WebSocket message:', error);
}
};

ws.onerror = (error) => {
console.error('WebSocket error:', error);
};

ws.onclose = () => {
console.log('WebSocket connection closed');
};

return ws;
}
}

// Usage example
const client = new PresenceAPIClient();

// Get all beacons
const beacons = await client.getBeacons();
console.log('Active beacons:', beacons);

// Create a new beacon
const newBeacon = await client.createBeacon({
name: 'Test Beacon',
beacon_id: 'test_beacon_001',
beacon_type: 'eddystone',
beacon_location: 'test_room'
});

// Connect to WebSocket for real-time updates
const ws = client.connectWebSocket((message) => {
switch (message.type) {
case 'beacon_update':
console.log('Beacon location updated:', message.data);
break;
case 'button_event':
console.log('Button pressed:', message.data);
break;
case 'battery_alert':
console.log('Low battery warning:', message.data);
break;
}
});
```

### Python Client

```python
import requests
import websocket
import json
from typing import List, Dict, Any

class PresenceAPIClient:
def __init__(self, base_url: str = "http://localhost:8080"):
self.base_url = base_url
self.ws_url = base_url.replace("http", "ws")

def get_beacons(self) -> List[Dict[str, Any]]:
"""Get all registered beacons."""
response = requests.get(f"{self.base_url}/api/beacons")
response.raise_for_status()
data = response.json()
return data["beacons"]

def create_beacon(self, beacon_data: Dict[str, Any]) -> Dict[str, Any]:
"""Create a new beacon."""
response = requests.post(
f"{self.base_url}/api/beacons",
json=beacon_data
)
response.raise_for_status()
data = response.json()
return data["beacon"]

def update_beacon(self, beacon_id: str, beacon_data: Dict[str, Any]) -> Dict[str, Any]:
"""Update an existing beacon."""
response = requests.put(
f"{self.base_url}/api/beacons/{beacon_id}",
json=beacon_data
)
response.raise_for_status()
data = response.json()
return data["beacon"]

def delete_beacon(self, beacon_id: str) -> None:
"""Delete a beacon."""
response = requests.delete(f"{self.base_url}/api/beacons/{beacon_id}")
response.raise_for_status()

def get_settings(self) -> Dict[str, Any]:
"""Get system settings."""
response = requests.get(f"{self.base_url}/api/settings")
response.raise_for_status()
return response.json()["settings"]

def update_settings(self, settings_data: Dict[str, Any]) -> Dict[str, Any]:
"""Update system settings."""
response = requests.post(
f"{self.base_url}/api/settings",
json=settings_data
)
response.raise_for_status()
return response.json()["settings"]

# Usage example
client = PresenceAPIClient()

# Get all beacons
beacons = client.get_beacons()
print(f"Found {len(beacons)} beacons")

# Create a new beacon
new_beacon = client.create_beacon({
"name": "Python Test Beacon",
"beacon_id": "python_test_001",
"beacon_type": "eddystone",
"beacon_location": "python_room"
})
print(f"Created beacon: {new_beacon['name']}")

# Update settings
settings = client.update_settings({
"location_confidence": 85,
"ha_send_interval": 30
})
print(f"Updated settings: {settings}")
```

## Testing

### Unit Testing Example (Go)

```go
package api_test

import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
)

func TestGetBeacons(t *testing.T) {
// Setup test server
router := setupTestRouter()

req, _ := http.NewRequest("GET", "/api/beacons", nil)
w := httptest.NewRecorder()
router.ServeHTTP(w, req)

assert.Equal(t, http.StatusOK, w.Code)

var response map[string]interface{}
err := json.Unmarshal(w.Body.Bytes(), &response)
assert.NoError(t, err)
assert.Contains(t, response, "beacons")
}

func TestCreateBeacon(t *testing.T) {
router := setupTestRouter()

beaconData := map[string]interface{}{
"name": "Test Beacon",
"beacon_id": "test_001",
"beacon_type": "eddystone",
"beacon_location": "test_room",
}

jsonData, _ := json.Marshal(beaconData)
req, _ := http.NewRequest("POST", "/api/beacons", bytes.NewBuffer(jsonData))
req.Header.Set("Content-Type", "application/json")

w := httptest.NewRecorder()
router.ServeHTTP(w, req)

assert.Equal(t, http.StatusCreated, w.Code)

var response map[string]interface{}
err := json.Unmarshal(w.Body.Bytes(), &response)
assert.NoError(t, err)
assert.Contains(t, response, "beacon")
}
```

## Security Considerations

For production deployments, consider implementing:

1. **Authentication**: JWT tokens or API key authentication
2. **Authorization**: Role-based access control (RBAC)
3. **Rate Limiting**: Prevent API abuse
4. **Input Validation**: Comprehensive input sanitization
5. **HTTPS**: TLS encryption for all API communications
6. **CORS**: Restrict origins to trusted domains
7. **Logging**: Comprehensive audit logging
8. **Security Headers**: Implement security HTTP headers

## API Versioning

The current API is version 1. Future versions will be:

- Version 1: `/api/v1/...` (current, implied)
- Version 2: `/api/v2/...` (future breaking changes)

Backward compatibility will be maintained within major versions.

+ 1039
- 0
docs/DEPLOYMENT.md
La diferencia del archivo ha sido suprimido porque es demasiado grande
Ver fichero


Cargando…
Cancelar
Guardar