diff --git a/bun.lock b/bun.lock index 5510edf..21f7cf6 100644 --- a/bun.lock +++ b/bun.lock @@ -9,6 +9,7 @@ "better-sqlite3": "^11.0.0", "hono": "^4.11.3", "pg": "^8.16.3", + "tplink-smarthome-api": "^5.0.0", }, "devDependencies": { "@types/better-sqlite3": "^7.6.11", @@ -20,6 +21,8 @@ }, }, "packages": { + "@commander-js/extra-typings": ["@commander-js/extra-typings@11.1.0", "", { "peerDependencies": { "commander": "11.1.x" } }, "sha512-GuvZ38d23H+7Tz2C9DhzCepivsOsky03s5NI+KCy7ke1FNUvsJ2oO47scQ9YaGGhgjgNW5OYYNSADmbjcSoIhw=="], + "@types/better-sqlite3": ["@types/better-sqlite3@7.6.13", "", { "dependencies": { "@types/node": "*" } }, "sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA=="], "@types/bun": ["@types/bun@1.3.5", "", { "dependencies": { "bun-types": "1.3.5" } }, "sha512-RnygCqNrd3srIPEWBd5LFeUYG7plCoH2Yw9WaZGyNmdTEei+gWaHqydbaIRkIkcbXwhBT94q78QljxN0Sk838w=="], @@ -42,6 +45,8 @@ "chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="], + "commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="], + "decompress-response": ["decompress-response@6.0.0", "", { "dependencies": { "mimic-response": "^3.1.0" } }, "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ=="], "deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="], @@ -66,6 +71,20 @@ "ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="], + "lodash.castarray": ["lodash.castarray@4.4.0", "", {}, "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q=="], + + "lodash.clone": ["lodash.clone@4.5.0", "", {}, "sha512-GhrVeweiTD6uTmmn5hV/lzgCQhccwReIVRLHp7LT4SopOjqEZ5BbX8b5WWEtAKasjmy8hR7ZPwsYlxRCku5odg=="], + + "lodash.defaultto": ["lodash.defaultto@4.14.0", "", {}, "sha512-G6tizqH6rg4P5j32Wy4Z3ZIip7OfG8YWWlPFzUFGcYStH1Ld0l1tWs6NevEQNEDnO1M3NZYjuHuraaFSN5WqeQ=="], + + "lodash.get": ["lodash.get@4.4.2", "", {}, "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="], + + "lodash.groupby": ["lodash.groupby@4.6.0", "", {}, "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw=="], + + "lodash.isequal": ["lodash.isequal@4.5.0", "", {}, "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="], + + "loglevel": ["loglevel@1.9.2", "", {}, "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg=="], + "mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="], "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], @@ -108,6 +127,8 @@ "prebuild-install": ["prebuild-install@7.1.3", "", { "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^2.0.0", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, "bin": { "prebuild-install": "bin.js" } }, "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug=="], + "promise-queue": ["promise-queue@2.2.5", "", {}, "sha512-p/iXrPSVfnqPft24ZdNNLECw/UrtLTpT3jpAAMzl/o5/rDsGCPo3/CQS2611flL6LkoEJ3oQZw7C8Q80ZISXRQ=="], + "pump": ["pump@3.0.3", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA=="], "rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="], @@ -132,6 +153,10 @@ "tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="], + "tplink-smarthome-api": ["tplink-smarthome-api@5.0.0", "", { "dependencies": { "@commander-js/extra-typings": "~11.1.0", "commander": "~11.1.0", "lodash.castarray": "^4.4.0", "lodash.clone": "^4.5.0", "lodash.defaultto": "^4.14.0", "lodash.get": "^4.4.2", "lodash.groupby": "^4.6.0", "lodash.isequal": "^4.5.0", "loglevel": "^1.8.1", "promise-queue": "^2.2.5", "tplink-smarthome-crypto": "^4.0.0" }, "bin": { "tplink-smarthome-api": "lib/cli.js" } }, "sha512-AJjIt4lD1tD1FHXAYu7t0kg8A7cEYFpC3xQdDCJYm89Hz26Drvo1QgaQQ7nk3XarT+O8RTBGkP/fmPutMPvFyQ=="], + + "tplink-smarthome-crypto": ["tplink-smarthome-crypto@4.0.0", "", {}, "sha512-sD8Qnh4ZRV8D7JK6nIxWum4Q3oEB53WUzmQSr7X6QlXAMy8fmf+u8HJh/FxVg/HaF7sfLbQIPOoNgd/dnNRDxQ=="], + "tunnel-agent": ["tunnel-agent@0.6.0", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w=="], "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], diff --git a/config.demo.json b/config.demo.json new file mode 100644 index 0000000..72fa054 --- /dev/null +++ b/config.demo.json @@ -0,0 +1,39 @@ +{ + "$schema": "https://veridian.runfoo.run/schemas/edge-config.json", + "version": "2.0", + "facilityId": "demo-facility-01", + "edgeId": "macbook-air-demo", + "server": { + "url": "https://veridian.runfoo.run/api", + "apiKey": "edge-demo-key", + "heartbeatIntervalSec": 60, + "syncIntervalSec": 300 + }, + "sensorpush": { + "email": "demo@veridian.runfoo.run", + "password": "CHANGE_ME" + }, + "alerts": { + "enabled": true, + "cooldownMinutes": 15, + "thresholds": [ + { + "sensor": "*", + "metric": "temperature", + "min": 60, + "max": 85 + } + ] + }, + "storage": { + "retentionDays": 30, + "maxRows": 100000 + }, + "dashboard": { + "enabled": true, + "port": 3030 + }, + "sensorMappings": [], + "pollingIntervalSec": 60, + "logLevel": "info" +} \ No newline at end of file diff --git a/package.json b/package.json index ce34e51..d727bb7 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ "@types/pg": "^8.16.0", "better-sqlite3": "^11.0.0", "hono": "^4.11.3", - "pg": "^8.16.3" + "pg": "^8.16.3", + "tplink-smarthome-api": "^5.0.0" }, "optionalDependencies": { "pigpio": "^3.3.1" diff --git a/src/buffer.ts b/src/buffer.ts index 2821285..7b1aaec 100644 --- a/src/buffer.ts +++ b/src/buffer.ts @@ -5,19 +5,19 @@ * Flushes to backend when connection is restored. */ -import Database from 'better-sqlite3'; +import { Database } from 'bun:sqlite'; import { join } from 'path'; import type { Reading } from './veridian'; const DB_PATH = join(process.env.HOME || '~', '.local/share/veridian-edge/buffer.db'); export class BufferManager { - private db: Database.Database; + private db: Database; private maxRows: number; constructor(maxRows: number = 10000) { this.maxRows = maxRows; - this.db = new Database(DB_PATH); + this.db = new Database(DB_PATH, { create: true }); this.init(); }