forked from kinkintama/Deneyap-Kart-Web-Agent
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBoard.py
150 lines (118 loc) · 5.47 KB
/
Board.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import subprocess
from utils import Data, createInoFile, executeCliPipe, executeCli
import config
import json
import logging
import websockets
class Board:
"""
Represents a deneyap kart that plugged to computer
boardName (str): Kartın adı (Deneyap Kart, Deneyap Mini vs.)
fqbn (str): fully qualified board name, arduino-cli'in kartı gördüğü isim
port (str): kartın bağlı olduğu port
ID (int): karta atanan rastgele id, (1000000 - 9999999) arası, web tarafında eşlemek için kullanılır
"""
def __init__(self, boardName: str, fqbn: str, port:str)->None:
"""
:param boardName: board name, currently Deneyap Kart, Deneyap Mini vs.
:type boardName: str
:param fqbn: fully qualified board name, board name that recognized by arduino-cli
dydk_mpv10 for Deneyap Kart
dym_mpv10 for Deneyap Mini
dydk1a_mpv10 for Deneyap Kart 1A
dyg_mpv10 for Deneyap Kart G
dym_mpv20 for Deneyap Mini v2
dydk1a_mpv20 for Deneyap Kart 1A v2
:type fqbn: str
:param port: COM port that board connected to like COM4
:type port: str
Deneyap mini is not recognized by Windows 10, so it is taken as Unknown.
"""
self.boardName = boardName
self.fqbn = fqbn
self.port = port
logging.info(f"Board with Name:{boardName}, FQBN:{fqbn}, Port:{port} is created")
def uploadCode(self, code:str, fqbn:str, uploadOptions:str) -> subprocess.Popen:
"""
Compiles and uploads code to board
:param code: code that sent by front-end
:type code: str
:param fqbn: fully qualified board name, board name that recognized by arduino-cli
dydk_mpv10 for Deneyap Kart
dym_mpv10 for Deneyap Mini
dydk1a_mpv10 for Deneyap Kart 1A
dyg_mpv10 for Deneyap Kart G
dym_mpv20 for Deneyap Mini v2
dydk1a_mpv20 for Deneyap Kart 1A v2
:type fqbn: str
:param uploadOptions: upload options for board. it is board spesific and sent by front-end as parsed.
:type uploadOptions: str
:return: returns subprocess.Popen object to write output to front-end
:rtype: subprocess.Popen
"""
logging.info(f"Uploading code to {self.boardName}:{self.port}")
createInoFile(code) #create Ino file so arduino-cli can read it to compile and upload to board
if uploadOptions == '':
pipe = executeCliPipe(f"compile --port {self.port} --upload --fqbn {fqbn} {config.TEMP_PATH}/tempCode")
else:
pipe = executeCliPipe(f"compile --port {self.port} --upload --fqbn {fqbn}:{uploadOptions} {config.TEMP_PATH}/tempCode")
return pipe
@staticmethod
def compileCode(code:str, fqbn:str, uploadOptions:str) -> subprocess.Popen:
"""
compiles code
:param code: code that sent by front-end
:type code: str
:param fqbn: fully qualified board name, board name that recognized by arduino-cli
dydk_mpv10 for Deneyap Kart
dym_mpv10 for Deneyap Mini
dydk1a_mpv10 for Deneyap Kart 1A
dyg_mpv10 for Deneyap Kart G
:type fqbn: str
:param uploadOptions: upload options for board. it is board spesific and sent by front-end as parsed.
:type uploadOptions: str
:return: returns subprocess.Popen object to write output to front-end
:rtype: subprocess.Popen
"""
logging.info(f"Compiling code for {fqbn}")
createInoFile(code) #create Ino file so arduino-cli can read it to compile
if uploadOptions == '':
pipe = executeCliPipe(f"compile --fqbn {fqbn} {config.TEMP_PATH}/tempCode")
else:
pipe = executeCliPipe(f"compile --fqbn {fqbn}:{uploadOptions} {config.TEMP_PATH}/tempCode")
return pipe
@staticmethod
def refreshBoards() -> None:
"""
Checks connected devices and append them to Data class for later use
"""
logging.info(f"Refresing Boards")
boardListString = executeCli("board list --format json")
boardsJson = json.loads(boardListString)
Data.boards = {}
for boardJson in boardsJson:
if "matching_boards" in boardJson:
boardName = boardJson["matching_boards"][0]["name"] # TODO investigate why index 0?
boardId = boardJson["matching_boards"][0]["fqbn"]
else:
boardName = "Unknown"
boardId = ""
boardPort = boardJson["port"]["address"]
logging.info(f"Found board with Name:{boardName}, FQBN:{boardId}, Port:{boardPort}")
board = Board(boardName, boardId, boardPort)
Data.boards[boardPort] = board
@staticmethod
async def sendBoardInfo(websocket: websockets.legacy.server.WebSocketServerProtocol) -> None:
"""
sends all board info to front-end via websocket
:param websocket: websocket connection to front-end
:type websocket: websockets.legacy.server.WebSocketServerProtocol
"""
body = {"command": "returnBoards", "boards": []}
for k, v in Data.boards.items():
body['boards'].append({"boardName": v.boardName, "port": v.port})
body = json.dumps(body)
logging.info(f"Sending {body}")
await websocket.send(body)
def __repr__(self) -> str:
return f"{self.boardName} on port: {self.port} with fqbn of {self.fqbn}"