Compare commits

...

6 Commits

Author SHA1 Message Date
da370c9050 room id
All checks were successful
ci/woodpecker/tag/build/5 Pipeline was successful
ci/woodpecker/tag/build/6 Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/namespace Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/config Pipeline was successful
ci/woodpecker/tag/build/7 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
ci/woodpecker/tag/deploy/5 Pipeline was successful
ci/woodpecker/tag/deploy/6 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
ci/woodpecker/tag/ingress Pipeline was successful
2025-12-09 17:13:51 +01:00
08294ca294 started 4
All checks were successful
ci/woodpecker/tag/build/5 Pipeline was successful
ci/woodpecker/tag/build/6 Pipeline was successful
ci/woodpecker/tag/namespace Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/build/7 Pipeline was successful
ci/woodpecker/tag/config Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
ci/woodpecker/tag/deploy/5 Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
ci/woodpecker/tag/deploy/6 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
ci/woodpecker/tag/ingress Pipeline was successful
2025-12-09 13:34:41 +01:00
e5eb368dca started 3 2025-12-09 13:00:47 +01:00
169d0505cb started 2
All checks were successful
ci/woodpecker/tag/build/5 Pipeline was successful
ci/woodpecker/tag/build/6 Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/namespace Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/config Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/build/7 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
ci/woodpecker/tag/deploy/5 Pipeline was successful
ci/woodpecker/tag/deploy/6 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
ci/woodpecker/tag/ingress Pipeline was successful
2025-12-09 12:53:53 +01:00
02a2be92d5 started
All checks were successful
ci/woodpecker/tag/build/5 Pipeline was successful
ci/woodpecker/tag/build/6 Pipeline was successful
ci/woodpecker/tag/namespace Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/build/7 Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/config Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
ci/woodpecker/tag/deploy/5 Pipeline was successful
ci/woodpecker/tag/deploy/6 Pipeline was successful
ci/woodpecker/tag/ingress Pipeline was successful
2025-12-09 12:34:05 +01:00
bcfc967460 Hottis PV Modbus sensor 2
All checks were successful
ci/woodpecker/tag/build/5 Pipeline was successful
ci/woodpecker/tag/build/6 Pipeline was successful
ci/woodpecker/tag/namespace Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/config Pipeline was successful
ci/woodpecker/tag/build/7 Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
ci/woodpecker/tag/deploy/5 Pipeline was successful
ci/woodpecker/tag/deploy/6 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
ci/woodpecker/tag/ingress Pipeline was successful
2025-12-09 12:01:47 +01:00
6 changed files with 107 additions and 49 deletions

View File

@@ -127,4 +127,8 @@ HANDLERS = {
("relay", "to_abstract"): transform_relay_to_abstract,
("three_phase_powermeter", "to_vendor"): transform_three_phase_powermeter_to_vendor,
("three_phase_powermeter", "to_abstract"): transform_three_phase_powermeter_to_abstract,
("contact_sensor", "to_vendor"): transform_contact_sensor_to_vendor,
("contact_sensor", "to_abstract"): transform_contact_sensor_to_abstract,
("contact", "to_vendor"): transform_contact_sensor_to_vendor,
("contact", "to_abstract"): transform_contact_sensor_to_abstract,
}

View File

@@ -8,9 +8,9 @@ ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
MQTT_BROKER=172.16.2.16 \
MQTT_PORT=1883 \
REDIS_HOST=localhost \
REDIS_HOST=172.23.1.116 \
REDIS_PORT=6379 \
REDIS_DB=0 \
REDIS_DB=8 \
REDIS_CHANNEL=ui:updates
# Create non-root user

View File

@@ -121,7 +121,10 @@ async def get_device_layout(device_id: str):
async def startup_event():
"""Include routers after app is initialized to avoid circular imports."""
from apps.api.routes.groups_scenes import router as groups_scenes_router
from apps.api.routes.rooms import router as rooms_router
app.include_router(groups_scenes_router, prefix="")
app.include_router(rooms_router, prefix="")
@app.get("/health")

View File

@@ -312,7 +312,8 @@
// Device IDs for garage devices
const GARAGE_DEVICES = [
'power_relay_caroutlet',
'powermeter_caroutlet'
'powermeter_caroutlet',
'sensor_caroutlet'
];
// Device states
@@ -410,7 +411,17 @@
renderOutletControls(controlSection, device);
container.appendChild(controlSection);
// 3. Powermeter section
// 3. Feedback section
const feedbackDevice = Object.values(devicesData).find(d => d.device_id === 'sensor_caroutlet');
if (feedbackDevice) {
const feedbackSection = document.createElement('div');
feedbackSection.className = 'device-section';
feedbackSection.dataset.deviceId = feedbackDevice.device_id;
renderFeedbackDisplay(feedbackSection, feedbackDevice);
container.appendChild(feedbackSection);
}
// 4. Powermeter section
const powermeterDevice = Object.values(devicesData).find(d => d.device_id === 'powermeter_caroutlet');
if (powermeterDevice) {
const powermeterSection = document.createElement('div');
@@ -424,7 +435,6 @@
function renderOutletControls(container, device) {
const controlGroup = document.createElement('div');
controlGroup.style.textAlign = 'center';
// controlGroup.style.marginBottom = '8px';
const state = deviceStates[device.device_id];
const currentPower = state?.power === 'on';
@@ -440,36 +450,36 @@
label.className = 'toggle-label';
label.textContent = currentPower ? 'Ein' : 'Aus';
// Status display
// const stateDisplay = document.createElement('div');
// stateDisplay.style.marginTop = '16px';
// stateDisplay.style.fontSize = '18px';
// stateDisplay.style.fontWeight = '600';
// stateDisplay.style.color = currentPower ? '#34c759' : '#666';
// stateDisplay.textContent = `Status: ${currentPower ? 'Eingeschaltet' : 'Ausgeschaltet'}`;
controlGroup.appendChild(toggleSwitch);
controlGroup.appendChild(label);
// controlGroup.appendChild(stateDisplay);
container.appendChild(controlGroup);
}
function renderFeedbackDisplay(container, device) {
const state = deviceStates[device.device_id] || {};
const controlGroup = document.createElement('div');
controlGroup.style.textAlign = 'center';
const label = document.createElement('div');
label.className = 'toggle-label';
console.log(`Rendering feedback for ${device.device_id}:`, state);
if (state.contact === 'closed') {
label.textContent = 'Schütz ✅ eingeschaltet';
} else {
label.textContent = 'Schütz 🅾️ ausgeschaltet';
}
controlGroup.appendChild(label);
container.appendChild(controlGroup);
}
function renderThreePhasePowerDisplay(container, device) {
const state = deviceStates[device.device_id] || {};
// Leistungsmessung Title
// const title = document.createElement('h3');
// title.style.margin = '0 0 20px 0';
// title.style.fontSize = '18px';
// title.style.fontWeight = '600';
// title.style.color = '#333';
// title.textContent = 'Leistungsmessung';
// container.appendChild(title);
// Übersicht
const overviewGrid = document.createElement('div');
overviewGrid.className = 'state-grid';
overviewGrid.innerHTML = `
@@ -484,16 +494,13 @@
`;
container.appendChild(overviewGrid);
// Phasen Title
const phaseTitle = document.createElement('h4');
phaseTitle.style.margin = '20px 0 8px 0';
phaseTitle.style.fontSize = '16px';
phaseTitle.style.fontWeight = '600';
phaseTitle.style.color = '#333';
// phaseTitle.textContent = 'Phasen';
container.appendChild(phaseTitle);
// Phasen Details
const phaseGrid = document.createElement('div');
phaseGrid.className = 'phase-grid';
phaseGrid.innerHTML = `
@@ -601,12 +608,14 @@
const state = deviceStates[deviceId];
console.log(`Updating UI for ${deviceId}:`, state);
switch (device.type) {
case 'relay':
case 'outlet':
switch (deviceId) {
case 'power_relay_caroutlet':
updateOutletUI(deviceId, state);
break;
case 'three_phase_powermeter':
case 'sensor_caroutlet':
updateFeedbackDisplay(deviceId, state);
break;
case 'powermeter_caroutlet':
updateThreePhasePowerUI(deviceId, state);
break;
}
@@ -637,6 +646,29 @@
}
}
function updateFeedbackDisplay(deviceId, state) {
const section = document.querySelector(`[data-device-id="${deviceId}"]`);
if (!section) return;
const label = section.querySelector('.toggle-label');
if (label) {
const isOn = state.contact === 'closed';
label.textContent = isOn ? 'Schütz ✅ eingeschaltet' : 'Schütz 🅾️ ausgeschaltet';
// Update state display in separate card
const cards = section.querySelectorAll('.card');
if (cards.length >= 3) { // Header, Control, State
const stateCard = cards[2];
stateCard.innerHTML = `
<div style="font-size: 18px; font-weight: 600; color: ${isOn ? '#34c759' : '#666'};">
Status: ${isOn ? 'Eingeschaltet' : 'Ausgeschaltet'}
</div>
`;
}
}
}
function updateThreePhasePowerUI(deviceId, state) {
// Update overview
const totalPower = document.getElementById(`total-power-${deviceId}`);

View File

@@ -1,5 +1,6 @@
rooms:
- name: Schlafzimmer
- id: Schlafzimmer
name: Schlafzimmer
devices:
- device_id: bettlicht_patty
title: Bettlicht Patty
@@ -33,7 +34,8 @@ rooms:
title: Temperatur & Luftfeuchte
icon: 🌡️
rank: 47
- name: Esszimmer
- id: Esszimmer
name: Esszimmer
devices:
- device_id: deckenlampe_esszimmer
title: Deckenlampe Esszimmer
@@ -79,7 +81,8 @@ rooms:
title: Kontakt Straße links
icon: 🪟
rank: 97
- name: Wohnzimmer
- id: Wohnzimmer
name: Wohnzimmer
devices:
- device_id: lampe_naehtischchen_wohnzimmer
title: Lampe Naehtischchen Wohnzimmer
@@ -121,7 +124,8 @@ rooms:
title: Temperatur & Luftfeuchte
icon: 🌡️
rank: 138
- name: Küche
- id: Küche
name: Küche
devices:
- device_id: kueche_deckenlampe
title: Küche Deckenlampe
@@ -163,7 +167,8 @@ rooms:
title: Temperatur & Luftfeuchte
icon: 🌡️
rank: 155
- name: Arbeitszimmer Patty
- id: Arbeitszimmer Patty
name: Arbeitszimmer Patty
devices:
- device_id: leselampe_patty
title: Leselampe Patty
@@ -205,7 +210,8 @@ rooms:
title: Temperatur & Luftfeuchte
icon: 🌡️
rank: 189
- name: Arbeitszimmer Wolfgang
- id: Arbeitszimmer Wolfgang
name: Arbeitszimmer Wolfgang
devices:
- device_id: thermostat_wolfgang
title: Wolfgang
@@ -223,7 +229,8 @@ rooms:
title: Temperatur & Luftfeuchte
icon: 🌡️
rank: 202
- name: Flur
- id: Flur
name: Flur
devices:
- device_id: deckenlampe_flur_oben
title: Deckenlampe Flur oben
@@ -249,7 +256,8 @@ rooms:
title: Temperatur & Luftfeuchte
icon: 🌡️
rank: 235
- name: Sportzimmer
- id: Sportzimmer
name: Sportzimmer
devices:
- device_id: sportlicht_regal
title: Sportlicht Regal
@@ -267,7 +275,8 @@ rooms:
title: Temperatur & Luftfeuchte
icon: 🌡️
rank: 265
- name: Bad Oben
- id: Bad Oben
name: Bad Oben
devices:
- device_id: thermostat_bad_oben
title: Thermostat Bad Oben
@@ -281,7 +290,8 @@ rooms:
title: Temperatur & Luftfeuchte
icon: 🌡️
rank: 272
- name: Bad Unten
- id: Bad Unten
name: Bad Unten
devices:
- device_id: thermostat_bad_unten
title: Thermostat Bad Unten
@@ -295,13 +305,15 @@ rooms:
title: Temperatur & Luftfeuchte
icon: 🌡️
rank: 282
- name: Waschküche
- id: Waschküche
name: Waschküche
devices:
- device_id: sensor_waschkueche
title: Temperatur & Luftfeuchte
icon: 🌡️
rank: 290
- name: Outdoor
- id: Outdoor
name: Outdoor
devices:
- device_id: licht_terasse
title: Licht Terasse
@@ -311,19 +323,20 @@ rooms:
title: Gartenlicht vorne
icon: 💡
rank: 291
- name: Garage
- id: Garage
name: Garage
devices:
- device_id: power_relay_caroutlet
title: Ladestrom
icon:
rank: 310
- device_id: sensor_caroutlet
title: Schützzustand
icon: 🔌
rank: 315
- device_id: powermeter_caroutlet
title: Ladestrom
title: Messwerte
icon: 📊
rank: 320
- device_id: sensor_caroutlet
title: Ladestrom
icon: 🪟
rank: 330

View File

@@ -46,10 +46,16 @@ class Room(BaseModel):
"""Represents a room containing devices.
Attributes:
id: Unique room identifier (used for API endpoints)
name: Room name (e.g., "Wohnzimmer", "Küche")
devices: List of device tiles in this room
"""
id: str = Field(
...,
description="Unique room identifier"
)
name: str = Field(
...,
description="Room name"