diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..5911f9e --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,34 @@ +{ + "name": "devcontainer for add-on repositories", + "image": "ghcr.io/home-assistant/devcontainer:addons", + "appPort": ["7123:8123", "7357:4357"], + "postStartCommand": "bash devcontainer_bootstrap", + "postCreateCommand": "sudo apt-get update && sudo apt-get install -y libwebp-dev", + "runArgs": ["-e", "GIT_EDITOR=code --wait", "--privileged"], + "containerEnv": { + "WORKSPACE_DIRECTORY": "${containerWorkspaceFolder}" + }, + "features": { + "ghcr.io/devcontainers/features/go:1": { + "version": "1.23.2" + } + }, + "customizations": { + "vscode": { + "extensions": ["timonwong.shellcheck", "esbenp.prettier-vscode", "golang.go", "github.vscode-github-actions"], + "settings": { + "terminal.integrated.profiles.linux": { + "zsh": { + "path": "/usr/bin/zsh" + } + }, + "terminal.integrated.defaultProfile.linux": "zsh", + "editor.formatOnPaste": false, + "editor.formatOnSave": true, + "editor.formatOnType": true, + "files.trimTrailingWhitespace": true + } + } + }, + "mounts": [ "type=volume,target=/var/lib/docker" ] + } \ No newline at end of file diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml new file mode 100644 index 0000000..9eff3ca --- /dev/null +++ b/.github/workflows/go.yml @@ -0,0 +1,34 @@ +name: Go + +on: + push: + branches: ["main"] + pull_request: + branches: ["main"] + +defaults: + run: + working-directory: ./TidbytAssistant + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: "1.23.2" + + - name: Install dependencies + run: sudo apt-get update && sudo apt-get -y install libweb-dev + + - name: Lint + run: go vet ./... + + - name: Build + run: go build -v ./... + + - name: Test + run: go test -v ./... diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..cd52231 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,19 @@ +name: hadolint + +on: + push: + branches: + - main + pull_request: + +defaults: + run: + working-directory: ./TidbytAssistant + +jobs: + hadolint: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4.2.1 + - uses: brpaz/hadolint-action@v1.5.0 \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..36e373a --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,20 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Start Home Assistant", + "type": "shell", + "command": "supervisor_run", + "group": { + "kind": "test", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "new" + }, + "problemMatcher": [] + } + ] + } + \ No newline at end of file diff --git a/README.md b/README.md index 70440d1..9724207 100644 --- a/README.md +++ b/README.md @@ -5,12 +5,14 @@ You can add this repository to your HomeAssistant instance by adding the URL bel ```txt https://github.com/savdagod/ha-addons ``` + ## Add-ons provided by this repository

- +

-A docker container that hosts the pixlet app as well as webhook to receive API request to display information on your Tidbyt. After installing this add-on, install the TidbytAssistant integration found here: +A Docker container that receives API requests to display information on your Tidbyt. +After installing this add-on, install the TidbytAssistant integration found here: ```txt https://github.com/savdagod/TidbytAssistant/ diff --git a/TidbytAssistant/CHANGELOG.md b/TidbytAssistant/CHANGELOG.md index 235f0d0..dba854a 100644 --- a/TidbytAssistant/CHANGELOG.md +++ b/TidbytAssistant/CHANGELOG.md @@ -1,10 +1,25 @@ # Changelog +## 1.0.9 + +- Reduced size of the addon by running a distroless container with a static Go server. + +## 1.0.8 + +- Use command line arguments for text scripts instead of replacing strings. +- Add Text & Title type for Text service. +- Publish service now pushes to the background, preventing the current app from being replaced by the pushed app. +- Push and Publish service now support key=value pair arguments. +- Scripts clear tmp folder before rather than after commands. +- Moved scripts to their own folder. + ## 1.0.7 + - Added option to publish from background or foreground. - **NOTE: Be sure to update the integration to v1.0.5 to be able to use this feature!** ## 1.0.6 + - Use command line arguments for text scripts instead of replacing strings. - Add Text & Title type for Text service. - Publish service now pushes to the background, preventing the current app from being replaced by the pushed app. @@ -14,28 +29,34 @@ - Point pixlet build to forked repo to keep Pixlet version consistent. - Add error handling to scripts, webhook responds with error which will be logged in HomeAssistant. - **NOTE: Be sure to update the integration to v1.0.4 to take advantage of these new features!** - + ## 1.0.5 + - Change Dockerfile to build pixlet binary. - Edit scripts to move .star files to tmp directory to work around current bug in pixlet. ## 1.0.4 + - Added libwep to image. ## 1.0.3 + - Added full path for pixlet app to potentially fix script not finding pixlet app. ## 1.0.2 + - Fix to Dockerfile for those building on arm64 architecture. - Added new service TidbytAssistant: Delete, which allows you to delete apps using their content IDs. - Be sure to download the most up to date TidbytAssistant integration (ver. 1.0.2) ## 1.0.1 + - Added 2 new services: Publish and Text - - Publish: Add apps to your rotation of apps - - Text: Push custom text to your device. Supports the various available Tidbyt fonts and colors. + - Publish: Add apps to your rotation of apps + - Text: Push custom text to your device. Supports the various available Tidbyt fonts and colors. - Be sure to download the most up to date TidbytAssistant integration. (ver. 1.0.1) ## 1.0.0 -- Initial release. + +- Initial release. - Be sure to download the most up to date TidbytAssistant integration. (ver. 1.0.0) diff --git a/TidbytAssistant/Dockerfile b/TidbytAssistant/Dockerfile index 7b2fe5f..3cc6f9c 100644 --- a/TidbytAssistant/Dockerfile +++ b/TidbytAssistant/Dockerfile @@ -1,51 +1,35 @@ -ARG BUILD_FROM +ARG BUILD_FROM=homeassistant/amd64-base:latest -FROM $BUILD_FROM +FROM ${BUILD_FROM} AS builder # Args from build.yaml -ARG GO_VERSION +ARG GO_VERSION=1.23.2 -# Copy data for add-on -COPY hooks.yaml / -ADD scripts /opt/scripts -RUN chmod a+x /opt/scripts/* -ADD display /opt/display +SHELL ["/bin/ash", "-eo", "pipefail", "-c"] # Download Go and add to PATH RUN arch=$(arch | sed s/aarch64/arm64/ | sed s/x86_64/amd64/) && \ - wget "https://go.dev/dl/go${GO_VERSION}.linux-${arch}.tar.gz" + wget -q "https://go.dev/dl/go${GO_VERSION}.linux-${arch}.tar.gz" RUN arch=$(arch | sed s/aarch64/arm64/ | sed s/x86_64/amd64/) && \ - tar -xzf go${GO_VERSION}.linux-${arch}.tar.gz -C /usr/local && \ - rm go${GO_VERSION}.linux-${arch}.tar.gz -ENV PATH=${PATH}:/usr/local/go/bin - -# Build Webhook binary using Go and move to PATH -RUN go install github.com/adnanh/webhook@latest -RUN mv /root/go/bin/webhook /usr/local/bin/webhook + tar -xzf "go${GO_VERSION}.linux-${arch}.tar.gz" -C /usr/local && \ + rm "go${GO_VERSION}.linux-${arch}.tar.gz" +ENV PATH=/usr/local/go/bin:${PATH} +ENV GOROOT=/usr/local/go # Download dependencies -ENV GOPATH /usr/local/go -ENV REPO $GOPATH/pixlet -RUN apk update && \ - apk upgrade -U && \ - apk add curl wget git make libc-dev gcc ca-certificates npm libwebp-dev libwebp-tools patchelf gcompat && \ - rm -rf /var/cache/* - -# Download Pixlet -RUN git clone https://github.com/savdagod/pixlet.git $REPO -WORKDIR $REPO - -#Build Pixlet -RUN npm install && npm run build -RUN make build +RUN apk --no-cache add libc-dev gcc ca-certificates libwebp-dev libwebp-static -# Move pixlet binary to path -RUN mv $GOPATH/pixlet/pixlet /usr/local/bin/pixlet +# Build binary +COPY *.go go.mod go.sum /src/ +WORKDIR /src +RUN CGO_ENABLED=1 go build -ldflags "-s -w -linkmode=external '-extldflags=-static -lsharpyuv'" -o /tidbyt-assistant ./... -# Clean up build prereqs -RUN apk del -r curl wget git make gcc patchelf libc-dev -RUN rm -r $GOPATH -RUN rm -r /root/go +FROM scratch -CMD [ "webhook", "-hooks", "/hooks.yaml", "-verbose" ] +COPY --from=builder /tidbyt-assistant /tidbyt-assistant +#COPY --from=builder /usr/lib/libwebp*.so* /usr/lib/libsharpyuv.so* /usr/lib/ +COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt +COPY display /display +ENTRYPOINT [ "/tidbyt-assistant" ] +HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 CMD [ "/tidbyt-assistant", "-health", "http://localhost:9000/health" ] diff --git a/TidbytAssistant/build.yaml b/TidbytAssistant/build.yaml index 0cb1fea..8b0ba01 100644 --- a/TidbytAssistant/build.yaml +++ b/TidbytAssistant/build.yaml @@ -1,2 +1,2 @@ args: - GO_VERSION: "1.23.1" + GO_VERSION: "1.23.2" diff --git a/TidbytAssistant/config.yaml b/TidbytAssistant/config.yaml index ad88c4a..bb9e645 100644 --- a/TidbytAssistant/config.yaml +++ b/TidbytAssistant/config.yaml @@ -1,6 +1,6 @@ name: "TidbytAssistant" description: "Add-on with Pixlet application. Allows you to push custom apps to your Tidbyt. Install with integration v1.0.5" -version: "1.0.7" +version: "1.0.9" slug: "tidbytassistant" url: "https://github.com/savdagod/ha-addons/tree/main/TidbytAssistant" init: False diff --git a/TidbytAssistant/hooks.yaml b/TidbytAssistant/hooks.yaml deleted file mode 100644 index c9fb6ef..0000000 --- a/TidbytAssistant/hooks.yaml +++ /dev/null @@ -1,70 +0,0 @@ -- id: tidbyt-push - execute-command: "/opt/scripts/TidbytPush.sh" - command-working-directory: "/opt" - include-command-output-in-response: true - include-command-output-in-response-on-error: true - pass-arguments-to-command: - - source: "payload" - name: "content" - - source: "payload" - name: "deviceid" - - source: "payload" - name: "token" - - source: "payload" - name: "contenttype" - - source: "payload" - name: "starargs" -- id: tidbyt-publish - execute-command: "/opt/scripts/TidbytPublish.sh" - command-working-directory: "/opt" - include-command-output-in-response: true - include-command-output-in-response-on-error: true - pass-arguments-to-command: - - source: "payload" - name: "content" - - source: "payload" - name: "deviceid" - - source: "payload" - name: "token" - - source: "payload" - name: "contentid" - - source: "payload" - name: "publishtype" - - source: "payload" - name: "starargs" -- id: tidbyt-text - execute-command: "/opt/scripts/TidbytText.sh" - command-working-directory: "/opt" - include-command-output-in-response: true - include-command-output-in-response-on-error: true - pass-arguments-to-command: - - source: "payload" - name: "content" - - source: "payload" - name: "deviceid" - - source: "payload" - name: "token" - - source: "payload" - name: "texttype" - - source: "payload" - name: "font" - - source: "payload" - name: "color" - - source: "payload" - name: "title" - - source: "payload" - name: "titlecolor" - - source: "payload" - name: "titlefont" -- id: tidbyt-delete - execute-command: "/opt/scripts/TidbytDelete.sh" - command-working-directory: "/opt" - include-command-output-in-response: true - include-command-output-in-response-on-error: true - pass-arguments-to-command: - - source: "payload" - name: "contentid" - - source: "payload" - name: "deviceid" - - source: "payload" - name: "token" diff --git a/TidbytAssistant/main.go b/TidbytAssistant/main.go new file mode 100644 index 0000000..7691dfc --- /dev/null +++ b/TidbytAssistant/main.go @@ -0,0 +1,367 @@ +package main + +import ( + "bytes" + "context" + "encoding/base64" + "encoding/json" + "flag" + "fmt" + "io" + "log/slog" + "net/http" + "net/url" + "os" + "path/filepath" + "strings" + "time" + + "tidbyt.dev/pixlet/encode" + "tidbyt.dev/pixlet/runtime" +) + +var ( + cache = runtime.NewInMemoryCache() + healthURL = flag.String("health", "", "perform health check for the given URL and exit") +) + +const ( + tidbytBaseURL = "https://api.tidbyt.com" + silenceOutput = false + renderGif = false + timeout = 30 * time.Second + maxDuration = 15 * time.Second +) + +type ( + pushRequest struct { + Content string `json:"content"` + DeviceID string `json:"deviceid"` + Token string `json:"token"` + ContentType string `json:"contenttype"` + Arguments []string `json:"starargs"` + } + + publishRequest struct { + Content string `json:"content"` + DeviceID string `json:"deviceid"` + Token string `json:"token"` + InstallationID string `json:"contentid"` + PublishType string `json:"publishtype"` + Arguments []string `json:"starargs"` + } + + textRequest struct { + Content string `json:"content"` + DeviceID string `json:"deviceid"` + Token string `json:"token"` + TextType string `json:"texttype"` + Font string `json:"font"` + Color string `json:"color"` + Title string `json:"title"` + TitleColor string `json:"titlecolor"` + TitleFont string `json:"titlefont"` + } + + deleteRequest struct { + InstallationID string `json:"contentid"` + DeviceID string `json:"deviceid"` + Token string `json:"token"` + } + + tidbytPushRequest struct { + Image string `json:"image"` + InstallationID string `json:"installationID,omitempty"` + Background bool `json:"background"` + } +) + +func pushHandler(w http.ResponseWriter, req *http.Request) { + var r pushRequest + + if err := json.NewDecoder(req.Body).Decode(&r); err != nil { + http.Error(w, fmt.Sprintf("failed to decode push request: %v", err), http.StatusBadRequest) + return + } + + slog.Debug(fmt.Sprintf("Received push request %+v", r)) + + var rootDir string + switch r.ContentType { + case "builtin": + rootDir = "/display" + case "custom": + rootDir = "/homeassistant/tidbyt" + default: + http.Error(w, fmt.Sprintf("unknown content type %q", r.ContentType), http.StatusBadRequest) + } + + config, err := parseArguments(r.Arguments) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + path := filepath.Join(rootDir, r.Content+".star") + if err := renderAndPush(path, config, r.DeviceID, "", r.Token, false); err != nil { + slog.Error(err.Error()) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + +func publishHandler(w http.ResponseWriter, req *http.Request) { + var r publishRequest + + if err := json.NewDecoder(req.Body).Decode(&r); err != nil { + http.Error(w, fmt.Sprintf("failed to decode publish request: %v", err), http.StatusBadRequest) + return + } + + slog.Debug(fmt.Sprintf("Received publish request %+v", r)) + + config, err := parseArguments(r.Arguments) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + path := filepath.Join("/homeassistant/tidbyt", r.Content+".star") + background := r.PublishType == "background" + + if err := renderAndPush(path, config, r.DeviceID, r.InstallationID, r.Token, background); err != nil { + slog.Error(err.Error()) + http.Error(w, err.Error(), http.StatusInternalServerError) + } +} + +func textHandler(w http.ResponseWriter, req *http.Request) { + var r textRequest + + if err := json.NewDecoder(req.Body).Decode(&r); err != nil { + http.Error(w, fmt.Sprintf("failed to decode text request: %v", err), http.StatusBadRequest) + return + } + + slog.Debug(fmt.Sprintf("Received text request %+v", r)) + + if r.TextType == "" { + http.Error(w, "missing \"texttype\"", http.StatusBadRequest) + return + } + + path := filepath.Join("/display", fmt.Sprintf("text-%s.star", r.TextType)) + config := map[string]string{ + "content": r.Content, + "font": r.Font, + "color": r.Color, + } + if r.TextType == "title" { + config["title"] = r.Title + config["titlecolor"] = r.TitleColor + config["titlefont"] = r.TitleFont + } + + if err := renderAndPush(path, config, r.DeviceID, "", r.Token, false); err != nil { + slog.Error(err.Error()) + http.Error(w, err.Error(), http.StatusInternalServerError) + } +} + +func deleteHandler(w http.ResponseWriter, req *http.Request) { + var r deleteRequest + + if err := json.NewDecoder(req.Body).Decode(&r); err != nil { + http.Error(w, fmt.Sprintf("failed to decode delete request: %v", err), http.StatusBadRequest) + return + } + + slog.Debug(fmt.Sprintf("Received delete request %+v", r)) + + u := fmt.Sprintf( + "%s/v0/devices/%s/installations/%s", + tidbytBaseURL, + r.DeviceID, + r.InstallationID, + ) + if err := tidbytAPI(u, "DELETE", nil, r.Token); err != nil { + slog.Error(err.Error()) + http.Error(w, fmt.Sprintf("failed to delete: %v", err), http.StatusInternalServerError) + return + } +} + +func healthHandler(w http.ResponseWriter, req *http.Request) { + w.WriteHeader(http.StatusOK) +} + +func renderAndPush(path string, arguments map[string]string, deviceID, installationID, token string, background bool) error { + image, err := renderApp(path, arguments) + if err != nil { + return fmt.Errorf("failed to render app: %v", err) + } + + if err := tidbytPush(image, deviceID, installationID, token, background); err != nil { + return fmt.Errorf("failed to push image: %v", err) + } + + slog.Info(fmt.Sprintf("Pushed %v", path)) + + return nil +} + +func tidbytPush(imageData []byte, deviceID, installationID, apiToken string, background bool) error { + payload, err := json.Marshal( + tidbytPushRequest{ + Image: base64.StdEncoding.EncodeToString(imageData), + InstallationID: installationID, + Background: background, + }, + ) + if err != nil { + return fmt.Errorf("failed to marshal json: %w", err) + } + u := fmt.Sprintf("%s/v0/devices/%s/push", tidbytBaseURL, url.PathEscape(deviceID)) + if err := tidbytAPI(u, "POST", payload, apiToken); err != nil { + return fmt.Errorf("failed to push image: %w", err) + } + return nil +} + +func tidbytAPI(u, method string, payload []byte, apiToken string) error { + req, err := http.NewRequest(method, u, bytes.NewReader(payload)) + if err != nil { + return fmt.Errorf("creating %v request: %w", method, err) + } + + req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", apiToken)) + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return fmt.Errorf("pushing to API: %w", err) + } + + if resp.StatusCode != http.StatusOK { + slog.Error(fmt.Sprintf("Tidbyt API returned status %s\n", resp.Status)) + body, _ := io.ReadAll(resp.Body) + slog.Error(string(body)) + return fmt.Errorf("Tidbyt API returned status: %s", resp.Status) + } + + return nil +} + +func parseArguments(args []string) (map[string]string, error) { + config := map[string]string{} + for _, param := range args { + split := strings.Split(param, "=") + if len(split) < 2 { + return nil, fmt.Errorf("parameters must be in form =, found %s", param) + } + config[split[0]] = strings.Join(split[1:], "=") + } + + return config, nil +} + +func renderApp(path string, config map[string]string) ([]byte, error) { + // check if path exists + _, err := os.Stat(path) + if err != nil { + return nil, fmt.Errorf("failed to stat %s: %w", path, err) + } + + // Remove the print function from the starlark thread if the silent flag is + // passed. + var opts []runtime.AppletOption + if silenceOutput { + opts = append(opts, runtime.WithPrintDisabled()) + } + + ctx := context.Background() + if timeout > 0 { + ctx, _ = context.WithTimeoutCause( + ctx, + timeout, + fmt.Errorf("timeout after %v", timeout), + ) + } + + srcBytes, err := os.ReadFile(path) + if err != nil { + return nil, fmt.Errorf("failed to read %s: %w", path, err) + } + + applet, err := runtime.NewApplet(filepath.Base(path), srcBytes, opts...) + if err != nil { + return nil, fmt.Errorf("failed to load applet: %w", err) + } + + roots, err := applet.RunWithConfig(ctx, config) + if err != nil { + return nil, fmt.Errorf("error running script: %w", err) + } + screens := encode.ScreensFromRoots(roots) + + var buf []byte + + duration := maxDuration + if screens.ShowFullAnimation { + duration = 0 * time.Millisecond + } + + if renderGif { + buf, err = screens.EncodeGIF(int(duration.Milliseconds())) + } else { + buf, err = screens.EncodeWebP(int(duration.Milliseconds())) + } + if err != nil { + return nil, fmt.Errorf("error rendering: %w", err) + } + + return buf, nil +} + +func checkHealth(url string) error { + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return fmt.Errorf("creating GET request: %w", err) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("unhealthy status: %d", resp.StatusCode) + } + + return nil +} + +func main() { + flag.Parse() + + if *healthURL != "" { + if err := checkHealth(*healthURL); err != nil { + slog.Error(fmt.Sprintf("Health check failed: %v", err)) + os.Exit(1) + } + os.Exit(0) + } + + runtime.InitHTTP(cache) + runtime.InitCache(cache) + + http.HandleFunc("POST /tidbyt-push", pushHandler) + http.HandleFunc("POST /tidbyt-publish", publishHandler) + http.HandleFunc("POST /tidbyt-text", textHandler) + http.HandleFunc("POST /tidbyt-delete", deleteHandler) + http.HandleFunc("GET /health", healthHandler) + + slog.Info("Starting TidbytAssistant server") + if err := http.ListenAndServe(":9000", nil); err != nil { + slog.Error(fmt.Sprintf("Failed to start server: %v", err)) + } +} diff --git a/TidbytAssistant/scripts/TidbytDelete.sh b/TidbytAssistant/scripts/TidbytDelete.sh deleted file mode 100644 index 576fa08..0000000 --- a/TidbytAssistant/scripts/TidbytDelete.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -set -e - -# These will be sent directly from HomeAssistant -CONTENT_ID=${1:?"missing arg 1 for CONTENT_ID"} -TB_DEVICEID=${2:?"missing arg 2 for DEVICE ID"} -TB_TOKEN=${3:?"missing arg 3 for TOKEN"} - -/usr/local/bin/pixlet delete $TB_DEVICEID $CONTENT_ID --api-token $TB_TOKEN - -exit 0 diff --git a/TidbytAssistant/scripts/TidbytPublish.sh b/TidbytAssistant/scripts/TidbytPublish.sh deleted file mode 100644 index 0f78883..0000000 --- a/TidbytAssistant/scripts/TidbytPublish.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash -set -e - -# These will be sent directly from HomeAssistant -CONTENT=${1:?"missing arg 1 for CONTENT"} -TB_DEVICEID=${2:?"missing arg 2 for DEVICE ID"} -TB_TOKEN=${3:?"missing arg 3 for TOKEN"} -CONTENT_ID=${4:?"missing arg 4 for CONTENT_ID"} -PUBLISH_TYPE=${5:?"missing arg 5 for PUBLISH_TYPE"} -ARGS=${6:-} - -rm -f /tmp/* - -ROOT_DIR=/homeassistant/tidbyt -RENDER_PATH=/tmp/render.webp - -cp $ROOT_DIR/$CONTENT.star /tmp/$CONTENT.star -f -if [[ $ARGS ]]; then - arg=() - IFS=';' read -ra pairs <<< "$ARGS" - for pair in "${pairs[@]}"; do - IFS='=' read -r key value <<< "$pair" - arg+=("$key=$value") - done - /usr/local/bin/pixlet render /tmp/$CONTENT.star "${arg[@]}" -o $RENDER_PATH -else - /usr/local/bin/pixlet render /tmp/$CONTENT.star -o $RENDER_PATH -fi - -if [[ $PUBLISH_TYPE == 'background' ]]; then - /usr/local/bin/pixlet push --installation-id $CONTENT_ID --background --api-token $TB_TOKEN $TB_DEVICEID $RENDER_PATH -else - /usr/local/bin/pixlet push --installation-id $CONTENT_ID --api-token $TB_TOKEN $TB_DEVICEID $RENDER_PATH -fi - -exit 0 diff --git a/TidbytAssistant/scripts/TidbytPush.sh b/TidbytAssistant/scripts/TidbytPush.sh deleted file mode 100644 index ba0341c..0000000 --- a/TidbytAssistant/scripts/TidbytPush.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash -set -e - -# These will be sent directly from HomeAssistant -CONTENT=${1:?"missing arg 1 for CONTENT"} -TB_DEVICEID=${2:?"missing arg 2 for DEVICE ID"} -TB_TOKEN=${3:?"missing arg 3 for TOKEN"} -CONTENT_TYPE=${4:?"missing arg 4 for CONTENT_TYPE"} -ARGS=${5:-} - -rm -f /tmp/* - -case "$CONTENT_TYPE" in - "builtin") - ROOT_DIR=/opt/display ;; - "custom") - ROOT_DIR=/homeassistant/tidbyt ;; -esac - -RENDER_PATH=/tmp/render.webp - -cp $ROOT_DIR/$CONTENT.star /tmp/$CONTENT.star -f -if [[ $ARGS ]]; then - arg=() - IFS=';' read -ra pairs <<< "$ARGS" - for pair in "${pairs[@]}"; do - IFS='=' read -r key value <<< "$pair" - arg+=("$key=$value") - done - /usr/local/bin/pixlet render /tmp/$CONTENT.star "${arg[@]}" -o $RENDER_PATH -else - /usr/local/bin/pixlet render /tmp/$CONTENT.star -o $RENDER_PATH -fi - -/usr/local/bin/pixlet push --api-token $TB_TOKEN $TB_DEVICEID $RENDER_PATH - -exit 0 diff --git a/TidbytAssistant/scripts/TidbytText.sh b/TidbytAssistant/scripts/TidbytText.sh deleted file mode 100644 index 5704457..0000000 --- a/TidbytAssistant/scripts/TidbytText.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash -set -e - -CONTENT=${1:?"missing arg 1 for CONTENT"} -TB_DEVICEID=${2:?"missing arg 2 for DEVICE ID"} -TB_TOKEN=${3:?"missing arg 3 for TOKEN"} -TEXT_TYPE=${4:?"missing arg 4 for TEXT_TYPE"} -FONT=${5:?"missing arg 5 for FONT"} -COLOR=${6:?"missing arg 6 for COLOR"} -TITLE=${7:-} -TITLE_COLOR=${8:-} -TITLE_FONT=${9:-} - -rm -f /tmp/* - -ROOT_DIR=/tmp -FILE=text-$TEXT_TYPE - -cp /opt/display/$FILE.star $ROOT_DIR/$FILE.star -f - -RENDER_PATH=/tmp/render.webp - -if [[ "$TEXT_TYPE" == "title" ]]; then - /usr/local/bin/pixlet render $ROOT_DIR/$FILE.star content="$CONTENT" font="$FONT" color="$COLOR" title="$TITLE" titlecolor="$TITLE_COLOR" titlefont="$TITLE_FONT" -o $RENDER_PATH -else - /usr/local/bin/pixlet render $ROOT_DIR/$FILE.star content="$CONTENT" font="$FONT" color="$COLOR" -o $RENDER_PATH -fi - -/usr/local/bin/pixlet push --api-token $TB_TOKEN $TB_DEVICEID $RENDER_PATH - -exit 0