ctucx.git: smartied

[nimlang] smarthome server

commit d4b070d3e7085e9124f233743727dceed6c9f39f
parent f07b88e6dbb7a7ee81895d773e7cbac9ebafb651
Author: Milan Pässler <me@pbb.lc>
Date: Wed, 11 Sep 2019 22:29:03 +0200

modbus: use shared async task for receiving
1 file changed, 22 insertions(+), 6 deletions(-)
M
src/modbus.nim
|
28
++++++++++++++++++++++------
diff --git a/src/modbus.nim b/src/modbus.nim
@@ -2,34 +2,48 @@ import asyncnet
 import asyncdispatch
 import strutils
 import vars
+import tables
 
 ### modbus general ###
 
 var sock {.threadvar.}: AsyncSocket
 var transaction_id {.threadvar.}: uint16
+var transactions {.threadvar.}: Table[uint16, proc(msg: string)]
 
 proc mkPacket_mbTcp(mb_packet: string): string =
   inc(transaction_id)
   return parseHexStr(toHex(transaction_id) & toHex(0u16) & toHex(uint16(len(mb_packet)))) & mb_packet
 
-proc readPacket_mbTcp(): Future[string] {.async.} =
+proc readPacket_mbTcp(): Future[(uint16, string)] {.async.} =
   var res = ""
 
   res = await sock.recv(6)
   if res == "":
     raise newException(OsError, "verbindung putt")
+
+  let transaction_id = fromHex[uint16](toHex(res[0..1]))
   let length = fromHex[uint16](toHex(res[4..5]))
 
   res = await sock.recv(int(length))
   if res == "":
     raise newException(OsError, "verbindung putt")
-  return res
 
-proc doRequest[T](req: string, parse_proc: proc(foo: string): T): Future[T] {.async.} =
+  return (transaction_id, res)
+
+proc processAnswers() {.async.} =
+  while true:
+    let (transaction_id, mb_packet) = await readPacket_mbTcp()
+    transactions[transaction_id](mb_packet)
+
+proc doRequest[T](req: string, parse_proc: proc(foo: string): T): Future[T] =
+  var fut = newFuture[T]()
+
   let tcp_packet = mkPacket_mbTcp(req)
-  await sock.send(tcp_packet)
-  let answer = await readPacket_mbTcp()
-  return parse_proc(answer)
+  asyncCheck sock.send(tcp_packet)
+  transactions[transaction_id] = proc(answer: string) =
+    fut.complete(parse_proc(answer))
+
+  return fut
 
 ### readInputRegisters ###
 

@@ -83,3 +97,5 @@ proc mbFloatDCBA*(input: seq[uint16]): float32 =
 proc initModbus*() {.async.} =
   sock = await asyncnet.dial(server.config.modbusAddr, Port(server.config.modbusPort))
   transaction_id = 0u16
+  transactions = initTable[uint16, proc(msg: string)]()
+  asyncCheck processAnswers()