diff --git a/app/package-lock.json b/app/package-lock.json index a6bd2ea..d6842f8 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0", "dependencies": { "@heroicons/react": "^2.0.18", - "@material-tailwind/react": "^2.1.2", + "@material-tailwind/react": "^2.1.8", "@reduxjs/toolkit": "^2.0.1", "@types/uuid": "^9.0.5", "framer-motion": "^10.16.4", diff --git a/app/package.json b/app/package.json index 2a62ef6..1d27cf2 100644 --- a/app/package.json +++ b/app/package.json @@ -14,7 +14,7 @@ }, "dependencies": { "@heroicons/react": "^2.0.18", - "@material-tailwind/react": "^2.1.2", + "@material-tailwind/react": "^2.1.8", "@reduxjs/toolkit": "^2.0.1", "@types/uuid": "^9.0.5", "framer-motion": "^10.16.4", diff --git a/app/src/components/animations/AnimationCard.tsx b/app/src/components/animations/AnimationCard.tsx index a9c9439..c3f8748 100644 --- a/app/src/components/animations/AnimationCard.tsx +++ b/app/src/components/animations/AnimationCard.tsx @@ -13,7 +13,7 @@ type AnimationCardProps = { export function AnimationCard(props: AnimationCardProps) { const { animation, ...rest } = props - switch (animation.details.animationType) { + switch (animation.details.type) { case AnimationType.BLINK: { return ( { const newBlinkOpts: BlinkAnimation = { - animationType: AnimationType.BLINK, + type: AnimationType.BLINK, onColor: rgbToRgbw(convert.hex.rgb(opts.onColor)), offColor: rgbToRgbw(convert.hex.rgb(opts.offColor)), onDuration: parseInt(opts.onDuration), diff --git a/app/src/components/animations/EditBounceAnimation.tsx b/app/src/components/animations/EditBounceAnimation.tsx index ec88686..ad95327 100644 --- a/app/src/components/animations/EditBounceAnimation.tsx +++ b/app/src/components/animations/EditBounceAnimation.tsx @@ -1,11 +1,11 @@ -import { useEffect, useState } from "react" -import type { ChangeEvent } from "react" -import { AnimationType, BounceAnimation } from "engine/types" -import { rgbToRgbw, rgbwToRgb } from "engine/utils" import { Button, Input } from "@material-tailwind/react" import convert from "color-convert" -import { ColorPickerInput } from "../ColorPickerInput" +import { AnimationType, BounceAnimation } from "engine/types" +import { rgbToRgbw, rgbwToRgb } from "engine/utils" +import type { ChangeEvent } from "react" +import { useEffect, useState } from "react" import { IAnimationNew } from "../../api/lampApi" +import { ColorPickerInput } from "../ColorPickerInput" type BounceFormProps = { name?: string @@ -96,7 +96,7 @@ export function EditBounceAnimation(props: BounceFormProps) { const handleAdd = () => { const bounceOpts: BounceAnimation = { - animationType: AnimationType.BOUNCE, + type: AnimationType.BOUNCE, color: rgbToRgbw(convert.hex.rgb(opts.color)), speed: parseInt(opts.speed), endLed: parseInt(opts.endLed), diff --git a/app/src/components/animations/EditSolidAnimation.tsx b/app/src/components/animations/EditSolidAnimation.tsx index fd5770f..0c07d7a 100644 --- a/app/src/components/animations/EditSolidAnimation.tsx +++ b/app/src/components/animations/EditSolidAnimation.tsx @@ -1,11 +1,11 @@ -import { useEffect, useState } from "react" -import type { ChangeEvent } from "react" -import { AnimationType, SolidAnimation } from "engine/types" -import { rgbToRgbw, rgbwToRgb } from "engine/utils" import { Button, Input } from "@material-tailwind/react" import convert from "color-convert" -import { ColorPickerInput } from "../ColorPickerInput" +import { AnimationType, SolidAnimation } from "engine/types" +import { rgbToRgbw, rgbwToRgb } from "engine/utils" +import type { ChangeEvent } from "react" +import { useEffect, useState } from "react" import { IAnimationNew } from "../../api/lampApi" +import { ColorPickerInput } from "../ColorPickerInput" type EditSolidAnimationProps = { name?: string @@ -85,7 +85,7 @@ export function EditSolidAnimation(props: EditSolidAnimationProps) { const handleAdd = () => { const solidOpts: SolidAnimation = { - animationType: AnimationType.SOLID, + type: AnimationType.SOLID, color: rgbToRgbw(convert.hex.rgb(opts.color)), endLed: parseInt(opts.endLed), startLed: parseInt(opts.startLed), diff --git a/app/src/routes/Animations.tsx b/app/src/routes/Animations.tsx index bb53bb1..decf4d6 100644 --- a/app/src/routes/Animations.tsx +++ b/app/src/routes/Animations.tsx @@ -1,4 +1,10 @@ -import { Button, List, ListItem, Typography } from "@material-tailwind/react" +import { + Button, + List, + ListItem, + ListItemSuffix, + Typography, +} from "@material-tailwind/react" import { useNavigate } from "react-router-dom" import { useGetAnimationsQuery, @@ -34,11 +40,11 @@ export default function Config() {
- Type: {animation.details.animationType} + Type: {animation.details.type} {animation.name}
- {/* + - */} +
))} diff --git a/app/src/routes/DeviceAnimations.tsx b/app/src/routes/DeviceAnimations.tsx index 66f3b64..d943892 100644 --- a/app/src/routes/DeviceAnimations.tsx +++ b/app/src/routes/DeviceAnimations.tsx @@ -34,7 +34,6 @@ export const DeviceAnimations = () => { const throttledColor = useThrottle(solidColor, 100) useEffect(() => { if (throttledColor && device) { - // TODO: Batch? setSolidColorMutation({ lampGuid: device.guid, color: throttledColor, diff --git a/app/src/routes/Devices.tsx b/app/src/routes/Devices.tsx index cca1b0c..50aea34 100644 --- a/app/src/routes/Devices.tsx +++ b/app/src/routes/Devices.tsx @@ -48,20 +48,18 @@ export default function DeviceList() { {lamp.currentIP}: {lamp.name}{" "} - {/* */} + ))} - diff --git a/engine/animations/rainbow.ts b/engine/animations/rainbow.ts index f0882fc..1b8b0f5 100644 --- a/engine/animations/rainbow.ts +++ b/engine/animations/rainbow.ts @@ -61,7 +61,12 @@ export function rainbow(opts: RainbowOptions): ColorGeneratorFunc { const hueChangePerTick = 0.01 // Sort, just incase. - const sortedLeds = [...leds].sort() + const sortedLeds = [...leds].sort((a, b) => { + if (a > b) return 1 + else if (a < b) return -1 + return 0 + }) + console.log("sorted leds: ", sortedLeds) let currentHueValue = 0 let currentValues: LedMap = sortedLeds.reduce((acc, l) => { diff --git a/engine/index.ts b/engine/index.ts index a9963b4..d5516be 100644 --- a/engine/index.ts +++ b/engine/index.ts @@ -16,7 +16,7 @@ function getLeds( numOfLeds: number ) { const first = start ? start : 0 - const last = Math.min(numOfLeds - 1, end ? end : numOfLeds - 1) + const last = Math.min(numOfLeds, end ? end : numOfLeds) const maxList = Array.from(Array(numOfLeds).keys()) return maxList.slice(first, last) } @@ -165,7 +165,7 @@ export class ColorEngine { static buildAnimation(animationDef: AnimationItem, numOfLeds: number) { const leds = getLeds(animationDef.startLed, animationDef.endLed, numOfLeds) - switch (animationDef.animationType) { + switch (animationDef.type) { case AnimationType.BLINK: { return Animations.blink({ leds, diff --git a/engine/types.ts b/engine/types.ts index 495ae44..395c49c 100644 --- a/engine/types.ts +++ b/engine/types.ts @@ -21,13 +21,13 @@ export enum AnimationType { } export interface Animation { - animationType: AnimationType + type: AnimationType startLed?: number endLed?: number } export interface BlinkAnimation extends Animation { - animationType: AnimationType.BLINK + type: AnimationType.BLINK onColor: RGBW onDuration: number offColor: RGBW @@ -36,18 +36,18 @@ export interface BlinkAnimation extends Animation { } export interface BounceAnimation extends Animation { - animationType: AnimationType.BOUNCE + type: AnimationType.BOUNCE color: RGBW speed: number } export interface SolidAnimation extends Animation { - animationType: AnimationType.SOLID + type: AnimationType.SOLID color: RGBW } export interface RainbowAnimation extends Animation { - animationType: AnimationType.RAINBOW + type: AnimationType.RAINBOW transitionMs: number } diff --git a/server/data/animations.yml b/server/data/animations.yml new file mode 100644 index 0000000..b4699b3 --- /dev/null +++ b/server/data/animations.yml @@ -0,0 +1,17 @@ +animations: + - guid: rain-bow + name: Rainbow + details: + type: RAINBOW + startLed: ~ + endLed: ~ + transitionMs: 50 + + - guid: red-rider + name: Red Rider + details: + type: BOUNCE + startLed: ~ + endLed: ~ + color: [255, 0, 0, 0] + speed: 50 diff --git a/server/data/devices.yml b/server/data/devices.yml new file mode 100644 index 0000000..5421a5a --- /dev/null +++ b/server/data/devices.yml @@ -0,0 +1,19 @@ +devices: + - guid: 6ea1f96e-dc3b-4599-9b3e-14573fabbe3b + currentIP: 192.168.12.199 + name: New Lamp 199 + macAddress: 28:cd:c1:0f:82:90 + numOfLeds: 20 + description: "" + - guid: 14bcd4fc-ad00-47f0-ac3c-d89fcecd4c31 + currentIP: 192.168.12.202 + name: New Lamp 202 + macAddress: 28:cd:c1:0f:7e:c1 + numOfLeds: 60 + description: "" + - guid: db79a99b-358a-48b7-b24d-4d015828124c + currentIP: 192.168.12.206 + name: New Lamp 206 + macAddress: 28:cd:c1:0f:93:da + numOfLeds: 60 + description: "" diff --git a/server/package-lock.json b/server/package-lock.json index cf92ec0..7e41903 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -18,12 +18,10 @@ "fastify": "^4.23.2", "fastify-plugin": "^4.5.1", "http-status-codes": "^2.3.0", - "mariadb": "^3.2.2", - "mongoose": "^7.6.2", - "sequelize": "^6.33.0", "socket.io": "^4.7.2", "uuid": "^9.0.1", - "ws": "^8.14.2" + "ws": "^8.14.2", + "yaml": "^2.3.4" }, "devDependencies": { "@tsconfig/node20": "^20.1.2", @@ -219,14 +217,6 @@ "@types/node": "*" } }, - "node_modules/@types/debug": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.10.tgz", - "integrity": "sha512-tOSCru6s732pofZ+sMv9o4o3Zc+Sa8l3bxd/tweTQudFn06vAzb13ZX46Zi6m6EJ+RUbRTHvgQJ1gBtSgkaUYA==", - "dependencies": { - "@types/ms": "*" - } - }, "node_modules/@types/express": { "version": "4.17.18", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.18.tgz", @@ -251,11 +241,6 @@ "@types/send": "*" } }, - "node_modules/@types/geojson": { - "version": "7946.0.12", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.12.tgz", - "integrity": "sha512-uK2z1ZHJyC0nQRbuovXFt4mzXDwf27vQeUWNhfKGwRcWW429GOhP8HxUHlM6TLH4bzmlv/HlEjpvJh3JfmGsAA==" - }, "node_modules/@types/http-errors": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.2.tgz", @@ -268,11 +253,6 @@ "integrity": "sha512-Ys+/St+2VF4+xuY6+kDIXGxbNRO0mesVg0bbxEfB97Od1Vjpjx9KD1qxs64Gcb3CWPirk9Xe+PT4YiiHQ9T+eg==", "dev": true }, - "node_modules/@types/ms": { - "version": "0.7.33", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.33.tgz", - "integrity": "sha512-AuHIyzR5Hea7ij0P9q7vx7xu4z0C28ucwjAZC0ja7JhINyCnOw8/DnvAPQQ9TfOlCtZAmCERKQX9+o1mgQhuOQ==" - }, "node_modules/@types/node": { "version": "20.8.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.0.tgz", @@ -317,11 +297,6 @@ "integrity": "sha512-xfHdwa1FMJ082prjSJpoEI57GZITiQz10r3vEJCHa2khEFQjKy91aWKz6+zybzssCvXUwE1LQWgWVwZ4nYUvHQ==", "dev": true }, - "node_modules/@types/validator": { - "version": "13.11.5", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.5.tgz", - "integrity": "sha512-xW4qsT4UIYILu+7ZrBnfQdBYniZrMLYYK3wN9M/NdeIHgBN5pZI2/8Q7UfdWIcr5RLJv/OGENsx91JIpUUoC7Q==" - }, "node_modules/@types/webidl-conversions": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.1.tgz", @@ -681,14 +656,6 @@ "ms": "2.0.0" } }, - "node_modules/denque": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", - "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", - "engines": { - "node": ">=0.10" - } - }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -726,11 +693,6 @@ "url": "https://github.com/motdotla/dotenv?sponsor=1" } }, - "node_modules/dottie": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.6.tgz", - "integrity": "sha512-iGCHkfUc5kFekGiqhe8B/mdaurD+lakO9txNnTvKtA6PISrw86LgqHvRzWYPyoE2Ph5aMIrCw9/uko6XHTKCwA==" - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -1187,14 +1149,6 @@ } ] }, - "node_modules/inflection": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.4.tgz", - "integrity": "sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==", - "engines": [ - "node >= 0.4.0" - ] - }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -1212,7 +1166,9 @@ "node_modules/ip": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", + "optional": true, + "peer": true }, "node_modules/ipaddr.js": { "version": "1.9.1", @@ -1247,14 +1203,6 @@ "node": ">=6" } }, - "node_modules/kareem": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz", - "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==", - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/light-my-request": { "version": "5.11.0", "resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-5.11.0.tgz", @@ -1265,11 +1213,6 @@ "set-cookie-parser": "^2.4.1" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -1287,45 +1230,6 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, - "node_modules/mariadb": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/mariadb/-/mariadb-3.2.2.tgz", - "integrity": "sha512-9ClJCFsLcK7WnPXVxuKGd7p0CBvNch3i5nwAf1HEqERj7RV60DG/0dJu4DfO33gpYQd9Cr4jq17O76/2VjSbkg==", - "dependencies": { - "@types/geojson": "^7946.0.10", - "@types/node": "^17.0.45", - "denque": "^2.1.0", - "iconv-lite": "^0.6.3", - "lru-cache": "^10.0.1" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/mariadb/node_modules/@types/node": { - "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", - "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" - }, - "node_modules/mariadb/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mariadb/node_modules/lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", - "engines": { - "node": "14 || >=16.14" - } - }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -1409,25 +1313,6 @@ "obliterator": "^2.0.1" } }, - "node_modules/moment": { - "version": "2.29.4", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", - "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", - "engines": { - "node": "*" - } - }, - "node_modules/moment-timezone": { - "version": "0.5.43", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.43.tgz", - "integrity": "sha512-72j3aNyuIsDxdF1i7CEgV2FfxM1r6aaqJyLB2vwb33mXYyoyLly+F1zbWqhA3/bVIoJ4szlUoMbUnVdid32NUQ==", - "dependencies": { - "moment": "^2.29.4" - }, - "engines": { - "node": "*" - } - }, "node_modules/mongodb": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.1.0.tgz", @@ -1513,120 +1398,6 @@ "node": ">=12" } }, - "node_modules/mongoose": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-7.6.2.tgz", - "integrity": "sha512-OVx6RWbfNOzBbfTvXoOkgZmaizdXDU/B/KbBjietXQoInSg/OSULjOavXJzL51XWFkbefqkOvbeE07DfvW6FkQ==", - "dependencies": { - "bson": "^5.5.0", - "kareem": "2.5.1", - "mongodb": "5.9.0", - "mpath": "0.9.0", - "mquery": "5.0.0", - "ms": "2.1.3", - "sift": "16.0.1" - }, - "engines": { - "node": ">=14.20.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mongoose" - } - }, - "node_modules/mongoose/node_modules/bson": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-5.5.0.tgz", - "integrity": "sha512-B+QB4YmDx9RStKv8LLSl/aVIEV3nYJc3cJNNTK2Cd1TL+7P+cNpw9mAPeCgc5K+j01Dv6sxUzcITXDx7ZU3F0w==", - "engines": { - "node": ">=14.20.1" - } - }, - "node_modules/mongoose/node_modules/mongodb": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.9.0.tgz", - "integrity": "sha512-g+GCMHN1CoRUA+wb1Agv0TI4YTSiWr42B5ulkiAfLLHitGK1R+PkSAf3Lr5rPZwi/3F04LiaZEW0Kxro9Fi2TA==", - "dependencies": { - "bson": "^5.5.0", - "mongodb-connection-string-url": "^2.6.0", - "socks": "^2.7.1" - }, - "engines": { - "node": ">=14.20.1" - }, - "optionalDependencies": { - "@mongodb-js/saslprep": "^1.1.0" - }, - "peerDependencies": { - "@aws-sdk/credential-providers": "^3.188.0", - "@mongodb-js/zstd": "^1.0.0", - "kerberos": "^1.0.0 || ^2.0.0", - "mongodb-client-encryption": ">=2.3.0 <3", - "snappy": "^7.2.2" - }, - "peerDependenciesMeta": { - "@aws-sdk/credential-providers": { - "optional": true - }, - "@mongodb-js/zstd": { - "optional": true - }, - "kerberos": { - "optional": true - }, - "mongodb-client-encryption": { - "optional": true - }, - "snappy": { - "optional": true - } - } - }, - "node_modules/mongoose/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/mpath": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", - "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mquery": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", - "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", - "dependencies": { - "debug": "4.x" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/mquery/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/mquery/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -1701,11 +1472,6 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, - "node_modules/pg-connection-string": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", - "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" - }, "node_modules/pino": { "version": "8.15.6", "resolved": "https://registry.npmjs.org/pino/-/pino-8.15.6.tgz", @@ -1887,11 +1653,6 @@ "node": ">=4" } }, - "node_modules/retry-as-promised": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-7.0.4.tgz", - "integrity": "sha512-XgmCoxKWkDofwH8WddD0w85ZfqYz+ZHlr5yo+3YUCfycWawU56T5ckWXsScsj5B8tqUcIG67DxXByo3VUgiAdA==" - }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -1993,104 +1754,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, - "node_modules/sequelize": { - "version": "6.33.0", - "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.33.0.tgz", - "integrity": "sha512-GkeCbqgaIcpyZ1EyXrDNIwktbfMldHAGOVXHGM4x8bxGSRAOql5htDWofPvwpfL/FoZ59CaFmfO3Mosv1lDbQw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/sequelize" - } - ], - "dependencies": { - "@types/debug": "^4.1.8", - "@types/validator": "^13.7.17", - "debug": "^4.3.4", - "dottie": "^2.0.6", - "inflection": "^1.13.4", - "lodash": "^4.17.21", - "moment": "^2.29.4", - "moment-timezone": "^0.5.43", - "pg-connection-string": "^2.6.1", - "retry-as-promised": "^7.0.4", - "semver": "^7.5.4", - "sequelize-pool": "^7.1.0", - "toposort-class": "^1.0.1", - "uuid": "^8.3.2", - "validator": "^13.9.0", - "wkx": "^0.5.0" - }, - "engines": { - "node": ">=10.0.0" - }, - "peerDependenciesMeta": { - "ibm_db": { - "optional": true - }, - "mariadb": { - "optional": true - }, - "mysql2": { - "optional": true - }, - "oracledb": { - "optional": true - }, - "pg": { - "optional": true - }, - "pg-hstore": { - "optional": true - }, - "snowflake-sdk": { - "optional": true - }, - "sqlite3": { - "optional": true - }, - "tedious": { - "optional": true - } - } - }, - "node_modules/sequelize-pool": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-7.1.0.tgz", - "integrity": "sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/sequelize/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/sequelize/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/sequelize/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", @@ -2128,15 +1791,12 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/sift": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz", - "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==" - }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "optional": true, + "peer": true, "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" @@ -2245,6 +1905,8 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "optional": true, + "peer": true, "dependencies": { "ip": "^2.0.0", "smart-buffer": "^4.2.0" @@ -2338,11 +2000,6 @@ "node": ">=0.6" } }, - "node_modules/toposort-class": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", - "integrity": "sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==" - }, "node_modules/ts-node": { "version": "10.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", @@ -2478,14 +2135,6 @@ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, - "node_modules/validator": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", - "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", - "engines": { - "node": ">= 0.10" - } - }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -2494,14 +2143,6 @@ "node": ">= 0.8" } }, - "node_modules/wkx": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz", - "integrity": "sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -2532,6 +2173,14 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "node_modules/yaml": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "engines": { + "node": ">= 14" + } + }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/server/package.json b/server/package.json index 0da7145..cc5aa27 100644 --- a/server/package.json +++ b/server/package.json @@ -20,12 +20,10 @@ "fastify": "^4.23.2", "fastify-plugin": "^4.5.1", "http-status-codes": "^2.3.0", - "mariadb": "^3.2.2", - "mongoose": "^7.6.2", - "sequelize": "^6.33.0", "socket.io": "^4.7.2", "uuid": "^9.0.1", - "ws": "^8.14.2" + "ws": "^8.14.2", + "yaml": "^2.3.4" }, "devDependencies": { "@tsconfig/node20": "^20.1.2", diff --git a/server/src/controllers/animations.ts b/server/src/controllers/animations.ts index 26a6a8f..380c6e9 100644 --- a/server/src/controllers/animations.ts +++ b/server/src/controllers/animations.ts @@ -2,7 +2,7 @@ import { FastifyReply, FastifyRequest } from "fastify" import { StatusCodes } from "http-status-codes" import { v4 as uuidv4 } from "uuid" -import { AnimationModel } from "../models/animation" +import * as Animation from "../models/animation" import type { IAnimation } from "../models/animation" import { createError } from "../utils/errors" import type { ApiResponse } from "../types" @@ -10,9 +10,9 @@ import type { ApiResponse } from "../types" export async function createAnimation( request: FastifyRequest, reply: FastifyReply -): ApiResponse { +): ApiResponse { const animationParts = request.body as Omit - const animation = await AnimationModel.create({ + const animation = await Animation.createAnimation({ ...animationParts, guid: uuidv4(), }) @@ -24,24 +24,22 @@ export async function getAnimations( _request: FastifyRequest, _reply: FastifyReply ): ApiResponse { - const animations = await AnimationModel.findAll() + const animations = await Animation.getAnimations() return animations } export async function removeAnimation( request: FastifyRequest, reply: FastifyReply -): ApiResponse { +): ApiResponse { const { animationGuid: guid } = request.params as { animationGuid: string } - const deletedCount = await AnimationModel.destroy({ where: { guid } }) + const successful = await Animation.deleteAnimation(guid) - if (deletedCount < 1) { + if (successful) { return createError( reply, `Couldn't find animation with guid: ${guid}`, StatusCodes.NOT_FOUND ) } - - return deletedCount } diff --git a/server/src/controllers/devices.ts b/server/src/controllers/devices.ts index 2123168..9079e1a 100644 --- a/server/src/controllers/devices.ts +++ b/server/src/controllers/devices.ts @@ -1,8 +1,9 @@ -import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify" +import { FastifyReply, FastifyRequest } from "fastify" import { StatusCodes } from "http-status-codes" -import { DeviceModel, IDevice } from "../models/device" +import { IDevice } from "../models/device" import { createError } from "../utils/errors" import type { ApiResponse } from "../types" +import { v4 as uuidv4 } from "uuid" import { ColorEngine } from "engine" import { Scanner, @@ -10,12 +11,9 @@ import { PingResponse, ColorCommunicator, } from "../utils/colorPusher" -import { AnimationModel } from "../models/animation" +import * as Animation from "../models/animation" +import * as Device from "../models/device" import { AnimationItem, RGBW } from "engine/types" -import { Op } from "sequelize" - -console.log("SETTING UP ROUTE:") -console.log("... DEVICES") const engines: Map = new Map() const colorCommunicator = new ColorCommunicator() @@ -29,10 +27,9 @@ export async function getDevices( request: FastifyRequest, reply: FastifyReply ): ApiResponse { - const lamps = await DeviceModel.findAll() - + const lamps = await Device.getDevices() return lamps.map((l) => ({ - ...l.toJSON(), + ...l, animationGuids: engines.get(l.guid)?.getAnimationGuids() || [], colors: engines.get(l.guid)?.getColors(), })) @@ -52,10 +49,10 @@ export async function scanForDevices( await addNewDevices(baseIp, results) } - const lamps = await DeviceModel.findAll() + const lamps = await Device.getDevices() return lamps.map((l) => ({ - ...l.toJSON(), + ...l, animationGuids: engines.get(l.guid)?.getAnimationGuids() || [], colors: engines.get(l.guid)?.getColors(), })) @@ -67,76 +64,60 @@ export async function scanForDevices( } async function addNewDevices(baseIp: string, devices: PingResponse[]) { - let currentLamps = await DeviceModel.findAll() + let currentLamps = await Device.getDevices() let currentLampMacAddresses = currentLamps.map((c) => c.macAddress) let newLampMacAddress = devices.filter( (d) => !currentLampMacAddresses.includes(d.macAddress) ) - newLampMacAddress.forEach(async (macObj) => { - let newLamp = { - currentIP: `${baseIp}.${macObj.ipOctlet}`, - name: `New Lamp ${macObj.ipOctlet}`, - macAddress: macObj.macAddress, - numOfLeds: macObj.numOfLeds, - description: "", - } - await DeviceModel.create(newLamp) - }) + const newDevices = newLampMacAddress.map((macObj) => ({ + guid: uuidv4(), + currentIP: `${baseIp}.${macObj.ipOctlet}`, + name: `New Lamp ${macObj.ipOctlet}`, + macAddress: macObj.macAddress, + numOfLeds: macObj.numOfLeds, + description: "", + })) + + await Device.addDevices(newDevices) } export async function createDevice( request: FastifyRequest, reply: FastifyReply ): ApiResponse { + // TODO: const lampParts = request.body as Omit - const lamp = await DeviceModel.create({ + return { + guid: "hi", ...lampParts, - }) - - return lamp + } } export async function updateDevice( request: FastifyRequest, reply: FastifyReply -): ApiResponse { +): ApiResponse { const { deviceGuid } = request.params as { deviceGuid: string } const lampParts = request.body as Partial - - const [affectedCount] = await DeviceModel.update( - { - ...lampParts, - }, - { - where: { - guid: deviceGuid, - }, - } - ) - - return affectedCount + return Device.updateDevice(deviceGuid, lampParts) } export async function deleteDevice( request: FastifyRequest, reply: FastifyReply -): ApiResponse { +): ApiResponse { const { deviceGuid } = request.params as { deviceGuid: string } - const deletedCount = await DeviceModel.destroy({ - where: { guid: deviceGuid }, - }) + const successful = await Device.deleteDevice(deviceGuid) - if (deletedCount < 1) { + if (successful) { return createError( reply, `Couldn't find lamp with guid: ${deviceGuid}`, StatusCodes.NOT_FOUND ) } - - return deletedCount } export async function getDevice( @@ -144,7 +125,7 @@ export async function getDevice( reply: FastifyReply ): ApiResponse { const { deviceGuid } = request.params as { deviceGuid: string } - const lamp = await DeviceModel.findOne({ where: { guid: deviceGuid } }) + const lamp = await Device.getDevice(deviceGuid) if (!lamp) { return createError( @@ -173,9 +154,7 @@ export async function setAnimations( animationGuids: string[] } - const lamps = await DeviceModel.findAll({ - where: { guid: { [Op.in]: deviceGuids } }, - }) + const lamps = await Device.getDevicesByIds(deviceGuids) if (!lamps) return createError( reply, @@ -183,9 +162,7 @@ export async function setAnimations( StatusCodes.NOT_FOUND ) - const animations = await AnimationModel.findAll({ - where: { guid: { [Op.in]: animationGuids } }, - }) + const animations = await Animation.getAnimationsByGuids(animationGuids) if (!animations) return createError( reply, @@ -193,6 +170,11 @@ export async function setAnimations( StatusCodes.NOT_FOUND ) + console.log("==== SETTING ANIMATIONS ON DEVICES =====") + + console.log({ lamps }) + console.log({ animations }) + const animationsByGuid = new Map() animations.forEach((anim) => { animationsByGuid.set(anim.guid, anim.details) @@ -229,7 +211,7 @@ export async function toggleAnimation( animationGuid: string } - const lamp = await DeviceModel.findOne({ where: { guid: deviceGuid } }) + const lamp = await Device.getDevice(deviceGuid) if (!lamp) return createError( reply, @@ -237,9 +219,7 @@ export async function toggleAnimation( StatusCodes.NOT_FOUND ) - const animation = await AnimationModel.findOne({ - where: { guid: animationGuid }, - }) + const animation = await Animation.getAnimation(animationGuid) if (!animation) return createError( reply, @@ -269,7 +249,7 @@ export async function setSolidColor( } const color = request.body as RGBW - const lamp = await DeviceModel.findOne({ where: { guid: deviceGuid } }) + const lamp = await Device.getDevice(deviceGuid) if (!lamp) return createError( reply, diff --git a/server/src/models/animation.ts b/server/src/models/animation.ts index e61e654..c2408d7 100644 --- a/server/src/models/animation.ts +++ b/server/src/models/animation.ts @@ -1,52 +1,57 @@ +import fs from "fs/promises" +import { parse } from "yaml" + import { AnimationItem, AnimationType, BlinkAnimation } from "engine/types" -import { - Attributes, - CreationOptional, - DataTypes, - InferAttributes, - InferCreationAttributes, - Model, -} from "sequelize" - -import { sequelize } from "../setupMariaDB" - -export class AnimationModel extends Model< - InferAttributes, - InferCreationAttributes -> { - declare guid: CreationOptional - declare name: string - declare details: AnimationItem +export type IAnimation = { + guid: string + name: string + details: AnimationItem } -AnimationModel.init( - { - guid: { - type: DataTypes.UUID, - defaultValue: DataTypes.UUIDV4, - primaryKey: true, - allowNull: false, - }, - name: { type: DataTypes.TEXT, allowNull: false }, - details: { - type: DataTypes.JSON, - allowNull: false, - validate: { - isValidAnimationDef, - }, - }, - }, - { - tableName: "animations", - sequelize, - } -) +export async function getAnimations(): Promise { + const file = await fs.readFile("data/animations.yml", "utf-8") + const animationDB = parse(file) + + // TODO: parse and validate... + return animationDB.animations as IAnimation[] +} -export type IAnimation = Attributes +export async function createAnimation( + parts: Partial +): Promise { + return null +} + +export async function updateAnimation( + guid: string, + parts: Partial +): Promise { + console.log("TODO: update", guid, parts) + return null +} + +export async function deleteAnimation(guid: string): Promise { + console.log("TODO: delete", guid) + return false +} + +export async function getAnimation( + guid: string +): Promise { + const animations = await getAnimations() + return animations.find((a) => a.guid === guid) +} + +export async function getAnimationsByGuids( + guids: string[] +): Promise { + const animations = await getAnimations() + return animations.filter((a) => guids.includes(a.guid)) +} -function isValidAnimationDef(animationDef: AnimationItem) { - switch (animationDef.animationType) { +export function isValidAnimationDef(animationDef: AnimationItem) { + switch (animationDef.type) { case AnimationType.BLINK: if (!animationDef.onColor || !isRGBW(animationDef.onColor)) { throw new Error( diff --git a/server/src/models/device.ts b/server/src/models/device.ts index 70a05ae..f295cb0 100644 --- a/server/src/models/device.ts +++ b/server/src/models/device.ts @@ -1,45 +1,60 @@ -import { - Attributes, - CreationOptional, - DataTypes, - InferAttributes, - InferCreationAttributes, - Model, -} from "sequelize" - -import { sequelize } from "../setupMariaDB" - -export class DeviceModel extends Model< - InferAttributes, - InferCreationAttributes -> { - // "Declare" so no class properites are emitted - declare guid: CreationOptional - declare name: string - declare description: string - declare currentIP: string - declare macAddress: string - declare numOfLeds: number -} - -DeviceModel.init( - { - guid: { - type: DataTypes.UUID, - defaultValue: DataTypes.UUIDV4, - primaryKey: true, - allowNull: false, - }, - name: { type: DataTypes.TEXT, allowNull: false }, - description: { type: DataTypes.TEXT }, - currentIP: { type: DataTypes.CHAR, allowNull: false }, - macAddress: { type: DataTypes.CHAR, allowNull: false }, - numOfLeds: { type: DataTypes.SMALLINT, allowNull: false }, - }, - { - tableName: "devices", - sequelize, +import fs from "fs/promises" +import { parse, stringify } from "yaml" + +export type IDevice = { + guid: string + name: string + description: string + currentIP: string + macAddress: string + numOfLeds: number +} + +const DEVICES_FILE = "data/devices.yml" + +export async function getDevices(): Promise { + const file = await fs.readFile(DEVICES_FILE, "utf-8") + const deviceDB = parse(file) + return deviceDB.devices as IDevice[] +} + +async function saveDevices(devices: IDevice[]): Promise { + const yaml = stringify({ devices }) + await fs.writeFile(DEVICES_FILE, yaml) + return true +} + +export async function addDevices(devices: IDevice[]): Promise { + const currentDevices = await getDevices() + const newDevices = currentDevices.concat(devices) + return await saveDevices(newDevices) +} + +export async function updateDevice( + guid: string, + parts: Partial +): Promise { + return { + guid, + name: "", + description: "", + currentIP: "", + macAddress: "", + numOfLeds: 20, } -) +} + +export async function deleteDevice(guid: string): Promise { + console.log("TODO: delete", guid) + return false +} + +export async function getDevice(guid: string): Promise { + const devices = await getDevices() + return devices.find((d) => d.guid === guid) +} -export type IDevice = Attributes +export async function getDevicesByIds(guids: string[]): Promise { + const devices = await getDevices() + return devices.filter((d) => guids.includes(d.guid)) +} diff --git a/server/src/server.ts b/server/src/server.ts index d5f0516..6e699ff 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -3,7 +3,6 @@ import { ColorEngine } from "engine" import { setupFastifyServer } from "./setupFastify" import { setupWsServer } from "./setupWs" -import { setupDb } from "./setupMariaDB" const HTTP_PORT = parseInt(process.env.LAMP_HTTP_SERVER_PORT || "", 10) const WS_PORT = parseInt(process.env.LAMP_WS_SERVER_PORT || "", 10) @@ -18,7 +17,6 @@ async function startUp() { // the engine map here and pass it down? How can we create // a more generic "event" system that each could listen to.. // That seem heavy... - await setupDb() await setupFastifyServer(HTTP_PORT) await setupWsServer(WS_PORT) } diff --git a/server/src/setupMariaDB.ts b/server/src/setupMariaDB.ts deleted file mode 100644 index 7c918f1..0000000 --- a/server/src/setupMariaDB.ts +++ /dev/null @@ -1,40 +0,0 @@ -// import mariadb from "mariadb" - -// const pool = mariadb.createPool({ -// host: process.env.LAMP_DB_HOST, -// user: process.env.LAMP_DB_USER, -// password: process.env.LAMP_DB_PASS, -// }) - -import { Sequelize } from "sequelize" - -console.error("=================") -console.error("DB Stuff") -console.error(process.env.LAMP_DB_HOST) -console.error(process.env.LAMP_DB_USER) -console.error(process.env.LAMP_DB_PASS) -console.error(process.env.LAMP_DB_DBNAME) - -export const sequelize = new Sequelize({ - host: process.env.LAMP_DB_HOST || "", - username: process.env.LAMP_DB_USER || "", - password: process.env.LAMP_DB_PASS || "", - database: process.env.LAMP_DB_DBNAME || "", - dialect: "mariadb", -}) - -export async function setupDb() { - try { - await sequelize.authenticate() - console.log("Connected to DB") - } catch (error) { -console.error("=================") -console.error("DB Stuff") -console.error(process.env.LAMP_DB_HOST) -console.error(process.env.LAMP_DB_USER) -console.error(process.env.LAMP_DB_PASS) -console.error(process.env.LAMP_DB_DBNAME) - - console.error("Couldn't connect to db", error) - } -} diff --git a/server/src/testServer.ts b/server/src/testServer.ts index 314a5e8..cec4538 100644 --- a/server/src/testServer.ts +++ b/server/src/testServer.ts @@ -69,7 +69,7 @@ for (let i = 0; i < LED_COUNT; i++) { const engine = new ColorEngine(LED_COUNT) engine.addAnimation("RAINBOW123", { - animationType: AnimationType.RAINBOW, + type: AnimationType.RAINBOW, transitionMs: 100, }) engine.setColorCollector(sendColors) diff --git a/server/src/utils/animationSchemaType.ts b/server/src/utils/animationSchemaType.ts index f0c24ed..7ddf08f 100644 --- a/server/src/utils/animationSchemaType.ts +++ b/server/src/utils/animationSchemaType.ts @@ -21,7 +21,7 @@ export class AnimationSchemaType extends mongoose.SchemaType { } cast(animationDef: any): AnimationItem { - switch (animationDef.animationType) { + switch (animationDef.type) { case AnimationType.BLINK: if (!animationDef.onColor || !isRGBW(animationDef.onColor)) { throw new Error(