Home AMX User Forum Scripting Languages

Setting comms parameters on idevice with Python

I am struggling to get the argument positions correct when calling setCommParams on an idevice serial port.
The Python stub in mojo/__init__.pyi has the following call signature:

def __call__(self, baudRate: Literal['1200'] | Literal['4800'] | Literal['9600'] | Literal['19200'] | Literal['38400'] | Literal['57600'] | Literal['115200'], mode: Literal['232'] | Literal['422'] | Literal['485'] = ..., stopBits: int, parity: Literal['NONE'] | Literal['EVEN'] | Literal['ODD'] | Literal['MARK'] | Literal['SPACE'], dataBits: int, ) -> None: ...

However, when the method is called with Python named parameters, the result is "unknown keyword argument baudRate". If I used positional arguments, then the order in the PYI file does not seem to match. I get:

com.amx.mojo.api.thing.exception.ThingValidationException: Invalid thing {mode} value [8]; index not in range [0..2]\n at com.amx.mojo.thing.AbstractThingValue.validate(AbstractThingValue.java:309)\n at com.amx.mojo.thing.ThingCommandImpl.invoke(ThingCommandImpl.java:180)\n at com.amx.mojo.thing.ThingCommandImpl.invoke(ThingCommandImpl.java:133)\n at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n at java.base/java.lang.reflect.Method.invoke(Method.java:566)\n at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244)\n at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357)\n at py4j.Gateway.invoke(Gateway.java:282)\n at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)\n at py4j.commands.CallCommand.execute(CallCommand.java:79)\n at py4j.GatewayConnection.run(GatewayConnection.java:238)\n at java.base/java.lang.Thread.run(Thread.java:829)\n

What order should the positional arguments be?
It seems that using baudRate, mode, stopBits, parity, dataBits is not correct.
<device>.setCommParams('38400', '232', 1, 'NONE', 8) results in the above error.

The following does not raise an exception, but the serial port ends up in 422 mode and 2 stop bits:
<device>.setCommParams('38400', 8 '232', 'NONE', 1) results in the above error.

The device descriptor matches the PYI file:
| +- setCommParams: Command (5)
| | +-- baudRate
| | | +- [ 1200, 4800, 9600, 19200, 38400, 57600, 115200 ]
| | +-- mode
| | | +- [ 232, 422, 485 ]
| | +-- stopBits
| | +-- parity
| | | +- [ NONE, EVEN, ODD, MARK, SPACE ]
| | +-- dataBits

Other combinations I have tried end up with:
com.amx.mojo.api.thing.exception.ThingValidationException: Value is a string that can't be converted to a number

Comments

  • Marc ScheibeinMarc Scheibein Posts: 882

    tried it out, same issue here:
    dvSerial1.setCommParams("9600", "232", 1, "NONE", 8) dvSerial1.setFlowControl("NONE")
    com.amx.mojo.api.thing.exception.ThingValidationException: Invalid thing {mode} value [8]; index not in range [0..2]

    I checked against Automator, and there the databits field is an (integer) field like the stopbits, and not and dropdown list with predefined values. This would match to the descriptor file.

    print('baudrate: ' + str(dvSerial1.baudRate.value)) print('dataBits: ' +str(dvSerial1.dataBits.value)) print('dataBits type: ' +str(dvSerial1.dataBits.type)) print('dataBits enum: ' +str(dvSerial1.dataBits.enum)) print('mode: ' +str(dvSerial1.mode.value)) print('parity: ' +str(dvSerial1.parity.value)) print('stopBits: ' +str(dvSerial1.stopBits.value))

    results into
    baudrate: 9600 dataBits: 8 dataBits type: integer [ERROR] Parameter has no attribute named: enum dataBits enum: None mode: 232 parity: NONE stopBits: 1

    If I set the params the way
    dvSerial1.setCommParams("9600", "232", 1, "NONE", 0)
    So databits value 0..2, the call is ok. Otherwise, with value 0..2, the dataBits value don't change at all, and stay on 8 bits.
    If changing the dataBits from Automator to e.g. 7, reading the parameters again with Python, the value is reporting 7 , which is correct

    I would say the .setCommParams() has a bug on the dataBits parameter, at least in Python.

    I will report this to TS.

  • Marc ScheibeinMarc Scheibein Posts: 882

    Just as I wrote the TS report.... I think I found the problem.

    dvSerial1.setCommParams("9600", "232", 1, "NONE", 8) dvSerial1.setFlowControl("NONE")
    com.amx.mojo.api.thing.exception.ThingValidationException: Invalid thing {mode} value [8]; index not in range [0..2]

    Why does the fault happen on parameter {mode} ?!?!?!??!

    Well, I compared with the demo conference room Python code on the ITG Github, and found:
    The parameter order in the idevice descriptor file is wrong!!!
    By descriptor: (baudRate, mode, stopBits, parity, dataBits)
    By Github sample: (baudRate, dataBits, stopBits, parity, mode)

    So if setting the comm parameters as a parameter list, the parameters for mode and dataBits get mixed up when assuming the order from the descriptor.

    I will modify my report to Harman about this.

  • clangerakclangerak Posts: 11

    Yes, can confirm that it works for me in that order. I'm sure I tried all combinations of order with no success, but it seems fine now.

    It would be far better if the methods allow keyword arguments, then the order would not matter.

    I have been having some issues also with the listen() method not invoking the callback on a serial receive. Hard power cycling the mojo controller fixes it. It seems py4j.java_gateway stops triggering messages. I've not been able to find a consistent way to get this to happen, but it seems to happen mostly on script upload. At one point, neither comm port on my MU-1300 would trigger receive events, even after multiple calls to listen() and enableReceive() and restarting the script. Only a hard reboot fixed it.

  • clangerakclangerak Posts: 11

    Same thing has happened on site with an MU-2300, once again, a power cycle fixed it.

  • Marc ScheibeinMarc Scheibein Posts: 882

    If you in that failed state, could you do a SSH terminal connection to the MU, e.g. by PuTTY (works faster than with the integrated console in the MU web interface). Please login, and then do
    tail:log
    This activates the debug output. Leaving tail:log is by ctrl-c.

    Do you see messages? kind of
    18:19:19.704 ERROR [41] com.amx.mojo.thing Cannot obtain a new communication channel
    18:19:22.234 INFO [51] com.amx.thing.icsp Update path:port/1/button/6 to true
    18:19:22.236 ERROR [41] com.amx.mojo.thing Cannot obtain a new communication channel
    18:19:22.430 INFO [51] com.amx.thing.icsp Update path:port/1/button/6 to false

    This is happening on my test environment at the moment. After changing a script and uploading, the script doesn't work, and I get that output. The push/release of the panel is received, but not passed into the script. Then I have to reboot the MU (can also be done in the SSH console, by simply "reboot"), the scripts do what I want (or better: what I wrote them to do, sometimes it's not the result I wanted :) )

Sign In or Register to comment.