URBot.java 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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.awt.*;
  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. public URBot(String ip) {
  23. sc = new ScReadThread(ip, this);
  24. }
  25. public synchronized void ackNumber(RobotProgramLabel rpl) {
  26. this.currentAck = rpl;
  27. cmdDoneSem.release();
  28. }
  29. public void start() {
  30. Thread readThread = new Thread(sc);
  31. readThread.start();
  32. Thread queueThread = new Thread(() -> {
  33. try {
  34. while (true) {
  35. var c = cmdq.take();
  36. sc.writeCmd(c);
  37. while (true) {
  38. cmdDoneSem.acquire();
  39. if (currentAck.id == c.id && currentAck.message.equals("URWEB_END")) {
  40. if (c.cpeeCallback != null) {
  41. ackCPEE(c);
  42. }
  43. break;
  44. }
  45. }
  46. }
  47. } catch (InterruptedException e) {
  48. e.printStackTrace();
  49. }
  50. });
  51. queueThread.start();
  52. }
  53. private void write(RobotCommand rc) {
  54. String[] lines = rc.cmd.split("[\\r\\n]+");
  55. String res = "";
  56. for (String line : lines) {
  57. line = line.trim();
  58. if (line.startsWith("//"))
  59. continue;
  60. if (line.startsWith("#"))
  61. continue;
  62. if (!line.endsWith("\n"))
  63. line += "\n";
  64. res += line;
  65. }
  66. if (!res.endsWith("\n"))
  67. res += "\n";
  68. res=res.trim();
  69. int id = nextID.getAndIncrement();
  70. if(res.endsWith("end")) {
  71. res=res.substring(0, res.length()-3);
  72. res+=String.format("$ %s \"URWEB_END\"\nend\n", id);
  73. }
  74. try {
  75. rc.id=id;
  76. // rc.cmd = String.format("def urweb():\n%s\n$ %s \"URWEB_END\"\nend\n", res, id);
  77. rc.cmd = res;
  78. this.cmdq.put(rc);
  79. } catch (InterruptedException e) {
  80. Thread.currentThread().interrupt();
  81. }
  82. }
  83. private void ackCPEE(RobotCommand r) {
  84. try {
  85. OkHttpClient client = new OkHttpClient();
  86. Request request = new Request.Builder()
  87. .url(r.cpeeCallback + "/")
  88. .put(RequestBody.create(MEDIA_TYPE_JSON, "[{}]"))
  89. .build();
  90. log.info("putting to {}", r.cpeeCallback);
  91. Response res = client.newCall(request).execute();
  92. log.info("result {}", res.toString());
  93. r.cpeeCallbackResult = res.body().string();
  94. r.cpeeCallbackCode = res.code();
  95. r.cpeeCallbackMessage = res.message();
  96. } catch (Exception e) {
  97. log.warn("cpee callback failed", e);
  98. r.cpeeCallbackError = e.getMessage();
  99. }
  100. }
  101. private void sendStringCmd(String cmd) {
  102. sc.writeCmd(new RobotCommand(nextID.getAndIncrement(), cmd));
  103. }
  104. public void sendFreedrive(int timeout) {
  105. sendStringCmd(String.format("def myProg():\n\tfreedrive_mode()\n\tsleep(%d)\nend", timeout));
  106. }
  107. public void sendMessage(String message) {
  108. sendStringCmd(String.format("textmsg(%s)", message));
  109. }
  110. public void setDigital(int which, boolean val) {
  111. sendStringCmd(String.format("digital_out[%d]=%s", which, val ? "True" : "False"));
  112. }
  113. public boolean getDigital(int which) {
  114. MasterBoardData mb = sc.getRde().getLastMB();
  115. return ((mb.digitalOutputBits & (1 << which)) > 0);
  116. }
  117. public void sendCmd(RobotCommand cmd) {
  118. write(cmd);
  119. }
  120. public BlockingQueue<RobotCommand> getCmdq() {
  121. return cmdq;
  122. }
  123. }