URBot.java 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package at.acdp.urweb;
  2. import at.acdp.urweb.sclient.data.MasterBoardData;
  3. import at.acdp.urweb.sclient.data.RobotProgramLabel;
  4. import at.acdp.urweb.sclient.data.ScReadThread;
  5. import okhttp3.*;
  6. import org.slf4j.Logger;
  7. import org.slf4j.LoggerFactory;
  8. import java.util.Optional;
  9. import java.util.concurrent.BlockingQueue;
  10. import java.util.concurrent.LinkedBlockingQueue;
  11. import java.util.concurrent.Semaphore;
  12. import java.util.concurrent.atomic.AtomicInteger;
  13. public class URBot {
  14. private static final Logger log = LoggerFactory.getLogger(URBot.class);
  15. private static final MediaType MEDIA_TYPE_JSON
  16. = MediaType.get("application/json; charset=utf-8");
  17. private ScReadThread sc;
  18. private BlockingQueue<RobotCommand> cmdq = new LinkedBlockingQueue<>();
  19. private AtomicInteger nextID = new AtomicInteger(1);
  20. private Semaphore cmdDoneSem = new Semaphore(0);
  21. private RobotProgramLabel currentAck;
  22. private Optional<RobotCommand> runningScript = Optional.empty();
  23. public URBot(String ip, int port) {
  24. sc = new ScReadThread(ip, port, this);
  25. }
  26. public synchronized void ackNumber(RobotProgramLabel rpl) {
  27. this.currentAck = rpl;
  28. cmdDoneSem.release();
  29. }
  30. public void start() {
  31. Thread readThread = new Thread(sc);
  32. readThread.start();
  33. Thread queueThread = new Thread(() -> {
  34. try {
  35. while (true) {
  36. runningScript = Optional.of(cmdq.take());
  37. var rs = runningScript.get();
  38. sc.writeCmd(rs);
  39. cmdDoneSem.acquire();
  40. while (true) {
  41. if (currentAck.id == rs.id && currentAck.message.equals("URWEB_END")) {
  42. if (rs.cpeeCallback != null) {
  43. ackCPEE(rs);
  44. }
  45. runningScript = Optional.empty();
  46. break;
  47. }
  48. }
  49. }
  50. } catch (InterruptedException e) {
  51. e.printStackTrace();
  52. }
  53. });
  54. queueThread.start();
  55. }
  56. private void write(RobotCommand rc) {
  57. String[] lines = rc.cmd.split("[\\r\\n]+");
  58. String res = "";
  59. for (String line : lines) {
  60. line = line.trim();
  61. if (line.startsWith("//"))
  62. continue;
  63. if (line.startsWith("#"))
  64. continue;
  65. if (!line.endsWith("\n"))
  66. line += "\n";
  67. res += line;
  68. }
  69. if (!res.endsWith("\n"))
  70. res += "\n";
  71. res = res.trim();
  72. int id = nextID.getAndIncrement();
  73. if (res.endsWith("end")) {
  74. res = res.substring(0, res.length() - 3);
  75. res += String.format("$ %s \"URWEB_END\"\nend\n", id);
  76. }
  77. try {
  78. rc.id = id;
  79. // rc.cmd = String.format("def urweb():\n%s\n$ %s \"URWEB_END\"\nend\n", res, id);
  80. rc.cmd = res;
  81. this.cmdq.put(rc);
  82. } catch (InterruptedException e) {
  83. Thread.currentThread().interrupt();
  84. }
  85. }
  86. private void ackCPEE(RobotCommand r) {
  87. try {
  88. OkHttpClient client = new OkHttpClient();
  89. Request request = new Request.Builder()
  90. .url(r.cpeeCallback + "/")
  91. .put(RequestBody.create(MEDIA_TYPE_JSON, "[{}]"))
  92. .build();
  93. log.info("putting to {}", r.cpeeCallback);
  94. Response res = client.newCall(request).execute();
  95. log.info("result {}", res.toString());
  96. r.cpeeCallbackResult = res.body().string();
  97. r.cpeeCallbackCode = res.code();
  98. r.cpeeCallbackMessage = res.message();
  99. } catch (Exception e) {
  100. log.warn("cpee callback failed", e);
  101. r.cpeeCallbackError = e.getMessage();
  102. }
  103. }
  104. private void sendStringCmd(String cmd) {
  105. sc.writeCmd(new RobotCommand(nextID.getAndIncrement(), cmd));
  106. }
  107. public void sendFreedrive(int timeout) {
  108. sendStringCmd(String.format("def myProg():\n\tfreedrive_mode()\n\tsleep(%d)\nend", timeout));
  109. }
  110. public void sendMessage(String message) {
  111. sendStringCmd(String.format("textmsg(%s)", message));
  112. }
  113. public void setDigital(int which, boolean val) {
  114. sendStringCmd(String.format("digital_out[%d]=%s", which, val ? "True" : "False"));
  115. }
  116. public boolean getDigital(int which) {
  117. MasterBoardData mb = sc.getRde().getLastMB();
  118. return ((mb.digitalOutputBits & (1 << which)) > 0);
  119. }
  120. public void sendCmd(RobotCommand cmd) {
  121. write(cmd);
  122. }
  123. public BlockingQueue<RobotCommand> getCmdq() {
  124. return cmdq;
  125. }
  126. public Optional<RobotCommand> getRunningScript() {
  127. return runningScript;
  128. }
  129. }