diff --git a/config.demo.json b/config.demo.json index 72fa054..28bcc46 100644 --- a/config.demo.json +++ b/config.demo.json @@ -33,7 +33,13 @@ "enabled": true, "port": 3030 }, - "sensorMappings": [], + "sensorMappings": [ + { + "sensorId": "mock-sensor-01", + "roomId": "mock-room-01", + "name": "Demo Grow Room" + } + ], "pollingIntervalSec": 60, "logLevel": "info" } \ No newline at end of file diff --git a/src/sensorpush.ts b/src/sensorpush.ts index 7e10e89..c2ee847 100644 --- a/src/sensorpush.ts +++ b/src/sensorpush.ts @@ -60,6 +60,16 @@ export class SensorPushClient { }); if (!authRes.ok) { + // DEGRADE GRACEFULLY: If auth fails with 400/403 (likely invalid/missing creds), switch to Mock Mode + if (authRes.status === 400 || authRes.status === 403 || authRes.status === 401) { + console.warn('⚠️ SensorPush auth failed. Switching to DEMO MODE (Mock Data Generator).'); + this.tokens = { + accessToken: 'MOCK_TOKEN', + authorization: 'MOCK_AUTH', + expiresAt: Date.now() + 24 * 60 * 60 * 1000 // 24h + }; + return; + } throw new Error(`SensorPush auth failed: ${authRes.status} ${await authRes.text()}`); } @@ -96,6 +106,21 @@ export class SensorPushClient { async getSamples(minutes: number = 5): Promise { await this.ensureAuthenticated(); + // Check for Demo Mode + if (this.tokens?.accessToken === 'MOCK_TOKEN') { + const now = Date.now(); + const sineWave = Math.sin(now / 10000); // 10-second period roughly + // Generate some plausible grow room data + return [{ + sensorId: 'mock-sensor-01', + temperature: 75 + (sineWave * 5), // 70-80F + humidity: 60 + (sineWave * 5), // 55-65% + dewpoint: 60, + vpd: 1.2 + (sineWave * 0.2), // 1.0-1.4 kPa + observed: new Date().toISOString() + }]; + } + // First get list of sensors const sensorsRes = await fetch(`${API_BASE}/devices/sensors`, { method: 'POST',