socialwifi/RouterOS-api

how to pass single command argument without key/value (monitor-traffic)

Closed this issue · 3 comments

I'm trying to monitor the traffic of some ethernet ports on my routerboard.
In the winbox terminal I can do this by entering this command
/interface monitor-traffic ether1 once

I've done a lot of tests trying to "call" this query from the RouterOS-api. My test current test code looks like this:

res = api.get_resource('/interface/')
ans = res.call('monitor-traffic', {'ether1': '', 'once': ''})

However, this throws an "unknown parameter" error:
routeros_api.exceptions.RouterOsApiCommunicationError: ('Error "unknown parameter" executing command b\'/interface/monitor-traffic =ether1= =once= .tag=4\'', b'unknown parameter')

I did some diggin in the source code of this API and found the raw representation of the query being sent to my routerboard:
[b'/interface/monitor-traffic', b'=ether1=', b'=once=', b'.tag=4']

Out of curiosity I removed the "=" before and after "ether1" by adding a few lines to the send_command method in the ApiCommunicatorBase. This actually gave me a successful response of what I wanted:

Query: [b'/interface/monitor-traffic', b'ether1', b'=once=', b'.tag=4']
Response: [{'rx-packets-per-second': '30', 'rx-bits-per-second': '18776', 'fp-rx-packets-per-second': '36', 'fp-rx-bits-per-second': '22672', 'rx-drops-per-second': '0', 'rx-errors-per-second': '0', 'tx-packets-per-second': '26', 'tx-bits-per-second': '184608', 'fp-tx-packets-per-second': '36', 'fp-tx-bits-per-second': '22672', 'tx-drops-per-second': '0', 'tx-queue-drops-per-second': '0', 'tx-errors-per-second': '0'}]

Now, is there a way I could send my monitor-traffic query using this API without having to modify the source code?

Here's my quick workaround:

File: base.py, Class: ApiCommunicatorBase, Method: send_command.

def send_command(self, command):
    cm = command.get_api_format()
    for i in range(len(cm)):
        if b'??' in cm[i]:
            cm[i] = cm[i].replace(b'??', b'').strip(b'=')
    # self.base.send_sentence(command.get_api_format())
    self.base.send_sentence(cm)

I can now successfully run my query by adding '??' to the parameter I want to trim '=' from.

res = api.get_resource('/interface/')
ans = res.call('monitor-traffic', {'??ether1': '', 'once': ''})

Looks like I jumped the gun. The query gives a successfull response no matter what I give it..
ans = res.call('monitor-traffic', {'qwerty': '', 'once': ''})

Solved.

There's this key called "interface" where the value is supposed to be "ether1".

res = api.get_resource('/interface/')
ans = res.call('monitor-traffic', {'interface': 'ether1', 'once': ''})