Compare commits

...

2 Commits

Author SHA1 Message Date
呓喵酱 22779cd6c4
Update README.md 3 years ago
IoTcat 91699c5a5c classified 3 years ago
  1. 397
      README.md
  2. 6
      examples/bigiot.js
  3. 10
      examples/breath_led.js
  4. 6
      examples/bus_test.js
  5. 6
      examples/hource_race_led.js
  6. 6
      examples/http.js
  7. 10
      examples/operate.js
  8. 22
      examples/pwm_operate_adc.js
  9. 6
      examples/redis.js
  10. 10
      examples/tcp.js
  11. 12
      examples/webpage.js
  12. 2
      flash.sh
  13. 11
      init.lua
  14. BIN
      lib/esptool-ck/esptool-32
  15. BIN
      lib/esptool-ck/esptool-64
  16. BIN
      lib/esptool-ck/esptool-arm
  17. BIN
      lib/esptool-ck/esptool-osx
  18. 2
      run.sh
  19. 13
      src/cli/modules/winFlash.js
  20. 19008
      src/drivers/nodemcu/bin/nodemcu_float_master_20210207-0810.map
  21. BIN
      src/drivers/nodemcu/bin/nodemcu_float_master_20210214-0803.bin
  22. BIN
      src/drivers/nodemcu/bin/old.bin
  23. BIN
      src/drivers/nodemcu/bin/old2.bin
  24. BIN
      src/drivers/nodemcu/bin/old3.bin
  25. BIN
      src/drivers/nodemcu/bin/old4.bin
  26. BIN
      src/drivers/nodemcu/bin/test.bin
  27. 11
      src/drivers/nodemcu/lua/FUNC.json
  28. 0
      src/drivers/nodemcu/lua/__stopped
  29. 15
      src/drivers/nodemcu/lua/config.json
  30. 134
      src/drivers/nodemcu/lua/fifosock.lua
  31. 9
      src/drivers/nodemcu/lua/heartbeatFunc.json
  32. BIN
      src/drivers/nodemcu/lua/httpserver.lc
  33. 217
      src/drivers/nodemcu/lua/httpserver.lua
  34. BIN
      src/drivers/nodemcu/lua/init.lc
  35. 12
      src/drivers/nodemcu/lua/init.lua
  36. 271
      src/drivers/nodemcu/lua/init.old.lua
  37. 842
      src/drivers/nodemcu/lua/init_old.lua
  38. 314
      src/drivers/nodemcu/lua/init_old2.lua
  39. BIN
      src/drivers/nodemcu/lua/lfs.zip
  40. 120
      src/drivers/nodemcu/lua/old.lua
  41. BIN
      src/drivers/nodemcu/lua/wiot.lc
  42. 15
      ttt.js
  43. 2
      upload.sh

@ -5,12 +5,397 @@
![license](https://img.shields.io/npm/l/wiot)
![download](https://img.shields.io/npm/dt/wiot)
wIoT - A distributed IoT operating system basing on NodeJS
wIoT - A distributed IoT network operating system for NodeMCU
> Ongoing project, ELEC340, BENG FYP
> This project is supported by [Dr. Zhang, Junqing](https://junqing-zhang.github.io/), University of Liverpool.
## Dependencies
### Firmware
- [NodeMCU Firmware](https://nodemcu.readthedocs.io/)
- [NodeMCU - ADC Module](https://github.com/nodemcu/nodemcu-firmware/tree/release/app/modules/adc.c)
- [NodeMCU - ENCODER Module](https://github.com/nodemcu/nodemcu-firmware/tree/release/app/modules/encoder.c)
- [NodeMCU - FILE Module](https://github.com/nodemcu/nodemcu-firmware/tree/release/app/modules/file.c)
- [NodeMCU - GPIO Module](https://github.com/nodemcu/nodemcu-firmware/tree/release/app/modules/gpio.c)
- [NodeMCU - HTTP Module](https://github.com/nodemcu/nodemcu-firmware/tree/release/app/modules/http.c)
- [NodeMCU - NET Module](https://github.com/nodemcu/nodemcu-firmware/tree/release/app/modules/net.c)
- [NodeMCU - NODE Module](https://github.com/nodemcu/nodemcu-firmware/tree/release/app/modules/node.c)
- [NodeMCU - PWM Module](https://github.com/nodemcu/nodemcu-firmware/tree/release/app/modules/pwm.c)
- [NodeMCU - SJSON Module](https://github.com/nodemcu/nodemcu-firmware/tree/release/app/modules/sjson.c)
- [NodeMCU -TMR Module](https://github.com/nodemcu/nodemcu-firmware/tree/release/app/modules/tmr.c)
- [NodeMCU - WIFI Module](https://github.com/nodemcu/nodemcu-firmware/tree/release/app/modules/wifi.c)
- [NodeMCU - REDIS Module](https://github.com/nodemcu/nodemcu-firmware/tree/release/lua_modules/redis/redis.lua)
- [NodeMCU - LFS](https://nodemcu.readthedocs.io/en/release/lfs/)
### CLI
- [Node.JS](http://nodejs.org/): running env
- [ora](https://www.npmjs.com/package/ora): terminal spinner
- [fs](https://www.npmjs.com/package/fs): file system operation
- [colors](https://www.npmjs.com/package/colors): get color and style in node.js console
- [boxen](https://www.npmjs.com/package/boxen): Create boxes in the terminal
- [cli-table](https://www.npmjs.com/package/cli-table): render unicode-aided tables on the command line from node.js scripts
- [got](https://www.npmjs.com/package/got): Human-friendly and powerful HTTP request library for Node.js
- [timeago.js](https://www.npmjs.com/package/timeago.js): format datetime with *** time ago statement
- [inquirer](https://www.npmjs.com/package/inquirer): an easily embeddable and beautiful command line interface for Node.js
- [md5](https://www.npmjs.com/package/md5): a JavaScript function for hashing messages with MD5
- [child_process](https://nodejs.org/api/child_process.html): spawn subprocesses
- [path](https://nodejs.org/api/path.html): utilities for working with file and directory paths
- [nodemcu-tool](https://www.npmjs.com/package/nodemcu-tool): Upload/Download Lua files to ESP8266/ESP32 module with NodeMCU firmware
- [yargs](https://www.npmjs.com/package/yargs): parsing arguments and generating an elegant user interface
- [esptool-ck](https://github.com/igrr/esptool-ck): create firmware files for the ESP8266 chip and flash the firmware to the chip over serial port
### Director
- [docker](https://www.docker.com/): Empowering App Development for Developers
- [Node.JS](http://nodejs.org/): running env
- [pm2](https://www.npmjs.com/package/pm2): production process manager for Node.js applications with a built-in load balancer
- [express](https://www.npmjs.com/package/express): Fast, unopinionated, minimalist web framework for nodeJS
- [log4js](https://www.npmjs.com/package/log4js): logging utility
- [net](https://nodejs.org/api/net.html): an asynchronous network API for creating stream-based TCP or IPC servers and clients
### Documentation Website
- Github Pages
- [Docsify](https://docsify.js.org/#/): Document website
- [mermaid](https://www.npmjs.com/package/mermaid): Chart generation
- [docsify-themeable](https://www.npmjs.com/package/docsify-themeable): Docsify theme
- [docsify-copy-code](https://www.npmjs.com/package/docsify-copy-code): code copy plugin
- [docsify-tabs](https://www.npmjs.com/package/docsify-tabs): markdown tab support
- [prismjs](https://www.npmjs.com/package/prismjs): code highlight
### Webpage Plugin
- [docker](https://www.docker.com/): Empowering App Development for Developers
- [Node.JS](http://nodejs.org/): running env
- [pm2](https://www.npmjs.com/package/pm2): production process manager for Node.js applications with a built-in load balancer
- [express](https://www.npmjs.com/package/express): Fast, unopinionated, minimalist web framework for nodeJS
- [fs](https://www.npmjs.com/package/fs): file system operation
- [md5](https://www.npmjs.com/package/md5): a JavaScript function for hashing messages with MD5
## Source Code Structure
### wIoT-dev
Main source code including wiot CLI, director, compiler, and NodeMCU Image.
```
| .gitignore (git ignore)
| .gitmodules (git submodules)
| LICENSE (open-source License)
| package.json (dependencies record for npm)
| README.md (readme file)
| yarn.lock (for dependencies management tool yarn)
|
+---bin
| wiot (wiot CLI entrance)
|
+---examples
| bigiot.js (example for 天猫精灵)
| breath_led.js (example for breathing LED)
| bus_test.js (example for node cluster cooperation)
| hource_race_led.js (example for testing interboard communication)
| http.js (example for sending http request)
| operate.js (example for testing operate primitives)
| pwm_operate_adc.js (example for testing pwm and adc)
| redis.js (example for testing redis database client)
| tcp.js (example for lunching tcp and udp)
| webpage.js (example for generating a web page)
|
+---lib
| \---esptool-ck (for flashing ESP device)
| esptool-32
| esptool-64
| esptool-arm
| esptool-osx
| esptool.exe
|
\---src
+---cli (wiot CLI)
| | compile.js
| | config.js
| | help.js
| | init.js
| | ls.js
| | node.js
| | publish.js
| | remove.js
| | restart.js
| | status.js
| | version.js
| | wifi.js
| |
| \---modules
| compile.js (compile command)
| error.js (error handler)
| getConfig.js (Get configuration of current wiot project)
| nidMatch.js (match incomplete nid)
| reset.js
| terminal.js (Open terminal of NodeMCU)
| upload.js (Upload files to NodeMCU)
| winDevList.js (show connected NodeMCU via USB)
| winFlash.js (Flash NodeMCU)
|
+---compiler
| | index.js (compiler entrance)
| | wiot-core.js (compile-core)
| |
| +---modules
| | breathing.js
| |
| +---operators
| | if.js
| | strIndexOf.js
| | strSubStr.js
| |
| \---primitives
| adc.js
| bigiot.js
| gpio.js
| http.js
| mail.js
| memobird.js
| print.js
| pwm.js
| redis.js
| sjson_decode.js
| sjson_encode.js
| tcp.js
| udp.js
| webpage.js
|
+---director
| | .gitignore
| | Dockerfile (docker configure file)
| | LICENSE
| | package.json
| | pm2.json (pm2 configure file)
| | README.md
| | yarn.lock
| |
| \---src
| | .gitignore
| | index.js (director entrance)
| |
| \---modules
| api.js (http api for CLI)
| log.js (log functions)
| node.js (node management)
| nodetable.js (data flow management)
| ns.js (name service)
|
\---drivers
\---nodemcu
+---bin
| full.bin (full features NodeMCU binary firmware)
| min.bin (minimized NodeMCU binary firmware)
|
\---lua
| lfs.img (wiot LFS image)
|
\---lfs (lfs.img source code)
bigiot.lua (for 天猫精灵)
dummy_strings.lua (optimize LFS)
redis.lua (for redis)
wiot.lua (wiot core)
_init.lua (boot file)
```
### wIoT-page
Source code for documentation website.
```
| .gitignore
| .nojekyll
| CNAME
| index.html
| index.md
| package-lock.json
| package.json
| README.md
| sw.js
| yarn.lock
| _404.md
| _coverpage.md
| _navbar.md
| _sidebar.md
|
+---logo
| favicon.ico
| full.png
| full.psd
| full_small.png
| full_small.psd
| logo.png
| logo.psd
|
\---zh-cn
logbook.md
plan.md
README.md
sd-iot.md
_coverpage.md
_navbar.md
_sidebar.md
```
### wiot-webpage
Source code for webpage plugin.
```
| .gitignore
| Dockerfile
| footer.html
| framework.html
| head.html
| index.html
| index.js
| LICENSE
| package.json
| pm2.json (pm2 configuration)
| README.md
| yarn.lock
|
\---src
framework.html (generated page framework)
index.html (root page for generating key)
index.js (main script)
```
## Test Procedure
### Install CLI (Assume on Win 10)
1. Download and install Node.js from [here](https://nodejs.org/en/download/) and adding the binary path (typically `%USERPROFILE%\AppData\Roaming\npm`) into the PATH system env.
2. Run `$ npm i -g wiot` in the command line.
3. Use `$ wiot -v` to check version (typically `v0.3.x`) and use `$ wiot -h` to see the supported commands.
### Create a wIoT Project
1. Use `$ wiot init "myproject"` to create a new wiot project in current folder with the name "myproject".
2. Type `$ cd myproject` to go into the project folder.
3. Use `$ npm i wiot` to install dependencies for this project.
### Manage the Configuaton of Project
1. Use `$ wiot config` to see current configuration.
2. Use `$ wiot config -h` to see how to change the configuation, including project name, director URL, default entrance script.
3. Use `$ wiot wifi set --ssid=your-wifi-ssid --pwd=your-wifi-passowrd` to save a WiFi setting. Repeat this to save multiple WiFi settings. These WiFi settings will be used configure the NodeMCU to let them connect to a WiFi AP.
4. Use `$ wiot wifi ls` to see all saved wifi settings.
5. You may also use `$ wiot wifi remove -h` to see how to remove a wifi setting.
### Add NodeMCU to Project
1. Connect one NodeMCU-8266 development board to computer via USB.
2. Run `$ wiot node search` to list all connected NodeMCU-8266 development board.
3. Assume that the target NodeMCU-8266 is at port COM3, run `$ wiot node init COM3 -n "myfirstnode"` to initiate the NodeMCU-8266 board with a nickname "myfirstnode". Use `$ wiot node init -h` to see more parameters this command supports. More command for node operation can be found with `$ wiot node -h`.
4. Run `$ wiot ls` to list all nodes.
### Check Node Status
1. Run `$ wiot status` to display the status of all nodes. `$ wiot status [nid]` can be used to show the detailed status of appointed node with its node id (nid). The nid can be found with `$ wiot ls`. Please note that when input a nid, you may only input some part of nid (for example, input `ac` for nid `ac7dg`) and it will be automatically completed.
### Operate Node
1. You may use `$ wiot restart <nid>` to restart a node.
2. You may use `$ wiot remove <nid>` to remove a node.
### Create wIoT Application
1. Create a new file under the root of your wIoT project folder named `index.js`.
2. Open `index.js` and input the following code, which achieves a button-controlled LED. When pressing the FLASH button on the NodeMCU-8266 board, the on-board LED will be on. When release the FLASH button, the LED will be off.
```js
// Require wiot package
const wiot = require('wiot');
// Create a new node in corresponding with a NodeMCU
let node1 = new wiot.node.nodemcu('<input your full nid here>');
// Create a new virtal wire
let wire1 = new wiot.wire();
// Use the virtual wire to onnect the D3 and D4 gpio on board
// achieving when D3 is LOW/HIGH, set D4 to be LOW/HIGH
wiot.gpio(node1, wiot.INPUT, node1.D3, wire1);
wiot.gpio(node1, wiot.OUTPUT, node1.D4, wire1);
```
3. Run `$ wiot compile` to compile the code in `index.js`.
4. Run `$ wiot publish` to push the compiled application to the NodeMCUs.
5. Now you may test the application on your NodeMCU.
6. You may try more examples in the examples folder and even write your own application refer to [API documentation](https://wiot.js.org/).
> Attention: Grammer check is not available yet, the compiler can only identify some simple errors but can not locate them. Therefore please be careful when writing your application.
### Test Director Locally
By default, the CLI will use the director at `wiot-director.yimian.xyz`, which is running in a Docker container guarded by pm2 on a cloud server in Beijing. As a choice, the director may be deployed locally with the following procedures.
1. Go to `src/director/src/` and run `$ node index.js`.
2. Configure your firewall to allow the incomming and outgoing flow of TCP package on 3001 and 6789 port.
3. Go to your project folder and run `$ wiot config --director=http://127.0.0.1:3001/`.
4. Update all NodeMCUs with `$ wiot node update <port> <nid>` via USB. Please make sure the nid is correct by checking `$ wiot ls`.
5. Recompile and publish the application.
> Similarly, the director can be deployed with `$ docker run -d -v /src/data/log:<your local log path> --name wiot-director -p 3001:3001 -p 6789:6789 iotcat/wiot-director` or `$ docker run -d -v /src/data/log:<your local log path> --name wiot-director -p 3001:3001 -p 6789:6789 docker.yimian.xyz:4450/wiot-director` for backup. The director can also be deployed on a intranet server with this method to keep the data safe for companies.
### Check Log
The log is maintained by the director. You may modify `/src/director/src/modules/log.js` to determine which kinds of log you want to keep. By default, the log will only be output to the standard output. You may change this to output the log to files.
### Test CLI Locally
1. In the source code folder, run `$ npm i` to install dependencies.
2. Run `$ node bin/wiot [...parameters]` to use the CLI locally. This is the same as `$ wiot [...parameters]`.
## Q&A
### No wIoT project selected
![No wIoT project selected](https://api.yimian.xyz/img/?path=imgbed/img_99e2e71_524x157_8_null_normal.jpeg)
Solution: Please make sure you are in a wIoT project folder.
### no such file or directory
Solution: Please make sure your node.js is installed properly, especially the environment variable `PATH`.
### Cannot found nid "xxxxx"! Please check your code!
Solution: Please make sure all nid in your index.js is in the list of `$ wiot ls`.
### Error occors in index.js
Solution: Please check your application in `index.js`, especially the order of the parameters of primitives, modules, and operators. Besides, JavaScript garmmer error may also result in this error.
---------------------------------------
# wIoT-old
Old version wIoT can be found [here](https://github.com/iotcat/wIoT-old).

@ -16,10 +16,10 @@ let w = new wiot.wire(0),
let node = nodes[0];
wiot.gpio(wiot.OUTPUT, node.D4, w, node);
wiot.gpio(node, wiot.OUTPUT, node.D4, w);
wiot.buffer(w, w2, node);
wiot.buffer(node, w, w2);
wiot.bigiot(node, 21249, 'ee37b3a2a', w3);
wiot.operate(`${wiot.if(`$1=='play'`, 0, wiot.if(`$1=='stop'`, 1, `$0`))}`, node, w2, w3);
wiot.operate(node, `${wiot.if(`$1=='play'`, 0, wiot.if(`$1=='stop'`, 1, `$0`))}`, w2, w3);

@ -16,11 +16,11 @@ let w = new wiot.wire(0),
let node = nodes[0];
let node1 = nodes[1];
wiot.gpio(wiot.INPUT, node1.D3, w3, node1);
wiot.operate(wiot.if(`$1==1`, `math.abs($0%2047-1023)`, `1023`), node, w2, w, w3);
wiot.operate('($0+20)%2048', node, w, w1);
wiot.buffer(w1, w, node, .01, true);
wiot.gpio(node1, wiot.INPUT, node1.D3, w3);
wiot.operate(node, wiot.if(`$1==1`, `math.abs($0%2047-1023)`, `1023`), w2, w, w3);
wiot.operate(node, '($0+20)%2048', w, w1);
wiot.buffer(node, w1, w, .01, true);
wiot.pwm(node.D4, w2, new wiot.wire(500), node);
wiot.pwm(node, node.D4, w2, new wiot.wire(500));
//wiot.print(node, w)

@ -18,14 +18,14 @@ nodes.forEach((node, index) => {
//}else{//if is not the first node (index!=0), do
//create another virtual wire
let w = new wiot.wire();
wiot.buffer(w_all/*output wire*/, w/*input wire*/, node);
wiot.gpio(wiot.INPUT, node.D3, w/*output wire*/, node);
wiot.buffer(node, w_all/*output wire*/, w/*input wire*/);
wiot.gpio(node, wiot.INPUT, node.D3, w/*output wire*/);
//implement a buffer module so only when signal in wire has changed and held
//for 0.2*index seconds, the w_delay will be updated with the value in the w
//create a gpio output module on D4 pin, controlled by the w_delayed virtual wire
//D4 is connected to an on-board LED on NodeMCU
wiot.gpio(wiot.OUTPUT, node.D4, w_all, node);
wiot.gpio(node, wiot.OUTPUT, node.D4, w_all);
//}
});

@ -14,16 +14,16 @@ nodes.forEach((node, index) => {
if(!index){//if is the first node (index=0, nid='7534c'), do
//create a gpio input listener on D3 pin and connect to the virtual wire w
//D3 pin is connected to an on-board button on NodeMCU
wiot.gpio(wiot.INPUT, node.D3, w/*output wire*/, node);
wiot.gpio(node, wiot.INPUT, node.D3, w/*output wire*/);
}else{//if is not the first node (index!=0), do
//create another virtual wire
let w_delayed = new wiot.wire();
//implement a buffer module so only when signal in wire has changed and held
//for 0.2*index seconds, the w_delay will be updated with the value in the w
wiot.buffer(w_delayed/*output wire*/, w/*input wire*/, nodes[0], .2*index/*delay*/);
wiot.buffer(nodes[0], w_delayed/*output wire*/, w/*input wire*/, .2*index/*delay*/);
//create a gpio output module on D4 pin, controlled by the w_delayed virtual wire
//D4 is connected to an on-board LED on NodeMCU
wiot.gpio(wiot.OUTPUT, node.D4, w_delayed, node);
wiot.gpio(node, wiot.OUTPUT, node.D4, w_delayed);
}
});

@ -16,8 +16,8 @@ let w = new wiot.wire(0),
let node = nodes[0];
let node1 = nodes[1];
wiot.gpio(wiot.INPUT, node.D3, w1, node);
wiot.gpio(node, wiot.INPUT, node.D3, w1);
//wiot.gpio(wiot.INPUT, node1.D3, w2, node1);
//wiot.print(node, w1, w1);
wiot.operate(`'http://192.168.3.100:5001/?value='..$0`, node, w3, w1);
wiot.http(w, w2, w3, node)
wiot.operate(node, `'http://192.168.3.100:5001/?value='..$0`, w3, w1);
wiot.http(node, w, w2, w3)

@ -14,16 +14,16 @@ let w = new wiot.wire(),
let node = nodes[0];
let node1 = nodes[1];
wiot.gpio(wiot.INPUT, node.D3, w1, node);
wiot.gpio(wiot.INPUT, node1.D3, w2, node1);
wiot.gpio(node, wiot.INPUT, node.D3, w1);
wiot.gpio(node1, wiot.INPUT, node1.D3, w2);
//or ($0+$1)%2+math.floor(($0+$1)/2)
//and math.floor(($0+$1)/2)
//xor ($0+$1)%2
//not ($0+1)%2
wiot.operate('(($0+$1)%2+1)%2', node, w, w1, w2);
wiot.operate(node, '(($0+$1)%2+1)%2', w, w1, w2);
wiot.gpio(wiot.OUTPUT, node.D4, w, node);
wiot.gpio(node, wiot.OUTPUT, node.D4, w);
//wiot.pwm(nodes[0].D4, new wiot.wire(800), new wiot.wire(500), nodes[0]);
//wiot.pwm(nodes[0], nodes[0].D4, new wiot.wire(800), new wiot.wire(500));

@ -14,24 +14,24 @@ let w = new wiot.wire(0),
let node = nodes[0];
let node1 = nodes[1];
/* wiot.gpio(wiot.INPUT, node.D3, w1, node);
wiot.gpio(wiot.INPUT, node1.D3, w2, node1);
/* wiot.gpio(node, wiot.INPUT, node.D3, w1);
wiot.gpio(node1, wiot.INPUT, node1.D3, w2);
//or ($0+$1)%2+math.floor(($0+$1)/2)
//and math.floor(($0+$1)/2)
//xor ($0+$1)%2
//not ($0+1)%2
wiot.operate('(($0+$1)%2+1)%2', node, w, w1, w2);
wiot.operate(node, '(($0+$1)%2+1)%2', w, w1, w2);
wiot.gpio(wiot.OUTPUT, node.D4, w, node);
wiot.gpio(node, wiot.OUTPUT, node.D4, w);
*/
//wiot.gpio(wiot.INPUT, node1.D3, w2, node1);
wiot.adc(w1, node);
//wiot.gpio(wiot.OUTPUT, node.D4, w, node);
//wiot.operate('math.floor($0/600)', node, w, w1);
wiot.operate('($0/2)+300', node, w, w1);
//wiot.operate(wiot.if(wiot.if(`$0<400`, false, true), 700, 0), node, w, w1);
//wiot.gpio(node1, wiot.INPUT, node1.D3, w2);
wiot.adc(node, w1);
//wiot.gpio(node, wiot.OUTPUT, node.D4, w);
//wiot.operate(node, 'math.floor($0/600)', w, w1);
wiot.operate(node, '($0/2)+300', w, w1);
//wiot.operate(node,wiot.if(wiot.if(`$0<400`, false, true), 700, 0), w, w1);
wiot.pwm(nodes[0].D4, w, new wiot.wire(500), nodes[0]);
wiot.pwm(nodes[0], nodes[0].D4, w, new wiot.wire(500));

@ -16,10 +16,10 @@ let w = new wiot.wire(0),
let node = nodes[0];
let node1 = nodes[1];
wiot.gpio(wiot.INPUT, node.D3, w1, node);
//wiot.gpio(wiot.INPUT, node1.D3, w2, node1);
wiot.gpio(node, wiot.INPUT, node.D3, w1);
//wiot.gpio(node1, wiot.INPUT, node1.D3, w2);
//wiot.print(node, w1, w1);
wiot.redis(w2, w1, node, '192.168.3.4', 'test2');
wiot.redis(node, w2, w1, '192.168.3.4', 'test2');
wiot.print(node, w2)

@ -19,12 +19,12 @@ let w = new wiot.wire(0),
let node = nodes[0];
let node1 = nodes[1];
wiot.gpio(wiot.INPUT, node.D3, w1, node);
wiot.gpio(wiot.INPUT, node1.D3, w2, node1);
wiot.gpio(node, wiot.INPUT, node.D3, w1);
wiot.gpio(node1, wiot.INPUT, node1.D3, w2);
//wiot.print(node, w1, w1);
wiot.udp(w4,w5,w6,new wiot.wire(`'192.168.3.100'`), new wiot.wire(4443), w1, node);
wiot.tcp(w,w1, node, '192.168.3.100', 4444);
wiot.tcp(w3,w2, node, '192.168.3.100', 4444);
wiot.udp(node), w4,w5,w6,new wiot.wire(`'192.168.3.100'`), new wiot.wire(4443), w1);
wiot.tcp(node, w,w1, '192.168.3.100', 4444);
wiot.tcp(node, w3,w2, '192.168.3.100', 4444);
wiot.print(node, w, w3, w4, w5, w6);

@ -16,16 +16,16 @@ let w = new wiot.wire(0),
let node = nodes[0];
wiot.gpio(wiot.OUTPUT, node.D4, w, node);
wiot.gpio(node, wiot.OUTPUT, node.D4, w);
wiot.gpio(wiot.INPUT, node.D3, w1, node);
wiot.gpio(node, wiot.INPUT, node.D3, w1);
wiot.buffer(w, w1, node);
wiot.buffer(node, w, w1);
wiot.buffer(w, w2, node);
wiot.buffer(node, w, w2);
wiot.operate(`${wiot.if(`$0==0`, `'true'`, `'false'`)}`, node, w3, w);
wiot.operate(`${wiot.if(`$0=='true'`, 0, 1)}`, node, w2, w4);
wiot.operate(node, `${wiot.if(`$0==0`, `'true'`, `'false'`)}`, w3, w);
wiot.operate(node, `${wiot.if(`$0=='true'`, 0, 1)}`, w2, w4);
wiot.webpage(node, '122f3169fa7e12989bd7f1ed1c571b64', [{
id: 'a',

@ -1,2 +0,0 @@
#!/bin/bash
.\lib\esptool-ck\esptool.exe -cp COM3 -cd nodemcu -ca 0x00000 -cf .\bin\test.bin

@ -1,11 +0,0 @@
--set AP mode
wifi.setmode(wifi.SOFTAP)
--config AP
cfg={}
cfg.ssid="myssid"
cfg.pwd="mypassword"
wifi.ap.config(cfg)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,2 +0,0 @@
#!/bin/bash
.\node_modules\.bin\nodemcu-tool.cmd run -p COM3 led.lua

@ -3,13 +3,24 @@ module.exports = async (port, bin) => {
const { execFile } = require('child_process');
const path = require('path');
const ora = require('ora');
const os = require('os');
const root = __dirname + '/../../../';
const getDevList = () => {
return new Promise((resolve, reject) => {
ban = new ora(`Flashing...`).start();
let process = execFile(root + 'lib/esptool-ck/esptool.exe', ['-cp', port, '-cd', 'nodemcu', '-ca', '0x00000', '-cf', bin], (err, stdout, stderr) => {
let exe = 'esptool.exe';
if(os.platform() != 'win32'){
if(os.platform() == 'linux'){
if(os.arch() == 'x32') exe = 'esptool-32';
if(os.arch() == 'x64') exe = 'esptool-64';
if(os.arch() == 'arm') exe = 'esptool-arm';
}else{
exe = 'esptool-osx';
}
}
let process = execFile(root + 'lib/esptool-ck/'+exe, ['-cp', port, '-cd', 'nodemcu', '-ca', '0x00000', '-cf', bin], (err, stdout, stderr) => {
if(err) {
console.log(stderr);
reject();

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,11 +0,0 @@
{
"info": "function() return CONFIG;end",
"restart": "function() node.restart();end",
"exec": "function(s) return loadstring(s)();end",
"list": "function() local obj = {};for k, v in pairs(w.f) do obj[k] = encoder.toHex(crypto.hash([[md5]],string.dump(v))); end;return obj;end",
"push": "function(s) print(s.hash) w.push(s.hash, s.func);return {status = true};end",
"pull": "function(s) w.pull(s);return {status = true};end",
"clear": "function() w.clear();return {status = true};end",
"refresh": "function() w.refresh();return {status = true};end",
"test": "function(s) return s end"
}

@ -1,15 +0,0 @@
{
"nid": "good",
"wifi": {
"ssid": "yimian-iot",
"pwd": "1234567890."
},
"msg": {
"port": 6789
},
"director": {
"HeartbeatInterval": 10000,
"hostname": "192.168.3.100",
"port": 6789
}
}

@ -1,134 +0,0 @@
-- Wrap a two-staged fifo around a socket's send; see
-- docs/lua-modules/fifosock.lua for more documentation.
--
-- See fifosocktest.lua for some examples of use or tricky cases.
--
-- Our fifos can take functions; these can be useful for either lazy
-- generators or callbacks for parts of the stream having been sent.
local BIGTHRESH = 256 -- how big is a "big" string?
local SPLITSLOP = 16 -- any slop in the big question?
local FSMALLLIM = 32 -- maximum number of small strings held
local COALIMIT = 3
local concat = table.concat
local insert = table.insert
local gc = collectgarbage
local function wrap(sock)
-- the two fifos
local fsmall, lsmall, fbig = {}, 0, (require "fifo").new()
-- ssend last aggregation string and aggregate count
local ssla, sslan = nil, 0
local ssend = function(s,islast)
local ns = nil
-- Optimistically, try coalescing FIFO dequeues. But, don't try to
-- coalesce function outputs, since functions might be staging their
-- execution on the send event implied by being called.
if type(s) == "function" then
if sslan ~= 0 then
sock:send(ssla)
ssla, sslan = nil, 0; gc()
return s, false -- stay as is and wait for :on("sent")
end
s, ns = s()
elseif type(s) == "string" and sslan < COALIMIT then
if sslan == 0
then ssla, sslan = s, 1
else ssla, sslan = ssla .. s, sslan + 1
end
if islast then
-- this is shipping; if there's room, steal the small fifo, too
if sslan < COALIMIT then
sock:send(ssla .. concat(fsmall))
fsmall, lsmall = {}, 0
else
sock:send(ssla)
end
ssla, sslan = "", 0; gc()
return nil, false
else
return nil, true
end
end
-- Either that was a function or we've hit our coalescing limit or
-- we didn't ship above. Ship now, if there's something to ship.
if s ~= nil then
if sslan == 0 then sock:send(s) else sock:send(ssla .. s) end
ssla, sslan = nil, 0; gc()
return ns or nil, false
elseif sslan ~= 0 then
assert (ns == nil)
sock:send(ssla)
ssla, sslan = nil, 0; gc()
return nil, false
else
assert (ns == nil)
return nil, true
end
end
-- Move fsmall to fbig; might send if fbig empty
local function promote(f)
if #fsmall == 0 then return end
local str = concat(fsmall)
fsmall, lsmall = {}, 0
fbig:queue(str, f or ssend)
end
local function sendnext()
if not fbig:dequeue(ssend) then promote() end
end
sock:on("sent", sendnext)
return function(s)
-- don't sweat the petty things
if s == nil or s == "" then return end
-- Function? Go ahead and queue this thing in the right place.
if type(s) == "function" then promote(); fbig:queue(s, ssend); return; end
s = tostring(s)
-- cork sending until the end in case we're the head of line
local corked = false
local function corker(t) corked = true; return t end
-- small fifo would overfill? promote it
if lsmall + #s > BIGTHRESH or #fsmall >= FSMALLLIM then promote(corker) end
-- big string? chunk and queue big components immediately
-- behind any promotion that just took place
while #s > BIGTHRESH + SPLITSLOP do
local pfx
pfx, s = s:sub(1,BIGTHRESH), s:sub(BIGTHRESH+1)
fbig:queue(pfx, corker)
end
-- Big string? queue and maybe tx now
if #s > BIGTHRESH then fbig:queue(s, corker)
-- small and fifo in immediate dequeue mode
elseif fbig._go and lsmall == 0 then fbig:queue(s, corker)
-- small and queue already moving; let it linger in the small fifo
else insert(fsmall, s) ; lsmall = lsmall + #s
end
-- if it happened that we corked the transmission above...
-- if we queued a good amount of data, go ahead and start transmitting;
-- otherwise, wait a tick and hopefully we will queue more in the interim
-- before transmitting.
if corked then
if #fbig <= COALIMIT
then tmr.create():alarm(1, tmr.ALARM_SINGLE, sendnext)
else sendnext()
end
end
end
end
return { wrap = wrap }

@ -1,9 +0,0 @@
{
"info": "function() return CONFIG;end",
"restart": "function() node.restart();end",
"exec": "function(s) return loadstring(s)();end",
"list": "function() local obj = {};for k, v in pairs(w.f) do obj[k] = encoder.toHex(crypto.hash([[md5]],string.dump(v))); end;return obj;end",
"push": "function(s) local obj = sjson.decode(s);w.push(obj.hash, obj.func);return {status = true};end",
"pull": "function(s) w.pull(s);return {status = true};end",
"clear": "function() w.clear();return {status = true};end"
}

@ -1,217 +0,0 @@
------------------------------------------------------------------------------
-- HTTP server module
--
-- LICENCE: http://opensource.org/licenses/MIT
-- Vladimir Dronnikov <dronnikov@gmail.com>
------------------------------------------------------------------------------
local collectgarbage, tonumber, tostring = collectgarbage, tonumber, tostring
local http
do
------------------------------------------------------------------------------
-- request methods
------------------------------------------------------------------------------
local make_req = function(conn, method, url)
return {
conn = conn,
method = method,
url = url,
}
end
------------------------------------------------------------------------------
-- response methods
------------------------------------------------------------------------------
local make_res = function(csend, cfini)
local send = function(self, data, status)
-- TODO: req.send should take care of response headers!
if self.send_header then
csend("HTTP/1.1 ")
csend(tostring(status or 200))
-- TODO: real HTTP status code/name table
csend(" OK\r\n")
-- we use chunked transfer encoding, to not deal with Content-Length:
-- response header
self:send_header("Transfer-Encoding", "chunked")
-- TODO: send standard response headers, such as Server:, Date:
end
if data then
-- NB: no headers allowed after response body started
if self.send_header then
self.send_header = nil
-- end response headers
csend("\r\n")
end
-- chunked transfer encoding
csend(("%X\r\n"):format(#data))
csend(data)
csend("\r\n")
end
end
local send_header = function(_, name, value)
-- NB: quite a naive implementation
csend(name)
csend(": ")
csend(value)
csend("\r\n")
end
-- finalize request, optionally sending data
local finish = function(self, data, status)
-- NB: res.send takes care of response headers
if data then
self:send(data, status)
end
-- finalize chunked transfer encoding
csend("0\r\n\r\n")
-- close connection
cfini()
end
--
local res = { }
res.send_header = send_header
res.send = send
res.finish = finish
return res
end
------------------------------------------------------------------------------
-- HTTP parser
------------------------------------------------------------------------------
local http_handler = function(handler)
return function(conn)
local csend = (require "fifosock").wrap(conn)
local req, res
local buf = ""
local method, url
local ondisconnect = function(connection)
connection:on("receive", nil)
connection:on("disconnection", nil)
connection:on("sent", nil)
collectgarbage("collect")
end
local cfini = function()
csend(function()
conn:on("sent", nil)
conn:close()
ondisconnect(conn)
end)
end
-- header parser
local cnt_len = 0
local onheader = function(_, k, v)
-- TODO: look for Content-Type: header
-- to help parse body
-- parse content length to know body length
if k == "content-length" then
cnt_len = tonumber(v)
end
if k == "expect" and v == "100-continue" then
csend("HTTP/1.1 100 Continue\r\n")
end
-- delegate to request object
if req and req.onheader then
req:onheader(k, v)
end
end
-- body data handler
local body_len = 0
local ondata = function(_, chunk)
-- feed request data to request handler
if not req or not req.ondata then return end
req:ondata(chunk)
-- NB: once length of seen chunks equals Content-Length:
-- ondata(conn) is called
body_len = body_len + #chunk
-- print("-B", #chunk, body_len, cnt_len, node.heap())
if body_len >= cnt_len then
req:ondata()
end
end
local onreceive = function(connection, chunk)
-- merge chunks in buffer
if buf then
buf = buf .. chunk
else
buf = chunk
end
-- consume buffer line by line
while #buf > 0 do
-- extract line
local e = buf:find("\r\n", 1, true)
if not e then break end
local line = buf:sub(1, e - 1)
buf = buf:sub(e + 2)
-- method, url?
if not method then
do
local _
-- NB: just version 1.1 assumed
_, _, method, url = line:find("^([A-Z]+) (.-) HTTP/1.1$")
end
if method then
-- make request and response objects
req = make_req(connection, method, url)
res = make_res(csend, cfini)
end
-- spawn request handler
handler(req, res)
-- header line?
elseif #line > 0 then
-- parse header
local _, _, k, v = line:find("^([%w-]+):%s*(.+)")
-- header seems ok?
if k then
k = k:lower()
onheader(connection, k, v)
end
-- headers end
else
-- NB: we explicitly reassign receive handler so that
-- next received chunks go directly to body handler
connection:on("receive", ondata)
-- NB: we feed the rest of the buffer as starting chunk of body
ondata(connection, buf)
-- buffer no longer needed
buf = nil
-- parser done
break
end
end
end
conn:on("receive", onreceive)
conn:on("disconnection", ondisconnect)
end
end
------------------------------------------------------------------------------
-- HTTP server
------------------------------------------------------------------------------
local srv
local createServer = function(port, handler)
-- NB: only one server at a time
if srv then srv:close() end
srv = net.createServer(net.TCP, 15)
-- listen
srv:listen(port, http_handler(handler))
return srv
end
------------------------------------------------------------------------------
-- HTTP server methods
------------------------------------------------------------------------------
http = {
createServer = createServer,
}
end
return http

Binary file not shown.

@ -1,12 +0,0 @@
if file.exists('_lfs.img') then
file.remove('_lfs.img');
elseif file.exists('lfs.img') then
file.rename('lfs.img', '_lfs.img');
node.LFS.reload('_lfs.img');
end
if adc.force_init_mode(adc.INIT_ADC)
then
node.restart()
return
end
node.LFS.wiot()

@ -1,271 +0,0 @@
--Global Var
CONFIG = {}
udp = nil --UDP Server
key = nil --Encrypt Key
G = {} --Var Zone
--wIoT Toolbox
w = {
f = {},
waitList = {},
send = function(ip, port, fid, body, cb)
local sid = func.randomLetter(8)
local o = {
fid = fid,
sid = sid,
id = CONFIG.w.id,
body = body
}
local status, msg = pcall(sjson.encode, o)
udp:send(port, ip, msg)
if cb == nil then return ;end
w.waitList[sid] = false
local resTimer = tmr.create()
local retryTimer = tmr.create()
local retryTimes = CONFIG.w.maxRetryTimes
resTimer:register(CONFIG.w.scanInterval, tmr.ALARM_AUTO, function()
if func.tableKeyExist(w.waitList, sid) and w.waitList[sid] ~= false then
cb(w.waitList[sid])
w.waitList[sid] = nil
resTimer:unregister()
retryTimer:unregister()
collectgarbage("collect")
end
end)
retryTimer:register(CONFIG.w.retryInterval, tmr.ALARM_AUTO, function()
if retryTimes > 0 and func.tableKeyExist(w.waitList, sid) and w.waitList[sid] == false then
udp:send(port, ip, msg)
retryTimes = retryTimes - 1
else
retryTimer:unregister()
collectgarbage("collect")
end
end)
resTimer:start()
retryTimer:start()
end,
receive = function(s, data, port, ip)
print(data)
local status, msg = pcall(sjson.decode, data)
if not status then return end
if not func.tableKeyExist(msg, 'sid') or not func.tableKeyExist(msg, 'body') then return end
--respond mode
print(msg.fid)
if not func.tableKeyExist(msg, 'fid') then
if func.tableKeyExist(w.waitList, msg.sid) then
w.waitList[msg.sid] = msg.body
end
return
end
print(msg.fid)
--request mode
if not func.tableKeyExist(w.f, msg.fid) then return end
local res = w.f[msg.fid](msg.body, {port = port, ip = ip, socket = s, sid = msg.sid, fid = msg.fid});
print(msg.fid)
local resObj = {
sid = msg.sid,
id = CONFIG.w.id,
body = res
}
status, res = pcall(sjson.encode, resObj)
print(res)
s:send(port, ip, res)
end,
heartbeat = function()
local o = {
version = CONFIG.firmware.version,
id = CONFIG.w.id,
ip = wifi.sta.getip(),
port = CONFIG.udp.server.port,
}
--request
print(sjson.encode(o))
udp:send(CONFIG.w.director.port, CONFIG.w.director.ip, sjson.encode(o))
end,
_push = function(hash, s)
w.f[hash] = function(r)
if hash == 'construct' or hash == 'destruct' then
print(s)
loadstring('print("hhhhhhh")')()
loadstring(s)()
return
end
local status, msg = pcall(loadstring('return '..s)(), r)
local data = {
status = status,
data = msg
}
return data
end
return hash
end,
push = function(hash, s)
w._push(hash, s)
func.jsonfPush('func.json', hash, s)
return hash
end,
pull = function(hash)
w.f[hash] = nil
func.jsonfPull('func.json', hash)
w.refresh()
end,
clear = function()
func.jsonfClear('func.json')
w.refresh()
end,
start = function()
print('w starting...')
local usr = func.jsonfRead('func.json')
if next(usr) ~= nil then
print('in usr')
for k, v in pairs(usr) do
print(k)
w._push(k, v)
end
else
print('in systemd')
local systemd = func.jsonfRead('FUNC.json')
for k, v in pairs(systemd) do
print(k)
w.push(k, v)
end
end
if func.tableKeyExist(w.f, 'construct') then
w.f:construct()
end
end,
stop = function()
if func.tableKeyExist(w.f, 'destruct') then
w.f:destruct()
end
w.f = {}
collectgarbage("collect")
end,
refresh = function()
pcall(w.stop)
pcall(w.start)
end
}
--Functions
func = {
init = {
run = function()
if file.exists("__running") then
file.rename("__running", "__stopped")
else
func.jsonfClear('func.json')
end
collectgarbage("collect")
w.start()
collectgarbage("collect")
func.init.wifi(func.init.udp, func.init.w, func.run)
end,
wifi = function(after, after2, after3)
print('Setting up WIFI...')
wifi.setmode(wifi.STATION)
wifi.sta.config(CONFIG.wifi.station)
wifi.sta.connect()
local wifiInit = tmr.create()
wifiInit:register(1000, tmr.ALARM_AUTO, function()
if wifi.sta.getip() == nil then
print('Waiting for IP ...')
else
print('IP is ' .. wifi.sta.getip())
wifiInit:unregister()
after(after2, after3)
end
end)
wifiInit:start()
end,
udp = function (after, after2)
udp = net.createUDPSocket()
udp:listen(CONFIG.udp.server.port)
udp:on("receive", w.receive)
after(after2)
end,
w = function(after)
w.heartbeat()
local heartbeat = tmr.create()
heartbeat:register(CONFIG.w.heartbeat.interval, tmr.ALARM_AUTO, function()
w.heartbeat()
file.rename("__stopped", "__running")
end);
heartbeat:start()
if after then after() end
end
},
randomLetter = function(len)
local rt = ""
for i = 1, len, 1 do
rt = rt..string.char(math.random(97,122))
end
return rt
end,
jsonfRead = function(f)
if file.open(f) then
local status, obj = pcall(sjson.decode, file.read())
file.close()
if status then
return obj
else
return {}
end
end
return {}
end,
jsonfWrite = function(f, obj)
if file.open(f, 'w+') then
local status, json = pcall(sjson.encode, obj)
if status then
file.write(json)
else
file.write("{}")
end
file.close()
end
end,
jsonfPush = function(f, hash, s)
local obj = func.jsonfRead(f)
obj[hash] = s
func.jsonfWrite(f, obj)
end,
jsonfPull = function(f, hash)
func.jsonfPush(f, hash, nil)
end,
jsonfClear = function(f)
func.jsonfWrite(f, {})
end,
encrypt = function(s, kay)
if key == nil then return s;end
local msg = encoder.toHex(crypto.encrypt("AES-ECB", key, s..func.randomLetter(4)))
return msg..string.sub(encoder.toHex(crypto.hmac("sha1", msg, key)), 1, 8)
end,
decrypt = function(s, kay)
if key == nil then return s;end
local msg, hmac = string.sub(s, 1, string.len(s)-8), string.sub(s, string.len(s)-7, 8)
if string.sub(encoder.toHex(crypto.hmac("sha1", msg, key)), 1, 8) ~= hmac then return nil; end
local raw = crypto.decrypt("AES-ECB", key, encoder.fromHex(msg))
return string.sub(raw, 1, string.len(raw) - 4)
end,
tableKeyExist = function(obj, key)
for k, v in pairs(obj) do
if k == key then
return true
end
end
return false
end
}
--Run
func.run = function()
--run content
gpio.write(0, gpio.LOW)
end
--Load CONFIG
CONFIG = func.jsonfRead('config.json')
--exec Init
func.init.run()

@ -1,842 +0,0 @@
tmr.delay(3000000);
print('total'..node.heap());
(function(__run)
--Packages Used: file, sjson, http, httpserver, mqtt, encoder, timer, node, wifi, gpio
print('close'..node.heap())
--Global Methods
---------------
-- File Object Operation
local f = {};
--f
f.read = function(f)--f:filename
local status, obj = pcall(sjson.decode, file.getcontents(f));
if status then
return obj;
else
return {};
end
end
f.write = function(f, obj)
local status, json = pcall(sjson.encode, obj);
if status then
return file.putcontents(f, json);
else
return false;
end
end
--split string
local stringSplit = function(str, reps)
local resultStrList = {}
string.gsub(str,'[^'..reps..']+', function (w)
table.insert(resultStrList,w);
end);
return resultStrList;
end
--Method Declaration
--------------------
_ = {
_ = {
restart = nil,
reset = nil
},
init = {
http = nil,
mqtt = nil,
onlineFunc = nil
},
config = {
v = nil,
path = 'config.json',
default = {
nid = 'default',
offlineOnly = true,
signalPin = 0,
flag = {
MaxRetryTimes = 2,
MaxResetTimes = 3
},
func = {
offline = {
MaxWaitTime = 60
},
online = {
MaxWaitTime = 60
}
},
fs = {
prefix = {
root = '',
system = '__system/',
data = '__data/',
swap = '__system/swap/'
},
filename = {
nsmap = 'ns.map',
flag = 'flag',
func = 'func.json',
error = 'error.json'
}
},
wifi = {
CheckInterval = 1000,
config = {
ssid = '',
pwd = '',
save = false
}
},
http = {
port = 6789,
api = {
discover = '/discover'
}
},
mqtt = {
host = 'mqtt.yimian.xyz',
port = 1883,
user = nil,
password = nil,
tls = false,
keepaliveTimer = 30,
topicPrefix = '/wiot/default/',
ConnectRetryInterval = 2000,
OfflineRetryInterval = 3000,
PostCheckInterval = 100,
PostTimeout = 10
}
}
},
flag = {
v = nil,
set = nil,
load = nil
},
func = {
id = nil,
offline = nil,
online = nil
},
table = {
merge = nil
},
timer = {
setTimeout = nil,
setInterval = nil
},
signal = {
init = nil,
set = nil,
destroy = nil,
v = nil
},
http = {
v = nil
},
mqtt = {
getTopic = nil,
v = nil
},
f = {
read = nil,
write = nil
},
ns = {
set = nil,
get = nil,
render = nil,
exist = nil,
check = nil,
verify = nil
},
package = {
pack = nil,
depack = nil,
set = nil,
get = nil
},
db = {
public = {
keys = nil,
get = nil,
set = nil,
del = nil,
clear = nil
},
toIndex = nil,
fromIndex = nil,
getFileName = nil
},
msg = {
reg = {
send = {},
post = {}
},
postWaitList = {},
public = {
post = nil,
send = nil,
onPost = nil,
onSend = nil
},
mpost = nil,
msend = nil,
dpost = nil,
dsend = nil
},
api = {
http = {
discover = nil,
msg = nil
},
mqtt = {
msg = nil,
heartbeat = nil,
ns = nil,
func = nil,
restart = nil
}
}
};
print('_.all'..node.heap())
print(_.config.default.nid);
local CONFIG_DEFAULT = {
nid = 'default',
offlineOnly = true,
signalPin = 0,
flag = {
MaxRetryTimes = 2,
MaxResetTimes = 3
},
func = {
offline = {
MaxWaitTime = 60
},
online = {
MaxWaitTime = 60
}
},
fs = {
prefix = {
root = '',
system = '__system/',
data = '__data/',
swap = '__system/swap/'
},
filename = {
nsmap = 'ns.map',
flag = 'flag',
func = 'func.json',
error = 'error.json'
}
},
wifi = {
CheckInterval = 1000,
config = {
ssid = '',
pwd = '',
save = false
}
},
http = {
port = 6789,
api = {
discover = '/discover'
}
},
mqtt = {
host = 'mqtt.yimian.xyz',
port = 1883,
user = nil,
password = nil,
tls = false,
keepaliveTimer = 30,
topicPrefix = '/wiot/default/',
ConnectRetryInterval = 2000,
OfflineRetryInterval = 3000,
PostCheckInterval = 100,
PostTimeout = 10
}
}
--Merge config
----------------------
--Methods preparation
-- merge two tables
tableMerge = function(a, b)
for k, v in pairs(b) do
if type(v) == 'table' and type(a[k] or false) == 'table' then
a[k] = tableMerge(a[k], v);
else
a[k] = v;
end
end
return a;
end
print('merge.p'..node.heap())
--Exec
_.config.v = _.config.default;
_.config.v = tableMerge(_.config.v, f.read(_.config.path));
print('merge.e'..node.heap())
--Release Resources
tableMerge = nil;
fRead = nil;
collectgarbage("collect");
print(_.config.v.wifi.config.ssid)
print(_.config.v.mqtt.host)
print('merge.r'..node.heap())
--Load SWAP
-----------
--Methods Preparation
Load_ToSwap = function(obj, s)
print('swap.p'..node.heap()..s)
for k, v in pairs(_) do
s = s..'_'..encoder.toBase64(k);
if type(v) == 'table' then
Load_ToSwap(v, s);
else
file.putcontents(_.config.v.fs.prefix.swap..s, v);
end
end
end
print('swap.p'..node.heap())
-- Exec
Load_ToSwap(_.config.v, encoder.toBase64('config')..'_'..encoder.toBase64('v'));
local SWAP_PREFIX = _.config.v.fs.prefix.swap;
print('swap.e'..node.heap())
--Release Resources
Load_ToSwap = nil;
_ = nil;
print('swap.r'..node.heap())
--Global APIs
_ = setmetaltable({}, {
__index = function(table, key)
local arr = stringSplit(key, '_');
local s = '';
for v in arr do
s = s..'_'..encoder.toBase64(v);
end
return file.getcontents(SWAP_PREFIX..s);
end,
__newindex = function(table, key, val)
local arr = stringSplit(key, '_');
local s = '';
for v in arr do
s = s..'_'..encoder.toBase64(v);
end
if type(val) == 'function' then
val = string.dump(val);
end
file.putcontents(SWAP_PREFIX..s, val);
end
});
print('swap.a'..node.heap())
print(_.config_v_nid);
--package loaded
----------------
local httpserver = dofile('httpserver.lua');
--Method Defination
-------------------
--_
_._.restart = function(err)
if err then
file.putcontents(_.config.v.fs.prefix.system.._.config.v.fs.filename.error, tostring(err));
end
node.restart();
end
_._.reset = function()
file.remove(_.config.v.fs.prefix.system.._.config.v.fs.filename.error);
file.remove(_.config.v.fs.prefix.system.._.config.v.fs.filename.func);
file.remove(_.config.v.fs.prefix.system.._.config.v.fs.filename.flag);
node.restart();
end
--flag
_.flag.load = function()
_.flag.v = tonumber(file.getcontents(_.config.v.fs.prefix.system.._.config.v.fs.filename.flag));
end
_.flag.set = function(val)
_.config.flag.v = val;
file.putcontents(_.config.v.fs.prefix.system.._.config.v.fs.filename.flag, tostring(val));
end
_.flag.ward = function(f)
f();
_.flag.set(-1);
end
--table
--timer
_.timer.setTimeout = function(f, time_ms)
return tmr.create():alarm(time_ms, tmr.ALARM_SINGLE, f);
end
_.timer.setInterval = function(f, time_ms)
return tmr.create():alarm(time_ms, tmr.ALARM_AUTO, function(timer)
f(function(delay_time_ms)
if delay_time_ms < 0 then
timer:unregister();
else
timer:stop();
_.timer.setTimeout(function()
timer:start();
end, delay_time_ms);
end
end)
end);
end
--signal
_.signal.init = function()
gpio.mode(_.config.v.signalPin, gpio.OUTPUT);
_.signal.v = tmr.create();
end
_.signal.set = function(interval_ms)
_.signal.v:alarm(interval_ms, tmr.ALARM_AUTO, function()
if gpio.read(_.config.v.signalPin) == gpio.HIGH then
gpio.write(_.config.v.signalPin, gpio.LOW);
else
gpio.write(_.config.v.signalPin, gpio.HIGH);
end
end);
end
_.signal.destroy = function()
gpio.write(_.config.v.signalPin, gpio.HIGH);
_.signal.v:unregister();
_.signal.v = nil;
end
--mqtt
_.mqtt.getTopic = function(s)
return _.config.v.mqtt.topicPrefix.._.config.v.nid..'/'..s;
end
_.mqtt.start = function()
_.mqtt.v:connect(
_.config.v.mqtt.host,
_.config.v.mqtt.port,
_.config.v.mqtt.tls,
function(client)
client:subscribe(_.mqtt.getTopic('msg/#'));
client:subscribe(_.mqtt.getTopic('ctl/#'));
client:publish(_.mqtt.getTopic('status'), 'online', 0, 0);
end,
function(client, reason)
_.timer.setTimeout(_.mqtt.start, _.config.v.mqtt.ConnectRetryInterval);
end
);
end
--ns
_.ns.set = function(obj)
return _.f.write(_.config.v.fs.prefix.system.._.config.v.fs.filename.nsmap, obj);
end
_.ns.get = function()
return _.f.read(_.config.v.fs.prefix.system.._.config.v.fs.filename.nsmap);
end
_.ns.render = function(nid)
for k, v in pairs(_.ns.get()) do
if k == nid and v then
return v;
end
end
return nid;
end
_.ns.exist = function(nid)
if _.ns.render(nid) == nid then
return false;
else
return true;
end
end
_.ns.check = function(nid, ip, cb)--cb:bool status
http.post('http://'..ip.._.config.v.http.api.discover, nil, '', function(code, data)
if code ~= 200 or data ~= nid then
cb(false);
else
cb(true);
end
end);
end
_.ns.verify = function()
local ns = _.ns.get();
for k, v in pairs(ns) do
_.ns.check(k, v, function(status)
if not status then
ns[k] = false;
_.ns.set(ns);
end
end)
end
end
--package
_.package.pack = function(o)
local status, json = pcall(sjson.encode, o);
if status then
return json;
else
return nil;
end
end
_.package.depack = function(s)
local status, obj = pcall(json.decode, s);
if status then
return obj;
else
return {};
end
end
_.package.set = function(to, body, mode)--to:nid, body:obj
local o = {
from = _.config.v.nid,
to = to,
mode = mode,
body = body
}
return _.package.pack(o);
end
_.package.get = function(pack)--string package
local status, obj = pcall(json.decode, pack);
if status and obj.from and obj.mode then
return obj.from, obj.body, obj.mode;
else
return nil, nil, nil;
end
end
--db
_.db.toIndex = function(key)
return encoder.toBase64(key);
end
_.db.fromIndex = function(index)
return encoder.fromBase64(index);
end
_.db.getFileName = function(key)
return _.config.v.fs.prefix.data.._.db.toIndex(key);
end
_.db.public.keys = function() --list all keys with size
local o = {};
for k, v in pairs(file.list(_.config.v.fs.prefix.data..'.')) do
o[_.db.fromIndex(k)] = v;
end
return o;
end
_.db.public.get = function(key)
return _.f.read();
end
_.db.public.set = function(key, obj)
return _.f.write(_.db.getFileName(key), obj);
end
_.db.public.del = function(key)
local fileName = _.db.getFileName(key);
file.remove(fileName);
return not file.exists(fileName);
end
_.db.public.clear = function()
local flag = true;
for k, v in pairs(_.db.public.keys()) do
flag = flag and _.db.public.del(k);
end
return flag;
end
--msg
_.msg.dpost = function(to, name, body, cb)--return (bool status, data)
if _.ns.exist(to) then
http.post(
'http://'.._.ns.render(to)..'/msg/'..encoder.toBase64(name),
'Content-Type: application/json\r\n',
_.package.set(to, body, 'post'),
function(code, res)
if code ~= 200 then
cb(false);
else
cb(true, _.package.get(res));
end
end
);
else
cb(false);
end
end
_.msg.dsend = function(to, name, body)
if _.ns.exist(to) then
http.post(
'http://'.._.ns.render(to)..'/msg/'..encoder.toBase64(name),
'Content-Type: application/json\r\n',
_.package.set(to, body, 'send'),
function(code, res) end
);
end
end
_.msg.mpost = function(to, name, body, cb)
_.msg.postWaitList[encoder.toBase64(name)..to] = false;
local PostBeginAt = tmr.time();
_.timer.setInterval(function(delay)
if _.msg.postWaitList[encoder.toBase64(name)..to] ~= false then
cb(true, _.msg.postWaitList[encoder.toBase64(name)..to]);
_.msg.postWaitList[encoder.toBase64(name)..to] = nil;
delay(-1);
else
if PostBeginAt < tmr.time() - _.config.v.mqtt.PostTimeout then
cb(false);
_.msg.postWaitList[encoder.toBase64(name)..to] = nil;
delay(-1);
end
end
end, _.config.v.mqtt.PostCheckInterval);
_.mqtt.v:publish(
_.config.v.mqtt.topicPrefix..to..'/'..encoder.toBase64(name),
_.package.set(to, body, 'post'),
1,
0
);
end
_.msg.msend = function(to, name, body)
_.mqtt.v:publish(
_.config.v.mqtt.topicPrefix..to..'/'..encoder.toBase64(name),
_.package.set(to, body, 'send'),
0,
0
);
end
_.msg.public.onSend = function(name, f)--f:return (body, from)
_.msg.reg.send[encoder.toBase64(name)] = f;
end
_.msg.public.onPost = function(name, f)--f:return body, from, reply(reply_body)
_.msg.reg.post[encoder.toBase64(name)] = f;
end
_.msg.public.send = function(to, name, body)
if _.ns.exist(to) then
_.msg.dsend(to, name, body);
else
_.msg.msend(to, name, body);
end
end
_.msg.public.post = function(to, name, body, cb)
if _.ns.exist(to) then
_.msg.dpost(to, name, body, cb);
else
_.msg.mpost(to, name, body, cb);
end
end
--api
_.api.http.discover = function(res)
res.finish(_.config.v.nid, 200);
end
_.api.http.msg = function(name, req, res)
local data = '';
req.ondata = function(req, chunk)
if chunk ~= nil then
data = data..chunk;
else
local from, body, mode = _.package.get(data);
if mode == 'send' then
res.finish();
for k, v in pairs(_.msg.reg.send) do
if k == name then
v(body, from);
return;
end
end
elseif mode == 'post' then
for k, v in pairs(_.msg.reg.post) do
if k == name then
v(body, from, function(reply_body)
res.finish(_.package.set(from, reply_body, 'reply'));
end);
return;
end
end
res.finish(nil, 404);
end
end
end
end
_.api.mqtt.msg = function(name, data)
local from, body, mode = _.package.get(data);
if mode == 'send' then
for k, v in pairs(_.msg.reg.send) do
if k == name then
v(body, from);
return;
end
end
elseif mode == 'post' then
for k, v in pairs(_.msg.reg.post) do
if k == name then
v(body, from, function(reply_body)
_.mqtt.v:publish(_.config.v.mqtt.topicPrefix..from..'/msg/'..name.._.config.v.nid, _.package.set(from, reply_body, 'reply'), 1, 0);
end);
return;
end
end
elseif mode == 'reply' then
for k, v in pairs(_.msg.postWaitList) do
if k == name then
_.msg.postWaitList[k] = body;
return;
end
end
end
end
_.api.mqtt.heartbeat = function()
local o = {
nid = _.config.v.nid,
uptime = tmr.time(),
heap = node.heap(),
funcID = _.func.id,
ip = wifi.sta.getip(),
ns = _.ns.get()
}
_.mqtt.v:publish(_.mqtt.getTopic('heartbeat'), _.package.pack(o), 0, 0);
end
_.api.mqtt.ns = function(data)
local obj = _.package.depack(data);
_.ns.set(obj);
end
_.api.mqtt.func = function(data)
local obj = _.package.depack(data);
_.f.write(_.config.v.fs.prefix.system.._.config.v.fs.filename.func, obj);
_._.restart();
end
_.api.mqtt.restart = function()
_._.restart();
end
--Environment Loading & Checking
----------------------
--Flag Checking
_.flag.load();
if _.flag.v == nil then
_.flag.set(0);
end
--User Func Checking
local func = _.f.read(_.config.v.fs.prefix.system.._.config.v.fs.filename.func);
if func and func.id and func.offline and func.online then
_.func.id = func.id;
_.func.offline = func.offline;
_.func.online = func.online;
end
func = nil;
--System Preparation
--------------------
--Signal Start
_.signal.init();
_.signal.set(1500);
--Decide System Mode
_.flag.set(_.flag.v + 1);
if _.flag.v >= _.config.v.flag.MaxRetryTimes and _.flag.v <= _.config.v.flag.MaxRetryTimes + _.config.v.flag.MaxResetTimes then
_._.reset();
elseif _.flag.v > _.config.v.flag.MaxRetryTimes + _.config.v.flag.MaxResetTimes then
--safe mode
--Signal set
_.signal.set(3000);
do return end;
end
--OFFLINE System Launch
-----------------------
--Signal set
_.signal.set(800);
--Run user offline func
_.flag.ward(function()
tmr.softwd(_.config.v.func.offline.MaxWaitTime); --start watchdog
if not __run(_.func.offline, _.timer, _.db.public, nil) then --enable DB and disable MSG
_._.restart('Offline Func Startup Fail..');
end
tmr.softwd(-1); --disable watchdog
end);
--Network Modules Init
----------------------
--If OFFLINEONLY is configed, do not start network
if _.config.v.offlineOnly == true then
return;
end
--Signal set
_.signal.set(200);
--Connect to wifi AP
wifi.setmode(wifi.STATION);
wifi.sta.sethostname('WIOT-'.._.config.v.nid);
wifi.sta.config(_.config.v.wifi.config);
_.timer.setInterval(function(delay)
if wifi.sta.getip() ~= nil then
delay(-1);
_.init.http();
_.init.mqtt();
end
end, _.config.v.wifi.CheckInterval);
--http module
_.init.http = function()
_.http.v = httpserver.createServer(_.config.v.http.port, function(req, res)
local path = string.split(req.url, '/');
if path[2] == 'discover' then
_.api.http.discover(res);
elseif path[2] == 'msg' and path[3] then
_.api.http.msg(path[3], req, res);
else
res.finish('', 500);
end
end);
end
--mqtt module
_.init.mqtt = function()
_.mqtt.v = mqtt.Client(_.config.v.nid, _.config.v.mqtt.keepaliveTimer, _.config.v.mqtt.user, _.config.v.mqtt.password);
_.mqtt.v:lwt(_.mqtt.getTopic('status'), 'offline', 0, 0);
_.mqtt.v:on('offline', function()
_.timer.setTimeout(_.mqtt.start, _.config.v.mqtt.OfflineRetryInterval);
end);
_.mqtt.v:on('message', function(client, topic, data)
local path = string.split(string.split(topic, _.config.v.mqtt.topicPrefix), '/');
if path[1] == 'ctl' then
if path[2] == 'heartbeat' then
_.api.mqtt.heartbeat();
elseif path[2] == 'ns' then
_.api.mqtt.ns(data);
elseif path[2] == 'func' then
_.api.mqtt.func(data);
elseif path[2] == 'restart' then
_.api.mqtt.restart();
end
elseif path[1] == 'msg' and path[2] then
_.api.mqtt.msg(path[2], data);
end
end);
end
--ONLINE System Launch
----------------------
--Run user offline func
_.init.onlineFunc = function()
_.flag.ward(function()
tmr.softwd(_.config.v.func.online.MaxWaitTime); --start watchdog
if not __run(_.func.online, _.timer, _.db.public, _.msg.public) then --enable DB and MSG
_._.restart('online Func Startup Fail..');
end
tmr.softwd(-1); --disable watchdog
_.signal.destroy(); --destroy signal
end);
end
end)(function(func, timer, db, msg)
return pcall(loadstring(func));
end);

@ -1,314 +0,0 @@
tmr.create():alarm(5000, tmr.ALARM_SINGLE, function()
print('total', node.heap());
(function(__run)
--Packages Used: file, sjson, http, httpserver, mqtt, encoder, timer, node, wifi, gpio
collectgarbage("collect")
print('close', node.heap())
--SYSTEM CONSTANT
local CONFIG_PATH = 'config.json';
local DEFAULT_CONFIG = {
nid = 'default',
offlineOnly = true,
signalPin = 0,
flag_MaxRetryTimes = 200,
flag_MaxResetTimes = 3,
func_offline_MaxWaitTime = 60,
func_online_MaxWaitTime = 60,
fs_prefix_root = '',
fs_prefix_system = '__system/',
fs_prefix_data = '__data/',
fs_prefix_swap = '__system/swap/',
fs_filename_nsmap = 'ns.map',
fs_filename_flag = 'flag',
fs_filename_func = 'func.json',
fs_filename_error = 'error',
wifi_CheckInterval = 1000,
wifi_config_ssid = '',
wifi_config_pwd = '',
wifi_config_save = false,
http_port = 6789,
http_api_discover = '/discover',
mqtt_host = 'mqtt.yimian.xyz',
mqtt_port = 1883,
mqtt_user = nil,
mqtt_password = nil,
mqtt_tls = false,
mqtt_keepaliverTimer = 30,
mqtt_topicPrefix = '/wiot/default/',
mqtt_ConnectRetryInterval = 2000,
mqtt_OfflineRetryInterval = 3000,
mqtt_PostCheckInterval = 100,
mqtt_PostTimeout = 10
}
collectgarbage("collect")
print('SYSTEM CONSTANT', node.heap())
--Init Global Methods
---------------------
-- File Object Operation
local fs = {
read = function(f)--f:filename
local status, obj = pcall(sjson.decode, file.getcontents(f));
if status then
return obj;
else
return {};
end
end,
write = function(f, obj)
local status, json = pcall(sjson.encode, obj);
if status then
return file.putcontents(f, json);
else
return false;
end
end
}
--split string
local stringSplit = function(str, reps)
local resultStrList = {}
string.gsub(str,'[^'..reps..']+', function (w)
table.insert(resultStrList,w);
end);
return resultStrList;
end
collectgarbage("collect")
print('Init Global Methods', node.heap())
--Config Loading
-----------------
--load user config
config = fs.read(CONFIG_PATH);
--print sth here, otherwise cause error. Amazing.
print('');
--merge user and default config
for k, v in pairs(DEFAULT_CONFIG) do
if config[k] == nil then
config[k] = v;
end
end
--release resource
DEFAULT_CONFIG = nil;
collectgarbage("collect")
print('Config Loading', node.heap())
--SWAP Medthods
----------------
local swap = {
set = function(index, val)
fs.write(config.fs_prefix_swap..index, {val});
end,
get = function(index)
return fs.read(config.fs_prefix_swap..index)[1];
end
}
collectgarbage("collect")
print('SWAP Medthods', node.heap())
--[[
--CONFIG to SWAP
----------------
for k, v in pairs(config) do
swap.set('C'..k, v);
end
config = setmetatable({
fs_prefix_swap = config.fs_prefix_swap
}, {
__index = function(table, key)
return swap.get('C'..key);
end
});
collectgarbage("collect")
print('CONFIG to SWAP', node.heap())
]]
--Variables in SWAP
----------------
var = setmetatable({}, {
__index = function(table, key)
return swap.get('V'..key);
end,
__newindex = function(table, key, val)
swap.set('V'..key, val);
end
});
collectgarbage("collect")
print('Variables in SWAP', node.heap())
--Methods in SWAP
----------------
f = setmetatable({}, {
__index = function(table, key)
return loadstring(encoder.fromBase64(swap.get('F'..key)));
end,
__newindex = function(table, key, val)
swap.set('F'..key, encoder.toBase64(string.dump(val)));
end
});
collectgarbage("collect")
print('Methods in SWAP', node.heap())
--_
f._restart = function(err)
if err then
file.putcontents(config.fs_prefix_system..config.fs_filename_error, tostring(err));
end
node.restart();
end
f._reset = function()
file.remove(_.config.v.fs.prefix.system.._.config.v.fs.filename.error);
file.remove(_.config.v.fs.prefix.system.._.config.v.fs.filename.func);
file.remove(_.config.v.fs.prefix.system.._.config.v.fs.filename.flag);
node.restart();
end
--flag
f.flag_load = function()
local flag = file.getcontents(config.fs_prefix_system..config.fs_filename_flag);
if flag then
var.flag_v = tonumber(flag);
end
end
f.flag_set = function(val)
var.flag_v = val;
file.putcontents(config.fs_prefix_system..config.fs_filename_flag, tostring(val));
end
f.flag_ward = function(func)
func();
f.flag_set(var, config, -1);
end
--signal
f.signal_init = function()
gpio.mode(config.signalPin, gpio.OUTPUT);
signal_v = tmr.create();
end
f.signal_set = function(interval_ms)
signal_v:alarm(interval_ms, tmr.ALARM_AUTO, function()
if gpio.read(config.signalPin) == gpio.HIGH then
gpio.write(config.signalPin, gpio.LOW);
else
gpio.write(config.signalPin, gpio.HIGH);
end
end);
end
f.signal_destroy = function()
gpio.write(config.signalPin, gpio.HIGH);
signal_v:unregister();
signal_v = nil;
end
--timer
f.timer_setTimeout = function(func, time_ms)
return tmr.create():alarm(time_ms, tmr.ALARM_SINGLE, func);
end
f.timer_setInterval = function(func, time_ms)
return tmr.create():alarm(time_ms, tmr.ALARM_AUTO, func);
end
--mqtt
f.mqtt_getTopic = function(s)
return _.config.v.mqtt.topicPrefix.._.config.v.nid..'/'..s;
end
f.mqtt_start = function()
mqtt_v:connect(
config.mqtt_host,
config.mqtt_port,
config.mqtt_tls,
function(client)
client:subscribe(f.mqtt_getTopic('msg/#'));
client:subscribe(f.mqtt_getTopic('ctl/#'));
client:publish(f.mqtt_getTopic('status'), 'online', 0, 0);
end,
function(client, reason)
f.timer_setTimeout(f.mqtt_start, config.mqtt_ConnectRetryInterval);
end
);
end
collectgarbage("collect")
print('Methods in SWAP', node.heap())
--Environment Loading & Checking
----------------------
--Flag Checking
f.flag_load();
if var.flag_v == nil then
f.flag_set(0);
end
--User Func Checking
local func = fs.read(config.fs_prefix_system..config.fs_filename_func);
if func and func.id and func.offline and func.online then
var.func_id = func.id;
var.func_offline = func.offline;
var.func_online = func.online;
end
func = nil;
collectgarbage("collect")
print('Environment Loading & Checking', node.heap())
--System Preparation
--------------------
--Signal Start
f.signal_init();
collectgarbage("collect")
print('System Preparation', node.heap())
f.signal_set(1500);
collectgarbage("collect")
print('System Preparation', node.heap())
--Decide System Mode
f.flag_set(var.flag_v + 1);
collectgarbage("collect")
print('System Preparation', node.heap())
if var.flag_v >= config.flag_MaxRetryTimes and var.flag_v <= config.flag_MaxRetryTimes + config.flag_MaxResetTimes then
f._reset();
elseif var.flag_v > config.flag_MaxRetryTimes + config.flag_MaxResetTimes then
--safe mode
--Signal set
f.signal_set(3000);
do return end;
end
collectgarbage("collect")
print('System Preparation', node.heap())
--OFFLINE System Launch
-----------------------
--Signal set
f.signal_set(800);
--Run user offline func
f.flag_ward(function()
tmr.softwd(config.func_offline_MaxWaitTime); --start watchdog
if not __run(var.func_offline) then --enable DB and disable MSG
f._restart('Offline Func Startup Fail..');
end
tmr.softwd(-1); --disable watchdog
end);
collectgarbage("collect")
print('OFFLINE System Launch', node.heap())
end)(function(func)
return pcall(loadstring(func));
end);
end);

Binary file not shown.

@ -1,120 +0,0 @@
--CONFIG
CONFIG = {
firmware = {
version = '0.0.1'
},
wifi = {
station = {
ssid = "yimian-iot",
pwd = "1234567890.",
save = true
}
},
coap = {
server = {
port = 5683
}
},
w = {
id = {}
director = {
ip = '192.168.3.251'
},
heartbeat = {
interval = 15000
}
}
}
--Global Var
cs = nil --coAP Server
cc = nil --coAP Client
--wIoT Toolbox
w = {
f = {},
push = function(hash, s)
w.f[hash] = loadstring(s)
cs:func('w.f.'..hash)
return hash
end,
pull = function(hash)
w.f[hash] = nil
w.refresh()
end,
clear = function()
w.f = nil
w.refresh()
end,
start = function()
cs = coap.Server()
cs:listen(CONFIG.coap.server.port)
w.push('_/info', 'function() local status, json;ok, json = pcall(sjson.encode, CONFIG);return json;end')
w.push('_/w/f', 'function() local status, json;ok, json = pcall(sjson.encode, w.f);return json;end');
w.push('_/w/push', 'function() ')
end,
stop = function()
cs:close()
cs = nil
collectgarbage("collect")
end,
refresh = function()
w.stop()
w.start()
for k, v in pairs(w.f) do
cs:func('w.f.'..k)
end
end
}
--Functions
func = {
init = {
run = function()
func.init.wifi(func.init.coap, func.init.w, func.run)
end,
wifi = function(after, after2, after3)
print('Setting up WIFI...')
wifi.setmode(wifi.STATION)
wifi.sta.config(CONFIG.wifi.station)
wifi.sta.connect()
local wifiInit = tmr.create()
wifiInit:register(1000, tmr.ALARM_AUTO, function()
if wifi.sta.getip() == nil then
print('Waiting for IP ...')
else
print('IP is ' .. wifi.sta.getip())
wifiInit:unregister()
after(after2, after3)
end
end)
wifiInit:start()
end,
coap = function (after, after2)
cs = coap.Server()
cs:listen(CONFIG.coap.server.port)
cc = coap.Client()
after(after2)
end,
w = function(after)
if after then after()
end
},
randomLetter = function(len)
local rt = ""
for i = 1, len, 1 do
rt = rt..string.char(math.random(97,122))
end
return rt
end
}
--Run
func.run = function()
gpio.write(0, gpio.LOW)
end
--exec Init
func.init.run()

Binary file not shown.

@ -1,15 +0,0 @@
var packageRoot = require.resolve('nodemcu-tool')
.match(/^.*[\/\\]node_modules[\/\\][^\/\\]*/)[0];
console.log(packageRoot)
;(async ()=>{
var _connector = require('nodemcu-tool');
console.log(await _connector.connect('COM3'))
console.log('dd')
console.log(await _connector.upload('test/led.lua', 'led.lua.', {minify: true}, ()=>{}))
await _connector.disconnect();
})();
//

@ -1,2 +0,0 @@
#!/bin/bash
.\node_modules\.bin\nodemcu-tool.cmd upload -p COM3 .\test\led.lua
Loading…
Cancel
Save