easycoder 251215.2__py2.py3-none-any.whl → 260111.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.
Files changed (48) hide show
  1. easycoder/__init__.py +4 -3
  2. easycoder/debugger/ec_dbg_value_display copy.py +1 -1
  3. easycoder/debugger/ec_dbg_value_display.py +12 -11
  4. easycoder/debugger/ec_dbg_watchlist.py +146 -12
  5. easycoder/debugger/ec_debug.py +85 -8
  6. easycoder/ec_classes.py +228 -25
  7. easycoder/ec_compiler.py +29 -8
  8. easycoder/ec_core.py +364 -242
  9. easycoder/ec_gclasses.py +20 -9
  10. easycoder/ec_graphics.py +42 -26
  11. easycoder/ec_handler.py +4 -3
  12. easycoder/ec_mqtt.py +248 -0
  13. easycoder/ec_program.py +63 -28
  14. easycoder/ec_psutil.py +1 -1
  15. easycoder/ec_value.py +57 -36
  16. easycoder/pre/README.md +3 -0
  17. easycoder/pre/__init__.py +17 -0
  18. easycoder/pre/debugger/__init__.py +5 -0
  19. easycoder/pre/debugger/ec_dbg_value_display copy.py +195 -0
  20. easycoder/pre/debugger/ec_dbg_value_display.py +24 -0
  21. easycoder/pre/debugger/ec_dbg_watch_list copy.py +219 -0
  22. easycoder/pre/debugger/ec_dbg_watchlist.py +293 -0
  23. easycoder/pre/debugger/ec_debug.py +1014 -0
  24. easycoder/pre/ec_border.py +67 -0
  25. easycoder/pre/ec_classes.py +470 -0
  26. easycoder/pre/ec_compiler.py +291 -0
  27. easycoder/pre/ec_condition.py +27 -0
  28. easycoder/pre/ec_core.py +2772 -0
  29. easycoder/pre/ec_gclasses.py +230 -0
  30. easycoder/pre/ec_graphics.py +1682 -0
  31. easycoder/pre/ec_handler.py +79 -0
  32. easycoder/pre/ec_keyboard.py +439 -0
  33. easycoder/pre/ec_program.py +557 -0
  34. easycoder/pre/ec_psutil.py +48 -0
  35. easycoder/pre/ec_timestamp.py +11 -0
  36. easycoder/pre/ec_value.py +124 -0
  37. easycoder/pre/icons/close.png +0 -0
  38. easycoder/pre/icons/exit.png +0 -0
  39. easycoder/pre/icons/run.png +0 -0
  40. easycoder/pre/icons/step.png +0 -0
  41. easycoder/pre/icons/stop.png +0 -0
  42. easycoder/pre/icons/tick.png +0 -0
  43. {easycoder-251215.2.dist-info → easycoder-260111.1.dist-info}/METADATA +1 -1
  44. easycoder-260111.1.dist-info/RECORD +59 -0
  45. easycoder-251215.2.dist-info/RECORD +0 -31
  46. {easycoder-251215.2.dist-info → easycoder-260111.1.dist-info}/WHEEL +0 -0
  47. {easycoder-251215.2.dist-info → easycoder-260111.1.dist-info}/entry_points.txt +0 -0
  48. {easycoder-251215.2.dist-info → easycoder-260111.1.dist-info}/licenses/LICENSE +0 -0
easycoder/ec_gclasses.py CHANGED
@@ -112,6 +112,12 @@ class ECLineInput(ECTextWidget):
112
112
  def hasRuntimeValue(self):
113
113
  return True
114
114
 
115
+ # Set the text of the widget
116
+ def setText(self, text):
117
+ v = self.getValue()
118
+ if v is None: return
119
+ v.getContent().setText(str(text)) # type: ignore
120
+
115
121
  # Get the text of the widget
116
122
  def getText(self):
117
123
  return self.getValue().getContent().text() # type: ignore
@@ -146,21 +152,26 @@ class ECListBox(ECCoreWidget):
146
152
  def isClearable(self):
147
153
  return True
148
154
 
149
- # Get the count of items in the list box
150
- def getCount(self):
151
- v = self.getContent().count() # type: ignore
152
- return v
153
-
154
155
  # Get the selected item in the list box
155
156
  def getContent(self):
156
- widget = self.getValue().getContent() # type: ignore
157
- content = widget.selectedItems()[0].text() if widget.selectedItems() else None
157
+ widget = self.getValue() # type: ignore
158
+ content = widget.selectedItems()[0].text() if widget.selectedItems() else None # type: ignore
158
159
  return content
159
160
 
160
161
  # Get the text of the widget
161
162
  def getText(self):
162
- return self.getValue().getContent().text() # type: ignore
163
-
163
+ return self.getContent() # type: ignore
164
+
165
+ # Get the count of items in the list box
166
+ def getCount(self):
167
+ v = self.getContent().count() # type: ignore
168
+ return v
169
+
170
+ # Get the index of the selected item
171
+ def getIndex(self):
172
+ widget = self.getValue() # type: ignore
173
+ index = widget.currentRow() # type: ignore
174
+ return index
164
175
 
165
176
  ###############################################################################
166
177
  # A combo box variable
easycoder/ec_graphics.py CHANGED
@@ -198,7 +198,6 @@ class Graphics(Handler):
198
198
  # Set a graphic element as the value of a record
199
199
  def setGraphicElement(self, record, element):
200
200
  object = self.getObject(record)
201
- # object.setValue(ECValue(domain=self.getName(), type='object', content=element))
202
201
  object.setValue(element)
203
202
 
204
203
  def dialogTypes(self):
@@ -769,7 +768,8 @@ class Graphics(Handler):
769
768
 
770
769
  def r_createLineEdit(self, command, record):
771
770
  lineinput = ECLineEditWidget()
772
- lineinput.setText(self.textify(command['text']))
771
+ text = self.textify(command['text'])
772
+ lineinput.setText(str(text))
773
773
  fm = lineinput.fontMetrics()
774
774
  m = lineinput.textMargins()
775
775
  c = lineinput.contentsMargins()
@@ -1128,9 +1128,10 @@ class Graphics(Handler):
1128
1128
  return self.nextPC()
1129
1129
 
1130
1130
  # remove [the] [current/selected] [item] [from/in] {combobox}/{listbox}
1131
+ # Graphics-reserved syntax: optional article pattern is plugin-safe (core-only command)
1131
1132
  def k_remove(self, command):
1132
1133
  command['variant'] = None
1133
- self.skip('the')
1134
+ self.skipArticles() # Optional 'the', 'a', 'an' — syntactic sugar
1134
1135
  self.skip(['current', 'selected'])
1135
1136
  self.skip('item')
1136
1137
  self.skip(['from', 'in'])
@@ -1201,7 +1202,10 @@ class Graphics(Handler):
1201
1202
  # set {listbox} to {list}
1202
1203
  # set blocked true/false
1203
1204
  def k_set(self, command):
1204
- self.skip('the')
1205
+ # Graphics-reserved syntax: optional article pattern with 'of'/'to' prepositions
1206
+ # Forms like 'set the layout of Window to MainPanel' and 'set layout of Window to MainPanel' are equivalent
1207
+ # Plugin-safe: graphics is a core-only module
1208
+ self.skipArticles() # Optional 'the', 'a', 'an' — syntactic sugar for readability
1205
1209
  token = self.nextToken()
1206
1210
  command['what'] = token
1207
1211
  if token in ['width', 'height']:
@@ -1363,15 +1367,16 @@ class Graphics(Handler):
1363
1367
  keyword = record['keyword']
1364
1368
  setText = getattr(widget, "setText", None)
1365
1369
  if callable(setText):
1366
- widget.setText(text) # type: ignore
1370
+ widget.setText(str(text)) # type: ignore
1367
1371
  elif self.isObjectType(record, ECMultiline):
1368
- widget.setPlainText(text) # type: ignore
1372
+ widget.setPlainText(str(text)) # type: ignore
1369
1373
  if self.isObjectType(record, ECPushButton):
1370
- widget.setAccessibleName(text) # type: ignore
1374
+ widget.setAccessibleName(str(text)) # type: ignore
1371
1375
  elif what == 'state':
1372
1376
  record = self.getVariable(command['name'])
1373
1377
  if self.isObjectType(record, ECCheckBox):
1374
1378
  state = self.textify(command['value'])
1379
+ state = False if state == None else True
1375
1380
  self.getInnerObject(record).setChecked(state) # type: ignore
1376
1381
  elif what == 'alignment':
1377
1382
  widget = self.getVariable(command['name'])['widget']
@@ -1468,7 +1473,7 @@ class Graphics(Handler):
1468
1473
  if choice == QMessageBox.StandardButton.Ok: result = 'OK'
1469
1474
  else: result = ''
1470
1475
  else: result = 'Cancel'
1471
- v = ECValue(domain='graphics', type='str', content=result)
1476
+ v = ECValue(domain='graphics', type=str, content=result)
1472
1477
  self.putSymbolValue(target, v)
1473
1478
  elif 'window' in command:
1474
1479
  window = self.getInnerObject(self.getVariable(command['window'])['object'])
@@ -1525,6 +1530,7 @@ class Graphics(Handler):
1525
1530
  self.skip('of')
1526
1531
  elif token in ['current', 'selected']:
1527
1532
  token = self.nextToken()
1533
+ value.option = token
1528
1534
  if token == 'item': self.skip('in')
1529
1535
  elif token == 'index': self.skip('of')
1530
1536
  if self.nextIsSymbol():
@@ -1548,6 +1554,14 @@ class Graphics(Handler):
1548
1554
  ): # type: ignore
1549
1555
  value.setContent(ECValue(domain=self.getName(), type='object', content=record['name']))
1550
1556
  return value
1557
+ elif token == 'index':
1558
+ self.skip('of')
1559
+ value.element = self.getValue()
1560
+ if self.nextIsSymbol():
1561
+ record = self.getSymbolRecord()
1562
+ if self.isObjectType(record, (ECListBox, ECComboBox)): # type: ignore
1563
+ value.setContent(ECValue(domain=self.getName(), type='object', content=record['name']))
1564
+ return value
1551
1565
  return None
1552
1566
 
1553
1567
  #############################################################################
@@ -1564,33 +1578,33 @@ class Graphics(Handler):
1564
1578
  keyword = record['keyword']
1565
1579
  if self.isObjectType(record, ECPushButton):
1566
1580
  pushbutton = self.getInnerObject(record)
1567
- v = ECValue(domain=self.getName(), type='str', content=pushbutton.accessibleName())
1581
+ v = ECValue(domain=self.getName(), type=str, content=pushbutton.accessibleName())
1568
1582
  return v
1569
1583
  elif self.isObjectType(record, ECLineInput):
1570
1584
  lineinput = self.getInnerObject(record)
1571
- v = ECValue(domain=self.getName(), type='str', content=lineinput.displayText())
1585
+ v = ECValue(domain=self.getName(), type=str, content=lineinput.displayText())
1572
1586
  return v
1573
1587
  elif self.isObjectType(record, ECMultiline):
1574
1588
  multiline = self.getInnerObject(record)
1575
- v = ECValue(domain=self.getName(), type='str', content=multiline.toPlainText())
1589
+ v = ECValue(domain=self.getName(), type=str, content=multiline.toPlainText())
1576
1590
  return v
1577
1591
  elif self.isObjectType(record, ECComboBox):
1578
1592
  combobox = self.getInnerObject(record)
1579
- v = ECValue(domain=self.getName(), type='str', content=combobox.currentText())
1593
+ v = ECValue(domain=self.getName(), type=str, content=combobox.currentText())
1580
1594
  return v
1581
1595
  elif self.isObjectType(record, ECListBox):
1582
1596
  listbox = self.getInnerObject(record)
1583
1597
  content = listbox.currentItem().text() # type: ignore
1584
- v = ECValue(domain=self.getName(), type='str', content=content)
1598
+ v = ECValue(domain=self.getName(), type=str, content=content)
1585
1599
  return v
1586
1600
  elif self.isObjectType(record, ECCheckBox):
1587
1601
  checkbox =self.getInnerObject(record)
1588
1602
  content = checkbox.isChecked() # type: ignore
1589
- v = ECValue(domain=self.getName(), type='boolean', content=content)
1603
+ v = ECValue(domain=self.getName(), type=bool, content=content)
1590
1604
  return v
1591
1605
  elif self.isObjectType(record, ECDialog):
1592
1606
  content = record['result']
1593
- v = ECValue(domain=self.getName(), type='str', content=content)
1607
+ v = ECValue(domain=self.getName(), type=str, content=content)
1594
1608
  return v
1595
1609
  return None
1596
1610
 
@@ -1602,22 +1616,24 @@ class Graphics(Handler):
1602
1616
  if isinstance(object, (ECListBox, ECComboBox)):
1603
1617
  widget = self.getInnerObject(object)
1604
1618
  value = widget.count() # type: ignore
1605
- return ECValue(domain=self.getName(), type='int', content=value) # type: ignore
1619
+ return ECValue(domain=self.getName(), type=int, content=value) # type: ignore
1606
1620
  else: raise RuntimeError(self.program, f"Object is not a listbox or combobox")
1607
1621
 
1608
1622
  def v_current(self, v):
1609
1623
  content = v.getContent()
1610
1624
  if isinstance(content, ECValue) and content.getType() == 'object':
1611
1625
  record = self.getVariable(content.getContent())
1612
- keyword = record['keyword']
1613
1626
  object = self.getObject(record)
1614
- widget = self.getInnerObject(object)
1615
- if isinstance(widget, (QListWidget)):
1616
- content = widget.currentItem().text() # type: ignore
1617
- return ECValue(domain=self.getName(), type='int', content=content)
1618
- elif isinstance(widget, (QComboBox)):
1619
- content = str(widget.currentText()) # type: ignore
1620
- return ECValue(domain=self.getName(), type='int', content=content)
1627
+ option = v.option
1628
+ if isinstance(object, (ECListBox)):
1629
+ if option == 'item':
1630
+ content = object.getText() # type: ignore
1631
+ elif option == 'index':
1632
+ content = object.getIndex() # type: ignore
1633
+ return ECValue(domain=self.getName(), type=int, content=content)
1634
+ elif isinstance(object, (ECComboBox)):
1635
+ content = str(object.currentText()) # type: ignore
1636
+ return ECValue(domain=self.getName(), type=int, content=content)
1621
1637
  else: raise RuntimeError(self.program, f"Object is not a listbox or combobox")
1622
1638
 
1623
1639
  def v_element(self, v):
@@ -1628,7 +1644,7 @@ class Graphics(Handler):
1628
1644
  record = self.getVariable(v.getContent())
1629
1645
  object = self.getObject(record)
1630
1646
  value = object.isEmpty()
1631
- return ECValue(domain=self.getName(), type='boolean', content=value) # type: ignore
1647
+ return ECValue(domain=self.getName(), type=bool, content=value) # type: ignore
1632
1648
  return None
1633
1649
 
1634
1650
  def v_selected(self, v): return self.v_current(v)
@@ -1639,7 +1655,7 @@ class Graphics(Handler):
1639
1655
  record = self.getVariable(content.getContent())
1640
1656
  object = self.getObject(record)
1641
1657
  value = object.getText()
1642
- return ECValue(domain=self.getName(), type='int', content=value) # type: ignore
1658
+ return ECValue(domain=self.getName(), type=int, content=value) # type: ignore
1643
1659
 
1644
1660
  #############################################################################
1645
1661
  # Get the value of an unknown item (domain-specific)
easycoder/ec_handler.py CHANGED
@@ -1,5 +1,5 @@
1
1
  import sys, json
2
- from .ec_classes import FatalError, ECValue
2
+ from .ec_classes import normalize_type
3
3
 
4
4
  class Handler:
5
5
 
@@ -9,6 +9,7 @@ class Handler:
9
9
  self.getToken = compiler.getToken
10
10
  self.nextToken = compiler.nextToken
11
11
  self.skip = compiler.skip
12
+ self.skipArticles = compiler.skipArticles
12
13
  self.peek = compiler.peek
13
14
  self.getValue = compiler.getValue
14
15
  self.nextValue = compiler.nextValue
@@ -71,8 +72,8 @@ class Handler:
71
72
 
72
73
  # Get a condition handler
73
74
  def conditionHandler(self, name):
74
- return getattr(self, f'c_{name}')
75
+ return getattr(self, f'c_{normalize_type(name)}')
75
76
 
76
77
  # Get the value of an unknown item (domain-specific)
77
78
  def getUnknownValue(self, value):
78
- return None # Unable to get value
79
+ return value
easycoder/ec_mqtt.py ADDED
@@ -0,0 +1,248 @@
1
+ from easycoder import Handler, ECObject, ECValue, RuntimeError
2
+ import paho.mqtt.client as mqtt
3
+
4
+ #############################################################################
5
+ # MQTT client class
6
+ class MQTTClient():
7
+ def __init__(self):
8
+ super().__init__()
9
+
10
+ def create(self, program, clientID, broker, port, topics):
11
+ self.program = program
12
+ self.clientID = clientID
13
+ self.broker = broker
14
+ self.port = port
15
+ self.topics = topics
16
+ self.onMessagePC = None
17
+ self.client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=self.clientID) # type: ignore
18
+
19
+ # Setup callbacks
20
+ self.client.on_connect = self.on_connect
21
+ self.client.on_message = self.on_message
22
+
23
+ def on_connect(self, client, userdata, flags, reason_code, properties):
24
+ print(f"Client {self.clientID} connected")
25
+ for item in self.topics:
26
+ topic = self.program.getObject(self.program.getVariable(item))
27
+ self.client.subscribe(topic.getName(), qos=topic.getQOS())
28
+ print(f"Subscribed to topic: {topic.getName()} with QoS {topic.getQOS()}")
29
+
30
+ def on_message(self, client, userdata, msg):
31
+ # print(f"Message received on topic {msg.topic}: {msg.payload.decode()}")
32
+ if self.onMessagePC is not None:
33
+ self.message = msg
34
+ self.program.run(self.onMessagePC)
35
+ self.program.flushCB()
36
+
37
+ def getMessageTopic(self):
38
+ return self.message.topic
39
+
40
+ def getMessagePayload(self):
41
+ return self.message.payload.decode('utf-8')
42
+
43
+ def onMessage(self, pc):
44
+ self.onMessagePC = pc
45
+
46
+ def sendMessage(self, topic, message, qos):
47
+ self.client.publish(topic, message, qos=qos)
48
+
49
+ def run(self):
50
+ self.client.connect(self.broker, int(self.port), 60)
51
+ self.client.loop_start()
52
+
53
+ ###############################################################################
54
+ # An MQTT topic
55
+ class ECTopic(ECObject):
56
+ def __init__(self):
57
+ super().__init__()
58
+
59
+ def create(self, name, qos=1):
60
+ super().__init__()
61
+ self.name = name
62
+ self.qos = qos
63
+
64
+ def getName(self):
65
+ return self.name
66
+
67
+ def getQOS(self):
68
+ return self.qos
69
+
70
+ ###############################################################################
71
+ # The MQTT compiler and rutime handlers
72
+ class MQTT(Handler):
73
+
74
+ def __init__(self, compiler):
75
+ Handler.__init__(self, compiler)
76
+ self.spoke = None
77
+
78
+ def getName(self):
79
+ return 'mqtt'
80
+
81
+ #############################################################################
82
+ # Keyword handlers
83
+
84
+ # init {topic} name {name} qos {qos}
85
+ def k_init(self, command):
86
+ if self.nextIsSymbol():
87
+ record = self.getSymbolRecord()
88
+ self.checkObjectType(record, ECTopic)
89
+ command['topic'] = record['name']
90
+ self.skip('name')
91
+ command['name'] = self.nextValue()
92
+ self.skip('qos')
93
+ command['qos'] = self.nextValue()
94
+ self.add(command)
95
+ return True
96
+ return False
97
+
98
+ def r_init(self, command):
99
+ record = self.getVariable(command['topic'])
100
+ topic = ECTopic()
101
+ topic.create(self.textify(command['name']), qos=int(self.textify(command['qos'])))
102
+ record['object'] = topic
103
+ return self.nextPC()
104
+
105
+ # mqtt id {clientID} broker {broker} port {port} topics {topic} [and {topic} ...]
106
+ def k_mqtt(self, command):
107
+ while True:
108
+ token = self.peek()
109
+ if token == 'id':
110
+ self.nextToken()
111
+ command['clientID'] = self.nextValue()
112
+ elif token == 'broker':
113
+ self.nextToken()
114
+ command['broker'] = self.nextValue()
115
+ elif token == 'port':
116
+ self.nextToken()
117
+ command['port'] = self.nextValue()
118
+ elif token == 'topics':
119
+ self.nextToken()
120
+ topics = []
121
+ while self.nextIsSymbol():
122
+ record = self.getSymbolRecord()
123
+ self.checkObjectType(record, ECTopic())
124
+ topics.append(record['name'])
125
+ if self.peek() == 'and': self.nextToken()
126
+ else:break
127
+ command['topics'] = topics
128
+ else:
129
+ self.add(command)
130
+ return True
131
+ return False
132
+
133
+ def r_mqtt(self, command):
134
+ if hasattr(self.program, 'mqttClient'):
135
+ raise RuntimeError(self.program, 'MQQT client already defined')
136
+ clientID = self.textify(command['clientID'])
137
+ broker = self.textify(command['broker'])
138
+ port = self.textify(command['port'])
139
+ topics = command['topics']
140
+ client = MQTTClient()
141
+ client.create(self.program, clientID, broker, port, topics)
142
+ client.run()
143
+ self.program.mqttClient = client
144
+ return self.nextPC()
145
+
146
+ # on mqtt message {action}
147
+ def k_on(self, command):
148
+ token = self.peek()
149
+ if token == 'mqtt':
150
+ self.nextToken()
151
+ if self.nextIs('message'):
152
+ self.nextToken()
153
+ command['goto'] = 0
154
+ self.add(command)
155
+ cmd = {}
156
+ cmd['domain'] = 'core'
157
+ cmd['lino'] = command['lino']
158
+ cmd['keyword'] = 'gotoPC'
159
+ cmd['goto'] = 0
160
+ cmd['debug'] = False
161
+ self.add(cmd)
162
+ # Add the action and a 'stop'
163
+ self.compileOne()
164
+ cmd = {}
165
+ cmd['domain'] = 'core'
166
+ cmd['lino'] = command['lino']
167
+ cmd['keyword'] = 'stop'
168
+ cmd['debug'] = False
169
+ self.add(cmd)
170
+ # Fixup the link
171
+ command['goto'] = self.getCodeSize()
172
+ return True
173
+ return False
174
+
175
+ def r_on(self, command):
176
+ self.program.mqttClient.onMessage(self.nextPC()+1)
177
+ return command['goto']
178
+
179
+ # send {message} to {topic}
180
+ def k_send(self, command):
181
+ if self.nextIs('mqtt'):
182
+ command['message'] = self.nextValue()
183
+ self.skip('from')
184
+ if self.nextIsSymbol():
185
+ record = self.getSymbolRecord()
186
+ self.checkObjectType(record, MQTTClient)
187
+ command['from'] = record['name']
188
+ self.skip('to')
189
+ if self.nextIsSymbol():
190
+ record = self.getSymbolRecord()
191
+ self.checkObjectType(record, MQTTClient)
192
+ command['to'] = record['name']
193
+ self.add(command)
194
+ return True
195
+ return False
196
+
197
+ def r_send(self, command):
198
+ if not hasattr(self.program, 'mqttClient'):
199
+ raise RuntimeError(self.program, 'No MQTT client defined')
200
+ topic = self.getObject(self.getVariable(command['to']))
201
+ message = self.textify(command['message'])
202
+ self.program.mqttClient.sendMessage(topic.getName(), message, topic.getQOS())
203
+ return self.nextPC()
204
+
205
+ # Declare a topic variable
206
+ def k_topic(self, command):
207
+ self.compiler.addValueType()
208
+ return self.compileVariable(command, 'ECTopic')
209
+
210
+ def r_topic(self, command):
211
+ return self.nextPC()
212
+
213
+ #############################################################################
214
+ # Compile a value in this domain
215
+ def compileValue(self):
216
+ token = self.nextToken()
217
+ if token == 'mqtt':
218
+ value = ECValue(domain=self.getName())
219
+ token = self.nextToken()
220
+ if token in ['topic', 'message']:
221
+ value.setType(token)
222
+ return value
223
+ else:
224
+ return self.getValue()
225
+ return None
226
+
227
+ #############################################################################
228
+ # Modify a value or leave it unchanged.
229
+ def modifyValue(self, value):
230
+ return value
231
+
232
+ #############################################################################
233
+ # Value handlers
234
+
235
+ def v_message(self, v):
236
+ return self.program.mqttClient.getMessagePayload()
237
+
238
+ def v_topic(self, v):
239
+ return self.program.mqttClient.getMessageTopic()
240
+
241
+ #############################################################################
242
+ # Compile a condition
243
+ def compileCondition(self):
244
+ condition = {}
245
+ return condition
246
+
247
+ #############################################################################
248
+ # Condition handlers