commit d4b070d3e7085e9124f233743727dceed6c9f39f
parent f07b88e6dbb7a7ee81895d773e7cbac9ebafb651
Author: Milan Pässler <me@pbb.lc>
Date: Wed, 11 Sep 2019 22:29:03 +0200
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(-)
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()