this post was submitted on 08 Feb 2025
64 points (100.0% liked)

Meshtastic

545 readers
2 users here now

A community to discuss Meshtastic (https://meshtastic.org/docs/introduction)

founded 1 year ago
MODERATORS
 

Made a python script to create posts via meshtastic messages. If you can see this, the test worked! Posting from the park with no mobile data ^_^

you are viewing a single comment's thread
view the rest of the comments
[–] Sal@mander.xyz 4 points 2 weeks ago (1 children)

For sure. It is quite basic and I am not proud of the hacky method I used to "parse" the message, but it might be useful for someone looking for a simple way to interface with a meshtastic device over TCP (onReceive) and the Lemmy API (createPost).

import json
import re
import meshtastic
import meshtastic.tcp_interface
from pubsub import pub
import time
import os
import requests


INSTANCE_API = "https://mander.xyz/api/v3"
MESHTEST_LEMMY_JWT = 'Cookie retrieved from browser'



def createPost(community_name, subject, body):
    url = f"{INSTANCE_API}/post"
    getCommunity = requests.get(f"{INSTANCE_API}/community?name={community_name}").json()
    communityId = getCommunity['community_view']['community']['id']
    data = {
        "community_id": communityId,
        "name": subject,
        "body": body}
    headers = {
        "Authorization": f"Bearer {MESHTEST_LEMMY_JWT}",
        "Content-Type": "application/json"
    }
    response = requests.post(url, headers=headers, json=data)
    return response


MESHTASTIC_NODE_IP = "Local IP of the base node connected to WiFi"

def sstrip(text):
 return re.sub(r'(?:\s|,)*(sub|SUB|Sub|COM|com|Com|Bod|bod|BOD)(?:\s|,)*$', '', text.strip())

def processMessage(message):
    blocks = message.split(':')    # Splits the message into blocks, but will also split smiley faces ":)", bad method. 
    try:
        for i in range(0,len(blocks)-1):
            if blocks[i][-3:].lower() == 'sub':
                subject = sstrip(blocks[i+1])
            if blocks[i][-3:].lower() == 'com':
                community_name = sstrip(blocks[i+1]).lower()
            if blocks[i][-3:].lower() == 'bod':
                body = sstrip(blocks[i+1])
        return community_name, subject, body
    except:
        return 'ERR','ERR','ERR'

def onReceive(packet, interface):
    if 'decoded' in packet and 'payload' in packet['decoded']:
        try:
            message = packet['decoded']['payload'].decode('utf-8')
            sender = packet['from']
            if 'Ping' in message:
                interface.sendText("Pong!", destinationId=sender)
            if message.split('\n')[0] == 'PST':
              try:
                community_name, subject, body = processMessage(message)
                response = createPost(community_name, subject, body)
                if response.ok:
                  interface.sendText("Post created succesfully!", destinationId=sender)
                else:
                  interface.sendText("Unable to create post!", destinationId=sender)
              except:
               interface.sendText("Exception triggered", destinationId=sender)
        except Exception as e:
            pass

interface = meshtastic.tcp_interface.TCPInterface(hostname=MESHTASTIC_NODE_IP)
pub.subscribe(onReceive, "meshtastic.receive")

while True:
    time.sleep(2) 
[–] mesamunefire@lemmy.world 4 points 2 weeks ago* (last edited 2 weeks ago) (1 children)

On a side note, I love how python looks on lemmy. This is awesome! I really like the way you parse the message, its readable.

            if 'Ping' in message:
                interface.sendText("Pong!", destinationId=sender)

Im totally doing that to test out my node(s).

Great job on this. I may take some of this later.

Here is the weather code (fat fingered the name, cant be bothered to change): https://yuno.chrisco.me/git/michael/meshtastic_forceast/src/branch/main/main.py

Heavily influenced by something I found online a while back which I lost the reference to.

Im guessing you were a C/C# dev based on the function names.

[–] Sal@mander.xyz 3 points 2 weeks ago (1 children)

Glad you like it :D

The ping is very useful. I know that there is a built-in range test, but sometimes I don't need the test to be on all the time, nor do I want to set the frequency too high. Actually.... This give me an idea, I can simply program a command to turn the range test off/on remotely.

That weather function is nice! The US makes available some nice weather APIs. I have a PinePhone and it has a weather module that relies on a US-based API, but I am not in the US. At least I can find out the weather in Oregon easily. I don't know if there is some similar API in the Netherlands.

Im guessing you were a C/C# dev based on the function names.

I helped re-factor some C++-based micro-controller firmware recently and the original code was not following any convention, so I looked at a list of conventions and decided that 'lower camel case' looked like a nice one to pick. So, I have been developing a habit to stick to that. I do scientific r&d and only sometimes need to do a bit of programming, so I'm not sure if I'd call myself a dev!

[–] mesamunefire@lemmy.world 2 points 2 weeks ago

You created code, congrats you are a "coder" ;)