Mikrotik GPS Script: Only Send Data When Speed Is Above 0 km/h

Hi everyone,

I’m using a Mikrotik LtAP LR8 (RouterOS 7.19) to send GPS data to a Traccar server via HTTP.
My goal is to only send data if the speed is NOT 0 km/h (in other words: when the vehicle is moving).
To test the script more easily, I set the threshold to 5 km/h – so if speed is not 5 km/h, it should send (when standing, the GPS gives me 0 km/h).

Here is my current script.
Can anyone spot an error, or tell me why it sometimes won’t send, even when the conditions are true?
Debug output looks correct, but the HTTP request is sometimes not triggered.

# Config: Set the speed which will NOT be logged/sent (for testing: 5)
:local skipSpeed 5
# Debug output (1 = enabled, 0 = disabled)
:local debug 1

# Get GPS data
:local gps [/system gps monitor once as-value]
:local lat ($gps->"latitude")
:local lon ($gps->"longitude")
:local alt ($gps->"altitude")
# Clean altitude
:if ([:typeof $alt] = "str") do={ :set alt [:pick $alt 0 [:find $alt " "]] }
:local speed ($gps->"speed")
# Clean speed (remove unit)
:if ([:typeof $speed] = "str") do={ :set speed [:pick $speed 0 [:find $speed " "]] }
:local bearing ($gps->"true-bearing")
# Clean bearing
:if ([:typeof $bearing] = "str") do={ :set bearing [:pick $bearing 0 [:find $bearing " "]] }
:local satellites ($gps->"satellites")
:local valid ($gps->"valid")

# Extract integer part of speed for comparison
:local speedInt [:pick $speed 0 [:find $speed "."]]
:if ($speedInt = "") do={ :set speedInt "0" }
:local numSpeedInt [:tonum $speedInt]
:local numSkipSpeed [:tonum $skipSpeed]

# Debug output for all relevant variables
:if ($debug = 1) do={
  :log info ("DEBUG: lat=" . $lat . " lon=" . $lon . " speed=" . $speed . " speedInt=" . $speedInt . " numSpeedInt=" . $numSpeedInt . " skipSpeed=" . $skipSpeed . " numSkipSpeed=" . $numSkipSpeed . " valid=" . $valid)
}

# Only send if speed is NOT equal to skipSpeed (e.g. 5) AND GPS is valid
:if (($valid = "true") && ($numSpeedInt != $numSkipSpeed)) do={
    :if ($debug = 1) do={ :log info ("SENT: speedInt=" . $speedInt) }
    /tool fetch keep-result=no url=("http://192.168.0.15:5055/?id=onkel-friedrich&lat=$lat&lon=$lon&altitude=$alt&speed=$speed&course=$bearing&satellites=$satellites&valid=$valid")
} else={
    :if ($debug = 1) do={ :log warning ("NOT SENT! valid=" . $valid . " speedInt=" . $speedInt . " numSpeedInt=" . $numSpeedInt . " skipSpeed=" . $skipSpeed . " numSkipSpeed=" . $numSkipSpeed) }

Log:

NOT SENT! valid=true speedInt=0 numSpeedInt=0 skipSpeed=5 numSkipSpeed=5

Questions:

Is my logic for comparing the speed integer correct?

Could there be a RouterOS scripting “trap” (e.g., type conversions, invisible characters) that breaks the IF statement?

Why might the script not trigger the HTTP request even though, according to the debug, the condition should be TRUE?

Thanks for any hints!

In you if sentence you are comparing $valid with a string, while its type is bool:

 
 :if (($valid = "true") && ($numSpeedInt != $numSkipSpeed)) do={

I would either remove the quotes:

 
 :if (($valid = true) && ($numSpeedInt != $numSkipSpeed)) do={

… or remove the comparison with true completely:

 
 :if ($valid && ($numSpeedInt != $numSkipSpeed)) do={

Also,

You are checking that $numSpeedInt is not equal to $numSkipSpeed:

$numSpeedInt != $numSkipSpeed

While you should probably be checking if $numSpeedInt is larger than $numSkipSpeed

:if ($valid && ($numSpeedInt > $numSkipSpeed)) do={