1 contributor
152 lines | 4.726kb

Meter Entity

Reprezentarea unui contor Bluetooth conectat (UM25C, UM34C, TC66C).

Responsabilități

  • Modelarea unui dispozitiv USB power meter BT
  • Gestionarea stării de conectare şi comunicare
  • Citirea măsurătorilor de la dispozitiv
  • Persistență metadate conector (device, timestamp, expiry)

Invarianți

  • MUST: Un Meter are un id (UUID) unic în aplicaţie
  • MUST: Un Meter cu macAddress nu poate fi duplicat în Core Data (Cloud-Kit safe)
  • MUST: Starea OperationalState este monoton crescătoare: notPresent → ... → dataIsAvailable
  • MUST: Dacă OperationalState este peripheralConnected sau mai mare, trebuie să existe o conexiune BT activă
  • SHOULD: Un Meter inactiv (fără măsurători > 2 ore) ar trebui să se reconecteze automat
  • MAY: Temperature unit preference (Celsius/Fahrenheit) poate fi schimbat oricând

Estados operaţionale

notPresent
  ↓
peripheralNotConnected
  ↓
peripheralConnectionPending
  ↓
peripheralConnected
  ↓
peripheralReady
  ↓
comunicating ↔ dataIsAvailable

API Public

Proprietăţi

Proprietate Tip Descriere Observaţii
id UUID Identificator unic Generat la creare
macAddress String Adresa MAC BT De ex: "AA:BB:CC:DD:EE:FF"
meter Model Tipul: UM25C, UM34C, TC66C Immutable după creare
meterName String Nume ales de utilizator Persistent în Core Data
operationalState OperationalState Starea curentă Published, triggers UI updates
lastDataPoint Measurement? Ultima măsurătoare Nullable
connectionMetadata ConnectionMetadata? Info conexiune curentă Device, timestamp, expiry
discoveryMetadata DiscoveryMetadata? Info descoperire BT Last seen, seen by
temperatureUnit TemperatureUnitPreference Unitatei temperatură Celsius/Fahrenheit

Metode

// Conectare
func connect() 
// MUST: tranzițe starea la peripheralConnectionPending
// SHOULD: se conectează în max 5s

func disconnect()
// MUST: tranzițe starea la peripheralNotConnected
// MUST: eliberează resurse BT

// Citire măsurători
func requestMeasurement() -> Bool
// SHOULD: retur true dacă cererea a fost trimisă
// SHOULD: se așteaptă răspuns în max 3s (timeout)
// MUST: nu trimite dacă starea este < comunicating

func processMeasurementData(_ data: Data) -> Measurement?
// Parsează payload-ul de la dispozitiv
// MUST: retur nil dacă payload-ul e invalid
// SHOULD: loghează checksum errors

// Gestionare sesiuni
func startChargeRecord(for device: ChargedDevice) -> ChargeRecord
// Inițiază o nouă sesiune de încărcare

func endChargeRecord(_ record: ChargeRecord)
// Finalizează sesiunea

// Naming
func renameToMeter(_ newName: String)
// MUST: actualizează proprietatea şi persistă în Core Data

Comportamente critice

Reconexiune automată

  • MUST: Dacă OperationalState < peripheralConnected, retry-ează conectarea
  • SHOULD: Backoff exponential: 1s, 2s, 4s, 8s, max 60s
  • SHOULD: Anulează retry-urile dacă utilizatorul deconectează manual

Timeout pe măsurători

  • MUST: Dacă nu primim răspuns în 3s după cerere, timeout-ul măsurătorii
  • SHOULD: Loghează timeout-urile pentru debugging
  • MAY: Incrementează contorul de failed requests

Stare după disconnecţie accidentală

  • MUST: Dacă BT drop-ă accidental, starea revine la peripheralNotConnected
  • SHOULD: Încearcă reconexiune automată (backoff)
  • MAY: Notifică UI-ul cu banner "Meter disconnected"

Validare MAC address

  • MUST: MAC address trebuie să fie format valid (XX:XX:XX:XX:XX:XX)
  • MUST: Dacă MAC e invalid, Meter nu poate fi creat

Testare

Unit tests

// Stări operaţionale
test_operationalStateTransition()
test_stateMonotonicity()

// Conectare
test_connectInitiatesPeripheralConnectionPending()
test_disconnectCleansUpResources()
test_reconnectWithBackoff()

// Măsurători
test_requestMeasurementFailsIfStateInvalid()
test_processMeasurementDataWithValidPayload()
test_measurementTimeout()

// Naming
test_renameUpdatesPersistence()

Integration tests

  • [ ] Meter apare în Sidebar după scan
  • [ ] Meter se reconectează după BT drop
  • [ ] Măsurătorile se salvează pentru ChargedDevice
  • [ ] Temperature unit e persistent între app restarts

Dependenţe

  • BluetoothManager: gestionează Core Bluetooth
  • ChargeInsightsStore: salvează măsurătorile
  • AppData: CloudKit sync

Note