easycoder 250915.1__tar.gz → 250920.1__tar.gz
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-250915.1 → easycoder-250920.1}/PKG-INFO +1 -1
- {easycoder-250915.1 → easycoder-250920.1}/easycoder/__init__.py +1 -1
- {easycoder-250915.1 → easycoder-250920.1}/easycoder/ec_compiler.py +0 -1
- {easycoder-250915.1 → easycoder-250920.1}/easycoder/ec_core.py +46 -9
- easycoder-250915.1/RBRNow copy/README.md +0 -89
- easycoder-250915.1/RBRNow copy/ap.py +0 -24
- easycoder-250915.1/RBRNow copy/blescan.py +0 -31
- easycoder-250915.1/RBRNow copy/boot.py +0 -5
- easycoder-250915.1/RBRNow copy/config.py +0 -117
- easycoder-250915.1/RBRNow copy/dht22.py +0 -45
- easycoder-250915.1/RBRNow copy/espcomms.py +0 -76
- easycoder-250915.1/RBRNow copy/files.py +0 -46
- easycoder-250915.1/RBRNow copy/files.txt +0 -13
- easycoder-250915.1/RBRNow copy/files2.txt +0 -23
- easycoder-250915.1/RBRNow copy/handler.py +0 -124
- easycoder-250915.1/RBRNow copy/lib/aioble/__init__.py +0 -32
- easycoder-250915.1/RBRNow copy/lib/aioble/central.py +0 -307
- easycoder-250915.1/RBRNow copy/lib/aioble/client.py +0 -456
- easycoder-250915.1/RBRNow copy/lib/aioble/core.py +0 -78
- easycoder-250915.1/RBRNow copy/lib/aioble/device.py +0 -304
- easycoder-250915.1/RBRNow copy/lib/aioble/files.txt +0 -9
- easycoder-250915.1/RBRNow copy/lib/aioble/l2cap.py +0 -214
- easycoder-250915.1/RBRNow copy/lib/aioble/peripheral.py +0 -178
- easycoder-250915.1/RBRNow copy/lib/aioble/security.py +0 -178
- easycoder-250915.1/RBRNow copy/lib/aioble/server.py +0 -340
- easycoder-250915.1/RBRNow copy/main.py +0 -79
- easycoder-250915.1/RBRNow copy/pin.py +0 -29
- easycoder-250915.1/RBRNow copy/server.py +0 -80
- easycoder-250915.1/RBRNow copy/sht41.py +0 -27
- easycoder-250915.1/RBRNow copy/sta.py +0 -31
- {easycoder-250915.1 → easycoder-250920.1}/.gitignore +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/LICENSE +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/README.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/backdrop.jpg +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/README.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/README.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/conditions/boolean.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/conditions/empty.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/conditions/ends.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/conditions/even.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/conditions/exists.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/conditions/greater.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/conditions/hasProperty.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/conditions/includes.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/conditions/is.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/conditions/less.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/conditions/list.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/conditions/none.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/conditions/not.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/conditions/numeric.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/conditions/object.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/conditions/odd.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/conditions/starts.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/conditions/string.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/add.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/append.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/assert.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/begin.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/clear.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/close.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/create.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/debug.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/decrement.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/delete.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/divide.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/exit.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/file.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/fork.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/get.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/go.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/gosub.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/if.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/import.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/increment.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/index.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/init.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/input.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/load.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/lock.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/log.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/module.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/multiply.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/negate.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/on.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/open.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/pop.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/post.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/print.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/push.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/put.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/read.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/release.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/replace.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/return.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/run.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/save.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/script.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/send.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/set.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/shuffle.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/split.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/stack.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/stop.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/system.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/take.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/toggle.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/truncate.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/unlock.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/use.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/variable.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/wait.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/while.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/keywords/write.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/arg.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/args.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/cos.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/datime.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/decode.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/element.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/elements.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/empty.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/encode.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/error.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/files.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/float.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/from.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/hash.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/index.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/integer.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/json.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/keys.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/left.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/length.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/lowercase.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/memory.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/modification.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/modulo.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/newline.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/now.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/position.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/property.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/random.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/right.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/sin.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/stringify.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/tab.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/tan.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/timestamp.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/today.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/trim.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/type.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/uppercase.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/value.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/core/values/weekday.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/graphics/README.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/graphics/keywords/attach.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/graphics/keywords/close.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/graphics/keywords/create.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/graphics/keywords/ellipse.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/graphics/keywords/image.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/graphics/keywords/move.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/graphics/keywords/on.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/graphics/keywords/rectangle.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/graphics/keywords/render.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/graphics/keywords/run.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/graphics/keywords/set.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/graphics/keywords/text.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/graphics/values/attribute.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/doc/graphics/values/window.md +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/easycoder/close.png +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/easycoder/ec_border.py +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/easycoder/ec_classes.py +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/easycoder/ec_condition.py +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/easycoder/ec_handler.py +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/easycoder/ec_keyboard.py +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/easycoder/ec_program.py +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/easycoder/ec_pyside.py +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/easycoder/ec_timestamp.py +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/easycoder/ec_value.py +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/easycoder/tick.png +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/images/Semoigo Dawn.jpg +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/json/graphics-demo.json +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/plugins/ec_keyboard.py +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/plugins/ec_p100.py +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/plugins/ec_pyside6.py +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/plugins/points.py +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/plugins/sql.py +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/pyproject.toml +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/scripts/benchmark.ecs +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/scripts/config.ecg +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/scripts/ec_keyboard.py +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/scripts/fizzbuzz.ecs +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/scripts/hello.ecs +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/scripts/points.ecs +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/scripts/test.ecs +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/scripts/tests.ecs +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/test.py +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/testrc.py +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/testsql.py +0 -0
- {easycoder-250915.1 → easycoder-250920.1}/testui.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: easycoder
|
|
3
|
-
Version:
|
|
3
|
+
Version: 250920.1
|
|
4
4
|
Summary: Rapid scripting in English
|
|
5
5
|
Keywords: compiler,scripting,prototyping,programming,coding,python,low code,hypertalk,computer language,learn to code
|
|
6
6
|
Author-email: Graham Trott <gtanyware@gmail.com>
|
|
@@ -211,7 +211,6 @@ class Compiler:
|
|
|
211
211
|
token = self.tokens[self.index]
|
|
212
212
|
keyword = token.token
|
|
213
213
|
if self.debugCompile: print(self.script.lines[token.lino])
|
|
214
|
-
# print(f'{keyword} - {line}')
|
|
215
214
|
# if keyword != 'else':
|
|
216
215
|
if self.compileOne() == True:
|
|
217
216
|
if self.index == len(self.tokens) - 1:
|
|
@@ -277,7 +277,7 @@ class Core(Handler):
|
|
|
277
277
|
return self.incdec(command, '-')
|
|
278
278
|
|
|
279
279
|
# Delete a file or a property
|
|
280
|
-
# delete {filename}
|
|
280
|
+
# delete file {filename}
|
|
281
281
|
# delete property {value} of {variable}
|
|
282
282
|
# delete element {name} of {variable}
|
|
283
283
|
def k_delete(self, command):
|
|
@@ -306,8 +306,8 @@ class Core(Handler):
|
|
|
306
306
|
type = command['type']
|
|
307
307
|
if type == 'file':
|
|
308
308
|
filename = self.getRuntimeValue(command['filename'])
|
|
309
|
-
if
|
|
310
|
-
os.remove(filename)
|
|
309
|
+
if filename != None:
|
|
310
|
+
if os.path.isfile(filename): os.remove(filename)
|
|
311
311
|
elif type == 'property':
|
|
312
312
|
key = self.getRuntimeValue(command['key'])
|
|
313
313
|
symbolRecord = self.getVariable(command['var'])
|
|
@@ -1504,8 +1504,11 @@ class Core(Handler):
|
|
|
1504
1504
|
ssh = paramiko.SSHClient()
|
|
1505
1505
|
target['ssh'] = ssh
|
|
1506
1506
|
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
1507
|
-
|
|
1508
|
-
|
|
1507
|
+
try:
|
|
1508
|
+
ssh.connect(host, username=user, password=password, timeout=10)
|
|
1509
|
+
target['sftp'] = ssh.open_sftp()
|
|
1510
|
+
except:
|
|
1511
|
+
target['error'] = f'Unable to connect to {host} (timeout)'
|
|
1509
1512
|
return self.nextPC()
|
|
1510
1513
|
|
|
1511
1514
|
# Shuffle a list
|
|
@@ -2109,14 +2112,24 @@ class Core(Handler):
|
|
|
2109
2112
|
return value
|
|
2110
2113
|
|
|
2111
2114
|
if token == 'error':
|
|
2112
|
-
|
|
2115
|
+
token = self.peek()
|
|
2116
|
+
if token == 'code':
|
|
2113
2117
|
self.nextToken()
|
|
2114
2118
|
value['item'] = 'errorCode'
|
|
2115
2119
|
return value
|
|
2116
|
-
|
|
2120
|
+
elif token == 'reason':
|
|
2117
2121
|
self.nextToken()
|
|
2118
2122
|
value['item'] = 'errorReason'
|
|
2119
2123
|
return value
|
|
2124
|
+
elif token in ['in', 'of']:
|
|
2125
|
+
self.nextToken()
|
|
2126
|
+
if self.nextIsSymbol():
|
|
2127
|
+
record = self.getSymbolRecord()
|
|
2128
|
+
if record['keyword'] == 'ssh':
|
|
2129
|
+
value['item'] = 'sshError'
|
|
2130
|
+
value['name'] = record['name']
|
|
2131
|
+
return value
|
|
2132
|
+
return None
|
|
2120
2133
|
|
|
2121
2134
|
if token == 'type':
|
|
2122
2135
|
if self.nextIs('of'):
|
|
@@ -2280,6 +2293,10 @@ class Core(Handler):
|
|
|
2280
2293
|
elif v['item'] == 'errorReason':
|
|
2281
2294
|
value['type'] = 'text'
|
|
2282
2295
|
value['content'] = errorReason
|
|
2296
|
+
elif v['item'] == 'sshError':
|
|
2297
|
+
record = self.getVariable(v['name'])
|
|
2298
|
+
value['type'] = 'text'
|
|
2299
|
+
value['content'] = record['error'] if 'error' in record else ''
|
|
2283
2300
|
return value
|
|
2284
2301
|
|
|
2285
2302
|
def v_files(self, v):
|
|
@@ -2614,12 +2631,25 @@ class Core(Handler):
|
|
|
2614
2631
|
def compileCondition(self):
|
|
2615
2632
|
condition = Condition()
|
|
2616
2633
|
|
|
2617
|
-
|
|
2634
|
+
token = self.getToken()
|
|
2635
|
+
|
|
2636
|
+
if token == 'not':
|
|
2618
2637
|
condition.type = 'not'
|
|
2619
2638
|
condition.value = self.nextValue()
|
|
2620
2639
|
return condition
|
|
2621
2640
|
|
|
2622
|
-
|
|
2641
|
+
elif token == 'error':
|
|
2642
|
+
self.nextToken()
|
|
2643
|
+
self.skip('in')
|
|
2644
|
+
if self.nextIsSymbol():
|
|
2645
|
+
record = self.getSymbolRecord()
|
|
2646
|
+
if record['keyword'] == 'ssh':
|
|
2647
|
+
condition.type = 'sshError'
|
|
2648
|
+
condition.target = record['name']
|
|
2649
|
+
return condition
|
|
2650
|
+
return None
|
|
2651
|
+
|
|
2652
|
+
elif token == 'file':
|
|
2623
2653
|
path = self.nextValue()
|
|
2624
2654
|
condition.path = path
|
|
2625
2655
|
condition.type = 'exists'
|
|
@@ -2799,6 +2829,13 @@ class Core(Handler):
|
|
|
2799
2829
|
|
|
2800
2830
|
def c_odd(self, condition):
|
|
2801
2831
|
return self.getRuntimeValue(condition.value1) % 2 == 1
|
|
2832
|
+
|
|
2833
|
+
def c_sshError(self, condition):
|
|
2834
|
+
target = self.getVariable(condition.target)
|
|
2835
|
+
errormsg = target['error'] if 'error' in target else None
|
|
2836
|
+
condition.errormsg = errormsg
|
|
2837
|
+
test = errormsg != None
|
|
2838
|
+
return not test if condition.negate else test
|
|
2802
2839
|
|
|
2803
2840
|
def c_starts(self, condition):
|
|
2804
2841
|
value1 = self.getRuntimeValue(condition.value1)
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
# RBR-Now #
|
|
2
|
-
|
|
3
|
-
**RBR-Now** is a networked control system based on the ESP32 microcontroller, designed for ESP32-based devices such as a radiator TRV or a DHT22 thermometer, and uses ESP-Now to implement chained networking allowing any device to run its own subnetwork to overcome range and capacity issues.
|
|
4
|
-
|
|
5
|
-
All the software in RBR-Now is MicroPython (uPython) and every device in the RBR-Now network is equipped with the same set of files. The behaviour of each device is determined by a small JSON configuration file.
|
|
6
|
-
|
|
7
|
-
The system can be deployed simply by loading devices with the core file set and a suitable configuration file, but is best managed by the RBRConf program; a Python GUI application for Linux computers. (It cannot run on Windows because it relies on networking commands that are not available on that OS.) RBRConf allows any device on the network to be interrogated, controlled and have its firmware updated remotely without any need to remove it from service.
|
|
8
|
-
|
|
9
|
-
An RBR-Now network comprises a hub (master) device and a number of slaves. A control system using RBR-Now connects solely to the hub device and controls the slaves through it. This documentation will first describe the slave functionality as this is the simpler device..
|
|
10
|
-
|
|
11
|
-
## The RBR-Now Slave device
|
|
12
|
-
|
|
13
|
-
An ESP-Now slave unit only receives; it doesn't initiate messages as it has no information about where to send any. To send a message to one we have to know its MAC address. This can be found by setting up the device as a wifi hotspot and arrange for the SSID to include the MAC address. To make things simpler, the RBR-Now system automates this process as follows.
|
|
14
|
-
|
|
15
|
-
When the device starts it looks for its configuration file, but this will not initially exist. So it drops into slave mode and creates a hotspot whose SSID is based on its MAC address but with a specific RBR prefix. When the configuration program is told to scan for slave devices it looks for this prefix and offers a list of all devices that match. The user selects one (there usually is only one, as I'll explain shortly) and the program notes the relevant MAC address. The new device is added to the list in the Slaves panel as an untitled device. When the user clicks that item, all relevant details for the device can be added in a panel on the UI screen. These details comprise the name by which the device will be known (usually the room name) and pin numbers for the onboard LED, the relay and the thermometer (if either of these are present). With this information, a JSON structure is created and sent to the device as its config file, so that next time it starts up it can configure itself appropriately.
|
|
16
|
-
|
|
17
|
-
The hotspot is basically open (otherwise the device couldn't be connected) so this is an obvious vulnerability. To overcome this, the hotspot is disabled after 2 minutes. (It cannot be removed entirely because this would prevent ESP-Now from working, so it's given an SSID comprising a single dash and a randomly generated numeric password, making it virtually impossible to get into and rendering the MAC address inaccessible.) So by the time a second device is to be configured, existing ones are unlikely to appear in a search.
|
|
18
|
-
|
|
19
|
-
Apart from initial configuration, all comms with a slave is done using ESP-Now, which only requires the MAC address to be known. The device indicates which mode it's in by flashing its onboard LED on-off with a 1-second cycle for the initial 2 minutes, then a brief flash every 5 seconds after that.
|
|
20
|
-
|
|
21
|
-
The slave code waits for messages to arrive and acts on them. Messages will only arrive from the system controller, although in some cases they may be relayed via another slave device. Each message is acknowledged and any requested data is passed back. This includes such things as the relay state, the up time (seconds from startup) and thermometer readings.
|
|
22
|
-
|
|
23
|
-
The device also runs concurrent code that monitors BLE transmissions, looking for the signature of a Mijia thermometer. Every time one is seen, its advertising packet is read and the relevant data extracted. This will be returned as part of the response to the next message from the controller. Queuing is not implemented, so if several Mijias are detected at the same time, only one of them will be captured on this occasion.
|
|
24
|
-
|
|
25
|
-
Among the commands that can be sent are some that permit any file on the device to be updated. (This does not include MicroPython itself.) The configurator has the ability to update one or all the files on a device.
|
|
26
|
-
|
|
27
|
-
## The RBR-Now Master device
|
|
28
|
-
|
|
29
|
-
The Master (or Hub) device is the gateway between the system controller and the network of RBR-Now devices. It can itself be one of those devices, or it can be a separate module placed centrally where it can easily be seen by all the others, which are all Slave devices as described above. The Master has no knowledge of the other devices, nor of the system controller; it just responds to requests. Most of the functionality of the Slave is also shared by the Master.
|
|
30
|
-
|
|
31
|
-
The Master must be the first device set up by the configurator, which treats it specially. As with the slaves, the device initially has no configuration file, so as above it publishes a hotspot and waits for a connection. The configurator creates a JSON configuration file similar to that for a slave but additionally containing the SSID and password of the home network router and identifying the device as the master, then sends the file to the device and asks it to reset itself. When it restarts, the device will connect to the router and will get an IP address. The configurator waits for 10 seconds to allow this to complete, then sends another message to the hotspot requesting the IP address. From then on, all communication is done through this IP address. As with the slave, after 2 minutes the hotspot is disabled and the LED cycle changes, this time to a double flash every 5 seconds.
|
|
32
|
-
|
|
33
|
-
## System messaging
|
|
34
|
-
|
|
35
|
-
All messages from the system controller to an RBR-Now device are sent to the Master/Hub device at its IP address on the home network. Messages are prefixed by the MAC address of the target device, as recorded by the configurator when the device was added to the system.
|
|
36
|
-
|
|
37
|
-
When the Master device receives a message it checks to see who the message is addressed to. If it's the master device itself the message is handled and a reply sent. If it's any other address the message is forwarded to that device via the ESP-Now network,and the reply from that device is returned to the system controller.
|
|
38
|
-
|
|
39
|
-
In some cases a device is too far away from the hub to receive messages reliably. In such cases the device can piggy-back off another, closer device. Here, the MAC address given has a special prefix and identifies the path to the target device, going via as many intermediates as necessary. The path is part of the configuration for a device; in most cases it is empty.
|
|
40
|
-
|
|
41
|
-
The messages understood by devices are as follows:
|
|
42
|
-
|
|
43
|
-
### on
|
|
44
|
-
|
|
45
|
-
Turns on the device relay. It returns 'OK' then the up time of the device (in seconds) and the most recent Mijia reading it has received (if any).
|
|
46
|
-
|
|
47
|
-
### off
|
|
48
|
-
|
|
49
|
-
Turns off the device relay. The reply is the same as for **on**.
|
|
50
|
-
|
|
51
|
-
### relay
|
|
52
|
-
|
|
53
|
-
Returns the current state of the relay.
|
|
54
|
-
|
|
55
|
-
### temp
|
|
56
|
-
|
|
57
|
-
Returns the current temperature, if the device is a thermometer.
|
|
58
|
-
|
|
59
|
-
### reset
|
|
60
|
-
|
|
61
|
-
Causes the device to reset itself.
|
|
62
|
-
|
|
63
|
-
### ipaddr
|
|
64
|
-
|
|
65
|
-
Returns the IP address of the device (master only).
|
|
66
|
-
|
|
67
|
-
### pause
|
|
68
|
-
|
|
69
|
-
Requests the device to pause all operations that may interfere with actions such as updating files.
|
|
70
|
-
|
|
71
|
-
### resume
|
|
72
|
-
|
|
73
|
-
Requests the device to resume operations as normal.
|
|
74
|
-
|
|
75
|
-
### part
|
|
76
|
-
|
|
77
|
-
Signals that the attached data (up to 100 characters) is part of a file to be saved by the device. The file content is sent in hex format, 100 bytes at a time, each with a part number starting with zero, and the device saves each part as it arrives. Part numbers must be in the correct sequence or an error occurs.
|
|
78
|
-
|
|
79
|
-
### save
|
|
80
|
-
|
|
81
|
-
Saves the accumulated parts into the file whose name is given. The device saves the file then reads it back to check it matches what was received by the **part** requests.
|
|
82
|
-
|
|
83
|
-
### delete
|
|
84
|
-
|
|
85
|
-
Deletes the file whose full path is given.
|
|
86
|
-
|
|
87
|
-
## mkdir
|
|
88
|
-
|
|
89
|
-
Creates a directory with the name given.
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import network,binascii,asyncio,random
|
|
2
|
-
|
|
3
|
-
class AP():
|
|
4
|
-
|
|
5
|
-
def __init__(self,config):
|
|
6
|
-
self.config=config
|
|
7
|
-
config.setAP(self)
|
|
8
|
-
ap=network.WLAN(network.AP_IF)
|
|
9
|
-
ap.active(True)
|
|
10
|
-
self.ap=ap
|
|
11
|
-
mac=binascii.hexlify(self.ap.config('mac')).decode()
|
|
12
|
-
self.config.setMAC(mac)
|
|
13
|
-
self.ssid=f'RBR-Now-{mac}'
|
|
14
|
-
ap.config(essid=self.ssid,password='00000000')
|
|
15
|
-
ap.config(channel=config.getChannel())
|
|
16
|
-
ap.ifconfig(('192.168.9.1','255.255.255.0','192.168.9.1','8.8.8.8'))
|
|
17
|
-
print(mac,config.getName())
|
|
18
|
-
|
|
19
|
-
def stop(self):
|
|
20
|
-
password=str(random.randrange(100000,999999))
|
|
21
|
-
print(password)
|
|
22
|
-
self.ap.config(essid='-',password=password)
|
|
23
|
-
|
|
24
|
-
def getChannel(self): return self.ap.config('channel')
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
import aioble
|
|
3
|
-
from binascii import hexlify
|
|
4
|
-
|
|
5
|
-
class BLEScan():
|
|
6
|
-
|
|
7
|
-
def __init__(self):
|
|
8
|
-
self.values=''
|
|
9
|
-
|
|
10
|
-
async def scan(self):
|
|
11
|
-
print("Scanning for BLE devices...")
|
|
12
|
-
while True:
|
|
13
|
-
async with aioble.scan(duration_ms=20000) as scanner:
|
|
14
|
-
async for result in scanner:
|
|
15
|
-
addr = result.device.addr_hex()
|
|
16
|
-
if addr.find('a4:c1:38:') == 0:
|
|
17
|
-
rssi = result.rssi
|
|
18
|
-
data = hexlify(result.adv_data).decode()
|
|
19
|
-
if len(data) > 28:
|
|
20
|
-
temp = int(data[20:24], 16)
|
|
21
|
-
hum = int(data[24:26], 16)
|
|
22
|
-
batt = int(data[26:28], 16)
|
|
23
|
-
print(f'{addr[9:]} {rssi} {temp} {hum} {batt}')
|
|
24
|
-
self.values = f'{addr[9:]};{rssi};{temp};{hum};{batt}'
|
|
25
|
-
# else: print(f'{addr} - no')
|
|
26
|
-
await asyncio.sleep(0.1)
|
|
27
|
-
|
|
28
|
-
def getValues(self):
|
|
29
|
-
values=self.values
|
|
30
|
-
self.values=''
|
|
31
|
-
return values
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import json,asyncio,time
|
|
2
|
-
from files import readFile,writeFile,fileExists
|
|
3
|
-
from pin import PIN
|
|
4
|
-
from server import Server
|
|
5
|
-
from dht22 import DHT22
|
|
6
|
-
from blescan import BLEScan
|
|
7
|
-
|
|
8
|
-
class Config():
|
|
9
|
-
|
|
10
|
-
def __init__(self):
|
|
11
|
-
if fileExists('config.json'):
|
|
12
|
-
self.config=json.loads(readFile('config.json'))
|
|
13
|
-
else:
|
|
14
|
-
self.config={}
|
|
15
|
-
self.config['name']='(none)'
|
|
16
|
-
self.config['master']=False
|
|
17
|
-
self.config['channel']=1
|
|
18
|
-
self.config['path']=''
|
|
19
|
-
self.config['pins']={}
|
|
20
|
-
pin={}
|
|
21
|
-
pin['pin']=''
|
|
22
|
-
pin['invert']=False
|
|
23
|
-
self.config['pins']['led']=pin
|
|
24
|
-
pin={}
|
|
25
|
-
pin['pin']=''
|
|
26
|
-
pin['invert']=False
|
|
27
|
-
self.config['pins']['relay']=pin
|
|
28
|
-
pin={}
|
|
29
|
-
pin['pin']=''
|
|
30
|
-
self.config['pins']['dht22']=pin
|
|
31
|
-
writeFile('config.json',json.dumps(self.config))
|
|
32
|
-
pin,invert=self.getPinInfo('led')
|
|
33
|
-
self.led=PIN(self,pin,invert)
|
|
34
|
-
pin,invert=self.getPinInfo('relay')
|
|
35
|
-
self.relay=PIN(self,pin,invert)
|
|
36
|
-
pin,_=self.getPinInfo('dht22')
|
|
37
|
-
if pin=='': self.dht22=None
|
|
38
|
-
else:
|
|
39
|
-
self.dht22=DHT22(pin)
|
|
40
|
-
asyncio.create_task(self.dht22.measure())
|
|
41
|
-
print('path:',self.config['path'])
|
|
42
|
-
self.ipaddr=None
|
|
43
|
-
self.uptime=0
|
|
44
|
-
self.resetRequested=False
|
|
45
|
-
self.server=Server(self)
|
|
46
|
-
asyncio.create_task(self.runWatchdog())
|
|
47
|
-
self.bleScan=BLEScan()
|
|
48
|
-
|
|
49
|
-
async def respond(self,response,writer):
|
|
50
|
-
await self.server.respond(response,writer)
|
|
51
|
-
async def sendDefaultResponse(self,writer):
|
|
52
|
-
await self.server.sendDefaultResponse(writer)
|
|
53
|
-
async def handleClient(self,reader,writer):
|
|
54
|
-
await self.server.handleClient(reader,writer)
|
|
55
|
-
|
|
56
|
-
async def send(self,peer,espmsg): return await self.espComms.send(peer,espmsg)
|
|
57
|
-
|
|
58
|
-
def reset(self):
|
|
59
|
-
print('Reset requested')
|
|
60
|
-
self.resetRequested=True
|
|
61
|
-
|
|
62
|
-
def pause(self):
|
|
63
|
-
if self.dht22!=None: self.dht22.pause()
|
|
64
|
-
|
|
65
|
-
def resume(self):
|
|
66
|
-
if self.dht22!=None: self.dht22.resume()
|
|
67
|
-
|
|
68
|
-
def setAP(self,ap): self.ap=ap
|
|
69
|
-
def setSTA(self,sta): self.sta=sta
|
|
70
|
-
def setMAC(self,mac): self.mac=mac
|
|
71
|
-
def setChannel(self,channel):
|
|
72
|
-
self.config['channel']=channel
|
|
73
|
-
writeFile('config.json',json.dumps(self.config))
|
|
74
|
-
def setIPAddr(self,ipaddr): self.ipaddr=ipaddr
|
|
75
|
-
def setHandler(self,handler): self.handler=handler
|
|
76
|
-
def setESPComms(self,espComms): self.espComms=espComms
|
|
77
|
-
def addUptime(self,t): self.uptime+=t
|
|
78
|
-
|
|
79
|
-
def isMaster(self): return self.config['master']
|
|
80
|
-
def isESP8266(self): return False
|
|
81
|
-
def getDevice(self): return self.config['device']
|
|
82
|
-
def getName(self): return self.config['name']
|
|
83
|
-
def getSSID(self): return self.config['hostssid']
|
|
84
|
-
def getPassword(self): return self.config['hostpass']
|
|
85
|
-
def getMAC(self): return self.mac
|
|
86
|
-
def getAP(self): return self.ap
|
|
87
|
-
def getSTA(self): return self.sta
|
|
88
|
-
def stopAP(self): self.ap.stop()
|
|
89
|
-
def startServer(self): self.server.startup()
|
|
90
|
-
def getIPAddr(self): return self.ipaddr
|
|
91
|
-
def getChannel(self): return self.ap.getChannel()
|
|
92
|
-
def getHandler(self): return self.handler
|
|
93
|
-
def getESPComms(self): return self.espComms
|
|
94
|
-
def getBLEScan(self): return self.bleScan
|
|
95
|
-
def getRBRNow(self): return self.rbrNow
|
|
96
|
-
def getPinInfo(self,name):
|
|
97
|
-
pin=self.config['pins'][name]
|
|
98
|
-
print(name,pin)
|
|
99
|
-
if 'invert' in pin: invert=pin['invert']
|
|
100
|
-
else: invert=False
|
|
101
|
-
return pin['pin'],invert
|
|
102
|
-
def getLED(self): return self.led
|
|
103
|
-
def getRelay(self): return self.relay
|
|
104
|
-
def getUptime(self): return int(round(self.uptime))
|
|
105
|
-
def getTemperature(self): return self.dht22.getTemperature()
|
|
106
|
-
|
|
107
|
-
async def runWatchdog(self):
|
|
108
|
-
while True:
|
|
109
|
-
self.active=False
|
|
110
|
-
await asyncio.sleep(180)
|
|
111
|
-
if not self.active:
|
|
112
|
-
print('No activity - reset')
|
|
113
|
-
asyncio.get_event_loop().stop()
|
|
114
|
-
pass
|
|
115
|
-
|
|
116
|
-
def kickWatchdog(self):
|
|
117
|
-
self.active=True
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import asyncio,dht
|
|
2
|
-
from machine import Pin,reset
|
|
3
|
-
|
|
4
|
-
class DHT22():
|
|
5
|
-
|
|
6
|
-
def __init__(self,sensorpin,verbose=False):
|
|
7
|
-
if verbose:
|
|
8
|
-
print('Initialise sensor on pin',sensorpin)
|
|
9
|
-
if sensorpin is '': self.sensor=None
|
|
10
|
-
else: self.sensor=dht.DHT22(Pin(int(sensorpin)))
|
|
11
|
-
self.verbose=verbose
|
|
12
|
-
self.temp=0
|
|
13
|
-
self.errors=0
|
|
14
|
-
self.paused=False
|
|
15
|
-
|
|
16
|
-
async def measure(self):
|
|
17
|
-
if self.sensor==None: return
|
|
18
|
-
msg=None
|
|
19
|
-
print('Run the temperature sensor')
|
|
20
|
-
while True:
|
|
21
|
-
if not self.paused:
|
|
22
|
-
try:
|
|
23
|
-
self.sensor.measure()
|
|
24
|
-
temperature=self.sensor.temperature()
|
|
25
|
-
if temperature>50: temperature=0
|
|
26
|
-
self.temp=round(temperature*10)
|
|
27
|
-
if self.verbose:
|
|
28
|
-
print('Temperature:',temperature)
|
|
29
|
-
self.errors=0
|
|
30
|
-
except OSError as e:
|
|
31
|
-
if self.verbose:
|
|
32
|
-
msg=f'Failed to read sensor: {str(e)}'
|
|
33
|
-
print(msg)
|
|
34
|
-
self.errors+=1
|
|
35
|
-
if self.errors>50: reset()
|
|
36
|
-
await asyncio.sleep(5)
|
|
37
|
-
|
|
38
|
-
def pause(self):
|
|
39
|
-
self.paused=True
|
|
40
|
-
|
|
41
|
-
def resume(self):
|
|
42
|
-
self.paused=False
|
|
43
|
-
|
|
44
|
-
def getTemperature(self):
|
|
45
|
-
return self.temp
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
from binascii import hexlify,unhexlify
|
|
3
|
-
from espnow import ESPNow as E
|
|
4
|
-
|
|
5
|
-
class ESPComms():
|
|
6
|
-
|
|
7
|
-
def __init__(self,config):
|
|
8
|
-
self.config=config
|
|
9
|
-
config.setESPComms(self)
|
|
10
|
-
E().active(True)
|
|
11
|
-
self.peers=[]
|
|
12
|
-
print('ESP-Now initialised')
|
|
13
|
-
|
|
14
|
-
def checkPeer(self,peer):
|
|
15
|
-
if not peer in self.peers:
|
|
16
|
-
self.peers.append(peer)
|
|
17
|
-
E().add_peer(peer)
|
|
18
|
-
|
|
19
|
-
async def send(self,mac,espmsg):
|
|
20
|
-
peer=unhexlify(mac.encode())
|
|
21
|
-
# Flush any incoming messages
|
|
22
|
-
while E().any(): _,_ = E().irecv()
|
|
23
|
-
self.checkPeer(peer)
|
|
24
|
-
try:
|
|
25
|
-
# print(f'Send {espmsg[0:20]}... to {mac}')
|
|
26
|
-
result=E().send(peer,espmsg)
|
|
27
|
-
# print(f'Result: {result}')
|
|
28
|
-
if result:
|
|
29
|
-
counter=50
|
|
30
|
-
while counter>0:
|
|
31
|
-
if E().any():
|
|
32
|
-
mac,response = E().irecv()
|
|
33
|
-
if response:
|
|
34
|
-
# print(f"Received response: {response.decode()}")
|
|
35
|
-
result=response.decode()
|
|
36
|
-
break
|
|
37
|
-
await asyncio.sleep(.1)
|
|
38
|
-
counter-=1
|
|
39
|
-
if counter==0:
|
|
40
|
-
result='Response timeout'
|
|
41
|
-
else: result='Fail (no result)'
|
|
42
|
-
except Exception as e:
|
|
43
|
-
print(e)
|
|
44
|
-
result=f'Fail ({e})'
|
|
45
|
-
return result
|
|
46
|
-
|
|
47
|
-
async def receive(self):
|
|
48
|
-
print('Starting ESPNow receiver on channel',self.config.getChannel())
|
|
49
|
-
self.waiting=False
|
|
50
|
-
while True:
|
|
51
|
-
if E().any():
|
|
52
|
-
mac,msg=E().recv()
|
|
53
|
-
sender=hexlify(mac).decode()
|
|
54
|
-
msg=msg.decode()
|
|
55
|
-
# print(f'Message from {sender}: {msg[0:30]}...')
|
|
56
|
-
if msg[0]=='!':
|
|
57
|
-
# It's a message to be relayed
|
|
58
|
-
comma=msg.index(',')
|
|
59
|
-
slave=msg[1:comma]
|
|
60
|
-
msg=msg[comma+1:]
|
|
61
|
-
# print(f'Slave: {slave}, msg: {msg}')
|
|
62
|
-
response=await self.send(slave,msg)
|
|
63
|
-
else:
|
|
64
|
-
# It's a message for me
|
|
65
|
-
response=self.config.getHandler().handleMessage(msg)
|
|
66
|
-
response=f'{response} {self.getRSS(sender)}'
|
|
67
|
-
print(f'Response to {sender}: {response}')
|
|
68
|
-
self.checkPeer(mac)
|
|
69
|
-
E().send(mac,response)
|
|
70
|
-
await asyncio.sleep(.1)
|
|
71
|
-
self.config.kickWatchdog()
|
|
72
|
-
|
|
73
|
-
def getRSS(self,mac):
|
|
74
|
-
peer=unhexlify(mac.encode())
|
|
75
|
-
try: return E().peers_table[peer][0]
|
|
76
|
-
except: return 0
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
|
|
3
|
-
def fileExists(filename):
|
|
4
|
-
try:
|
|
5
|
-
os.stat(filename)
|
|
6
|
-
return True
|
|
7
|
-
except OSError:
|
|
8
|
-
return False
|
|
9
|
-
|
|
10
|
-
def readFile(name):
|
|
11
|
-
try:
|
|
12
|
-
f=open(name,'r')
|
|
13
|
-
value=f.read()
|
|
14
|
-
f.close()
|
|
15
|
-
except:
|
|
16
|
-
value=None
|
|
17
|
-
return value
|
|
18
|
-
|
|
19
|
-
def writeFile(name,text):
|
|
20
|
-
f=open(name,'w')
|
|
21
|
-
f.write(text)
|
|
22
|
-
f.close()
|
|
23
|
-
|
|
24
|
-
def appendFile(name,text):
|
|
25
|
-
f=open(name,'a')
|
|
26
|
-
f.write(text)
|
|
27
|
-
f.close()
|
|
28
|
-
|
|
29
|
-
def createDirectory(path):
|
|
30
|
-
try:
|
|
31
|
-
os.mkdir(path)
|
|
32
|
-
except OSError as e:
|
|
33
|
-
if e.args[0] != 17: return False
|
|
34
|
-
return True
|
|
35
|
-
|
|
36
|
-
def clearFile(name):
|
|
37
|
-
open(name,'w').close()
|
|
38
|
-
|
|
39
|
-
def deleteFile(file):
|
|
40
|
-
try:
|
|
41
|
-
os.remove(file)
|
|
42
|
-
return True
|
|
43
|
-
except: return False
|
|
44
|
-
|
|
45
|
-
def renameFile(oldName,newName):
|
|
46
|
-
os.rename(oldName,newName)
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
lib/
|
|
2
|
-
lib/aioble/
|
|
3
|
-
lib/aioble/central.py
|
|
4
|
-
lib/aioble/client.py
|
|
5
|
-
lib/aioble/core.py
|
|
6
|
-
lib/aioble/device.py
|
|
7
|
-
lib/aioble/__init__.py
|
|
8
|
-
lib/aioble/l2cap.py
|
|
9
|
-
lib/aioble/peripheral.py
|
|
10
|
-
lib/aioble/security.py
|
|
11
|
-
lib/aioble/server.py
|
|
12
|
-
ap.py
|
|
13
|
-
blescan.py
|
|
14
|
-
boot.py
|
|
15
|
-
config.py
|
|
16
|
-
dht22.py
|
|
17
|
-
espcomms.py
|
|
18
|
-
files.py
|
|
19
|
-
handler.py
|
|
20
|
-
main.py
|
|
21
|
-
pin.py
|
|
22
|
-
server.py
|
|
23
|
-
sta.py
|