homeassistant-mikrotik_router icon indicating copy to clipboard operation
homeassistant-mikrotik_router copied to clipboard

[Feature] LTE modem cell info

Open sshalyminov opened this issue 1 year ago • 26 comments

Is it possible to implement cell info for LTE modem connected to router?

Here how to know lte interface:

[*@MikroTik] > /interface/lte/print 
Flags: R - RUNNING
Columns: NAME, MTU, NETWORK-MODE, APN-PROFILES
#   NAME   MTU  NETWORK-MODE  APN-PROFILES
0 R lte1  1500  3g            default     
                lte 

How to collect info:

[*@MikroTik] > /interface/lte/monitor lte1 once 
            status: connected
             model: EP06-E
          revision: EP06ELAR04A04M4G
  current-operator: 
    current-cellid: 134982913
            enb-id: 527277
         sector-id: 1
        phy-cellid: 249
        data-class: LTE
    session-uptime: 6h57m15s
              imei: [cutted]
              imsi: [cutted]
              uicc: [cutted]
      primary-band: B3@15Mhz earfcn: 1725 phy-cellid: 249
              rssi: -54dBm
              rsrp: -85dBm
              rsrq: -12dB
              sinr: 26dB

For me interesting next sensors: for interface sensors: current-cellid (numeric) enb-id (numeric) sector-id (numeric) phy-cellid (numeric) data-class (text) session-uptime (timestamp) primary-band (text) ca-band (text, in my example earlier it is not exist because of my cell does not support aggregation, but for future and another places) rssi (numeric) rsrp (numeric) rsrq (numeric) sinr (numeric)

This can help to monitor connection stability and quality.

Thank you!

sshalyminov avatar Sep 27 '22 11:09 sshalyminov

How it looks in WinBox: image

sshalyminov avatar Sep 27 '22 11:09 sshalyminov

I can see how this would help, but I dont have any LTE modem to test work on this. Monitor commands can be tricky. Will try to ask around if somebody has one that I can use for a day.

tomaae avatar Sep 27 '22 11:09 tomaae

If you need any debug - no problem, I can do this for you.

sshalyminov avatar Sep 27 '22 11:09 sshalyminov

that wont work unfortunatly. api is not fully documented so I dont know interface attribute name for monitor command. it will require lot of trial and error work just to get to debug output I need to implement this functionality.

tomaae avatar Sep 27 '22 12:09 tomaae

/interface/lte/print will show you all lte interfaces - see firs output in my initial message

sshalyminov avatar Sep 27 '22 12:09 sshalyminov

thats not what I mean. that part is simple and will work. monitor needs a parameter, api works different compared to command line

tomaae avatar Sep 27 '22 16:09 tomaae

I'm not able to get one. can you recommend something? if I can get it cheap, I will consider it.

tomaae avatar Sep 29 '22 22:09 tomaae

Better to ask your cell operator. Here simpliest LTE modem cost is around $40. You can find much cheaper on Aliexpress if you use it.

sshalyminov avatar Sep 29 '22 23:09 sshalyminov

Unfortunatly, all offers I got are way more I'm willing to put into something I most likely wont ever use. So there are really only few options:

  1. You can give me api access to your device. This of course involves exposing api to internet, so there may be a risk involved.
  2. Get me an LTE capable device compatible with one of my devices
  3. Try to add the functionality on your own

tomaae avatar Oct 06 '22 13:10 tomaae

Using API client from https://github.com/DEssMALA/RouterOS_API I've got next:

API command: /interface/lte/print output: [{'.id': '*6', 'default-name': 'lte1', 'name': 'lte1', 'mtu': '1500', 'apn-profiles': 'default', 'allow-roaming': 'false', 'network-mode': '3g,lte', 'band': '', 'running': 'true', 'disabled': 'false'}]

Here we can take interface name from "name" field.

API command:

/interface/lte/monitor
=numbers=lte1
=once=

Output: [{'status': 'connected', 'model': 'EP06-E', 'revision': 'EP06ELAR04A04M4G', 'current-operator': '', 'current-cellid': '134982913', 'enb-id': '527277', 'sector-id': '1', 'phy-cellid': '249', 'data-class': 'LTE', 'session-uptime': '3d14h25m28s', 'imei': '***', 'imsi': '***', 'uicc': '***', 'primary-band': 'B3@15Mhz earfcn: 1725 phy-cellid: 249', 'rssi': '-63', 'rsrp': '-89', 'rsrq': '-7', 'sinr': '22'}]

I've removed imei, imsi and uicc manually from output. So as you see all fields are available (except ca-band as I mentioned earlier because of limitation of my current cell).

Is this enough for implementation? I can test your changes on my installation. I'm not sure I have ability to change your code to implement it by myself - it will required lot of time to understand how you doing things. I can't open API for you because of do not have "white IP", my cell operator gives us IP under it's NAT.

sshalyminov avatar Oct 06 '22 22:10 sshalyminov

Thats wont help me much, since I need to know how to access it. That API uses something custom, as "numbers" field does not exist. You can try adding this somewhere, for example on top of get_interface function.

_LOGGER.error(self.api.query(
                    "/interface/lte",
                    command="monitor",
                    args={".id": 6, "once": True},
                ))

My guess this should give a response if it is working like most command queries. No need to run debug, it will show as error, to make things easier.

Also, which information from both print and monitor is important to have in HA? I never used custom LTE, so I would be guessing.

tomaae avatar Oct 07 '22 10:10 tomaae

Added as next lines after def get_interface(self): in mikrotik_controller.py file.

Command:

        _LOGGER.error(self.api.query(
                    "/interface/lte",
                    command="print",
                    args={},
                ))

Error in log with answer:

Logger: custom_components.mikrotik_router.mikrotik_controller
Source: custom_components/mikrotik_router/mikrotik_controller.py:743
Integration: Mikrotik Router ([documentation](https://github.com/tomaae/homeassistant-mikrotik_router), [issues](https://github.com/tomaae/homeassistant-mikrotik_router/issues))
First occurred: 15:55:17 (1 occurrences)
Last logged: 15:55:17

[{'.id': '*6', 'default-name': 'lte1', 'name': 'lte1', 'mtu': 1500, 'apn-profiles': 'default', 'allow-roaming': False, 'network-mode': '3g,lte', 'band': '', 'running': True, 'disabled': False}]

Command:

        _LOGGER.error(self.api.query(
                    "/interface/lte",
                    command="monitor",
                    args={".id": 6, "once": True},
                ))

Error in log is "None" and secondary error from mikrotik api is "item not found"

Then command argument changed to:

        _LOGGER.error(self.api.query(
                    "/interface/lte",
                    command="monitor",
                    args={".id": 0, "once": True},
                ))

And this gives answer:

Logger: custom_components.mikrotik_router.mikrotik_controller
Source: custom_components/mikrotik_router/mikrotik_controller.py:743
Integration: Mikrotik Router ([documentation](https://github.com/tomaae/homeassistant-mikrotik_router), [issues](https://github.com/tomaae/homeassistant-mikrotik_router/issues))
First occurred: 15:45:17 (2 occurrences)
Last logged: 15:46:09

[{'status': 'connected', 'model': 'EP06-E', 'revision': 'EP06ELAR04A04M4G', 'current-operator': '', 'current-cellid': 134982913, 'enb-id': 527277, 'sector-id': 1, 'phy-cellid': 249, 'data-class': 'LTE', 'session-uptime': '4d4h51m45s', 'imei': ****, 'imsi': ***, 'uicc': '***', 'primary-band': 'B3@15Mhz earfcn: 1725 phy-cellid: 249', 'rssi': -60, 'rsrp': -88, 'rsrq': -10, 'sinr': 22}]
[{'status': 'connected', 'model': 'EP06-E', 'revision': 'EP06ELAR04A04M4G', 'current-operator': '', 'current-cellid': 134982913, 'enb-id': 527277, 'sector-id': 1, 'phy-cellid': 249, 'data-class': 'LTE', 'session-uptime': '4d4h52m38s', 'imei': ***, 'imsi': ***, 'uicc': '***', 'primary-band': 'B3@15Mhz earfcn: 1725 phy-cellid: 249', 'rssi': -57, 'rsrp': -88, 'rsrq': -12, 'sinr': 24}]

I don't know why id is not same as in "print" command, probably it's re-numerated in monitor? And need to enum interfaces from "print" command from 0 incrementally if few interfaces available? I don't have secondary modem to check.

Regarding information - I've already listed it earlier, for me interesting: status (boolean, connected or not) current-cellid (integer) enb-id (integer) sector-id (integer) phy-cellid (integer) data-class (string) session-uptime (timestamp? or string at least for later parsing) primary-band (string) ca-band (string) (if available, otherwise 'None') rssi (integer, dBm) rsrp (integer, dBm) rsrq (integer, dB) sinr (integer, dB)

Also "name" from "print" command may be used as interface name. And "model" from "monitor" as additional information for device (description?) if you provide it.

sshalyminov avatar Oct 07 '22 13:10 sshalyminov

Yea, thats really weird behaviour. ".id" should be exact match for interface ".id". Could be a bug, or maybe something that is not implemented in this command. But at least we have a response, which is good.

what if you try:

        _LOGGER.error(self.api.query(
                    "/interface/lte",
                    command="monitor",
                    args={".id": "lte1", "once": True},
                ))

if that works, change lte1 to something that does not exist to see if you get error.

it could also be

        _LOGGER.error(self.api.query(
                    "/interface/lte",
                    command="monitor",
                    args={"name": "lte1", "once": True},
                ))

or default-name instead of name

Also, is current-operator really empty, or did you just removed it?

Also 2, what are you looking to do with this functionality/how do you plan to use it?

tomaae avatar Oct 07 '22 13:10 tomaae

        _LOGGER.error(self.api.query(
                    "/interface/lte",
                    command="monitor",
                    args={".id": "lte1", "once": True},
                ))

This one working excellent, all info returned. Others generate error "unknown parameter"

sshalyminov avatar Oct 07 '22 15:10 sshalyminov

Also, is current-operator really empty, or did you just removed it?

Empty. Probably firmware just don't know my operator code/name :)

Also 2, what are you looking to do with this functionality/how do you plan to use it?

I wrote at beginning - monitor stability of channel. Week ago my closest cell breaks and I had 2 days of fun looking in WinBox how modem tried find another ways to connect - changed LTE/3G protocols, changed channels and other things. Especially interesting rssi/rsrp/rsrq/sinr in a case if you want to adjust antenna position to find best signal. And rest things :)

Of course I can see all of this in WinBox, but HA is much interesting in sight of statistics, for example how signal changing depends on weather conditions - may be much better to setup antenna to less powerful cell station but more stable instead of powerful one but with unstable signal.

sshalyminov avatar Oct 07 '22 15:10 sshalyminov

if that works, change lte1 to something that does not exist to see if you get error.

Forget to add - if I set ".id" anything else than 0 or 'lte1' - I've got error "item not found" - I had same when ".id" was set to 6 earlier if you remember.

sshalyminov avatar Oct 07 '22 15:10 sshalyminov

thanks, I just need one more thing.

'default-name': 'lte1', 'name': 'lte1'

Can you temporary rename the interface to anything else and test it again? I need to know if monitor it is accepting 'default-name' or 'name' as a parameter. could be actually both, but it is important to know this one.

tomaae avatar Oct 07 '22 17:10 tomaae

Renamed to lte1m

        _LOGGER.error(self.api.query(
                    "/interface/lte",
                    command="print",
                    args={},
                ))
[{'.id': '*6', 'default-name': 'lte1', 'name': 'lte1m', 'mtu': 1500, 'apn-profiles': 'default', 'allow-roaming': False, 'network-mode': '3g,lte', 'band': '', 'running': True, 'disabled': False}]

        _LOGGER.error(self.api.query(
                    "/interface/lte",
                    command="monitor",
                    args={".id": "lte1m", "once": True},
                ))
[{'status': 'connected', 'model': 'EP06-E', 'revision': 'EP06ELAR04A04M4G', 'current-operator': '', 'current-cellid': 134982913, 'enb-id': 527277, 'sector-id': 1, 'phy-cellid': 249, 'data-class': 'LTE', 'session-uptime': '4d10h57m14s', 'imei': ***, 'imsi': ***, 'uicc': '***', 'primary-band': 'B3@15Mhz earfcn: 1725 phy-cellid: 249', 'rssi': -57, 'rsrp': -88, 'rsrq': -10, 'sinr': 24}]

sshalyminov avatar Oct 07 '22 18:10 sshalyminov

ok, so it takes "name". thanks, thats all I needed for implementation.

tomaae avatar Oct 07 '22 21:10 tomaae