...
# Required packages: iot
################################ Configuration ################################
# Name of an existing MQTT broker that should be used for publishing
:local broker "tb"# MQTT topic where the message should be published
:local topic "v1/devices/me/telemetry"# Interface whose MAC should be used as 'Locator ID'
:local locatorIface "ether1"# POSIX regex for filtering advertisement Bluetooth addresses. E.g. "^BC:33:AC"
# would only include addresses which start with those 3 octets.
# To disable this filter, set it to ""
:local addressRegex "2C:C8:1B:4B:BB:0A"# POSIX regex for filtering Bluetooth advertisements based on their data. Same
# usage as with 'addressRegex'.
:local advertisingDataRegex ""# Signal strength filter. E.g. -40 would only include Bluetooth advertisements
# whose signal strength is stronger than -40dBm.
# To disable this filter, set it to ""
:local rssiThreshold ""####The lines below are used for the data conversion from hex to dec###
:local from88 do={
:global invertU16
:global le16ToHost
:local num [$le16ToHost $1]# Handle negative numbers
:if ($num & 0x8000) do={
:set num (-1 * ([$invertU16 $num] + 1))
}# Convert from 8.8. Scale by 1000 since floating point is not supported
:return (($num * 125) / 32)
}#################################### System ###################################
:put ("[*] Gathering system info...")
:local ifaceMac [/interface get [/interface find name=$locatorIface] mac-address]
:local cpuLoad [/system resource get cpu-load]
:local freeMemory [/system resource get free-memory]
:local usedMemory ([/system resource get total-memory] - $freeMemory)
:local rosVersion [/system package get value-name=version \
[/system package find where name ~ "^routeros"]]
:local model [/system routerboard get value-name=model]
:local serialNumber [/system routerboard get value-name=serial-number]
# Health is a bit iffy since '/system health' does not have 'find' in ROS6
:local health [/system health print as-value]
:local supplyVoltage 0
:local boardTemp 0
:foreach entry in=$health do={
:if ($entry->"name" = "voltage") do={:set $supplyVoltage ($entry->"value")}
:if ($entry->"name" = "board-temperature1") do={:set $boardTemp ($entry->"value")}
}################################## Bluetooth ##################################
:put ("[*] Gathering Bluetooth info...")
:global btOldestAdvertisementTimestamp
:if ([:typeof $btOldestAdvertisementTimestamp] = "nothing") do={
# First time this script has been run since booting, need to initialize
# persistent variables
:set $btOldestAdvertisementTimestamp 0
}
:local btProcessingStart [/system clock get time]
:local advertisements [/iot bluetooth scanners advertisements print detail \
as-value where \
epoch > $btOldestAdvertisementTimestamp and \
address ~ $addressRegex and \
data ~ $advertisingDataRegex and \
rssi > $rssiThreshold
]
:local advJson ""
:local advCount 0
:local advSeparator ""
:local lastAdvTimestamp 0
# Remove semicolons from MAC/Bluetooth addresses
:local minimizeMac do={
:local minimized
:local lastIdx ([:len $address] - 1)
:for idx from=0 to=$lastIdx step=1 do={
:local char [:pick $address $idx]
:if ($char != ":") do={
:set $minimized "$minimized$char"
}
}
:return $minimized
}:foreach adv in=$advertisements do={
:local address ($adv->"address")
:local ts ($adv->"epoch")
:local rssi ($adv->"rssi")
:local ad ($adv->"data")
:local tempf [:pick ($adv->"data") 28 32]#The line below will set temperature in hexadecimal format, like "0x1950"
:local temp ([:pick $tempf 2 4].[:pick $tempf 0 2])#The line below will set temperature in decimal format, like "25313". It is commented with "#", so if you wish to use it instead of the hexadecimal format value, comment the line above and uncomment the line below > remove "#" from the line below and add "#" to the line above.
# :local temp [$from88 [:pick $ad 28 32]]
:local obj "{\
\
\"ts\":$ts,\
\"values\":{\
\"id\":\"$[$minimizeMac address=$address]\",\
\"rssi\":\"$rssi\",\
\"temp\":\"$temp\",\
\"ad\":\"$ad\"\
}\
}"
:set $advCount ($advCount + 1)
:set $lastAdvTimestamp $ts
# Ensure that the last object is not terminated by a comma
:set $advJson "$advJson$advSeparator$obj"
:if ($advSeparator = "") do={
:set $advSeparator ","}
}:if ($advCount > 0) do={
:set $btOldestAdvertisementTimestamp $lastAdvTimestamp
}
:put ("[*] Found $advCount new advertisements \
(processing time: $[([/system clock get time] - $btProcessingStart)])")#################################### MQTT #####################################
:local message \
"[$advJson]"
:log info "$message";
:put ("[*] Total message size: $[:len $message] bytes")
:put ("[*] Sending message to MQTT broker...")
/iot mqtt publish broker=$broker topic=$topic message=$message
:put ("[*] Done")
...