easycoder 251105.1__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.
- 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_classes.py +487 -11
- easycoder/ec_compiler.py +81 -44
- easycoder/ec_condition.py +1 -1
- easycoder/ec_core.py +1042 -1081
- easycoder/ec_gclasses.py +236 -0
- easycoder/ec_graphics.py +1683 -0
- easycoder/ec_handler.py +18 -14
- easycoder/ec_mqtt.py +248 -0
- easycoder/ec_program.py +297 -168
- easycoder/ec_psutil.py +48 -0
- easycoder/ec_value.py +65 -47
- 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/{ec_debug.py → pre/debugger/ec_debug.py} +418 -185
- 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} +583 -433
- 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-251105.1.dist-info → easycoder-260111.1.dist-info}/METADATA +11 -1
- easycoder-260111.1.dist-info/RECORD +59 -0
- easycoder-251105.1.dist-info/RECORD +0 -24
- {easycoder-251105.1.dist-info → easycoder-260111.1.dist-info}/WHEEL +0 -0
- {easycoder-251105.1.dist-info → easycoder-260111.1.dist-info}/entry_points.txt +0 -0
- {easycoder-251105.1.dist-info → easycoder-260111.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,12 +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
|
-
def
|
|
71
|
-
|
|
72
|
-
json.loads(value)
|
|
73
|
-
except ValueError as e:
|
|
74
|
-
return False
|
|
75
|
-
return True
|
|
77
|
+
# Get the value of an unknown item (domain-specific)
|
|
78
|
+
def getUnknownValue(self, 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
|