Add blog posts, cleanup unused files, update components

- Add 100 blog posts covering AI, development, and tech topics
- Add .env.example for environment configuration
- Add accessibility and lighthouse audit scripts
- Remove obsolete SEO reports and temporary files
- Remove dev-dist build artifacts and backup files
- Remove unused portrait images (moved/consolidated elsewhere)
- Update contact form and component improvements

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-25 11:42:11 +01:00
co-authored by Claude Opus 4.5
parent cba6c66ccc
commit 43484c5023
164 changed files with 60969 additions and 23346 deletions
+728
View File
@@ -0,0 +1,728 @@
# Zigbee & Zigbee2MQTT Integration
**Meta-Description:** Zigbee Smart Home mit Zigbee2MQTT. Lokale Kontrolle, MQTT Bridge, Device Pairing und Home Assistant Integration.
**Keywords:** Zigbee, Zigbee2MQTT, Smart Home, MQTT, Home Assistant, Local Control, Mesh Network
---
## Einführung
**Zigbee** ist das bewährte Protokoll für batteriebetriebene Smart Home Geräte. **Zigbee2MQTT** macht es unabhängig von proprietären Bridges lokale Kontrolle via MQTT mit über 4.000 unterstützten Geräten.
---
## Zigbee Architecture
```
┌─────────────────────────────────────────────────────────────┐
│ ZIGBEE2MQTT ARCHITECTURE │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Applications │ │
│ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │
│ │ │ Home │ │ Node │ │ Custom │ │ │
│ │ │ Assistant │ │ RED │ │ App │ │ │
│ │ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ │ │
│ └────────┼──────────────┼──────────────┼─────────────┘ │
│ │ │ │ │
│ ┌────────┴──────────────┴──────────────┴─────────────┐ │
│ │ MQTT Broker │ │
│ │ (Mosquitto / EMQX) │ │
│ └────────────────────────┬───────────────────────────┘ │
│ │ │
│ ┌────────────────────────┴───────────────────────────┐ │
│ │ Zigbee2MQTT │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌───────────┐ │ │
│ │ │ Frontend │ │ Bridge │ │ Converters│ │ │
│ │ │ (Web UI) │ │ (Core) │ │ (4000+) │ │ │
│ │ └─────────────┘ └─────────────┘ └───────────┘ │ │
│ └────────────────────────┬───────────────────────────┘ │
│ │ │
│ ┌────────────────────────┴───────────────────────────┐ │
│ │ zigbee-herdsman │ │
│ │ (Zigbee Protocol Stack) │ │
│ └────────────────────────┬───────────────────────────┘ │
│ │ │
│ ┌────────────────────────┴───────────────────────────┐ │
│ │ USB Adapter (Coordinator) │ │
│ │ Sonoff ZBDongle-P / ConBee II / CC2652P │ │
│ └────────────────────────┬───────────────────────────┘ │
│ │ │
│ ┌────────────────────────┴───────────────────────────┐ │
│ │ Zigbee Mesh Network │ │
│ │ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │ │
│ │ │Router│───│Router│───│Router│───│ End │ │ │
│ │ │(Plug)│ │(Bulb)│ │(Plug)│ │Device│ │ │
│ │ └──────┘ └──────┘ └──────┘ └──────┘ │ │
│ └────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
```
---
## Installation
```bash
# Docker Installation (empfohlen)
mkdir zigbee2mqtt-data
cd zigbee2mqtt-data
# configuration.yaml erstellen
cat > configuration.yaml << 'EOF'
homeassistant: true
permit_join: false
mqtt:
base_topic: zigbee2mqtt
server: mqtt://localhost:1883
user: mqtt_user
password: mqtt_password
serial:
port: /dev/ttyUSB0
adapter: zstack
frontend:
port: 8080
advanced:
network_key: GENERATE
pan_id: GENERATE
channel: 15
log_level: info
last_seen: 'ISO_8601'
EOF
```
```yaml
# docker-compose.yml
version: '3.8'
services:
zigbee2mqtt:
container_name: zigbee2mqtt
image: koenkk/zigbee2mqtt:latest
restart: unless-stopped
volumes:
- ./zigbee2mqtt-data:/app/data
- /run/udev:/run/udev:ro
ports:
- 8080:8080
environment:
- TZ=Europe/Berlin
devices:
- /dev/ttyUSB0:/dev/ttyUSB0
depends_on:
- mosquitto
mosquitto:
container_name: mosquitto
image: eclipse-mosquitto:2
restart: unless-stopped
volumes:
- ./mosquitto/config:/mosquitto/config
- ./mosquitto/data:/mosquitto/data
- ./mosquitto/log:/mosquitto/log
ports:
- 1883:1883
- 9001:9001
```
---
## MQTT Topics
```typescript
// Zigbee2MQTT MQTT Topic Structure
// Base Topic: zigbee2mqtt
// Device State (Subscribe)
// zigbee2mqtt/[friendly_name]
{
"state": "ON",
"brightness": 254,
"color_temp": 370,
"linkquality": 156,
"last_seen": "2026-01-18T10:30:00.000Z"
}
// Device Control (Publish)
// zigbee2mqtt/[friendly_name]/set
{
"state": "ON",
"brightness": 200,
"color_temp": 300,
"transition": 2
}
// Device Availability
// zigbee2mqtt/[friendly_name]/availability
"online" | "offline"
// Bridge Status
// zigbee2mqtt/bridge/state
"online" | "offline"
// Bridge Info
// zigbee2mqtt/bridge/info
{
"version": "1.40.0",
"commit": "abc123",
"coordinator": {
"ieee_address": "0x00124b001cda7a45",
"type": "zStack3x0"
},
"network": {
"channel": 15,
"pan_id": 6754,
"extended_pan_id": "0xdddddddddddddddd"
}
}
// Device List
// zigbee2mqtt/bridge/devices
[
{
"ieee_address": "0x00158d00012345678",
"friendly_name": "living_room_light",
"type": "Router",
"model": "LED1545G12",
"vendor": "IKEA"
}
]
```
---
## Node.js Integration
```typescript
// lib/zigbee2mqtt-client.ts
import mqtt, { MqttClient } from 'mqtt';
interface Z2MDevice {
ieee_address: string;
friendly_name: string;
type: 'Coordinator' | 'Router' | 'EndDevice';
model?: string;
vendor?: string;
supported: boolean;
definition?: {
description: string;
supports: string;
exposes: Z2MExpose[];
};
}
interface Z2MExpose {
type: string;
name: string;
property: string;
access: number;
values?: string[];
value_min?: number;
value_max?: number;
}
interface DeviceState {
state?: 'ON' | 'OFF';
brightness?: number;
color_temp?: number;
color?: { x: number; y: number };
temperature?: number;
humidity?: number;
battery?: number;
occupancy?: boolean;
contact?: boolean;
linkquality?: number;
last_seen?: string;
}
class Zigbee2MQTTClient {
private client: MqttClient;
private baseTopic: string;
private devices: Map<string, Z2MDevice> = new Map();
private states: Map<string, DeviceState> = new Map();
private listeners: Map<string, Set<(state: DeviceState) => void>> = new Map();
constructor(
brokerUrl: string,
baseTopic: string = 'zigbee2mqtt'
) {
this.baseTopic = baseTopic;
this.client = mqtt.connect(brokerUrl);
this.client.on('connect', () => this.onConnect());
this.client.on('message', (topic, payload) =>
this.onMessage(topic, payload.toString())
);
}
private onConnect(): void {
console.log('Connected to MQTT broker');
// Subscribe to all Z2M topics
this.client.subscribe(`${this.baseTopic}/#`);
// Request device list
this.publish('bridge/request/devices', '');
}
private onMessage(topic: string, payload: string): void {
const relativeTopic = topic.replace(`${this.baseTopic}/`, '');
// Bridge Events
if (relativeTopic === 'bridge/devices') {
const devices = JSON.parse(payload) as Z2MDevice[];
this.updateDeviceList(devices);
return;
}
if (relativeTopic === 'bridge/state') {
console.log(`Bridge state: ${payload}`);
return;
}
// Device State Updates
if (!relativeTopic.includes('/') || relativeTopic.endsWith('/availability')) {
return;
}
// State Update für Gerät
const deviceName = relativeTopic.split('/')[0];
try {
const state = JSON.parse(payload) as DeviceState;
this.states.set(deviceName, { ...this.states.get(deviceName), ...state });
// Listener benachrichtigen
this.listeners.get(deviceName)?.forEach(cb => cb(state));
this.listeners.get('*')?.forEach(cb => cb(state));
} catch {
// Nicht-JSON Payload ignorieren
}
}
private updateDeviceList(devices: Z2MDevice[]): void {
devices.forEach(device => {
this.devices.set(device.friendly_name, device);
});
console.log(`Loaded ${devices.length} devices`);
}
private publish(topic: string, payload: any): void {
const fullTopic = `${this.baseTopic}/${topic}`;
const message = typeof payload === 'string'
? payload
: JSON.stringify(payload);
this.client.publish(fullTopic, message);
}
// Public API
getDevices(): Z2MDevice[] {
return Array.from(this.devices.values());
}
getDevice(name: string): Z2MDevice | undefined {
return this.devices.get(name);
}
getState(deviceName: string): DeviceState | undefined {
return this.states.get(deviceName);
}
// Device Control
setState(deviceName: string, state: Partial<DeviceState>): void {
this.publish(`${deviceName}/set`, state);
}
turnOn(deviceName: string): void {
this.setState(deviceName, { state: 'ON' });
}
turnOff(deviceName: string): void {
this.setState(deviceName, { state: 'OFF' });
}
toggle(deviceName: string): void {
this.publish(`${deviceName}/set`, { state: 'TOGGLE' });
}
setBrightness(deviceName: string, brightness: number, transition?: number): void {
this.setState(deviceName, {
brightness: Math.min(254, Math.max(0, brightness)),
...(transition && { transition })
});
}
setColorTemp(deviceName: string, colorTemp: number): void {
// Mired: 153 (cool) - 500 (warm)
this.setState(deviceName, { color_temp: colorTemp });
}
setColor(deviceName: string, x: number, y: number): void {
this.setState(deviceName, { color: { x, y } });
}
// Event Listener
onStateChange(
deviceName: string,
callback: (state: DeviceState) => void
): () => void {
if (!this.listeners.has(deviceName)) {
this.listeners.set(deviceName, new Set());
}
this.listeners.get(deviceName)!.add(callback);
return () => {
this.listeners.get(deviceName)?.delete(callback);
};
}
// Bridge Control
permitJoin(permit: boolean, duration?: number): void {
this.publish('bridge/request/permit_join', {
value: permit,
time: duration || 120
});
}
renameDevice(oldName: string, newName: string): void {
this.publish('bridge/request/device/rename', {
from: oldName,
to: newName
});
}
removeDevice(deviceName: string, force?: boolean): void {
this.publish('bridge/request/device/remove', {
id: deviceName,
force: force || false
});
}
// OTA Updates
checkOTAUpdates(): void {
this.publish('bridge/request/device/ota_update/check', '');
}
updateDevice(deviceName: string): void {
this.publish('bridge/request/device/ota_update/update', {
id: deviceName
});
}
disconnect(): void {
this.client.end();
}
}
export { Zigbee2MQTTClient };
```
---
## Express API Wrapper
```typescript
// api/zigbee-api.ts
import express from 'express';
import { Zigbee2MQTTClient } from '../lib/zigbee2mqtt-client';
const router = express.Router();
const z2m = new Zigbee2MQTTClient(process.env.MQTT_URL || 'mqtt://localhost:1883');
// GET /api/devices
router.get('/devices', (req, res) => {
const devices = z2m.getDevices()
.filter(d => d.type !== 'Coordinator')
.map(d => ({
name: d.friendly_name,
ieee: d.ieee_address,
type: d.type,
model: d.model,
vendor: d.vendor,
state: z2m.getState(d.friendly_name)
}));
res.json(devices);
});
// GET /api/devices/:name
router.get('/devices/:name', (req, res) => {
const device = z2m.getDevice(req.params.name);
if (!device) {
return res.status(404).json({ error: 'Device not found' });
}
res.json({
...device,
state: z2m.getState(req.params.name)
});
});
// POST /api/devices/:name/set
router.post('/devices/:name/set', (req, res) => {
const device = z2m.getDevice(req.params.name);
if (!device) {
return res.status(404).json({ error: 'Device not found' });
}
z2m.setState(req.params.name, req.body);
res.json({ success: true });
});
// POST /api/devices/:name/toggle
router.post('/devices/:name/toggle', (req, res) => {
z2m.toggle(req.params.name);
res.json({ success: true });
});
// Groups
// POST /api/groups/:name/set
router.post('/groups/:name/set', (req, res) => {
z2m.setState(req.params.name, req.body);
res.json({ success: true });
});
// Bridge Control
// POST /api/bridge/permit_join
router.post('/bridge/permit_join', (req, res) => {
const { permit, duration } = req.body;
z2m.permitJoin(permit, duration);
res.json({ success: true });
});
export default router;
```
---
## Home Assistant Auto-Discovery
```typescript
// Zigbee2MQTT sendet automatisch Home Assistant Discovery Messages
// homeassistant/light/0x00158d00012345678/light/config
{
"name": "Living Room Light",
"unique_id": "0x00158d00012345678_light_zigbee2mqtt",
"state_topic": "zigbee2mqtt/living_room_light",
"command_topic": "zigbee2mqtt/living_room_light/set",
"availability": [
{ "topic": "zigbee2mqtt/bridge/state" },
{ "topic": "zigbee2mqtt/living_room_light/availability" }
],
"brightness": true,
"brightness_scale": 254,
"color_mode": true,
"supported_color_modes": ["color_temp", "xy"],
"min_mireds": 153,
"max_mireds": 500,
"schema": "json",
"device": {
"identifiers": ["zigbee2mqtt_0x00158d00012345678"],
"name": "Living Room Light",
"model": "LED1545G12",
"manufacturer": "IKEA",
"via_device": "zigbee2mqtt_bridge"
}
}
```
---
## Device Groups
```yaml
# configuration.yaml
groups:
living_room:
friendly_name: Wohnzimmer
devices:
- living_room_light_1
- living_room_light_2
- living_room_light_3
all_lights:
friendly_name: Alle Lichter
devices:
- living_room_light_1
- living_room_light_2
- bedroom_light
- kitchen_light
```
```typescript
// Gruppen steuern
z2m.setState('living_room', { state: 'ON', brightness: 200 });
// Alle Lichter aus
z2m.turnOff('all_lights');
```
---
## Scenes & Automations
```yaml
# configuration.yaml
# Szenen definieren
scenes:
- name: movie_mode
data:
living_room:
state: 'ON'
brightness: 50
color_temp: 500
kitchen:
state: 'OFF'
- name: morning_routine
data:
bedroom_light:
state: 'ON'
brightness: 100
color_temp: 250
```
```typescript
// Szene aktivieren
z2m.publish('scene/recall', { scene: 'movie_mode' });
// Custom Automation
z2m.onStateChange('motion_sensor', (state) => {
if (state.occupancy) {
z2m.turnOn('hallway_light');
// Auto-Off nach 5 Minuten
setTimeout(() => {
const currentState = z2m.getState('motion_sensor');
if (!currentState?.occupancy) {
z2m.turnOff('hallway_light');
}
}, 5 * 60 * 1000);
}
});
// Temperature-basierte Automation
z2m.onStateChange('temperature_sensor', (state) => {
if (state.temperature && state.temperature > 25) {
z2m.publish('fan/set', { state: 'ON', preset_mode: 'high' });
}
});
```
---
## Zigbee Network Map
```typescript
// Network Topology abrufen
// zigbee2mqtt/bridge/request/networkmap
z2m.publish('bridge/request/networkmap', { type: 'raw' });
// Antwort auf zigbee2mqtt/bridge/response/networkmap
interface NetworkMap {
nodes: Array<{
ieee_address: string;
friendly_name: string;
type: 'Coordinator' | 'Router' | 'EndDevice';
network_address: number;
lqi: number; // Link Quality Indicator
relationship: number;
}>;
links: Array<{
source: { ieee_address: string };
target: { ieee_address: string };
lqi: number;
depth: number;
}>;
}
```
---
## Troubleshooting
```typescript
// Häufige Probleme und Lösungen
// 1. Gerät reagiert nicht
async function troubleshootDevice(deviceName: string) {
const state = z2m.getState(deviceName);
// Linkqualität prüfen
if (state?.linkquality && state.linkquality < 50) {
console.log('Low link quality - consider adding router devices');
}
// Availability prüfen
// Subscribe to zigbee2mqtt/[device]/availability
// Device Interview neu durchführen
z2m.publish('bridge/request/device/interview', { id: deviceName });
}
// 2. Pairing funktioniert nicht
function resetAndPair() {
// Permit Join aktivieren
z2m.permitJoin(true, 180); // 3 Minuten
// Gerät in Pairing-Modus versetzen (geräteabhängig)
console.log('Reset device and put in pairing mode');
}
// 3. Mesh-Netzwerk optimieren
function optimizeMesh() {
// Router-Geräte (Steckdosen, Lampen) sind wichtig für Mesh
// Mindestens ein Router pro Raum
const devices = z2m.getDevices();
const routers = devices.filter(d => d.type === 'Router');
const endDevices = devices.filter(d => d.type === 'EndDevice');
console.log(`Routers: ${routers.length}, End Devices: ${endDevices.length}`);
if (endDevices.length / routers.length > 6) {
console.log('Warning: Not enough routers for stable mesh');
}
}
```
---
## Fazit
Zigbee2MQTT bietet:
1. **Lokale Kontrolle**: Keine Cloud-Abhängigkeit
2. **4000+ Geräte**: Herstellerunabhängig
3. **MQTT Integration**: Einfache Anbindung
4. **Open Source**: Aktive Community
Der beste Weg für ein offenes Smart Home.
---
## Bildprompts
1. "Zigbee mesh network diagram with router and end devices connected"
2. "Zigbee2MQTT web interface showing device list and controls"
3. "USB Zigbee coordinator stick connected to Raspberry Pi, smart home hub"
---
## Quellen
- [Zigbee2MQTT Documentation](https://www.zigbee2mqtt.io/)
- [zigbee-herdsman GitHub](https://github.com/Koenkk/zigbee-herdsman)
- [Supported Devices](https://www.zigbee2mqtt.io/supported-devices/)
- [Zigbee Technology 2026](https://zigbeehubs.com/zigbee-technology-2026/)