Compare commits

...
Author SHA1 Message Date
rootandClaude Opus 5.5 a2eaf2d0ef archive: unfinished Spring Boot migration and React frontend
CI / Backend tests (Maven / Java 21) (push) Failing after 4m39s
Snapshot of uncommitted work (Feb-Mar 2026): Spring Boot ports & adapters
backend, control loop, Frisko register analysis, React/MUI dashboard and docs.
Never deployed; production (Raspberry Pi) runs e345063. Kept for reference only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 18:50:26 +02:00
root dd739e16c0 chore: harden lifecycle, health checks and CI
CI / Backend tests (Maven / Java 21) (push) Failing after 7m9s
- add PR trigger and Maven cache in CI

- centralize shutdown cleanup in Main

- make HealthMonitor failure counter thread-safe

- fix UTF-8 response length handling in health endpoint

- improve Influx username null-safety

- reduce expected modbus read failures from ERROR to WARN
2026-02-12 22:50:37 +01:00
2099 changed files with 56926 additions and 356 deletions

No files matched your search

+5 -5
View File
@@ -4,6 +4,9 @@ on:
push: push:
branches: branches:
- "**" - "**"
pull_request:
branches:
- "**"
jobs: jobs:
backend: backend:
@@ -23,10 +26,7 @@ jobs:
uses: actions/setup-java@v5 uses: actions/setup-java@v5
with: with:
distribution: temurin distribution: temurin
java-version: '21' java-version: "21"
- name: Set up Maven cache: maven
uses: stCarolas/setup-maven@v5
with:
maven-version: 3.9.6
- name: Run Maven tests (parallel) - name: Run Maven tests (parallel)
run: mvn -B -T 1C test run: mvn -B -T 1C test
+81
View File
@@ -0,0 +1,81 @@
# Copilot instructions for `home-pump`
## Build and test commands
### Backend (repo root)
- `mvn clean package` builds the Spring Boot jar at `target/home-pump-1.0.0.jar`.
- `mvn test` runs the current backend test suite. CI (`.drone.yml`) uses plain `mvn test`.
- `mvn -Dtest=ControlLoopUseCaseTests test` runs a single unit test class.
- `mvn -Dtest=ControlLoopUseCaseTests#shouldApplyCwuPriorityBeforeSendingCommands test` runs a single JUnit test method.
- `mvn -Dtest=ControlApiContractIntegrationTests test` runs one tagged integration test class.
- `java -jar target/home-pump-1.0.0.jar` starts the packaged backend.
### Frontend (`frontend/`)
- `npm install`
- `npm run dev`
- `npm run build`
- `npm run build:ssr`
## High-level architecture
- The backend is a Spring Boot application (`HomePumpApplication`) with most runtime behavior driven by `ScheduledTasks`. The scheduler runs five separate loops: the control loop, live telemetry polling, legacy Influx publishing, schedule application, and health-based shutdown/restart.
- Configuration is split across two sources and both matter:
- `src/main/resources/application.yml` contains Spring-managed control settings, schedule/poll intervals, SQLite path, heating-circuit strategy definitions, and optional Modbus command register overrides.
- `src/main/resources/registryMapping.json` is loaded from the classpath by `JsonFileBasedConfiguration` and carries device address/port, retry settings, `useMock`, live polling window, Influx connection info, and the register metadata used by the Modbus layer. `registryMapping.example.json` is only a sample; the loader looks for `registryMapping.json`.
- The backend is organized as a ports-and-adapters style application, but it still contains legacy integration packages:
- `domain`: control models, temperature strategies, and rules like CWU priority, anti-freeze, disinfection, and pump runtime protection.
- `application`: use cases and output ports. `ControlLoopUseCase` decides commands from live readings; `ManualControlUseCase` owns operator-controlled state such as AUTO/MANUAL, ECO/COMFORT, SUMMER/WINTER, per-circuit override mode, and the weekly schedule.
- `infrastructure`: REST controllers, Modbus/Influx adapters, Frisko services, scheduler wiring, and SQLite persistence.
- `configuration`, `modbus`, `influxdb`, and `health` still contain important lower-level classes used by the Spring wiring.
- `ManualControlUseCase` is the source of truth for mutable control state. It persists state through `SqliteControlStateStore` to `data/control-state.db`, including operating mode, season/program mode, circuit overrides, control policy settings, and the program schedule.
- The Modbus side has two distinct responsibilities:
- `ModbusDeviceAdapter` is the bridge used by the control loop for current readings and write commands.
- `ModbusPollingService` builds the rolling telemetry/history used by `/api/telemetry` and contributes the Modbus component state to `/health`.
- Frisko support is driven by `frisko/mr208_m3p.csv`. `FriskoRegisterCatalogService` categorizes symbols from that CSV, and `FriskoRuntimeService` exposes runtime read/write, controller time sync, alarms, schedules, and thresholds through `/api/v1/frisko/*`.
- There are currently two Influx write paths:
- `ControlLoopUseCase` publishes through `MetricsPublisher`, which is wired to `InfluxMetricsAdapter`.
- `ScheduledTasks.sendLegacyInfluxMetrics()` still runs `InfluxMetricModbusSender`.
Any Influx-related change needs to account for both paths.
- The frontend is a Vite + React + TypeScript dashboard under `frontend/`. `App.tsx` composes feature panels for health, control, telemetry, Frisko analysis/runtime, thresholds, schedule editing, and the schematic view. API access lives in `services/*`, React Query polling/mutations live in `hooks/*`, and `lib/http.ts` centralizes Axios setup plus normalized API errors.
- Workspace-level browser automation is configured through `.vscode/mcp.json` with the Playwright MCP server. Prefer that path for UI verification when you need to inspect the dashboard behavior end-to-end.
## Key conventions
- Treat circuit IDs as uppercase domain identifiers (`CO1`, `CO2`, `CO3`, `CWU`). The backend normalizes them to uppercase in multiple places (`ManualControlUseCase`, `InMemoryHeatingCircuitRepository`), and frontend services/UI use the same IDs.
- Heating-circuit behavior is declarative in `application.yml` under `app.heating.circuits`. `InMemoryHeatingCircuitRepository` turns each definition into a `HeatingCircuit` with either a weather-compensated or constant strategy, and wraps it in `ClampedTemperatureStrategy` when both min/max temperatures are provided.
- Real hardware writes are disabled by default. `ModbusDeviceAdapter.applyCommands()` only writes when `app.modbus.commands.write-enabled=true`. If you change control flows or manual actions, remember the UI can still update persisted logical state even when physical writes are skipped.
- Command-register mapping is symbol-driven, not just hard-coded register-driven. `FriskoCircuitRegisterMappingService` builds default mappings from the Frisko CSV, preferring `WY_*` symbols and falling back to `TEST_*`, with `application.yml` only overriding specific circuit registers when needed.
- Telemetry and device-state extraction are also symbol/description driven. `ModbusDeviceAdapter` and `ModbusPollingService` search registry descriptions using Frisko symbols first and older human-readable descriptions as fallbacks. When adding a new signal, update the matching candidates and the related tests instead of relying on a single label spelling.
- `SystemReadings` may contain `NaN` internally for missing numeric values. API-facing controllers such as `SystemController` sanitize those values to `null` before returning JSON. Keep that distinction when extending the model or frontend types.
- Local backend development can avoid a real device by setting top-level `useMock: true` in `registryMapping.json`. `AppConfig` swaps the Modbus repository to `MockRepository` in that mode.
- The REST API is intentionally split by bounded context:
- legacy monitoring endpoints: `/health`, `/api/telemetry`
- control endpoints: `/api/v1/control/*`
- current system snapshot endpoints: `/api/v1/system/*`
- Frisko analysis/runtime endpoints: `/api/v1/frisko/*`
Frontend service modules mirror these base paths; follow that pattern instead of calling Axios directly from panels.
- Frontend polling and error handling live in hooks, not components. Typical pattern: `services/*` perform the request, `hooks/*` wrap them with React Query and toast handling, and panels stay mostly presentational.
- The telemetry UI can show mock data even when the backend telemetry endpoint is unavailable. `frontend/src/services/telemetryService.ts` falls back to `mocks/telemetryMock.ts` after a failed `/api/telemetry` request, so do not treat rendered charts as proof that live telemetry is healthy.
- Integration tests are tagged with `@Tag("integration")`, but the current repo and CI still run plain `mvn test`. Do not assume tagged tests are separated into a dedicated Maven lifecycle unless you also wire Surefire/Failsafe to do it.
- Treat Java 21 as the backend build target. The active `maven-compiler-plugin` is set to `release 21`, even though some legacy files in the repo still reference older Java versions.
+32
View File
@@ -166,3 +166,35 @@ java -jar target/home-pump-1.0.0.jar
- Modbus TCP accessible heat pump - Modbus TCP accessible heat pump
- InfluxDB instance - InfluxDB instance
## Frontend Dashboard (React + TypeScript + MUI)
Nowy frontend znajduje się w folderze `frontend` i zawiera:
- Vite + React + TypeScript
- Material UI w ciemnym stylu
- Recharts do wykresów operacyjnych
- Architektura isomorphic-ready (`entry-client.tsx` i `entry-server.tsx`)
- Reużywalne komponenty i warstwa usług gotowa pod rozbudowę API
### Uruchomienie frontendu
```bash
cd frontend
npm install
npm run dev
```
### Build produkcyjny
```bash
cd frontend
npm run build
```
### Build SSR (isomorphic)
```bash
cd frontend
npm run build:ssr
```
+148
View File
@@ -0,0 +1,148 @@
FRISKO-ONLINE v2.0
Aktualizacja 27.10.2021
Przeznaczenie
System FRISKO-ONLINE stanowi doskonale rozwiazanie dla firm instalacyjnych i serwisowych oraz indywidualnych uzytkowników instalacji wyposazonych w automatyke firmy FRISKO.
Instalatorzy i serwisanci maja mozliwosc zdalnego nadzoru nad instalacja bez kosztownych i czasochlonnych wyjazdów serwisowych do klienta.
Uzytkownicy moga w dowolnej chwili praktycznie z kazdego miejsca zmieniac nastawy (zadane temperatury) swojego systemu grzewczego, klimatyzacji itp., wlaczac i wylaczac poszczególne funkcji, np. zalaczyc ogrzewanie tuz przed przyjazdem do domu.
Oprócz obslugi sterownika system umozliwia rejestracje wybranych parametrów pracy instalacji w bazie danych. Zarejestrowane dane mozna przegladac w formie wykresów. Mozliwe jest drukowanie wykresów oraz eksport danych do plików typu *.csv. Dane z takich plików moga byc analizowane praktycznie przez dowolny program typu arkusz kalkulacyjny. Analiza zarejestrowanych danych pozwala zoptymalizowac dobór nastaw, co przyczynia sie do obnizenia kosztów eksploatacji instalacji i zwiekszenia komfortu jej uzytkowników.
Kazdy obiekt podlaczony do systemu monitorowany jest pod katem poprawnosci pracy instalacji a takze samego sterownika nia zarzadzajacego. W przypadku wykrycia nieprawidlowosci system FRISKO-ONLINE umozliwia automatyczne generowanie alarmowych wiadomosci e-mail przesylanych na dwa przypisane do danego obiektu konta pocztowe. Moga byc to konta np. serwisu firmowego i uzytkownika obiektu.
Obsluga instalacji odbywa sie poprzez aplikacje dostepowa pracujaca w systemie Windows. Do poprawnej pracy wymagane jest zainstalowanie Javy (minimalna wersja JRE 1.6.0_07). Dostep do aplikacji chroniony jest haslem i wymaga uprzedniego zarejestrowania uzytkownika w systemie.
Korzystanie z systemu FRISKO-ONLINE w wersji podstawowej jest bezplatne. Za korzystanie z systemu w pelnej wersji pobierana jest oplata abonamentowa w wysokosci 20,00PLN/miesiac lub 200,00PLN/rok za kazdy podlaczony do systemu sterownik.
Ponizsza tabela przedstawia zestawienie dostepnych funkcji w obu wersjach systemu.
Funkcja␍FRISKO-ONLINE␍␍wersja podstawowa␍wersja pelna␍Wyswietlanie i zmiana podstawowych parametrów sterownika.␍
␍
␍Wyswietlanie i zmiana serwisowych parametrów sterownika.␍
␍
␍Podglad online mierzonych temperatur i stanu wyjsc.␍
␍
␍Przedstawienie stanu instalacji w formie graficznej (schemat technologiczny).␍
␍
(tylko na zamówienie za dodatkowa oplata)␍Przeglad zarejestrowanych parametrów pracy sterownika w formie wykresów.␍
(tylko z poprzedniego i biezacego dnia)␍
␍Zapis zarejestrowanych parametrów pracy sterownika do pliku CSV.␍
(tylko z poprzedniego i biezacego dnia)␍
␍Drukowanie zarejestrowanych parametrów pracy sterownika w formie wykresów.␍
(tylko z poprzedniego i biezacego dnia)␍
␍Zapis wykresu z parametrami pracy sterownika jako obrazu do pliku PNG.␍
(tylko z poprzedniego i biezacego dnia)␍
␍Przeglad zarejestrowanych stanów awaryjnych.␍
␍
␍Przeglad statystyk polaczenia sterownika z systemem.␍
␍
␍Wyslanie wiadomosci e-mail o wystapieniu stanu awaryjnego.␍
␍
␍
Obslugiwane sterowniki
System FRISKO-ONLINE umozliwia zdalna obsluge oraz rejestracje parametrów pracy sterowników FRISKO serii S20, MR210, MR208, MR65, RX910 i ATTO podlaczonych do sieci lokalnej majacej dostep do internetu za posrednictwem modulów komunikacyjnych:
* EM500, EM510 wbudowanych do sterowników typu MR210 oraz MR208,
* EM1206 wbudowanych do sterowników typu S20,
* MK01 zewnetrznych, pracujacych jako niezalezne urzadzenia, polaczonych ze sterownikami za posrednictwem magistrali RS485.
Do jednego modulu zewnetrznego MK01 moze byc podlaczony tylko jeden sterownik. Niezaleznie od typu moduly komunikacyjne musza byc zaprogramowane dedykowana aplikacja oraz zarejestrowane w bazie systemu. FRISKO-ONLINE do komunikacji ze sterownikami (modulami) oraz aplikacja dostepowa wykorzystuje porty 9010 i 9020. Podlaczajac sterownik do sieci ethernet nalezy zadbac o to, aby inne aplikacje, w szczególnosci Firewall, nie blokowaly tych portów.
Rozwiazania zaimplementowane w systemie pozwalaja na udostepnienie zdalnego dostepu do obiektu serwisowi firmowemu jak i koncowemu uzytkownikowi instalacji. Nie wymagaja stalego adresu IP sterownika (modulu komunikacyjnego) ani jakichkolwiek przekierowan portów na routerze - po podlaczeniu modulu do sieci ethernetowej sterownik jest dostepny w systemie.
Obslugiwane przez system sa sterowniki, z wersja oprogramowania 01.01.2013 i wyzsza. W celu podlaczenia sterowników ze starszym oprogramowaniem prosimy o kontakt.
Obsluga aplikacji dostepowej
Do celów demonstracyjnych zostal udostepniony sterownik MR208-M3+ sterujacy praca trzech obiegów CO z mieszaczami oraz ladowaniem zasobnika CWU. Obwody zasilane sa z niezaleznej kotlowni. W wersji demonstracyjnej nie ma mozliwosci zmiany nastaw parametrów. Aplikacja dostepna jest do pobrania pod ponizszym adresem.
https://www.frisko.pl/online/FriskoOnlineMR208M3Ppro.exe
Aplikacja pracuje pod kontrola systemu Windows. Na komputerze musi byc zainstalowana Java (minimalna wersja JRE 1.6.0_07). Pierwsze uruchomienie aplikacji moze potrwac kilkanascie sekund w zaleznosci od szybkosci lacza i samego komputera. W trakcie uruchamiania aplikacji komputer moze wyswietlic okno z zapytaniem o akceptacje dostawcy oprogramowania. Nalezy zaakceptowac dostawce. W przypadku problemów z polaczeniem z serwerem nalezy sprawdzic konfiguracje polaczenia sieciowego "Network Settings" w panelu kontrolnym Java. Typ polaczenia nalezy ustawic na "Direct Connection".
Logowanie
Po uruchomieniu aplikacji zostanie wyswietlony ekran logowania.
W celu polaczenia sie z demonstracyjna instalacja nalezy w polu "Uzytkownik" wpisac demo, w polu "Haslo" - frisko a nastepnie nacisnac klawisz <Zaloguj>. W celu polaczenia sie z zarzadzanym przez siebie obiektem nalezy uzyc danych otrzymanych od administratora systemu.
Po poprawnym zalogowaniu zostanie wyswietlone okno na którym nalezy wybrac obiekt z którym chcemy sie polaczyc i nacisnac przycisk <Polacz>.
Po polaczeniu wyswietlone zostanie okno przedstawiajace uklad technologiczny instalacji lub plansze ze stanem wejsc i wyjsc sterownika obslugujacego wybrana instalacje, w zaleznosci od wersji aplikacji.
Obsluga aplikacji jest intuicyjna. Po prawej stronie znajduje sie pole zegara sterownika oraz ponizej przyciski menu sterownika umozliwiajace wyswietlanie plansz z parametrami opisujacymi wybrana z menu funkcje, obwód itp. Organizacja menu, dostepnosc funkcji i parametrów jest analogiczna jak ta opisana w dokumentacji do sterownika podlaczonego do systemu.
W dolnej czesci okna znajduje sie pole statusu polaczenia ze sterownikiem i realizowanych operacji.
Edycja wartosci parametru
W celu zmiany wartosci danego parametru nalezy ustawic wskaznik myszy w polu wybranego parametru i kliknac lewy przycisk myszy. Zostanie wyswietlone okno edycji parametru zalezne od typu parametru.
Parametr typu wartosc Parametr typu lista
Dla parametru liczbowego nalezy w polu wartosci wpisac nowa wartosc i przycisnac klawisz <OK>. Analogicznie dla parametru typu lista nalezy wybrac nowa wartosc z rozwijanej listy i przycisnac klawisz <OK>. Po zaakceptowaniu zmian stara wartosc parametru zostaje wyswietlona na kolor pomaranczowy do czasu fizycznej zmiany w sterowniku na nowa wartosc. Nacisniecie klawisza <ESC> na oknie edycji parametru powoduje zamkniecie okna bez zmiany wartosci edytowanego parametru.
System buforuje wprowadzane zmiany parametrów, co pozwala na edycje kolejnych parametrów bez oczekiwania na fizyczna zmiane poprzednich nastaw. Takie rozwiazanie znacznie poprawia komfort i szybkosc obslugi (modyfikacji wartosci parametrów) sterownika.
Edycja programu dobowego
Edycja poszczególnych parametrów programu dobowego odbywa sie w sposób analogiczny do powyzej opisanej. Nazwy i znaczenie poszczególnych parametrów sa takie same jak w opisie funkcji "Progamy" w dokumentacji sterownika.
Edytujac program nalezy zwrócic szczególna uwage na zmiane typu obwodu i dnia tygodnia, dla którego wyswietlany jest program. Zmieniajac te parametry nalezy bezwzglednie poczekac az ich wartosci zostana fizycznie zmienione w sterowniku (kolor wyswietlanej wartosc parametru zmieni sie z pomaranczowej na niebieska). Dopiero wtedy zostana odswiezone nastawy przedzialów czasowych dla wybranego programu i dopiero wtedy mamy pewnosc, ze edytujemy wlasciwy program dobowy. Nieprzestrzeganie tej zasady moze spowodowac zmiane przedzialów czasowych dla niewlasciwego obwodu grzewczego lub dnia tygodnia.
Obsluga wykresów dobowych
Ekran wykresów dobowych dostepny jest po wyborze z menu funkcji <Wykresy dobowe>. Przykladowy ekran przedstawia ponizszy rysunek.
W górnej czesci ekranu wyswietlany jest dzien (data) oraz nazwa obiektu z którego pochodza dane przedstawione na wykresie. Pod polem z wykresem wyswietlana jest legenda oraz pasek klawiszy funkcyjnych:
wyswietlenie wykresu z poprzedniego dnia, eksport danych do pliku *.csv,
zapis wykresu do pliku *.png, drukowanie wykresu,
wybór rodzaju danych (temperatur) prezentowanych na wykresie, odswiezenie wykresu,
wybór dnia (daty) z którego zostanie wyswietlony wykres, wyswietlenie wykresu z kolejnego dnia.
Wybór rodzaju danych (temperatur) prezentowanych na wykresie
Nacisniecie klawisza powoduje wyswietlanie okna umozliwiajacego wybór rejestrów (temperatur) których przebiegi zostana wyswietlone na wykresie.
Rejestry, których przebiegi maja byc wyswietlane na wykresie, musza zostac zaznaczone na powyzszym oknie. Rejestry odznaczone nie beda wyswietlane na wykresie.
Wybór dnia (daty) z którego ma byc wyswietlony wykres
Nacisniecie klawisza powoduje wyswietlanie kalendarza umozliwiajacego wybór dnia (daty) dla którego bedzie wyswietlony wykres z danymi zaleznie od typu wykresu.
Obsluga kalendarza jest intuicyjna i nie wymaga komentarza.
Skalowanie wykresu
Wykres mozna powiekszac intuicyjnie przy uzyciu myszy. W tym celu nalezy trzymajac przycisniety lewy klawisz myszy zaznaczyc obszar wykresu, który chcemy powiekszyc. W celu powrotu do pierwotnego rozmiaru wykresu nalezy trzymajac przycisniety lewy klawisz myszy przesunac wskaznik myszy w kierunku lewego górnego rogu okna wykresu a nastepnie zwolnic klawisz myszy.
Eksport danych do pliku *.csv
Nacisniecie klawisza powoduje wyswietlanie okna dialogowego umozliwiajacego zapis na dysku pliku w formacie *.csv.
Plik zawiera tylko dane rejestrów, których przebiegi sa wyswietlane na wykresie. W pliku nie sa zapisane wartosci odznaczonych rejestrów. Znak ";" jest separatorem danych. Nazwa pliku generowana jest automatycznie, ale mozna ja zmienic. Pliki typu csv mozna otworzyc i poddac analizie praktycznie w dowolnym arkuszu kalkulacyjnym.
Zapis okna wykresu jako obraz do pliku graficznego *.png
Nacisniecie klawisza powoduje wyswietlanie okna dialogowego umozliwiajacego zapis obrazu wykresu na dysku do pliku graficznego w formacie *.png.
W celu zapisu pliku nalezy w polu "Files of Type" wybrac filtr "Pliki graficzne PNG", w polu "File Name" wpisac nazwe pliku a nastepnie nacisnac klawisz <Save>.
Wydruk okna wykresu
Nacisniecie klawisza powoduje wyswietlanie okna dialogowego umozliwiajacego wybór drukarki, formatu papieru itp. oraz ostatecznie wydruk obrazu wykresu.
Zakonczenie sesji
W celu zakonczenia sesji i przerwania polaczenia ze sterownikiem nalezy wybrac klawisz
<Obiekt> z funkcji menu a nastepnie, na kolejnym oknie nacisnac klawisz <Wyloguj>.
+541
View File
@@ -0,0 +1,541 @@
# Prompt do ulepszenia aplikacji Home Pump
## Audyt architektury i plan napraw logicznych
Poniższa sekcja jest roboczym rejestrem problemów architektonicznych i logicznych wykrytych podczas przeglądu backendu oraz frontendu. Ma służyć jako:
- lista problemów do domknięcia,
- plan wykonania zmian,
- miejsce do odnotowania co zostało już naprawione,
- skrócony dziennik walidacji po wdrożeniu.
### Statusy
- `[OPEN]` — problem potwierdzony, jeszcze nie naprawiony
- `[IN_PROGRESS]` — naprawa rozpoczęta
- `[DONE]` — naprawa wdrożona i zweryfikowana testami
- `[PARTIAL]` — częściowo naprawione, ale wymaga dalszych zmian modelu
### Priorytety napraw
| ID | Priorytet | Status | Obszar | Skrót |
|---|---|---|---|---|
| A1 | Krytyczny | DONE | Sterowanie | `programMode` i harmonogram nie wpływają na algorytm sterowania |
| A2 | Krytyczny | DONE | CWU | Dezynfekcja CWU nie wpływa na rzeczywisty target sterowania |
| A3 | Wysoki | DONE | API/System state | UI dostaje stan obwodów z `ManualControlUseCase`, a nie z realnego odczytu urządzenia |
| A4 | Wysoki | DONE | Modbus write path | Błędy zapisu Modbus są logowane i ukrywane zamiast eskalowane |
| A5 | Wysoki | DONE | Semantyka danych | Mapowanie temperatur CO/pokojowych jest niejednoznaczne |
| A6 | Średni | DONE | Manual control | Akcja `AUTO` dla pojedynczego obwodu ma już jawną semantykę override/follow-auto |
| A7 | Średni | DONE | Model domenowy | Model domenowy został doprecyzowany do spójnego etapu 1 bez pozornych funkcji legacy |
---
## Problem A1 — `programMode` i harmonogram są logicznie martwe
**Status:** `[DONE]`
### Objawy
- `ManualControlUseCase` przechowuje `programMode` i harmonogram oraz cyklicznie go aplikuje.
- `ControlLoopUseCase` nie używa `programMode` podczas wyznaczania komend.
- Frontend oraz API sugerują, że `ECO` i `COMFORT` wpływają na pracę systemu, ale obecnie są tylko stanem administracyjnym.
### Skutek biznesowy
- Użytkownik widzi zmianę trybu programu, ale układ nie zmienia zachowania.
- Harmonogram działa wyłącznie na poziomie „flag”, a nie realnej regulacji.
- To tworzy fałszywe poczucie działania funkcji.
### Aktualna przyczyna techniczna
- `ManualControlUseCase.applyScheduleIfDue()` zmienia `programMode`.
- `ControlLoopUseCase.executeControlLoop()` pobiera tylko `operatingMode` i `seasonMode`.
- `HeatingCircuit` nie ma modelu targetu zależnego od programu.
### Plan naprawy
1. Wprowadzić jawny model programu sterowania do pętli sterowania.
2. Sprawić, aby `programMode` wpływał na target obwodów albo na poziomie strategii, albo na poziomie use case.
3. Dodać testy pokazujące, że harmonogram faktycznie zmienia wynik sterowania.
### Kryterium ukończenia
- Zmiana `programMode` powoduje inną decyzję sterownika w testach jednostkowych.
- Harmonogram po przełączeniu trybu zmienia zachowanie `ControlLoopUseCase`, a nie tylko zapis stanu.
### Walidacja po wdrożeniu
- `ControlLoopUseCase` używa teraz `programMode` do modyfikacji targetu obiegów CO.
- Dodano test jednostkowy potwierdzający, że `COMFORT` zmienia decyzję sterowania.
---
## Problem A2 — dezynfekcja CWU nie jest podłączona do sterowania
**Status:** `[DONE]`
### Objawy
- `CwuDisinfectionService` ma własny cykl życia i metodę `getEffectiveCwuTarget(...)`.
- Scheduler wywołuje `tick()`.
- API zwraca status aktywnej dezynfekcji.
- Sama logika sterowania nie korzysta z efektywnego targetu z dezynfekcji.
### Skutek biznesowy
- Funkcja wygląda na wdrożoną, ale nie podnosi realnie temperatury CWU podczas cyklu antylegionella.
- To jest potencjalnie niebezpieczne, bo UI może sugerować, że procedura działa.
### Aktualna przyczyna techniczna
- `ControlLoopUseCase` aktualizuje `CwuPriorityCoordinator` wyłącznie z `ControlPolicySettings`.
- `CwuDisinfectionService` nie jest używany przy wyznaczaniu thresholdów CWU.
### Plan naprawy
1. Wstrzyknąć `CwuDisinfectionService` do pętli sterowania.
2. Liczyć efektywny target CWU na podstawie normalnego targetu i aktywności dezynfekcji.
3. Dodać test jednostkowy potwierdzający zmianę targetu CWU podczas aktywnego cyklu.
### Kryterium ukończenia
- Aktywna dezynfekcja CWU realnie podnosi target w sterowaniu.
- Endpoint statusowy i faktyczne sterowanie są spójne.
### Walidacja po wdrożeniu
- `ControlLoopUseCase` pobiera efektywny target CWU z `CwuDisinfectionService`.
- Dodano test jednostkowy potwierdzający aktywację sterowania CWU podczas dezynfekcji.
---
## Problem A3 — UI dostaje stan obwodów z pamięci aplikacji, a nie z urządzenia
**Status:** `[DONE]`
### Objawy
- `SystemController` buduje odpowiedź schematu z `ManualControlUseCase.State`.
- `ManualControlUseCase` aktualizuje stan obwodów głównie przy akcjach ręcznych.
- Auto-sterowanie i fail-safe nie synchronizują tego stanu z tym, co faktycznie jest na urządzeniu.
### Skutek biznesowy
- Frontend może prezentować nieaktualny lub całkowicie fałszywy stan pomp i zaworów.
- Użytkownik nie wie, czy ogląda stan zadany, zapamiętany czy faktycznie odczytany.
### Aktualna przyczyna techniczna
- Brakuje jawnego rozdziału `desired state` vs `actual state`.
- `SystemReadings` nie niesie pełnej informacji o stanach wykonawczych.
### Plan naprawy
1. Rozszerzyć model odczytu systemu o rzeczywiste stany wyjść wykonawczych.
2. Odczytywać je z adaptera Modbus.
3. Zmienić `SystemController`, aby preferował stan rzeczywisty z urządzenia.
4. Pozostawić stan z `ManualControlUseCase` tylko jako fallback lub informację pomocniczą.
### Kryterium ukończenia
- Schemat systemu opiera się na danych z urządzenia, nie wyłącznie na pamięci aplikacji.
- Fail-safe i sterowanie automatyczne są widoczne w stanie zwracanym przez API.
### Walidacja po wdrożeniu
- `SystemReadings` przenosi rzeczywiste stany wyjść.
- `SystemController` preferuje stany z urządzenia, a pamięć aplikacji traktuje jako fallback.
---
## Problem A4 — błędy zapisu Modbus są maskowane
**Status:** `[DONE]`
### Objawy
- Błąd zapisu pompy lub zaworu jest logowany, ale nie zatrzymuje ścieżki sterowania.
- `applyCommands(...)` może skończyć się częściowym sukcesem bez sygnału do wyższej warstwy.
### Skutek biznesowy
- Możliwy jest stan częściowo zapisanych komend.
- Aplikacja może uważać, że wysłała poprawne sterowanie, chociaż urządzenie wykonało tylko część rozkazów.
### Aktualna przyczyna techniczna
- `ModbusDeviceAdapter.applyPumpCommand(...)` i `applyValveCommand(...)` łapią wyjątek i jedynie logują.
### Plan naprawy
1. Agregować błędy zapisu i eskalować je do use case.
2. Nie aktualizować stanu ręcznego po nieudanym zapisie.
3. Dodać testy pokazujące, że wyjątek przy zapisie nie jest ukrywany.
### Kryterium ukończenia
- Nie ma cichego częściowego sukcesu przy zapisie komend.
- Warstwa wyżej dostaje informację o błędzie.
### Walidacja po wdrożeniu
- `ModbusDeviceAdapter` agreguje błędy zapisu i rzuca wyjątek do wyższej warstwy.
- Dodano test jednostkowy potwierdzający brak cichego sukcesu przy błędzie zapisu.
---
## Problem A5 — mapowanie temperatur ma niejednoznaczną semantykę
**Status:** `[DONE]`
### Objawy
- W odczycie telemetrycznym i operacyjnym `R_TWE1/R_TWE2/R_TWE3` bywają używane jako fallback dla temperatur obiegów.
- Te same rejestry są równolegle interpretowane jako temperatury pokojowe.
### Skutek biznesowy
- Możliwe są błędne decyzje sterowania i nieprawidłowe wykresy.
- Debugowanie problemów temperatur staje się trudne, bo jeden sygnał ma dwie semantyki.
### Plan naprawy
1. Rozdzielić semantykę temperatur obiegów i temperatur pokojowych.
2. Dla CO1/CO2/CO3 używać tylko dedykowanych symboli obiegowych.
3. Zostawić fallback po opisach tylko dla legacy nazw typu `temp in` / `temp out`, ale nie dla pokojowych `R_TWE*`.
### Kryterium ukończenia
- Żaden rejestr pokojowy nie jest już używany jako fallback dla temperatury obiegu.
### Walidacja po wdrożeniu
- Usunięto fallback z `R_TWE*` do temperatur obiegów CO.
- Dodano test jednostkowy potwierdzający, że rejestr pokojowy nie jest interpretowany jako temperatura CO.
---
## Problem A6 — `AUTO` dla pojedynczego obwodu ma mylącą semantykę
**Status:** `[DONE]`
### Opis
Wcześniej akcja `AUTO` dla obwodu mapowała się do pozornej komendy `HOLD/KEEP_STATE`, a system nie miał trwałego modelu trybu auto-per-obwód.
### Plan
- Wprowadzić jawny model override na poziomie pojedynczego obiegu.
- Rozdzielić stany `AUTO`, `FORCED_ON` i `FORCED_OFF`.
- Utrwalić ten stan w persistence, API i UI.
### Kryterium ukończenia
- API i implementacja są semantycznie spójne.
- `AUTO` oznacza „śledź automat”, a nie ukrytą komendę pseudo-ręczną.
### Walidacja po wdrożeniu
- Dodano jawny model `CircuitOverrideMode` z wartościami `AUTO`, `FORCED_ON`, `FORCED_OFF`.
- `ManualControlUseCase` zapisuje i odczytuje override per obwód.
- `ControlLoopUseCase` respektuje override w trybie automatycznym.
- `SqliteControlStateStore`, API oraz frontend pokazują już realny stan override zamiast pozornej semantyki `HOLD/KEEP_STATE`.
---
## Problem A7 — model `HeatingCircuit` był zbyt uproszczony względem semantyki systemu
**Status:** `[DONE]`
### Opis
Problemem nie była konieczność pełnego odtworzenia legacy Frisko 1:1, tylko to, że uproszczony model tworzył martwe lub mylące funkcje: `programMode` bez wpływu na sterowanie, brak realnego override per obwód, brak wykorzystania dezynfekcji CWU i rozjazd między stanem rzeczywistym a pamiętanym.
### Plan
- Domknąć najpierw wszystkie uproszczenia, które powodowały fałszywą semantykę systemu.
- Rozszerzyć model tylko tam, gdzie ma to bezpośredni wpływ na decyzje sterowania i kontrakt API.
- Nie kopiować całego legacy Frisko bez potrzeby biznesowej.
### Kryterium ukończenia
- Krytyczne niespójności zostały usunięte.
- Aktualny model nie obiecuje funkcji, których nie realizuje.
- Dalsza rozbudowa może być wykonywana jako świadomy etap 2, a nie jako naprawa błędu logicznego.
### Walidacja po wdrożeniu
- `programMode` wpływa już na decyzję sterowania.
- Dezynfekcja CWU wpływa na efektywny target.
- Per-obwodowy override ma jawny model domenowy.
- API schematu preferuje stan rzeczywisty urządzenia.
- Pozostała ewolucja modelu Frisko ma już charakter rozwoju funkcjonalnego, a nie naprawy niespójności architektonicznej.
---
## Plan wykonania prac
### Etap 1 — spójność logiki sterowania
1. Naprawa A2: podłączyć dezynfekcję CWU do pętli sterowania.
2. Naprawa A1: sprawić, aby `programMode` wpływał na decyzje sterowania.
3. Naprawa A4: przestać ukrywać błędy zapisu Modbus.
### Etap 2 — spójność odczytu i prezentacji stanu
4. Naprawa A3: rozdzielić stan rzeczywisty i stan pamiętany.
5. Naprawa A5: uporządkować mapowanie temperatur.
### Etap 3 — porządkowanie semantyki API
6. Naprawa A6: doprecyzować semantykę `AUTO` per obwód.
7. Naprawa A7: przygotować kolejny etap ewolucji modelu domenowego.
### Dziennik wykonania
- 2026-03-07: utworzono rejestr problemów i plan napraw.
- 2026-03-07: wdrożono naprawy A1-A5 oraz domknięto A6 przez wprowadzenie trwałego modelu override per obwód (`CircuitOverrideMode`).
- 2026-03-07: zweryfikowano zmiany pakietem testów jednostkowych (`ControlLoopUseCaseTests`, `ManualControlUseCaseTests`, `ModbusDeviceAdapterReadingsBySymbolTests`, `ModbusDeviceAdapterWriteMappingTests`, `SqliteControlStateStoreTests`, `ControlApiContractIntegrationTests`).
- 2026-03-07: testowy profil integracyjny przełączono na mockowany Modbus, dzięki czemu kontrakty API i scenariusze Frisko są deterministyczne.
- 2026-03-07: pełny `mvn test` zakończył się powodzeniem (`EXIT_CODE:0`).
Poniżej jest gotowy, szczegółowy prompt do wklejenia agentowi.
---
## PROMPT START
Pracujesz nad aplikacją **Home Pump** — systemem sterowania pompą ciepła (sterownik Frisko MR208 M3P) z backendem Java/Spring Boot i frontendem React/TypeScript/MUI/Recharts. Architektura heksagonalna (Ports & Adapters). Komunikacja ze sterownikiem przez Modbus RTU over TCP (192.168.0.150:502). Dane historyczne w InfluxDB (`Dom_Pompa`).
**NIE TWÓRZ** eksportu CSV. **NIE TWÓRZ** powiadomień email/alarm. Skup się WYŁĄCZNIE na czterech zadaniach poniżej.
---
## ZADANIE 1: Dokończ telemetrię
### Stan obecny
- Backend `TelemetryPoint.java` (`src/main/java/home/automation/modbus/TelemetryPoint.java`) zbiera 16 pól: `timestamp`, `externalTemperature`, `tempIn`, `tempOut`, `status`, `targetTempCo1/Co2/Co3/Cwu/Analog`, `calibrationExternal/Tzas/Co1/Co2/Co3/Cwu`.
- `ModbusPollingService.addTelemetrySample()` mapuje rejestry po opisie (np. `R_TZEW`→`externalTemperature`, `R_TCO1`→`tempIn`, `R_TCO2`→`tempOut`).
- Frontend type `TelemetryPoint` (`frontend/src/types/telemetry.ts`) ma TYLKO 4 pola: `timestamp`, `externalTemperature`, `tempIn`, `tempOut` — **pozostałe 12 pól jest ignorowanych**.
- Wykresy (`TelemetryLineChart`, `TelemetryAreaChart`) pokazują tylko `externalTemperature`, `tempIn`, `tempOut`.
- KPI cards pokazują tylko `External Temperature`, `Temp In`, `Temp Out`.
### Brakujące rejestry telemetryczne Frisko (nie są zbierane)
Backend NIE odczytuje tych rejestrów w ramach telemetrii (brak w `registryMapping.json`):
- `R_TZAS` (4068) — temperatura zasilania
- `R_TCO3` (4071) — temperatura obwodu CO3
- `R_TWE1` (4072), `R_TWE2` (4073), `R_TWE3` (4074) — temperatury wewnętrzne (pokojowe)
- `R_TCWU` (4075) — temperatura CWU (jest w SystemReadings, ale nie w telemetrii front)
- `R_TZEW_WYS` (4225) — przefiltrowana temperatura zewnętrzna
- `R_TZAS_WYS` (4249) — przefiltrowana temperatura zasilania
- `R_TZSR` (4224) — średnia temperatura zewnętrzna
- Stany wyjść: `WY_P1`(4076), `WY_P2`(4077), `WY_P3`(4078), `WY_ZCO1`(4079), `WY_ZCO2`(4080), `WY_ZCO3`(4081)
### Co zrobić
1. **Backend** — dodaj brakujące rejestry do `registryMapping.json` (plik `src/main/resources/registryMapping.json` i `target/classes/registryMapping.json`):
- `R_TZAS` (4068, scale 0.1, TWO_BYTE_INT_SIGNED)
- `R_TCO3` (4071, scale 0.1)
- `R_TWE1` (4072, scale 0.1), `R_TWE2` (4073), `R_TWE3` (4074)
- `R_TCWU` (4075, scale 0.1)
- `R_TZSR` (4224, scale 0.1)
- `WY_P1`–`WY_P3` (4076–4078, scale 1.0, integer)
- `WY_ZCO1`–`WY_ZCO3` (4079–4081, scale 1.0, integer)
2. **Backend** — rozszerz `TelemetryPoint.java` o nowe pola: `supplyTemperature` (R_TZAS), `co3Temperature` (R_TCO3), `room1Temperature`/`room2Temperature`/`room3Temperature` (R_TWE1-3), `cwuTemperature` (R_TCWU), `avgExternalTemperature` (R_TZSR), `pumpCo1`/`pumpCo2`/`pumpCwu` (WY_P1-3, jako Boolean), `valveCo1`/`valveCo2`/`valveCo3` (WY_ZCO1-3, jako Double 0-100).
3. **Backend** — zaktualizuj `ModbusPollingService.addTelemetrySample()` aby wypełniał nowe pola.
4. **Frontend** — zaktualizuj `frontend/src/types/telemetry.ts` o WSZYSTKIE pola z backendu (`TelemetryPoint`), włącznie z nowymi.
5. **Frontend** — zaktualizuj `frontend/src/mocks/telemetryMock.ts` aby generował dane dla nowych pól.
6. **Frontend** — dodaj KPI cardsy CWU Temperature i Supply Temperature (R_TZAS) obok istniejących w `App.tsx`.
---
## ZADANIE 2: Dodaj logikę schedulera (harmonogram Frisko)
### Stan obecny
- Backend ma `ProgramScheduleSlot` (dayOfWeek, time, programMode ECO/COMFORT) przechowywany w SQLite.
- `ManualControlUseCase.applyScheduleIfDue()` sprawdza co minutę i przełącza `ProgramMode`.
- Frontend `ProgramSchedulePanel` pozwala dodawać sloty dzień+godzina+tryb.
- **Problem**: harmonogram jest TYLKO aplikacyjny — NIE synchronizuje się z rejestrami PROG_* sterownika Frisko.
### Rejestry harmonogramu Frisko (z `mr208_m3p.csv`)
Sterownik Frisko ma 4 sloty czasowe na dzień na obwód:
- `PROG_DZIEN` (4199) — wybrany dzień tygodnia (1-7)
- `PROG_OBW` (4209) — wybrany obwód
- `PROG_GODZ1`–`PROG_GODZ4` (4201–4204) — godziny slotów 1-4
- `PROG_MIN1`–`PROG_MIN4` (4205–4208) — minuty slotów 1-4
- `PROG_COPY` (4200) — kopiowanie programu między dniami
- `PAR_PRG` (4179) — numer programu
### Co zrobić
1. **Backend** — dodaj rejestry PROG_* do `registryMapping.json`:
- `PROG_DZIEN` (4199, scale 1.0, integer, min 1, max 7)
- `PROG_OBW` (4209, scale 1.0, integer)
- `PROG_GODZ1`–`PROG_GODZ4` (4201–4204, scale 1.0, integer, min 0, max 23)
- `PROG_MIN1`–`PROG_MIN4` (4205–4208, scale 1.0, integer, min 0, max 59)
- `PAR_PRG` (4179, scale 1.0, integer)
2. **Backend** — stwórz nowe DTO `FriskoScheduleSlot`:
```java
record FriskoScheduleSlot(int dayOfWeek, int circuit, int hour1, int min1, int hour2, int min2, int hour3, int min3, int hour4, int min4) {}
```
3. **Backend** — dodaj do `FriskoRuntimeService` metody:
- `readScheduleForDayAndCircuit(int dayOfWeek, int circuit)` — ustawia PROG_DZIEN i PROG_OBW przez Modbus write, czeka 200ms, odczytuje GODZ1-4/MIN1-4
- `writeScheduleSlot(FriskoScheduleSlot slot)` — ustawia PROG_DZIEN, PROG_OBW, potem zapisuje GODZ1-4/MIN1-4
4. **Backend** — dodaj endpointy w `FriskoAnalysisController`:
- `GET /api/v1/frisko/schedule?day={1-7}&circuit={id}` → `FriskoScheduleSlot`
- `POST /api/v1/frisko/schedule` z body `FriskoScheduleSlot` → zapisuje do sterownika
5. **Frontend** — stwórz nowy panel `FriskoSchedulePanel` w `frontend/src/components/panels/`:
- Dropdown wyboru dnia tygodnia (Poniedziałek–Niedziela) i obwodu (CO1, CO2, CO3, CWU)
- Widok 4 slotów czasowych (godzina:minuta) z edycją inline
- Przycisk "Odczytaj z sterownika" i "Zapisz do sterownika"
- Wizualizacja timeline 24h (pasek kolorowy — comfort=ciepły kolor, eco=chłodny) — wzór z Frisko `WizualProgram`
6. **Frontend** — dodaj hook `useFriskoSchedule.ts`, service `friskoScheduleService.ts`, typy w `types/frisko.ts`.
7. **Frontend** — wstaw `FriskoSchedulePanel` w `App.tsx` obok istniejącego `ProgramSchedulePanel`.
---
## ZADANIE 3: Dodaj progi rejestrów (parametry sterownika)
### Stan obecny
- Backend `FriskoRuntimeEditorPanel` pozwala ręcznie zapisywać do dowolnego rejestru PAR_*/KONF_*.
- Brak dedykowanego UI do zarządzania progami i parametrami obiegów.
- `ControlPolicySettings` ma tylko `cwuTargetTemperature`, `cwuHysteresis`, `minPumpRunSeconds`, `minPumpStopSeconds`.
### Rejestry progów per obwód z Frisko
Każdy obwód (CO1: 4100–4120, CO2: 4121–4141, CO3: 4142–4162) ma:
- `PAR_COx_TEKO` — temperatura ECO
- `PAR_COx_TKMF` — temperatura COMFORT
- `PAR_COx_TMIN` — minimum temperatury
- `PAR_COx_TMAX` — maksimum temperatury
- `PAR_COx_DELTA` — histereza
- `PAR_COx_KRZYWA` — typ krzywej grzewczej
- `PAR_COx_PRZESKRZ` — przesunięcie krzywej
- `PAR_COx_T_WYL` — temperatura wyłączenia
- `PAR_COx_TZAD` — temperatura zadana
CWU (4167–4176):
- `PAR_CWU_TEKO`, `PAR_CWU_TKMF`, `PAR_CWU_DELTA`, `PAR_CWU_TMAX`, `PAR_CWU_T_WYL`
- `PAR_CWU_DEZYNF` (dezynfekcja antylegionella), `PAR_CWU_DEZDNI`, `PAR_CWU_DEZCZAS`
Globalne:
- `PAR_TPROGZ_L` (4099) — próg przełączenia lato/zima
- `PAR_TMINZAS` (4182) — min temperatura zasilania
- `PAR_TMAXZAS` (4183) — max temperatura zasilania
### Co zrobić
1. **Backend** — dodaj WSZYSTKIE rejestry PAR_CO1_*, PAR_CO2_*, PAR_CO3_*, PAR_CWU_*, PAR_TPROGZ_L, PAR_TMINZAS, PAR_TMAXZAS do `registryMapping.json` z poprawnymi: `desc` (symbol Frisko), `scale` (0.1 dla temperatur, 1.0 dla integer), `min`, `max`, `unit` (°C, min, itp.), `controlType` ("number").
2. **Backend** — stwórz `CircuitThresholds` record:
```java
record CircuitThresholds(
String circuitId,
Double ecoTemperature, Double comfortTemperature,
Double minTemperature, Double maxTemperature,
Double hysteresis, Double shutdownTemperature,
Double setpointTemperature, Integer heatingCurveType,
Double curveOffset
) {}
```
3. **Backend** — dodaj do `FriskoRuntimeService`:
- `readCircuitThresholds(String circuitId)` — odczytuje blok PAR_COx_* dla danego obwodu
- `writeCircuitThreshold(String circuitId, String paramName, double value)` — zapisuje pojedynczy próg
4. **Backend** — dodaj endpointy w `FriskoAnalysisController`:
- `GET /api/v1/frisko/thresholds/{circuitId}` → `CircuitThresholds`
- `POST /api/v1/frisko/thresholds/{circuitId}` z body `Map<String, Double>` → zapisuje progi
- `GET /api/v1/frisko/thresholds/global` → `{summerWinterThreshold, minSupplyTemp, maxSupplyTemp}`
- `POST /api/v1/frisko/thresholds/global` → zapisuje globalne progi
5. **Frontend** — stwórz panel `CircuitThresholdsPanel` (`frontend/src/components/panels/CircuitThresholdsPanel.tsx`):
- Tabsy lub accordion per obwód: CO1, CO2, CO3, CWU
- Dla CO1/CO2/CO3: edytowalne pola z labels po polsku:
- Temperatura ECO (°C), Temperatura COMFORT (°C)
- Min temperatura (°C), Max temperatura (°C)
- Histereza (°C), Temp. wyłączenia (°C)
- Krzywa grzewcza (typ), Przesunięcie krzywej
- Dla CWU: Temp ECO, Temp COMFORT, Histereza, Max temp, Dezynfekcja (tak/nie), Dni dezynf., Czas dezynf.
- Sekcja "Progi globalne": Próg lato/zima, Min temp zasilania, Max temp zasilania
- Przycisk "Odczytaj" per obwód i "Zapisz" per obwód
- Wizualne oznaczenie zmienionych wartości (pomarańczowe tło — wzór z Frisko `APParUSER`)
6. **Frontend** — dodaj hook `useCircuitThresholds.ts`, service do `friskoService.ts`, rozszerz typy w `types/frisko.ts`.
7. **Frontend** — wstaw `CircuitThresholdsPanel` w `App.tsx` — poniżej ControlPanel, przed FriskoRegistersPanel.
---
## ZADANIE 4: Wykresy — czytelne, osobne, użyteczne
### Stan obecny
Obecne wykresy to:
1. `TelemetryLineChart` — linie External + Temp In na jednym wykresie (mało czytelne, brak legendy)
2. `TelemetryAreaChart` — area Temp Out (sam, ok)
3. `LegacyAnalyticsPanels` — delta + bar chart min/avg/max (pomocnicze)
### Problemy
- Dwa różne sygnały o różnych zakresach (zewnętrzna -20..+40°C vs wewnętrzna 20..60°C) na jednym wykresie = nieczytelne
- Brak wykresów: CWU, temperatura zasilania, stany pomp/zaworów
- Brak zakresów setpoint vs actual (porównanie cel vs rzeczywistość)
### Co zrobić — ZASADA: jeden wykres = jedno zagadnienie, duży, czytelny
Zamień obecne wykresy na następujące **osobne, pełnoszerokie** komponenty. Każdy wykres to `Grid size={{ xs: 12 }}` — pełna szerokość, min 360px wysokości wykresu (nie karty, samego wykresu). Kolory ciemne tło (motyw obecny), kontrastowe linie, tooltip z dokładnymi wartościami.
1. **`ExternalTemperatureChart`** — NOWY, zastępuje TelemetryLineChart
- Osobny wykres TYLKO temperatury zewnętrznej (`externalTemperature`)
- Jedna linia, kolor cyan `#22d3ee`, gruba (3px)
- Y-axis zakres dynamiczny z paddingiem ±2°C
- Opcjonalnie: linia przerywana `avgExternalTemperature` (R_TZSR) jako średnia krocząca
- Tytuł: "Temperatura zewnętrzna"
2. **`CircuitTemperaturesChart`** — NOWY, zastępuje obecną część TelemetryLineChart
- Osobny wykres temperatur obiegów: CO1 (`tempIn`), CO2 (`tempOut`), CO3 (`co3Temperature`)
- 3 linie w różnych kolorach: CO1=`#f97316` (orange), CO2=`#3b82f6` (blue), CO3=`#a855f7` (purple)
- Legenda na dole
- Tytuł: "Temperatury obiegów CO"
3. **`CwuTemperatureChart`** — NOWY
- Osobny wykres temperatury CWU (`cwuTemperature`) vs setpoint (`targetTempCwu`)
- Area fill dla actual, przerywana linia dla setpoint
- Kolory: actual=`#ef4444` (red fill), setpoint=`#fbbf24` (yellow dashed)
- Tytuł: "Temperatura CWU (rzeczywista vs zadana)"
4. **`SupplyTemperatureChart`** — NOWY
- Osobny wykres temperatury zasilania (`supplyTemperature`)
- Area chart z gradientem, kolor `#10b981` (emerald)
- Tytuł: "Temperatura zasilania"
5. **`PumpValveStatusChart`** — NOWY
- Wykres stanów pomp i zaworów w czasie (step chart / binary timeline)
- Pola: `pumpCo1`, `pumpCo2`, `pumpCwu` (boolean → 0/1), `valveCo1`, `valveCo2`, `valveCo3` (0-100%)
- Pompy jako step lines (ON/OFF), zawory jako area (0-100%)
- Oddzielne Y-axis: lewa = pompy (0/1), prawa = zawory (0-100%)
- Kolory: pompy solid, zawory przerywane
- Tytuł: "Stany wyjść (pompy i zawory)"
### Usunięcia
- **Usuń** `TelemetryLineChart.tsx` (zastąpiony przez ExternalTemperatureChart + CircuitTemperaturesChart)
- **Usuń** `TelemetryAreaChart.tsx` (zastąpiony przez SupplyTemperatureChart)
- **Zachowaj** `LegacyAnalyticsPanels` ale rozszerz o nowe metryki (CWU, supply)
### Układ w App.tsx (nowy porządek sekcji wykresów)
```tsx
{/* KPI cards — rozszerzone o CWU i Supply temp */}
<Grid size={{ xs: 12, sm: 6, md: 2.4 }}> KpiCard External </Grid>
<Grid size={{ xs: 12, sm: 6, md: 2.4 }}> KpiCard Temp In (CO1) </Grid>
<Grid size={{ xs: 12, sm: 6, md: 2.4 }}> KpiCard Temp Out (CO2) </Grid>
<Grid size={{ xs: 12, sm: 6, md: 2.4 }}> KpiCard CWU Temp </Grid>
<Grid size={{ xs: 12, sm: 6, md: 2.4 }}> KpiCard Supply Temp </Grid>
{/* Wykresy — każdy full-width, osobny */}
<Grid size={{ xs: 12 }}> ExternalTemperatureChart </Grid>
<Grid size={{ xs: 12 }}> CircuitTemperaturesChart </Grid>
<Grid size={{ xs: 12 }}> CwuTemperatureChart </Grid>
<Grid size={{ xs: 12 }}> SupplyTemperatureChart </Grid>
<Grid size={{ xs: 12 }}> PumpValveStatusChart </Grid>
{/* Reszta dashboardu */}
<Grid ...> HealthPanel </Grid>
<Grid ...> SchematicPreviewPanel </Grid>
<Grid ...> ControlPanel </Grid>
<Grid ...> CircuitThresholdsPanel </Grid> ← NOWY z zadania 3
<Grid ...> ProgramSchedulePanel </Grid>
<Grid ...> FriskoSchedulePanel </Grid> ← NOWY z zadania 2
...
```
### Styl wykresów (wspólna konwencja)
- Tło karty: `background.paper` (#111827)
- Grid lines: `rgba(148,163,184,0.08)`
- Osie: `#64748b`, bez tick lines
- Tooltip: ciemne tło `#0f172a`, zaokrąglony border 12px, biały tekst
- Tytuły: `variant="h6"`, marginBottom 16px
- Font size na osiach: 12px
- Responsive container: `width="100%"` `height={360}`
- Recharts `<CartesianGrid strokeDasharray="3 3" stroke="rgba(148,163,184,0.08)" />`
- Każdy wykres w osobnym `<Card>` z `<CardContent>`
---
## WAŻNE ZASADY
1. **Nie zmieniaj istniejącej architektury** — hexagonal, ports & adapters, clean architecture. Dodawaj kod w odpowiednich warstwach.
2. **Nie dodawaj eksportu CSV** — eksplicytnie NIE jest chciany.
3. **Nie dodawaj powiadomień email** — eksplicytnie NIE jest chciane.
4. **Zachowaj istniejącą funkcjonalność** — wszystko co działa musi dalej działać.
5. **Konwencja nazw plików**: camelCase dla serwisów/hooków, PascalCase dla komponentów TSX.
6. **Testy**: dodaj unit testy dla nowych endpointów backendu w `src/test/java/`.
7. **Język UI**: etykiety po polsku (wzór z istniejących paneli: "Sterowanie", "Programator tygodniowy").
8. **registryMapping.json**: duplikuj zmiany w `src/main/resources/registryMapping.json` ORAZ `target/classes/registryMapping.json`.
## PROMPT END
+59
View File
@@ -0,0 +1,59 @@
# Audyt Techniczny i Status Migracji (Home Pump)
**Data audytu:** 22 lutego 2026
**Status:** 🟡 W TOKU NAPRAW (NIE GOTOWE DO PRODUKCJI)
Ten dokument służy jako punkt wejścia dla agentów AI i programistów. Zawiera zwięzłą listę zidentyfikowanych problemów architektonicznych i funkcjonalnych, które blokują wdrożenie systemu na produkcję.
---
## 🔴 Blockery (Krytyczne do wdrożenia)
Te elementy muszą zostać naprawione przed jakimkolwiek releasem. Obecny stan grozi uszkodzeniem sprzętu lub całkowitą nieużywalnością systemu.
- [x] **Konflikt pętli sterowania z trybem MANUAL:** `ControlLoopUseCase` respektuje `OperatingMode` i nie wysyła komend w trybie MANUAL.
- [x] **Egzekucja harmonogramów:** Dodano scheduler (`app.control.schedule-interval`) oraz `applyScheduleIfDue(...)` w `ManualControlUseCase`.
- [x] **Tryb LATO/ZIMA:** Dodano `SeasonMode` w domenie, API (`POST /api/v1/control/season`) i UI (panel sterowania).
- [x] **Mechanizm Fail-Safe:** Dodano próg `app.control.communication-fail-safe-seconds` i wymuszone STOP/CLOSE po długotrwałym braku odczytów.
- [x] **Przeciążenie magistrali Modbus:** W `AppConfig` `ModbusService` został spięty przez `ModbusCachedWrapper`.
---
## 🟡 Dług Technologiczny i Stabilność (Ważne)
Elementy kluczowe dla stabilności działania i poprawnego monitoringu.
- [x] **Retry bez blokującego sleep:** Usunięto `Thread.sleep()` z retry w `ModbusConnection` (brak blokowania schedulerów).
- [x] **Metryki InfluxDB:** `InfluxMetricsAdapter` publikuje temperaturę CWU i osobne pomiary z tagiem `circuit`.
- [x] **Testy integracyjne E2E:** Dodano testy dla alarm-flow (`shouldExposeAlarmFlowEndpoint`, `shouldReportAlarmStructureWithRegisters`) oraz fail-safe (`shouldApplyFailSafeAfterProlongedCommunicationFailure`). Brakuje jeszcze kompleksowych testów pełnego przepływu `Odczyt Modbus -> Logika Domenowa -> Zapis Modbus`.
- [ ] **Nadużywanie `synchronized`:** `ManualControlUseCase` używa `synchronized` na prawie każdej metodzie, co jest antywzorcem w Springu. Zastąpić przez `ReentrantLock` lub polegać na bazie danych.
---
## 🟠 Frisko Coverage (Nowe)
Weryfikacja katalogu `frisko/mr208_m3p.csv` potwierdziła, że intuicja była poprawna: pokrycie nie jest pełne i nie wszystkie feature’y Frisko są domknięte domenowo.
- [x] **Spójność raportu `/api/v1/frisko/features` (important):** logika coverage została zsynchronizowana z realnie wspieranymi symbolami sterowania i telemetrii (w tym fallbacki WY/TEST oraz rozszerzona telemetria `STATUS`/`TZAD`/`KAL`).
- [x] **Obiektywny status pokrycia:** `GET /api/v1/frisko/features` zwraca teraz statusy liczone z realnego pokrycia (`done/partial/missing`), a nie same stałe wartości.
- [~] **Sterowanie WY_/TEST_ (critical):** rozszerzono mapowanie o fallback `TEST_P*`/`TEST_ZCO*` oraz CO3, dodano testy zapisu per symbol; do domknięcia zostaje mapowanie pozostałych wyjść specjalnych (`TEST_WYJSC*`).
- [x] **Telemetria Frisko (critical):** backend mapuje teraz pełną macierz sygnałów telemetrycznych (`R_T*`, `STATUS`, `R_TZAD_*`, `R_TZADANA`, `KAL_*`) ze strategią symbol-first i fallbackiem do legacy tam, gdzie dostępny; pokryte testami fallback/NaN (brak i wartości nienumeryczne).
- [ ] **Schedule PROG_/PAR_PRG (important):** zsynchronizować harmonogram aplikacji z semantyką rejestrów Frisko i pokryć to testem E2E (zapis->odczyt->egzekucja).
- [x] **Alarm-flow E2E (important):** dodano testy integracyjne dla endpointu `/api/v1/frisko/alarms` weryfikujące strukturę odpowiedzi i dostępność danych alarmowych.
---
## 🔵 Opcjonalne (Nice to Have)
- [ ] **Usunięcie Legacy InfluxDB:** Stary `InfluxMetricModbusSender` działa równolegle z nowym adapterem, dublując zapisy. Należy go usunąć po naprawieniu nowego adaptera.
- [ ] **Testy Architektury:** Dodać testy ArchUnit, aby zapobiec wyciekaniu logiki domenowej do warstwy infrastruktury.
---
## 📝 Kontekst dla Agenta AI
Jeśli zaczynasz pracę nad tym projektem, kontynuuj od sekcji **🟡 Dług Technologiczny i Stabilność**.
1. Dodaj testy integracyjne E2E dla pętli sterowania.
2. Ogranicz `synchronized` w `ManualControlUseCase`.
3. Zaplanuj wygaszenie `InfluxMetricModbusSender`.
+55
View File
@@ -0,0 +1,55 @@
# Backend migration status (Frisko -> clean architecture)
## Co już jest zrobione
- Migracja aplikacji backend do Spring Boot (`HomePumpApplication`) z harmonogramami `@Scheduled`.
- Wydzielenie warstw:
- `domain` (model i strategie)
- `application` (use case + porty)
- `infrastructure` (adaptery Modbus/Influx + API)
- Działa pętla sterowania `ControlLoopUseCase` oparta o porty.
- Wdrożone reguły domenowe:
- priorytet CWU względem CO (przy niskiej temperaturze CWU)
- minimalny czas pracy i postoju pompy (anti short-cycle)
- Działa kompatybilne API monitoringu:
- `GET /health`
- `GET /api/telemetry`
- Dodana analiza Frisko oparta o `frisko/mr208_m3p.csv`:
- `GET /api/v1/frisko/features`
- `GET /api/v1/frisko/registers`
## Co trzeba jeszcze zrobić (kolejność)
1. **Mapowanie komend do rejestrów Modbus (critical)**
- obecnie `ModbusDeviceAdapter.applyCommands` nie wykonuje rzeczywistych zapisów.
- potrzebna jawna tabela mapowań per obieg/akcja (np. `CO1 + PUMP_START -> register X`).
2. **Rozszerzenie reguł domenowych z Frisko (critical)**
- tryby pracy (AUTO/RĘCZNY, LATO/ZIMA, ECO/KOMFORT)
- parametryzacja progów CWU/histerezy i czasów min run/stop z konfiguracji
3. **Konfiguracja schedulera i retry policy (important)**
- zewnętrzne parametry w `application.yml`
- rozdzielenie interwałów: polling / control loop / health
4. **Audit metryk Influx (important)**
- standaryzacja nazw pomiarów i pól
- tagowanie obiegów (`circuit=CO1/CO2/...`)
5. **Testy architektoniczne i domenowe (important)**
- testy use case’ów bez Modbusa
- testy adaptera Modbus z mock repo i tabelą mapowań
## Decyzja architektoniczna: Spring Boot
Spring Boot jest właściwą decyzją dla tego projektu:
- skraca czas implementacji (DI, scheduling, REST)
- redukuje kod infrastrukturalny
- ułatwia testowanie i obserwowalność
- dobrze współgra z podejściem Ports & Adapters
## Uwaga o Frisko
Frisko jest traktowane jako źródło wymagań i semantyki rejestrów, nie jako źródło kodu.
Kod nowego backendu pozostaje niezależny i czysty architektonicznie.
+174
View File
@@ -0,0 +1,174 @@
# Analiza Dokumentacji Frisko Online v2.3
**Data analizy:** 22 lutego 2026
**Źródło:** FRISKO-ONLINE-wersja-2_3.pdf (konwersja TXT)
---
## 1. Przeznaczenie i Zakres Systemu
Frisko Online to system zdalnego nadzoru dla instalacji wyposażonych w automatykę firmy FRISKO. System oferuje:
- Zdalną obsługę sterowników przez instalatorów i serwisantów
- Możliwość zmiany nastaw przez użytkowników końcowych
- Rejestrację parametrów pracy w bazie danych
- Przeglądanie danych w formie wykresów (eksport CSV, drukowanie)
- **Automatyczne generowanie alarmowych wiadomości e-mail** (na dwa przypisane konta)
---
## 2. Wspierane Sterowniki
System obsługuje:
- **Sterowniki:** S20, MR210, **MR208**, MR65, RX910, ATTO
- **Moduły komunikacyjne:**
- EM500, EM510 (wbudowane w MR210/MR208)
- EM1206 (wbudowane w S20)
- MK01 (zewnętrzne, RS485, jeden sterownik per moduł)
- **Protokół:** Modbus przez ethernet (porty 9010, 9020)
- **Minimalna wersja oprogramowania sterownika:** 01.01.2013
---
## 3. Funkcje Systemu (Wersja Pełna)
### 3.1 Funkcje Podstawowe
✅ **Wyświetlanie i zmiana podstawowych parametrów sterownika** - MAMY
✅ **Wyświetlanie i zmiana serwisowych parametrów** - MAMY (endpoint `/api/v1/frisko/runtime/write`)
✅ **Podgląd online temperatur i stanu wyjść** - MAMY (endpoints `/api/v1/system/readings`, `/api/v1/control/state`)
⚠️ **Schemat technologiczny** - MAMY podstawowy (`/api/v1/system/schematic`), ale nie graficzny UI per obiekt
### 3.2 Funkcje Analityczne
✅ **Rejestracja parametrów pracy** - MAMY (InfluxDB, telemetria)
⚠️ **Wykresy dobowe** - MAMY backend (InfluxDB), brak dedykowanego UI
❌ **Eksport CSV** - NIE MAMY (backend ma tylko JSON API)
❌ **Drukowanie wykresów** - NIE MAMY (można zaimplementować w frontend)
### 3.3 Funkcje Alarmowe
✅ **Przegląd zarejestrowanych stanów awaryjnych** - MAMY (`/api/v1/frisko/alarms`)
❌ **Automatyczne e-maile o stanach awaryjnych** - NIE MAMY (krytyczny gap!)
✅ **E2E testy alarm-flow** - MAMY (nowe testy integracyjne)
### 3.4 Edycja Programów Dobowych
⚠️ **Edycja programu dobowego** - MAMY schedule API (`/api/v1/control/schedule`), ale:
- Brak mapowania rejestrów `PROG_*` (PROG_DZIEN, PROG_GODZ1-4, PROG_MIN1-4, PROG_OBW, PROG_COPY)
- Schedule działa na poziomie aplikacji, nie synchronizuje się z rejestrami sterownika
- Gap analysis pokazuje 3/14 rejestrów schedule pokrytych
---
## 4. Porównanie z Naszą Implementacją
### 4.1 Kompletność Funkcjonalna
| Kategoria | Frisko Online | Nasza Implementacja | Status |
|-----------|---------------|---------------------|--------|
| **Sterowanie** | Full | Full (14/14 rejestrów) | ✅ DONE |
| **Telemetria** | Full | Substantial (30/46 w main) | ⚠️ PARTIAL |
| **Alarmy (API)** | Full | Full (endpoint + testy E2E) | ✅ DONE |
| **Alarmy (notyfikacje)** | Email auto | Brak | ❌ CRITICAL GAP |
| **Schedule (logika)** | Full | Basic (app-level) | ⚠️ PARTIAL |
| **Schedule (PROG_*)** | Full | Minimal (3/14) | ❌ GAP |
| **Wykresy** | Desktop UI | Backend only | ⚠️ PARTIAL |
| **Eksport CSV** | Tak | Nie | ❌ NICE-TO-HAVE |
| **Schemat graficzny** | Per obiekt | Generic JSON | ⚠️ PARTIAL |
### 4.2 Kluczowe Luki
#### 🔴 KRYTYCZNE:
1. **Brak automatycznych notyfikacji alarmowych**
- Frisko Online: Auto email na 2 konta (serwis + użytkownik)
- My: Tylko endpoint API `/api/v1/frisko/alarms`
- **Rekomendacja:** Dodać Spring mail sender z konfiguracją SMTP + watch service dla `ALARM_ZBIORCZY`, `R_ALARM_KOM`
#### 🟠 WAŻNE:
2. **Niepełne mapowanie PROG_* schedule**
- Frisko Online: PROG_DZIEN, PROG_GODZ1-4, PROG_MIN1-4, PROG_OBW, PROG_COPY
- My: Schedule w bazie SQLite, nie synchronizuje z rejestrami sterownika
- **Rekomendacja:** Dodać dwukierunkową synchronizację schedule ↔ PROG_* rejestry
3. **Eksport CSV wykresów**
- Frisko Online: Export z desktop app
- My: Brak
- **Rekomendacja:** Dodać `/api/v1/telemetry/export?from=...&to=...&format=csv`
#### 🟢 NICE-TO-HAVE:
4. **Graficzny schemat technologiczny per obiekt**
- Frisko Online: Customowy schemat na zamówienie (za dodatkową opłatą)
- My: Generic JSON schematic snapshot
- **Rekomendacja:** Niski priorytet, można zaimplementować w frontend (SVG + bindings)
---
## 5. Rekomendacje Priorytetowe
### P0 (DO PRODUKCJI):
1. **Alarm Email Notifications**
- Monitorować rejestry `ALARM_ZBIORCZY` (3005) i `R_ALARM_KOM` (3006)
- Spring Boot mail sender + configurable recipient list
- Throttling (max 1 email/alarm/godzinę, aby uniknąć spamu)
### P1 (POST-LAUNCH):
2. **PROG_* Schedule Synchronization**
- Mapowanie `PROG_DZIEN` (3035) jako bieżący dzień
- `PROG_GODZ1-4` (3036-3039) jako godziny przełączeń
- `PROG_MIN1-4` (3040-3043) jako minuty przełączeń
- `PROG_OBW` (3044) jako wybrany obwód
- `PROG_COPY` (3034) jako trigger kopiowania programu
3. **CSV Export API**
- Endpoint eksportu danych telemetrycznych z InfluxDB
- Format zgodny z Frisko Online (separator `;`, ISO datetime)
### P2 (FUTURE):
4. **Graficzne schematy** - jeśli będzie demand od użytkowników
5. **Drukowanie wykresów** - można zrobić browser-native (window.print() z wykresu Chart.js)
---
## 6. Gap Analysis → Nasza Implementacja
Z comprehensive gap analysis (wykonanej wcześniej):
**Kontrola wyjść:** 14/14 ✅ (100% – WY_*, TEST_*, CO3)
**Telemetria:** 30/46 ⚠️ (65% – R_T*, STATUS, TZAD, KAL)
**Schedule:** 3/14 ❌ (21% – brak PROG_* pełnego mapowania)
**Alarmy (odczyt):** 0/2 → **2/2 ✅** (dodano endpoint + testy E2E)
**Alarmy (notyfikacje):** 0/2 ❌ (brak email sender)
**Konfiguracja:** 7/104 ⚠️ (7% – PAR_*, KONF_*)
---
## 7. Wnioski Techniczne
### Architektura Frisko Online
- Java desktop app (wymaga JRE 1.6.0_07+)
- Komunikacja przez dedicated porty 9010, 9020
- Brak wymagania stałego IP (moduł się rejestruje w chmurze)
- Buffer zmian parametrów (nie blokuje UI podczas zapisu Modbus)
### Architektura Nasza
- Spring Boot backend (Java 17) + React frontend
- REST API + React Query (no dedicated ports, standard HTTP/HTTPS)
- ModbusCachedWrapper dla optymalizacji
- SQLite dla persystencji state
**Różnice kluczowe:**
- My: Modern stack (React, REST), deployable jako Docker/systemd service
- Oni: Desktop-only, wymaga instalacji Java na każdym stanowisku
---
## 8. Następne Kroki
### Ukończone w tej sesji:
- [x] E2E test alarm-flow (`shouldExposeAlarmFlowEndpoint`, `shouldReportAlarmStructureWithRegisters`)
- [x] Test fail-safe (`shouldApplyFailSafeAfterProlongedCommunicationFailure`)
- [x] Aktualizacja `docs/audit-status.md`
### Do implementacji (priorytet):
1. **Alarm email notifications** (Spring Mail + scheduler watching `ALARM_ZBIORCZY`)
2. **PROG_* schedule synchronization** (dwukierunkowe mapowanie rejestrów)
3. **CSV export endpoint** (InfluxDB query → CSV format)
### Tracking:
Wszystkie gaps i rekomendacje dodane do `docs/audit-status.md` w sekcjach odpowiednich priorytetów.
+14
View File
@@ -0,0 +1,14 @@
#Fat Jar Configuration File
#Fri Jul 18 12:12:13 CEST 2014
onejar.license.required=true
manifest.classpath=
manifest.removesigners=true
onejar.checkbox=false
jarname=ApletUSER.jar
manifest.mergeall=true
manifest.mainclass=Kasandra
manifest.file=<createnew>
jarname.isextern=false
onejar.expand=
excludes=<po|KAS_MR208_M3P>~AlertBox.java;<po|KAS_MR208_M3P>~APCheckBox.java;<po|KAS_MR208_M3P>~APkalendarz.java;<po|KAS_MR208_M3P>~ApletUSER.java;<po|KAS_MR208_M3P>~ApletUSER1333444161078.html;<po|KAS_MR208_M3P>~APParUSER.java;<po|KAS_MR208_M3P>~APSECsys.java;<po|KAS_MR208_M3P>~APzakres.java;<po|KAS_MR208_M3P>~Bufor.java;<po|KAS_MR208_M3P>~BytesInputStream.java;<po|KAS_MR208_M3P>~BytesOutputStream.java;<po|KAS_MR208_M3P>~CopyOfAPCheckBox.java;<po|KAS_MR208_M3P>~Czujnik.java;<po|KAS_MR208_M3P>~daneCSV.java;<po|KAS_MR208_M3P>~Dane_DB.java;<po|KAS_MR208_M3P>~Dane_Logowanie.java;<po|KAS_MR208_M3P>~Dane_ReadAll.java;<po|KAS_MR208_M3P>~Dane_Status.java;<po|KAS_MR208_M3P>~DUOv2.epr;<po|KAS_MR208_M3P>~FastByteArrayInputStream.java;<po|KAS_MR208_M3P>~FastByteArrayOutputStream.java;<po|KAS_MR208_M3P>~FiltrPlikow.java;<po|KAS_MR208_M3P>~Grzejnik.java;<po|KAS_MR208_M3P>~JAwariaPanel.java;<po|KAS_MR208_M3P>~JCzasPanel.java;<po|KAS_MR208_M3P>~JOdczytuStatusPanel.java;<po|KAS_MR208_M3P>~JPanelKlawiszy.java;<po|KAS_MR208_M3P>~JPanelLogowania.java;<po|KAS_MR208_M3P>~JParamPanel.java;<po|KAS_MR208_M3P>~JProgram2Panel.java;<po|KAS_MR208_M3P>~JProgramPanel.java;<po|KAS_MR208_M3P>~JWykresCharakterystyk2pktPanel.java;<po|KAS_MR208_M3P>~JWykresCzasowyPanel.java;<po|KAS_MR208_M3P>~JWykresOgrPowrotu.java;<po|KAS_MR208_M3P>~JWykresPanel.java;<po|KAS_MR208_M3P>~JWykresSrednichPanel.java;<po|KAS_MR208_M3P>~JZmianyParametrowPanel.java;<po|KAS_MR208_M3P>~Kasandra.java;<po|KAS_MR208_M3P>~Kasandra_208_M3P.jar;<po|KAS_MR208_M3P>~KociolGazowy.java;<po|KAS_MR208_M3P>~KodyDB.java;<po|KAS_MR208_M3P>~Kran.java;<po|KAS_MR208_M3P>~Lampka.java;<po|KAS_MR208_M3P>~MR.csv.csv;<po|KAS_MR208_M3P>~mr208_m2p.csv;<po|KAS_MR208_M3P>~MR208_M3P.java;<po|KAS_MR208_M3P>~ObrazPanel.java;<po|KAS_MR208_M3P>~OknoHaslo.java;<po|KAS_MR208_M3P>~OpisSterownika.java;<po|KAS_MR208_M3P>~OpisUzytkow.java;<po|KAS_MR208_M3P>~PasekPostepu.java;<po|KAS_MR208_M3P>~Pompa.java;<po|KAS_MR208_M3P>~RamkaApletu.java;<po|KAS_MR208_M3P>~RegReader.java;<po|KAS_MR208_M3P>~Rura.java;<po|KAS_MR208_M3P>~StatusPlik.java;<po|KAS_MR208_M3P>~Sterownik.java;<po|KAS_MR208_M3P>~USERRozkaz.java;<po|KAS_MR208_M3P>~USERSystem.java;<po|KAS_MR208_M3P>~Video.java;<po|KAS_MR208_M3P>~Wentylator.java;<po|KAS_MR208_M3P>~WizualAkcja.java;<po|KAS_MR208_M3P>~WizualAlertBox.java;<po|KAS_MR208_M3P>~WizualBufor.java;<po|KAS_MR208_M3P>~WizualCzujnik.java;<po|KAS_MR208_M3P>~WizualGIF.java;<po|KAS_MR208_M3P>~WizualGrzejnik.java;<po|KAS_MR208_M3P>~WizualJPG.java;<po|KAS_MR208_M3P>~WizualKociolGazowy.java;<po|KAS_MR208_M3P>~WizualKomponent.java;<po|KAS_MR208_M3P>~WizualKran.java;<po|KAS_MR208_M3P>~WizualLampka.java;<po|KAS_MR208_M3P>~WizualPanel.java;<po|KAS_MR208_M3P>~WizualPNG.java;<po|KAS_MR208_M3P>~WizualPompa.java;<po|KAS_MR208_M3P>~WizualProgram.java;<po|KAS_MR208_M3P>~WizualProgram2.java;<po|KAS_MR208_M3P>~WizualRura.java;<po|KAS_MR208_M3P>~WizualText.java;<po|KAS_MR208_M3P>~WizualVideo.java;<po|KAS_MR208_M3P>~WizualWentylator.java;<po|KAS_MR208_M3P>~WizualWymiennik.java;<po|KAS_MR208_M3P>~WizualZaluzja.java;<po|KAS_MR208_M3P>~WizualZawor.java;<po|KAS_MR208_M3P>~WizualZaworAnalog.java;<po|KAS_MR208_M3P>~WizualZaworOnOf.java;<po|KAS_MR208_M3P>~Wymiennik.java;<po|KAS_MR208_M3P>~ZaworOnOf.java
includes=
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
+11
View File
@@ -0,0 +1,11 @@
Manifest-Version: 1.0
Created-By: Fat Jar Eclipse Plug-In
Main-Class: Kasandra
@@ -0,0 +1,5 @@
#Generated by org.apache.felix.bundleplugin
#Thu Jun 03 04:43:18 PDT 2010
version=1.4.5
groupId=org.jbundle.thin.base.screen
artifactId=jcalendarbutton
@@ -0,0 +1,154 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>oss-parent</artifactId>
<groupId>org.sonatype.oss</groupId>
<version>1</version>
</parent>
<groupId>org.jbundle.thin.base.screen</groupId>
<artifactId>jcalendarbutton</artifactId>
<version>1.4.5</version>
<packaging>bundle</packaging>
<name>JCalendarButton - Date and Time Popup Buttons</name>
<description>JCalendarButton is a simple java swing component that displays a popup calendar next to a date input field.</description>
<url>http://www.jbundle.org/thin/base/screen/jcalendarbutton</url>
<licenses>
<license>
<name>The GNU General Public License, Version 3.0</name>
<url>http://www.gnu.org/licenses/gpl.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<url>http://jcalendarbutton.hg.sourceforge.net:8000/hgroot/jcalendarbutton/jcalendarbutton</url>
<connection>scm:hg:http://jcalendarbutton.hg.sourceforge.net:8000/hgroot/jcalendarbutton/jcalendarbutton</connection>
<developerConnection>scm:hg:ssh://doncorley@jcalendarbutton.hg.sourceforge.net/hgroot/jcalendarbutton/jcalendarbutton</developerConnection>
</scm>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<issueManagement>
<system>Tracker</system>
<url>https://sourceforge.net/tracker/?group_id=239200</url>
</issueManagement>
<developers>
<developer>
<id>doncorley</id>
<name>Don Corley</name>
<email>don@donandann.com</email>
<url>http://www.donandann.com</url>
<timezone>PDT – Pacific Daylight Time (UTC -08:00)</timezone>
</developer>
</developers>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-ManifestVersion>2</Bundle-ManifestVersion>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Export-Package>org.jbundle.thin.base.screen.jcalendarbutton.*</Export-Package>
<Bundle-Version>${project.version}</Bundle-Version>
<Import-Package>
*;resolution:=optional,
</Import-Package>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>2.1</version>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>release-sign-artifacts</id>
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<distributionManagement>
<site>
<id>jbundle.org</id>
<url>scp://www.jbundle.org://space/web/jbundle/thin/base/screen/jcalendarbutton</url>
</site>
</distributionManagement>
</project>
+1
View File
@@ -0,0 +1 @@
org.postgresql.Driver
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loaded 100 of 2099 files, more files were not shown because too many files have changed in this diff. Show more