diff --git a/README.md b/README.md index 3c339bb..e9715c3 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ Relay operation is implemented using the **Meshtastic <=> Matrix Relay** [https: Feel free to explore the **Meshtastic** project on their website: [https://meshtastic.org](https://meshtastic.org). +``` git clone https://github.com/mate-dev/mmrelaynode.git cd mmrelaynode && git submodule update --init docker compose -f "docker-compose.yaml" up -d --build +``` \ No newline at end of file diff --git a/app/Dockerfile b/app/Dockerfile index a654ede..10459ae 100644 --- a/app/Dockerfile +++ b/app/Dockerfile @@ -2,14 +2,11 @@ FROM python:3.11-slim-bookworm AS app LABEL "website"="https://github.com/mate-dev/mmrelaynode" RUN groupadd -g 1000 mesh && useradd -ml -u 1000 -g 1000 -s /bin/bash mesh RUN pip install --upgrade pip -qq +ADD https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh /usr/local/bin/wait-for-it.sh +RUN chmod +x /usr/local/bin/wait-for-it.sh RUN ln -s /home/mesh/.local/bin/meshtastic /bin/meshtastic USER mesh COPY --chown=mesh:mesh meshtastic-matrix-relay /home/mesh/app WORKDIR /home/mesh/app RUN pip install -qq -r /home/mesh/app/requirements.txt --no-cache-dir -RUN echo "export PATH=/home/mesh/.local/bin:\$PATH" >> /home/mesh/.bashrc -COPY --chown=mesh:mesh config.yaml . -#ENTRYPOINT ["sh", "-c", "sleep 30 && python3 main.py"] - - - +RUN echo "export PATH=/home/mesh/.local/bin:\$PATH" >> /home/mesh/.bashrc \ No newline at end of file diff --git a/app/command_wrapper.py b/app/command_wrapper.py new file mode 100644 index 0000000..0e58d21 --- /dev/null +++ b/app/command_wrapper.py @@ -0,0 +1,22 @@ +import os +import subprocess +import time + +def execute_meshtastic_command(options): + """Execute a meshtastic command with the given options.""" + command = ["meshtastic", "--set"] + options.split() + subprocess.run(command) + time.sleep(30) # Pause for 30 seconds + +# Loop through environment variables in sequence +index = 1 +while True: + command = os.environ.get(f'MESHTASTIC_COMMAND_{index}') + if command: + execute_meshtastic_command(command) + index += 1 + else: + break + +# Finally, run the main Meshtastic process (or whatever process you want to keep the container running) +subprocess.run(["meshtastic"]) diff --git a/app/conf_wrapper.py b/app/conf_wrapper.py new file mode 100644 index 0000000..97a4fe3 --- /dev/null +++ b/app/conf_wrapper.py @@ -0,0 +1,58 @@ +import os +import yaml + +# Read environment variables and construct the configuration dictionary +relay_config = { + "matrix": { + "homeserver": os.environ.get('MATRIX_HOMESERVER'), + "access_token": os.environ.get('MATRIX_ACCESS_TOKEN'), + "bot_user_id": os.environ.get('MATRIX_BOT_USER_ID') + }, + "meshtastic": { + "connection_type": os.environ.get('MESHTASTIC_CONNECTION_TYPE'), + "serial_port": os.environ.get('MESHTASTIC_SERIAL_PORT'), + "host": os.environ.get('MESHTASTIC_HOST'), + "meshnet_name": os.environ.get('MESHTASTIC_MESHNET_NAME'), + "broadcast_enabled": os.environ.get('MESHTASTIC_BROADCAST_ENABLED') == 'true' + }, + "logging": { + "level": os.environ.get('LOGGING_LEVEL') + } +} + +# Construct the matrix_rooms list based on environment variables +matrix_rooms = [] +for i in range(1, 9): # Loop for 8 rooms + room_id = os.environ.get(f'MATRIX_ROOMS_ID_{i}') + meshtastic_channel = os.environ.get(f'MATRIX_ROOMS_MESHTASTIC_CHANNEL_{i}') + if room_id and meshtastic_channel is not None: + matrix_rooms.append({ + "id": room_id, + "meshtastic_channel": int(meshtastic_channel) + }) + +# Add the matrix_rooms list to the relay_config dictionary +relay_config["matrix_rooms"] = matrix_rooms + +# Construct the plugins dictionary based on environment variables +plugins_config = {} + +health_plugin_active = os.environ.get('HEALTH_PLUGIN_ACTIVE') +if health_plugin_active: + plugins_config["health"] = {"active": health_plugin_active.lower() == "true"} + +map_plugin_active = os.environ.get('MAP_PLUGIN_ACTIVE') +if map_plugin_active: + plugins_config["map"] = {"active": map_plugin_active.lower() == "true"} + +nodes_plugin_active = os.environ.get('NODES_PLUGIN_ACTIVE') +if nodes_plugin_active: + plugins_config["nodes"] = {"active": nodes_plugin_active.lower() == "true"} + +# Add the plugins dictionary to the relay_config if it's not empty +if plugins_config: + relay_config["plugins"] = plugins_config + +# Write the configuration to config.yaml +with open("config.yaml", "w") as f: + yaml.dump(relay_config, f) diff --git a/app/config.yaml b/app/config.yaml deleted file mode 100644 index 4d0b05c..0000000 --- a/app/config.yaml +++ /dev/null @@ -1,30 +0,0 @@ -matrix: - homeserver: "https://example.matrix.org" - access_token: "reaalllllyloooooongsecretttttcodeeeeeeforrrrbot" # See: https://t2bot.io/docs/access_tokens/ - bot_user_id: "@botuser:example.matrix.org" - -matrix_rooms: # Needs at least 1 room & channel, but supports all Meshtastic channels - - id: "#someroomalias:example.matrix.org" # Matrix room aliases & IDs supported - meshtastic_channel: 0 - - id: "!someroomid:example.matrix.org" - meshtastic_channel: 2 - -meshtastic: - connection_type: network # Do not change! - # serial_port: /dev/ttyUSB0 # Only used when connection is "serial" - host: "mmrelaynode" # Do not change! - meshnet_name: "Your Meshnet Name" # This is displayed in full on Matrix, but is truncated when sent to a Meshnet - broadcast_enabled: true - hwid: "12345" # Change to your Hardware ID - -logging: - level: "info" - -plugins: # Optional plugins - health: - active: true - map: - active: true - nodes: - active: true - \ No newline at end of file diff --git a/node/Dockerfile b/device/Dockerfile similarity index 100% rename from node/Dockerfile rename to device/Dockerfile diff --git a/docker-compose.yaml b/docker-compose.yaml index 303ec86..58b144a 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,9 +1,10 @@ -version: "3" +version: '3.8' + services: mmrelaynode: build: node image: mmrelaynode:latest - container_name: mmrelay-node + container_name: mmrelaynode-device restart: unless-stopped volumes: - mesh:/home/mesh @@ -12,23 +13,60 @@ services: networks: - mesh entrypoint: ["sh", "-c", "meshtasticd"] + environment: + MESHTASTIC_COMMAND_1: "--set-owner 'LongName' --set-owner-short 'SHRT' --set-url https://meshtastic.org/e/#CgMSAQESDAgBOAFAA0gBUB5oAQ" + MESHTASTIC_COMMAND_2: "--set mqtt.enabled true --set mqtt.address mqtt.meshtastic.org --set mqtt.username meshdev --set mqtt.password large4cats" + MESHTASTIC_COMMAND_3: "--ch-set uplink_enabled true --ch-set downlink_enabled true --ch-index 3" + # You can add as many MESHTASTIC_COMMAND_X as you need, they will be executed in order with a 30 second delay between mmrelayapp: build: app image: mmrelayapp:latest - container_name: mmrelay-app + container_name: mmrelaynode-app restart: unless-stopped depends_on: - mmrelaynode volumes: - mesh:/home/mesh networks: - - mesh - command: ["sleep 30"] - entrypoint: ["python3", "main.py"] - -volumes: - mesh: + - mesh + entrypoint: [ "sh", "-c", "wait-for-it.sh mmrelaynode:4403 -t 60 && python3 command_wrapper.py && python3 conf_wrapper.py && python3 main.py" ] + environment: + MATRIX_HOMESERVER: "https://example.matrix.org" + MATRIX_ACCESS_TOKEN: "your_access_token" + MATRIX_BOT_USER_ID: "@botuser:example.matrix.org" + MESHTASTIC_CONNECTION_TYPE: "serial" # "serial" or "network" + MESHTASTIC_SERIAL_PORT: "/dev/ttyUSB0" + MESHTASTIC_HOST: "meshtastic.local" + MESHTASTIC_MESHNET_NAME: "Your Meshnet Name" + MESHTASTIC_BROADCAST_ENABLED: "true" + LOGGING_LEVEL: "info" + # Need at least 1 room & channel mapped, maximum 8 + MATRIX_ROOMS_ID_1: "#someroomalias1:example.matrix.org" + MATRIX_ROOMS_MESHTASTIC_CHANNEL_1: "0" + # MATRIX_ROOMS_ID_2: "#someroomalias2:example.matrix.org" + # MATRIX_ROOMS_MESHTASTIC_CHANNEL_2: "1" + # MATRIX_ROOMS_ID_3: "#someroomalias3:example.matrix.org" + # MATRIX_ROOMS_MESHTASTIC_CHANNEL_3: "2" + # MATRIX_ROOMS_ID_4: "#someroomalias4:example.matrix.org" + # MATRIX_ROOMS_MESHTASTIC_CHANNEL_4: "3" + # MATRIX_ROOMS_ID_5: "#someroomalias5:example.matrix.org" + # MATRIX_ROOMS_MESHTASTIC_CHANNEL_5: "4" + # MATRIX_ROOMS_ID_6: "#someroomalias6:example.matrix.org" + # MATRIX_ROOMS_MESHTASTIC_CHANNEL_6: "5" + # MATRIX_ROOMS_ID_7: "#someroomalias7:example.matrix.org" + # MATRIX_ROOMS_MESHTASTIC_CHANNEL_7: "6" + # MATRIX_ROOMS_ID_8: "#someroomalias8:example.matrix.org" + # MATRIX_ROOMS_MESHTASTIC_CHANNEL_8: "7" + + # Plugin environment variables + # HEALTH_PLUGIN_ACTIVE: "true" + # MAP_PLUGIN_ACTIVE: "true" + # NODES_PLUGIN_ACTIVE: "true" networks: mesh: + driver: bridge + +volumes: + mesh: