Need help in Script to Read or Parse a File

Hi All,
I have a windows openhab setup below is the quick config

  • Platform information:
    • Hardware: AMD Ryzen 5 Desktop
    • OS: Windows 10
    • Java Runtime Environment: openjdk version “11.0.15” (Azul Zulu )
    • openHAB version: 3.0.2

I am trying to write a script to read a file from my disk(have a windows system running openhab 3.0.2). The file sits within the openhab’s conf folder

I have referenced following threads:

From the references i have gathered the basic is


import java.io.File

try{

logInfo('Info', 'Info')
}
catch(Exception e){
logInfo('Error', 'Error')
}

So I put this in a DSL script and even executing the above line i get following error

[ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'testReadScript' failed:  ___ import  ___ java.io.File

try{

logInfo('Info', 'Info')
}
catch(Exception e){
logInfo('Error', 'Error')
}
   1. The method or field import is undefined; line 1, column 0, length 6
   2. This expression is not allowed in this context, since it doesn't cause any side effects.; line 1, column 7, length 12

I have tried the following

  • Use ECMA Script type i get a whole different error
  • Changed my JDK from AdoptOpenJDK to Azul Zulu
  • Restarts system, openhab service
  • Run in console (command prompt) the error is consistent.

Also don’t want to use the html static folder workaround and use http binding to read the file as it will be exposed to the http server.

I feel I am making some basic mistake as even using only import statement is giving error. Am i missing any automation / scripting add-ons. Can you please help on getting the script for reading of file in windows setup working.

Thanks

Import needs to be done before rule statement

import is the very first line in my script

If you are working in UI rules, you can’t do this with Rules DSL in this way because you can’t import anything. You have to import stuff before the rule and in a UI Script, there is no before the rule.

If you want to use UI rules with Rules DSL, you’ll have to be clever. If you are on Linux you can use cat.

val myFileContents = executeCommandLine(java.time.Duration.ofSeconds(1), 'cat /path/to/file')

To do it in ECMAScript, see Javascript | Program to read text File - GeeksforGeeks or any of the many generic JavaScript tutorials on the topic.

Thanks, yes I am using UI rules and as im on a Win system cat or even exec command is not a feasible option.

I will try the ECMA route

why ?

type would be the windows equivalent for the linux command cat in this context.

Since I have a similar need I experimented a bit with writing a file from Javascript (ECMAScript-2021).

Create a script (or a rule) in MainUI and try this code:

// Creating a test file
var FileWriter = Java.type('java.io.FileWriter');
var BufferedWriter = Java.type('java.io.BufferedWriter');

var outFile = new FileWriter("deleteme.txt");
var out = new BufferedWriter(outFile);
out.write("Some text");
out.newLine();
out.flush();
//out.close();

out.append('more text');
out.newLine();
out.append('even more text');
out.close();

In my tests the file was created in the ‘userdata’ directory (since I did not explicitly specify a directory).
If you do not want to use the exec solution, this may help getting started with a plain JavaScript solution.

1 Like

Think its to do with getting a UI for the command prompt if i am correct (OH3 Windows 10 executeCommandLine can't run batch files - #2 by Wolfgang_S)

Thanks @Fleck this is what i needed. I have modified the code to read a file instead of writing.
Abstract code is as below in the ECMA Script in the Main UI

var scanner = Java.type('java.util.Scanner');
var file =Java.type('java.io.File');
var myFile = new file('..\\conf\\scripts\\new.txt'); //relative path to userdata folder
var myScanner = new scanner(myFile);
var line = "";
var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);
while (myScanner.hasNextLine()) {
            line = myScanner.nextLine();
            var fields = line.split("=");
           
           logger.info(fields[0]);//Just got the first value
        }