homeassistant-mikrotik_router
homeassistant-mikrotik_router copied to clipboard
[Feature] LTE modem cell info
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!
How it looks in WinBox:
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.
If you need any debug - no problem, I can do this for you.
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.
/interface/lte/print will show you all lte interfaces - see firs output in my initial message
thats not what I mean. that part is simple and will work. monitor needs a parameter, api works different compared to command line
I'm not able to get one. can you recommend something? if I can get it cheap, I will consider it.
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.
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:
- You can give me api access to your device. This of course involves exposing api to internet, so there may be a risk involved.
- Get me an LTE capable device compatible with one of my devices
- Try to add the functionality on your own
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.
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.
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.
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?
_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"
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.
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.
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.
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}]
ok, so it takes "name". thanks, thats all I needed for implementation.