• R/O
  • SSH

提交

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

アルファ版。新版→https://osdn.jp/users/tacticsrealize/pf/ChlorophyllUploader/wiki/FrontPage


Commit MetaInfo

修订版82b375367456635f711775be0d76dcafef88ca32 (tree)
时间2015-07-08 20:15:01
作者 <15b05@15b0...>

Log Message

新ファイル形式に対応しArduinoとの連携

更改概述

差异

diff -r f4c95ebf297a -r 82b375367456 src/ants/SampleFileWatcherSpawning.java
--- a/src/ants/SampleFileWatcherSpawning.java Wed Jul 08 20:14:06 2015 +0900
+++ b/src/ants/SampleFileWatcherSpawning.java Wed Jul 08 20:15:01 2015 +0900
@@ -1,18 +1,11 @@
11 package ants;
22
33 import java.io.File;
4-import java.io.FileInputStream;
5-import java.io.InputStreamReader;
6-import java.time.LocalDateTime;
74 import java.time.format.DateTimeFormatter;
8-import java.util.ArrayList;
9-import java.util.List;
10-import java.util.stream.Collectors;
11-import java.util.stream.Stream;
125
136 import mirrg.file.watcherspawning.FileWatcherSpawning;
14-
15-import com.opencsv.CSVReader;
7+import ants.chlorofilsender.BuilderMessage;
8+import ants.chlorofilsender.PacketChlorofilSender;
169
1710 public class SampleFileWatcherSpawning
1811 {
@@ -20,13 +13,13 @@
2013 /**
2114 * ファイル名
2215 */
23- private final static DateTimeFormatter formatterIn =
16+ public final static DateTimeFormatter formatterIn =
2417 DateTimeFormatter.ofPattern("uuuuMMddHHmmss");
2518
2619 /**
2720 * 保存・Arduino送信形式
2821 */
29- private final static DateTimeFormatter formatterOut =
22+ public final static DateTimeFormatter formatterOut =
3023 DateTimeFormatter.ofPattern("uuuu/MM/dd HH:mm:ss");
3124
3225 public static void main(String[] args)
@@ -37,75 +30,31 @@
3730 formatterIn,
3831 formatterOut,
3932 (file, localDateTime) -> {
40- try (CSVReader csvReader = new CSVReader(new InputStreamReader(
41- new FileInputStream(file)))) {
4233
43- csvReader.forEach(csvLine ->
44- SampleFileWatcherSpawning.onData(file, localDateTime, csvLine));
34+ try {
35+ PacketChlorofilSender.parse(localDateTime, file)
36+ .forEach(SampleFileWatcherSpawning::onData);
37+ } catch (Exception e) {
38+ e.printStackTrace();
4539 }
40+
4641 });
4742
43+ // initialized!!
44+
45+ System.out.println(BuilderMessage.setPrefix(
46+ "http://j.kisarazu.ac.jp/Arduino/ANTS/0301/"));
47+
4848 fileWatcherSpawning.start();
4949
5050 }
5151
52- private static void onData(File file, LocalDateTime localDateTime, String[] csvLine)
52+ protected static void onData(PacketChlorofilSender packet)
5353 {
54- // CSV生カットデータがくる
55-
56- // カットデータの長さチェック
57- if (csvLine.length != 15) {
58- System.err.println("illegal size of columns: "
59- + file
60- + " (content: ["
61- + String.join(", ", csvLine)
62- + "])");
63- return;
64- }
65-
66- // カットデータの整形と型変換
67- List<Double> doubles;
68- try {
69- doubles = Stream.of(csvLine)
70- .map(String::trim)
71- .map(Double::parseDouble)
72- .collect(Collectors.toList());
73- } catch (NumberFormatException e) {
74- System.err.println("illegal input string: '"
75- + e.getMessage()
76- + "', file: "
77- + file
78- + "");
79- return;
80- }
81-
82- // 出力用文字列群のビルド
83- ArrayList<String> outputs = new ArrayList<>();
84- outputs.add(formatterOut.format(localDateTime));
85- doubles.stream()
86- .map(output -> output.toString())
87- .forEach(outputs::add);
88-
89- // 出力用文字列群→出力用1行CSV
90- String outputCsv = outputs.stream()
91- .collect(Collectors.joining(","));
92-
93- // 出力
94- onData(file, localDateTime, outputCsv);
95-
96- }
97-
98- protected static void onData(File file,
99- LocalDateTime localDateTime,
100- String outputCsv)
101- {
102-
103- System.out.println("Processed!!: '"
104- + file
105- + "', "
106- + localDateTime.format(formatterOut));
107- System.out.println(outputCsv);
108-
54+ System.out.println(String.format(
55+ "Processed!!: '%s'",
56+ packet.time.format(formatterOut)));
57+ System.out.println(BuilderMessage.build(packet));
10958 }
11059
11160 }
diff -r f4c95ebf297a -r 82b375367456 src/ants/chlorofilsender/BuilderMessage.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ants/chlorofilsender/BuilderMessage.java Wed Jul 08 20:15:01 2015 +0900
@@ -0,0 +1,199 @@
1+package ants.chlorofilsender;
2+
3+import static org.junit.Assert.*;
4+
5+import java.time.LocalDateTime;
6+import java.util.function.Consumer;
7+import java.util.regex.Matcher;
8+import java.util.regex.Pattern;
9+
10+import org.junit.Test;
11+
12+public class BuilderMessage
13+{
14+
15+ @Test
16+ public void test_build()
17+ {
18+ PacketChlorofilSender packet = new PacketChlorofilSender();
19+
20+ packet.time = LocalDateTime.of(2015, 11, 4, 22, 56, 8);
21+ packet.channels[0].set(1.1, 1.2);
22+ packet.channels[1].set(2.1, 2.2);
23+ packet.channels[2].set(3.1, 3.2);
24+ packet.channels[3].set(4.1, 4.2);
25+ packet.channels[4].set(5.1, 5.2);
26+ packet.channels[5].set(6.1, 6.2);
27+ packet.average.set(7.1, 7.2);
28+ packet.height = 8.1;
29+
30+ String res = ""
31+ + "C;SPushFiapPacket;I2015;I11;I4;I22;I56;I8;SCH1/P;S1.1;M" + "\n"
32+ + "C;SPushFiapPacket;I2015;I11;I4;I22;I56;I8;SCH1/S;S1.2;M" + "\n"
33+ + "C;SPushFiapPacket;I2015;I11;I4;I22;I56;I8;SCH2/P;S2.1;M" + "\n"
34+ + "C;SPushFiapPacket;I2015;I11;I4;I22;I56;I8;SCH2/S;S2.2;M" + "\n"
35+ + "C;SPushFiapPacket;I2015;I11;I4;I22;I56;I8;SCH3/P;S3.1;M" + "\n"
36+ + "C;SPushFiapPacket;I2015;I11;I4;I22;I56;I8;SCH3/S;S3.2;M" + "\n"
37+ + "C;SPushFiapPacket;I2015;I11;I4;I22;I56;I8;SCH4/P;S4.1;M" + "\n"
38+ + "C;SPushFiapPacket;I2015;I11;I4;I22;I56;I8;SCH4/S;S4.2;M" + "\n"
39+ + "C;SPushFiapPacket;I2015;I11;I4;I22;I56;I8;SCH5/P;S5.1;M" + "\n"
40+ + "C;SPushFiapPacket;I2015;I11;I4;I22;I56;I8;SCH5/S;S5.2;M" + "\n"
41+ + "C;SPushFiapPacket;I2015;I11;I4;I22;I56;I8;SCH6/P;S6.1;M" + "\n"
42+ + "C;SPushFiapPacket;I2015;I11;I4;I22;I56;I8;SCH6/S;S6.2;M" + "\n"
43+ + "C;SPushFiapPacket;I2015;I11;I4;I22;I56;I8;SAverage/P;S7.1;M" + "\n"
44+ + "C;SPushFiapPacket;I2015;I11;I4;I22;I56;I8;SAverage/S;S7.2;M" + "\n"
45+ + "C;SPushFiapPacket;I2015;I11;I4;I22;I56;I8;SHeight;S8.1;M" + "\n"
46+ + "C;SFlushFiapPackets;M" + "\n";
47+
48+ assertEquals(res,
49+ build(packet));
50+ }
51+
52+ public static String build(PacketChlorofilSender packet)
53+ {
54+ StringBuilder sb = new StringBuilder();
55+
56+ sb.append(sendPacket(packet.time, "CH1/P", "" + packet.channels[0].p));
57+ sb.append(sendPacket(packet.time, "CH1/S", "" + packet.channels[0].s));
58+ sb.append(sendPacket(packet.time, "CH2/P", "" + packet.channels[1].p));
59+ sb.append(sendPacket(packet.time, "CH2/S", "" + packet.channels[1].s));
60+ sb.append(sendPacket(packet.time, "CH3/P", "" + packet.channels[2].p));
61+ sb.append(sendPacket(packet.time, "CH3/S", "" + packet.channels[2].s));
62+ sb.append(sendPacket(packet.time, "CH4/P", "" + packet.channels[3].p));
63+ sb.append(sendPacket(packet.time, "CH4/S", "" + packet.channels[3].s));
64+ sb.append(sendPacket(packet.time, "CH5/P", "" + packet.channels[4].p));
65+ sb.append(sendPacket(packet.time, "CH5/S", "" + packet.channels[4].s));
66+ sb.append(sendPacket(packet.time, "CH6/P", "" + packet.channels[5].p));
67+ sb.append(sendPacket(packet.time, "CH6/S", "" + packet.channels[5].s));
68+ sb.append(sendPacket(packet.time, "Average/P", "" + packet.average.p));
69+ sb.append(sendPacket(packet.time, "Average/S", "" + packet.average.s));
70+ sb.append(sendPacket(packet.time, "Height", "" + packet.height));
71+ sb.append(flush());
72+
73+ return sb.toString();
74+ }
75+
76+ @Test
77+ public void test_sendPacket()
78+ {
79+ assertEquals(
80+ "C;SPushFiapPacket;I2015;I6;I30;I20;I9;I24;STest;S234;M\n",
81+ sendPacket(
82+ LocalDateTime.of(2015, 6, 30, 20, 9, 24),
83+ "Test", "234"));
84+ }
85+
86+ public static String sendPacket(
87+ LocalDateTime time,
88+ String path, String value)
89+ {
90+ return callMethod("PushFiapPacket", consumer -> {
91+ consumer.accept(time.getYear());
92+ consumer.accept(time.getMonthValue());
93+ consumer.accept(time.getDayOfMonth());
94+ consumer.accept(time.getHour());
95+ consumer.accept(time.getMinute());
96+ consumer.accept(time.getSecond());
97+
98+ consumer.accept(path);
99+ consumer.accept(value);
100+ });
101+ }
102+
103+ @Test
104+ public void test_flush()
105+ {
106+ assertEquals(
107+ "C;SFlushFiapPackets;M\n",
108+ flush());
109+ }
110+
111+ public static String flush()
112+ {
113+ return callMethod("FlushFiapPackets", consumer -> {
114+ });
115+ }
116+
117+ @Test
118+ public void test_setPrefix()
119+ {
120+ assertEquals(
121+ "C;SSetFiapIdPrefix;Shttp://www.google.com/Test/;M\n",
122+ setPrefix("http://www.google.com/Test/"));
123+ }
124+
125+ public static String setPrefix(String string)
126+ {
127+ return callMethod("SetFiapIdPrefix", consumer -> {
128+ consumer.accept(string);
129+ });
130+ }
131+
132+ @Test
133+ public void test_callMethod()
134+ {
135+ assertEquals(
136+ "C;SMeth;D4.5;I79;D0.0;I0;S68;S;S/f4b[@\\\\4,].5o@s,\\;4e\\\n0o;M\n",
137+ callMethod("Meth", consumer -> {
138+ consumer.accept(4.5);
139+ consumer.accept(79);
140+ consumer.accept(0.0);
141+ consumer.accept(0);
142+ consumer.accept("68");
143+ consumer.accept("");
144+ consumer.accept("/f4b[@\\4,].5o@s,;4e\n0o");
145+ }));
146+ }
147+
148+ protected static final Pattern patternOperatorBreak =
149+ Pattern.compile("([\\n;\\\\])");
150+
151+ public static String callMethod(String name, Consumer<IConsumerArgument> arguments)
152+ {
153+ StringBuilder sb = new StringBuilder();
154+
155+ sb.append("C;");
156+ IConsumerArgument consumerArgument = new IConsumerArgument() {
157+
158+ @Override
159+ public void accept(int argument)
160+ {
161+ sb.append("I" + argument + ";");
162+ }
163+
164+ @Override
165+ public void accept(double argument)
166+ {
167+ sb.append("D" + argument + ";");
168+ }
169+
170+ @Override
171+ public void accept(String argument)
172+ {
173+ Matcher matcher = patternOperatorBreak.matcher(argument);
174+ sb.append("S"
175+ + matcher.replaceAll("\\\\$1")
176+ + ";");
177+ }
178+
179+ };
180+ consumerArgument.accept(name);
181+ arguments.accept(consumerArgument);
182+ sb.append("M");
183+ sb.append("\n");
184+
185+ return sb.toString();
186+ }
187+
188+ public interface IConsumerArgument
189+ {
190+
191+ public void accept(int argument);
192+
193+ public void accept(double argument);
194+
195+ public void accept(String argument);
196+
197+ }
198+
199+}
diff -r f4c95ebf297a -r 82b375367456 src/ants/chlorofilsender/FrameChlorofilPacket.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ants/chlorofilsender/FrameChlorofilPacket.java Wed Jul 08 20:15:01 2015 +0900
@@ -0,0 +1,172 @@
1+package ants.chlorofilsender;
2+
3+import java.awt.Component;
4+import java.time.LocalDateTime;
5+import java.time.ZoneId;
6+import java.util.ArrayList;
7+import java.util.Date;
8+import java.util.function.Consumer;
9+
10+import javax.swing.JButton;
11+import javax.swing.JCheckBox;
12+import javax.swing.JLabel;
13+import javax.swing.JSpinner;
14+import javax.swing.SpinnerDateModel;
15+import javax.swing.SpinnerNumberModel;
16+import javax.swing.Timer;
17+
18+import jp.hishidama.swing.layout.GroupLayoutUtil;
19+import mirrg.util.FrameMirrg;
20+import mirrg.util.Tuple;
21+
22+public class FrameChlorofilPacket extends FrameMirrg
23+{
24+
25+ public FrameChlorofilPacket(Consumer<PacketChlorofilSender> consumerPacket)
26+ {
27+ super("ChlorofilPacket");
28+
29+ {
30+ JCheckBox checkBox1 = new JCheckBox("現在時刻に同期", true);
31+ Tuple<JLabel, JSpinner> spinnerTime = createSpinnerRowDate("Time");
32+
33+ // P S
34+ ArrayList<JSpinner[]> listSpinners = new ArrayList<>();
35+ for (int i = 0; i < 6; i++) {
36+ listSpinners.add(createSpinnersRowDouble());
37+ }
38+ JSpinner[] spinnersAverage = createSpinnersRowDouble();
39+
40+ Tuple<JLabel, JSpinner> spinnerHeight = createSpinnerRowDouble("Height", 0, -10000, 10000, 0.1);
41+
42+ JButton buttonSend = new JButton("Send!");
43+ JButton buttonRandomize = new JButton("Randomize");
44+
45+ //
46+
47+ buttonSend.addActionListener(e -> {
48+ consumerPacket.accept(new PacketChlorofilSender(
49+ LocalDateTime.ofInstant(
50+ ((Date) spinnerTime.getY().getValue()).toInstant(),
51+ ZoneId.systemDefault()),
52+ ((Double) listSpinners.get(0)[0].getValue()),
53+ ((Double) listSpinners.get(0)[1].getValue()),
54+ ((Double) listSpinners.get(1)[0].getValue()),
55+ ((Double) listSpinners.get(1)[1].getValue()),
56+ ((Double) listSpinners.get(2)[0].getValue()),
57+ ((Double) listSpinners.get(2)[1].getValue()),
58+ ((Double) listSpinners.get(3)[0].getValue()),
59+ ((Double) listSpinners.get(3)[1].getValue()),
60+ ((Double) listSpinners.get(4)[0].getValue()),
61+ ((Double) listSpinners.get(4)[1].getValue()),
62+ ((Double) listSpinners.get(5)[0].getValue()),
63+ ((Double) listSpinners.get(5)[1].getValue()),
64+ ((Double) spinnersAverage[0].getValue()),
65+ ((Double) spinnersAverage[1].getValue()),
66+ ((Double) spinnerHeight.getY().getValue())));
67+ });
68+
69+ buttonRandomize.addActionListener(e -> {
70+ listSpinners.forEach(spinners -> {
71+ spinners[0].setValue(Math.random() * 500);
72+ spinners[1].setValue(Math.random() * 500);
73+ });
74+ spinnersAverage[0].setValue(Math.random() * 500);
75+ spinnersAverage[1].setValue(Math.random() * 500);
76+ spinnerHeight.getY().setValue(Math.random() * 500);
77+ });
78+
79+ {
80+ Timer timer1 = new Timer(1000, e -> {
81+ if (!checkBox1.isSelected()) return;
82+
83+ LocalDateTime value = LocalDateTime.now();
84+ spinnerTime.getY().getModel().setValue(
85+ Date.from(
86+ value.atZone(ZoneId.systemDefault()).toInstant()));
87+ });
88+ timer1.start();
89+
90+ onClosed(e -> {
91+ timer1.stop();
92+ });
93+ }
94+
95+ {
96+ ArrayList<Component[]> arrayComponents = new ArrayList<>();
97+ arrayComponents.add(new Component[] {
98+ null, checkBox1, GroupLayoutUtil.SAME_L,
99+ });
100+ arrayComponents.add(new Component[] {
101+ spinnerTime.getX(), spinnerTime.getY(), GroupLayoutUtil.SAME_L,
102+ });
103+ arrayComponents.add(new Component[] {
104+ null, new JLabel("P"), new JLabel("S"),
105+ });
106+ for (int i = 0; i < listSpinners.size(); i++) {
107+ JSpinner[] spinners = listSpinners.get(i);
108+ arrayComponents.add(new Component[] {
109+ new JLabel("CH" + i), spinners[0], spinners[1],
110+ });
111+ }
112+ arrayComponents.add(new Component[] {
113+ new JLabel("Average"), spinnersAverage[0], spinnersAverage[1],
114+ });
115+ arrayComponents.add(new Component[] {
116+ spinnerHeight.getX(), spinnerHeight.getY(), GroupLayoutUtil.SAME_L,
117+ });
118+ arrayComponents.add(new Component[] {
119+ null, buttonSend, buttonRandomize,
120+ });
121+
122+ Component[][] components = arrayComponents.toArray(new Component[0][]);
123+
124+ GroupLayoutUtil groupLayoutUtil = new GroupLayoutUtil();
125+
126+ groupLayoutUtil.setComponents(components);
127+ groupLayoutUtil.setGroupLayoutTo(this.getContentPane());
128+
129+ groupLayoutUtil.getGroupLayout().setAutoCreateContainerGaps(true);
130+ groupLayoutUtil.getGroupLayout().setAutoCreateGaps(true);
131+ }
132+ }
133+
134+ prepareFrame();
135+ }
136+
137+ private static Tuple<JLabel, JSpinner> createSpinnerRowDouble(
138+ String labelText, double value, double min, double max, double step)
139+ {
140+ return new Tuple<>(new JLabel(labelText), createSpinnerRowDouble(value, min, max, step));
141+ }
142+
143+ private static JSpinner createSpinnerRowDouble(
144+ double value, double min, double max, double step)
145+ {
146+ JSpinner spinner = new JSpinner(new SpinnerNumberModel(value, min, max, step));
147+ spinner.setEditor(new JSpinner.NumberEditor(spinner));
148+
149+ return spinner;
150+ }
151+
152+ private static JSpinner[] createSpinnersRowDouble()
153+ {
154+ return new JSpinner[] {
155+ createSpinnerRowDouble(0, -10000, 10000, 0.1),
156+ createSpinnerRowDouble(0, -10000, 10000, 0.1),
157+ };
158+ }
159+
160+ private static final String dateFormat = "yyyy/MM/dd HH:mm:ss";
161+
162+ private static Tuple<JLabel, JSpinner> createSpinnerRowDate(String labelText)
163+ {
164+ JLabel label = new JLabel(labelText);
165+
166+ JSpinner spinner = new JSpinner(new SpinnerDateModel());
167+ spinner.setEditor(new JSpinner.DateEditor(spinner, dateFormat));
168+
169+ return new Tuple<>(label, spinner);
170+ }
171+
172+}
diff -r f4c95ebf297a -r 82b375367456 src/ants/chlorofilsender/InputChlorofilSender.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ants/chlorofilsender/InputChlorofilSender.java Wed Jul 08 20:15:01 2015 +0900
@@ -0,0 +1,101 @@
1+package ants.chlorofilsender;
2+
3+import java.io.InputStream;
4+import java.util.ArrayList;
5+import java.util.function.BiConsumer;
6+import java.util.function.Consumer;
7+import java.util.function.IntConsumer;
8+
9+import mirrg.util.UTF8StreamReader;
10+
11+public class InputChlorofilSender extends UTF8StreamReader
12+{
13+
14+ public InputChlorofilSender(InputStream in, boolean blocking)
15+ {
16+ super(in, blocking);
17+ }
18+
19+ protected ArrayList<String> messageBlockBuffer;
20+ protected String messageBlockSentinel = null;
21+
22+ public void stream(
23+ IntConsumer consumerAcceptedChar,
24+ BiConsumer<EnumTypeMessage, String> consumerMessage,
25+ Consumer<ArrayList<String>> consumerMessageBlock,
26+ Consumer<Exception> consumerInternalException)
27+ {
28+ stream((Consumer<String>) line -> {
29+
30+ if (messageBlockSentinel != null) {
31+ if (line.equals(messageBlockSentinel)) {
32+ messageBlockSentinel = null;
33+ consumerMessageBlock.accept(messageBlockBuffer);
34+ messageBlockBuffer = new ArrayList<>();
35+ } else {
36+ messageBlockBuffer.add(line);
37+ }
38+
39+ return;
40+ }
41+
42+ {
43+ String res;
44+
45+ if ((res = getProperty(line, "C")) != null) {
46+ int i;
47+ try {
48+ i = Integer.parseInt(res, 10);
49+ } catch (NumberFormatException e) {
50+ consumerInternalException.accept(e);
51+ return;
52+ }
53+ consumerAcceptedChar.accept(i);
54+ return;
55+ }
56+ if ((res = getProperty(line, "Message")) != null) {
57+ consumerMessage.accept(EnumTypeMessage.MESSAGE, res);
58+ return;
59+ }
60+ if ((res = getProperty(line, "Error")) != null) {
61+ consumerMessage.accept(EnumTypeMessage.ERROR, res);
62+ return;
63+ }
64+ if ((res = getProperty(line, "Warnings")) != null) {
65+ consumerMessage.accept(EnumTypeMessage.WARNINGS, res);
66+ return;
67+ }
68+ if ((res = getProperty(line, "MessageBlock")) != null) {
69+ messageBlockSentinel = res;
70+ messageBlockBuffer = new ArrayList<>();
71+ return;
72+ }
73+
74+ }
75+
76+ });
77+ }
78+
79+ protected String getProperty(String string, String prefix)
80+ {
81+ prefix += ":";
82+
83+ if (string.startsWith(prefix)) {
84+ return string.substring(prefix.length());
85+ } else {
86+ return null;
87+ }
88+ }
89+
90+ public static enum EnumTypeMessage
91+ {
92+ MESSAGE, ERROR, WARNINGS,
93+ }
94+
95+ public void close()
96+ {
97+ // TODO 自動生成されたメソッド・スタブ
98+
99+ }
100+
101+}
diff -r f4c95ebf297a -r 82b375367456 src/ants/chlorofilsender/OutputChlorofilSender.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ants/chlorofilsender/OutputChlorofilSender.java Wed Jul 08 20:15:01 2015 +0900
@@ -0,0 +1,101 @@
1+package ants.chlorofilsender;
2+
3+import java.io.OutputStream;
4+import java.io.PrintStream;
5+import java.io.UnsupportedEncodingException;
6+import java.util.Iterator;
7+import java.util.LinkedList;
8+import java.util.function.IntConsumer;
9+
10+public class OutputChlorofilSender
11+{
12+
13+ protected static final int ARDUINO_MAX_BUFFER = 63;
14+
15+ protected PrintStream out;
16+
17+ public OutputChlorofilSender(OutputStream outputStream)
18+ {
19+ try {
20+ out = new PrintStream(outputStream, false, "UTF-8");
21+ } catch (UnsupportedEncodingException e) {
22+ throw new RuntimeException(e);
23+ }
24+ }
25+
26+ protected int sentChars = 0;
27+ protected transient int acceptedChars = 0;
28+
29+ public IntConsumer getConsumerAcceptedChars()
30+ {
31+ return acceptedChars -> {
32+ this.acceptedChars = acceptedChars;
33+ };
34+ }
35+
36+ public void send(String string)
37+ {
38+ synchronized (sendingStrings) {
39+ sendingStrings.add(string);
40+ }
41+ }
42+
43+ protected LinkedList<String> sendingStrings = new LinkedList<>();
44+
45+ protected Thread thread;
46+
47+ public Thread startSenderThread()
48+ {
49+ thread = new Thread(() -> {
50+ try {
51+ while (true) {
52+
53+ synchronized (sendingStrings) {
54+ for (Iterator<String> iterator = sendingStrings.iterator(); iterator.hasNext();) {
55+ String string = iterator.next();
56+ sendImpl(string);
57+ iterator.remove();
58+ }
59+ }
60+
61+ Thread.sleep(5);
62+ }
63+ } catch (InterruptedException e) {
64+ }
65+ });
66+ thread.setDaemon(true);
67+ thread.start();
68+ return thread;
69+ }
70+
71+ protected void sendImpl(String string) throws InterruptedException
72+ {
73+ do {
74+ int bufferedChars = sentChars - acceptedChars;
75+ int bufferSpace = ARDUINO_MAX_BUFFER - bufferedChars;
76+ int sendingChars = Math.min(string.length(), bufferSpace);
77+
78+ sendImpl2(string.substring(0, sendingChars));
79+ string = string.substring(sendingChars);
80+
81+ if (string.isEmpty()) break;
82+
83+ Thread.sleep(5);
84+
85+ } while (true);
86+ }
87+
88+ protected void sendImpl2(String string)
89+ {
90+ sentChars += string.length();
91+ out.print(string);
92+ out.flush();
93+ }
94+
95+ public void close()
96+ {
97+ thread.interrupt();
98+ out.close();
99+ }
100+
101+}
diff -r f4c95ebf297a -r 82b375367456 src/ants/chlorofilsender/PacketChlorofilSender.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ants/chlorofilsender/PacketChlorofilSender.java Wed Jul 08 20:15:01 2015 +0900
@@ -0,0 +1,152 @@
1+package ants.chlorofilsender;
2+
3+import java.io.File;
4+import java.io.FileInputStream;
5+import java.io.IOException;
6+import java.io.InputStream;
7+import java.io.InputStreamReader;
8+import java.time.LocalDateTime;
9+import java.util.ArrayList;
10+import java.util.List;
11+import java.util.stream.Collectors;
12+import java.util.stream.Stream;
13+
14+import com.opencsv.CSVParser;
15+import com.opencsv.CSVReader;
16+
17+public class PacketChlorofilSender
18+{
19+
20+ public LocalDateTime time;
21+ public Channel[] channels = new Channel[6];
22+ public Channel average = new Channel();
23+ public double height;
24+
25+ public PacketChlorofilSender()
26+ {
27+ for (int i = 0; i < channels.length; i++) {
28+ channels[i] = new Channel();
29+ }
30+ }
31+
32+ public PacketChlorofilSender(
33+ LocalDateTime time,
34+ double ch1p, double ch1s,
35+ double ch2p, double ch2s,
36+ double ch3p, double ch3s,
37+ double ch4p, double ch4s,
38+ double ch5p, double ch5s,
39+ double ch6p, double ch6s,
40+ double averageP, double averageS,
41+ double height)
42+ {
43+ this();
44+
45+ this.time = time;
46+ channels[0].set(ch1p, ch1s);
47+ channels[1].set(ch2p, ch2s);
48+ channels[2].set(ch3p, ch3s);
49+ channels[3].set(ch4p, ch4s);
50+ channels[4].set(ch5p, ch5s);
51+ channels[5].set(ch6p, ch6s);
52+ average.set(averageP, averageS);
53+ this.height = height;
54+ }
55+
56+ public static ArrayList<PacketChlorofilSender> parse(LocalDateTime time, File file) throws IOException, PacketChlorofilSenderExcception
57+ {
58+ return parse(time, new FileInputStream(file));
59+ }
60+
61+ public static ArrayList<PacketChlorofilSender> parse(LocalDateTime time, InputStream in) throws IOException, PacketChlorofilSenderExcception
62+ {
63+ try (CSVReader csvReader =
64+ new CSVReader(new InputStreamReader(in))) {
65+
66+ ArrayList<PacketChlorofilSender> packets = new ArrayList<>();
67+
68+ for (String[] csvLine : csvReader) {
69+ packets.add(parse(time, csvLine));
70+ }
71+
72+ return packets;
73+ }
74+ }
75+
76+ public static PacketChlorofilSender parse(LocalDateTime time, String csv) throws IOException, PacketChlorofilSenderExcception
77+ {
78+ CSVParser parser = new CSVParser();
79+ return parse(time, parser.parseLineMulti(csv));
80+ }
81+
82+ public static class PacketChlorofilSenderExcception extends Exception
83+ {
84+
85+ public PacketChlorofilSenderExcception(String string)
86+ {
87+ super(string);
88+ }
89+
90+ public PacketChlorofilSenderExcception(NumberFormatException e)
91+ {
92+ super(e);
93+ }
94+
95+ }
96+
97+ public static PacketChlorofilSender parse(LocalDateTime time, String[] csvLine) throws PacketChlorofilSenderExcception
98+ {
99+ // CSV生カットデータがくる
100+
101+ // カットデータの長さチェック
102+ if (csvLine.length != 15) {
103+ throw new PacketChlorofilSenderExcception("illegal size of columns: "
104+ + csvLine.length
105+ + " != 15");
106+ }
107+
108+ // カットデータの整形と型変換
109+ List<Double> doubles;
110+ try {
111+ doubles = Stream.of(csvLine)
112+ .map(String::trim)
113+ .map(Double::parseDouble)
114+ .collect(Collectors.toList());
115+ } catch (NumberFormatException e) {
116+ throw new PacketChlorofilSenderExcception(e);
117+ }
118+
119+ // build
120+ return new PacketChlorofilSender(
121+ time,
122+ doubles.get(0),
123+ doubles.get(1),
124+ doubles.get(2),
125+ doubles.get(3),
126+ doubles.get(4),
127+ doubles.get(5),
128+ doubles.get(6),
129+ doubles.get(7),
130+ doubles.get(8),
131+ doubles.get(9),
132+ doubles.get(10),
133+ doubles.get(11),
134+ doubles.get(12),
135+ doubles.get(13),
136+ doubles.get(14));
137+
138+ }
139+
140+ public static class Channel
141+ {
142+ public double p;
143+ public double s;
144+
145+ public void set(double p, double s)
146+ {
147+ this.p = p;
148+ this.s = s;
149+ }
150+ }
151+
152+}
diff -r f4c95ebf297a -r 82b375367456 src/ants/chlorofilsender/test/SampleChlorofilSending.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ants/chlorofilsender/test/SampleChlorofilSending.java Wed Jul 08 20:15:01 2015 +0900
@@ -0,0 +1,160 @@
1+package ants.chlorofilsender.test;
2+
3+import gnu.io.CommPortIdentifier;
4+import gnu.io.PortInUseException;
5+import gnu.io.RXTXPort;
6+import gnu.io.SerialPort;
7+import gnu.io.UnsupportedCommOperationException;
8+
9+import java.io.File;
10+
11+import mirrg.file.watcherspawning.FileWatcherSpawning;
12+import ants.Main;
13+import ants.SampleFileWatcherSpawning;
14+import ants.chlorofilsender.BuilderMessage;
15+import ants.chlorofilsender.FrameChlorofilPacket;
16+import ants.chlorofilsender.InputChlorofilSender;
17+import ants.chlorofilsender.OutputChlorofilSender;
18+import ants.chlorofilsender.PacketChlorofilSender;
19+import ants.gui.frames.FrameSelectPort;
20+
21+public class SampleChlorofilSending
22+{
23+
24+ public static void main(String[] args)
25+ {
26+ Main.init();
27+ new FrameSelectPort(SampleChlorofilSending::start).setVisible(true);
28+ }
29+
30+ public static void start(CommPortIdentifier portIdentifier)
31+ {
32+ RXTXPort port;
33+ try {
34+ port = (RXTXPort) portIdentifier.open("ANTS_FILE", 2000);
35+ } catch (PortInUseException e) {
36+ e.printStackTrace();
37+ return;
38+ }
39+
40+ try {
41+ port.setSerialPortParams(
42+ 9600,
43+ SerialPort.DATABITS_8,
44+ SerialPort.STOPBITS_1,
45+ SerialPort.PARITY_NONE);
46+ port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
47+ } catch (UnsupportedCommOperationException e) {
48+ e.printStackTrace();
49+ return;
50+ }
51+
52+ System.out.println("Serial Connected");
53+
54+ ///////////////////////////////////////////////////
55+
56+ OutputChlorofilSender outputChlorofilSender =
57+ new OutputChlorofilSender(port.getOutputStream());
58+
59+ InputChlorofilSender inputChlorofilSender =
60+ new InputChlorofilSender(port.getInputStream(), false);
61+
62+ outputChlorofilSender.startSenderThread();
63+
64+ Thread threadInput;
65+ {
66+ threadInput = new Thread(() -> {
67+ inputChlorofilSender.stream(
68+ outputChlorofilSender.getConsumerAcceptedChars().andThen(acceptedChars -> {
69+ System.out.println(String.format(
70+ "AcceptedChars: %s",
71+ acceptedChars));
72+ }),
73+ (typeMessage, message) -> {
74+ System.out.println(String.format(
75+ "%s: %s",
76+ typeMessage.name(),
77+ message));
78+ },
79+ messageBlock -> {
80+ System.out.println("MESSAGE_BLOCK >>>");
81+ messageBlock.forEach(string -> {
82+ System.out.println(" " + string);
83+ });
84+ },
85+ e -> {
86+ e.printStackTrace();
87+ });
88+ });
89+ threadInput.setDaemon(true);
90+ threadInput.start();
91+ }
92+
93+ System.out.println("Initialized ChlorofilSender IO Wrapper");
94+
95+ ////////////////////////////////////////
96+
97+ FrameChlorofilPacket frameChlorofilPacket = new FrameChlorofilPacket(packet -> {
98+ outputChlorofilSender.send(BuilderMessage.build(packet));
99+ flush(outputChlorofilSender);
100+ });
101+
102+ frameChlorofilPacket.onClosed(e -> {
103+ threadInput.interrupt();
104+ outputChlorofilSender.close();
105+ port.close();
106+ });
107+
108+ System.out.println("Start: port=" + portIdentifier.getName());
109+
110+ FileWatcherSpawning fileWatcherSpawning = new FileWatcherSpawning(
111+ new File("./csvs"),
112+ new File("./config.txt"),
113+ SampleFileWatcherSpawning.formatterIn,
114+ SampleFileWatcherSpawning.formatterOut,
115+ (file, localDateTime) -> {
116+
117+ try {
118+ PacketChlorofilSender.parse(localDateTime, file)
119+ .forEach(packet -> {
120+ outputChlorofilSender.send(BuilderMessage.build(packet));
121+ flush(outputChlorofilSender);
122+ });
123+ } catch (Exception e) {
124+ e.printStackTrace();
125+ }
126+
127+ });
128+
129+ // initialized!!
130+
131+ System.out.println(BuilderMessage.setPrefix(
132+ "http://j.kisarazu.ac.jp/Arduino/ANTS/0301/"));
133+
134+ fileWatcherSpawning.start();
135+
136+ /////////////////////////////////////////////////////
137+
138+ frameChlorofilPacket.setVisible(true);
139+
140+ outputChlorofilSender.send(
141+ "C;SResetSerialReader;M;");
142+
143+ try {
144+ Thread.sleep(1000);
145+ } catch (InterruptedException e) {
146+ e.printStackTrace();
147+ return;
148+ }
149+
150+ outputChlorofilSender.send(
151+ "C;SSetIdPrefix;Shttp://j.kisarazu.ac.jp/Arduino/ANTS/0630/;M;");
152+
153+ }
154+
155+ private static void flush(OutputChlorofilSender outputChlorofilSender)
156+ {
157+ outputChlorofilSender.send("C;SFlushFiapPacket;M;");
158+ }
159+
160+}
diff -r f4c95ebf297a -r 82b375367456 src/ants/chlorofilsender/test/SampleFrameChlorofilPacket.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ants/chlorofilsender/test/SampleFrameChlorofilPacket.java Wed Jul 08 20:15:01 2015 +0900
@@ -0,0 +1,19 @@
1+package ants.chlorofilsender.test;
2+
3+import ants.Main;
4+import ants.chlorofilsender.BuilderMessage;
5+import ants.chlorofilsender.FrameChlorofilPacket;
6+
7+public class SampleFrameChlorofilPacket
8+{
9+
10+ public static void main(String[] args)
11+ {
12+ Main.init();
13+ new FrameChlorofilPacket(packet -> {
14+ String res = BuilderMessage.build(packet);
15+ System.out.println(res);
16+ }).setVisible(true);
17+ }
18+
19+}
diff -r f4c95ebf297a -r 82b375367456 src/ants/chlorofilsender/test/TestPacketChlorofilSender.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ants/chlorofilsender/test/TestPacketChlorofilSender.java Wed Jul 08 20:15:01 2015 +0900
@@ -0,0 +1,67 @@
1+package ants.chlorofilsender.test;
2+
3+import static org.junit.Assert.*;
4+
5+import java.io.ByteArrayInputStream;
6+import java.io.IOException;
7+import java.time.LocalDateTime;
8+import java.util.ArrayList;
9+
10+import org.junit.Test;
11+
12+import ants.chlorofilsender.PacketChlorofilSender;
13+import ants.chlorofilsender.PacketChlorofilSender.PacketChlorofilSenderExcception;
14+
15+public class TestPacketChlorofilSender
16+{
17+
18+ @Test
19+ public void test_parse0() throws IOException, PacketChlorofilSenderExcception
20+ {
21+ ArrayList<PacketChlorofilSender> parse = PacketChlorofilSender.parse(
22+ LocalDateTime.of(2015, 1, 2, 3, 4, 5),
23+ new ByteArrayInputStream(CSV_TEST_PACKET.getBytes("utf-8")));
24+
25+ assertEquals(1, parse.size());
26+ assertPacket(parse.get(0));
27+ }
28+
29+ @Test
30+ public void test_parse1() throws IOException, PacketChlorofilSenderExcception
31+ {
32+ assertPacket(PacketChlorofilSender.parse(
33+ LocalDateTime.of(2015, 1, 2, 3, 4, 5),
34+ CSV_TEST_PACKET));
35+ }
36+
37+ protected String CSV_TEST_PACKET =
38+ "1.1, 1.2, 2.1, 2.2, 3.1, 3.2, 4.1, 4.2, 5.1, 5.2, 6.1, 6.2, 7.1, 7.2, 8.1";
39+
40+ protected void assertPacket(PacketChlorofilSender packet)
41+ {
42+ assertEquals(2015, packet.time.getYear());
43+ assertEquals(1, packet.time.getMonthValue());
44+ assertEquals(2, packet.time.getDayOfMonth());
45+ assertEquals(3, packet.time.getHour());
46+ assertEquals(4, packet.time.getMinute());
47+ assertEquals(5, packet.time.getSecond());
48+
49+ assertEquals(0.0001, 1.1, packet.channels[0].p);
50+ assertEquals(0.0001, 1.2, packet.channels[0].s);
51+ assertEquals(0.0001, 2.1, packet.channels[1].p);
52+ assertEquals(0.0001, 2.2, packet.channels[1].s);
53+ assertEquals(0.0001, 3.1, packet.channels[2].p);
54+ assertEquals(0.0001, 3.2, packet.channels[2].s);
55+ assertEquals(0.0001, 4.1, packet.channels[3].p);
56+ assertEquals(0.0001, 4.2, packet.channels[3].s);
57+ assertEquals(0.0001, 5.1, packet.channels[4].p);
58+ assertEquals(0.0001, 5.2, packet.channels[4].s);
59+ assertEquals(0.0001, 6.1, packet.channels[5].p);
60+ assertEquals(0.0001, 6.2, packet.channels[5].s);
61+ assertEquals(0.0001, 7.1, packet.average.p);
62+ assertEquals(0.0001, 7.2, packet.average.s);
63+
64+ assertEquals(0.0001, 8.1, packet.height);
65+ }
66+
67+}