• Recent
    • Tags
    • Popular
    • Register
    • Login

    Please Note This forum exists for community support for the Mango product family and the Radix IoT Platform. Although Radix IoT employees participate in this forum from time to time, there is no guarantee of a response to anything posted here, nor can Radix IoT, LLC guarantee the accuracy of any information expressed or conveyed. Specific project questions from customers with active support contracts are asked to send requests to support@radixiot.com.

    Radix IoT Website Mango 3 Documentation Website Mango 4 Documentation Website Mango 5 Documentation Website

    Issue with Serial Port Data Source

    User help
    2
    6
    515
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • E
      emeinig
      last edited by

      Hey everyone,

      I could use some advice in dealing with an issue regarding the serial data source in Mango. I currently have serial data source that is set to read from a SPI-12 to USB adapter through /dev/ttyUSB0. The data point currently looks for \r\n line terminators and uses the regex ()[^ ]+ Within the data source is a data point that I have set up as a "catch-all" of sorts. The catchall has no point identifier, uses a value group of 0 and uses RegEx that'll capture everything ([^]+).

      I also have another data source that uses scripting to query the adapter at /dev/ttyUSB0. The script looks like this:

          // Send the ID command. We expect a response of
          // 013METER   ATM41 529ATM-410004576
          catchall.set('0I!\r\n');
      
          // Give the sensor 1 second to respond
          RuntimeManager.sleep(1000);
      
          // response is a variable for a data point within the scripting data source
          response.set(catchall.value);
      

      where response is a virtual and settable variable from the scripting data source

      Neither response nor the catchall data source thus far have been able to capture any sort of value. The serial IO log indicate that there is an output of 0I! and input of 013METER ATM41 529ATM 410004576 as desired:

      2023/09/25-14:43:08,854 O: 0I!
      
      2023/09/25-14:43:09,366 I: 013METER   ATM41 529ATM-410004576
      

      Looking through ma.log reveals that there's this:

          ERROR 2023-09-25T14:43:24,367 (com.infiniteautomation.serial.rt.SerialDataSourceRT.serialEvent:476) - No authentication set in security context
          com.serotonin.m2m2.vo.permission.PermissionException: No authentication set in security context
                  at com.serotonin.m2m2.Common.getUser(Common.java:455) ~[mango-5.0.0.jar:?]
                  at com.serotonin.timer.Task.<init>(Task.java:98) ~[mango-5.0.0.jar:?]
                  at com.serotonin.timer.TimerTask.<init>(TimerTask.java:21) ~[mango-5.0.0.jar:?]
                  at com.serotonin.m2m2.util.timeout.TimeoutTask.<init>(TimeoutTask.java:38) ~[mango-5.0.0.jar:?]
                  at com.serotonin.m2m2.util.timeout.TimeoutTask.<init>(TimeoutTask.java:30) ~[mango-5.0.0.jar:?]
                  at com.infiniteautomation.serial.rt.SerialDataSourceRT.serialEvent(SerialDataSourceRT.java:293) ~[?:?]
                  at com.infiniteautomation.mango.io.serial.SerialPortProxyEventTask.run(SerialPortProxyEventTask.java:38) ~[mango-5.0.0.jar:?]
                  at com.infiniteautomation.mango.io.serial.JsscSerialPortManager$1.run(JsscSerialPortManager.java:67) ~[mango-5.0.0.jar:?]
      

      All of the data sources and data points have the correct permissions (i.e., they're editable and readable by users and the anonymous group). the Mango user is a member of the dialout group and can read/write to /dev/ttyUSB0.

      Are there any potential avenues I should look into with getting Mango to record the input from the adapter? Any help is greatly appreciated!

      MattFoxM 1 Reply Last reply Reply Quote 0
      • MattFoxM
        MattFox @emeinig
        last edited by MattFox

        @emeinig first off for simplicity's sake
        The two regexes for both the datasource and datapoint can be

        (.*)
        

        with the the '\r\n' terminator.
        A capture group of 0 for the datasource should pass the entire string in (Although a 1 shouldn't make a difference), then use a capture group of 1 on the datapoint itself.
        No point indicator required.

        Start from that and see what comes in.

        Fox

        Do not follow where the path may lead; go instead where there is no path.
        And leave a trail - Muriel Strode

        E 1 Reply Last reply Reply Quote 0
        • E
          emeinig @MattFox
          last edited by

          @MattFox

          Heya Matt,

          Thanks for the suggestions. I implemented them and still no joy.

          I'm still getting the mysterious PermissionException error in ma.log

          MattFoxM 1 Reply Last reply Reply Quote 0
          • MattFoxM
            MattFox @emeinig
            last edited by

            @emeinig you're not logged out by any chance are you?

            Fox

            Do not follow where the path may lead; go instead where there is no path.
            And leave a trail - Muriel Strode

            E 1 Reply Last reply Reply Quote 0
            • E
              emeinig @MattFox
              last edited by

              @MattFox

              I just double checked and I can confirm I'm logged in as the admin

              E 1 Reply Last reply Reply Quote 0
              • E
                emeinig @emeinig
                last edited by emeinig

                @emeinig

                I got it resolved with a workaround. I'm going to post what I did for posterity and to hopefully help anyone who might come across the same issue in the future.

                What I ended up doing is creating a scripting data source. The datasource uses Rhino as its scripting engine so you can use some Java in it. With the Java, you can read/write to files and leverage the "Everything is a file" philosophy in *nix systems.

                The code:

                // import the file reader
                var FileReader = java.io.FileReader;
                var BufferedReader = java.io.BufferedReader;
                
                // import the writer. We must use OutputStreamWriter to write to device files
                var OutputStreamWriter = java.io.OutputStreamWriter;
                var FileOutputStream = java.io.FileOutputStream;
                
                // Be careful because this could change on us depending on how many USB devices
                // are plugged in
                var serial_port = "/dev/ttyUSB0";
                // Initialize a bunch of blank strings to store measurements
                var max_time_measurements,
                  temp_and_pressure,
                  wind_attrs,
                  solar_and_precip = new String();
                
                // Set up the writer
                var file = new FileOutputStream(serial_port);
                var output = new OutputStreamWriter(file);
                
                // Set up the streamer
                var fr = new FileReader(serial_port);
                var br = new BufferedReader(fr);
                
                // Write the measurement command to the serial port and flush to ensure the
                // buffer is empty for the next command.
                output.write("0M!\r\n");
                output.flush();
                // The sensor takes around 3 seconds to return 9 values, so we sleep for 4
                // seconds to give it a generous margin
                RuntimeManager.sleep(4000);
                // Now we write our data commands to get it all.
                output.write("0D0!\r\n");
                output.flush();
                output.write("0D1!\r\n");
                output.flush();
                output.write("0D2!\r\n");
                output.flush();
                output.close();
                
                // readLine will read the return values
                max_time_measurements = br.readLine();
                solar_and_precip = br.readLine();
                wind_attrs = br.readLine();
                temp_and_pressure = br.readLine();
                
                //split the 0D0! result
                var solar_and_precip_array = solar_and_precip.split("+");
                solarRad.set(solar_and_precip_array[1]);
                precipitation.set(solar_and_precip_array[2]);
                lightningStrikes.set(solar_and_precip_array[3]);
                
                //split the 0D1! result
                var wind_attrs_array = wind_attrs.split("+");
                windSpeed.set(wind_attrs_array[1]);
                windDirection.set(wind_attrs_array[2]);
                gustWindSpeed.set(wind_attrs_array[3]);
                
                //split the 0D2! result
                var temp_and_pressure_array = temp_and_pressure.split("+");
                temp.set(temp_and_pressure_array[1]);
                vaporPressure.set(temp_and_pressure_array[2]);
                atmosphericPressure.set(temp_and_pressure_array[3]);
                
                

                The code isn't the prettiest or most elegant but it does work. Just make sure you have the necessary variables created as data points and that they're settable and you're all good to go.

                1 Reply Last reply Reply Quote 0
                • First post
                  Last post