From 74a8b7c74e6794dbb77a6b4b7a7128eed49f7b83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20P=C3=B6schl?= Date: Sat, 14 Sep 2024 00:29:04 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=89=20Extract=20addon=20from=20mono-re?= =?UTF-8?q?pository?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/dependabot.yml | 16 ++ .github/workflows/addon-deploy.yaml | 13 + .github/workflows/addon-main-push.yaml | 9 + .github/workflows/addon-pr.yaml | 13 + .gitignore | 1 + .hadolint.yaml | 2 + .markdownlint.yaml | 10 + .shellcheckrc | 1 + .yamllint | 37 +++ CHANGELOG.md | 228 ++++++++++++++++++ Dockerfile | 54 +++++ README.md | 40 +++ build.yaml | 5 + config.yaml | 71 ++++++ icon.png | Bin 0 -> 5895 bytes logo.png | Bin 0 -> 9044 bytes root/app/config-template.jq | 8 + .../ICantBelieveItsNotValetudo/producer-for | 1 + .../s6-rc.d/ICantBelieveItsNotValetudo/run | 10 + .../s6-rc.d/ICantBelieveItsNotValetudo/type | 1 + .../s6-overlay/s6-rc.d/Server/consumer-for | 1 + root/etc/s6-overlay/s6-rc.d/Server/run | 7 + root/etc/s6-overlay/s6-rc.d/Server/type | 1 + .../contents.d/ICantBelieveItsNotValetudo | 0 .../s6-overlay/s6-rc.d/user/contents.d/Server | 0 root/server/main.js | 46 ++++ root/server/package.json | 9 + 27 files changed, 584 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/addon-deploy.yaml create mode 100644 .github/workflows/addon-main-push.yaml create mode 100644 .github/workflows/addon-pr.yaml create mode 100644 .gitignore create mode 100644 .hadolint.yaml create mode 100644 .markdownlint.yaml create mode 100644 .shellcheckrc create mode 100644 .yamllint create mode 100644 CHANGELOG.md create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 build.yaml create mode 100644 config.yaml create mode 100644 icon.png create mode 100644 logo.png create mode 100644 root/app/config-template.jq create mode 100644 root/etc/s6-overlay/s6-rc.d/ICantBelieveItsNotValetudo/producer-for create mode 100644 root/etc/s6-overlay/s6-rc.d/ICantBelieveItsNotValetudo/run create mode 100644 root/etc/s6-overlay/s6-rc.d/ICantBelieveItsNotValetudo/type create mode 100644 root/etc/s6-overlay/s6-rc.d/Server/consumer-for create mode 100644 root/etc/s6-overlay/s6-rc.d/Server/run create mode 100644 root/etc/s6-overlay/s6-rc.d/Server/type create mode 100644 root/etc/s6-overlay/s6-rc.d/user/contents.d/ICantBelieveItsNotValetudo create mode 100644 root/etc/s6-overlay/s6-rc.d/user/contents.d/Server create mode 100644 root/server/main.js create mode 100644 root/server/package.json diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..bf50d6c --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,16 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + groups: + GH actions: + dependency-type: production + - package-ecosystem: "npm" + directory: "/root/server" + schedule: + interval: "monthly" + groups: + npm: + dependency-type: production diff --git a/.github/workflows/addon-deploy.yaml b/.github/workflows/addon-deploy.yaml new file mode 100644 index 0000000..aa4019a --- /dev/null +++ b/.github/workflows/addon-deploy.yaml @@ -0,0 +1,13 @@ +name: Deploy + +# yamllint disable-line rule:truthy +on: + release: + types: + - published + +jobs: + workflows: + uses: Poeschl-HomeAssistant-Addons/workflows/.github/workflows/addon-deploy.yaml@main + secrets: + DISPATCH_TOKEN: ${{ secrets.DISPATCH_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/addon-main-push.yaml b/.github/workflows/addon-main-push.yaml new file mode 100644 index 0000000..5ac1e54 --- /dev/null +++ b/.github/workflows/addon-main-push.yaml @@ -0,0 +1,9 @@ +name: Draft release from new main push +on: + push: + branches: + - main + +jobs: + workflows: + uses: Poeschl-HomeAssistant-Addons/workflows/.github/workflows/release-drafter.yaml@main \ No newline at end of file diff --git a/.github/workflows/addon-pr.yaml b/.github/workflows/addon-pr.yaml new file mode 100644 index 0000000..803c051 --- /dev/null +++ b/.github/workflows/addon-pr.yaml @@ -0,0 +1,13 @@ +name: Check addon with linters +on: + push: + pull_request: + types: + - opened + - reopened + - synchronize + workflow_dispatch: + +jobs: + workflows: + uses: Poeschl-HomeAssistant-Addons/workflows/.github/workflows/addon-pr.yaml@main \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5a4addb --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +**/data/options.json \ No newline at end of file diff --git a/.hadolint.yaml b/.hadolint.yaml new file mode 100644 index 0000000..db03439 --- /dev/null +++ b/.hadolint.yaml @@ -0,0 +1,2 @@ +ignored: + - DL3006 diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 0000000..268233a --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,10 @@ +default: true + +MD001: false # Heading levels should only increment by one level at a time +MD002: false # First header should be a h1 header +MD007: # Unordered list indentation + indent: 2 +MD012: false # Multiple consecutive blank lines +MD013: false # Line length +MD025: false # Multiple top level headings in the same document +MD041: false # First line in file should be a top level header \ No newline at end of file diff --git a/.shellcheckrc b/.shellcheckrc new file mode 100644 index 0000000..6eccb2a --- /dev/null +++ b/.shellcheckrc @@ -0,0 +1 @@ +disable=SC2002 diff --git a/.yamllint b/.yamllint new file mode 100644 index 0000000..2bd2a2c --- /dev/null +++ b/.yamllint @@ -0,0 +1,37 @@ +--- +rules: + document-end: + level: error + present: false + document-start: + level: error + present: false + empty-lines: + level: error + max: 1 + max-start: 0 + max-end: 1 + hyphens: + level: error + max-spaces-after: 1 + indentation: + level: error + spaces: 2 + indent-sequences: true + check-multi-line-strings: false + key-duplicates: + level: error + line-length: + level: warning + max: 180 + allow-non-breakable-words: true + allow-non-breakable-inline-mappings: true + new-line-at-end-of-file: + level: error + new-lines: + level: error + type: unix + trailing-spaces: + level: error + truthy: + level: error \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..4d933e8 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,228 @@ +## 4.0.0 - 2022-09-11 + +* 🔨 Changed OS from alpine to debian (glibc is now required) +* 🔥 Remove support for armhf architecture since [ICantBelieveItsNotValetudo does not support + it right now](https://github.com/Hypfer/ICantBelieveItsNotValetudo/issues/85) + +## 3.7.0 - 2022-07-28 + +* 🔼 Updated ICantBelieveItsNotValetudo to latest release `2022.05.0` +* 🔼 Update alpine to `3.16` +* 🔼 Update git to `2.36.2-r0` +* 🔼 Update npm to `8.10.0-r0` +* 🔼 Update pixman/pixman-dev to `0.40.0-r3` +* 🔼 Update pango/pango-dev to `1.50.7-r0` +* 🔼 Update cairo/cairo-dev to `1.17.4-r2` +* 🔼 Updated python3 to `3.10.5-r0` +* 🔼 Updated build-base to `0.5-r3` +* 🔼 Updated libjpeg-turbo/libjpeg-turbo-dev to `2.1.3-r1` +* 🔨 Migrated to S6-Overlay `V3` +* 📝 Updated to new repository structure + Yaml config + +## 3.6.2 - 2022-04-10 + +* 📝 Updated Readme + +## 3.6.1 - 2021-12-06 + +* ➕ Add optional crop and padding settings + +## 3.6.0 - 2021-12-06 + +* 🔼 Updated python3 to `3.9.5-r2` +* 🔼 Updated ICantBelieveItsNotValetudo to latest release `2021.12.0` + +## 3.5.0 - 2021-10-31 + +* 🔼 Updated ICantBelieveItsNotValetudo to latest release `2021.8.0` + +## 3.4.1 - 2021-07-27 + +* 🔧 Added port of mqtt broker to schema validaton +* 🔼 Update alpine to `3.14` +* 🔼 Update git to `2.32.0-r0` +* 🔼 Update npm to `7.17.0-r0` +* 🔼 Update pango/pango-dev to `1.48.5-r0` +* 🔼 Update cairo/cairo-dev to `1.16.0-r3` +* 🔼 Updated python3 to `3.9.5-r1` + +## 3.4.0 - 2021-06-20 + +* 🔼 Updated ICantBelieveItsNotValetudo to latest release `2021.6.0` (thanks @ishioni) +* 🔼 Updated python3 to `3.8.10-r0` + +## 3.3.1 - 2021-05-03 + +* 🔼 Updated ICantBelieveItsNotValetudo default mqtt path, (@shalak) + + +## 3.3.0 - 2021-04-25 + +* 🔼 Updated ICantBelieveItsNotValetudo to latest release `2021.4.0` +* 🔼 Updated libjpeg-turbo/libjpeg-turbo-dev to `2.1.0-r0` +* 🔼 Updated npm to `14.16.1-r1` + + +## 3.2.0 - 2021-04-02 + +* 🔼 Updated ICantBelieveItsNotValetudo to latest release `2021.3.1` +* ➕ Bring back the png image via webserver. + + +## 3.1.0 - 2021-04-02 + +* 🔨 Use ghcr.io/home-assistant for base images + + +## 3.0.1 - 2021-03-17 + +* 🐛 Specifiy own S6 entrypoint, don't rely on the base image. +* ➕ Add optional `segments` color setting +* 🔼 Update git to `2.30.2-r0` +* 🔼 Updated python3 to `3.8.8-r0` + + +## 3.0.0 - 2021-02-27 + +* 🔼 Updated ICantBelieveItsNotValetudo to latest commit `73a7965` to make it fully compatible with Valetudo > 2021.02.1 +* 🔼 Updated npm to `14.16.0-r0` +* ➖ Removed `homeassistantMapHack` notice + + +## 2.8.1 - 2021-02-20 + +* 🔼 Updated python3 to `3.8.7-r1` +* 🔨 Changed the addon configuration to the current configuration of ICantBelieveItsNotValetudo (removing under/overlay images and cropping) +* ➕ Add `homeassistantMapHack` notice +* ➖ Removed `/share` mount + + +## 2.8.0 - 2021-02-18 + +* 🔼 Updated ICantBelieveItsNotValetudo to latest commit `74b6c33` +* 🔼 Updated npm to `14.15.5-r0` +* 🔨 Unspecify version of pkgconf +* ➖ Removed webserver since [no image is served anymore](https://github.com/Hypfer/ICantBelieveItsNotValetudo/commit/54cc0d96a6c03ee4dc92b86e533c0cd3999a7068#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5L14) +* ➖ Removed ingress since not needed anymore, since nothing to serve + +### 📌 Note 📌 + +* No image will be served to the side panel anymore. The map is only available as mqtt camera. + + +## 2.7.0 - 2021-02-15 + +* 🔨 Allow also anonymous access in mqtt broker url +* 🔼 Updated pango to `1.48.2-r0` + + +## 2.6.1 - 2021-02-10 + +* 🔼 Updated git to `2.30.1-r0` + + +## 2.6.0 - 2021-01-30 + +* 🔼 Updated alpine image to `3.13` +* 🔼 Updated git to `2.30.0-r0` +* 🔼 Updated npm to `14.15.4-r0` +* 🔼 Updated python3 to `3.8.7-r0` +* 🔼 Updated pkgconf to `1.7.3-r0` +* 🔼 Updated pango/pango-dev to `1.48.1-r0` +* 🔼 Updated libjpeg-turbo/libjpeg-turbo-dev to `2.0.6-r0` +* 🔨 Use Jemalloc for better memory handling + + +## 2.5.0 - 2020-12-14 + +* 🔨 Include small webserver to center the floorplan and apply the HA theme. +* 🔼 Updated ICantBelieveItsNotValetudo to latest commit `bd687c1` + + +## 2.4.0 - 2020-11-28 + +* 🔼 Updated ICantBelieveItsNotValetudo to latest commit `4b4a62c` + + +## 2.3.0 - 2020-10-23 + +* 🔼 Updated ICantBelieveItsNotValetudo to latest commit `67f86e2` + +### ⚠️ Breaking Change ⚠️ + +* Colors are only supported as hex values. See [Colors](https://github.com/Hypfer/ICantBelieveItsNotValetudo#new-map-colors) +* Colors are not optional anymore, they will be set to the defaults if not existing. + +## 2.2.2 - 2020-10-22 + +* 🔨 Start as `application` startup type + +## 2.2.1 - 2020-10-06 + +* 🔼 Updated npm to `12.18.4-r0` + +## 2.2.0 - 2020-07-29 + +* 🔼 Updated ICantBelieveItsNotValetudo to latest commit `30945f9` to use the new map data format +* 🔼 Updated alpine image to `3.12` +* 🔼 Updated git to `2.26.2-r0` +* 🔼 Updated npm to `12.17.0-r0` +* 🔨 Change build system to two-staged system for compiling needed npm packages outside of the running image +* 🔨 Use S6 system + +## 2.1.0 - 2020-05-29 + +* 🔼 🐛 Updated ICantBelieveItsNotValetudo to latest commit `9bcfc25` + +## 2.0.3 - 2020-05-22 + +* 🔨 Updated Changelog to new format + +## 2.0.2 - 2020-04-29 + +* 🔼 Updated git to `2.24.3-r0` + +## 2.0.1 - 2020-04-16 + +* 🔼 Updated git to `2.24.2-r0` + +## 2.0.0 - 2020-02-27 + +* 🔼 Updated ICantBelieveItsNotValetudo to latest commit `3cf4f8a` +* ➕ Adjusted to new config structure (__Make sure to migrate your existing config!__) + +## 1.0.0 - 2020-02-07 + +* ➕ Own versioning for changes. Start with `1.0.0` +* 🔼 Updated Dependencies: + * alpine `3.11` + * git `2.24.1-r0` + * npm `12.15.0-r1` + +## 0.2.0-5 - 2019-11-06 + +* ➕ Added schema for optional cropping parameters + +## 0.2.0-4 - 2019-10-19 + +* 🔨 Switch to current master instead of latest version (thanks @Nickerchen) + +## 0.2.0-3 - 2019-10-15 + +* 🔼 Use alpine 3.9 as base image + +## 0.2.0-2 - 2019-10-06 + +* 🔨 Integration into new build setup + +## 0.2.0-1 - 2019-09-02 + +* ➕ Added HASS.io Ingress feature (#6) +* 🔨 Ingress is now the default access method + +## 0.2.0 - 2019-08-14 + +* ➕ SSL Mapping on HASS.io +* ➕ Add ICantBelieveItsNotValetudo Version 0.2.0 in its basic form +* ➕ Added plugin to pre-built ones +* 🐛 Fixed MQTT config setting diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2b75c9d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,54 @@ +ARG BUILD_FROM +FROM $BUILD_FROM AS BUILD + +ENV LANG C.UTF-8 + +RUN apt-get update && apt-get -y --no-install-recommends install \ + git=1:2.35.1-1 \ + npm=8.19.2~ds1-2 \ + python3=3.10.6-1 \ + libpixman-1-dev=0.40.0-1 \ + libcairo2-dev=1.16.0-6 \ + libpango1.0-dev=1.50.10+ds-1 \ + build-essential=12.9 \ + libjpeg62-turbo-dev=1:2.1.2-1+b1 + +# Splited RUN for better layer caching +# hadolint ignore=DL3059 +RUN git config --global advice.detachedHead false && \ + git clone https://github.com/Hypfer/ICantBelieveItsNotValetudo.git -b 2022.05.0 /app + +WORKDIR /app +RUN npm install + + +FROM $BUILD_FROM AS SERVER + +RUN apt-get update && apt-get -y --no-install-recommends install \ + npm=8.19.2~ds1-2 + +COPY root/server /server + +WORKDIR /server +RUN npm install + + +FROM $BUILD_FROM AS RUNNING + +RUN apt-get update && apt-get -y --no-install-recommends install \ + npm=8.19.2~ds1-2 \ + libpixman-1-0=0.40.0-1 \ + libcairo2=1.16.0-6 \ + libpango-1.0-0=1.50.10+ds-1 \ + libjpeg62-turbo=1:2.1.2-1+b1 \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /app + +COPY --from=BUILD /app /app +COPY --from=SERVER /server /server + +ENTRYPOINT [ "/init" ] +CMD [] +COPY root / diff --git a/README.md b/README.md new file mode 100644 index 0000000..0a4729b --- /dev/null +++ b/README.md @@ -0,0 +1,40 @@ +# ICantBelieveItsNotValetudo Addon + +This is the adaption of [ICantBelieveItsNotValetudo](https://github.com/Hypfer/ICantBelieveItsNotValetudo) as a Supervisor addon. + +![Addon Stage][stage-badge] +![Supports aarch64 Architecture][aarch64-badge] +![Supports amd64 Architecture][amd64-badge] +![Supports armhf Architecture][armhf-badge] +![Supports armv7 Architecture][armv7-badge] +![Supports i386 Architecture][i386-badge] + +[![Add repository on my Home Assistant][repository-badge]][repository-url] +[![Install on my Home Assistant][install-badge]][install-url] +[![Donate][donation-badge]][donation-url] + +## Config + +The configuration keys are identical to the [configuration of ICantBelieveItsNotValetudo](https://github.com/Hypfer/ICantBelieveItsNotValetudo/blob/main/README.md). +Please get the meaning for them from there. +It's normal that the structure of the addon differs from the official config file, this is nessesary because of the Supervisor Addon config structure. + +If you use the Mosquitto Addon in Home Assistant `core-mosquitto` can be used as broker address like this: `mqtt://:@core-mosquitto`. Keep in mind to set proper `mapDataTopic` value. As of Valetudo 2021.04.0, it's `${topicPrefix}/${identifier}/MapData/map-data`, which with default values is equal to `valetudo/rockrobo/MapData/map-data`. + +## PNG image + +The generated image will be served over the Supervisor Ingress feature. So the floor plan can be accessed via the build-in side panel and the auto-configured mqtt camera. + +[aarch64-badge]: https://img.shields.io/badge/aarch64-yes-green.svg?style=for-the-badge +[amd64-badge]: https://img.shields.io/badge/amd64-yes-green.svg?style=for-the-badge +[armhf-badge]: https://img.shields.io/badge/armhf-no-red.svg?style=for-the-badge +[armv7-badge]: https://img.shields.io/badge/armv7-yes-green.svg?style=for-the-badge +[i386-badge]: https://img.shields.io/badge/i386-yes-green.svg?style=for-the-badge +[stage-badge]: https://img.shields.io/badge/Addon%20stage-stable-green.svg?style=for-the-badge +[install-badge]: https://img.shields.io/badge/Install%20on%20my-Home%20Assistant-41BDF5?logo=home-assistant&style=for-the-badge +[donation-badge]: https://img.shields.io/badge/Buy%20me%20a%20coffee-%23d32f2f?logo=buy-me-a-coffee&style=for-the-badge&logoColor=white +[donation-url]: https://www.buymeacoffee.com/Poeschl +[repository-badge]: https://img.shields.io/badge/Add%20repository%20to%20my-Home%20Assistant-41BDF5?logo=home-assistant&style=for-the-badge + +[install-url]: https://my.home-assistant.io/redirect/supervisor_addon?addon=243ffc37_icantbelieveitsnotvaletudo +[repository-url]: https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2FPoeschl%2FHassio-Addons diff --git a/build.yaml b/build.yaml new file mode 100644 index 0000000..337046e --- /dev/null +++ b/build.yaml @@ -0,0 +1,5 @@ +build_from: + armv7: ghcr.io/home-assistant/armv7-base-debian:bookworm + aarch64: ghcr.io/home-assistant/aarch64-base-debian:bookworm + amd64: ghcr.io/home-assistant/amd64-base-debian:bookworm + i386: ghcr.io/home-assistant/i386-base-debian:bookworm diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..849573f --- /dev/null +++ b/config.yaml @@ -0,0 +1,71 @@ +name: ICantBelieveItsNotValetudo +version: 4.0.0 +slug: icantbelieveitsnotvaletudo +description: This is a simple companion service for valetudo which generates the map pngs. +url: https://github.com/Poeschl/Hassio-Addons/tree/main/ICantBelieveItsNotValetudo +arch: + - armv7 + - aarch64 + - amd64 + - i386 +image: ghcr.io/poeschl-homeAssistant-addons/icantbelieveitsnotvaletudo-{arch} +ports: + 8080/tcp: +ports_description: + 8080/tcp: Port serving the floor plan (Not required for Supervisor Ingress) +ingress: true +ingress_port: 8080 +panel_title: Valetudo Floorplan +panel_icon: mdi:floor-plan +init: false +map: + - ssl +schema: + mapSettings: + drawPath: bool + drawCharger: bool + drawRobot: bool + scale: int(0,) + rotate: int(0,) + crop_top: int(0,)? + crop_bottom: int(0,)? + crop_left: int(0,)? + crop_right: int(0,)? + padding_top: int(0,)? + padding_bottom: int(0,)? + padding_right: int(0,)? + padding_left: int(0,)? + mapColors: + floor: match(#(?:[0-9a-fA-F]{2}){2,4}$|(#[0-9a-fA-F]{3})$) + obstacle: match(#(?:[0-9a-fA-F]{2}){2,4}$|(#[0-9a-fA-F]{3})$) + path: match(#(?:[0-9a-fA-F]{2}){2,4}$|(#[0-9a-fA-F]{3})$) + segments: match(#(?:[0-9a-fA-F]{2}){2,4}$|(#[0-9a-fA-F]{3})$)? + mqtt: + identifier: str + topicPrefix: str + autoconfPrefix: str + broker_url: match(^mqtts?://(.+:.+@)?[^:@]+(:[0-9]+)?$) + caPath: str + mapDataTopic: str + minMillisecondsBetweenMapUpdates: int + publishMapImage: bool +options: + mapSettings: + drawPath: true + drawCharger: true + drawRobot: true + scale: 4 + rotate: 0 + mapColors: + floor: "#0076ff" + obstacle: "#52aeff" + path: "#ffffff" + mqtt: + identifier: rockrobo + topicPrefix: valetudo + autoconfPrefix: homeassistant + broker_url: mqtt://user:pass@foobar.example + caPath: "" + mapDataTopic: valetudo/rockrobo/MapData/map-data + minMillisecondsBetweenMapUpdates: 10000 + publishMapImage: true diff --git a/icon.png b/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5e0f976381e3c4aeb06f0809c55bacae0fb1a118 GIT binary patch literal 5895 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 literal 0 HcmV?d00001 diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..17a74855ebfda5e53f1342eea6c4e205418f083c GIT binary patch literal 9044 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 /app/config.json + +bashio::log.info 'Start ICantBelieveItsNotValetudo' +cd /app +npm start diff --git a/root/etc/s6-overlay/s6-rc.d/ICantBelieveItsNotValetudo/type b/root/etc/s6-overlay/s6-rc.d/ICantBelieveItsNotValetudo/type new file mode 100644 index 0000000..5883cff --- /dev/null +++ b/root/etc/s6-overlay/s6-rc.d/ICantBelieveItsNotValetudo/type @@ -0,0 +1 @@ +longrun diff --git a/root/etc/s6-overlay/s6-rc.d/Server/consumer-for b/root/etc/s6-overlay/s6-rc.d/Server/consumer-for new file mode 100644 index 0000000..e63a7f3 --- /dev/null +++ b/root/etc/s6-overlay/s6-rc.d/Server/consumer-for @@ -0,0 +1 @@ +ICantBelieveItsNotValetudo diff --git a/root/etc/s6-overlay/s6-rc.d/Server/run b/root/etc/s6-overlay/s6-rc.d/Server/run new file mode 100644 index 0000000..6fb0701 --- /dev/null +++ b/root/etc/s6-overlay/s6-rc.d/Server/run @@ -0,0 +1,7 @@ +#!/command/with-contenv bashio +# shellcheck shell=bash +set -e + +bashio::log.info 'Start Proxywebserver' +cd /server +npm start diff --git a/root/etc/s6-overlay/s6-rc.d/Server/type b/root/etc/s6-overlay/s6-rc.d/Server/type new file mode 100644 index 0000000..5883cff --- /dev/null +++ b/root/etc/s6-overlay/s6-rc.d/Server/type @@ -0,0 +1 @@ +longrun diff --git a/root/etc/s6-overlay/s6-rc.d/user/contents.d/ICantBelieveItsNotValetudo b/root/etc/s6-overlay/s6-rc.d/user/contents.d/ICantBelieveItsNotValetudo new file mode 100644 index 0000000..e69de29 diff --git a/root/etc/s6-overlay/s6-rc.d/user/contents.d/Server b/root/etc/s6-overlay/s6-rc.d/user/contents.d/Server new file mode 100644 index 0000000..e69de29 diff --git a/root/server/main.js b/root/server/main.js new file mode 100644 index 0000000..f9b754b --- /dev/null +++ b/root/server/main.js @@ -0,0 +1,46 @@ +const http = require('http'); +const request = require('request'); + +const index = ` + + + + + + + + + + +` + +http.createServer(function (req, resp) { + + var path = req.url; + + if (path == '/') { + resp.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'}); + resp.end(index, 'utf-8'); + + } else if (path == '/image') { + //Proxy to the original image + const mapImage = request('http://localhost:3000/api/map/image') + req.pipe(mapImage) + mapImage.pipe(resp) + + } else if (path == '/favicon.ico') { + //Ignore favicon + + } else { + console.warn('Invalid request ', path) + } +}).listen(8080); diff --git a/root/server/package.json b/root/server/package.json new file mode 100644 index 0000000..b8c1377 --- /dev/null +++ b/root/server/package.json @@ -0,0 +1,9 @@ +{ + "name": "valetudo-mini-server", + "dependencies": { + "request": "^2.88.2" + }, + "scripts": { + "start": "node main.js" + } +} \ No newline at end of file