Skip to content

Commit

Permalink
Move old SiPunch into SiPunchLog
Browse files Browse the repository at this point in the history
Create SiPunch which is pure SI punch without metadata
  • Loading branch information
lukipuki committed May 26, 2024
1 parent d015381 commit 0673cc0
Show file tree
Hide file tree
Showing 12 changed files with 141 additions and 111 deletions.
10 changes: 5 additions & 5 deletions python/yaroc/clients/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from serial_asyncio import open_serial_connection

from ..pb.status_pb2 import Status
from ..rs import SiPunch
from ..rs import SiPunchLog


class Client(ABC):
Expand All @@ -22,7 +22,7 @@ async def loop(self):
pass

@abstractmethod
async def send_punch(self, punch: SiPunch) -> bool:
async def send_punch(self, punch_log: SiPunchLog) -> bool:
pass

@abstractmethod
Expand Down Expand Up @@ -69,12 +69,12 @@ async def loop(self):
)
self.writer.write(msg)

async def send_punch(self, punch: SiPunch) -> bool:
async def send_punch(self, punch_log: SiPunchLog) -> bool:
if self.writer is None:
logging.error("Serial client not connected")
return False
try:
self.writer.write(bytes(punch.raw))
self.writer.write(bytes(punch_log.raw))
logging.info("Punch sent via serial port")
return True
except serial.serialutil.SerialException as err:
Expand Down Expand Up @@ -109,7 +109,7 @@ async def send_status(self, status: Status, mac_address: str) -> Sequence[bool |
ClientGroup.handle_results(results)
return results

async def send_punch(self, punch: SiPunch) -> Sequence[bool | BaseException]:
async def send_punch(self, punch: SiPunchLog) -> Sequence[bool | BaseException]:
handles = [client.send_punch(punch) for client in self.clients]
results = await asyncio.gather(*handles)
ClientGroup.handle_results(results)
Expand Down
12 changes: 6 additions & 6 deletions python/yaroc/clients/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from ..pb.punches_pb2 import Punch, Punches
from ..pb.status_pb2 import Disconnected, Status
from ..pb.utils import create_punch_proto
from ..rs import SiPunch
from ..rs import SiPunchLog
from ..utils.async_serial import AsyncATCom
from ..utils.modem_manager import ModemManager, NetworkType
from ..utils.retries import BackoffBatchedRetries
Expand Down Expand Up @@ -83,15 +83,15 @@ def get_topics(self, mac_addr: str) -> Topics:

async def send_punch(
self,
punch: SiPunch,
punch_log: SiPunchLog,
) -> bool:
punches = Punches()
try:
punches.punches.append(create_punch_proto(punch))
punches.punches.append(create_punch_proto(punch_log))
except Exception as err:
logging.error(f"Creation of Punch proto failed: {err}")
punches.sending_timestamp.GetCurrentTime()
topics = self.get_topics(punch.host_info.mac_address)
topics = self.get_topics(punch_log.host_info.mac_address)
return await self._send(topics.punch, punches.SerializeToString(), 1, "Punch")

async def send_status(self, status: Status, mac_addr: str) -> bool:
Expand Down Expand Up @@ -192,9 +192,9 @@ async def _send_punches(self, punches: list[Punch]) -> list[bool]:

async def send_punch(
self,
punch: SiPunch,
punch_log: SiPunchLog,
) -> bool:
res = await self._retries.send(create_punch_proto(punch))
res = await self._retries.send(create_punch_proto(punch_log))
return res if res is not None else False

async def send_status(self, status: Status, mac_addr: str) -> bool:
Expand Down
7 changes: 4 additions & 3 deletions python/yaroc/clients/roc.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from aiohttp_retry import ExponentialRetry, RetryClient

from ..pb.status_pb2 import EventType, Status
from ..rs import SiPunch
from ..rs import SiPunchLog
from ..utils.modem_manager import NetworkType
from ..utils.sys_info import FREQ_MULTIPLIER
from .client import Client
Expand All @@ -30,7 +30,7 @@ async def loop(self):

async def send_punch(
self,
punch: SiPunch,
punch_log: SiPunchLog,
) -> bool:
def length(x: int):
if x == 0:
Expand All @@ -40,6 +40,7 @@ def length(x: int):

return int(math.log10(x)) + 1

punch = punch_log.punch
now = datetime.now()
data = {
"control1": str(punch.code),
Expand All @@ -49,7 +50,7 @@ def length(x: int):
"sitime1": punch.time.strftime("%H:%M:%S"),
"ms1": punch.time.strftime("%f")[:3],
"roctime1": str(now)[:19],
"macaddr": punch.host_info.mac_address,
"macaddr": punch_log.host_info.mac_address,
"1": "f",
"length": str(118 + sum(map(length, [punch.code, punch.card, punch.mode]))),
}
Expand Down
5 changes: 3 additions & 2 deletions python/yaroc/clients/sirap.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from typing import Literal

from ..pb.status_pb2 import Status
from ..rs import SiPunch
from ..rs import SiPunchLog
from .client import Client

ENDIAN: Literal["little", "big"] = "little"
Expand Down Expand Up @@ -61,7 +61,8 @@ def _serialize_punch(card_number: int, si_daytime: time, code: int) -> bytes:
+ SirapClient._time_to_bytes(si_daytime)
)

async def send_punch(self, punch: SiPunch) -> bool:
async def send_punch(self, punch_log: SiPunchLog) -> bool:
punch = punch_log.punch
message = SirapClient._serialize_punch(punch.card, punch.time.time(), punch.code)
return await self._send(message)

Expand Down
6 changes: 3 additions & 3 deletions python/yaroc/pb/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from google.protobuf.timestamp_pb2 import Timestamp

from ..rs import SiPunch
from ..rs import SiPunchLog
from .punches_pb2 import Punch
from .status_pb2 import Coordinates

Expand All @@ -14,9 +14,9 @@ def _datetime_to_prototime(time: datetime) -> Timestamp:
return ret


def create_punch_proto(si_punch: SiPunch) -> Punch:
def create_punch_proto(punch_log: SiPunchLog) -> Punch:
punch = Punch()
punch.raw = bytes(si_punch.raw)
punch.raw = bytes(punch_log.punch.raw)
return punch


Expand Down
14 changes: 9 additions & 5 deletions python/yaroc/rs.pyi
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import datetime
from datetime import datetime, timedelta
from enum import IntEnum
from typing import ClassVar as _ClassVar
from typing import Dict
Expand All @@ -17,17 +17,21 @@ class SiPunch(object):
code: int
time: datetime
mode: int
host_info: HostInfo
raw: bytes

class SiPunchLog(object):
punch: SiPunch
latency: timedelta
host_info: HostInfo

@staticmethod
def new(
card: int, code: int, time: datetime, mode: int, host_info: HostInfo, now: datetime
) -> "SiPunch": ...
) -> "SiPunchLog": ...
@staticmethod
def from_raw(payload: bytes, host_info: HostInfo, now: datetime) -> "SiPunch": ...
def from_raw(payload: bytes, host_info: HostInfo, now: datetime) -> "SiPunchLog": ...
@staticmethod
def from_msh_serial(payload: bytes) -> "SiPunch": ...
def from_msh_serial(payload: bytes) -> "SiPunchLog": ...

class RaspberryModel(IntEnum):
Unknown = 0
Expand Down
4 changes: 2 additions & 2 deletions python/yaroc/sources/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from ..clients.client import ClientGroup
from ..clients.mqtt import BROKER_PORT, BROKER_URL
from ..pb.status_pb2 import Status as StatusProto
from ..rs import MessageHandler, SiPunch
from ..rs import MessageHandler, SiPunchLog
from ..utils.status import StatusDrawer


Expand Down Expand Up @@ -42,7 +42,7 @@ def _payload_to_bytes(payload: PayloadType) -> bytes:
else:
raise TypeError("Unexpected type of a message payload")

async def _process_punch(self, punch: SiPunch):
async def _process_punch(self, punch: SiPunchLog):
logging.info(punch)
await self.client_group.send_punch(punch)

Expand Down
23 changes: 12 additions & 11 deletions python/yaroc/sources/si.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from usbmonitor import USBMonitor
from usbmonitor.attributes import DEVNAME, ID_MODEL_ID, ID_VENDOR_ID

from ..rs import HostInfo, SiPunch
from ..rs import HostInfo, SiPunchLog

DEFAULT_TIMEOUT_MS = 3.0
START_MODE = 3
Expand All @@ -34,13 +34,14 @@ class SiWorker:
def __init__(self):
self._codes: set[int] = set()

async def process_punch(self, punch: SiPunch, queue: Queue):
async def process_punch(self, punch_log: SiPunchLog, queue: Queue):
now = datetime.now().astimezone()
punch = punch_log.punch
logging.info(
f"{punch.card} punched {punch.code} at {punch.time:%H:%M:%S.%f}, received after "
f"{(now-punch.time).total_seconds():3.2f}s"
)
await queue.put(punch)
await queue.put(punch_log)
self._codes.add(punch.code)

def __str__(self):
Expand All @@ -58,7 +59,7 @@ def __init__(self, port: str, host_info: HostInfo):
self.host_info = host_info
self._finished = Event()

async def loop(self, queue: Queue[SiPunch]):
async def loop(self, queue: Queue[SiPunchLog]):
successful = False
for i in range(3):
try:
Expand All @@ -82,7 +83,7 @@ async def loop(self, queue: Queue[SiPunch]):
await asyncio.sleep(1.0)
continue
now = datetime.now().astimezone()
punch = SiPunch.from_raw(data, self.host_info, now)
punch = SiPunchLog.from_raw(data, self.host_info, now)
await self.process_punch(punch, queue)

except serial.serialutil.SerialException as err:
Expand Down Expand Up @@ -125,7 +126,7 @@ async def loop(self, queue: Queue, _status_queue):
await asyncio.sleep(1.0)
continue
now = datetime.now().astimezone()
punch = SiPunch.from_raw(data, self.host_info, now)
punch = SiPunchLog.from_raw(data, self.host_info, now)
await self.process_punch(punch, queue)

except Exception as err:
Expand All @@ -148,7 +149,7 @@ def extract_com(device_name: str) -> str:

return match.groups()[0]

async def loop(self, queue: Queue[SiPunch], status_queue: Queue[DeviceEvent]):
async def loop(self, queue: Queue[SiPunchLog], status_queue: Queue[DeviceEvent]):
self._loop = asyncio.get_event_loop()
logging.info("Starting USB SportIdent device manager")
self.monitor = USBMonitor(({ID_VENDOR_ID: "10c4"}, {ID_VENDOR_ID: "1a86"}))
Expand Down Expand Up @@ -251,8 +252,8 @@ async def loop(self, queue: Queue, _status_queue):
while True:
time_start = time.time()
now = datetime.now().astimezone()
punch = SiPunch.new(46283, 47, now, 18, HostInfo.new("fake", self.mac_addr), now)
await self.process_punch(punch, queue)
punch_log = SiPunchLog.new(46283, 47, now, 18, HostInfo.new("fake", self.mac_addr), now)
await self.process_punch(punch_log, queue)
await asyncio.sleep(self._punch_interval - (time.time() - time_start))


Expand All @@ -266,7 +267,7 @@ class SiPunchManager:

def __init__(self, workers: list[SiWorker]) -> None:
self._si_workers: set[SiWorker] = set(workers)
self._queue: Queue[SiPunch] = Queue()
self._queue: Queue[SiPunchLog] = Queue()
self._status_queue: Queue[DeviceEvent] = Queue()

def __str__(self) -> str:
Expand All @@ -280,7 +281,7 @@ async def loop(self):
await asyncio.sleep(3) # Allow some time for an MQTT connection
await asyncio.gather(*loops, return_exceptions=True)

async def punches(self) -> AsyncIterator[SiPunch]:
async def punches(self) -> AsyncIterator[SiPunchLog]:
while True:
yield await self._queue.get()

Expand Down
Loading

0 comments on commit 0673cc0

Please sign in to comment.