Removed deprecated in-process MQTT service in favor of standalone IoT Bridge container:
Deleted:
- services/ directory (iot_bridge_service, mqtt_client, session_detector, parsers)
- Old tests (test_mqtt_connection, test_mqtt_mocked, test_session_detector, test_topic_matching, test_no_duplicate_messages)
Modified:
- mqtt_connection.py: action_start/stop now show deprecation message
- mqtt_connection.py: Auto-start on Odoo restart disabled
- mqtt_device.py: Auto-subscribe on device changes disabled
- tests/__init__.py: Removed old test imports
- tests/common.py: Replaced with stub (legacy support only)
Reason:
- Old integration ran MQTT client in Odoo process (tight coupling)
- New architecture: Standalone IoT Bridge container + REST API
- Better separation of concerns, scalability, and maintainability
- All functionality moved to iot_bridge/ (Phase 1) + REST API (Phase 2)
All old code is preserved in git history if needed.
Models (mqtt.device, mqtt.session, mqtt.connection, ows.iot.event) remain unchanged.
Integriert SessionDetector vollständig in iot_bridge_service:
iot_bridge_service.py:
- SessionDetector Import & _detectors Dictionary
- Timeout Worker Thread für automatisches Session-Ende
- _restore_detector_states() bei Service-Start
- _get_or_create_detector() Factory Methode
- _process_session() ruft detector.process_power_event(env, power, ts)
- _timeout_worker_loop() prüft alle 10s auf Timeouts
models/mqtt_session.py:
- current_power_w Field für Live-Power Updates
- current_state Field für State Machine Status (idle/starting/standby/working/stopping)
- last_message_time Field für Timeout Detection
tests/__init__.py:
- Import test_session_detector Module
Diese Änderungen sind essentiell für SessionDetector!
Ohne sie würde der Detector nicht aufgerufen werden.
- Fix MQTT topic pattern matching (_mqtt_topic_matches):
* Implement proper # wildcard (multi-level)
* Implement proper + wildcard (single-level)
* Fix bug where first device got ALL messages
* Now shaperorigin/# only matches shaperorigin/* topics
- Fix Stop Connection button (Odoo-style):
* Remove manual commit() - let Odoo handle it
* Use write() to update state
* Handle case where service doesn't have connection
- Fix Test Connection hanging:
* Add proper cleanup with sleep after disconnect
* Catch cleanup exceptions
- Add @unittest.skip to real MQTT tests:
* TransactionCase incompatible with paho-mqtt threads
* See TODO.md M8 for details
- Fix run-tests.sh:
* Remove -i flag (was hanging)
* Simplify to direct output redirect
- Add TODO.md documentation
- Update .gitignore for test logs
- pos_order.py von open_workshop_base nach open_workshop_pos verschoben
POS-spezifische Logik gehört ins POS-Modul, nicht ins Base-Modul
- Workaround für Odoo 18 pos_sms Bug hinzugefügt (hooks.py)
Problem: pos_sms hatte auto_install=True in älteren Odoo 18 Versionen
Lösung: Post-init Hook löscht verwaiste pos_sms Views automatisch
- l10n_de als Dependency hinzugefügt
Benötigt für POS Demo-Daten (Bankjournal muss existieren)
open_workshop_base kann jetzt ohne POS installiert werden
open_workshop_pos enthält alle POS-spezifische Funktionalität
- POS-Dependency entfernt: pos_order.py Import deaktiviert (Modul benötigt kein POS mehr)
HINWEIS: pos_order.py sollte später eventuell nach open_workshop_pos verschoben werden
- maintenance_equipment_status zu Dependencies hinzugefügt
- Menu-Lade-Reihenfolge korrigiert: menu_views.xml wird nun nach den View-Dateien geladen
- Action-Referenz korrigiert: open_workshop_base.action_machine_area_list -> action_machine_area_list
- Altes open_workshop Modul entfernt (war bereits auf installable=False)
- open_workshop_auto_backup Modul entfernt
Das Modul kann nun ohne point_of_sale installiert werden.
- Created test_mqtt_mocked.py with unittest.mock (following OCA patterns)
- Old tests with real MQTT broker hang in TransactionCase tearDown
- Created run-tests.sh following OCA/oca-ci best practices
- TODO: Find proper way to test MQTT with background threads in Odoo
- TODO: Either fully mock or use different test approach (not TransactionCase)
✅ M5 Complete - All 21 tests passing
**MQTT Auto-Reconnect:**
- Exponential backoff (1s → 60s) in mqtt_client.py
- Automatic reconnection on disconnect
- Reset delay on successful connect
**State Recovery:**
- load_sessions() and get_running_sessions() in event_storage.py
- restore_state() in session_detector.py
- _restore_running_sessions() in main.py before MQTT connect
- Running sessions continue with timeout detection after restart
**Error Handling:**
- All parsers wrapped in try-except (shelly_parser, session_detector)
- Errors logged with exc_info=True for debugging
- Bridge continues running on malformed messages
**Bug Fixes:**
- Fixed field name mismatch: duration_s → total_duration_s
- Fixed None handling in session end methods
- Fixed infinite recursion in _read_sessions()
Test Results: 21 passed in 175.46s (0:02:55)
Änderungen:
- maintenance_equipment.py: Zwei neue computed HTML-Felder hinzugefügt:
- wiki_doku_link: Zeigt wiki_doku_id als Link zur Dokumentations-Seite
- wiki_status_link: Zeigt wiki_status_id als Link zur Odoo-Status-Seite
- maintenance_equipment_views.xml: Tree View erweitert mit Wiki-Links
- Wiki Doku: Standardmäßig sichtbar (optional='show')
- Wiki Status: Standardmäßig ausgeblendet (optional='hide')
- maintenance_equipment_views.xml: Formular-Layout verbessert
- Doku-Seite mit prominentem Link oben
Nutzen:
- Benutzer sehen jetzt 'sabko-laser' statt vollständige URL
- Links sind klickbar und öffnen in neuem Tab
- Übersichtlichere List View mit relevanten Wiki-Informationen
Änderungen:
- maintenance_equipment.py: wiki_doku_id wird bei action_reset_wiki_sync_status() nicht mehr zurückgesetzt (ist manuell editierbar)
- equipment_wiki_sync_wizard.py: Deprecated force_sync Feld und zugehörige Logik entfernt
- equipment_wiki_sync_wizard_views.xml: force_sync UI-Element entfernt
- FEATURE_REQUEST/Odoo18_MQTT_IoT.md: Projektplan für MQTT-basierte IoT-Events hinzugefügt
Grund:
- force_sync Feature referenzierte nicht existierende Methoden (_generate_wiki_doku_page_content, _get_wiki_doku_page_id)
- wiki_doku_id ist jetzt manuell editierbar und sollte nicht automatisch zurückgesetzt werden
- Cleanup von veralteter/fehlerhafter Funktionalität
- Explizite Commits nach jeder ALTER TABLE Operation
- Besseres Logging mit Statusmeldungen
- Verifizierung nach Migration
- Fehlerbehandlung mit detaillierten Fehlermeldungen
- Prüfung ob maintenance_equipment Tabelle existiert
- Neues Feld wiki_status_id: Eindeutige ID für Odoo-Status-Seite (name-seriennummer)
- Überarbeitung wiki_doku_id: Editierbar, für Benutzer-Dokumentation (Duplikate erlaubt)
- Funktion _get_wiki_doku_page_id → _get_wiki_status_page_id (bessere Benennung)
- Template-Platzhalter: wiki_doku_page/link → wiki_status_page/link
- Pre-Migration-Script für Upgrade ohne Fehler (18.0.2.1.0)
View-Verbesserungen:
- 3-spaltige Darstellung: Wiki Status Seite | Wiki Dokumentations Seite
- Separate Gruppe für Wiki URL
- Erweiterte Hilfe mit Unterscheidung Status-/Doku-Seite
- Include-Plugin-Beispiel für DokuWiki-Integration
Version: 18.0.2.0.0 → 18.0.2.1.0
- Default 120s timeout was too short for large SFTP uploads
- Set time_limit to 3600s (1 hour) to prevent incomplete backups
- Fixes timeout during SFTP upload causing server reload
- Crop-Rahmen ist fixiert (nicht verschiebbar/skalierbar), nur Bild bewegbar
- Zuschnitt auf exakt 369×492 Pixel
- Finales Badge im A4-Format (794×1123px / 21×29.7cm)
- Vorschau auf 35% skaliert mit korrektem Platzverbrauch
- Große Bilder passen initial in Container, unbegrenztes Zoomen möglich
- Badge-Template behält alle mm/cm-Maße aus print.html
- Removed all console.log debug statements from JavaScript files
- Deleted unnecessary backend models (hr_employee.py, res_users.py, pos_session.py, pos_config.py)
- Added comprehensive German comments explaining the BroadcastChannel architecture
- Updated README with detailed technical documentation about frontend-only approach
- Removed debug info box from customer display template
- Simplified __init__.py files (pure frontend solution)
The module now uses a clean, maintainable frontend-only approach that:
- Patches Chrome component with effect(batched()) for reactive updates
- Sends cashier data via BroadcastChannel (same pattern as order updates)
- Uses hr.employee.public URL format (identical to POS navbar)
- Falls back to company logo when no employee image available
- Show current cashier's employee image in customer display sidebar
- Image updates automatically when cashier changes
- Fallback to company logo when no image available or before first order
- Uses BroadcastChannel to sync between POS and customer display
- Full-size image display with correct aspect ratio (object-fit: contain)
- Fügt reaktive Preisanzeige auf POS-Produktkarten hinzu
- Preis wird basierend auf der Preisliste des aktuellen Kunden berechnet
- Automatische Aktualisierung bei Kundenwechsel/Preislistenänderung
- Unterstützt Maßeinheiten für gewichtsbasierte Produkte
- Remove internal note button from control buttons
- Add pricelist button directly visible in main view (not only in Actions dialog)
- Shows current pricelist name of the order/partner
- Allows direct access to change pricelist without opening Actions menu
- Geändert von :media: Sub-Namespace zu paralleler Struktur :{area}:
- Media-IDs folgen jetzt dem gleichen Muster wie Pages
- Alt: werkstatt:ausstattung:media:{id}.jpg
- Neu: werkstatt:ausstattung:{bereich}:{id}.jpg
- Entspricht DokuWiki-Konvention für parallele Page/Media-Strukturen
- Dokumentation im Docstring aktualisiert
- partner_ref zu sync_fields hinzugefügt für automatische Synchronisation
- action_clear_template_cache() Methode hinzugefügt zum manuellen Leeren des Caches
- Template-Cache-Leeren Button im Wiki-Sync Wizard
- Debug-Logging für partner_ref Wert
Fixes: partner_ref wurde nicht automatisch synchronisiert und Template-Änderungen erforderten Server-Neustart
- Create ows_order_patch.js to collect voucher codes from orderlines
- Add voucher codes section at end of receipt with large readable format
- Include voucher code, product name, and value for each voucher
- Move partner name logic from receipt_header_patch to order_patch
- Add German labels (GUTSCHEIN-CODES, Wert:)
- Patch PosOrder.export_for_printing() to include partner data in headerData
- Update receipt header template to display partner name above tracking number
- Partner name shown only when partner is selected for the order
- Automatische Auswahl einer konfigurierbaren Standard-Kategorie
- Konfiguration über Kategorie-Name oder ID möglich
- Aktuell auf 'Nutzung' gesetzt
- Vereinfacht die Navigation für häufig genutzte Kategorien