API send Gcode and get back information from console log

Hi, after searching a lot in API documentation, API demo script and the forum my question is still unanswered / have no idea how to do that. What i want to do is to send different GCodes to a printer and get their response from log line. This is not time critical. The sending gcode part works - i can see this in Repetier Server UI > Console. Doing from bash:

CMD='{"cmd":"M552"}' #empty response
source /opt/urlcoder.sh && ENC_CMD=$(urlencode $CMD)
curl "http://localhost:3344/printer/api/myPrinter?apikey=AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEEEE&a=send&data=$ENC_CMD"
But how do i catch the result?

in the UI it prints:
23:47:24.408: Network is enabled, configured IP address: 0.0.0.0, actual IP address: 10.149.10.80
i think it has to be done with the action called "response". Could you please help me with some example? What i want to grab is the actual IP address in this example. And id like to be able to parse other output from other M/G commands later

regards, Mario





Comments

  • Ok, there is no way to get directly responses to a special g-code. Reason is responses from firmware are not marked to belong to a special g-code.

    You have 2 possible solution.
    Bad solution is to enable logging in frontend and watch all responses for the one you need. This increases traffic and load and is not very elegant.

    The better solution is to make the server scan for a special response and send an event with the line content. You can do this in printer configuration->g-codes->advanced. There you define a regular expression to detect your line. If you assign a event name, it will issue an event like other server events just with the name given and the line and matched string of first group as content. Alternatively you can send a gocde in response. But that is the easiest and best way to do it.
  • Hi, i am trying this. first thing i recognized is a UI bug. You cannot save an event if the field "G-code to execute" is empty but the UI says "configuration saved".
  • edit: entering a whitespace will work. I want this "monitoring-only" event so it should do not trigger any other G/M Code

    The demo script puts out the line i need. How do i get this from bash curl?
    {
      "data": {
        "line": "Network is enabled, configured IP address: 0.0.0.0, actual IP address: 10.149.10.195",
        "match": ""
      },
      "event": "IP Adresse",
      "printer": "myPrinter"
    }

  • Since it is an event, you only get it if you have an open websocket connection.
    If you need to trigger an action you could in this case use the gcode to execute a script and do something with the ip you get as parameter.

    A empty line is no issue and gets not executed, but will check why save did not work. Is not supposed to happen.
  • edited March 2020
    Hi, thanks for your feedback. I got it working basically. Due the fact i did not find a handy example for shell scripting, i just share some lines of code for websocket communication which might help other users. Its really simple but it took me some time to understand (because i never worked with websockets)

    # get websocat tool to "stream" open websocket from Repetier Server to local console
    # get arm build and create some symlink for handy usage
    cd /usr/bin
    wget https://github.com/vi/websocat/releases/download/v2.0.0-alpha0/websocat_arm-linux
    chmod +x websocat_arm-linux
    ln -sf websocat_arm-linux websocat

    # call the websocket from Repetier Server instance - some basic command
    ./websocat ws://localhost:3344/socket

    # the result:
    {"callback_id":-1,"data":[{"data":{"session":"&e!gy3fXxXBOdb^HO80QwDqV%Tnu76AF"},"event":"loginRequired","printer":""}],"eventList":true}

    #So Just attach the apikey to login accordingly:
    websocat ws://localhost:3344/socket?apikey=YOURKEY

    # And to send something to Repetier, use thins for instance:
    echo '{"callback_id":-1,"data":{},"action":"stateList","printer":"myPrinter"}' | websocat ws://localhost:3344/socket?apikey=YOURKEY


    To grep out some event just do
    websocat ws://localhost:3344/socket?apikey=YOURKEY | grep IP

    And if you want to run websocat feedback loop all the time you can pipe all the output into screen session. I just played a bit with this. I think this is not professional but might be useful too. I know that's weird because it's just output which could be written by Repetier Server directly into some regular log file. Maybe this is the case but i didn't find the according output file? Maybe what i am doing slows down the server?
    #step 1 - if not already present on system
    apt install screen

    #step 2 - create some .sh file and chmod +x it

    #!/bin/bash
    #this script will get all the websocket output from Repetier Server by writing it into log file
    # define some basic stuff
    API_KEY="YOURKEY" # some valid API key
    HOST="localhost" # default: localhost
    PORT="3344" # default: 3344
    WS="ws" # might also be wss
    SLUG="myPrinter" # the printer name (see URLs in browser to get the slug name)
    LOG_FILE="/opt/repetier-monitor/websocat_out.log"

    #make a new screen to deal with websocat session. nohup and & background streaming did not work
    screen -d -m sh -c "websocat '${WS}://${HOST}:${PORT}/socket?apikey=${API_KEY}' | tee ${LOG_FILE}"

    #step 3 - run the script
    screen -list #check if it's running. If you want to show the screen itself run screen -R to attach to the detached screen session

    # step 4 - check output log (what you really want)
    tail -f /opt/repetier-monitor/websocat_out.log

    # step 5 - do whatever you want with that kind of log









  • This is some self update for this thread - just to collect some examples ;-)

    /opt/urlcoder.sh (googled)
    urlencode() {
    # urlencode <string>
    old_lc_collate=$LC_COLLATE
    LC_COLLATE=C

    local length="${#1}"
    for (( i = 0; i < length; i++ )); do
    local c="${1:i:1}"
    case $c in
    [a-zA-Z0-9.~_-]) printf "$c" ;;
    *) printf '%%%02X' "'$c" ;;
    esac
    done

    LC_COLLATE=$old_lc_collate
    }

    urldecode() {
    # urldecode <string>

    local url_encoded="${1//+/ }"
    printf '%b' "${url_encoded//%/\\x}"
    }

    A script to get the recent network ip address from a Duet 2 Ethernet controller which is connected to USB serial @ Repetier Server

    Reason i did this: a bit more complex too explain. It's main reason is because it's not in a regular home network.
    Reason i post: show how to websocket Repetier, how to curl Repetier, how to filter content with jq and some other

    /opt/duet_ip.sh
    #!/bin/bash
    # this script will read the current IP Adress by using a pre-defined custom event in Repetier Server. Please see documentation for more details on how to do that

    # define some basic stuff
    API_KEY="SOMEKEY" # some valid API key
    HOST="localhost" # default: localhost
    PORT="3344" # default: 3344
    WS="ws" # might also be wss
    SLUG="myPrinter" # the printer name (see URLs in browser to get the slug name)
    LOG_FILE="/opt/duet_ip.log"

    # remove old log file if existent
    rm "${LOG_FILE}" > /dev/null 2>&1

    # make a new screen called "RepetierWebsocat" to deal with websocat session. nohup and & background streaming did not work
    screen -d -m -L "${LOG_FILE}" -S RepetierWebsocat sh -c "websocat '${WS}://${HOST}:${PORT}/socket?apikey=${API_KEY}'"

    HTTP_PROTO="http"

    # send the IP address call
    CMD='{"cmd":"M552"}' # empty response
    source /opt/urlcoder.sh # source methods to use them in this script
    ENC_CMD=$(urlencode $CMD) # build some encoded command

    # empty result. so pipe it to /dev/null
    curl --silent "${HTTP_PROTO}://${HOST}:${PORT}/printer/api/${SLUG}?apikey=${API_KEY}&a=send&data=$ENC_CMD" > /dev/null

    # wait 2 seconds then continue to close screen - desired data should have been captured in this time
    sleep 2

    # destroy screen and ignore output
    screen -R RepetierWebsocat -X quit > /dev/null 2>&1

    # get the line which contains the desired IP address information
    RAW=$(grep "actual IP address" "${LOG_FILE}")

    # filter Duet's IP address
    DUET_IP_ADDR=$(jq -r '.|{data}|.[]|.[]|.data|select(.line)|.line' <<< $RAW | awk '{print $(NF)}')

    echo $DUET_IP_ADDR





  • edited March 2020
    Looks like you are better with bash than me. Quite some overhead. My solution would probably have been the event solution and running a script with @execute that writes last reported ip into a file that you can read with other scripts any time. Then maybe in connect script already add M552 so you get IP directly when it connects automatically.

    But otherwise, your solution is a cool example what is possible with a simple script and joining some commands.
  • edited March 2020
    Hey,

    actually i am not aware of how to do the thing with @execute. Are there some docs which explain this action a bit better? To retrieve some file containing that event would sureley exactly be the thing i am looking for (where are they stored - whats the location?). I'd like to simplify because the more spaghetti code i produce, more comments to explain, and more bugs are in and it's not compatible to other platforms maybe.
  • i guess i found some ressources:

    is there some example on how to integrate this? I could write some lua but how do i wire it to be fired from @execute event listener? where are the method names declared?

    is it like @execute "doCoolStuff" to call a same name file called "doCoolStuff.lua" in the /var/lib/Repetier-Server/lua/ dir?




  • The docs for @execute are in our user manual in section "Advanced Setup". Basically you define a shell command in a file named extcommands.xml in database directory. These can accept parameter (if allowed) so you can add the event result as parameter. Would be a simple bash script in your case, no lua required.

    Lua is not reachable with @execute - it is more for code you want to run server side. It can e.g. add new api commands or react on events.
Sign In or Register to comment.