easycoder 251104.2__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.

Files changed (61) hide show
  1. easycoder/__init__.py +6 -3
  2. easycoder/debugger/__init__.py +5 -0
  3. easycoder/debugger/ec_dbg_value_display copy.py +195 -0
  4. easycoder/debugger/ec_dbg_value_display.py +24 -0
  5. easycoder/debugger/ec_dbg_watch_list copy.py +219 -0
  6. easycoder/debugger/ec_dbg_watchlist.py +293 -0
  7. easycoder/debugger/ec_debug.py +1025 -0
  8. easycoder/ec_border.py +15 -11
  9. easycoder/ec_classes.py +493 -11
  10. easycoder/ec_compiler.py +81 -44
  11. easycoder/ec_condition.py +1 -1
  12. easycoder/ec_core.py +1043 -1089
  13. easycoder/ec_gclasses.py +236 -0
  14. easycoder/ec_graphics.py +1683 -0
  15. easycoder/ec_handler.py +18 -13
  16. easycoder/ec_keyboard.py +50 -50
  17. easycoder/ec_mqtt.py +249 -0
  18. easycoder/ec_program.py +308 -156
  19. easycoder/ec_psutil.py +48 -0
  20. easycoder/ec_timestamp.py +2 -1
  21. easycoder/ec_value.py +65 -47
  22. easycoder/icons/exit.png +0 -0
  23. easycoder/icons/run.png +0 -0
  24. easycoder/icons/step.png +0 -0
  25. easycoder/icons/stop.png +0 -0
  26. easycoder/pre/README.md +3 -0
  27. easycoder/pre/__init__.py +17 -0
  28. easycoder/pre/debugger/__init__.py +5 -0
  29. easycoder/pre/debugger/ec_dbg_value_display copy.py +195 -0
  30. easycoder/pre/debugger/ec_dbg_value_display.py +24 -0
  31. easycoder/pre/debugger/ec_dbg_watch_list copy.py +219 -0
  32. easycoder/pre/debugger/ec_dbg_watchlist.py +293 -0
  33. easycoder/pre/debugger/ec_debug.py +1014 -0
  34. easycoder/pre/ec_border.py +67 -0
  35. easycoder/pre/ec_classes.py +470 -0
  36. easycoder/pre/ec_compiler.py +291 -0
  37. easycoder/pre/ec_condition.py +27 -0
  38. easycoder/pre/ec_core.py +2772 -0
  39. easycoder/pre/ec_gclasses.py +230 -0
  40. easycoder/{ec_pyside.py → pre/ec_graphics.py} +631 -496
  41. easycoder/pre/ec_handler.py +79 -0
  42. easycoder/pre/ec_keyboard.py +439 -0
  43. easycoder/pre/ec_program.py +557 -0
  44. easycoder/pre/ec_psutil.py +48 -0
  45. easycoder/pre/ec_timestamp.py +11 -0
  46. easycoder/pre/ec_value.py +124 -0
  47. easycoder/pre/icons/close.png +0 -0
  48. easycoder/pre/icons/exit.png +0 -0
  49. easycoder/pre/icons/run.png +0 -0
  50. easycoder/pre/icons/step.png +0 -0
  51. easycoder/pre/icons/stop.png +0 -0
  52. easycoder/pre/icons/tick.png +0 -0
  53. {easycoder-251104.2.dist-info → easycoder-260108.1.dist-info}/METADATA +11 -1
  54. easycoder-260108.1.dist-info/RECORD +59 -0
  55. easycoder/ec_debug.py +0 -464
  56. easycoder-251104.2.dist-info/RECORD +0 -20
  57. /easycoder/{close.png → icons/close.png} +0 -0
  58. /easycoder/{tick.png → icons/tick.png} +0 -0
  59. {easycoder-251104.2.dist-info → easycoder-260108.1.dist-info}/WHEEL +0 -0
  60. {easycoder-251104.2.dist-info → easycoder-260108.1.dist-info}/entry_points.txt +0 -0
  61. {easycoder-251104.2.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.getSymbolRecord
35
- self.getRuntimeValue = self.program.getRuntimeValue
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
- def isJson(value):
70
- try:
71
- json.loads(value)
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