Advertisement
Guest User

OpenWRT ModemManager mqtt statistics

a guest
Sep 8th, 2020
868
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 10.31 KB | None | 0 0
  1. #!/bin/sh
  2. # Copyright (C) 2016-2019 Aleksander Morgado <aleksander@aleksander.es>
  3. # Used Aleksander's orginal code for base of this script
  4.  
  5. # sends modem data to mqtt server
  6. # install mqtt client: opkg install mosquitto-client
  7. # copy to this file to: /etc/config/
  8. # chmod +x /etc/config/modem_mqtt.sh
  9.  
  10. # in /etc/rc.local add:
  11.  
  12. # sleep 60
  13. # /etc/config/modem_mqtt.sh &
  14.  
  15. # before  exit 0
  16.  
  17. #Home Assistant MQTT server
  18. MQTTSERVER=odroid
  19. #MQTT port, default is 1883
  20. PORT=1883
  21. #change device to your modem device number
  22. device="0"
  23.  
  24. [ -x /usr/bin/mmcli ] || exit 0
  25. [ -x /usr/sbin/pppd ] || exit 0
  26.  
  27. # [ -n "$INCLUDE_ONLY" ] || {
  28.     # . /lib/functions.sh
  29.     # . ../netifd-proto.sh
  30.     # . ./ppp.sh
  31.     # init_proto "$@"
  32. # }
  33.  
  34. cdr2mask ()
  35. {
  36.     # Number of args to shift, 255..255, first non-255 byte, zeroes
  37.     set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
  38.     if [ "$1" -gt 1 ]
  39.     then
  40.         shift "$1"
  41.     else
  42.         shift
  43.     fi
  44.     echo "${1-0}"."${2-0}"."${3-0}"."${4-0}"
  45. }
  46.  
  47. # This method expects as first argument a list of key-value pairs, as returned by mmcli --output-keyvalue
  48. # The second argument must be exactly the name of the field to read
  49. #
  50. # Sample output:
  51. #     $ mmcli -m 0 -K
  52. #     modem.dbus-path                                 : /org/freedesktop/ModemManager1/Modem/0
  53. #     modem.generic.device-identifier                 : ed6eff2e3e0f90463da1c2a755b2acacd1335752
  54. #     modem.generic.manufacturer                      : Dell Inc.
  55. #     modem.generic.model                             : DW5821e Snapdragon X20 LTE
  56. #     modem.generic.revision                          : T77W968.F1.0.0.4.0.GC.009\n026
  57. #     modem.generic.carrier-configuration             : GCF
  58. #     modem.generic.carrier-configuration-revision    : 08E00009
  59. #     modem.generic.hardware-revision                 : DW5821e Snapdragon X20 LTE
  60. #     ....
  61. modemmanager_get_field() {
  62.     local list=$1
  63.     local field=$2
  64.     local value=""
  65.  
  66.     [ -z "${list}" ] || [ -z "${field}" ] && return
  67.  
  68.     # there is always at least a whitespace after each key, and we use that as part of the
  69.     # key matching we do (e.g. to avoid getting 'modem.generic.state-failed-reason' as a result
  70.     # when grepping for 'modem.generic.state'.
  71.     line=$(echo "${list}" | grep "${field} ")
  72.     value=$(echo ${line#*:})
  73.  
  74.     # not found?
  75.     [ -n "${value}" ] || return 2
  76.  
  77.     # only print value if set
  78.     [ "${value}" != "--" ] && echo "${value}"
  79.     return 0
  80. }
  81.  
  82. # build a comma-separated list of values from the list
  83. modemmanager_get_multivalue_field() {
  84.     local list=$1
  85.     local field=$2
  86.     local value=""
  87.     local length idx item
  88.  
  89.     [ -z "${list}" ] || [ -z "${field}" ] && return
  90.  
  91.     length=$(modemmanager_get_field "${list}" "${field}.length")
  92.     [ -n "${length}" ] || return 0
  93.     [ "$length" -ge 1 ] || return 0
  94.  
  95.     idx=1
  96.     while [ $idx -le "$length" ]; do
  97.         item=$(modemmanager_get_field "${list}" "${field}.value\[$idx\]")
  98.         [ -n "${item}" ] && [ "${item}" != "--" ] && {
  99.             [ -n "${value}" ] && value="${value}, "
  100.             value="${value}${item}"
  101.         }
  102.         idx=$((idx + 1))
  103.     done
  104.  
  105.     # nothing built?
  106.     [ -n "${value}" ] || return 2
  107.  
  108.     # only print value if set
  109.     echo "${value}"
  110.     return 0
  111. }
  112.  
  113. modemstatus=$(mmcli --modem="${device}" --output-keyvalue)
  114.    
  115. send_config_data() {
  116.  
  117.     model=$(modemmanager_get_field "${modemstatus}" "modem.generic.model" | cut -d " " -f 1-3)
  118.     [ -n "${model}" ] && model=",\"model\":\"${model}\"" || model=""
  119.     manufacturer=$(modemmanager_get_field "${modemstatus}" "modem.generic.manufacturer")
  120.     [ -n "${manufacturer}" ] && manufacturer=",\"manufacturer\":\"${manufacturer}\"" || manufacturer=""
  121.     name=$(modemmanager_get_field "${modemstatus}" "modem.generic.hardware-revision")
  122.     [ -n "${name}" ] && name="${name}" || name=""
  123.  
  124. #send MQTT discovery message
  125. mosquitto_pub -h $MQTTSERVER -p $PORT -t "homeassistant/sensor/modem/config" -m "{\
  126. \"name\":\"$name\"\
  127. ,\"state_topic\":\"modem/state\"\
  128. ,\"json_attributes_topic\":\"modem/status\"\
  129. ,\"icon\":\"mdi:router-wireless\",\"unit_of_measurement\":\"%\",\"value_template\":\"{{ value_json.signal }}\"\
  130. ,\"unique_id\":\"modem_$name\"\
  131. }" -i "OpenWRT" -r -d
  132.  
  133. #discover snr sensor
  134. mosquitto_pub -h $MQTTSERVER -p $PORT -t "homeassistant/sensor/modem/snr/config" -m "{\
  135. \"name\":\"snr_$name\"\
  136. ,\"state_topic\":\"modem/status\"\
  137. ,\"icon\":\"mdi:signal\",\"unit_of_measurement\":\"dB\",\"value_template\":\"{{ value_json.lte_snr }}\"\
  138. ,\"unique_id\":\"snr_$name\"\
  139. }" -i "OpenWRT" -r
  140. #discover rssi sensor
  141. mosquitto_pub -h $MQTTSERVER -p $PORT -t "homeassistant/sensor/modem/rssi/config" -m "{\
  142. \"name\":\"rssi_$name\"\
  143. ,\"state_topic\":\"modem/status\"\
  144. ,\"icon\":\"mdi:signal\",\"unit_of_measurement\":\"dBm\",\"value_template\":\"{{ value_json.lte_rssi }}\"\
  145. ,\"unique_id\":\"rssi_$name\"\
  146. }" -i "OpenWRT" -r
  147. #discover rsrq sensor
  148. mosquitto_pub -h $MQTTSERVER -p $PORT -t "homeassistant/sensor/modem/rsrq/config" -m "{\
  149. \"name\":\"rsrq_$name\"\
  150. ,\"state_topic\":\"modem/status\"\
  151. ,\"icon\":\"mdi:signal\",\"unit_of_measurement\":\"dB\",\"value_template\":\"{{ value_json.lte_rsrq }}\"\
  152. ,\"unique_id\":\"rsrq_$name\"\
  153. }" -i "OpenWRT" -r
  154. #discover rsrp sensor
  155. mosquitto_pub -h $MQTTSERVER -p $PORT -t "homeassistant/sensor/modem/rsrp/config" -m "{\
  156. \"name\":\"rsrp_$name\"\
  157. ,\"state_topic\":\"modem/status\"\
  158. ,\"icon\":\"mdi:signal\",\"unit_of_measurement\":\"dBm\",\"value_template\":\"{{ value_json.lte_rsrp }}\"\
  159. ,\"unique_id\":\"rsrp_$name\"\
  160. }" -i "OpenWRT" -r
  161. #discover inbound traffic sensor
  162. mosquitto_pub -h $MQTTSERVER -p $PORT -t "homeassistant/sensor/modem/rxspeed/config" -m "{\
  163. \"name\":\"rx_$name\"\
  164. ,\"state_topic\":\"modem/status\"\
  165. ,\"icon\":\"mdi:download\",\"unit_of_measurement\":\"Mbps\",\"value_template\":\"{{ value_json.rx_speed }}\"\
  166. ,\"unique_id\":\"rx_$name\"\
  167. }" -i "OpenWRT" -r
  168. #discover outbound traffic sensor
  169. mosquitto_pub -h $MQTTSERVER -p $PORT -t "homeassistant/sensor/modem/txspeed/config" -m "{\
  170. \"name\":\"tx_$name\"\
  171. ,\"state_topic\":\"modem/status\"\
  172. ,\"icon\":\"mdi:upload\",\"unit_of_measurement\":\"Mbps\",\"value_template\":\"{{ value_json.tx_speed }}\"\
  173. ,\"unique_id\":\"tx_$name\"\
  174. }" -i "OpenWRT" -r
  175.  
  176. }
  177. make_mqtt_message() {
  178.     local lte_rssi lte_rsrq lte_rsrp lte_snr
  179.     local ipv4address ipv6address rx_speed tx_speed
  180.     local operator duration signal state
  181.     local bearerpath bearerstatus
  182.  
  183.     bearerpath=$(modemmanager_get_field "${modemstatus}" "modem.generic.bearers.value\[1\]")
  184.     bearerstatus=$(mmcli --bearer "${bearerpath}" --output-keyvalue)
  185.     modemsignal=$(mmcli --modem="${device}" --signal-get --output-keyvalue)
  186.  
  187.     name=$(modemmanager_get_field "${modemstatus}" "modem.generic.hardware-revision")
  188.     [ -n "${name}" ] && name="${name}" || name=""
  189.     model=$(modemmanager_get_field "${modemstatus}" "modem.generic.model" | cut -d " " -f 1-3)
  190.     [ -n "${model}" ] && model=",\"model\":\"${model}\"" || model=""
  191.     manufacturer=$(modemmanager_get_field "${modemstatus}" "modem.generic.manufacturer")
  192.     [ -n "${manufacturer}" ] && manufacturer=",\"manufacturer\":\"${manufacturer}\"" || manufacturer=""
  193.     operator=$(modemmanager_get_field "${modemstatus}" "modem.3gpp.operator-name")
  194.     [ -n "${operator}" ] && operator=",\"operator\":\"${operator}\"" || operator=""
  195.     state=$(modemmanager_get_field "${modemstatus}" "modem.generic.state")
  196.     [ -n "${state}" ] && state=",\"state\":\"${state}\"" || state=""
  197.     duration=$(modemmanager_get_field "${bearerstatus}" "bearer.stats.duration")
  198.     [ -n "${duration}" ] && duration=",\"duration\":\"${duration}\"" || duration=""
  199.     signal=$(modemmanager_get_field "${modemstatus}" "modem.generic.signal-quality.value")
  200.     [ -n "${signal}" ] && signal="${signal}" || signal=""
  201.     lte_rssi=$(modemmanager_get_field "${modemsignal}" "modem.signal.lte.rssi")
  202.     [ -n "${lte_rssi}" ] && lte_rssi=",\"lte_rssi\":${lte_rssi}" || lte_rssi=""
  203.     lte_rsrq=$(modemmanager_get_field "${modemsignal}" "modem.signal.lte.rsrq")
  204.     [ -n "${lte_rsrq}" ] && lte_rsrq=",\"lte_rsrq\":${lte_rsrq}" || lte_rsrq=""
  205.     lte_rsrp=$(modemmanager_get_field "${modemsignal}" "modem.signal.lte.rsrp")
  206.     [ -n "${lte_rsrp}" ] && lte_rsrp=",\"lte_rsrp\":${lte_rsrp}" || lte_rsrp=""
  207.     lte_snr=$(modemmanager_get_field "${modemsignal}" "modem.signal.lte.snr")
  208.     [ -n "${lte_snr}" ] && lte_snr=",\"lte_snr\":${lte_snr}" || lte_snr=""
  209.     ipv4address=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv4-config.address")
  210.     [ -n "${ipv4address}" ] && ipv4address=",\"ipv4 address\":\"${ipv4address}\"" || ipv4address=""
  211.     ipv6address=$(modemmanager_get_field "${bearerstatus}" "bearer.ipv6-config.address")
  212.     [ -n "${ipv6address}" ] && ipv6address=",\"ipv6 address\":\"${ipv6address}\"" || ipv6address=""
  213.  
  214.     #calculating current download speed
  215.     [ -n "${rxbytes}" ] && rxbyteslast=$rxbytes
  216.     rxbytes="$(ifconfig wwan0 | grep "RX bytes:" | sed 's/bytes://g' | awk '{print $2}') $(date +%s)"
  217.     [ -n "${rxbyteslast}" ] && rx_speed=$(echo $rxbytes $rxbyteslast | awk '{printf "%.2f\n",(($1-$3)/($2-$4)*8)/1024/1024}')
  218.     [ -n "${rx_speed}" ] && rx_speed=",\"rx_speed\":${rx_speed}" || rx_speed=""
  219.  
  220.     #calculating current upload speed
  221.     [ -n "${txbytes}" ] && txbyteslast=$txbytes
  222.     txbytes="$(ifconfig wwan0 | grep "TX bytes:" | sed 's/bytes://g' | awk '{for(i=1;i<=NF;i++)if($i~/TX/)print $(i+1)}') $(date +%s)"
  223.     [ -n "${txbyteslast}" ] && tx_speed=$(echo $txbytes $txbyteslast | awk '{printf "%.2f\n",(($1-$3)/($2-$4)*8)/1024/1024}')
  224.     [ -n "${tx_speed}" ] && tx_speed=",\"tx_speed\":${tx_speed}" || tx_speed=""
  225.  
  226.     mosquitto_pub -h $MQTTSERVER -t modem/status -m "{\
  227. \"name\":\"$name\"\
  228. $model\
  229. $manufacturer\
  230. $operator\
  231. $state\
  232. $duration\
  233. ,\"signal\":$signal\
  234. $lte_snr\
  235. $lte_rssi\
  236. $lte_rsrq\
  237. $lte_rsrp\
  238. $ipv4address\
  239. $ipv6address\
  240. $rx_speed\
  241. $tx_speed\
  242. }" -i "OpenWRT"
  243.     mosquitto_pub -h $MQTTSERVER -t modem/state -m "{\"signal\":$signal}" -i "OpenWRT"
  244. }
  245. #wait that ModemManager process has started
  246. while ! pgrep -f "ModemManager" > /dev/null; do
  247.         sleep 30
  248. done
  249.  
  250. #wait that modem is found in ModemManager
  251. while [[ "${name}" == "" ]]
  252.     do
  253.     name=$(modemmanager_get_field "${modemstatus}" "modem.generic.hardware-revision")
  254.     sleep 10
  255. done
  256.  
  257. #sending config data to Home Assistant for autodiscovery
  258. [ -n "${name}" ] && send_config_data
  259.  
  260. resendconf=0
  261. while true;do
  262.     [ -n "${name}" ] && make_mqtt_message
  263.     resendconf=$((resendconf+1))
  264.     #resend config message every 15 minutes for in case that mqtt server has been down
  265.     if [[ $resendconf == 30 ]]; then
  266.         [ -n "${name}" ] && send_config_data
  267.         resendconf=0
  268.     fi
  269.     sleep 29
  270. done
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement