Warstwa pośrednia do komunikacji BACnet/IP (odczyt obiektów i właściwości) zbudowana na Symfony 7.1, Doctrine ORM 3 i JWT (LexikJWTAuthenticationBundle).
Informacje ogólne #
- Cel: Pośrednik do pozyskiwania danych urządzeń systemów automatyki budynkowej przez BACnet/IP i ekspozycji ich przez API.
- Język/Framework: PHP 8.2+, Symfony 7.1
- Uwierzytelnianie: JWT (LexikJWTAuthenticationBundle)
- Warstwa danych: Doctrine ORM 3 + MySQL 8.0.32
Repozytorium #
Bitbucket: https://Poligrand@bitbucket.org/Poligrand/bacnet-middleware.git
Klonowanie (HTTPS; w razie potrzeby użyj tokenu/aplikacyjnego hasła):
git clone https://Poligrand@bitbucket.org/Poligrand/bacnet-middleware.git
cd bacnet-middleware
Wymagania #
- System: Linux / macOS / WSL2
- PHP: >= 8.2 (typowe rozszerzenia:
ctype,iconv,openssl,pdo_mysql,json,mbstring,xml) - Composer: 2.5+
- Baza danych: MySQL 8.0.32+
- Serwer HTTP: Nginx lub Apache 2.4+
- (Opcjonalnie) Symfony CLI
Kluczowe pakiety (z composer.json): Symfony 7.1 (framework-bundle, console, serializer, validator, form, yaml), Doctrine (orm, dbal, migrations), lexik/jwt-authentication-bundle.
Architektura #
[Klient/API] ⇄ (JWT) ⇄ [Middleware (Symfony 7.1)] ⇄ [BACnet/IP] ⇄ [Urządzenia]
└─ SQL (Doctrine) ─→ [MySQL]
Warstwa API/CLI zarządza odczytami/zapisami właściwości BACnet oraz konfiguracją sieciową (BBMD, porty, interfejs).
Struktura katalogów (tylko katalogi) #
bacnet-middleware/
├── bin/
├── config/
│ ├── packages/
│ └── routes/
├── migrations/
├── public/
├── src/
│ ├── Command/
│ ├── Controller/
│ ├── Entity/
│ ├── Repository/
│ ├── Service/
│ └── Util/
├── tests/
└── var/
└── jwt/
Konfiguracja środowisk #
Pliki .env* ładowane są zgodnie z konwencją Symfony (zmienne środowiskowe mają pierwszeństwo). Poniżej redagowany przykład .env.local — uzupełnij własnymi wartościami:
# Symfony
APP_ENV=dev
APP_SECRET=<zmien_w_produkcji>
# JWT (LexikJWTAuthenticationBundle)
JWT_SECRET_KEY="%kernel.project_dir%/var/jwt/private.pem"
JWT_PUBLIC_KEY="%kernel.project_dir%/var/jwt/public.pem"
JWT_PASSPHRASE=<twoje_haslo_do_kluczy>
# DB – MySQL 8.0.32
DATABASE_URL="mysql://bacnet:secret@mysql-service:3306/bacnet?serverVersion=8.0.32&charset=utf8mb4"
# BACnet/IP – parametry środowiskowe
BACNET_IFACE=tun0
BACNET_BBMD_ADDRESS=192.168.1.94
BACNET_BBMD_PORT=47808
BACNET_IP_PORT=47808
BACNET_BBMD_TIMETOLIVE=60
BACNET_APDU_TIMEOUT=10000
BACNET_APDU_RETRIES=5
BACNET_WORKDIR="var/bacnet"
Uwaga (prod): użyj APP_ENV=prod, APP_DEBUG=0 oraz composer dump-env prod. Sekrety trzymaj poza repozytorium.
Szybki start (dev) #
# 1) Klonowanie
git clone https://Poligrand@bitbucket.org/Poligrand/bacnet-middleware.git
cd bacnet-middleware
# 2) Zależności
composer install
# 3) Konfiguracja ENV
cp .env .env.local # albo utwórz .env.local z wartościami powyżej
# 4) Baza danych (MySQL)
php bin/console doctrine:database:create || true
php bin/console doctrine:migrations:migrate -n
# 5) JWT – wygeneruj klucze (patrz poniżej)
# 6) Uruchomienie serwera dev
symfony serve -d # lub: php -S 127.0.0.1:8000 -t public
Baza danych i migracje #
php bin/console doctrine:database:create
php bin/console doctrine:migrations:migrate -n
# (opcjonalnie) Fixtures – jeśli projekt je udostępnia
# php bin/console doctrine:fixtures:load -n
JWT – generowanie kluczy #
Ścieżki kluczy zgodne z .env.local: var/jwt/private.pem, var/jwt/public.pem.
# ustaw hasło (to samo co JWT_PASSPHRASE w .env.local)
export JWT_PASSPHRASE="<twoje_haslo_do_kluczy>"
mkdir -p var/jwt
openssl genpkey -algorithm RSA -out var/jwt/private.pem -pkeyopt rsa_keygen_bits:4096
openssl pkey -in var/jwt/private.pem -pubout -out var/jwt/public.pem
# uprawnienia
chmod 600 var/jwt/private.pem
chmod 644 var/jwt/public.pem
Uruchamianie #
Lokalnie:
symfony serve -d
# lub
php -S 127.0.0.1:8000 -t public
CLI (lista dostępnych komend):
php bin/console list | grep app:
Budowanie i wdrożenie (prod) #
- Konfiguracja prod:
APP_ENV=prod,APP_DEBUG=0(zmienne środowiskowe / secrets). - Build i optymalizacja:
composer install --no-dev --optimize-autoloader
composer dump-env prod
php bin/console cache:clear --env=prod
php bin/console doctrine:migrations:migrate --no-interaction --env=prod
- Nginx – minimalny przykład:
server {
server_name api.example.com;
root /var/www/bacnet-middleware/public;
location / { try_files $uri /index.php$is_args$args; }
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
}
}
Parametry BACnet (omówienie) #
BACNET_IFACE– interfejs sieciowy używany do komunikacji BACnet/IP (np.eth0,tun0).BACNET_BBMD_ADDRESS– adres BBMD w przypadku routingu BACnet przez sieci/IP.BACNET_BBMD_PORT/BACNET_IP_PORT– typowy port BACnet to 47808/UDP (0xBAC0).BACNET_BBMD_TIMETOLIVE– czas życia wpisów w FDT (Foreign Device Table) w sekundach.BACNET_APDU_TIMEOUT– timeout APDU w ms (np. 10000).BACNET_APDU_RETRIES– liczba powtórzeń zapytań APDU.BACNET_WORKDIR– katalog roboczy na pliki tymczasowe/konfiguracyjne.
W środowiskach izolowanych (kontenery/K8s) pamiętaj o otwarciu UDP 47808 i przydzieleniu właściwego interfejsu.
