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 _

  • SalamanderMA
    link
    fedilink
    arrow-up
    4
    ·
    6 hours ago

    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) 
    
    • mesamune@lemmy.world
      link
      fedilink
      English
      arrow-up
      4
      ·
      edit-2
      6 hours ago

      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.

      • SalamanderMA
        link
        fedilink
        arrow-up
        3
        ·
        4 hours ago

        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!