Processing: Write HTML file from arduino input - java

I'm trying to make a plant monitor using an Arduino and processing.
Processing writes an html file based on the sensor input by the Arduino.
WinSCP is monitoring the file created for changes and directly uploads trough FTP when the file has changed.
The Arduino is sending the following to processing via serial:
45
0
31
40
x
Using the following code in processing I write an html page with this data:
import processing.serial.*;
Serial myPort;
String dataReading = "";
int lol = 0;
String string0 = "<h1>Jurze Plants <img src=\"https://html-online.com/editor/tinymce/plugins/emoticons/img/smiley-laughing.gif\" alt=\"laughing\" /></h1>";
String string1 = "Moisture Level: ";
String string2 = " %<br> Motorstate: ";
String string3 = "<br> Temperature: ";
String string4 = " °C<br> Humidity: ";
String string5 = "%<br>";
void setup() {
size(500, 500);
myPort = new Serial(this, "COM4", 9600);
myPort.bufferUntil('x');
}
void draw() {
}
String [] dataOutput = {};
void serialEvent(Serial myPort) {
dataReading = myPort.readString();
if (dataReading!=null) {
dataOutput = split(dataReading, '\n');
String [] tempfile = {string0,string1,dataOutput[1],string2,dataOutput[2],string3,dataOutput[3],string4,dataOutput[4],string5 };
println("saving to html file...");
saveStrings("data/index.html",tempfile);
}
}
The html code I get the first time is :
<h1>Jurze Plants <img src="https://html-online.com/editor/tinymce/plugins/emoticons/img/smiley-laughing.gif" alt="laughing" /></h1>
Moisture Level: 46 %<br>
Motorstate: 0 <br>
Temperature:31.00 °C <br>
Humidity: 35.00% <br>
Though, after it gets the data from the Arduino for the second time it looks like this:
<h1>Jurze Plants <img src="https://html-online.com/editor/tinymce/plugins/emoticons/img/smiley-laughing.gif" alt="laughing" /></h1>
Moisture Level: %<br>
Motorstate: 46 <br>
Temperature:0 °C <br>
Humidity: 31.00% <br>
I guess there is something wrong with the array?
Any help would be highly appreciated! :D

Time to debug your code! (We can't really do this for you, since we don't have your Arduino.)
Step 1: In your serialEvent() function, use the println() function to print out the value of dataReading. Is the value what you expect?
Step 2: Print out the value of dataOutput. Is that what you expect? Print out each index. Are they all what you expect? Check for extra spaces and control characters.
Step 3: Are the indexes what you expect them to be? I see you're starting with index 1 instead of index 0. Is that what you meant to do?
The point is, you have to print out the values of every variable to make sure they're what you expect. When you find the variable with the wrong value, you can trace back through your code to figure out exactly what's happening.

Related

.replace isn't updating variable value resulting in incorrect write to an output file

This is a portion of a mab libs game that is reading in a template from one file and then using PrintStream to send out the game results to another wherever a tag in the template such as or exists, the user is prompted to give a value to replace it. The issue that I'm having right now is that the tags with a "-" are not being replaced. One of the requirements is that all "-" be converted to spaces instead so I have some code to do so. As a result of the code that checks for a "-", the template output where tags contain "-" don't get changed to the user input. If I remove the code that checks for -, It works fine but the user prompt cant include a -.
while (each.hasNext()) {
String word = each.next();
if (word.contains("<")) {
int start = word.indexOf("<");
int end = word.indexOf(">");
// word between <>
String x = word.substring(start + 1, end);
// checks
if (x.contains("-")) {
x = x.replace("-", " ");
}
// if tag starts with a vowel, make "an";
if (vowelCheck(x) == true) {
preInput = "an";
}
System.out.println("please enter " + preInput + " " + x + ":");
String lib = userInput.nextLine();
// maybe make it not word
word = word.replace(x, lib);
// edit not holding changed text ,lib is correct though
output.print(word);
} else {
// normal words in lines with tags
output.print(word + " ");
}
}
I used some print statements to check var values and word = word.replace(x, lib) doesn't seem to be getting updated from the x value as I expected it to, Think that might be where the issue is occurring but haven't been able to get passed that.
I spent a long time trying to figure this out and I'm totally stuck! All help is greatly appreciated
data:
input file looks something like this:
<Male-Name> has announced that his <adjective>
clothing store in the heart of downtown <CITY> is having
a/an <adjective> sale of all merchandise, including
<unusual-adjective> suits and slightly irregular <plural-noun>
available. Men's cable-knit <plural-noun> , only $15.99.
Hand-woven Italian <plural-noun> , 1/2-price. Double-
breasted cashmere <plural-noun> , $50.00. Genuine imported
<Color!> <adjective> shoes, <Exciting-adjective> handerchiefs,
and women's embroidered <plural-noun> , all at rock-bottom prices.
This is a chance to get some really <Interesting-Adjective> bargains.
BAD OUTPUT:
<Male-Name>has announced that his <flat>
clothing store in the heart of downtown <LA>is having
a/an <fast>sale of all merchandise, including
<unusual-adjective>suits and slightly irregular <plural-noun>
available. Men's cable-knit <plural-noun>, only $15.99.
Hand-woven Italian <plural-noun>, 1/2-price. Double-
breasted cashmere <plural-noun>, $50.00. Genuine imported
<blue><small>shoes, <Exciting-adjective>handerchiefs,
and women's embroidered <plural-noun>, all at rock-bottom prices.
This is a chance to get some really <Interesting-Adjective>bargains.
All should be replaced just like the rest.
Your problem is that when you have dashes in a replacement tag, you're replacing the dashes with spaces, but then you're trying to find that modified version of the string in the input text to replace it with the user's input value. Since you changed the value after you pulled it out of the text, it is no longer going to match the text.
What you can do is save off the original value and use that to find/replace the user's input into the original text.
int start = word.indexOf("<");
int end = word.indexOf(">");
// word between <>
String x = word.substring(start + 1, end);
String origX = x; // <- MAKE A COPY OF THE TAG STRING
// checks
if (x.contains("-")) {
x = x.replace("-", " ");
}
String preInput = "";
System.out.println("please enter " + preInput + " " + x + ":");
String lib = userInput.nextLine();
// maybe make it not word
word = word.replace(origX, lib); // <- USE THE COPY YOU MADE EARLIER TO DO THE FIND/REPLACE
// edit not holding changed text ,lib is correct though
System.out.println(word);

How to find if HL7 Segment has ended or not if Carriage return is not present

I am working on a tool which will construct a HL7 message in following Way :
Message will start with : 0B
Segment will end with : OD
And Message will end with : 1C0D
So, here i have reached so far, i am able to add OB and add 1C0D in the end of the HL7 Message. I am also able to add OD before at the end of the segment. I am accomplishing with the of code where i will check if Character before Segment name is 0D or not.
But the issue is if text in the message is somewhat like this ...PID| my code will add 0D before PID| which is not correct it should check if its the start of the segment or not.
Please help if someone has worked on similar requirement.
Link to my code is :
Arraylist Sublist IndexOutOfBounds Exception
I had some time to look at this problem. As far as I could understand, you have some piece of code that generates the HL7v2 segments for you and then you want to create a message with the following delimiters:
Segment delimiter: 0x0D (or 13 in ASCII), which is the Carriage Return. It's the segment separator, as per HL7v2 standard;
Message start delimiter: 0x0B (ASCII 11 - Vertical Tab);
Message finish delimiter: 0x1C0D. My guess is that this value is supposed to be the concatenation of 0x1C (ASCII 28 - File Separator) and 0x0D (ASCII 13 - Carriage Return).
With #1 you get HL7v2 messages standard-compliant. With #2 and #3 you are able to clearly define delimiters for the message so that it can be processed and parsed later by some custom processor.
So I took a shot writing some simple code and here's the result:
public class App
{
public static void main( String[] args ) throws Exception
{
String msg = "MSH|^~\\&|HIS|RIH|EKG|EKG|199904140038||ADT^A01||P|2.5" +
"PID|0001|00009874|00001122|A00977|SMITH^JOHN^M|MOM|19581119|F|NOTREAL^LINDA^M|C|564 SPRING ST^^NEEDHAM^MA^02494^US" +
"AL1||SEV|001^POLLEN";
String[] segments = msg.split("(?=PID|AL1)");
System.out.println("Initial message:");
for (String s : segments)
System.out.println(s);
byte hexStartMessage = 0x0B;
byte hexFinishMessage1 = 0x1C;
byte hexFinishMessage2 = 0x0D;
byte hexFinishSegment = 0x0D;
String finalMessage = Byte.toString(hexStartMessage) +
intersperse(segments, hexFinishSegment) +
Byte.toString(hexFinishMessage1) +
Byte.toString(hexFinishMessage2);
System.out.println("\nFinal message:\n" + finalMessage);
}
public static String intersperse(String[] segments, byte delimiter) throws UnsupportedEncodingException {
// uncomment this line if you wish to show the delimiter in the output
//System.out.printf("Byte Delimiter: %s", String.format("%04x", (int)delimiter));
StringBuilder sb = new StringBuilder();
String defaultDelimiter = "";
for (String segment : segments) {
sb.append(defaultDelimiter).append(segment);
defaultDelimiter = Byte.toString(delimiter);
}
return sb.toString();
}
}
I picked up a simple HL7v2 message and I splitted it in segments, according to the segments (name) used in the message, with the help of a regex with a lookahead strategy. This means that, for your messages you'll need to know the segments that are going to be used (you can get that from the standard).
I then interspersed the segment delimiter between each segment (at its end) and added the message start and end delimiters. In this case, for the message end delimiters, I used the 0x1C and 0x0D values separated, but if you need to use a single value then you only need to change the final appends.
Here's the output:
Initial message:
MSH|^~\&|HIS|RIH|EKG|EKG|199904140038||ADT^A01||P|2.5
PID|0001|00009874|00001122|A00977|SMITH^JOHN^M|MOM|19581119|F|NOTREAL^LINDA^M|C|564 SPRING ST^^NEEDHAM^MA^02494^US
AL1||SEV|001^POLLEN
Final message:
11MSH|^~\&|HIS|RIH|EKG|EKG|199904140038||ADT^A01||P|2.5
PID|0001|00009874|00001122|A00977|SMITH^JOHN^M|MOM|19581119|F|NOTREAL^LINDA^M|C|564 SPRING ST^^NEEDHAM^MA^02494^US
AL1||SEV|001^POLLEN2813
As you see, the final message begins with value 11 (0x0B) and ends with 28 (0x1C) and 13 (0x0D). The 13 (0x0D) at the end of each segment is not shown because Java's System.out.println() recognizes it as being the '\r' character and starts a new line because I'm running in Mac OS X. If you try to intersperse the segments with any other character (ex: 0x25 = '%') you'll notice that the final message is printed in a single line:
11MSH|^~\&|HIS|RIH|EKG|EKG|199904140038||ADT^A01||P|2.5%PID|0001|00009874|00001122|A00977|SMITH^JOHN^M|MOM|19581119|F|NOTREAL^LINDA^M|C|564 SPRING ST^^NEEDHAM^MA^02494^US%AL1||SEV|001^POLLEN2813
If I run in Ubuntu, you get to see the message in one line with the segment delimiter:
11MSH|^~\&|HIS|RIH|EKG|EKG|199904140038||ADT^A01||P|2.513PID|0001|00009874|00001122|A00977|SMITH^JOHN^M|MOM|19581119|F|NOTREAL^LINDA^M|C|564 SPRING ST^^NEEDHAM^MA^02494^US13AL1||SEV|001^POLLEN2813

Using regex to parse a string from text that includes a newline

Given the following text, I'm trying to parse out the string "TestFile" after Address::
File: TestFile
Branch
OFFICE INFORMATION
Address: TestFile
City: L.A.
District.: 43
State: California
Zip Code: 90210
DISTRICT INFORMATION
Address: TestFile2
....
I understand that lookbehinds require zero-width so quantifiers are not allowed, meaning this won't work:
(?<=OFFICE INFORMATION\n\s*Address:).*(?=\n)
I could use this
(?<=OFFICE INFORMATION\n Address:).*
but it depends on consistent spacing, which isn't dynamic and thus not ideal.
How do I reliably parse out "TestFile" and not "TestFile2" as shown in my example above. Note that Address appears twice but I only need the first value.
Thank you
You don't really need to use a lookbehind here. Get your matched text using captured group:
(?:\bOFFICE INFORMATION\s+Address:\s*)(\S+)
RegEx Demo
captured group #1 will have value TestFile
JS Code:
var re = /(?:\bOFFICE INFORMATION\s+Address:\s*)(\S+)/;
var m;
var matches = [];
if ((m = re.exec(input)) !== null) {
if (m.index === re.lastIndex)
re.lastIndex++;
matches.push(m[1]);
}
console.log(matches);
Working with Array:
// A sample String
String questions = "File: TestFile Branch OFFICE INFORMATION Address: TestFile City: L.A. District.: 43 State: California Zip Code: 90210 DISTRICT INFORMATION Address: TestFile2";
// An array list to store split elements
ArrayList arr = new ArrayList();
// Split based on colon and spaces.
// Including spaces resolves problems for new lines etc
for(String x : questions.split(":|\\s"))
// Ignore blank elements, so we get a clean array
if(!x.trim().isEmpty())
arr.add(x);
This will give you an array which is:
[File, TestFile, Branch, OFFICE, INFORMATION, Address, TestFile, City, L.A., District., 43, State, California, Zip, Code, 90210, DISTRICT, INFORMATION, Address, TestFile2]
Now lets analyze... suppose you want information corresponding to Address, or element Address. This element is at position 5 in array. That means element 6 is what you want.
So you would do this:
String address = arr.get(6);
This will return you testFile.
Similarly for City, element 8 is what you want. The count starts from 0. You can ofcourse modify my matching pattern or even create a loop and get yourself even better ways to do this task. This is just a hint.
Here is one such example loop:
// Every i+1 is the property tag, and every i+2 is the property name for
// Skip first 6 elements because they are of no real purpose to us
for(int i = 6; i<(arr.size()/2)+6; i+=2)
System.out.println(arr.get(i));
This gives following output:
TestFile
L.A.
43
California
Code
Ofcourse this loop is unrefined, refine it a little and you will get every element correctly. Even the last element. Or better yet, use ZipCode instead of Zip Code and dont use spaces in between and you will have a perfect loop with nothing much to be done in addition).
The advantage over using direct regex: You wont have to specify the regex for every single element. Iteration is always more handy to get things done automatically.
See this
//read input from file
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(new File("D:/tests/sample.txt"))));
StringBuilder string = new StringBuilder();
String line = "";
while((line = reader.readLine()) != null){
string.append(line);
string.append("\n");
}
//now string will contain the input as
/*File: TestFile
Branch
OFFICE INFORMATION
Address: TestFile
City: L.A.
District.: 43
State: California
Zip Code: 90210
DISTRICT INFORMATION
Address: TestFile2
....*/
Pattern regex = Pattern.compile("(OFFICE INFORMATION.*\\r?\\n.*Address:(?<officeAddress>.*)\\r?\\n)");
Matcher regexMatcher = regex.matcher(string.toString());
while (regexMatcher.find()) {
System.out.println(regexMatcher.group("officeAddress"));//prints TestFile
}
You can see the named group officeAddress in the pattern which is needed to be extracted.

Imacros Parsing String

I was wondering if someone could show me how to extract part of string from a var in a Imacros java script.
WebPageNumber = "Code: ";
WebPageNumber += "TAB T=1" + NewLine;
WebPageNumber += "FRAME NAME="+"ext-comp-1006" + NewLine;
WebPageNumber += "TAG POS=1 TYPE=SPAN ATTR=ID:00B70000007Wo0i_paginator_rpp_target EXTRACT=TXT" + NewLine;
WebPageNumber += "SET !CLIPBOARD {{!EXTRACT}}";
PlayMacro = iimPlay(WebPageNumber);
alert (iimGetLastExtract ());
My Result is
1-75 of 75 Display 10 records per page Display 25 records per page Display 50 records per page Display 100 records per page Display 200 records per page
All I want to take from it is 1 & 75
Since you're already using the JS implementation of iMacros, wouldn't it be easier just to manipulate that information with JS?
var extractString = iimGetLastExtract();
var firstNumber = extractString.substring(0,1);
var secondNumber = extractString.substring(2,2);
That's assuming that you'll always be looking for the first number and the second pair of numbers. You can also use regular expressions with the JavaScript String match() method, but
that'll dump an array of values.

extract values of ping message

I am working on an application on android that performs ping requests (via android shell) and I read from the console the message displayed. A typical message is the following
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=46 time=186 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=46 time=209 ms
--- 8.8.8.8 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 186.127/197.891/209.656/11.772 ms
I store the above message in a String. I want to extract the values of the time, for example 186 and 209 and also the percentage for loss, 0 (in this case).
I was thinking to go through the string and look the values after "time=". However I don't know how to do it.
How can I manipulate the string I have in order to extract the values?
Start by getting each line of the string:
String[] lines = pingResult.split("\n");
Then, loop and use substring.
for (String line : lines) {
if (!line.contains("time=")) continue;
// Find the index of "time="
int index = line.indexOf("time=");
String time = line.substring(index + "time=".length());
// do what you will
}
If you want to parse to an int, you could additionally do:
int millis = Integer.parseInt(time.replaceAll("[^0-9]", ""));
This will remove all non-digit characters
You can do something similar for the percentage:
for (String line : lines) {
if (!line.contains("%")) continue;
// Find the index of "received, "
int index1 = line.indexOf("received, ");
// Find the index of "%"
int index2 = line.indexOf("%");
String percent = line.substring(index1 + "received, ".length(), index2);
// do what you will
}

Categories

Resources