Author SHA1 Message Date
theoandClaude Fable 5.1 66bce8e8d0 chore: ignore phpunit result cache
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 15:13:54 +02:00
theoandClaude Fable 5.1 7fd49cc391 docs: deploy via Ansible on pensare-server
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 15:13:01 +02:00
theoandClaude Fable 5.1 246756438b Merge feature/weerscherm: Weerscherm v1 (backend, frontend, Netatmo, Open-Meteo, PWA, docs)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 14:50:52 +02:00
3 changed files with 32 additions and 16 deletions
+1
View File
@@ -3,3 +3,4 @@ config.php
/vendor/ /vendor/
/node_modules/ /node_modules/
.DS_Store .DS_Store
.phpunit.result.cache
-1
View File
@@ -1 +0,0 @@
{"version":2,"defects":{"Weerscherm\\Tests\\DashboardServiceTest::testForecastUsesStationLocationUnlessConfigured":7,"Weerscherm\\Tests\\DashboardServiceTest::testMeasureFailureFallsBackToSumRain24":7,"Weerscherm\\Tests\\NetatmoClientTest::testRejectedTokenAlreadyReplacedByOtherProcessIsReusedWithoutRefresh":8},"times":{"Weerscherm\\Tests\\ConfigTest::testDefaultsApplyWhenKeysAreMissing":0,"Weerscherm\\Tests\\ConfigTest::testFileValuesOverrideDefaults":0,"Weerscherm\\Tests\\ConfigTest::testUnknownKeyReturnsGivenDefault":0,"Weerscherm\\Tests\\ConfigTest::testFileMustReturnArray":0,"Weerscherm\\Tests\\StationMapperTest::testStationMetadata":0,"Weerscherm\\Tests\\StationMapperTest::testOutdoor":0,"Weerscherm\\Tests\\StationMapperTest::testIndoorDefaultOrderAndUnreachableModule":0,"Weerscherm\\Tests\\StationMapperTest::testIndoorConfigDeterminesOrderAndLabels":0,"Weerscherm\\Tests\\StationMapperTest::testRainModule":0,"Weerscherm\\Tests\\StationMapperTest::testWithoutRainModule":0,"Weerscherm\\Tests\\StationMapperTest::testUnreachableOutdoorModuleGivesNulls":0,"Weerscherm\\Tests\\StationMapperTest::testUnknownDeviceIdFallsBackToFirstStation":0,"Weerscherm\\Tests\\StationMapperTest::testEmptyDevicesGivesNullsWithoutCrashing":0,"Weerscherm\\Tests\\RainCalculatorTest::testNormalWeek":0,"Weerscherm\\Tests\\RainCalculatorTest::testMissingPreviousDayIsNullAndExcludedFromTotal":0,"Weerscherm\\Tests\\RainCalculatorTest::testMissingTodayFallsBackToSumRain24":0,"Weerscherm\\Tests\\RainCalculatorTest::testMonthBoundaryKeepsPreviousDaysButNotInMonthTotal":0,"Weerscherm\\Tests\\RainCalculatorTest::testDaylightSavingTransitionMapsTimestampsToLocalDates":0,"Weerscherm\\Tests\\RainCalculatorTest::testEmptyBodyGivesNulls":0,"Weerscherm\\Tests\\RainCalculatorTest::testDateBeginIsMinOfFirstOfMonthAndThreeDaysAgo":0,"Weerscherm\\Tests\\CacheTest::testWriteThenReadRoundTrip":0.003,"Weerscherm\\Tests\\CacheTest::testMissingKeyReadsNull":0.004,"Weerscherm\\Tests\\CacheTest::testCorruptFileReadsNull":0,"Weerscherm\\Tests\\CacheTest::testFreshness":0.001,"Weerscherm\\Tests\\CacheTest::testKeyIsSanitised":0,"Weerscherm\\Tests\\CacheTest::testWriteCreatesDirectory":0,"Weerscherm\\Tests\\ForecastMapperTest::testSkipsTodayAndReturnsFiveDays":0,"Weerscherm\\Tests\\ForecastMapperTest::testNullValuesStayNull":0,"Weerscherm\\Tests\\ForecastMapperTest::testShorterResponseGivesFewerDays":0,"Weerscherm\\Tests\\ForecastMapperTest::testMissingTimeArrayGivesEmptyList":0,"Weerscherm\\Tests\\DashboardServiceTest::testHappyPathMatchesContract":0.002,"Weerscherm\\Tests\\DashboardServiceTest::testMeasureIsRequestedForRainModuleFromMidnightOfDateBegin":0.001,"Weerscherm\\Tests\\DashboardServiceTest::testForecastUsesStationLocationUnlessConfigured":0.001,"Weerscherm\\Tests\\DashboardServiceTest::testStationsFailureWithoutCacheGivesNullsAndError":0,"Weerscherm\\Tests\\DashboardServiceTest::testStationsFailureWithCacheServesStaleData":0.001,"Weerscherm\\Tests\\DashboardServiceTest::testAuthFailureGivesNetatmoAuthError":0.001,"Weerscherm\\Tests\\DashboardServiceTest::testMeasureFailureFallsBackToSumRain24":0,"Weerscherm\\Tests\\DashboardServiceTest::testForecastFailureLeavesRestIntact":0.001,"Weerscherm\\Tests\\DashboardServiceTest::testSecondBuildWithinTtlUsesCache":0.001,"Weerscherm\\Tests\\TokenStoreTest::testWriteReadRoundTripAndMode":0,"Weerscherm\\Tests\\TokenStoreTest::testMissingOrInvalidFileReadsNull":0,"Weerscherm\\Tests\\TokenStoreTest::testWithLockReturnsValueAndReleasesAfterException":0,"Weerscherm\\Tests\\TokenStoreTest::testConcurrentProcessesAreSerialised":0.438,"Weerscherm\\Tests\\NetatmoClientTest::testValidTokenIsUsedWithoutRefresh":0.001,"Weerscherm\\Tests\\NetatmoClientTest::testExpiringTokenIsRefreshedAndRotatedRefreshTokenStored":0.001,"Weerscherm\\Tests\\NetatmoClientTest::testFreshlyInitialisedStoreWithoutAccessTokenRefreshesFirst":0.001,"Weerscherm\\Tests\\NetatmoClientTest::testUnauthorizedResponseTriggersOneRefreshAndRetry":0.001,"Weerscherm\\Tests\\NetatmoClientTest::testSecondUnauthorizedResponseIsAuthError":0.001,"Weerscherm\\Tests\\NetatmoClientTest::testInvalidGrantIsAuthError":0,"Weerscherm\\Tests\\NetatmoClientTest::testMissingTokenFileIsAuthError":0,"Weerscherm\\Tests\\NetatmoClientTest::testServerErrorIsUpstreamError":0,"Weerscherm\\Tests\\NetatmoClientTest::testRefreshServerErrorIsUpstreamNotAuth":0.001,"Weerscherm\\Tests\\NetatmoClientTest::testConcurrentClientsShareOneRefresh":0.001,"Weerscherm\\Tests\\NetatmoClientTest::testRejectedTokenAlreadyReplacedByOtherProcessIsReusedWithoutRefresh":0.001,"Weerscherm\\Tests\\NetatmoClientTest::testGetMeasureQuery":0,"Weerscherm\\Tests\\OpenMeteoClientTest::testRequestsSixDaysWithAllDailyVariables":0,"Weerscherm\\Tests\\OpenMeteoClientTest::testErrorStatusIsUpstreamException":0,"Weerscherm\\Tests\\OpenMeteoClientTest::testMissingDailyIsUpstreamException":0}}
+31 -15
View File
@@ -92,25 +92,41 @@ De bestanden staan in `orbstack/divers/weerscherm/` (Dockerfile, compose) en `or
## Deploy (productie) ## Deploy (productie)
Productie-URL: `https://homedisplay.bahne-drei.de/` Productie-URL: `https://homedisplay.bahne-drei.de/` op `pensare-server`, beheerd met Ansible
(`infra-ansible-pensare`, app `weerscherm` in `inventories/production/host_vars/pensare-server.yml`).
- Git op de self-hosted Gitea, squash-and-merge naar `main`, deploy via DeployPad. - Code komt uit de publieke Gitea-repo `https://git.pensare.nl/theo/weerscherm.git` (branch `main`);
- Document root is `public/`. `src/`, `storage/`, `config.php` en `bin/` zijn dan niet via HTTP bereikbaar. de role cloont of pullt als Linux-user `weerscherm`.
- `storage/` moet deploys overleven: maak er in DeployPad een gedeelde map van (shared folder) of zet - `config.php` wordt gerenderd uit `roles/webapp/templates/weerscherm.config.php.j2` met de Netatmo-gegevens
`storage_path` in `config.php` naar een map buiten de release-map, bijvoorbeeld `/var/www/weerscherm-storage`. uit de vault (`vault_weerscherm_netatmo_client_id`, `vault_weerscherm_netatmo_client_secret`).
De map moet schrijfbaar zijn voor de webserver-gebruiker (`www-data`). - `storage_path` is `/var/www/weerscherm-storage` (www-data, 0770), buiten de release-map, zodat de token
- `config.php` is per omgeving en staat niet in git; zet hem ook in de gedeelde map en symlink, of maak hem en de cache deploys overleven.
eenmalig aan in de release-root. - Document root is `public/`; `src/`, `bin/` en `config.php` zijn niet via HTTP bereikbaar.
- `composer install` is op de server niet nodig: `src/autoload.php` laadt de klassen zelf als `vendor/` ontbreekt. - `composer install` is op de server niet nodig: `src/autoload.php` laadt de klassen zelf.
- HTTPS is vereist voor de service worker en "Zet op beginscherm". - SSL via certbot in dezelfde playbook-run.
- Na de eerste deploy: `php bin/netatmo-init.php '<refresh_token>'` op de server, en controleer
`https://homedisplay.bahne-drei.de/api/data.php` op `"errors": []`.
- De app staat bewust zonder login. Kies een niet-voor-de-hand-liggend (sub)domein; `robots.txt` en
`X-Robots-Tag: noindex` houden zoekmachines buiten de deur.
Nieuwe versie van de frontend? Verhoog `VERSION` in `public/sw.js`; de app herlaadt zichzelf bij `controllerchange` Nieuwe versie uitrollen:
```bash
git push origin main
cd /Volumes/development/sites/pensare/infra-ansible-pensare
ansible-playbook playbooks/deploy-app.yml -e app=weerscherm
```
Verhoog bij frontend-wijzigingen `VERSION` in `public/sw.js`; de app herlaadt zichzelf bij `controllerchange`
en in elk geval dagelijks rond 04:00. en in elk geval dagelijks rond 04:00.
Token opnieuw koppelen (melding "Netatmo-koppeling verlopen"):
```bash
ssh weerscherm@65.108.40.86 'cd /var/www/weerscherm && sudo -u www-data php8.3 bin/netatmo-init.php "<refresh_token>"'
```
Lukt `sudo -u www-data` niet als `weerscherm`, doe het dan als `deploy` met `sudo`. Controleer daarna
`https://homedisplay.bahne-drei.de/api/data.php` op `"errors": []`.
- De app staat bewust zonder login. `robots.txt` en `X-Robots-Tag: noindex` houden zoekmachines buiten de deur.
## iPad-instellingen ## iPad-instellingen
1. Open de URL in Safari, tik op Delen → **Zet op beginscherm**. Start de app daarna altijd vanaf het beginscherm 1. Open de URL in Safari, tik op Delen → **Zet op beginscherm**. Start de app daarna altijd vanaf het beginscherm