Compare commits

..

6 Commits

Author SHA1 Message Date
1df1c6bd83 [P] Add primary use-case activity diagram
All checks were successful
Component testing / Hub testing (push) Successful in 24s
Component testing / Store testing (push) Successful in 24s
Component testing / Integration smoke testing (push) Successful in 2m29s
2026-03-24 16:04:08 +02:00
8160f030cd [P] Simplify general sequence diagram 2026-03-24 16:04:08 +02:00
a5dcf09bf2 [P] Move diagrams into a dedicated directory 2026-03-24 16:04:08 +02:00
8548714537 [P] Convert use case diagram files to PlantUML format 2026-03-24 16:04:08 +02:00
942ce98c4b [P] Convert sequence diagram files to PlantUML format 2026-03-24 16:04:08 +02:00
d4e369d5f8 Add use-case and sequence diagrams 2026-03-24 16:04:08 +02:00
5 changed files with 70 additions and 10 deletions

View File

@@ -32,7 +32,7 @@ class MapViewApp(App):
Встановлює необхідні маркери, викликає функцію для оновлення мапи Встановлює необхідні маркери, викликає функцію для оновлення мапи
""" """
self.update() self.update()
Clock.schedule_interval(self.update, 0.1) Clock.schedule_interval(self.update, 5)
def update(self, *args): def update(self, *args):
""" """

View File

@@ -0,0 +1,19 @@
@startuml
actor Worker as worker
participant Agent as agent
participant "Edge" as edge
participant "Hub" as hub
participant "Store" as store
participant "MapView" as mapview
actor Spectator as spectator
worker -> agent : Start agent
agent -> edge : Send sensor data
edge -> edge : Classify road state
edge -> hub : Send processed data
hub -> hub : Save processed data
hub -> store : Send processed data batch
store -> store : Save processed data batch
store -> mapview : Send new rows
mapview -> spectator : Update paths and markers
@enduml

View File

@@ -0,0 +1,15 @@
@startuml
|Користувач|
start
:Натискає на іконку ями;
|Система|
:Запитує підтвердження видалення ями;
|Користувач|
:Підтверджує видалення ями;
|Система|
:Модифікує запис про яму;
note right #ff9999: Можлива виключна ситуація 1
:Видаляє яму;
|Користувач|
stop
@enduml

23
diagrams/use-case.puml Normal file
View File

@@ -0,0 +1,23 @@
@startuml
rectangle IoT-Systems {
usecase "Collect telemetry (accelerometer + GPS)" as uc1
usecase "Send telemetry" as uc2
usecase "Process telemetry" as uc3
usecase "Determine road condition (pothole / bump /\nnormal)" as uc4
usecase "View road defect marks" as uc5
usecase "View route on map" as uc6
}
rectangle "The user is the card operator" as uc10
rectangle "Sensor Agent\n(Device/STM32/Emulator)" as uc11
uc11 - uc1
uc11 - uc2
uc10 - uc5
uc10 - uc6
uc2 -.|> uc3 : <<include>>
uc3 -.|> uc4 : <<include>>
@enduml

View File

@@ -33,7 +33,7 @@ processed_agent_data = Table(
) )
# WebSocket subscriptions # WebSocket subscriptions
subscriptions: Set[WebSocket] = set() subscriptions: Dict[int, Set[WebSocket]] = {}
# FastAPI WebSocket endpoint # FastAPI WebSocket endpoint
@@ -41,7 +41,10 @@ subscriptions: Set[WebSocket] = set()
async def websocket_endpoint(websocket: WebSocket, user_id: int): async def websocket_endpoint(websocket: WebSocket, user_id: int):
await websocket.accept() await websocket.accept()
subscriptions.add(websocket) if user_id not in subscriptions:
subscriptions[user_id] = set()
subscriptions[user_id].add(websocket)
try: try:
# send already available data # send already available data
@@ -52,20 +55,20 @@ async def websocket_endpoint(websocket: WebSocket, user_id: int):
for i in jsonable_data: for i in jsonable_data:
i['timestamp'] = i['timestamp'].strftime("%Y-%m-%dT%H:%M:%SZ") i['timestamp'] = i['timestamp'].strftime("%Y-%m-%dT%H:%M:%SZ")
for i in jsonable_data: await websocket.send_json(json.dumps(jsonable_data))
await websocket.send_json(json.dumps([i]))
# receive forever # receive forever
while True: while True:
await websocket.receive_text() await websocket.receive_text()
except WebSocketDisconnect: except WebSocketDisconnect:
subscriptions.remove(websocket) subscriptions[user_id].remove(websocket)
# Function to send data to subscribed users # Function to send data to subscribed users
async def send_data_to_subscribers(data): async def send_data_to_subscribers(user_id: int, data):
for websocket in subscriptions: if user_id in subscriptions:
await websocket.send_json(json.dumps([data])) for websocket in subscriptions[user_id]:
await websocket.send_json(json.dumps(data))
# FastAPI CRUDL endpoints # FastAPI CRUDL endpoints
@@ -97,7 +100,7 @@ async def create_processed_agent_data(data: List[ProcessedAgentData], user_id: i
session.commit() session.commit()
for record in created_records: for record in created_records:
await send_data_to_subscribers(jsonable_encoder(record)) await send_data_to_subscribers(user_id, jsonable_encoder(record))
return created_records return created_records
except Exception as err: except Exception as err:
session.rollback() session.rollback()