easycoder 251104.1__py2.py3-none-any.whl → 260108.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of easycoder might be problematic. Click here for more details.
- easycoder/__init__.py +6 -3
- easycoder/debugger/__init__.py +5 -0
- easycoder/debugger/ec_dbg_value_display copy.py +195 -0
- easycoder/debugger/ec_dbg_value_display.py +24 -0
- easycoder/debugger/ec_dbg_watch_list copy.py +219 -0
- easycoder/debugger/ec_dbg_watchlist.py +293 -0
- easycoder/debugger/ec_debug.py +1025 -0
- easycoder/ec_border.py +15 -11
- easycoder/ec_classes.py +494 -7
- easycoder/ec_compiler.py +82 -44
- easycoder/ec_condition.py +1 -1
- easycoder/ec_core.py +1043 -1089
- easycoder/ec_gclasses.py +236 -0
- easycoder/ec_graphics.py +1683 -0
- easycoder/ec_handler.py +18 -13
- easycoder/ec_keyboard.py +50 -50
- easycoder/ec_mqtt.py +249 -0
- easycoder/ec_program.py +313 -152
- easycoder/ec_psutil.py +48 -0
- easycoder/ec_timestamp.py +2 -1
- easycoder/ec_value.py +65 -47
- easycoder/icons/exit.png +0 -0
- easycoder/icons/run.png +0 -0
- easycoder/icons/step.png +0 -0
- easycoder/icons/stop.png +0 -0
- easycoder/pre/README.md +3 -0
- easycoder/pre/__init__.py +17 -0
- easycoder/pre/debugger/__init__.py +5 -0
- easycoder/pre/debugger/ec_dbg_value_display copy.py +195 -0
- easycoder/pre/debugger/ec_dbg_value_display.py +24 -0
- easycoder/pre/debugger/ec_dbg_watch_list copy.py +219 -0
- easycoder/pre/debugger/ec_dbg_watchlist.py +293 -0
- easycoder/pre/debugger/ec_debug.py +1014 -0
- easycoder/pre/ec_border.py +67 -0
- easycoder/pre/ec_classes.py +470 -0
- easycoder/pre/ec_compiler.py +291 -0
- easycoder/pre/ec_condition.py +27 -0
- easycoder/pre/ec_core.py +2772 -0
- easycoder/pre/ec_gclasses.py +230 -0
- easycoder/{ec_pyside.py → pre/ec_graphics.py} +631 -494
- easycoder/pre/ec_handler.py +79 -0
- easycoder/pre/ec_keyboard.py +439 -0
- easycoder/pre/ec_program.py +557 -0
- easycoder/pre/ec_psutil.py +48 -0
- easycoder/pre/ec_timestamp.py +11 -0
- easycoder/pre/ec_value.py +124 -0
- easycoder/pre/icons/close.png +0 -0
- easycoder/pre/icons/exit.png +0 -0
- easycoder/pre/icons/run.png +0 -0
- easycoder/pre/icons/step.png +0 -0
- easycoder/pre/icons/stop.png +0 -0
- easycoder/pre/icons/tick.png +0 -0
- {easycoder-251104.1.dist-info → easycoder-260108.1.dist-info}/METADATA +11 -1
- easycoder-260108.1.dist-info/RECORD +59 -0
- easycoder-251104.1.dist-info/RECORD +0 -19
- /easycoder/{close.png → icons/close.png} +0 -0
- /easycoder/{tick.png → icons/tick.png} +0 -0
- {easycoder-251104.1.dist-info → easycoder-260108.1.dist-info}/WHEEL +0 -0
- {easycoder-251104.1.dist-info → easycoder-260108.1.dist-info}/entry_points.txt +0 -0
- {easycoder-251104.1.dist-info → easycoder-260108.1.dist-info}/licenses/LICENSE +0 -0
easycoder/ec_handler.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import json
|
|
1
|
+
import sys, json
|
|
2
|
+
from .ec_classes import normalize_type
|
|
2
3
|
|
|
3
4
|
class Handler:
|
|
4
5
|
|
|
@@ -8,6 +9,7 @@ class Handler:
|
|
|
8
9
|
self.getToken = compiler.getToken
|
|
9
10
|
self.nextToken = compiler.nextToken
|
|
10
11
|
self.skip = compiler.skip
|
|
12
|
+
self.skipArticles = compiler.skipArticles
|
|
11
13
|
self.peek = compiler.peek
|
|
12
14
|
self.getValue = compiler.getValue
|
|
13
15
|
self.nextValue = compiler.nextValue
|
|
@@ -18,8 +20,9 @@ class Handler:
|
|
|
18
20
|
self.nextIs = compiler.nextIs
|
|
19
21
|
self.isSymbol = compiler.isSymbol
|
|
20
22
|
self.nextIsSymbol = compiler.nextIsSymbol
|
|
21
|
-
self.getSymbolRecord = compiler.getSymbolRecord
|
|
22
23
|
self.compileVariable = compiler.compileVariable
|
|
24
|
+
self.compileSymbol = compiler.compileSymbol
|
|
25
|
+
self.getSymbolRecord = compiler.getSymbolRecord
|
|
23
26
|
self.rewindTo = compiler.rewindTo
|
|
24
27
|
self.warning = compiler.warning
|
|
25
28
|
self.getCodeSize = compiler.getCodeSize
|
|
@@ -30,9 +33,15 @@ class Handler:
|
|
|
30
33
|
self.compileConstant = compiler.compileConstant
|
|
31
34
|
|
|
32
35
|
self.code = self.program.code
|
|
36
|
+
self.checkObjectType = self.program.checkObjectType
|
|
37
|
+
self.isObjectType = self.program.isObjectType
|
|
38
|
+
self.isObjectType = self.program.isObjectType
|
|
39
|
+
self.getInnerObject = self.program.getInnerObject
|
|
40
|
+
self.getItemType = self.program.getItemType
|
|
33
41
|
self.evaluate = self.program.evaluate
|
|
34
|
-
self.getVariable = self.program.
|
|
35
|
-
self.
|
|
42
|
+
self.getVariable = self.program.getVariable
|
|
43
|
+
self.getObject = self.program.getObject
|
|
44
|
+
self.textify = self.program.textify
|
|
36
45
|
self.testCondition = self.program.condition.testCondition
|
|
37
46
|
self.symbols = self.program.symbols
|
|
38
47
|
self.stack = self.program.stack
|
|
@@ -40,10 +49,9 @@ class Handler:
|
|
|
40
49
|
self.getSymbolValue = self.program.getSymbolValue
|
|
41
50
|
self.putSymbolValue = self.program.putSymbolValue
|
|
42
51
|
self.run = self.program.run
|
|
52
|
+
self.callback = self.program.callback
|
|
43
53
|
|
|
44
54
|
self.nonNumericValueError = self.program.nonNumericValueError
|
|
45
|
-
self.variableDoesNotHoldAValueError = self.program.variableDoesNotHoldAValueError
|
|
46
|
-
self.noneValueError = self.program.noneValueError
|
|
47
55
|
|
|
48
56
|
def nextPC(self):
|
|
49
57
|
return self.program.pc + 1
|
|
@@ -64,11 +72,8 @@ class Handler:
|
|
|
64
72
|
|
|
65
73
|
# Get a condition handler
|
|
66
74
|
def conditionHandler(self, name):
|
|
67
|
-
return getattr(self, f'c_{name}')
|
|
75
|
+
return getattr(self, f'c_{normalize_type(name)}')
|
|
68
76
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
except ValueError as e:
|
|
73
|
-
return False
|
|
74
|
-
return True
|
|
77
|
+
# Get the value of an unknown item (domain-specific)
|
|
78
|
+
def getUnknownValue(self, value):
|
|
79
|
+
return None # Unable to get value
|
easycoder/ec_keyboard.py
CHANGED
|
@@ -29,7 +29,7 @@ class Keyboard(Handler):
|
|
|
29
29
|
self.dialog = dialog
|
|
30
30
|
|
|
31
31
|
# dialog.setWindowTitle('')
|
|
32
|
-
dialog.setWindowFlags(Qt.FramelessWindowHint)
|
|
32
|
+
dialog.setWindowFlags(Qt.WindowType.FramelessWindowHint)
|
|
33
33
|
dialog.setModal(True)
|
|
34
34
|
dialog.setFixedWidth(500)
|
|
35
35
|
dialog.setStyleSheet('background-color: white;border:1px solid black;')
|
|
@@ -38,7 +38,7 @@ class Keyboard(Handler):
|
|
|
38
38
|
shadow = QGraphicsDropShadowEffect(dialog)
|
|
39
39
|
shadow.setBlurRadius(40)
|
|
40
40
|
shadow.setOffset(0, 4)
|
|
41
|
-
shadow.setColor(Qt.black)
|
|
41
|
+
shadow.setColor(Qt.GlobalColor.black)
|
|
42
42
|
dialog.setGraphicsEffect(shadow)
|
|
43
43
|
|
|
44
44
|
# Add the keyboard
|
|
@@ -186,43 +186,43 @@ class VirtualKeyboard(QStackedWidget):
|
|
|
186
186
|
|
|
187
187
|
# Row 2: qwertyuiop
|
|
188
188
|
row2 = KeyboardRow([
|
|
189
|
-
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
189
|
+
QSpacerItem(20, 40, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum),
|
|
190
190
|
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in 'qwertyuiop'],
|
|
191
|
-
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
191
|
+
QSpacerItem(20, 40, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
192
192
|
])
|
|
193
193
|
rowList.append(row2)
|
|
194
194
|
|
|
195
195
|
# Row 3: asdfghjkl with horizontal stretches
|
|
196
196
|
row3 = KeyboardRow([
|
|
197
|
-
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
197
|
+
QSpacerItem(20, 40, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum),
|
|
198
198
|
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in 'asdfghjkl'],
|
|
199
|
-
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
199
|
+
QSpacerItem(20, 40, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
200
200
|
])
|
|
201
201
|
rowList.append(row3)
|
|
202
202
|
|
|
203
203
|
# Row 4: Shift, ZXC..., Backspace
|
|
204
204
|
row4 = KeyboardRow([
|
|
205
|
-
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
205
|
+
QSpacerItem(20, 40, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum),
|
|
206
206
|
KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickShift, None, 'img/up.png'),
|
|
207
|
-
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
207
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum),
|
|
208
208
|
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in 'zxcvbnm'],
|
|
209
|
-
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
209
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum),
|
|
210
210
|
KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickBack, None, 'img/back.png'),
|
|
211
|
-
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
211
|
+
QSpacerItem(20, 40, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
212
212
|
])
|
|
213
213
|
rowList.append(row4)
|
|
214
214
|
|
|
215
215
|
# Row 5: Numbers, Space, Enter
|
|
216
216
|
row5 = KeyboardRow([
|
|
217
|
-
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
217
|
+
QSpacerItem(20, 40, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum),
|
|
218
218
|
KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickNumbers, None, 'img/numbers.png'),
|
|
219
|
-
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
219
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum),
|
|
220
220
|
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, ","),
|
|
221
221
|
KeyboardButton(self.buttonHeight * 5, self.buttonHeight, self.onClickSpace, None, 'keyboard/space.png'),
|
|
222
222
|
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, "."),
|
|
223
|
-
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
223
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum),
|
|
224
224
|
KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickEnter, None, 'img/enter.png'),
|
|
225
|
-
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
225
|
+
QSpacerItem(20, 40, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
226
226
|
])
|
|
227
227
|
rowList.append(row5)
|
|
228
228
|
|
|
@@ -243,43 +243,43 @@ class VirtualKeyboard(QStackedWidget):
|
|
|
243
243
|
|
|
244
244
|
# Row 2: Uppercase QWERTY
|
|
245
245
|
row2 = KeyboardRow([
|
|
246
|
-
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
246
|
+
QSpacerItem(20, 40, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum),
|
|
247
247
|
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in 'QWERTYUIOP'],
|
|
248
|
-
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
248
|
+
QSpacerItem(20, 40, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
249
249
|
])
|
|
250
250
|
rowList.append(row2)
|
|
251
251
|
|
|
252
252
|
# Row 3: Uppercase ASDFGHJKL with horizontal stretches
|
|
253
253
|
row3 = KeyboardRow([
|
|
254
|
-
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
254
|
+
QSpacerItem(20, 40, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum),
|
|
255
255
|
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in 'ASDFGHJKL'],
|
|
256
|
-
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
256
|
+
QSpacerItem(20, 40, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
257
257
|
])
|
|
258
258
|
rowList.append(row3)
|
|
259
259
|
|
|
260
260
|
# Row 4: Shift, Uppercase ZXC..., Backspace
|
|
261
261
|
row4 = KeyboardRow([
|
|
262
|
-
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
262
|
+
QSpacerItem(20, 40, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum),
|
|
263
263
|
KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickShift, None, 'img/up.png'),
|
|
264
|
-
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
264
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum),
|
|
265
265
|
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in 'ZXCVBNM'],
|
|
266
|
-
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
266
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum),
|
|
267
267
|
KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickBack, None, 'img/back.png'),
|
|
268
|
-
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
268
|
+
QSpacerItem(20, 40, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
269
269
|
])
|
|
270
270
|
rowList.append(row4)
|
|
271
271
|
|
|
272
272
|
# Row 5: Numbers, Space, Enter
|
|
273
273
|
row5 = KeyboardRow([
|
|
274
|
-
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
274
|
+
QSpacerItem(20, 40, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum),
|
|
275
275
|
KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickNumbers, None, 'img/numbers.png'),
|
|
276
|
-
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
276
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum),
|
|
277
277
|
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, ","),
|
|
278
278
|
KeyboardButton(self.buttonHeight * 5, self.buttonHeight, self.onClickSpace, None, 'img/space.png'),
|
|
279
279
|
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, "."),
|
|
280
|
-
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
280
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum),
|
|
281
281
|
KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickEnter, None, 'img/enter.png'),
|
|
282
|
-
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
282
|
+
QSpacerItem(20, 40, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
283
283
|
])
|
|
284
284
|
rowList.append(row5)
|
|
285
285
|
|
|
@@ -296,43 +296,43 @@ class VirtualKeyboard(QStackedWidget):
|
|
|
296
296
|
|
|
297
297
|
# Row 1: Numbers
|
|
298
298
|
row1 = KeyboardRow([
|
|
299
|
-
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
299
|
+
QSpacerItem(0, 0, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum),
|
|
300
300
|
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '1234567890'],
|
|
301
|
-
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
301
|
+
QSpacerItem(0, 0, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
302
302
|
])
|
|
303
303
|
rowList.append(row1)
|
|
304
304
|
|
|
305
305
|
# Row 2: Symbols
|
|
306
306
|
row2 = KeyboardRow([
|
|
307
|
-
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
307
|
+
QSpacerItem(0, 0, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum),
|
|
308
308
|
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '@#£&_-()=%'],
|
|
309
|
-
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
309
|
+
QSpacerItem(0, 0, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
310
310
|
])
|
|
311
311
|
rowList.append(row2)
|
|
312
312
|
|
|
313
313
|
# Row 3: Symbols with horizontal stretches
|
|
314
314
|
row3 = KeyboardRow([
|
|
315
|
-
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
315
|
+
QSpacerItem(0, 0, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum),
|
|
316
316
|
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickSymbols, None, 'img/symbols.png'),
|
|
317
|
-
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
317
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum),
|
|
318
318
|
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '"*\'/:!?+'],
|
|
319
|
-
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
319
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum),
|
|
320
320
|
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickBack, None, 'img/back.png'),
|
|
321
|
-
QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
321
|
+
QSpacerItem(20, 40, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
322
322
|
])
|
|
323
323
|
rowList.append(row3)
|
|
324
324
|
|
|
325
325
|
# Row 4: Numbers, Space, Enter
|
|
326
326
|
row4 = KeyboardRow([
|
|
327
|
-
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
327
|
+
QSpacerItem(0, 0, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum),
|
|
328
328
|
KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickLetters, None, 'img/letters.png'),
|
|
329
|
-
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
329
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum),
|
|
330
330
|
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, ","),
|
|
331
331
|
KeyboardButton(self.buttonHeight * 5.2, self.buttonHeight, self.onClickSpace, None, 'keyboard/space.png'),
|
|
332
332
|
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, "."),
|
|
333
|
-
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
333
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum),
|
|
334
334
|
KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickEnter, None, 'img/enter.png'),
|
|
335
|
-
QSpacerItem(10, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
335
|
+
QSpacerItem(10, 40, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
336
336
|
])
|
|
337
337
|
rowList.append(row4)
|
|
338
338
|
|
|
@@ -349,43 +349,43 @@ class VirtualKeyboard(QStackedWidget):
|
|
|
349
349
|
|
|
350
350
|
# Row 1: Extended symbols
|
|
351
351
|
row1 = KeyboardRow([
|
|
352
|
-
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
352
|
+
QSpacerItem(0, 0, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum),
|
|
353
353
|
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '$€¥¢©®µ~¿¡'],
|
|
354
|
-
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
354
|
+
QSpacerItem(0, 0, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
355
355
|
])
|
|
356
356
|
rowList.append(row1)
|
|
357
357
|
|
|
358
358
|
# Row 2: Additional symbols
|
|
359
359
|
row2 = KeyboardRow([
|
|
360
|
-
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
360
|
+
QSpacerItem(0, 0, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum),
|
|
361
361
|
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '¼½¾[]{}<>^'],
|
|
362
|
-
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
362
|
+
QSpacerItem(0, 0, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
363
363
|
])
|
|
364
364
|
rowList.append(row2)
|
|
365
365
|
|
|
366
366
|
# Row 3: Symbols with horizontal stretches
|
|
367
367
|
row3 = KeyboardRow([
|
|
368
|
-
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
368
|
+
QSpacerItem(0, 0, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum),
|
|
369
369
|
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickNumbers, None, 'img/numbers.png'),
|
|
370
|
-
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
370
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum),
|
|
371
371
|
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '`;÷\\∣|¬±'],
|
|
372
|
-
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
372
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum),
|
|
373
373
|
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickBack, None, 'img/back.png'),
|
|
374
|
-
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
374
|
+
QSpacerItem(0, 0, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
375
375
|
])
|
|
376
376
|
rowList.append(row3)
|
|
377
377
|
|
|
378
378
|
# Row 4: Numbers, Space, Enter
|
|
379
379
|
row4 = KeyboardRow([
|
|
380
|
-
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
|
|
380
|
+
QSpacerItem(0, 0, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum),
|
|
381
381
|
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickLetters, None, 'img/letters.png'),
|
|
382
|
-
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
382
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum),
|
|
383
383
|
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, ","),
|
|
384
384
|
KeyboardButton(self.buttonHeight * 3, self.buttonHeight, self.onClickSpace, None, 'img/space.png'),
|
|
385
|
-
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
|
|
385
|
+
QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Minimum),
|
|
386
386
|
*[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '✕§¶°'],
|
|
387
387
|
KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickEnter, None, 'img/enter.png'),
|
|
388
|
-
QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
388
|
+
QSpacerItem(0, 0, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
389
389
|
])
|
|
390
390
|
rowList.append(row4)
|
|
391
391
|
|
easycoder/ec_mqtt.py
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
from easycoder import Handler, ECObject, ECValue, ECDictionary, FatalError, RuntimeError
|
|
2
|
+
import paho.mqtt.client as mqtt
|
|
3
|
+
import time
|
|
4
|
+
|
|
5
|
+
#############################################################################
|
|
6
|
+
# MQTT client class
|
|
7
|
+
class MQTTClient():
|
|
8
|
+
def __init__(self):
|
|
9
|
+
super().__init__()
|
|
10
|
+
|
|
11
|
+
def create(self, program, clientID, broker, port, topics):
|
|
12
|
+
self.program = program
|
|
13
|
+
self.clientID = clientID
|
|
14
|
+
self.broker = broker
|
|
15
|
+
self.port = port
|
|
16
|
+
self.topics = topics
|
|
17
|
+
self.onMessagePC = None
|
|
18
|
+
self.client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=self.clientID) # type: ignore
|
|
19
|
+
|
|
20
|
+
# Setup callbacks
|
|
21
|
+
self.client.on_connect = self.on_connect
|
|
22
|
+
self.client.on_message = self.on_message
|
|
23
|
+
|
|
24
|
+
def on_connect(self, client, userdata, flags, reason_code, properties):
|
|
25
|
+
print(f"Client {self.clientID} connected")
|
|
26
|
+
for item in self.topics:
|
|
27
|
+
topic = self.program.getObject(self.program.getVariable(item))
|
|
28
|
+
self.client.subscribe(topic.getName(), qos=topic.getQOS())
|
|
29
|
+
print(f"Subscribed to topic: {topic.getName()} with QoS {topic.getQOS()}")
|
|
30
|
+
|
|
31
|
+
def on_message(self, client, userdata, msg):
|
|
32
|
+
# print(f"Message received on topic {msg.topic}: {msg.payload.decode()}")
|
|
33
|
+
if self.onMessagePC is not None:
|
|
34
|
+
self.message = msg
|
|
35
|
+
self.program.run(self.onMessagePC)
|
|
36
|
+
self.program.flushCB()
|
|
37
|
+
|
|
38
|
+
def getMessageTopic(self):
|
|
39
|
+
return self.message.topic
|
|
40
|
+
|
|
41
|
+
def getMessagePayload(self):
|
|
42
|
+
return self.message.payload.decode('utf-8')
|
|
43
|
+
|
|
44
|
+
def onMessage(self, pc):
|
|
45
|
+
self.onMessagePC = pc
|
|
46
|
+
|
|
47
|
+
def sendMessage(self, topic, message, qos):
|
|
48
|
+
self.client.publish(topic, message, qos=qos)
|
|
49
|
+
|
|
50
|
+
def run(self):
|
|
51
|
+
self.client.connect(self.broker, int(self.port), 60)
|
|
52
|
+
self.client.loop_start()
|
|
53
|
+
|
|
54
|
+
###############################################################################
|
|
55
|
+
# An MQTT topic
|
|
56
|
+
class ECTopic(ECObject):
|
|
57
|
+
def __init__(self):
|
|
58
|
+
super().__init__()
|
|
59
|
+
|
|
60
|
+
def create(self, name, qos=1):
|
|
61
|
+
super().__init__()
|
|
62
|
+
self.name = name
|
|
63
|
+
self.qos = qos
|
|
64
|
+
|
|
65
|
+
def getName(self):
|
|
66
|
+
return self.name
|
|
67
|
+
|
|
68
|
+
def getQOS(self):
|
|
69
|
+
return self.qos
|
|
70
|
+
|
|
71
|
+
###############################################################################
|
|
72
|
+
# The MQTT compiler and rutime handlers
|
|
73
|
+
class MQTT(Handler):
|
|
74
|
+
|
|
75
|
+
def __init__(self, compiler):
|
|
76
|
+
Handler.__init__(self, compiler)
|
|
77
|
+
self.spoke = None
|
|
78
|
+
|
|
79
|
+
def getName(self):
|
|
80
|
+
return 'mqtt'
|
|
81
|
+
|
|
82
|
+
#############################################################################
|
|
83
|
+
# Keyword handlers
|
|
84
|
+
|
|
85
|
+
# init {topic} name {name} qos {qos}
|
|
86
|
+
def k_init(self, command):
|
|
87
|
+
if self.nextIsSymbol():
|
|
88
|
+
record = self.getSymbolRecord()
|
|
89
|
+
self.checkObjectType(record, ECTopic)
|
|
90
|
+
command['topic'] = record['name']
|
|
91
|
+
self.skip('name')
|
|
92
|
+
command['name'] = self.nextValue()
|
|
93
|
+
self.skip('qos')
|
|
94
|
+
command['qos'] = self.nextValue()
|
|
95
|
+
self.add(command)
|
|
96
|
+
return True
|
|
97
|
+
return False
|
|
98
|
+
|
|
99
|
+
def r_init(self, command):
|
|
100
|
+
record = self.getVariable(command['topic'])
|
|
101
|
+
topic = ECTopic()
|
|
102
|
+
topic.create(self.textify(command['name']), qos=int(self.textify(command['qos'])))
|
|
103
|
+
record['object'] = topic
|
|
104
|
+
return self.nextPC()
|
|
105
|
+
|
|
106
|
+
# mqtt id {clientID} broker {broker} port {port} topics {topic} [and {topic} ...]
|
|
107
|
+
def k_mqtt(self, command):
|
|
108
|
+
while True:
|
|
109
|
+
token = self.peek()
|
|
110
|
+
if token == 'id':
|
|
111
|
+
self.nextToken()
|
|
112
|
+
command['clientID'] = self.nextValue()
|
|
113
|
+
elif token == 'broker':
|
|
114
|
+
self.nextToken()
|
|
115
|
+
command['broker'] = self.nextValue()
|
|
116
|
+
elif token == 'port':
|
|
117
|
+
self.nextToken()
|
|
118
|
+
command['port'] = self.nextValue()
|
|
119
|
+
elif token == 'topics':
|
|
120
|
+
self.nextToken()
|
|
121
|
+
topics = []
|
|
122
|
+
while self.nextIsSymbol():
|
|
123
|
+
record = self.getSymbolRecord()
|
|
124
|
+
self.checkObjectType(record, ECTopic())
|
|
125
|
+
topics.append(record['name'])
|
|
126
|
+
if self.peek() == 'and': self.nextToken()
|
|
127
|
+
else:break
|
|
128
|
+
command['topics'] = topics
|
|
129
|
+
else:
|
|
130
|
+
self.add(command)
|
|
131
|
+
return True
|
|
132
|
+
return False
|
|
133
|
+
|
|
134
|
+
def r_mqtt(self, command):
|
|
135
|
+
if hasattr(self.program, 'mqttClient'):
|
|
136
|
+
raise RuntimeError(self.program, 'MQQT client already defined')
|
|
137
|
+
clientID = self.textify(command['clientID'])
|
|
138
|
+
broker = self.textify(command['broker'])
|
|
139
|
+
port = self.textify(command['port'])
|
|
140
|
+
topics = command['topics']
|
|
141
|
+
client = MQTTClient()
|
|
142
|
+
client.create(self.program, clientID, broker, port, topics)
|
|
143
|
+
client.run()
|
|
144
|
+
self.program.mqttClient = client
|
|
145
|
+
return self.nextPC()
|
|
146
|
+
|
|
147
|
+
# on mqtt message {action}
|
|
148
|
+
def k_on(self, command):
|
|
149
|
+
token = self.peek()
|
|
150
|
+
if token == 'mqtt':
|
|
151
|
+
self.nextToken()
|
|
152
|
+
if self.nextIs('message'):
|
|
153
|
+
self.nextToken()
|
|
154
|
+
command['goto'] = 0
|
|
155
|
+
self.add(command)
|
|
156
|
+
cmd = {}
|
|
157
|
+
cmd['domain'] = 'core'
|
|
158
|
+
cmd['lino'] = command['lino']
|
|
159
|
+
cmd['keyword'] = 'gotoPC'
|
|
160
|
+
cmd['goto'] = 0
|
|
161
|
+
cmd['debug'] = False
|
|
162
|
+
self.add(cmd)
|
|
163
|
+
# Add the action and a 'stop'
|
|
164
|
+
self.compileOne()
|
|
165
|
+
cmd = {}
|
|
166
|
+
cmd['domain'] = 'core'
|
|
167
|
+
cmd['lino'] = command['lino']
|
|
168
|
+
cmd['keyword'] = 'stop'
|
|
169
|
+
cmd['debug'] = False
|
|
170
|
+
self.add(cmd)
|
|
171
|
+
# Fixup the link
|
|
172
|
+
command['goto'] = self.getCodeSize()
|
|
173
|
+
return True
|
|
174
|
+
return False
|
|
175
|
+
|
|
176
|
+
def r_on(self, command):
|
|
177
|
+
self.program.mqttClient.onMessage(self.nextPC()+1)
|
|
178
|
+
return command['goto']
|
|
179
|
+
|
|
180
|
+
# send {message} to {topic}
|
|
181
|
+
def k_send(self, command):
|
|
182
|
+
if self.nextIs('mqtt'):
|
|
183
|
+
command['message'] = self.nextValue()
|
|
184
|
+
self.skip('from')
|
|
185
|
+
if self.nextIsSymbol():
|
|
186
|
+
record = self.getSymbolRecord()
|
|
187
|
+
self.checkObjectType(record, MQTTClient)
|
|
188
|
+
command['from'] = record['name']
|
|
189
|
+
self.skip('to')
|
|
190
|
+
if self.nextIsSymbol():
|
|
191
|
+
record = self.getSymbolRecord()
|
|
192
|
+
self.checkObjectType(record, MQTTClient)
|
|
193
|
+
command['to'] = record['name']
|
|
194
|
+
self.add(command)
|
|
195
|
+
return True
|
|
196
|
+
return False
|
|
197
|
+
|
|
198
|
+
def r_send(self, command):
|
|
199
|
+
if not hasattr(self.program, 'mqttClient'):
|
|
200
|
+
raise RuntimeError(self.program, 'No MQTT client defined')
|
|
201
|
+
topic = self.getObject(self.getVariable(command['to']))
|
|
202
|
+
message = self.textify(command['message'])
|
|
203
|
+
self.program.mqttClient.sendMessage(topic.getName(), message, topic.getQOS())
|
|
204
|
+
return self.nextPC()
|
|
205
|
+
|
|
206
|
+
# Declare a topic variable
|
|
207
|
+
def k_topic(self, command):
|
|
208
|
+
self.compiler.addValueType()
|
|
209
|
+
return self.compileVariable(command, 'ECTopic')
|
|
210
|
+
|
|
211
|
+
def r_topic(self, command):
|
|
212
|
+
return self.nextPC()
|
|
213
|
+
|
|
214
|
+
#############################################################################
|
|
215
|
+
# Compile a value in this domain
|
|
216
|
+
def compileValue(self):
|
|
217
|
+
token = self.nextToken()
|
|
218
|
+
if token == 'mqtt':
|
|
219
|
+
value = ECValue(domain=self.getName())
|
|
220
|
+
token = self.nextToken()
|
|
221
|
+
if token in ['topic', 'message']:
|
|
222
|
+
value.setType(token)
|
|
223
|
+
return value
|
|
224
|
+
else:
|
|
225
|
+
return self.getValue()
|
|
226
|
+
return None
|
|
227
|
+
|
|
228
|
+
#############################################################################
|
|
229
|
+
# Modify a value or leave it unchanged.
|
|
230
|
+
def modifyValue(self, value):
|
|
231
|
+
return value
|
|
232
|
+
|
|
233
|
+
#############################################################################
|
|
234
|
+
# Value handlers
|
|
235
|
+
|
|
236
|
+
def v_message(self, v):
|
|
237
|
+
return self.program.mqttClient.getMessagePayload()
|
|
238
|
+
|
|
239
|
+
def v_topic(self, v):
|
|
240
|
+
return self.program.mqttClient.getMessageTopic()
|
|
241
|
+
|
|
242
|
+
#############################################################################
|
|
243
|
+
# Compile a condition
|
|
244
|
+
def compileCondition(self):
|
|
245
|
+
condition = {}
|
|
246
|
+
return condition
|
|
247
|
+
|
|
248
|
+
#############################################################################
|
|
249
|
+
# Condition handlers
|