Hello,
I’m looking for a script that notifies me by email when I move TG-BT5-IN by X or Y axis. is that possible?
E.g. if someone opens the server room door, we would like to be notified.
it’s a pity I don’t have them, I would have seen if something could be done …
Yes, this is a pity. Check out the Mikrotik Knots. The technique is really interesting.
Can someone else help us? For example, here are some scripts.
https://help.mikrotik.com/docs/display/UM/MikroTik+Tag+advertisement+formats
can nobody help here?
take TG-BT5-in and see whats data get on knot. I dont have this beacon jet. Ordered two pieces and think get after few days…
mikrotik have some example for bluetooth, i think this is enought for start.
btw i get tg5-in, little trouble, just sometime need read manual
this sample script from mikrotik working. i change this for mqtt-domoticz, working fine. react to tilt and switch.
https://help.mikrotik.com/docs/display/UM/Email+notification+on+the+MikroTik+BLE+tag's+accelerometer+triggers
and second script is more useful i think, for me not working.. trying find reason why. just return nothin in terminal ![]()
# 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 "00:CC:66:88:11:BB"
# 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 ""
################################## Bluetooth ##################################
:global invertU16 do={
:local inverted 0
:for idx from=0 to=15 step=1 do={
:local mask (1 << $idx)
:if ($1 & $mask = 0) do={
:set $inverted ($inverted | $mask)
}
}
return $inverted
}
:global le16ToHost do={
:local lsb [:pick $1 0 2]
:local msb [:pick $1 2 4]
:return [:tonum "0x$msb$lsb"]
}
:local le32ToHost do={
:local lsb [:pick $1 0 2]
:local midL [:pick $1 2 4]
:local midH [:pick $1 4 6]
:local msb [:pick $1 6 8]
:return [:tonum "0x$msb$midH$midL$lsb"]
}
: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)
}
:local flagStr do={
:local str ""
:if ($1 & 0x01) do={ :set $str " switch" }
:if ($1 & 0x02) do={ :set $str "$str tilt" }
:if ($1 & 0x04) do={ :set $str "$str free_fall" }
:if ($1 & 0x08) do={ :set $str "$str impact_x" }
:if ($1 & 0x10) do={ :set $str "$str impact_y" }
:if ($1 & 0x20) do={ :set $str "$str impact_z" }
:if ([:len $str] = 0) do={ :return "" }
:return [:pick $str 1 [:len $str]]
}
# Find fresh Bluetooth advertisements
: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 advertisements [/iot bluetooth scanners advertisements print detail \
as-value where \
epoch > $btOldestAdvertisementTimestamp and \
address ~ $addressRegex and \
data ~ $advertisingDataRegex and \
rssi > $rssiThreshold
]
:local advCount 0
:local lastAdvTimestamp 0
:local advJson ""
:local advSeparator ""
# 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 rssi ($adv->"rssi")
:local epoch ($adv->"epoch")
:local ad ($adv->"data")
:local version [:tonum "0x$[:pick $ad 8 10]"]
:local encrypted [:tonum "0x$[:pick $ad 10 12]"]
:local salt [$le16ToHost [:pick $ad 12 16]]
:local accelX [$from88 [:pick $ad 16 20]]
:local accelY [$from88 [:pick $ad 20 24]]
:local accelZ [$from88 [:pick $ad 24 28]]
:local temp [$from88 [:pick $ad 28 32]]
:local uptime [$le32ToHost [:pick $ad 32 40]]
:local flags [:tonum "0x$[:pick $ad 40 42]"]
:local bat [:tonum "0x$[:pick $ad 42 44]"]
:put ("$advCount: \
address=$address \
ts=$epoch \
rssi=$rssi \
version=$version \
encrypted=$encrypted \
salt=$salt \
accelX=$accelX \
accelY=$accelY \
accelZ=$accelZ \
temp=$temp \
uptime=$uptime \
flags=\"$[$flagStr $flags]\" \
bat=$bat" \
)
:set $advCount ($advCount + 1)
:set $lastAdvTimestamp $epoch
}
:if ($advCount > 0) do={
:set $btOldestAdvertisementTimestamp $lastAdvTimestamp
:log info $advCount
}
this works for me when tilt or impage, unfortunately not yet if you only move it
[admin@Knot] > /system/script/export
# dec/12/2022 06:01:20 by RouterOS 7.4
# software id = LMW4-2MB9
#
# model = RB924i-2nD-BT5&BG77
# serial number = F5750ECE0D59
/system script
add dont-require-permissions=no name=script4 owner=admin policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="# Input MAC address of the tag within \"\"\r\
\n:local addressRegex \"DC:2C:6E:13:15:7E\"\r\
\n\r\
\n# POSIX regex for filtering Bluetooth advertisements based on their data. Same\r\
\n# usage as with 'addressRegex'.\r\
\n:local advertisingDataRegex \"\"\r\
\n\r\
\n# Signal strength filter. E.g. -40 would only include Bluetooth advertisements\r\
\n# whose signal strength is stronger than -40dBm.\r\
\n# To disable this filter, set it to \"\"\r\
\n:local rssiThreshold \"\"\r\
\n\r\
\n#enter the subject for the email within the \"\"\r\
\n:local emailsubject \"RouterOS report!\"\r\
\n\r\
\n#enter the email address wthin the \"\"\r\
\n:local emailaddress \"mail@domain.com\"\r\
\n\r\
\n#Script:\r\
\n################################## Bluetooth ##################################\r\
\n:local flagStr do={\r\
\n :local str \"\"\r\
\n\r\
\n :if (\$1 & 0x01) do={ :set \$str \" switch\" }\r\
\n :if (\$1 & 0x02) do={ :set \$str \"\$str tilt\" }\r\
\n :if (\$1 & 0x04) do={ :set \$str \"\$str free_fall\" }\r\
\n :if (\$1 & 0x08) do={ :set \$str \"\$str impact_x\" }\r\
\n :if (\$1 & 0x10) do={ :set \$str \"\$str impact_y\" }\r\
\n :if (\$1 & 0x20) do={ :set \$str \"\$str impact_z\" }\r\
\n\r\
\n :if ([:len \$str] = 0) do={ :return \"\" }\r\
\n\r\
\n :return [:pick \$str 1 [:len \$str]]\r\
\n}\r\
\n\r\
\n:local triggernameF \"free_fall\"\r\
\n:local triggernameT \"tilt\"\r\
\n:local triggernameX \"impact_x\"\r\
\n:local triggernameY \"impact_y\"\r\
\n:local triggernameZ \"impact_z\"\r\
\n:local triggernameS \"switch\"\r\
\n\r\
\n# Find fresh Bluetooth advertisements\r\
\n:global btOldestAdvertisementTimestamp\r\
\n:if ([:typeof \$btOldestAdvertisementTimestamp] = \"nothing\") do={\r\
\n # First time this script has been run since booting, need to initialize\r\
\n # persistent variables\r\
\n :set \$btOldestAdvertisementTimestamp 0\r\
\n}\r\
\n:local advertisements [/iot bluetooth scanners advertisements print detail \\\r\
\n as-value where \\\r\
\n epoch > \$btOldestAdvertisementTimestamp and \\\r\
\n address ~ \$addressRegex and \\\r\
\n data ~ \$advertisingDataRegex and \\\r\
\n rssi > \$rssiThreshold\r\
\n]\r\
\n:local advCount 0\r\
\n:local lastAdvTimestamp 0\r\
\n:local triggerlist \"\"\r\
\n\r\
\n:local triggerF\r\
\n:local triggerT\r\
\n:local triggerX\r\
\n:local triggerY\r\
\n:local triggerZ\r\
\n:local triggerS\r\
\n\r\
\n:local messageF \"\"\r\
\n:local messageT \"\"\r\
\n:local messageX \"\"\r\
\n:local messageY \"\"\r\
\n:local messageZ \"\"\r\
\n:local messageS \"\"\r\
\n\r\
\n:local 21st \"\"\r\
\n\r\
\n:foreach adv in=\$advertisements do={\r\
\n :local address (\$adv->\"address\")\r\
\n :local rssi (\$adv->\"rssi\")\r\
\n :local epoch (\$adv->\"epoch\")\r\
\n :local rtime (\$adv->\"time\")\r\
\n :local ad (\$adv->\"data\")\r\
\n :local flags [:tonum \"0x\$[:pick \$ad 40 42]\"]\r\
\n :local fflags \"\$[\$flagStr \$flags]\"\r\
\n :if (\$fflags=\"\") do={:set \$fflags \"none - periodically broadcasted payload\"}\r\
\n\r\
\n :local obj \"# \$advCount:\r\
\n time: \$rtime\r\
\n trigger: \$fflags\r\
\n\r\
\n\"\r\
\n :set \$advCount (\$advCount + 1)\r\
\n :set \$lastAdvTimestamp \$epoch\r\
\n :set \$triggerlist \"\$triggerlist\$obj\"\r\
\n\r\
\n:set triggerF [:pick \$triggerlist ([find \$triggerlist \"free_fall\"]-0) ([find \$triggerlist \"free_fall\"]+9)]\r\
\n:if (\$triggerF=\$triggernameF) do={:set messageF \"\$triggernameF\";:set 21st \"not00\";}\r\
\n:set triggerT [:pick \$triggerlist ([find \$triggerlist \"tilt\"]-0) ([find \$triggerlist \"tilt\"]+4)]\r\
\n:if (\$triggerT=\$triggernameT) do={:set messageT \"\$triggernameT\";:set 21st \"not00\";}\r\
\n:set triggerX [:pick \$triggerlist ([find \$triggerlist \"impact_x\"]-0) ([find \$triggerlist \"impact_x\"]+8)]\r\
\n:if (\$triggerX=\$triggernameX) do={:set messageX \"\$triggernameX\";:set 21st \"not00\";}\r\
\n:set triggerY [:pick \$triggerlist ([find \$triggerlist \"impact_y\"]-0) ([find \$triggerlist \"impact_y\"]+8)]\r\
\n:if (\$triggerY=\$triggernameY) do={:set messageY \"\$triggernameY\";:set 21st \"not00\";}\r\
\n:set triggerZ [:pick \$triggerlist ([find \$triggerlist \"impact_z\"]-0) ([find \$triggerlist \"impact_z\"]+8)]\r\
\n:if (\$triggerZ=\$triggernameZ) do={:set messageZ \"\$triggernameZ\";:set 21st \"not00\";}\r\
\n:set triggerS [:pick \$triggerlist ([find \$triggerlist \"switch\"]-0) ([find \$triggerlist \"switch\"]+6)]\r\
\n:if (\$triggerS=\$triggernameS) do={:set messageS \"\$triggernameS\";:set 21st \"not00\";}\r\
\n\r\
\n}\r\
\n:if (\$advCount > 0) do={\r\
\n :set \$btOldestAdvertisementTimestamp \$lastAdvTimestamp\r\
\n}\r\
\n\r\
\n:if (\$21st=\"not00\") do={/tool e-mail send to=\$emailaddress subject=\"\$emailsubject\" body=\"\$triggerlist\"} else={:put \"21st octet does not have triggers detected!\"}"
[admin@Knot] > /system/scheduler/export
# dec/12/2022 06:01:25 by RouterOS 7.4
# software id = LMW4-2MB9
#
# model = RB924i-2nD-BT5&BG77
# serial number = F5750ECE0D59
/system scheduler
add interval=10s name=schedule1 on-event="/system script run script4\r\
\n/system script run test" policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon start-date=nov/12/2022 start-time=19:33:27
[admin@Knot] >
We have several videos about using the TG-BT tags, maybe it helps: https://youtube.com/playlist?list=PLXr-HoBo2VtWSXU2pMH7vd5D2Cgi5pOez
Thanks, I had already looked at some.
Is there possibly also support for money? or can one inquire there somewhere?
I’m sorry. But can anyone really help me with this topic? Or does someone know a support?
Even if someone has the good will to help you with the scripting, if they don’t have the device they can’t…
Contact support@mikrotik.com directly and let us know what they reply to you.
I’ll buy you a device if you help me ![]()
Many thanks to Mikrotik Support, they helped me a lot. Thanks
Here’s how it works:
# Input MAC address of the tag within ""
:local addressRegex "AC:2C:6E:13:05:9E"
# 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 ""
#enter the subject for the email within the ""
:local emailsubject "Move"
#enter the email address wthin the ""
:local emailaddress "mail@domain.com"
#Script:
################################## Bluetooth ##################################
:local flagStr do={
:local str ""
:if ($1 & 0x01) do={ :set $str " switch" }
:if ($1 & 0x02) do={ :set $str "$str tilt" }
:if ($1 & 0x04) do={ :set $str "$str free_fall" }
:if ($1 & 0x08) do={ :set $str "$str impact_x" }
:if ($1 & 0x10) do={ :set $str "$str impact_y" }
:if ($1 & 0x20) do={ :set $str "$str impact_z" }
:if ([:len $str] = 0) do={ :return "" }
:return [:pick $str 1 [:len $str]]
}
:local triggernameF "free_fall"
:local triggernameT "tilt"
:local triggernameX "impact_x"
:local triggernameY "impact_y"
:local triggernameZ "impact_z"
:local triggernameS "switch"
# Find fresh Bluetooth advertisements
: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 advertisements [/iot bluetooth scanners advertisements print detail \
as-value where \
epoch > $btOldestAdvertisementTimestamp and \
address ~ $addressRegex and \
data ~ $advertisingDataRegex and \
rssi > $rssiThreshold
]
:local advCount 0
:local lastAdvTimestamp 0
:local triggerlist ""
:local triggerF
:local triggerT
:local triggerX
:local triggerY
:local triggerZ
:local triggerS
:local messageF ""
:local messageT ""
:local messageX ""
:local messageY ""
:local messageZ ""
:local messageS ""
:local 21st ""
:foreach adv in=$advertisements do={
:local address ($adv->"address")
:local rssi ($adv->"rssi")
:local epoch ($adv->"epoch")
:local rtime ($adv->"time")
:local ad ($adv->"data")
:local flags [:tonum "0x$[:pick $ad 40 42]"]
:local fflags "$[$flagStr $flags]"
:if ($fflags="") do={:set $fflags "none - periodically broadcasted payload"}
:local obj "# $advCount:
time: $rtime
trigger: $fflags
"
:set $advCount ($advCount + 1)
:set $lastAdvTimestamp $epoch
:set $triggerlist "$triggerlist$obj"
:set triggerF [:pick $triggerlist ([find $triggerlist "free_fall"]-0) ([find $triggerlist "free_fall"]+9)]
:if ($triggerF=$triggernameF) do={:set messageF "$triggernameF";:set 21st "not00";}
:set triggerT [:pick $triggerlist ([find $triggerlist "tilt"]-0) ([find $triggerlist "tilt"]+1)]
:if ($triggerT=$triggernameT) do={:set messageT "$triggernameT";:set 21st "not00";}
:set triggerX [:pick $triggerlist ([find $triggerlist "impact_x"]-0) ([find $triggerlist "impact_x"]+1)]
:if ($triggerX=$triggernameX) do={:set messageX "$triggernameX";:set 21st "not00";}
:set triggerY [:pick $triggerlist ([find $triggerlist "impact_y"]-0) ([find $triggerlist "impact_y"]+1)]
:if ($triggerY=$triggernameY) do={:set messageY "$triggernameY";:set 21st "not00";}
:set triggerZ [:pick $triggerlist ([find $triggerlist "impact_z"]-0) ([find $triggerlist "impact_z"]+8)]
:if ($triggerZ=$triggernameZ) do={:set messageZ "$triggernameZ";:set 21st "not00";}
:set triggerS [:pick $triggerlist ([find $triggerlist "switch"]-0) ([find $triggerlist "switch"]+6)]
:if ($triggerS=$triggernameS) do={:set messageS "$triggernameS";:set 21st "not00";}
}
:if ($advCount > 0) do={
:set $btOldestAdvertisementTimestamp $lastAdvTimestamp
}
:if ($21st="not00") do={/tool e-mail send to=$emailaddress subject="$emailsubject" body="TAG MOVED!"} else={:put "21st octet does not have triggers detected!"}