From 0656d74146bad1cda65751bb11da66a17a3f2970 Mon Sep 17 00:00:00 2001 From: Severin Schols Date: Mon, 9 Feb 2026 22:53:37 +0100 Subject: [PATCH 1/6] add docker magic, package.json --- .dockerignore | 3 +++ .env.sample | 7 +++++-- Dockerfile | 6 ++++++ compose.yml | 38 ++++++++++++++++++++++++++++++++++++++ package.json | 25 +++++++++++++++++++++++++ 5 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 compose.yml create mode 100644 package.json diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0fe2442 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +compose.yml +README.md +database \ No newline at end of file diff --git a/.env.sample b/.env.sample index ce32924..da7edfd 100644 --- a/.env.sample +++ b/.env.sample @@ -1,8 +1,11 @@ -DB_HOST="172.0.0.1" +DB_HOST="mariadb" +DB_ROOT_PASSWORD="root_password" DB_USER="openunitstate" DB_PASSWORD="" DB_NAME="openunitstate" +MQTT_URL="mqtt://broker.example.com:1883" MQTT_CLIENT_ID="njs_1" MQTT_USERNAME="ousbackendmaster" MQTT_PASSWORD="" -MQTT_PUB_CLIENT_ID="njs_publisher" \ No newline at end of file +MQTT_PUB_CLIENT_ID="njs_publisher" +ROOT_TOPIC="openunitstate" \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9f86808 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,6 @@ +FROM node:25 +WORKDIR /app +COPY package*.json ./ +RUN npm install +COPY . . +CMD ["npm", "start"] \ No newline at end of file diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..26d0f6b --- /dev/null +++ b/compose.yml @@ -0,0 +1,38 @@ +services: + mariadb: + image: mariadb:latest + environment: + MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} + MYSQL_DATABASE: ${DB_NAME} + MYSQL_USER: ${DB_USER} + MYSQL_PASSWORD: ${DB_PASSWORD} + volumes: + - ./database:/var/lib/mysql + - ./sql_structure_openunitstate.sql:/docker-entrypoint-initdb.d/init.sql + healthcheck: + test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] + timeout: 20s + retries: 10 + restart: unless-stopped + + app: + build: . + depends_on: + mariadb: + condition: service_healthy + environment: + DB_HOST: mariadb + DB_USER: ${DB_USER} + DB_PASSWORD: ${DB_PASSWORD} + DB_NAME: ${DB_NAME} + MQTT_URL: ${MQTT_URL} + MQTT_CLIENT_ID: ${MQTT_CLIENT_ID} + MQTT_USERNAME: ${MQTT_USERNAME} + MQTT_PASSWORD: ${MQTT_PASSWORD} + ROOT_TOPIC: ${ROOT_TOPIC} + restart: unless-stopped + +networks: + default: + driver: bridge + name: openunitstate \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..4adfa11 --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "name": "openunitstate-backend", + "version": "1.0.0", + "description": "Backend service for OpenUnitState", + "main": "app.js", + "scripts": { + "start": "node app.js", + "dev": "node app.js" + }, + "dependencies": { + "mqtt": "^4.3.7", + "mysql": "^2.18.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "keywords": [ + "mqtt", + "mysql", + "iot", + "unit-state" + ], + "author": "", + "license": "GPL-3.0-only" +} From 119458e49f10655730fd40373ccf57de12f18207 Mon Sep 17 00:00:00 2001 From: Severin Schols Date: Mon, 9 Feb 2026 23:12:49 +0100 Subject: [PATCH 2/6] names --- .env.sample | 2 +- compose.yml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.env.sample b/.env.sample index da7edfd..30dd97f 100644 --- a/.env.sample +++ b/.env.sample @@ -1,4 +1,4 @@ -DB_HOST="mariadb" +DB_HOST="db" DB_ROOT_PASSWORD="root_password" DB_USER="openunitstate" DB_PASSWORD="" diff --git a/compose.yml b/compose.yml index 26d0f6b..0d7c93b 100644 --- a/compose.yml +++ b/compose.yml @@ -1,5 +1,6 @@ +name: openunitstate-backend services: - mariadb: + db: image: mariadb:latest environment: MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} From 9838fc41518b861b6ff5f9692dbe31a2464bb387 Mon Sep 17 00:00:00 2001 From: Severin Schols Date: Mon, 9 Feb 2026 23:14:02 +0100 Subject: [PATCH 3/6] missed dependency --- compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose.yml b/compose.yml index 0d7c93b..d5ce413 100644 --- a/compose.yml +++ b/compose.yml @@ -19,7 +19,7 @@ services: app: build: . depends_on: - mariadb: + db: condition: service_healthy environment: DB_HOST: mariadb From 6e7ef0a170c287e248560ef3736b91aa3e2f7f7e Mon Sep 17 00:00:00 2001 From: Severin Schols Date: Mon, 9 Feb 2026 23:57:28 +0100 Subject: [PATCH 4/6] another miss --- compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose.yml b/compose.yml index d5ce413..c6dd951 100644 --- a/compose.yml +++ b/compose.yml @@ -22,7 +22,7 @@ services: db: condition: service_healthy environment: - DB_HOST: mariadb + DB_HOST: db DB_USER: ${DB_USER} DB_PASSWORD: ${DB_PASSWORD} DB_NAME: ${DB_NAME} From 0d7e191683167d6f9634264aa2a2b83eaf6e2387 Mon Sep 17 00:00:00 2001 From: IT crew Date: Fri, 13 Mar 2026 22:32:21 +0100 Subject: [PATCH 5/6] finalize docker setup --- .dockerignore | 4 +++- .gitignore | 1 + compose.yml | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.dockerignore b/.dockerignore index 0fe2442..4d5d1a9 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,5 @@ +.env compose.yml README.md -database \ No newline at end of file +database +database diff --git a/.gitignore b/.gitignore index 33cca4c..4feb209 100644 --- a/.gitignore +++ b/.gitignore @@ -137,3 +137,4 @@ dist # Vite logs files vite.config.js.timestamp-* vite.config.ts.timestamp-* +database diff --git a/compose.yml b/compose.yml index c6dd951..b2495e4 100644 --- a/compose.yml +++ b/compose.yml @@ -36,4 +36,4 @@ services: networks: default: driver: bridge - name: openunitstate \ No newline at end of file + name: openunitstate From c2a4075f9d44085d9e0c3acd0cc460e637220044 Mon Sep 17 00:00:00 2001 From: IT crew Date: Fri, 13 Mar 2026 22:33:41 +0100 Subject: [PATCH 6/6] OUS firmware does not deal with unitOrg in mqtt topic -> removing it --- app.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/app.js b/app.js index 91cfc46..0e30271 100644 --- a/app.js +++ b/app.js @@ -93,9 +93,9 @@ function parseMessage(topic, message) { var meta = topic.replace(ROOT_TOPIC + "/", "").split("/") - var orgId = meta[0] - var chipId = meta[1] - var func = meta[2] + var orgId = '-1' // meta[0] + var chipId = meta[0] + var func = meta[1] var payload = message.toString() return { @@ -142,10 +142,10 @@ async function pushUnitConfig(chipId) { var name = await getUnitName(chipId) var unitOrg = await getUnitOrg(chipId); if (unitOrg != null) { - console.log("Setting name on", chipId, "mqtt message:", ROOT_TOPIC + "/" + unitOrg + "/" + chipId + "/config_name", name) - mqtt_client.publish(ROOT_TOPIC + "/" + unitOrg + "/" + chipId + "/config_name", name) - console.log("Setting status on", chipId, "mqtt message:", ROOT_TOPIC + "/" + unitOrg + "/" + chipId + "/config_status", status) - mqtt_client.publish(ROOT_TOPIC + "/" + unitOrg + "/" + chipId + "/config_status", status.toString()) + console.log("Setting name on", chipId, "mqtt message:", ROOT_TOPIC + "/" + chipId + "/config_name", name) + mqtt_client.publish(ROOT_TOPIC + "/" + chipId + "/config_name", name) + console.log("Setting status on", chipId, "mqtt message:", ROOT_TOPIC + "/" + chipId + "/config_status", status) + mqtt_client.publish(ROOT_TOPIC + "/" + chipId + "/config_status", status.toString()) } else { console.log(chipId, "unitOrg is null") } @@ -328,8 +328,8 @@ async function unlockUnit(chipId, unlockTime = 0) { return; } unlockTime = unlockTime * 1000; - console.log("Unlocking", chipId, "mqtt message:", ROOT_TOPIC + "/" + unitOrg + "/" + chipId + "/unlocked_time", unlockTime) - mqtt_client.publish(ROOT_TOPIC + "/" + unitOrg + "/" + chipId + "/unlocked_time", unlockTime.toString()) + console.log("Unlocking", chipId, "mqtt message:", ROOT_TOPIC + "/" + chipId + "/unlocked_time", unlockTime) + mqtt_client.publish(ROOT_TOPIC + "/" + chipId + "/unlocked_time", unlockTime.toString()) } else { console.log("unlockUnit: Couldn't find org associated with chipId", chipId); } @@ -341,8 +341,8 @@ async function showMessage(chipId, message) { var unitOrg = await getUnitOrg(chipId); console.log(unitOrg) if (unitOrg != null) { - console.log("Showing message", ROOT_TOPIC + "/" + unitOrg + "/" + chipId + "/quick_display_msg", message) - mqtt_client.publish(ROOT_TOPIC + "/" + unitOrg + "/" + chipId + "/quick_display_msg", message) + console.log("Showing message", ROOT_TOPIC + "/" + chipId + "/quick_display_msg", message) + mqtt_client.publish(ROOT_TOPIC + "/" + chipId + "/quick_display_msg", message) } }); }