Send command to serial port and receive a answer

I can live with time cost. At the moment I have only one issue and it’s a java version.
Not sure if armbian is “ready” for openhab with correct java version or I must search how to downgrade under dietpi (or armbian). I tried a sugested instructions but no luck till now.

Nobody seems to have mentioned actually removing Java 17

problem solved :

java 11 installed, downgrade not necessary

Instruction:
install java 11:

sudo apt-get -s install openjdk-11-jdk

then install the default Java Development Kit:

sudo apt install default-jdk

and set default java :

sudo update-alternatives --config java
sudo update-alternatives --config javac

and

reboot

after reboot must

java -version
javac -version

show java 11

1 Like

Let’s go back to my next step. Decode a answer to get relevant data from the answer.
I created rule which will work with received data. Idea is following, take a received string, split char to char and then convert to hex.

var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);
var item = itemRegistry.getItem('Received');
var text = item.getState();
val string1 = item.state.split("");

in the terminal I’m looking online on logger information. Problem is to get working a split function. I tried a several instructions, but always a split error.

tested:

val string1 = itemName.state.toString.split("");
String[] arrOfStr = str.split("");

What about https://www.baeldung.com/string/get-bytes
There is an older thread with may need a bit of adaption Rule to convert ASCII to HEX

Your input string is binary, not characters…
Break the string into bytes - almost certainly by using getBytes. Have another look at examples already given.

When you say this sort of thing, remember we cannot see what you are doing. What’s a ‘split error’, for example? Show us the logs when relevant.

As first step I tried modify part of code from this :

https://community.openhab.org/t/help-with-binary-data-serial-binding-3-1/126859

So my code is :

var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID)
val char[] hexArray = "0123456789ABCDEF".toCharArray()
val byte[] bytes = RawType.valueOf(POSLAT.state.toString()).getBytes()
val char[] hexChars = newCharArrayOfSize(bytes.length() * 2)
	 for (var j = 0; j < bytes.length(); j++) {
	 var int v = bytes.get(j).bitwiseAnd(0xFF)
	 hexChars.set(j * 2, hexArray.get(v >>> 4))
	 hexChars.set(j * 2 + 1, hexArray.get(v.bitwiseAnd(0x0F)))
    }
val outString = new String(hexChars)
logger.info(outString)

but I have a error:

The code you took the example from is written in DSL syntax.
Looks like you try to run it with the javascript interpreter. Javascript expects a semicolon at end of rows.

That’s DSL rule, written in the original oH1 rules language.
You’ve decided to use javascript, so you can’t just copy/paste, the syntax is different. You don’t declare variables in javascript with val, for example.

oh, my error. I have a mixture of java and DSL
I think if I will run it as DSL then first line

var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID)

isn’t ok.
Is also under DSL any logger for debug ?

Yes, see examples for different log levels at Logging | openHAB

so i took my code

val char[] hexArray = "0123456789ABCDEF".toCharArray()
val byte[] bytes = RawType.valueOf(POSLAT.state.toString()).getBytes()
val char[] hexChars = newCharArrayOfSize(bytes.length() * 2)
	 for (var j = 0; j < bytes.length(); j++) {
	 var int v = bytes.get(j).bitwiseAnd(0xFF)
	 hexChars.set(j * 2, hexArray.get(v >>> 4))
	 hexChars.set(j * 2 + 1, hexArray.get(v.bitwiseAnd(0x0F)))
    }
val outString = new String(hexChars)
stav.postUpdate(outString)

and switched rule to DSL and started again
Received new error :

In meantime I’m playing/testing/learning java.
I copied simple example text and placed as jave rule :

      try {
 
            // taking input string
            String s = "GeeksForGeeks";
 
            // name of supported charset
            // UTF-16 is an encoding constant
            String charsetName = "UTF-16";
 
            // UTF-16 charset encoding and storing the
            // resultant bytearray.
            byte[] byteArray = s.getBytes("UTF-16");
 
            // printing the byte array to convert it into
            // string
            System.out.println(Arrays.toString(byteArray));
 
            // printing the length of input string and
            // resultant byte array
            System.out.println("Length of String"
                               + " " + s.length() + " "
                               + "Length of byte Array"
                               + " " + byteArray.length);
        }
        catch (UnsupportedEncodingException e) {
            System.out.println("Unsupported charset :" + e);
        }

also there I have a error (same as before regarding ; ):

I know that code isn’t perfect, but first of all compilation must work

The error message about invalid URI syntax is coming from RawType.valueOf.

If you are trying to decode binary data then you need to be using the binary channel from the serial bridge.

1 Like

Thank you. I reworked, so now I have serial bridge with string channel and binary channel :

in the rule I’m sending a command to the string channel :

var testoutput = '\u0010\u0001\u00FF\u00FF\u0000\u0060\u0008\u0002\u00D3\u00D1\u00FF'
SerialBridge_StringData.sendCommand(testoutput)

and response I’m reading from the binary channel and decoding to HEX:

val char[] hexArray = "0123456789ABCDEF".toCharArray()
val byte[] bytes = RawType.valueOf(SerialBridge_BinaryData.state.toString()).getBytes()
val char[] hexChars = newCharArrayOfSize(bytes.length() * 2)
	 for (var j = 0; j < bytes.length(); j++) {
	 var int v = bytes.get(j).bitwiseAnd(0xFF)
	 hexChars.set(j * 2, hexArray.get(v >>> 4))
	 hexChars.set(j * 2 + 1, hexArray.get(v.bitwiseAnd(0x0F)))
    }
val outString = new String(hexChars)
stav.postUpdate(outString)

and yes, now I have a HEX answer from the external unit:

Now I will try decode important informations for me and do next actions.

2 Likes

I want ask following
during transformation to hex I’m creating a array :

val char[] hexChars = newCharArrayOfSize(bytes.length() * 2)
	 for (var j = 0; j < bytes.length(); j++) {
	 var int v = bytes.get(j).bitwiseAnd(0xFF)
	 hexChars.set(j * 2, hexArray.get(v >>> 4))
	 hexChars.set(j * 2 + 1, hexArray.get(v.bitwiseAnd(0x0F)))

is it possible read somehow exact byte from this array ?

I tried this :
val outString = new String(hexChars.getBytes(1))
val outString = new String(hexChars.get(1))
but it’s not a right one

That’s what this part does

v is an “exact byte”.
It’s not a string like “0”, “F”, it’s an integer with a value that might be expressed as 16 decimal or 0F hex.

What do you want to do with it, might be the right question? Compare, multiply, convert to a string like “0F” etc.?

I received this :
FFFF1017FFFF1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F0000BFAD
FFFF1017FFFF - it’s start information
but next 16x 1F is 16 temperatures for 16 rooms. 1F = 31. To this value is added a constant (for me 5) and then this 16 values I want link to items (room temperature)

Okay, so work out what you want to do. Something like “get the twentieth byte, get the numeric value, divide by ten, add a unit, and pass to a Number:Temperature Item”
You can’t code until you have an objective.