├── .gitignore ├── LICENSE ├── README.md ├── data ├── ACS712.jpg ├── ACS712.png ├── SCT013-000.jpg ├── SCT013-000.png ├── ZMPT101B.jpg ├── ZMPT101B.png ├── alarm.js ├── bad_sin.png ├── channel.htm ├── display.htm ├── good_sin.png ├── group.htm ├── index.htm ├── info.htm ├── ioport.htm ├── jquery-lastest.min.js ├── live.htm ├── mqtt.htm ├── script.js ├── sensor.htm ├── signalpath.png ├── styles.css ├── update.htm ├── voltage-div.png └── wlan.htm ├── hardware └── powermeter_supply │ ├── README.md │ ├── cnc_1.png │ ├── cnc_2.png │ ├── config │ └── measure.json │ ├── gocde │ ├── iso_fine.gcode │ ├── iso_fine_probe.gcode │ └── powermeter.png │ ├── powermeter.brd │ ├── powermeter.pdf │ ├── powermeter.pro │ ├── powermeter.sch │ ├── powermeter_ChiliPeppr.png │ ├── powermeter_ChiliPeppr_low.png │ ├── powermeter_bottom.png │ ├── powermeter_schematic.pdf │ ├── powermeter_schematic.png │ ├── powermeter_schematic_low.png │ └── powermeter_top.png ├── images ├── ACS712.jpg ├── ACS712.png ├── SCT013-000.jpg ├── SCT013-000.png ├── ZMPT101B.jpg ├── ZMPT101B.png ├── live-view.gif ├── live-view.png ├── measurement-setting.png ├── mqtt-setting.png ├── preview.gif ├── schematic.png ├── signalpath.png ├── signalpath.svg └── voltage-div.png ├── lib └── async-mqtt-client-develop │ ├── .editorconfig │ ├── .github │ └── workflows │ │ ├── build_examples_pio.yml │ │ └── cpplint.yml │ ├── .gitignore │ ├── LICENSE │ ├── Makefile │ ├── README.md │ ├── async-mqtt-client.cppcheck │ ├── docs │ ├── 1.-Getting-started.md │ ├── 2.-API-reference.md │ ├── 3.-Memory-management.md │ ├── 4.-Limitations-and-known-issues.md │ ├── 5.-Troubleshooting.md │ ├── README.md │ └── index.md │ ├── examples │ ├── FullyFeatured-ESP32 │ │ └── FullyFeatured-ESP32.ino │ ├── FullyFeatured-ESP8266 │ │ └── FullyFeatured-ESP8266.ino │ └── FullyFeaturedSSL │ │ ├── platformio.ini │ │ └── src │ │ └── main.cpp │ ├── keywords.txt │ ├── library.json │ ├── library.properties │ ├── scripts │ ├── CI │ │ ├── build_examples_pio.sh │ │ ├── platformio_esp32.ini │ │ └── platformio_esp8266.ini │ └── get-fingerprint │ │ └── get-fingerprint.py │ └── src │ ├── AsyncMqttClient.cpp │ ├── AsyncMqttClient.h │ ├── AsyncMqttClient.hpp │ └── AsyncMqttClient │ ├── Callbacks.hpp │ ├── DisconnectReasons.hpp │ ├── Errors.hpp │ ├── Flags.hpp │ ├── Helpers.hpp │ ├── MessageProperties.hpp │ ├── Packets │ ├── ConnAckPacket.cpp │ ├── ConnAckPacket.hpp │ ├── Out │ │ ├── Connect.cpp │ │ ├── Connect.hpp │ │ ├── Disconn.cpp │ │ ├── Disconn.hpp │ │ ├── OutPacket.cpp │ │ ├── OutPacket.hpp │ │ ├── PingReq.cpp │ │ ├── PingReq.hpp │ │ ├── PubAck.cpp │ │ ├── PubAck.hpp │ │ ├── Publish.cpp │ │ ├── Publish.hpp │ │ ├── Subscribe.cpp │ │ ├── Subscribe.hpp │ │ ├── Unsubscribe.cpp │ │ └── Unsubscribe.hpp │ ├── Packet.hpp │ ├── PingRespPacket.cpp │ ├── PingRespPacket.hpp │ ├── PubAckPacket.cpp │ ├── PubAckPacket.hpp │ ├── PubCompPacket.cpp │ ├── PubCompPacket.hpp │ ├── PubRecPacket.cpp │ ├── PubRecPacket.hpp │ ├── PubRelPacket.cpp │ ├── PubRelPacket.hpp │ ├── PublishPacket.cpp │ ├── PublishPacket.hpp │ ├── SubAckPacket.cpp │ ├── SubAckPacket.hpp │ ├── UnsubAckPacket.cpp │ └── UnsubAckPacket.hpp │ ├── ParsingInformation.hpp │ └── Storage.hpp ├── platformio.ini ├── powermeter.bin └── src ├── config.h ├── config ├── display_config.cpp ├── display_config.h ├── ioport_config.cpp ├── ioport_config.h ├── measure_config.cpp ├── measure_config.h ├── mqtt_config.cpp ├── mqtt_config.h ├── wifi_config.cpp └── wifi_config.h ├── display.cpp ├── display.h ├── ioport.cpp ├── ioport.h ├── measure.cpp ├── measure.h ├── mqttclient.cpp ├── mqttclient.h ├── ntp.cpp ├── ntp.h ├── powermeter.cpp ├── utils ├── basejsonconfig.cpp └── basejsonconfig.h ├── webserver.cpp ├── webserver.h ├── wificlient.cpp └── wificlient.h /.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode 3 | update_firmware.sh 4 | update_spiffs.sh 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |   4 | 5 |   6 | 7 |

8 |
9 | 10 | # powermeter 11 | 12 | A not so simple but very flexible smart meter based on ESP32. It supports MQTT, live monitoring via web interface, IO ports ( can be switched depending on measured values ), a simple OLED driver for simple value reports, editable opcode sequences per channel and group management. And the best is: everything can also be set via the web interface and has immediate effect and invites to play to improve the understanding of AC voltage/current or DC voltage/current.
13 |

Note: From version 2022110101 a complete reconfiguration is required.

14 |

Danger: Working with 110V or 230V is dangerous!

15 | 16 | # install 17 | 18 | Clone this repository and open it with platformIO. Remember, the SPIFF must also be flashed. On a terminal in vscode you can do it with 19 | ```bash 20 | pio run -t uploadfs 21 | pio run -t upload 22 | ``` 23 | 24 | After that, take a look at your monitorport ... 25 | 26 | ```text 27 | Read config from SPIFFS 28 | scan for SSID "" ... not found 29 | starting Wifi-AP with SSID "powermeter_aadee0" 30 | AP IP address: 192.168.4.1 31 | Start Main Task on Core: 1 32 | Start NTP Task on Core: 1 33 | Start Measurement Task on Core: 0 34 | Start MQTT-Client on Core: 1 35 | Start Webserver on Core: 1 36 | NTP-client: renew time 37 | Start OTA Task on Core: 1 38 | Failed to obtain time 39 | NTP-client: Thursday, January 01 1970 01:00:07 40 | ``` 41 | When the output look like this, congratulation! 42 | 43 | After the first start an access point will be opened with an unique name like 44 | ```bash 45 | powermeter_XXXXX 46 | ``` 47 | and an not so unique password 48 | ```bash 49 | powermeter 50 | ``` 51 | After that you can configure the powermeter under the following IP-address with your favorite webbrowser 52 | ```bash 53 | http://192.168.4.1 or powermeter_xxxxxx.local 54 | ``` 55 | # how it works 56 | 57 | ![signalpath](images/signalpath.png) 58 | 59 | At any time, all 6 adc channel are read in simultaneously regardless of the settings. Afterwards, these 6 ADC channels are distributed to 13 virtual channels with the help of editable microopcodes, each sample has a maximum of 10 opcodes available for real-time calculations (mixing, sum calculation, reactive power and so on). These 13 virtual channels can then be combined into a maximum of 6 output groups. For more information about how AC current or three-phase current and power calculations works, [read here](https://en.wikipedia.org/wiki/Alternating_current) and [here](https://en.wikipedia.org/wiki/Three-phase_electric_power) 60 | 61 | # sensor hardware 62 | 63 | ## Sensors 64 | SCT013-000 current sensor (~100A)
65 | ![SCT013-000 current sensor (~100A)](data/SCT013-000.png) 66 | 67 | ZMPT101B voltage sensor (~250V)
68 | ![current sensor](data/ZMPT101B.png) 69 | 70 | ACS712 current sensor 5A, 20A and 30A
71 | ![current sensor](data/ACS712.png) 72 | 73 | simple voltage divider
74 | ![current sensor](data/voltage-div.png) 75 | 76 | For ratio calculation see inline documentation via webinterface. 77 | 78 | ## Display hardware 79 | Uncomment in "**display.cpp**" the line of the display you want to use
80 | ```c 81 | //#include 82 | //#include 83 | ``` 84 | 85 | # Interface 86 | 87 | ## live view 88 | ![live view](images/preview.gif) 89 | ## round trip 90 | ![round trip](images/live-view.gif) 91 | 92 | # contributors 93 | 94 | Every Contribution to this repository is highly welcome! Don't fear to create pull requests which enhance or fix the project, you are going to help everybody. 95 |

96 | If you want to donate to the author then you can buy me a coffee. 97 |

98 | 99 |

100 | -------------------------------------------------------------------------------- /data/ACS712.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/data/ACS712.jpg -------------------------------------------------------------------------------- /data/ACS712.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/data/ACS712.png -------------------------------------------------------------------------------- /data/SCT013-000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/data/SCT013-000.jpg -------------------------------------------------------------------------------- /data/SCT013-000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/data/SCT013-000.png -------------------------------------------------------------------------------- /data/ZMPT101B.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/data/ZMPT101B.jpg -------------------------------------------------------------------------------- /data/ZMPT101B.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/data/ZMPT101B.png -------------------------------------------------------------------------------- /data/bad_sin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/data/bad_sin.png -------------------------------------------------------------------------------- /data/display.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 26 |

display hardware settings

27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | 38 |
39 |
40 |
41 |
42 |
43 | 44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | 56 |
57 |
58 |

display info settings

59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | 69 |
70 |
71 |
72 |
73 |
74 | 75 |
76 |
77 |
78 |
79 |
80 | 81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 | 99 |
100 |
101 |
102 |
103 |
104 |

105 |
106 |
107 |
108 |
offline
109 | 110 | -------------------------------------------------------------------------------- /data/good_sin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/data/good_sin.png -------------------------------------------------------------------------------- /data/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 26 |

host settings

27 |
28 |
29 |
30 |
31 | 32 |
33 |
34 |
35 |
36 |
37 |

38 |
39 |
40 |
41 |
offline
42 | 43 | -------------------------------------------------------------------------------- /data/info.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 24 |
25 |
26 |
27 |
signalpath.png
28 |
29 |
© 2022 / Dirk Broßwick / Email: dirk.brosswick@googlemail.com
30 |
31 |
32 |
offline
33 | 34 | 35 | -------------------------------------------------------------------------------- /data/ioport.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 26 |

ioport channel settings

27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | 38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |

ioport hardware settings

47 |
48 |
49 |
50 | 51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |

ioport condition settings

66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | 82 |
83 |
84 |
85 |
86 |
87 |

88 |
89 |
90 |
91 |
offline
92 | 93 | -------------------------------------------------------------------------------- /data/live.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 26 |

live view

27 |
28 | 29 | 30 | 33 | 36 | 39 | 40 | 42 | 97 | 106 | 107 | 108 |
31 | 32 | 34 | 35 | 37 | 38 |
41 | 43 | 44 | zoom:
45 | 46 | 47 | 50 | 53 | 56 | 57 | 58 | 61 | 64 | 67 | 68 | 69 | 72 | 75 | 78 | 79 | 80 | 83 | 86 | 89 | 90 | 91 | 94 | 95 |
48 | 49 | 51 | 52 | 54 |
55 |
59 | 60 | 62 | 63 | 65 |
66 |
70 | 71 | 73 | 74 | 76 |
77 |
81 | 82 | 84 | 85 | 87 |
88 |
92 | 93 |
96 |
98 | samplerate:
99 | 100 |
101 | phaseshift: 102 | 103 | 104 | 105 |
109 |
110 |
offline
111 | 112 | 113 | -------------------------------------------------------------------------------- /data/mqtt.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 25 |

mqtt settings

26 |
27 |
28 |
29 |
30 | 31 |
32 |
33 |
34 |
35 |
36 | 37 |
38 |
39 |
40 |
41 |
42 | 43 |
44 |
45 |
46 |
47 |
48 | 49 |
50 |
51 |
52 |
53 |
54 | 55 |
56 |
57 |
58 |
59 |
60 | 61 |
62 |
63 |
64 | 65 |
66 |
67 |
68 |
69 |

70 |
71 |
72 |
73 |
offline
74 | 75 | 76 | -------------------------------------------------------------------------------- /data/script.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 3 | $.fn.menumaker = function(options) { 4 | 5 | var cssmenu = $(this), settings = $.extend({ 6 | title: "Menu", 7 | format: "dropdown", 8 | sticky: false 9 | }, options); 10 | 11 | return this.each(function() { 12 | cssmenu.prepend(''); 13 | $(this).find("#menu-button").on('click', function(){ 14 | $(this).toggleClass('menu-opened'); 15 | var mainmenu = $(this).next('ul'); 16 | if (mainmenu.hasClass('open')) { 17 | mainmenu.hide().removeClass('open'); 18 | } 19 | else { 20 | mainmenu.show().addClass('open'); 21 | if (settings.format === "dropdown") { 22 | mainmenu.find('ul').show(); 23 | } 24 | } 25 | }); 26 | 27 | cssmenu.find('li ul').parent().addClass('has-sub'); 28 | 29 | multiTg = function() { 30 | cssmenu.find(".has-sub").prepend(''); 31 | cssmenu.find('.submenu-button').on('click', function() { 32 | $(this).toggleClass('submenu-opened'); 33 | if ($(this).siblings('ul').hasClass('open')) { 34 | $(this).siblings('ul').removeClass('open').hide(); 35 | } 36 | else { 37 | $(this).siblings('ul').addClass('open').show(); 38 | } 39 | }); 40 | }; 41 | 42 | if (settings.format === 'multitoggle') multiTg(); 43 | else cssmenu.addClass('dropdown'); 44 | 45 | if (settings.sticky === true) cssmenu.css('position', 'fixed'); 46 | 47 | resizeFix = function() { 48 | if ($( window ).width() > 768) { 49 | cssmenu.find('ul').show(); 50 | } 51 | 52 | if ($(window).width() <= 768) { 53 | cssmenu.find('ul').hide().removeClass('open'); 54 | } 55 | }; 56 | resizeFix(); 57 | return $(window).on('resize', resizeFix); 58 | 59 | }); 60 | }; 61 | })(jQuery); 62 | 63 | (function($){ 64 | $(document).ready(function(){ 65 | 66 | $("#cssmenu").menumaker({ 67 | title: "powermeter", 68 | format: "multitoggle" 69 | }); 70 | 71 | }); 72 | })(jQuery); 73 | -------------------------------------------------------------------------------- /data/sensor.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 50 | 51 | 52 | 53 | 54 | 55 | 58 | 59 |
calculation
SCT013-000SCT013-000.jpgSCT013-000.png( ( turns / burden ) * 3.3V ) / 4096 = ratio
( ( 2000 / 62 ) * 3.3V ) / 4096 = 0.025989163
ZMPT101BZMPT101B.jpgZMPT101B.pngUnfortunately, it is not possible to give a precise figure here. First, the potentiometer should be adjusted so that the sine voltage to be measured is no longer consumed. It is important to use a high-impedance voltage divider, otherwise the sine voltage will be consumed even at low values (example: bad sine and good sine). The ratio 0.33 has proven to be a good starting point. This value should then be adjusted until the measured voltage matches the input voltage.
ACS712ACS712.jpgACS712.pngDatasheet

( 1A / ( V per Ampere ) x ( 5V / 4096 ) = ratio
5A variant: ( 1A / 0.185V ) x ( 5V / 4096 ) = 0.006598395
20A variant: ( 1A / 0.100V ) x ( 5V / 4096 ) = 0.012207031
30A variant: ( 1A / 0.066V ) x ( 5V / 4096 ) = 0.018495502
voltage dividervoltage-div.pngWith a simple voltage divider, you can also measure voltages greater than VCC (3.3V). If you want to measure voltage up to 36V, you can use an 11:1 (10k:1K) divider as in the example.

39 | 3.3V / ( R7 / ( R7 + R8 ) ) = voltage range
40 | example:
41 | 3.3V / ( 1k / ( 1k + 10k ) ) = 36.6V
42 | 3.3V / ( 2k / ( 2k + 10k ) ) = 19.8V
43 | 3.3V / ( 2k / ( 2k + 1k ) ) = 4.95V
44 | and the ratio:
45 | 3.3V / ( R7 / ( R7 + R8 ) ) / 4096 = ratio
46 | 3.3V / ( 1k / ( 1k + 10k ) ) / 4096 = 0.008862305 (36V)
47 | 3.3V / ( 2k / ( 2k + 10k ) ) / 4096 = 0,004833984 (19.8V)
48 | 3.3V / ( 2k / ( 2k + 1k ) ) / 4096 = 0,001208496 (4.95V)
49 |
direct voltageWithout a voltage divider, you can also measure voltages up to VCC (3.3V).

56 | 3.3V / 4096 = 0.000805664
57 |
60 |
61 |
© 2022 / Dirk Broßwick / Email: dirk.brosswick@googlemail.com
62 |
63 |
64 | 65 | 66 | -------------------------------------------------------------------------------- /data/signalpath.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/data/signalpath.png -------------------------------------------------------------------------------- /data/update.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 24 | 25 | 26 | 40 |
41 |
42 |

43 | 44 |
45 | 75 |
offline
76 | 77 | 78 | -------------------------------------------------------------------------------- /data/voltage-div.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/data/voltage-div.png -------------------------------------------------------------------------------- /data/wlan.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 26 |

Wlan settings

27 |
28 |
29 |
30 |
31 | 32 |
33 |
34 |
35 |
36 |
37 | 38 |
39 |
40 |
41 | 42 |
43 |
44 | 45 |
46 |
47 | 48 |
49 |
50 |
51 |
52 | 53 |
54 |
55 |
56 |
57 |
58 | 59 |
60 |
61 |
62 |
63 |
64 |

65 |
66 |
67 |
68 |
offline
69 | 70 | 71 | -------------------------------------------------------------------------------- /hardware/powermeter_supply/README.md: -------------------------------------------------------------------------------- 1 | # powermeter with supply 2 | 3 | Here is the simplest standalone powermeter with supply you can build with current and voltage measurement. 4 | 5 | ![](powermeter_schematic_low.png) 6 | 7 | ## eagle files 8 | 9 | [schematic](powermeter.sch)
10 | [board](powermeter.brd) 11 | 12 | ## bill of material 13 | 14 | 1 x 150x100x1mm 35µm FR4 [amazon](https://amzn.eu/d/hufknsN)
15 | esp32 D1 mini [amazon](https://amzn.eu/d/gZaocqF)
16 | ZMPT101 [amazon](https://amzn.eu/d/3shv3Ax)
17 | SCT-013-000 [amazon](https://amzn.eu/d/5wpwDs4)
18 | AC-05-03 ( 110-250V/AC -> 5V/DC ) [amazon](https://amzn.eu/d/ckoURve)
19 | 3.5mm jack [amazon](https://amzn.eu/d/a7YUG0G)
20 | MSTBA2 connector [amazon](https://amzn.eu/d/0bCERTn)
21 | 2 x 10k resistor
22 | 1 x 62R resistor
23 | 1 x 1M resistor
24 | 1 x 2M resistor
25 | 1 x 47µF cap
26 | 27 | ![](powermeter_top.png) 28 | 29 | ## gcode 30 | 31 | The G-code files are intended for Chilipeppr with a CNC3018 and contain everything. Engraving, drilling and cutting. There are two files. A normal one, where you should have your own gcode for tool change and length measurement and one with the appropriate gcode that also contains the length measurement. The reference point is X=0 and Y=0. 32 | 33 | A backlash-free Z-axis is very important for accurate engraving of the tracks and cutting out! 34 | 35 | The following tools are required: 36 | 37 | 0.1mm milling bit
38 | 0.6mm drill bit
39 | 0.9mm drill bit
40 | 1.2mm drill bit
41 | 1.3mm drill bit
42 | 1.4mm drill bit
43 | 2.0mm end mill
44 | 45 | Drag and drop the preferred gcode file into Chilipeppr. Autoleveling is a must. And then just press play. For the tool change, the program is paused at the appropriate position (M6). 46 | 47 | If everything has gone well, you are rewarded with a finished board without any post-processing and is ready to soldering. 48 | 49 | ![](powermeter_bottom.png) 50 | ![](powermeter_ChiliPeppr_low.png) 51 | ![](cnc_1.png) 52 | ![](cnc_2.png) 53 | 54 | ## config 55 | 56 | After soldering and software installtion (wifi,mqtt and so on) you can copy the content from config/measure.json to your powermeter. From here you can tweake the ratio settings for precise measuring via web interface under "channel settings". -------------------------------------------------------------------------------- /hardware/powermeter_supply/cnc_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/hardware/powermeter_supply/cnc_1.png -------------------------------------------------------------------------------- /hardware/powermeter_supply/cnc_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/hardware/powermeter_supply/cnc_2.png -------------------------------------------------------------------------------- /hardware/powermeter_supply/config/measure.json: -------------------------------------------------------------------------------- 1 | { 2 | "samplerate_corr": 146, 3 | "network_frequency": 50, 4 | "group": [ 5 | { 6 | "name": "L1", 7 | "active": true 8 | }, 9 | { 10 | "name": "L2", 11 | "active": false 12 | }, 13 | { 14 | "name": "L3", 15 | "active": false 16 | }, 17 | { 18 | "name": "all power", 19 | "active": false 20 | }, 21 | { 22 | "name": "unused", 23 | "active": false 24 | }, 25 | { 26 | "name": "unused", 27 | "active": false 28 | } 29 | ], 30 | "channel": [ 31 | { 32 | "name": "L1 current", 33 | "type": 0, 34 | "true_rms": true, 35 | "report_exp": 0, 36 | "offset": 0, 37 | "ratio": 0.023696, 38 | "phaseshift": 0, 39 | "group_id": 0, 40 | "mircocode": "55700000000000000000" 41 | }, 42 | { 43 | "name": "L1 voltage", 44 | "type": 1, 45 | "true_rms": true, 46 | "report_exp": 0, 47 | "offset": 0, 48 | "ratio": 0.412, 49 | "phaseshift": 16, 50 | "group_id": 0, 51 | "mircocode": "51750000000000000000" 52 | }, 53 | { 54 | "name": "L1 power", 55 | "type": 4, 56 | "true_rms": false, 57 | "report_exp": 3, 58 | "offset": 0, 59 | "ratio": 1, 60 | "phaseshift": 0, 61 | "group_id": 0, 62 | "mircocode": "6130318081a000000000" 63 | }, 64 | { 65 | "name": "L1 reactive power", 66 | "type": 5, 67 | "true_rms": false, 68 | "report_exp": 3, 69 | "offset": 0, 70 | "ratio": 1, 71 | "phaseshift": 0, 72 | "group_id": 0, 73 | "mircocode": "6130318081e0b1a0d000" 74 | }, 75 | { 76 | "name": "L2 current", 77 | "type": 0, 78 | "true_rms": true, 79 | "report_exp": 0, 80 | "offset": 0, 81 | "ratio": 0.025989, 82 | "phaseshift": 0, 83 | "group_id": 1, 84 | "mircocode": "51700000000000000000" 85 | }, 86 | { 87 | "name": "L2 voltage", 88 | "type": 1, 89 | "true_rms": true, 90 | "report_exp": 0, 91 | "offset": 0, 92 | "ratio": 0.324, 93 | "phaseshift": 30, 94 | "group_id": 1, 95 | "mircocode": "54700000000000000000" 96 | }, 97 | { 98 | "name": "L2 power", 99 | "type": 4, 100 | "true_rms": false, 101 | "report_exp": 3, 102 | "offset": 0, 103 | "ratio": 1, 104 | "phaseshift": 0, 105 | "group_id": 1, 106 | "mircocode": "6132338283a000000000" 107 | }, 108 | { 109 | "name": "L2 reactive power", 110 | "type": 5, 111 | "true_rms": false, 112 | "report_exp": 3, 113 | "offset": 0, 114 | "ratio": 1, 115 | "phaseshift": 0, 116 | "group_id": 1, 117 | "mircocode": "6132338283e0b5a0d000" 118 | }, 119 | { 120 | "name": "L3 current", 121 | "type": 0, 122 | "true_rms": true, 123 | "report_exp": 0, 124 | "offset": 0, 125 | "ratio": 0.025989, 126 | "phaseshift": 0, 127 | "group_id": 2, 128 | "mircocode": "52700000000000000000" 129 | }, 130 | { 131 | "name": "L3 voltage", 132 | "type": 1, 133 | "true_rms": true, 134 | "report_exp": 0, 135 | "offset": 0, 136 | "ratio": 0.324, 137 | "phaseshift": 30, 138 | "group_id": 2, 139 | "mircocode": "55700000000000000000" 140 | }, 141 | { 142 | "name": "L3 power", 143 | "type": 4, 144 | "true_rms": false, 145 | "report_exp": 3, 146 | "offset": 0, 147 | "ratio": 1, 148 | "phaseshift": 0, 149 | "group_id": 2, 150 | "mircocode": "6134358485a000000000" 151 | }, 152 | { 153 | "name": "L3 reactive power", 154 | "type": 5, 155 | "true_rms": false, 156 | "report_exp": 3, 157 | "offset": 0, 158 | "ratio": 1, 159 | "phaseshift": 0, 160 | "group_id": 2, 161 | "mircocode": "6134358485e0b9a0d000" 162 | }, 163 | { 164 | "name": "all power", 165 | "type": 4, 166 | "true_rms": false, 167 | "report_exp": 3, 168 | "offset": 0, 169 | "ratio": 1, 170 | "phaseshift": 0, 171 | "group_id": 3, 172 | "mircocode": "60101214000000000000" 173 | } 174 | ] 175 | } -------------------------------------------------------------------------------- /hardware/powermeter_supply/gocde/powermeter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/hardware/powermeter_supply/gocde/powermeter.png -------------------------------------------------------------------------------- /hardware/powermeter_supply/powermeter.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/hardware/powermeter_supply/powermeter.pdf -------------------------------------------------------------------------------- /hardware/powermeter_supply/powermeter.pro: -------------------------------------------------------------------------------- 1 | EAGLE AutoRouter Statistics: 2 | 3 | Job : /home/sharan/eagle/powermeter_supply/powermeter.brd 4 | 5 | Start at : 19:10:56 (29.10.22) 6 | End at : 19:10:56 (29.10.22) 7 | Elapsed time : 00:00:00 8 | 9 | Signals : 11 RoutingGrid: 12.5 mil Layers: 2 10 | Connections : 25 predefined: 25 ( 0 Vias ) 11 | 12 | Router memory : 267528 13 | 14 | Passname : Route Optimize1 Optimize2 Optimize3 Optimize4 15 | 16 | Time per pass : 00:00:00 00:00:00 00:00:00 00:00:00 00:00:00 17 | Number of Ripups : 0 0 0 0 0 18 | max. Level : 0 0 0 0 0 19 | max. Total : 0 0 0 0 0 20 | 21 | Routed : 0 0 0 0 0 22 | Vias : 0 0 0 0 0 23 | Resolution : 100.0 % 100.0 % 100.0 % 100.0 % 100.0 % 24 | 25 | Final : 100.0% beendet 26 | -------------------------------------------------------------------------------- /hardware/powermeter_supply/powermeter_ChiliPeppr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/hardware/powermeter_supply/powermeter_ChiliPeppr.png -------------------------------------------------------------------------------- /hardware/powermeter_supply/powermeter_ChiliPeppr_low.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/hardware/powermeter_supply/powermeter_ChiliPeppr_low.png -------------------------------------------------------------------------------- /hardware/powermeter_supply/powermeter_bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/hardware/powermeter_supply/powermeter_bottom.png -------------------------------------------------------------------------------- /hardware/powermeter_supply/powermeter_schematic.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/hardware/powermeter_supply/powermeter_schematic.pdf -------------------------------------------------------------------------------- /hardware/powermeter_supply/powermeter_schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/hardware/powermeter_supply/powermeter_schematic.png -------------------------------------------------------------------------------- /hardware/powermeter_supply/powermeter_schematic_low.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/hardware/powermeter_supply/powermeter_schematic_low.png -------------------------------------------------------------------------------- /hardware/powermeter_supply/powermeter_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/hardware/powermeter_supply/powermeter_top.png -------------------------------------------------------------------------------- /images/ACS712.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/images/ACS712.jpg -------------------------------------------------------------------------------- /images/ACS712.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/images/ACS712.png -------------------------------------------------------------------------------- /images/SCT013-000.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/images/SCT013-000.jpg -------------------------------------------------------------------------------- /images/SCT013-000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/images/SCT013-000.png -------------------------------------------------------------------------------- /images/ZMPT101B.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/images/ZMPT101B.jpg -------------------------------------------------------------------------------- /images/ZMPT101B.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/images/ZMPT101B.png -------------------------------------------------------------------------------- /images/live-view.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/images/live-view.gif -------------------------------------------------------------------------------- /images/live-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/images/live-view.png -------------------------------------------------------------------------------- /images/measurement-setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/images/measurement-setting.png -------------------------------------------------------------------------------- /images/mqtt-setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/images/mqtt-setting.png -------------------------------------------------------------------------------- /images/preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/images/preview.gif -------------------------------------------------------------------------------- /images/schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/images/schematic.png -------------------------------------------------------------------------------- /images/signalpath.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/images/signalpath.png -------------------------------------------------------------------------------- /images/voltage-div.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/images/voltage-div.png -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | trim_trailing_whitespace = true 10 | 11 | [keywords.txt] 12 | indent_style = tab 13 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/.github/workflows/build_examples_pio.yml: -------------------------------------------------------------------------------- 1 | name: Build with Platformio 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v1 12 | - name: Set up Python 13 | uses: actions/setup-python@v1 14 | - name: Install dependencies 15 | run: | 16 | python -m pip install --upgrade pip 17 | pip install platformio 18 | - name: Add libraries 19 | run: | 20 | platformio lib -g install AsyncTCP 21 | platformio lib -g install ESPAsyncTCP 22 | - name: Getting ready 23 | run: | 24 | chmod +x ./scripts/CI/build_examples_pio.sh 25 | - name: Build examples 26 | run: | 27 | ./scripts/CI/build_examples_pio.sh 28 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/.github/workflows/cpplint.yml: -------------------------------------------------------------------------------- 1 | name: cpplint 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v1 12 | - name: Set up Python 13 | uses: actions/setup-python@v1 14 | - name: Install dependencies 15 | run: | 16 | python -m pip install --upgrade pip 17 | pip install cpplint 18 | - name: Linting 19 | run: | 20 | cpplint --repository=. --recursive --filter=-whitespace/line_length,-legal/copyright,-runtime/printf,-build/include,-build/namespace ./src 21 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/.gitignore: -------------------------------------------------------------------------------- 1 | /config.json 2 | .vscode/ -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-2021 Marvin Roger 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/Makefile: -------------------------------------------------------------------------------- 1 | cpplint: 2 | cpplint --repository=. --recursive --filter=-whitespace/line_length,-legal/copyright,-runtime/printf,-build/include,-build/namespace ./src 3 | .PHONY: cpplint 4 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/README.md: -------------------------------------------------------------------------------- 1 | # Async MQTT client for ESP8266 and ESP32 2 | 3 | ![Build with PlatformIO](https://github.com/marvinroger/async-mqtt-client/workflows/Build%20with%20Platformio/badge.svg) 4 | ![cpplint](https://github.com/marvinroger/async-mqtt-client/workflows/cpplint/badge.svg) 5 | 6 | An Arduino for ESP8266 and ESP32 asynchronous [MQTT](http://mqtt.org/) client implementation, built on [me-no-dev/ESPAsyncTCP (ESP8266)](https://github.com/me-no-dev/ESPAsyncTCP) | [me-no-dev/AsyncTCP (ESP32)](https://github.com/me-no-dev/AsyncTCP) . 7 | 8 | ## Features 9 | 10 | * Compliant with the 3.1.1 version of the protocol 11 | * Fully asynchronous 12 | * Subscribe at QoS 0, 1 and 2 13 | * Publish at QoS 0, 1 and 2 14 | * SSL/TLS support 15 | * Available in the [PlatformIO registry](http://platformio.org/lib/show/346/AsyncMqttClient) 16 | 17 | ## Requirements, installation and usage 18 | 19 | The project is documented in the [/docs folder](docs). 20 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/async-mqtt-client.cppcheck: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/docs/1.-Getting-started.md: -------------------------------------------------------------------------------- 1 | # Getting started 2 | 3 | To use AsyncMqttClient, you need: 4 | 5 | * An ESP8266 or ESP32 6 | * The Arduino IDE or equivalent IDE for ESP8266/32 7 | * Basic knowledge of the Arduino environment (use the IDE, upload a sketch, import libraries, ...) 8 | 9 | ## Installing AsyncMqttClient 10 | 11 | There are two ways to install AsyncMqttClient. 12 | 13 | ### 1a. For the Arduino IDE 14 | 15 | 1. Download the [corresponding release](https://github.com/marvinroger/async-mqtt-client/releases/latest) 16 | 2. Load the `.zip` with **Sketch → Include Library → Add .ZIP Library** 17 | 18 | AsyncMqttClient has 1 dependency: 19 | * For ESP8266: [ESPAsyncTCP](https://github.com/me-no-dev/ESPAsyncTCP). Download the [.zip](https://github.com/me-no-dev/ESPAsyncTCP/archive/master.zip) and install it with the same method as above. 20 | * For ESP32: [AsyncTCP](https://github.com/me-no-dev/AsyncTCP). Download the [.zip](https://github.com/me-no-dev/AsyncTCP/archive/master.zip) and install it with the same method as above. 21 | 22 | ## Fully-featured sketch 23 | 24 | See [examples/FullyFeatured-ESP8266.ino](../examples/FullyFeatured-ESP8266/FullyFeatured-ESP8266.ino) 25 | 26 | **Very important: As a rule of thumb, never use blocking functions in the callbacks (don't use `delay()` or `yield()`).** Otherwise, you may very probably experience unexpected behaviors. 27 | 28 | You can go to the [API reference](2.-API-reference.md). 29 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/docs/2.-API-reference.md: -------------------------------------------------------------------------------- 1 | # API reference 2 | 3 | #### AsyncMqttClient() 4 | 5 | Instantiate a new AsyncMqttClient object. 6 | 7 | ### Configuration 8 | 9 | #### AsyncMqttClient& setKeepAlive(uint16_t `keepAlive`) 10 | 11 | Set the keep alive. Defaults to 15 seconds. 12 | 13 | * **`keepAlive`**: Keep alive in seconds 14 | 15 | #### AsyncMqttClient& setClientId(const char\* `clientId`) 16 | 17 | Set the client ID. Defaults to `esp8266`. 18 | 19 | * **`clientId`**: Client ID 20 | 21 | #### AsyncMqttClient& setCleanSession(bool `cleanSession`) 22 | 23 | Whether or not to set the CleanSession flag. Defaults to `true`. 24 | 25 | * **`cleanSession`**: clean session wanted or not 26 | 27 | #### AsyncMqttClient& setMaxTopicLength(uint16_t `maxTopicLength`) 28 | 29 | Set the maximum allowed topic length to receive. If an MQTT packet is received 30 | with a topic longer than this maximum, the packet will be ignored. Defaults to `128`. 31 | 32 | * **`maxTopicLength`**: Maximum allowed topic length to receive 33 | 34 | #### AsyncMqttClient& setCredentials(const char\* `username`, const char\* `password` = nullptr) 35 | 36 | Set the username/password. Defaults to non-auth. 37 | 38 | * **`username`**: Username 39 | * **`password`**: Password 40 | 41 | #### AsyncMqttClient& setWill(const char\* `topic`, uint8_t `qos`, bool `retain`, const char\* `payload` = nullptr, size_t `length` = 0) 42 | 43 | Set the Last Will Testament. Defaults to none. 44 | 45 | * **`topic`**: Topic of the LWT 46 | * **`qos`**: QoS of the LWT 47 | * **`retain`**: Retain flag of the LWT 48 | * **`payload`**: Payload of the LWT. If unset, the payload will be empty 49 | * **`length`**: Payload length. If unset or set to 0, the payload will be considered as a string and its size will be calculated using `strlen(payload)` 50 | 51 | #### AsyncMqttClient& setServer(IPAddress `ip`, uint16_t `port`) 52 | 53 | Set the server. 54 | 55 | * **`ip`**: IP of the server 56 | * **`port`**: Port of the server 57 | 58 | #### AsyncMqttClient& setServer(const char\* `host`, uint16_t `port`) 59 | 60 | Set the server. 61 | 62 | * **`host`**: Host of the server 63 | * **`port`**: Port of the server 64 | 65 | #### AsyncMqttClient& setSecure(bool `secure`) 66 | 67 | Whether or not to use SSL. Defaults to `false`. 68 | 69 | * **`secure`**: SSL wanted or not. 70 | 71 | #### AsyncMqttClient& addServerFingerprint(const uint8_t\* `fingerprint`) 72 | 73 | Adds an acceptable server fingerprint (SHA1). This may be called multiple times to permit any one of the specified fingerprints. By default, if no fingerprint is added, any fingerprint is accepted. 74 | 75 | * **`fingerprint`**: Fingerprint to add 76 | 77 | ### Events handlers 78 | 79 | #### AsyncMqttClient& onConnect(AsyncMqttClientInternals::OnConnectUserCallback `callback`) 80 | 81 | Add a connect event handler. 82 | 83 | * **`callback`**: Function to call 84 | 85 | #### AsyncMqttClient& onDisconnect(AsyncMqttClientInternals::OnDisconnectUserCallback `callback`) 86 | 87 | Add a disconnect event handler. 88 | 89 | * **`callback`**: Function to call 90 | 91 | #### AsyncMqttClient& onSubscribe(AsyncMqttClientInternals::OnSubscribeUserCallback `callback`) 92 | 93 | Add a subscribe acknowledged event handler. 94 | 95 | * **`callback`**: Function to call 96 | 97 | #### AsyncMqttClient& onUnsubscribe(AsyncMqttClientInternals::OnUnsubscribeUserCallback `callback`) 98 | 99 | Add an unsubscribe acknowledged event handler. 100 | 101 | * **`callback`**: Function to call 102 | 103 | #### AsyncMqttClient& onMessage(AsyncMqttClientInternals::OnMessageUserCallback `callback`) 104 | 105 | Add a publish received event handler. 106 | 107 | * **`callback`**: Function to call 108 | 109 | #### AsyncMqttClient& onPublish(AsyncMqttClientInternals::OnPublishUserCallback `callback`) 110 | 111 | Add a publish acknowledged event handler. 112 | 113 | * **`callback`**: Function to call 114 | 115 | ### Operation functions 116 | 117 | #### bool connected() 118 | 119 | Return if the client is currently connected to the broker or not. 120 | 121 | #### void connect() 122 | 123 | Connect to the server. 124 | 125 | #### void disconnect(bool `force` = false) 126 | 127 | Disconnect from the server. 128 | 129 | * **`force`**: Whether to force the disconnection. Defaults to `false` (clean disconnection). 130 | 131 | #### uint16_t subscribe(const char\* `topic`, uint8_t `qos`) 132 | 133 | Subscribe to the given topic at the given QoS. 134 | 135 | Return the packet ID or 0 if failed. 136 | 137 | * **`topic`**: Topic 138 | * **`qos`**: QoS 139 | 140 | #### uint16_t unsubscribe(const char\* `topic`) 141 | 142 | Unsubscribe from the given topic. 143 | 144 | Return the packet ID or 0 if failed. 145 | 146 | * **`topic`**: Topic 147 | 148 | #### uint16_t publish(const char\* `topic`, uint8_t `qos`, bool `retain`, const char\* `payload` = nullptr, size_t `length` = 0, bool dup = false, uint16_t message_id = 0) 149 | 150 | Publish a packet. 151 | 152 | Return the packet ID (or 1 if QoS 0) or 0 if failed. 153 | 154 | * **`topic`**: Topic 155 | * **`qos`**: QoS 156 | * **`retain`**: Retain flag 157 | * **`payload`**: Payload. If unset, the payload will be empty 158 | * **`length`**: Payload length. If unset or set to 0, the payload will be considered as a string and its size will be calculated using `strlen(payload)` 159 | * **`dup`**: ~~Duplicate flag. If set or set to 1, the payload will be flagged as a duplicate~~ Setting is not used anymore 160 | * **`message_id`**: ~~The message ID. If unset or set to 0, the message ID will be automtaically assigned. Use this with the DUP flag to identify which message is being duplicated~~ Setting is not used anymore 161 | 162 | #### bool clearQueue() 163 | 164 | When disconnected, clears all queued messages 165 | 166 | Returns true on succes, false on failure (client is no disconnected) 167 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/docs/3.-Memory-management.md: -------------------------------------------------------------------------------- 1 | # Memory management 2 | 3 | AsyncMqttClient buffers outgoing messages in a queue. On sending data is copied to a raw TCP buffer. Received data is passed directly to the API. 4 | 5 | ## Outgoing messages 6 | 7 | You can send data as long as memory permits. A minimum amount of free memory is set at 4096 bytes. You can lower (or raise) this value by setting `MQTT_MIN_FREE_MEMORY` to your desired value. 8 | If the free memory was sufficient to send your packet, the `publish` method will return a packet ID indicating the packet was queued. Otherwise, a `0` will be returned, and it's your responsability to resend the packet with `publish`. 9 | 10 | ## Incoming messages 11 | 12 | No incoming data is buffered by this library. Messages received by the TCP library is passed directly to the API. The max receive size is about 1460 bytes per call to your onMessage callback but the amount of data you can receive is unlimited. If you receive, say, a 300kB payload (such as an OTA payload), then your `onMessage` callback will be called about 200 times, with the according len, index and total parameters. Keep in mind the library will call your `onMessage` callbacks with the same topic buffer, so if you change the buffer on one call, the buffer will remain changed on subsequent calls. 13 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/docs/4.-Limitations-and-known-issues.md: -------------------------------------------------------------------------------- 1 | # Limitations and known issues 2 | 3 | * The library is spec compliant with one limitation. In case of power loss the following is not honored: 4 | 5 | > Must be kept in memory: 6 | * All messages in a QoS 1 or 2 flow, which are not confirmed by the broker 7 | * All received QoS 2 messages, which are not yet confirmed to the broker 8 | 9 | This means retransmission is not honored in case of a power failure. This behaviour is like explained in point 4.1.1 of the MQTT specification v3.1.1 10 | 11 | * You cannot send payload larger that what can fit on RAM. 12 | 13 | ## SSL limitations 14 | 15 | * SSL requires the build flag -DASYNC_TCP_SSL_ENABLED=1 16 | * SSL only supports fingerprints for server validation. 17 | * If you do not specify one or more acceptable server fingerprints, the SSL connection will be vulnerable to man-in-the-middle attacks. 18 | * Some server certificate signature algorithms do not work. SHA1, SHA224, SHA256, and MD5 are working. SHA384, and SHA512 will cause a crash. 19 | * TLS1.2 is not supported. 20 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/docs/5.-Troubleshooting.md: -------------------------------------------------------------------------------- 1 | # Troubleshooting 2 | 3 | * The payload of incoming messages contains **raw data**. You cannot just print out the data without formatting. This is because Arduino's `print` functions expect a C-string as input and a MQTT payload is not. A simple solution is to print each character of the payload: 4 | 5 | ```cpp 6 | for (size_t i = 0; i < len; ++i) { 7 | Serial.print(payload[i]); 8 | } 9 | ``` 10 | 11 | Further reading: https://en.wikipedia.org/wiki/C_string_handling 12 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/docs/README.md: -------------------------------------------------------------------------------- 1 | AsyncMqttClient documentation 2 | ============================= 3 | 4 | See [index.md](index.md) to view it locally, or http://marvinroger.viewdocs.io/async-mqtt-client/ to view it online. 5 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/docs/index.md: -------------------------------------------------------------------------------- 1 | Welcome to the AsyncMqttClient for ESP8266 docs. 2 | 3 | **

This documentation is only valid for the AsyncMqttClient version in this repo/directory

** 4 | 5 | ----- 6 | 7 | #### 1. [Getting started](1.-Getting-started.md) 8 | #### 2. [API reference](2.-API-reference.md) 9 | #### 3. [Memory management](3.-Memory-management.md) 10 | #### 4. [Limitations and known issues](4.-Limitations-and-known-issues.md) 11 | #### 5. [Troubleshooting](5.-Troubleshooting.md) 12 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/examples/FullyFeatured-ESP32/FullyFeatured-ESP32.ino: -------------------------------------------------------------------------------- 1 | /* 2 | This example uses FreeRTOS softwaretimers as there is no built-in Ticker library 3 | */ 4 | 5 | 6 | #include 7 | extern "C" { 8 | #include "freertos/FreeRTOS.h" 9 | #include "freertos/timers.h" 10 | } 11 | #include 12 | 13 | #define WIFI_SSID "yourSSID" 14 | #define WIFI_PASSWORD "yourpass" 15 | 16 | #define MQTT_HOST IPAddress(192, 168, 1, 10) 17 | #define MQTT_PORT 1883 18 | 19 | AsyncMqttClient mqttClient; 20 | TimerHandle_t mqttReconnectTimer; 21 | TimerHandle_t wifiReconnectTimer; 22 | 23 | void connectToWifi() { 24 | Serial.println("Connecting to Wi-Fi..."); 25 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 26 | } 27 | 28 | void connectToMqtt() { 29 | Serial.println("Connecting to MQTT..."); 30 | mqttClient.connect(); 31 | } 32 | 33 | void WiFiEvent(WiFiEvent_t event) { 34 | Serial.printf("[WiFi-event] event: %d\n", event); 35 | switch(event) { 36 | case SYSTEM_EVENT_STA_GOT_IP: 37 | Serial.println("WiFi connected"); 38 | Serial.println("IP address: "); 39 | Serial.println(WiFi.localIP()); 40 | connectToMqtt(); 41 | break; 42 | case SYSTEM_EVENT_STA_DISCONNECTED: 43 | Serial.println("WiFi lost connection"); 44 | xTimerStop(mqttReconnectTimer, 0); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi 45 | xTimerStart(wifiReconnectTimer, 0); 46 | break; 47 | } 48 | } 49 | 50 | void onMqttConnect(bool sessionPresent) { 51 | Serial.println("Connected to MQTT."); 52 | Serial.print("Session present: "); 53 | Serial.println(sessionPresent); 54 | uint16_t packetIdSub = mqttClient.subscribe("test/lol", 2); 55 | Serial.print("Subscribing at QoS 2, packetId: "); 56 | Serial.println(packetIdSub); 57 | mqttClient.publish("test/lol", 0, true, "test 1"); 58 | Serial.println("Publishing at QoS 0"); 59 | uint16_t packetIdPub1 = mqttClient.publish("test/lol", 1, true, "test 2"); 60 | Serial.print("Publishing at QoS 1, packetId: "); 61 | Serial.println(packetIdPub1); 62 | uint16_t packetIdPub2 = mqttClient.publish("test/lol", 2, true, "test 3"); 63 | Serial.print("Publishing at QoS 2, packetId: "); 64 | Serial.println(packetIdPub2); 65 | } 66 | 67 | void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) { 68 | Serial.println("Disconnected from MQTT."); 69 | 70 | if (WiFi.isConnected()) { 71 | xTimerStart(mqttReconnectTimer, 0); 72 | } 73 | } 74 | 75 | void onMqttSubscribe(uint16_t packetId, uint8_t qos) { 76 | Serial.println("Subscribe acknowledged."); 77 | Serial.print(" packetId: "); 78 | Serial.println(packetId); 79 | Serial.print(" qos: "); 80 | Serial.println(qos); 81 | } 82 | 83 | void onMqttUnsubscribe(uint16_t packetId) { 84 | Serial.println("Unsubscribe acknowledged."); 85 | Serial.print(" packetId: "); 86 | Serial.println(packetId); 87 | } 88 | 89 | void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) { 90 | Serial.println("Publish received."); 91 | Serial.print(" topic: "); 92 | Serial.println(topic); 93 | Serial.print(" qos: "); 94 | Serial.println(properties.qos); 95 | Serial.print(" dup: "); 96 | Serial.println(properties.dup); 97 | Serial.print(" retain: "); 98 | Serial.println(properties.retain); 99 | Serial.print(" len: "); 100 | Serial.println(len); 101 | Serial.print(" index: "); 102 | Serial.println(index); 103 | Serial.print(" total: "); 104 | Serial.println(total); 105 | } 106 | 107 | void onMqttPublish(uint16_t packetId) { 108 | Serial.println("Publish acknowledged."); 109 | Serial.print(" packetId: "); 110 | Serial.println(packetId); 111 | } 112 | 113 | void setup() { 114 | Serial.begin(115200); 115 | Serial.println(); 116 | Serial.println(); 117 | 118 | mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast(connectToMqtt)); 119 | wifiReconnectTimer = xTimerCreate("wifiTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast(connectToWifi)); 120 | 121 | WiFi.onEvent(WiFiEvent); 122 | 123 | mqttClient.onConnect(onMqttConnect); 124 | mqttClient.onDisconnect(onMqttDisconnect); 125 | mqttClient.onSubscribe(onMqttSubscribe); 126 | mqttClient.onUnsubscribe(onMqttUnsubscribe); 127 | mqttClient.onMessage(onMqttMessage); 128 | mqttClient.onPublish(onMqttPublish); 129 | mqttClient.setServer(MQTT_HOST, MQTT_PORT); 130 | 131 | connectToWifi(); 132 | } 133 | 134 | void loop() { 135 | } 136 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/examples/FullyFeatured-ESP8266/FullyFeatured-ESP8266.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define WIFI_SSID "My_Wi-Fi" 6 | #define WIFI_PASSWORD "my-awesome-password" 7 | 8 | #define MQTT_HOST IPAddress(192, 168, 1, 10) 9 | #define MQTT_PORT 1883 10 | 11 | AsyncMqttClient mqttClient; 12 | Ticker mqttReconnectTimer; 13 | 14 | WiFiEventHandler wifiConnectHandler; 15 | WiFiEventHandler wifiDisconnectHandler; 16 | Ticker wifiReconnectTimer; 17 | 18 | void connectToWifi() { 19 | Serial.println("Connecting to Wi-Fi..."); 20 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 21 | } 22 | 23 | void connectToMqtt() { 24 | Serial.println("Connecting to MQTT..."); 25 | mqttClient.connect(); 26 | } 27 | 28 | void onWifiConnect(const WiFiEventStationModeGotIP& event) { 29 | Serial.println("Connected to Wi-Fi."); 30 | connectToMqtt(); 31 | } 32 | 33 | void onWifiDisconnect(const WiFiEventStationModeDisconnected& event) { 34 | Serial.println("Disconnected from Wi-Fi."); 35 | mqttReconnectTimer.detach(); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi 36 | wifiReconnectTimer.once(2, connectToWifi); 37 | } 38 | 39 | void onMqttConnect(bool sessionPresent) { 40 | Serial.println("Connected to MQTT."); 41 | Serial.print("Session present: "); 42 | Serial.println(sessionPresent); 43 | uint16_t packetIdSub = mqttClient.subscribe("test/lol", 2); 44 | Serial.print("Subscribing at QoS 2, packetId: "); 45 | Serial.println(packetIdSub); 46 | mqttClient.publish("test/lol", 0, true, "test 1"); 47 | Serial.println("Publishing at QoS 0"); 48 | uint16_t packetIdPub1 = mqttClient.publish("test/lol", 1, true, "test 2"); 49 | Serial.print("Publishing at QoS 1, packetId: "); 50 | Serial.println(packetIdPub1); 51 | uint16_t packetIdPub2 = mqttClient.publish("test/lol", 2, true, "test 3"); 52 | Serial.print("Publishing at QoS 2, packetId: "); 53 | Serial.println(packetIdPub2); 54 | } 55 | 56 | void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) { 57 | Serial.println("Disconnected from MQTT."); 58 | 59 | if (WiFi.isConnected()) { 60 | mqttReconnectTimer.once(2, connectToMqtt); 61 | } 62 | } 63 | 64 | void onMqttSubscribe(uint16_t packetId, uint8_t qos) { 65 | Serial.println("Subscribe acknowledged."); 66 | Serial.print(" packetId: "); 67 | Serial.println(packetId); 68 | Serial.print(" qos: "); 69 | Serial.println(qos); 70 | } 71 | 72 | void onMqttUnsubscribe(uint16_t packetId) { 73 | Serial.println("Unsubscribe acknowledged."); 74 | Serial.print(" packetId: "); 75 | Serial.println(packetId); 76 | } 77 | 78 | void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) { 79 | Serial.println("Publish received."); 80 | Serial.print(" topic: "); 81 | Serial.println(topic); 82 | Serial.print(" qos: "); 83 | Serial.println(properties.qos); 84 | Serial.print(" dup: "); 85 | Serial.println(properties.dup); 86 | Serial.print(" retain: "); 87 | Serial.println(properties.retain); 88 | Serial.print(" len: "); 89 | Serial.println(len); 90 | Serial.print(" index: "); 91 | Serial.println(index); 92 | Serial.print(" total: "); 93 | Serial.println(total); 94 | } 95 | 96 | void onMqttPublish(uint16_t packetId) { 97 | Serial.println("Publish acknowledged."); 98 | Serial.print(" packetId: "); 99 | Serial.println(packetId); 100 | } 101 | 102 | void setup() { 103 | Serial.begin(115200); 104 | Serial.println(); 105 | Serial.println(); 106 | 107 | wifiConnectHandler = WiFi.onStationModeGotIP(onWifiConnect); 108 | wifiDisconnectHandler = WiFi.onStationModeDisconnected(onWifiDisconnect); 109 | 110 | mqttClient.onConnect(onMqttConnect); 111 | mqttClient.onDisconnect(onMqttDisconnect); 112 | mqttClient.onSubscribe(onMqttSubscribe); 113 | mqttClient.onUnsubscribe(onMqttUnsubscribe); 114 | mqttClient.onMessage(onMqttMessage); 115 | mqttClient.onPublish(onMqttPublish); 116 | mqttClient.setServer(MQTT_HOST, MQTT_PORT); 117 | 118 | connectToWifi(); 119 | } 120 | 121 | void loop() { 122 | } 123 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/examples/FullyFeaturedSSL/platformio.ini: -------------------------------------------------------------------------------- 1 | # 2 | # Example PlatformIO configuration file for SSL and non-SSL builds. 3 | # 4 | # Before you will be able to build the SSL version of this project, you will 5 | # need to explicitly install the espressif8266_stage platform. 6 | # 7 | # To perform this installation, refer to step 1 of: 8 | # http://docs.platformio.org/en/latest/platforms/espressif8266.html#using-arduino-framework-with-staging-version 9 | 10 | [platformio] 11 | env_default = ssl 12 | 13 | [env:ssl] 14 | platform = espressif8266_stage 15 | framework = arduino 16 | board = esp01_1m 17 | build_flags = -DASYNC_TCP_SSL_ENABLED=1 18 | lib_deps = AsyncMqttClient 19 | 20 | [env:nossl] 21 | platform = espressif8266 22 | framework = arduino 23 | board = esp01_1m 24 | lib_deps = AsyncMqttClient 25 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/examples/FullyFeaturedSSL/src/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Example project which can be built with SSL enabled or disabled. 3 | // The espressif8266_stage platform must be installed. 4 | // Refer to platformio.ini for the build configuration and platform installation. 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define WIFI_SSID "My_Wi-Fi" 12 | #define WIFI_PASSWORD "my-awesome-password" 13 | 14 | #define MQTT_HOST IPAddress(192, 168, 1, 10) 15 | 16 | #if ASYNC_TCP_SSL_ENABLED 17 | #define MQTT_SECURE true 18 | #define MQTT_SERVER_FINGERPRINT {0x7e, 0x36, 0x22, 0x01, 0xf9, 0x7e, 0x99, 0x2f, 0xc5, 0xdb, 0x3d, 0xbe, 0xac, 0x48, 0x67, 0x5b, 0x5d, 0x47, 0x94, 0xd2} 19 | #define MQTT_PORT 8883 20 | #else 21 | #define MQTT_PORT 1883 22 | #endif 23 | 24 | AsyncMqttClient mqttClient; 25 | Ticker mqttReconnectTimer; 26 | 27 | WiFiEventHandler wifiConnectHandler; 28 | WiFiEventHandler wifiDisconnectHandler; 29 | Ticker wifiReconnectTimer; 30 | 31 | void connectToWifi() { 32 | Serial.println("Connecting to Wi-Fi..."); 33 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 34 | } 35 | 36 | void connectToMqtt() { 37 | Serial.println("Connecting to MQTT..."); 38 | mqttClient.connect(); 39 | } 40 | 41 | void onWifiConnect(const WiFiEventStationModeGotIP& event) { 42 | Serial.println("Connected to Wi-Fi."); 43 | connectToMqtt(); 44 | } 45 | 46 | void onWifiDisconnect(const WiFiEventStationModeDisconnected& event) { 47 | Serial.println("Disconnected from Wi-Fi."); 48 | mqttReconnectTimer.detach(); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi 49 | wifiReconnectTimer.once(2, connectToWifi); 50 | } 51 | 52 | void onMqttConnect(bool sessionPresent) { 53 | Serial.println("Connected to MQTT."); 54 | Serial.print("Session present: "); 55 | Serial.println(sessionPresent); 56 | uint16_t packetIdSub = mqttClient.subscribe("test/lol", 2); 57 | Serial.print("Subscribing at QoS 2, packetId: "); 58 | Serial.println(packetIdSub); 59 | mqttClient.publish("test/lol", 0, true, "test 1"); 60 | Serial.println("Publishing at QoS 0"); 61 | uint16_t packetIdPub1 = mqttClient.publish("test/lol", 1, true, "test 2"); 62 | Serial.print("Publishing at QoS 1, packetId: "); 63 | Serial.println(packetIdPub1); 64 | uint16_t packetIdPub2 = mqttClient.publish("test/lol", 2, true, "test 3"); 65 | Serial.print("Publishing at QoS 2, packetId: "); 66 | Serial.println(packetIdPub2); 67 | } 68 | 69 | void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) { 70 | Serial.println("Disconnected from MQTT."); 71 | 72 | if (reason == AsyncMqttClientDisconnectReason::TLS_BAD_FINGERPRINT) { 73 | Serial.println("Bad server fingerprint."); 74 | } 75 | 76 | if (WiFi.isConnected()) { 77 | mqttReconnectTimer.once(2, connectToMqtt); 78 | } 79 | } 80 | 81 | void onMqttSubscribe(uint16_t packetId, uint8_t qos) { 82 | Serial.println("Subscribe acknowledged."); 83 | Serial.print(" packetId: "); 84 | Serial.println(packetId); 85 | Serial.print(" qos: "); 86 | Serial.println(qos); 87 | } 88 | 89 | void onMqttUnsubscribe(uint16_t packetId) { 90 | Serial.println("Unsubscribe acknowledged."); 91 | Serial.print(" packetId: "); 92 | Serial.println(packetId); 93 | } 94 | 95 | void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) { 96 | Serial.println("Publish received."); 97 | Serial.print(" topic: "); 98 | Serial.println(topic); 99 | Serial.print(" qos: "); 100 | Serial.println(properties.qos); 101 | Serial.print(" dup: "); 102 | Serial.println(properties.dup); 103 | Serial.print(" retain: "); 104 | Serial.println(properties.retain); 105 | Serial.print(" len: "); 106 | Serial.println(len); 107 | Serial.print(" index: "); 108 | Serial.println(index); 109 | Serial.print(" total: "); 110 | Serial.println(total); 111 | } 112 | 113 | void onMqttPublish(uint16_t packetId) { 114 | Serial.println("Publish acknowledged."); 115 | Serial.print(" packetId: "); 116 | Serial.println(packetId); 117 | } 118 | 119 | void setup() { 120 | Serial.begin(115200); 121 | Serial.println(); 122 | Serial.println(); 123 | 124 | wifiConnectHandler = WiFi.onStationModeGotIP(onWifiConnect); 125 | wifiDisconnectHandler = WiFi.onStationModeDisconnected(onWifiDisconnect); 126 | 127 | mqttClient.onConnect(onMqttConnect); 128 | mqttClient.onDisconnect(onMqttDisconnect); 129 | mqttClient.onSubscribe(onMqttSubscribe); 130 | mqttClient.onUnsubscribe(onMqttUnsubscribe); 131 | mqttClient.onMessage(onMqttMessage); 132 | mqttClient.onPublish(onMqttPublish); 133 | mqttClient.setServer(MQTT_HOST, MQTT_PORT); 134 | #if ASYNC_TCP_SSL_ENABLED 135 | mqttClient.setSecure(MQTT_SECURE); 136 | if (MQTT_SECURE) { 137 | mqttClient.addServerFingerprint((const uint8_t[])MQTT_SERVER_FINGERPRINT); 138 | } 139 | #endif 140 | 141 | connectToWifi(); 142 | } 143 | 144 | void loop() { 145 | } 146 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Datatypes (KEYWORD1) 3 | ####################################### 4 | 5 | AsyncMqttClient KEYWORD1 6 | AsyncMqttClientDisconnectReason KEYWORD1 7 | AsyncMqttClientMessageProperties KEYWORD1 8 | 9 | ####################################### 10 | # Methods and Functions (KEYWORD2) 11 | ####################################### 12 | 13 | setKeepAlive KEYWORD2 14 | setClientId KEYWORD2 15 | setCleanSession KEYWORD2 16 | setMaxTopicLength KEYWORD2 17 | setCredentials KEYWORD2 18 | setWill KEYWORD2 19 | setServer KEYWORD2 20 | setSecure KEYWORD2 21 | addServerFingerprint KEYWORD2 22 | 23 | onConnect KEYWORD2 24 | onDisconnect KEYWORD2 25 | onSubscribe KEYWORD2 26 | onUnsubscribe KEYWORD2 27 | onMessage KEYWORD2 28 | onPublish KEYWORD2 29 | 30 | connected KEYWORD2 31 | connect KEYWORD2 32 | disconnect KEYWORD2 33 | subscribe KEYWORD2 34 | unsubscribe KEYWORD2 35 | publish KEYWORD2 36 | clearQueue KEYWORD2 37 | 38 | ####################################### 39 | # Constants (LITERAL1) 40 | ####################################### 41 | 42 | TCP_DISCONNECTED LITERAL1 43 | 44 | MQTT_UNACCEPTABLE_PROTOCOL_VERSION LITERAL1 45 | MQTT_IDENTIFIER_REJECTED LITERAL1 46 | MQTT_SERVER_UNAVAILABLE LITERAL1 47 | MQTT_MALFORMED_CREDENTIALS LITERAL1 48 | MQTT_NOT_AUTHORIZED LITERAL1 49 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AsyncMqttClient", 3 | "keywords": "iot, home, automation, async, mqtt, client, esp8266", 4 | "description": "An Arduino for ESP8266 / ESP32 asynchronous MQTT client implementation", 5 | "authors": 6 | { 7 | "name": "Marvin ROGER", 8 | "url": "https://www.marvinroger.fr" 9 | }, 10 | "repository": 11 | { 12 | "type": "git", 13 | "url": "https://github.com/marvinroger/async-mqtt-client.git" 14 | }, 15 | "version": "0.9.0", 16 | "frameworks": "arduino", 17 | "platforms": ["espressif8266", "espressif32"], 18 | "dependencies": [ 19 | { 20 | "name": "ESPAsyncTCP", 21 | "version": ">=1.2.2", 22 | "platforms": "espressif8266" 23 | }, 24 | { 25 | "name": "AsyncTCP", 26 | "version": ">=1.1.1", 27 | "platforms": "espressif32" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/library.properties: -------------------------------------------------------------------------------- 1 | name=AsyncMqttClient 2 | version=0.9.0 3 | author=Marvin ROGER 4 | maintainer=Marvin ROGER 5 | sentence=An Arduino for ESP8266 and ESP32 asynchronous MQTT client implementation 6 | paragraph=Like this project? Please star it on GitHub! 7 | category=Communication 8 | url=https://github.com/marvinroger/async-mqtt-client 9 | architectures=esp8266,esp32 10 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/scripts/CI/build_examples_pio.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #pip install -U platformio 4 | #platformio update 5 | platformio lib -g install AsyncTCP 6 | platformio lib -g install ESPAsyncTCP 7 | 8 | RED='\033[0;31m' 9 | GREEN='\033[0;32m' 10 | YELLOW='\033[0;33m' 11 | NC='\033[0m' 12 | 13 | lines=$(find ./examples/ -maxdepth 1 -mindepth 1 -type d) 14 | retval=0 15 | while read line; do 16 | if [[ "$line" != *ESP8266 && "$line" != *ESP32 ]] 17 | then 18 | echo -e "========================== BUILDING $line ==========================" 19 | echo -e "${YELLOW}SKIPPING${NC}" 20 | continue 21 | fi 22 | echo -e "========================== BUILDING $line ==========================" 23 | if [[ -e "$line/platformio.ini" ]] 24 | then 25 | # skipping 26 | #output=$(platformio ci --lib="." --project-conf="$line/platformio.ini" $line 2>&1) 27 | : 28 | else 29 | if [[ "$line" == *ESP8266 ]] 30 | then 31 | output=$(platformio ci --lib="." --project-conf="scripts/CI/platformio_esp8266.ini" $line 2>&1) 32 | else 33 | output=$(platformio ci --lib="." --project-conf="scripts/CI/platformio_esp32.ini" $line 2>&1) 34 | fi 35 | fi 36 | if [ $? -ne 0 ]; then 37 | echo "$output" 38 | echo -e "Building $line ${RED}FAILED${NC}" 39 | retval=1 40 | else 41 | echo -e "${GREEN}SUCCESS${NC}" 42 | fi 43 | done <<< "$lines" 44 | 45 | # cleanup 46 | platformio lib -g uninstall AsyncTCP 47 | platformio lib -g uninstall ESPAsyncTCP 48 | 49 | exit "$retval" 50 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/scripts/CI/platformio_esp32.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [env:esp32] 12 | platform = espressif32 13 | board = esp32dev 14 | framework = arduino 15 | build_flags = 16 | -Wall -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/scripts/CI/platformio_esp8266.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [env:esp8266] 12 | platform = espressif8266 13 | board = esp01_1m 14 | framework = arduino 15 | build_flags = 16 | -Wall 17 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/scripts/get-fingerprint/get-fingerprint.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import argparse 4 | import ssl 5 | import hashlib 6 | 7 | parser = argparse.ArgumentParser(description='Compute SSL/TLS fingerprints.') 8 | parser.add_argument('--host', required=True) 9 | parser.add_argument('--port', default=8883) 10 | 11 | args = parser.parse_args() 12 | print(args.host) 13 | 14 | cert_pem = ssl.get_server_certificate((args.host, args.port)) 15 | cert_der = ssl.PEM_cert_to_DER_cert(cert_pem) 16 | 17 | md5 = hashlib.md5(cert_der).hexdigest() 18 | sha1 = hashlib.sha1(cert_der).hexdigest() 19 | sha256 = hashlib.sha256(cert_der).hexdigest() 20 | print("MD5: " + md5) 21 | print("SHA1: " + sha1) 22 | print("SHA256: " + sha256) 23 | 24 | print("\nSHA1 as array initializer:") 25 | print("const uint8_t fingerprint[] = {0x" + ", 0x".join([sha1[i:i+2] for i in range(0, len(sha1), 2)]) + "};") 26 | 27 | print("\nSHA1 as function call:") 28 | print("mqttClient.addServerFingerprint((const uint8_t[]){0x" + ", 0x".join([sha1[i:i+2] for i in range(0, len(sha1), 2)]) + "});") 29 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient.h: -------------------------------------------------------------------------------- 1 | #ifndef SRC_ASYNCMQTTCLIENT_H_ 2 | #define SRC_ASYNCMQTTCLIENT_H_ 3 | 4 | #include "AsyncMqttClient.hpp" 5 | 6 | #endif // SRC_ASYNCMQTTCLIENT_H_ 7 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "Arduino.h" 7 | 8 | #ifndef MQTT_MIN_FREE_MEMORY 9 | #define MQTT_MIN_FREE_MEMORY 4096 10 | #endif 11 | 12 | #ifdef ESP32 13 | #include 14 | #include 15 | #elif defined(ESP8266) 16 | #include 17 | #else 18 | #error Platform not supported 19 | #endif 20 | 21 | #if ASYNC_TCP_SSL_ENABLED 22 | #include 23 | #define SHA1_SIZE 20 24 | #endif 25 | 26 | #include "AsyncMqttClient/Flags.hpp" 27 | #include "AsyncMqttClient/ParsingInformation.hpp" 28 | #include "AsyncMqttClient/MessageProperties.hpp" 29 | #include "AsyncMqttClient/Helpers.hpp" 30 | #include "AsyncMqttClient/Callbacks.hpp" 31 | #include "AsyncMqttClient/DisconnectReasons.hpp" 32 | #include "AsyncMqttClient/Storage.hpp" 33 | 34 | #include "AsyncMqttClient/Packets/Packet.hpp" 35 | #include "AsyncMqttClient/Packets/ConnAckPacket.hpp" 36 | #include "AsyncMqttClient/Packets/PingRespPacket.hpp" 37 | #include "AsyncMqttClient/Packets/SubAckPacket.hpp" 38 | #include "AsyncMqttClient/Packets/UnsubAckPacket.hpp" 39 | #include "AsyncMqttClient/Packets/PublishPacket.hpp" 40 | #include "AsyncMqttClient/Packets/PubRelPacket.hpp" 41 | #include "AsyncMqttClient/Packets/PubAckPacket.hpp" 42 | #include "AsyncMqttClient/Packets/PubRecPacket.hpp" 43 | #include "AsyncMqttClient/Packets/PubCompPacket.hpp" 44 | 45 | #include "AsyncMqttClient/Packets/Out/Connect.hpp" 46 | #include "AsyncMqttClient/Packets/Out/PingReq.hpp" 47 | #include "AsyncMqttClient/Packets/Out/PubAck.hpp" 48 | #include "AsyncMqttClient/Packets/Out/Disconn.hpp" 49 | #include "AsyncMqttClient/Packets/Out/Subscribe.hpp" 50 | #include "AsyncMqttClient/Packets/Out/Unsubscribe.hpp" 51 | #include "AsyncMqttClient/Packets/Out/Publish.hpp" 52 | 53 | class AsyncMqttClient { 54 | public: 55 | AsyncMqttClient(); 56 | ~AsyncMqttClient(); 57 | 58 | AsyncMqttClient& setKeepAlive(uint16_t keepAlive); 59 | AsyncMqttClient& setClientId(const char* clientId); 60 | AsyncMqttClient& setCleanSession(bool cleanSession); 61 | AsyncMqttClient& setMaxTopicLength(uint16_t maxTopicLength); 62 | AsyncMqttClient& setCredentials(const char* username, const char* password = nullptr); 63 | AsyncMqttClient& setWill(const char* topic, uint8_t qos, bool retain, const char* payload = nullptr, size_t length = 0); 64 | AsyncMqttClient& setServer(IPAddress ip, uint16_t port); 65 | AsyncMqttClient& setServer(const char* host, uint16_t port); 66 | #if ASYNC_TCP_SSL_ENABLED 67 | AsyncMqttClient& setSecure(bool secure); 68 | AsyncMqttClient& addServerFingerprint(const uint8_t* fingerprint); 69 | #endif 70 | 71 | AsyncMqttClient& onConnect(AsyncMqttClientInternals::OnConnectUserCallback callback); 72 | AsyncMqttClient& onDisconnect(AsyncMqttClientInternals::OnDisconnectUserCallback callback); 73 | AsyncMqttClient& onSubscribe(AsyncMqttClientInternals::OnSubscribeUserCallback callback); 74 | AsyncMqttClient& onUnsubscribe(AsyncMqttClientInternals::OnUnsubscribeUserCallback callback); 75 | AsyncMqttClient& onMessage(AsyncMqttClientInternals::OnMessageUserCallback callback); 76 | AsyncMqttClient& onPublish(AsyncMqttClientInternals::OnPublishUserCallback callback); 77 | 78 | bool connected() const; 79 | void connect(); 80 | void disconnect(bool force = false); 81 | uint16_t subscribe(const char* topic, uint8_t qos); 82 | uint16_t unsubscribe(const char* topic); 83 | uint16_t publish(const char* topic, uint8_t qos, bool retain, const char* payload = nullptr, size_t length = 0, bool dup = false, uint16_t message_id = 0); 84 | bool clearQueue(); // Not MQTT compliant! 85 | 86 | const char* getClientId() const; 87 | 88 | private: 89 | AsyncClient _client; 90 | AsyncMqttClientInternals::OutPacket* _head; 91 | AsyncMqttClientInternals::OutPacket* _tail; 92 | size_t _sent; 93 | enum { 94 | CONNECTING, 95 | CONNECTED, 96 | DISCONNECTING, 97 | DISCONNECTED 98 | } _state; 99 | AsyncMqttClientDisconnectReason _disconnectReason; 100 | uint32_t _lastClientActivity; 101 | uint32_t _lastServerActivity; 102 | uint32_t _lastPingRequestTime; 103 | 104 | char _generatedClientId[18 + 1]; // esp8266-abc123 and esp32-abcdef123456 105 | IPAddress _ip; 106 | const char* _host; 107 | bool _useIp; 108 | #if ASYNC_TCP_SSL_ENABLED 109 | bool _secure; 110 | #endif 111 | uint16_t _port; 112 | uint16_t _keepAlive; 113 | bool _cleanSession; 114 | const char* _clientId; 115 | const char* _username; 116 | const char* _password; 117 | const char* _willTopic; 118 | const char* _willPayload; 119 | uint16_t _willPayloadLength; 120 | uint8_t _willQos; 121 | bool _willRetain; 122 | 123 | #if ASYNC_TCP_SSL_ENABLED 124 | std::vector> _secureServerFingerprints; 125 | #endif 126 | 127 | std::vector _onConnectUserCallbacks; 128 | std::vector _onDisconnectUserCallbacks; 129 | std::vector _onSubscribeUserCallbacks; 130 | std::vector _onUnsubscribeUserCallbacks; 131 | std::vector _onMessageUserCallbacks; 132 | std::vector _onPublishUserCallbacks; 133 | 134 | AsyncMqttClientInternals::ParsingInformation _parsingInformation; 135 | AsyncMqttClientInternals::Packet* _currentParsedPacket; 136 | uint8_t _remainingLengthBufferPosition; 137 | char _remainingLengthBuffer[4]; 138 | 139 | std::vector _pendingPubRels; 140 | 141 | #if defined(ESP32) 142 | SemaphoreHandle_t _xSemaphore = nullptr; 143 | #elif defined(ESP8266) 144 | bool _xSemaphore = false; 145 | #endif 146 | 147 | void _clear(); 148 | void _freeCurrentParsedPacket(); 149 | 150 | // TCP 151 | void _onConnect(); 152 | void _onDisconnect(); 153 | // void _onError(int8_t error); 154 | // void _onTimeout(); 155 | void _onAck(size_t len); 156 | void _onData(char* data, size_t len); 157 | void _onPoll(); 158 | 159 | // QUEUE 160 | void _insert(AsyncMqttClientInternals::OutPacket* packet); // for PUBREL 161 | void _addFront(AsyncMqttClientInternals::OutPacket* packet); // for CONNECT 162 | void _addBack(AsyncMqttClientInternals::OutPacket* packet); // all the rest 163 | void _handleQueue(); 164 | void _clearQueue(bool keepSessionData); 165 | 166 | // MQTT 167 | void _onPingResp(); 168 | void _onConnAck(bool sessionPresent, uint8_t connectReturnCode); 169 | void _onSubAck(uint16_t packetId, char status); 170 | void _onUnsubAck(uint16_t packetId); 171 | void _onMessage(char* topic, char* payload, uint8_t qos, bool dup, bool retain, size_t len, size_t index, size_t total, uint16_t packetId); 172 | void _onPublish(uint16_t packetId, uint8_t qos); 173 | void _onPubRel(uint16_t packetId); 174 | void _onPubAck(uint16_t packetId); 175 | void _onPubRec(uint16_t packetId); 176 | void _onPubComp(uint16_t packetId); 177 | 178 | void _sendPing(); 179 | }; 180 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Callbacks.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "DisconnectReasons.hpp" 6 | #include "MessageProperties.hpp" 7 | #include "Errors.hpp" 8 | 9 | namespace AsyncMqttClientInternals { 10 | // user callbacks 11 | typedef std::function OnConnectUserCallback; 12 | typedef std::function OnDisconnectUserCallback; 13 | typedef std::function OnSubscribeUserCallback; 14 | typedef std::function OnUnsubscribeUserCallback; 15 | typedef std::function OnMessageUserCallback; 16 | typedef std::function OnPublishUserCallback; 17 | typedef std::function OnErrorUserCallback; 18 | 19 | // internal callbacks 20 | typedef std::function OnConnAckInternalCallback; 21 | typedef std::function OnPingRespInternalCallback; 22 | typedef std::function OnSubAckInternalCallback; 23 | typedef std::function OnUnsubAckInternalCallback; 24 | typedef std::function OnMessageInternalCallback; 25 | typedef std::function OnPublishInternalCallback; 26 | typedef std::function OnPubRelInternalCallback; 27 | typedef std::function OnPubAckInternalCallback; 28 | typedef std::function OnPubRecInternalCallback; 29 | typedef std::function OnPubCompInternalCallback; 30 | } // namespace AsyncMqttClientInternals 31 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/DisconnectReasons.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum class AsyncMqttClientDisconnectReason : uint8_t { 4 | TCP_DISCONNECTED = 0, 5 | 6 | MQTT_UNACCEPTABLE_PROTOCOL_VERSION = 1, 7 | MQTT_IDENTIFIER_REJECTED = 2, 8 | MQTT_SERVER_UNAVAILABLE = 3, 9 | MQTT_MALFORMED_CREDENTIALS = 4, 10 | MQTT_NOT_AUTHORIZED = 5, 11 | 12 | ESP8266_NOT_ENOUGH_SPACE = 6, 13 | 14 | TLS_BAD_FINGERPRINT = 7 15 | }; 16 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Errors.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | enum class AsyncMqttClientError : uint8_t { 4 | MAX_RETRIES = 0, 5 | OUT_OF_MEMORY = 1 6 | }; 7 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Flags.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AsyncMqttClientInternals { 4 | constexpr struct { 5 | const uint8_t RESERVED = 0; 6 | const uint8_t CONNECT = 1; 7 | const uint8_t CONNACK = 2; 8 | const uint8_t PUBLISH = 3; 9 | const uint8_t PUBACK = 4; 10 | const uint8_t PUBREC = 5; 11 | const uint8_t PUBREL = 6; 12 | const uint8_t PUBCOMP = 7; 13 | const uint8_t SUBSCRIBE = 8; 14 | const uint8_t SUBACK = 9; 15 | const uint8_t UNSUBSCRIBE = 10; 16 | const uint8_t UNSUBACK = 11; 17 | const uint8_t PINGREQ = 12; 18 | const uint8_t PINGRESP = 13; 19 | const uint8_t DISCONNECT = 14; 20 | const uint8_t RESERVED2 = 1; 21 | } PacketType; 22 | 23 | constexpr struct { 24 | const uint8_t CONNECT_RESERVED = 0x00; 25 | const uint8_t CONNACK_RESERVED = 0x00; 26 | const uint8_t PUBLISH_DUP = 0x08; 27 | const uint8_t PUBLISH_QOS0 = 0x00; 28 | const uint8_t PUBLISH_QOS1 = 0x02; 29 | const uint8_t PUBLISH_QOS2 = 0x04; 30 | const uint8_t PUBLISH_QOSRESERVED = 0x06; 31 | const uint8_t PUBLISH_RETAIN = 0x01; 32 | const uint8_t PUBACK_RESERVED = 0x00; 33 | const uint8_t PUBREC_RESERVED = 0x00; 34 | const uint8_t PUBREL_RESERVED = 0x02; 35 | const uint8_t PUBCOMP_RESERVED = 0x00; 36 | const uint8_t SUBSCRIBE_RESERVED = 0x02; 37 | const uint8_t SUBACK_RESERVED = 0x00; 38 | const uint8_t UNSUBSCRIBE_RESERVED = 0x02; 39 | const uint8_t UNSUBACK_RESERVED = 0x00; 40 | const uint8_t PINGREQ_RESERVED = 0x00; 41 | const uint8_t PINGRESP_RESERVED = 0x00; 42 | const uint8_t DISCONNECT_RESERVED = 0x00; 43 | const uint8_t RESERVED2_RESERVED = 0x00; 44 | } HeaderFlag; 45 | 46 | constexpr struct { 47 | const uint8_t USERNAME = 0x80; 48 | const uint8_t PASSWORD = 0x40; 49 | const uint8_t WILL_RETAIN = 0x20; 50 | const uint8_t WILL_QOS0 = 0x00; 51 | const uint8_t WILL_QOS1 = 0x08; 52 | const uint8_t WILL_QOS2 = 0x10; 53 | const uint8_t WILL = 0x04; 54 | const uint8_t CLEAN_SESSION = 0x02; 55 | const uint8_t RESERVED = 0x00; 56 | } ConnectFlag; 57 | } // namespace AsyncMqttClientInternals 58 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Helpers.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AsyncMqttClientInternals { 4 | class Helpers { 5 | public: 6 | static uint32_t decodeRemainingLength(char* bytes) { 7 | uint32_t multiplier = 1; 8 | uint32_t value = 0; 9 | uint8_t currentByte = 0; 10 | uint8_t encodedByte; 11 | do { 12 | encodedByte = bytes[currentByte++]; 13 | value += (encodedByte & 127) * multiplier; 14 | multiplier *= 128; 15 | } while ((encodedByte & 128) != 0); 16 | 17 | return value; 18 | } 19 | 20 | static uint8_t encodeRemainingLength(uint32_t remainingLength, char* destination) { 21 | uint8_t currentByte = 0; 22 | uint8_t bytesNeeded = 0; 23 | 24 | do { 25 | uint8_t encodedByte = remainingLength % 128; 26 | remainingLength /= 128; 27 | if (remainingLength > 0) { 28 | encodedByte = encodedByte | 128; 29 | } 30 | 31 | destination[currentByte++] = encodedByte; 32 | bytesNeeded++; 33 | } while (remainingLength > 0); 34 | 35 | return bytesNeeded; 36 | } 37 | }; 38 | 39 | #if defined(ARDUINO_ARCH_ESP32) 40 | #define SEMAPHORE_TAKE() xSemaphoreTake(_xSemaphore, portMAX_DELAY) 41 | #define SEMAPHORE_GIVE() xSemaphoreGive(_xSemaphore) 42 | #define GET_FREE_MEMORY() ESP.getMaxAllocHeap() 43 | #include 44 | #elif defined(ARDUINO_ARCH_ESP8266) 45 | #define SEMAPHORE_TAKE(X) while (_xSemaphore) { /*ESP.wdtFeed();*/ } _xSemaphore = true 46 | #define SEMAPHORE_GIVE() _xSemaphore = false 47 | #define GET_FREE_MEMORY() ESP.getMaxFreeBlockSize() 48 | #if defined(DEBUG_ESP_PORT) && defined(DEBUG_ASYNC_MQTT_CLIENT) 49 | #define log_i(...) DEBUG_ESP_PORT.printf(__VA_ARGS__); DEBUG_ESP_PORT.print("\n") 50 | #define log_e(...) DEBUG_ESP_PORT.printf(__VA_ARGS__); DEBUG_ESP_PORT.print("\n") 51 | #define log_w(...) DEBUG_ESP_PORT.printf(__VA_ARGS__); DEBUG_ESP_PORT.print("\n") 52 | #else 53 | #define log_i(...) 54 | #define log_e(...) 55 | #define log_w(...) 56 | #endif 57 | #else 58 | #pragma error "No valid architecture" 59 | #endif 60 | 61 | } // namespace AsyncMqttClientInternals 62 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/MessageProperties.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct AsyncMqttClientMessageProperties { 4 | uint8_t qos; 5 | bool dup; 6 | bool retain; 7 | }; 8 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/ConnAckPacket.cpp: -------------------------------------------------------------------------------- 1 | #include "ConnAckPacket.hpp" 2 | 3 | using AsyncMqttClientInternals::ConnAckPacket; 4 | 5 | ConnAckPacket::ConnAckPacket(ParsingInformation* parsingInformation, OnConnAckInternalCallback callback) 6 | : _parsingInformation(parsingInformation) 7 | , _callback(callback) 8 | , _bytePosition(0) 9 | , _sessionPresent(false) 10 | , _connectReturnCode(0) { 11 | } 12 | 13 | ConnAckPacket::~ConnAckPacket() { 14 | } 15 | 16 | void ConnAckPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) { 17 | char currentByte = data[(*currentBytePosition)++]; 18 | if (_bytePosition++ == 0) { 19 | _sessionPresent = (currentByte << 7) >> 7; 20 | } else { 21 | _connectReturnCode = currentByte; 22 | _parsingInformation->bufferState = BufferState::NONE; 23 | _callback(_sessionPresent, _connectReturnCode); 24 | } 25 | } 26 | 27 | void ConnAckPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) { 28 | (void)data; 29 | (void)currentBytePosition; 30 | } 31 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/ConnAckPacket.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Arduino.h" 4 | #include "Packet.hpp" 5 | #include "../ParsingInformation.hpp" 6 | #include "../Callbacks.hpp" 7 | 8 | namespace AsyncMqttClientInternals { 9 | class ConnAckPacket : public Packet { 10 | public: 11 | explicit ConnAckPacket(ParsingInformation* parsingInformation, OnConnAckInternalCallback callback); 12 | ~ConnAckPacket(); 13 | 14 | void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition); 15 | void parsePayload(char* data, size_t len, size_t* currentBytePosition); 16 | 17 | private: 18 | ParsingInformation* _parsingInformation; 19 | OnConnAckInternalCallback _callback; 20 | 21 | uint8_t _bytePosition; 22 | bool _sessionPresent; 23 | uint8_t _connectReturnCode; 24 | }; 25 | } // namespace AsyncMqttClientInternals 26 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/Out/Connect.cpp: -------------------------------------------------------------------------------- 1 | #include "Connect.hpp" 2 | 3 | using AsyncMqttClientInternals::ConnectOutPacket; 4 | 5 | ConnectOutPacket::ConnectOutPacket(bool cleanSession, 6 | const char* username, 7 | const char* password, 8 | const char* willTopic, 9 | bool willRetain, 10 | uint8_t willQos, 11 | const char* willPayload, 12 | uint16_t willPayloadLength, 13 | uint16_t keepAlive, 14 | const char* clientId) { 15 | char fixedHeader[5]; 16 | fixedHeader[0] = AsyncMqttClientInternals::PacketType.CONNECT; 17 | fixedHeader[0] = fixedHeader[0] << 4; 18 | fixedHeader[0] = fixedHeader[0] | AsyncMqttClientInternals::HeaderFlag.CONNECT_RESERVED; 19 | 20 | uint16_t protocolNameLength = 4; 21 | char protocolNameLengthBytes[2]; 22 | protocolNameLengthBytes[0] = protocolNameLength >> 8; 23 | protocolNameLengthBytes[1] = protocolNameLength & 0xFF; 24 | 25 | char protocolLevel[1]; 26 | protocolLevel[0] = 0x04; 27 | 28 | char connectFlags[1]; 29 | connectFlags[0] = 0; 30 | if (cleanSession) connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.CLEAN_SESSION; 31 | if (username != nullptr) connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.USERNAME; 32 | if (password != nullptr) connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.PASSWORD; 33 | if (willTopic != nullptr) { 34 | connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.WILL; 35 | if (willRetain) connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.WILL_RETAIN; 36 | switch (willQos) { 37 | case 0: 38 | connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.WILL_QOS0; 39 | break; 40 | case 1: 41 | connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.WILL_QOS1; 42 | break; 43 | case 2: 44 | connectFlags[0] |= AsyncMqttClientInternals::ConnectFlag.WILL_QOS2; 45 | break; 46 | } 47 | } 48 | 49 | char keepAliveBytes[2]; 50 | keepAliveBytes[0] = keepAlive >> 8; 51 | keepAliveBytes[1] = keepAlive & 0xFF; 52 | 53 | uint16_t clientIdLength = strlen(clientId); 54 | char clientIdLengthBytes[2]; 55 | clientIdLengthBytes[0] = clientIdLength >> 8; 56 | clientIdLengthBytes[1] = clientIdLength & 0xFF; 57 | 58 | // Optional fields 59 | uint16_t willTopicLength = 0; 60 | char willTopicLengthBytes[2]; 61 | char willPayloadLengthBytes[2]; 62 | if (willTopic != nullptr) { 63 | willTopicLength = strlen(willTopic); 64 | willTopicLengthBytes[0] = willTopicLength >> 8; 65 | willTopicLengthBytes[1] = willTopicLength & 0xFF; 66 | 67 | if (willPayload != nullptr && willPayloadLength == 0) willPayloadLength = strlen(willPayload); 68 | 69 | willPayloadLengthBytes[0] = willPayloadLength >> 8; 70 | willPayloadLengthBytes[1] = willPayloadLength & 0xFF; 71 | } 72 | 73 | uint16_t usernameLength = 0; 74 | char usernameLengthBytes[2]; 75 | if (username != nullptr) { 76 | usernameLength = strlen(username); 77 | usernameLengthBytes[0] = usernameLength >> 8; 78 | usernameLengthBytes[1] = usernameLength & 0xFF; 79 | } 80 | 81 | uint16_t passwordLength = 0; 82 | char passwordLengthBytes[2]; 83 | if (password != nullptr) { 84 | passwordLength = strlen(password); 85 | passwordLengthBytes[0] = passwordLength >> 8; 86 | passwordLengthBytes[1] = passwordLength & 0xFF; 87 | } 88 | 89 | uint32_t remainingLength = 2 + protocolNameLength + 1 + 1 + 2 + 2 + clientIdLength; // always present 90 | if (willTopic != nullptr) remainingLength += 2 + willTopicLength + 2 + willPayloadLength; 91 | if (username != nullptr) remainingLength += 2 + usernameLength; 92 | if (password != nullptr) remainingLength += 2 + passwordLength; 93 | uint8_t remainingLengthLength = AsyncMqttClientInternals::Helpers::encodeRemainingLength(remainingLength, fixedHeader + 1); 94 | 95 | uint32_t neededSpace = 1 + remainingLengthLength; 96 | neededSpace += 2; 97 | neededSpace += protocolNameLength; 98 | neededSpace += 1; 99 | neededSpace += 1; 100 | neededSpace += 2; 101 | neededSpace += 2; 102 | neededSpace += clientIdLength; 103 | if (willTopic != nullptr) { 104 | neededSpace += 2; 105 | neededSpace += willTopicLength; 106 | 107 | neededSpace += 2; 108 | if (willPayload != nullptr) neededSpace += willPayloadLength; 109 | } 110 | if (username != nullptr) { 111 | neededSpace += 2; 112 | neededSpace += usernameLength; 113 | } 114 | if (password != nullptr) { 115 | neededSpace += 2; 116 | neededSpace += passwordLength; 117 | } 118 | 119 | _data.reserve(neededSpace); 120 | 121 | _data.insert(_data.end(), fixedHeader, fixedHeader + 1 + remainingLengthLength); 122 | 123 | _data.push_back(protocolNameLengthBytes[0]); 124 | _data.push_back(protocolNameLengthBytes[1]); 125 | 126 | _data.push_back('M'); 127 | _data.push_back('Q'); 128 | _data.push_back('T'); 129 | _data.push_back('T'); 130 | 131 | _data.push_back(protocolLevel[0]); 132 | _data.push_back(connectFlags[0]); 133 | _data.push_back(keepAliveBytes[0]); 134 | _data.push_back(keepAliveBytes[1]); 135 | _data.push_back(clientIdLengthBytes[0]); 136 | _data.push_back(clientIdLengthBytes[1]); 137 | 138 | _data.insert(_data.end(), clientId, clientId + clientIdLength); 139 | if (willTopic != nullptr) { 140 | _data.insert(_data.end(), willTopicLengthBytes, willTopicLengthBytes + 2); 141 | _data.insert(_data.end(), willTopic, willTopic + willTopicLength); 142 | 143 | _data.insert(_data.end(), willPayloadLengthBytes, willPayloadLengthBytes + 2); 144 | if (willPayload != nullptr) _data.insert(_data.end(), willPayload, willPayload + willPayloadLength); 145 | } 146 | if (username != nullptr) { 147 | _data.insert(_data.end(), usernameLengthBytes, usernameLengthBytes + 2); 148 | _data.insert(_data.end(), username, username + usernameLength); 149 | } 150 | if (password != nullptr) { 151 | _data.insert(_data.end(), passwordLengthBytes, passwordLengthBytes + 2); 152 | _data.insert(_data.end(), password, password + passwordLength); 153 | } 154 | } 155 | 156 | const uint8_t* ConnectOutPacket::data(size_t index) const { 157 | return &_data.data()[index]; 158 | } 159 | 160 | size_t ConnectOutPacket::size() const { 161 | return _data.size(); 162 | } 163 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/Out/Connect.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include // strlen 5 | 6 | #include "OutPacket.hpp" 7 | #include "../../Flags.hpp" 8 | #include "../../Helpers.hpp" 9 | 10 | namespace AsyncMqttClientInternals { 11 | class ConnectOutPacket : public OutPacket { 12 | public: 13 | ConnectOutPacket(bool cleanSession, 14 | const char* username, 15 | const char* password, 16 | const char* willTopic, 17 | bool willRetain, 18 | uint8_t willQos, 19 | const char* willPayload, 20 | uint16_t willPayloadLength, 21 | uint16_t keepAlive, 22 | const char* clientId); 23 | const uint8_t* data(size_t index = 0) const; 24 | size_t size() const; 25 | 26 | private: 27 | std::vector _data; 28 | }; 29 | } // namespace AsyncMqttClientInternals 30 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/Out/Disconn.cpp: -------------------------------------------------------------------------------- 1 | #include "Disconn.hpp" 2 | 3 | using AsyncMqttClientInternals::DisconnOutPacket; 4 | 5 | DisconnOutPacket::DisconnOutPacket() { 6 | _data[0] = AsyncMqttClientInternals::PacketType.DISCONNECT; 7 | _data[0] = _data[0] << 4; 8 | _data[0] = _data[0] | AsyncMqttClientInternals::HeaderFlag.DISCONNECT_RESERVED; 9 | _data[1] = 0; 10 | } 11 | 12 | const uint8_t* DisconnOutPacket::data(size_t index) const { 13 | return &_data[index]; 14 | } 15 | 16 | size_t DisconnOutPacket::size() const { 17 | return 2; 18 | } 19 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/Out/Disconn.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "OutPacket.hpp" 4 | #include "../../Flags.hpp" 5 | #include "../../Helpers.hpp" 6 | 7 | namespace AsyncMqttClientInternals { 8 | class DisconnOutPacket : public OutPacket { 9 | public: 10 | DisconnOutPacket(); 11 | const uint8_t* data(size_t index = 0) const; 12 | size_t size() const; 13 | 14 | private: 15 | uint8_t _data[2]; 16 | }; 17 | } // namespace AsyncMqttClientInternals 18 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/Out/OutPacket.cpp: -------------------------------------------------------------------------------- 1 | #include "OutPacket.hpp" 2 | 3 | using AsyncMqttClientInternals::OutPacket; 4 | 5 | OutPacket::OutPacket() 6 | : next(nullptr) 7 | , timeout(0) 8 | , noTries(0) 9 | , _released(true) 10 | , _packetId(0) {} 11 | 12 | OutPacket::~OutPacket() {} 13 | 14 | bool OutPacket::released() const { 15 | return _released; 16 | } 17 | 18 | uint8_t OutPacket::packetType() const { 19 | return data(0)[0] >> 4; 20 | } 21 | 22 | uint16_t OutPacket::packetId() const { 23 | return _packetId; 24 | } 25 | 26 | uint8_t OutPacket::qos() const { 27 | if (packetType() == AsyncMqttClientInternals::PacketType.PUBLISH) { 28 | return (data()[1] & 0x06) >> 1; 29 | } 30 | return 0; 31 | } 32 | 33 | void OutPacket::release() { 34 | _released = true; 35 | } 36 | 37 | uint16_t OutPacket::_nextPacketId = 0; 38 | 39 | uint16_t OutPacket::_getNextPacketId() { 40 | if (++_nextPacketId == 0) { 41 | ++_nextPacketId; 42 | } 43 | return _nextPacketId; 44 | } 45 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/Out/OutPacket.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // uint*_t 4 | #include // size_t 5 | #include // std::min 6 | 7 | #include "../../Flags.hpp" 8 | 9 | namespace AsyncMqttClientInternals { 10 | class OutPacket { 11 | public: 12 | OutPacket(); 13 | virtual ~OutPacket(); 14 | virtual const uint8_t* data(size_t index = 0) const = 0; 15 | virtual size_t size() const = 0; 16 | bool released() const; 17 | uint8_t packetType() const; 18 | uint16_t packetId() const; 19 | uint8_t qos() const; 20 | void release(); 21 | 22 | public: 23 | OutPacket* next; 24 | uint32_t timeout; 25 | uint8_t noTries; 26 | 27 | protected: 28 | static uint16_t _getNextPacketId(); 29 | bool _released; 30 | uint16_t _packetId; 31 | 32 | private: 33 | static uint16_t _nextPacketId; 34 | }; 35 | } // namespace AsyncMqttClientInternals 36 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/Out/PingReq.cpp: -------------------------------------------------------------------------------- 1 | #include "PingReq.hpp" 2 | 3 | using AsyncMqttClientInternals::PingReqOutPacket; 4 | 5 | PingReqOutPacket::PingReqOutPacket() { 6 | _data[0] = AsyncMqttClientInternals::PacketType.PINGREQ; 7 | _data[0] = _data[0] << 4; 8 | _data[0] = _data[0] | AsyncMqttClientInternals::HeaderFlag.PINGREQ_RESERVED; 9 | _data[1] = 0; 10 | } 11 | 12 | const uint8_t* PingReqOutPacket::data(size_t index) const { 13 | return &_data[index];; 14 | } 15 | 16 | size_t PingReqOutPacket::size() const { 17 | return 2; 18 | } 19 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/Out/PingReq.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "OutPacket.hpp" 4 | #include "../../Flags.hpp" 5 | #include "../../Helpers.hpp" 6 | 7 | namespace AsyncMqttClientInternals { 8 | class PingReqOutPacket : public OutPacket { 9 | public: 10 | PingReqOutPacket(); 11 | const uint8_t* data(size_t index = 0) const; 12 | size_t size() const; 13 | 14 | private: 15 | uint8_t _data[2]; 16 | }; 17 | } // namespace AsyncMqttClientInternals 18 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/Out/PubAck.cpp: -------------------------------------------------------------------------------- 1 | #include "PubAck.hpp" 2 | 3 | using AsyncMqttClientInternals::PubAckOutPacket; 4 | 5 | PubAckOutPacket::PubAckOutPacket(PendingAck pendingAck) { 6 | _data[0] = pendingAck.packetType; 7 | _data[0] = _data[0] << 4; 8 | _data[0] = _data[0] | pendingAck.headerFlag; 9 | _data[1] = 2; 10 | _packetId = pendingAck.packetId; 11 | _data[2] = pendingAck.packetId >> 8; 12 | _data[3] = pendingAck.packetId & 0xFF; 13 | if (packetType() == AsyncMqttClientInternals::PacketType.PUBREL || 14 | packetType() == AsyncMqttClientInternals::PacketType.PUBREC) { 15 | _released = false; 16 | } 17 | } 18 | 19 | const uint8_t* PubAckOutPacket::data(size_t index) const { 20 | return &_data[index]; 21 | } 22 | 23 | size_t PubAckOutPacket::size() const { 24 | return 4; 25 | } 26 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/Out/PubAck.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "OutPacket.hpp" 4 | #include "../../Flags.hpp" 5 | #include "../../Helpers.hpp" 6 | #include "../../Storage.hpp" 7 | 8 | namespace AsyncMqttClientInternals { 9 | class PubAckOutPacket : public OutPacket { 10 | public: 11 | explicit PubAckOutPacket(PendingAck pendingAck); 12 | const uint8_t* data(size_t index = 0) const; 13 | size_t size() const; 14 | 15 | private: 16 | uint8_t _data[4]; 17 | }; 18 | } // namespace AsyncMqttClientInternals 19 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/Out/Publish.cpp: -------------------------------------------------------------------------------- 1 | #include "Publish.hpp" 2 | 3 | using AsyncMqttClientInternals::PublishOutPacket; 4 | 5 | PublishOutPacket::PublishOutPacket(const char* topic, uint8_t qos, bool retain, const char* payload, size_t length) { 6 | char fixedHeader[5]; 7 | fixedHeader[0] = AsyncMqttClientInternals::PacketType.PUBLISH; 8 | fixedHeader[0] = fixedHeader[0] << 4; 9 | // if (dup) fixedHeader[0] |= AsyncMqttClientInternals::HeaderFlag.PUBLISH_DUP; 10 | if (retain) fixedHeader[0] |= AsyncMqttClientInternals::HeaderFlag.PUBLISH_RETAIN; 11 | switch (qos) { 12 | case 0: 13 | fixedHeader[0] |= AsyncMqttClientInternals::HeaderFlag.PUBLISH_QOS0; 14 | break; 15 | case 1: 16 | fixedHeader[0] |= AsyncMqttClientInternals::HeaderFlag.PUBLISH_QOS1; 17 | break; 18 | case 2: 19 | fixedHeader[0] |= AsyncMqttClientInternals::HeaderFlag.PUBLISH_QOS2; 20 | break; 21 | } 22 | 23 | uint16_t topicLength = strlen(topic); 24 | char topicLengthBytes[2]; 25 | topicLengthBytes[0] = topicLength >> 8; 26 | topicLengthBytes[1] = topicLength & 0xFF; 27 | 28 | uint32_t payloadLength = length; 29 | if (payload != nullptr && payloadLength == 0) payloadLength = strlen(payload); 30 | 31 | uint32_t remainingLength = 2 + topicLength + payloadLength; 32 | if (qos != 0) remainingLength += 2; 33 | uint8_t remainingLengthLength = AsyncMqttClientInternals::Helpers::encodeRemainingLength(remainingLength, fixedHeader + 1); 34 | 35 | size_t neededSpace = 0; 36 | neededSpace += 1 + remainingLengthLength; 37 | neededSpace += 2; 38 | neededSpace += topicLength; 39 | if (qos != 0) neededSpace += 2; 40 | if (payload != nullptr) neededSpace += payloadLength; 41 | 42 | _data.reserve(neededSpace); 43 | 44 | _packetId = (qos !=0) ? _getNextPacketId() : 1; 45 | char packetIdBytes[2]; 46 | packetIdBytes[0] = _packetId >> 8; 47 | packetIdBytes[1] = _packetId & 0xFF; 48 | 49 | _data.insert(_data.end(), fixedHeader, fixedHeader + 1 + remainingLengthLength); 50 | _data.insert(_data.end(), topicLengthBytes, topicLengthBytes + 2); 51 | _data.insert(_data.end(), topic, topic + topicLength); 52 | if (qos != 0) { 53 | _data.insert(_data.end(), packetIdBytes, packetIdBytes + 2); 54 | _released = false; 55 | } 56 | if (payload != nullptr) _data.insert(_data.end(), payload, payload + payloadLength); 57 | } 58 | 59 | const uint8_t* PublishOutPacket::data(size_t index) const { 60 | return &_data.data()[index]; 61 | } 62 | 63 | size_t PublishOutPacket::size() const { 64 | return _data.size(); 65 | } 66 | 67 | void PublishOutPacket::setDup() { 68 | _data[0] |= AsyncMqttClientInternals::HeaderFlag.PUBLISH_DUP; 69 | } 70 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/Out/Publish.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // strlen 4 | #include 5 | 6 | #include "OutPacket.hpp" 7 | #include "../../Flags.hpp" 8 | #include "../../Helpers.hpp" 9 | #include "../../Storage.hpp" 10 | 11 | namespace AsyncMqttClientInternals { 12 | class PublishOutPacket : public OutPacket { 13 | public: 14 | PublishOutPacket(const char* topic, uint8_t qos, bool retain, const char* payload, size_t length); 15 | const uint8_t* data(size_t index = 0) const; 16 | size_t size() const; 17 | 18 | void setDup(); // you cannot unset dup 19 | 20 | private: 21 | std::vector _data; 22 | }; 23 | } // namespace AsyncMqttClientInternals 24 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/Out/Subscribe.cpp: -------------------------------------------------------------------------------- 1 | #include "Subscribe.hpp" 2 | 3 | using AsyncMqttClientInternals::SubscribeOutPacket; 4 | 5 | SubscribeOutPacket::SubscribeOutPacket(const char* topic, uint8_t qos) { 6 | char fixedHeader[5]; 7 | fixedHeader[0] = AsyncMqttClientInternals::PacketType.SUBSCRIBE; 8 | fixedHeader[0] = fixedHeader[0] << 4; 9 | fixedHeader[0] = fixedHeader[0] | AsyncMqttClientInternals::HeaderFlag.SUBSCRIBE_RESERVED; 10 | 11 | uint16_t topicLength = strlen(topic); 12 | char topicLengthBytes[2]; 13 | topicLengthBytes[0] = topicLength >> 8; 14 | topicLengthBytes[1] = topicLength & 0xFF; 15 | 16 | char qosByte[1]; 17 | qosByte[0] = qos; 18 | 19 | uint8_t remainingLengthLength = AsyncMqttClientInternals::Helpers::encodeRemainingLength(2 + 2 + topicLength + 1, fixedHeader + 1); 20 | 21 | size_t neededSpace = 0; 22 | neededSpace += 1 + remainingLengthLength; 23 | neededSpace += 2; 24 | neededSpace += 2; 25 | neededSpace += topicLength; 26 | neededSpace += 1; 27 | 28 | _data.reserve(neededSpace); 29 | 30 | _packetId = _getNextPacketId(); 31 | char packetIdBytes[2]; 32 | packetIdBytes[0] = _packetId >> 8; 33 | packetIdBytes[1] = _packetId & 0xFF; 34 | 35 | _data.insert(_data.end(), fixedHeader, fixedHeader + 1 + remainingLengthLength); 36 | _data.insert(_data.end(), packetIdBytes, packetIdBytes + 2); 37 | _data.insert(_data.end(), topicLengthBytes, topicLengthBytes + 2); 38 | _data.insert(_data.end(), topic, topic + topicLength); 39 | _data.push_back(qosByte[0]); 40 | _released = false; 41 | } 42 | 43 | const uint8_t* SubscribeOutPacket::data(size_t index) const { 44 | return &_data.data()[index]; 45 | } 46 | 47 | size_t SubscribeOutPacket::size() const { 48 | return _data.size(); 49 | } 50 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/Out/Subscribe.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // strlen 4 | #include 5 | 6 | #include "OutPacket.hpp" 7 | #include "../../Flags.hpp" 8 | #include "../../Helpers.hpp" 9 | #include "../../Storage.hpp" 10 | 11 | namespace AsyncMqttClientInternals { 12 | class SubscribeOutPacket : public OutPacket { 13 | public: 14 | SubscribeOutPacket(const char* topic, uint8_t qos); 15 | const uint8_t* data(size_t index = 0) const; 16 | size_t size() const; 17 | 18 | private: 19 | std::vector _data; 20 | }; 21 | } // namespace AsyncMqttClientInternals 22 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/Out/Unsubscribe.cpp: -------------------------------------------------------------------------------- 1 | #include "Unsubscribe.hpp" 2 | 3 | using AsyncMqttClientInternals::UnsubscribeOutPacket; 4 | 5 | UnsubscribeOutPacket::UnsubscribeOutPacket(const char* topic) { 6 | char fixedHeader[5]; 7 | fixedHeader[0] = AsyncMqttClientInternals::PacketType.UNSUBSCRIBE; 8 | fixedHeader[0] = fixedHeader[0] << 4; 9 | fixedHeader[0] = fixedHeader[0] | AsyncMqttClientInternals::HeaderFlag.UNSUBSCRIBE_RESERVED; 10 | 11 | uint16_t topicLength = strlen(topic); 12 | char topicLengthBytes[2]; 13 | topicLengthBytes[0] = topicLength >> 8; 14 | topicLengthBytes[1] = topicLength & 0xFF; 15 | 16 | uint8_t remainingLengthLength = AsyncMqttClientInternals::Helpers::encodeRemainingLength(2 + 2 + topicLength, fixedHeader + 1); 17 | 18 | size_t neededSpace = 0; 19 | neededSpace += 1 + remainingLengthLength; 20 | neededSpace += 2; 21 | neededSpace += 2; 22 | neededSpace += topicLength; 23 | 24 | _packetId = _getNextPacketId(); 25 | char packetIdBytes[2]; 26 | packetIdBytes[0] = _packetId >> 8; 27 | packetIdBytes[1] = _packetId & 0xFF; 28 | 29 | _data.insert(_data.end(), fixedHeader, fixedHeader + 1 + remainingLengthLength); 30 | _data.insert(_data.end(), packetIdBytes, packetIdBytes + 2); 31 | _data.insert(_data.end(), topicLengthBytes, topicLengthBytes + 2); 32 | _data.insert(_data.end(), topic, topic + topicLength); 33 | _released = false; 34 | } 35 | 36 | const uint8_t* UnsubscribeOutPacket::data(size_t index) const { 37 | return &_data.data()[index]; 38 | } 39 | 40 | size_t UnsubscribeOutPacket::size() const { 41 | return _data.size(); 42 | } 43 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/Out/Unsubscribe.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include // strlen 4 | #include 5 | 6 | #include "OutPacket.hpp" 7 | #include "../../Flags.hpp" 8 | #include "../../Helpers.hpp" 9 | #include "../../Storage.hpp" 10 | 11 | namespace AsyncMqttClientInternals { 12 | class UnsubscribeOutPacket : public OutPacket { 13 | public: 14 | explicit UnsubscribeOutPacket(const char* topic); 15 | const uint8_t* data(size_t index = 0) const; 16 | size_t size() const; 17 | 18 | private: 19 | std::vector _data; 20 | }; 21 | } // namespace AsyncMqttClientInternals 22 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/Packet.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AsyncMqttClientInternals { 4 | class Packet { 5 | public: 6 | virtual ~Packet() {} 7 | 8 | virtual void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) = 0; 9 | virtual void parsePayload(char* data, size_t len, size_t* currentBytePosition) = 0; 10 | }; 11 | } // namespace AsyncMqttClientInternals 12 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/PingRespPacket.cpp: -------------------------------------------------------------------------------- 1 | #include "PingRespPacket.hpp" 2 | 3 | using AsyncMqttClientInternals::PingRespPacket; 4 | 5 | PingRespPacket::PingRespPacket(ParsingInformation* parsingInformation, OnPingRespInternalCallback callback) 6 | : _parsingInformation(parsingInformation) 7 | , _callback(callback) { 8 | } 9 | 10 | PingRespPacket::~PingRespPacket() { 11 | } 12 | 13 | void PingRespPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) { 14 | (void)data; 15 | (void)currentBytePosition; 16 | } 17 | 18 | void PingRespPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) { 19 | (void)data; 20 | (void)currentBytePosition; 21 | } 22 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/PingRespPacket.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Arduino.h" 4 | #include "Packet.hpp" 5 | #include "../ParsingInformation.hpp" 6 | #include "../Callbacks.hpp" 7 | 8 | namespace AsyncMqttClientInternals { 9 | class PingRespPacket : public Packet { 10 | public: 11 | explicit PingRespPacket(ParsingInformation* parsingInformation, OnPingRespInternalCallback callback); 12 | ~PingRespPacket(); 13 | 14 | void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition); 15 | void parsePayload(char* data, size_t len, size_t* currentBytePosition); 16 | 17 | private: 18 | ParsingInformation* _parsingInformation; 19 | OnPingRespInternalCallback _callback; 20 | }; 21 | } // namespace AsyncMqttClientInternals 22 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/PubAckPacket.cpp: -------------------------------------------------------------------------------- 1 | #include "PubAckPacket.hpp" 2 | 3 | using AsyncMqttClientInternals::PubAckPacket; 4 | 5 | PubAckPacket::PubAckPacket(ParsingInformation* parsingInformation, OnPubAckInternalCallback callback) 6 | : _parsingInformation(parsingInformation) 7 | , _callback(callback) 8 | , _bytePosition(0) 9 | , _packetIdMsb(0) 10 | , _packetId(0) { 11 | } 12 | 13 | PubAckPacket::~PubAckPacket() { 14 | } 15 | 16 | void PubAckPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) { 17 | char currentByte = data[(*currentBytePosition)++]; 18 | if (_bytePosition++ == 0) { 19 | _packetIdMsb = currentByte; 20 | } else { 21 | _packetId = currentByte | _packetIdMsb << 8; 22 | _parsingInformation->bufferState = BufferState::NONE; 23 | _callback(_packetId); 24 | } 25 | } 26 | 27 | void PubAckPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) { 28 | (void)data; 29 | (void)currentBytePosition; 30 | } 31 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/PubAckPacket.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Arduino.h" 4 | #include "Packet.hpp" 5 | #include "../ParsingInformation.hpp" 6 | #include "../Callbacks.hpp" 7 | 8 | namespace AsyncMqttClientInternals { 9 | class PubAckPacket : public Packet { 10 | public: 11 | explicit PubAckPacket(ParsingInformation* parsingInformation, OnPubAckInternalCallback callback); 12 | ~PubAckPacket(); 13 | 14 | void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition); 15 | void parsePayload(char* data, size_t len, size_t* currentBytePosition); 16 | 17 | private: 18 | ParsingInformation* _parsingInformation; 19 | OnPubAckInternalCallback _callback; 20 | 21 | uint8_t _bytePosition; 22 | char _packetIdMsb; 23 | uint16_t _packetId; 24 | }; 25 | } // namespace AsyncMqttClientInternals 26 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/PubCompPacket.cpp: -------------------------------------------------------------------------------- 1 | #include "PubCompPacket.hpp" 2 | 3 | using AsyncMqttClientInternals::PubCompPacket; 4 | 5 | PubCompPacket::PubCompPacket(ParsingInformation* parsingInformation, OnPubCompInternalCallback callback) 6 | : _parsingInformation(parsingInformation) 7 | , _callback(callback) 8 | , _bytePosition(0) 9 | , _packetIdMsb(0) 10 | , _packetId(0) { 11 | } 12 | 13 | PubCompPacket::~PubCompPacket() { 14 | } 15 | 16 | void PubCompPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) { 17 | char currentByte = data[(*currentBytePosition)++]; 18 | if (_bytePosition++ == 0) { 19 | _packetIdMsb = currentByte; 20 | } else { 21 | _packetId = currentByte | _packetIdMsb << 8; 22 | _parsingInformation->bufferState = BufferState::NONE; 23 | _callback(_packetId); 24 | } 25 | } 26 | 27 | void PubCompPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) { 28 | (void)data; 29 | (void)currentBytePosition; 30 | } 31 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/PubCompPacket.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Arduino.h" 4 | #include "Packet.hpp" 5 | #include "../ParsingInformation.hpp" 6 | #include "../Callbacks.hpp" 7 | 8 | namespace AsyncMqttClientInternals { 9 | class PubCompPacket : public Packet { 10 | public: 11 | explicit PubCompPacket(ParsingInformation* parsingInformation, OnPubCompInternalCallback callback); 12 | ~PubCompPacket(); 13 | 14 | void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition); 15 | void parsePayload(char* data, size_t len, size_t* currentBytePosition); 16 | 17 | private: 18 | ParsingInformation* _parsingInformation; 19 | OnPubCompInternalCallback _callback; 20 | 21 | uint8_t _bytePosition; 22 | char _packetIdMsb; 23 | uint16_t _packetId; 24 | }; 25 | } // namespace AsyncMqttClientInternals 26 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/PubRecPacket.cpp: -------------------------------------------------------------------------------- 1 | #include "PubRecPacket.hpp" 2 | 3 | using AsyncMqttClientInternals::PubRecPacket; 4 | 5 | PubRecPacket::PubRecPacket(ParsingInformation* parsingInformation, OnPubRecInternalCallback callback) 6 | : _parsingInformation(parsingInformation) 7 | , _callback(callback) 8 | , _bytePosition(0) 9 | , _packetIdMsb(0) 10 | , _packetId(0) { 11 | } 12 | 13 | PubRecPacket::~PubRecPacket() { 14 | } 15 | 16 | void PubRecPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) { 17 | char currentByte = data[(*currentBytePosition)++]; 18 | if (_bytePosition++ == 0) { 19 | _packetIdMsb = currentByte; 20 | } else { 21 | _packetId = currentByte | _packetIdMsb << 8; 22 | _parsingInformation->bufferState = BufferState::NONE; 23 | _callback(_packetId); 24 | } 25 | } 26 | 27 | void PubRecPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) { 28 | (void)data; 29 | (void)currentBytePosition; 30 | } 31 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/PubRecPacket.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Arduino.h" 4 | #include "Packet.hpp" 5 | #include "../ParsingInformation.hpp" 6 | #include "../Callbacks.hpp" 7 | 8 | namespace AsyncMqttClientInternals { 9 | class PubRecPacket : public Packet { 10 | public: 11 | explicit PubRecPacket(ParsingInformation* parsingInformation, OnPubRecInternalCallback callback); 12 | ~PubRecPacket(); 13 | 14 | void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition); 15 | void parsePayload(char* data, size_t len, size_t* currentBytePosition); 16 | 17 | private: 18 | ParsingInformation* _parsingInformation; 19 | OnPubRecInternalCallback _callback; 20 | 21 | uint8_t _bytePosition; 22 | char _packetIdMsb; 23 | uint16_t _packetId; 24 | }; 25 | } // namespace AsyncMqttClientInternals 26 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/PubRelPacket.cpp: -------------------------------------------------------------------------------- 1 | #include "PubRelPacket.hpp" 2 | 3 | using AsyncMqttClientInternals::PubRelPacket; 4 | 5 | PubRelPacket::PubRelPacket(ParsingInformation* parsingInformation, OnPubRelInternalCallback callback) 6 | : _parsingInformation(parsingInformation) 7 | , _callback(callback) 8 | , _bytePosition(0) 9 | , _packetIdMsb(0) 10 | , _packetId(0) { 11 | } 12 | 13 | PubRelPacket::~PubRelPacket() { 14 | } 15 | 16 | void PubRelPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) { 17 | char currentByte = data[(*currentBytePosition)++]; 18 | if (_bytePosition++ == 0) { 19 | _packetIdMsb = currentByte; 20 | } else { 21 | _packetId = currentByte | _packetIdMsb << 8; 22 | _parsingInformation->bufferState = BufferState::NONE; 23 | _callback(_packetId); 24 | } 25 | } 26 | 27 | void PubRelPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) { 28 | (void)data; 29 | (void)currentBytePosition; 30 | } 31 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/PubRelPacket.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Arduino.h" 4 | #include "Packet.hpp" 5 | #include "../ParsingInformation.hpp" 6 | #include "../Callbacks.hpp" 7 | 8 | namespace AsyncMqttClientInternals { 9 | class PubRelPacket : public Packet { 10 | public: 11 | explicit PubRelPacket(ParsingInformation* parsingInformation, OnPubRelInternalCallback callback); 12 | ~PubRelPacket(); 13 | 14 | void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition); 15 | void parsePayload(char* data, size_t len, size_t* currentBytePosition); 16 | 17 | private: 18 | ParsingInformation* _parsingInformation; 19 | OnPubRelInternalCallback _callback; 20 | 21 | uint8_t _bytePosition; 22 | char _packetIdMsb; 23 | uint16_t _packetId; 24 | }; 25 | } // namespace AsyncMqttClientInternals 26 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/PublishPacket.cpp: -------------------------------------------------------------------------------- 1 | #include "PublishPacket.hpp" 2 | 3 | using AsyncMqttClientInternals::PublishPacket; 4 | 5 | PublishPacket::PublishPacket(ParsingInformation* parsingInformation, OnMessageInternalCallback dataCallback, OnPublishInternalCallback completeCallback) 6 | : _parsingInformation(parsingInformation) 7 | , _dataCallback(dataCallback) 8 | , _completeCallback(completeCallback) 9 | , _dup(false) 10 | , _qos(0) 11 | , _retain(0) 12 | , _bytePosition(0) 13 | , _topicLengthMsb(0) 14 | , _topicLength(0) 15 | , _ignore(false) 16 | , _packetIdMsb(0) 17 | , _packetId(0) 18 | , _payloadLength(0) 19 | , _payloadBytesRead(0) { 20 | _dup = _parsingInformation->packetFlags & HeaderFlag.PUBLISH_DUP; 21 | _retain = _parsingInformation->packetFlags & HeaderFlag.PUBLISH_RETAIN; 22 | char qosMasked = _parsingInformation->packetFlags & 0x06; 23 | switch (qosMasked) { 24 | case HeaderFlag.PUBLISH_QOS0: 25 | _qos = 0; 26 | break; 27 | case HeaderFlag.PUBLISH_QOS1: 28 | _qos = 1; 29 | break; 30 | case HeaderFlag.PUBLISH_QOS2: 31 | _qos = 2; 32 | break; 33 | } 34 | } 35 | 36 | PublishPacket::~PublishPacket() { 37 | } 38 | 39 | void PublishPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) { 40 | char currentByte = data[(*currentBytePosition)++]; 41 | if (_bytePosition == 0) { 42 | _topicLengthMsb = currentByte; 43 | } else if (_bytePosition == 1) { 44 | _topicLength = currentByte | _topicLengthMsb << 8; 45 | if (_topicLength > _parsingInformation->maxTopicLength) { 46 | _ignore = true; 47 | } else { 48 | _parsingInformation->topicBuffer[_topicLength] = '\0'; 49 | } 50 | } else if (_bytePosition >= 2 && _bytePosition < 2 + _topicLength) { 51 | // Starting from here, _ignore might be true 52 | if (!_ignore) _parsingInformation->topicBuffer[_bytePosition - 2] = currentByte; 53 | if (_bytePosition == 2 + _topicLength - 1 && _qos == 0) { 54 | _preparePayloadHandling(_parsingInformation->remainingLength - (_bytePosition + 1)); 55 | return; 56 | } 57 | } else if (_bytePosition == 2 + _topicLength) { 58 | _packetIdMsb = currentByte; 59 | } else { 60 | _packetId = currentByte | _packetIdMsb << 8; 61 | _preparePayloadHandling(_parsingInformation->remainingLength - (_bytePosition + 1)); 62 | } 63 | _bytePosition++; 64 | } 65 | 66 | void PublishPacket::_preparePayloadHandling(uint32_t payloadLength) { 67 | _payloadLength = payloadLength; 68 | if (payloadLength == 0) { 69 | _parsingInformation->bufferState = BufferState::NONE; 70 | if (!_ignore) { 71 | _dataCallback(_parsingInformation->topicBuffer, nullptr, _qos, _dup, _retain, 0, 0, 0, _packetId); 72 | _completeCallback(_packetId, _qos); 73 | } 74 | } else { 75 | _parsingInformation->bufferState = BufferState::PAYLOAD; 76 | } 77 | } 78 | 79 | void PublishPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) { 80 | size_t remainToRead = len - (*currentBytePosition); 81 | if (_payloadBytesRead + remainToRead > _payloadLength) remainToRead = _payloadLength - _payloadBytesRead; 82 | 83 | if (!_ignore) _dataCallback(_parsingInformation->topicBuffer, data + (*currentBytePosition), _qos, _dup, _retain, remainToRead, _payloadBytesRead, _payloadLength, _packetId); 84 | _payloadBytesRead += remainToRead; 85 | (*currentBytePosition) += remainToRead; 86 | 87 | if (_payloadBytesRead == _payloadLength) { 88 | _parsingInformation->bufferState = BufferState::NONE; 89 | if (!_ignore) _completeCallback(_packetId, _qos); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/PublishPacket.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Arduino.h" 4 | #include "Packet.hpp" 5 | #include "../Flags.hpp" 6 | #include "../ParsingInformation.hpp" 7 | #include "../Callbacks.hpp" 8 | 9 | namespace AsyncMqttClientInternals { 10 | class PublishPacket : public Packet { 11 | public: 12 | explicit PublishPacket(ParsingInformation* parsingInformation, OnMessageInternalCallback dataCallback, OnPublishInternalCallback completeCallback); 13 | ~PublishPacket(); 14 | 15 | void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition); 16 | void parsePayload(char* data, size_t len, size_t* currentBytePosition); 17 | 18 | private: 19 | ParsingInformation* _parsingInformation; 20 | OnMessageInternalCallback _dataCallback; 21 | OnPublishInternalCallback _completeCallback; 22 | 23 | void _preparePayloadHandling(uint32_t payloadLength); 24 | 25 | bool _dup; 26 | uint8_t _qos; 27 | bool _retain; 28 | 29 | uint8_t _bytePosition; 30 | char _topicLengthMsb; 31 | uint16_t _topicLength; 32 | bool _ignore; 33 | char _packetIdMsb; 34 | uint16_t _packetId; 35 | uint32_t _payloadLength; 36 | uint32_t _payloadBytesRead; 37 | }; 38 | } // namespace AsyncMqttClientInternals 39 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/SubAckPacket.cpp: -------------------------------------------------------------------------------- 1 | #include "SubAckPacket.hpp" 2 | 3 | using AsyncMqttClientInternals::SubAckPacket; 4 | 5 | SubAckPacket::SubAckPacket(ParsingInformation* parsingInformation, OnSubAckInternalCallback callback) 6 | : _parsingInformation(parsingInformation) 7 | , _callback(callback) 8 | , _bytePosition(0) 9 | , _packetIdMsb(0) 10 | , _packetId(0) { 11 | } 12 | 13 | SubAckPacket::~SubAckPacket() { 14 | } 15 | 16 | void SubAckPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) { 17 | char currentByte = data[(*currentBytePosition)++]; 18 | if (_bytePosition++ == 0) { 19 | _packetIdMsb = currentByte; 20 | } else { 21 | _packetId = currentByte | _packetIdMsb << 8; 22 | _parsingInformation->bufferState = BufferState::PAYLOAD; 23 | } 24 | } 25 | 26 | void SubAckPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) { 27 | char status = data[(*currentBytePosition)++]; 28 | 29 | /* switch (status) { 30 | case 0: 31 | Serial.println("Success QoS 0"); 32 | break; 33 | case 1: 34 | Serial.println("Success QoS 1"); 35 | break; 36 | case 2: 37 | Serial.println("Success QoS 2"); 38 | break; 39 | case 0x80: 40 | Serial.println("Failure"); 41 | break; 42 | } */ 43 | 44 | _parsingInformation->bufferState = BufferState::NONE; 45 | _callback(_packetId, status); 46 | } 47 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/SubAckPacket.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Arduino.h" 4 | #include "Packet.hpp" 5 | #include "../ParsingInformation.hpp" 6 | #include "../Callbacks.hpp" 7 | 8 | namespace AsyncMqttClientInternals { 9 | class SubAckPacket : public Packet { 10 | public: 11 | explicit SubAckPacket(ParsingInformation* parsingInformation, OnSubAckInternalCallback callback); 12 | ~SubAckPacket(); 13 | 14 | void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition); 15 | void parsePayload(char* data, size_t len, size_t* currentBytePosition); 16 | 17 | private: 18 | ParsingInformation* _parsingInformation; 19 | OnSubAckInternalCallback _callback; 20 | 21 | uint8_t _bytePosition; 22 | char _packetIdMsb; 23 | uint16_t _packetId; 24 | }; 25 | } // namespace AsyncMqttClientInternals 26 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/UnsubAckPacket.cpp: -------------------------------------------------------------------------------- 1 | #include "UnsubAckPacket.hpp" 2 | 3 | using AsyncMqttClientInternals::UnsubAckPacket; 4 | 5 | UnsubAckPacket::UnsubAckPacket(ParsingInformation* parsingInformation, OnUnsubAckInternalCallback callback) 6 | : _parsingInformation(parsingInformation) 7 | , _callback(callback) 8 | , _bytePosition(0) 9 | , _packetIdMsb(0) 10 | , _packetId(0) { 11 | } 12 | 13 | UnsubAckPacket::~UnsubAckPacket() { 14 | } 15 | 16 | void UnsubAckPacket::parseVariableHeader(char* data, size_t len, size_t* currentBytePosition) { 17 | char currentByte = data[(*currentBytePosition)++]; 18 | if (_bytePosition++ == 0) { 19 | _packetIdMsb = currentByte; 20 | } else { 21 | _packetId = currentByte | _packetIdMsb << 8; 22 | _parsingInformation->bufferState = BufferState::NONE; 23 | _callback(_packetId); 24 | } 25 | } 26 | 27 | void UnsubAckPacket::parsePayload(char* data, size_t len, size_t* currentBytePosition) { 28 | (void)data; 29 | (void)currentBytePosition; 30 | } 31 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Packets/UnsubAckPacket.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Arduino.h" 4 | #include "Packet.hpp" 5 | #include "../ParsingInformation.hpp" 6 | #include "../Callbacks.hpp" 7 | 8 | namespace AsyncMqttClientInternals { 9 | class UnsubAckPacket : public Packet { 10 | public: 11 | explicit UnsubAckPacket(ParsingInformation* parsingInformation, OnUnsubAckInternalCallback callback); 12 | ~UnsubAckPacket(); 13 | 14 | void parseVariableHeader(char* data, size_t len, size_t* currentBytePosition); 15 | void parsePayload(char* data, size_t len, size_t* currentBytePosition); 16 | 17 | private: 18 | ParsingInformation* _parsingInformation; 19 | OnUnsubAckInternalCallback _callback; 20 | 21 | uint8_t _bytePosition; 22 | char _packetIdMsb; 23 | uint16_t _packetId; 24 | }; 25 | } // namespace AsyncMqttClientInternals 26 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/ParsingInformation.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AsyncMqttClientInternals { 4 | enum class BufferState : uint8_t { 5 | NONE = 0, 6 | REMAINING_LENGTH = 2, 7 | VARIABLE_HEADER = 3, 8 | PAYLOAD = 4 9 | }; 10 | 11 | struct ParsingInformation { 12 | BufferState bufferState; 13 | 14 | uint16_t maxTopicLength; 15 | char* topicBuffer; 16 | 17 | uint8_t packetType; 18 | uint16_t packetFlags; 19 | uint32_t remainingLength; 20 | }; 21 | } // namespace AsyncMqttClientInternals 22 | -------------------------------------------------------------------------------- /lib/async-mqtt-client-develop/src/AsyncMqttClient/Storage.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace AsyncMqttClientInternals { 4 | struct PendingPubRel { 5 | uint16_t packetId; 6 | }; 7 | 8 | struct PendingAck { 9 | uint8_t packetType; 10 | uint8_t headerFlag; 11 | uint16_t packetId; 12 | }; 13 | } // namespace AsyncMqttClientInternals 14 | -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [env:esp32dev] 12 | platform = espressif32@3.5.0 13 | board = esp32dev 14 | framework = arduino 15 | board_build.f_cpu = 240000000L 16 | board_build.f_flash = 80000000L 17 | board_build.flash_mode = qio 18 | lib_archive = true 19 | monitor_speed = 115200 20 | monitor_filters = 21 | default 22 | esp32_exception_decoder 23 | lib_deps = 24 | AsyncTCP@>=1.1.1 25 | ESP Async WebServer@>=1.2.0 26 | kosme/arduinoFFT@>=1.5.6 27 | ArduinoJson@>=6.15.2 28 | adafruit/Adafruit SSD1306 @ ^2.5.1 29 | adafruit/Adafruit SH110X @ ^2.1.8 30 | build_flags = 31 | -DCORE_DEBUG_LEVEL=3 32 | -mfix-esp32-psram-cache-issue 33 | -ffunction-sections 34 | -fdata-sections 35 | -Wl,--gc-sections 36 | -Os -------------------------------------------------------------------------------- /powermeter.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sharandac/powermeter/9de258164b17fa8030b47d2ee7b023b7635cd76a/powermeter.bin -------------------------------------------------------------------------------- /src/config.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file config.h 3 | * @author Dirk Broßwick (dirk.brosswick@googlemail.com) 4 | * @brief 5 | * @version 1.0 6 | * @date 2022-10-03 7 | * 8 | * @copyright Copyright (c) 2022 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | */ 24 | #ifndef _CONFIG_H 25 | #define _CONFIG_H 26 | 27 | #if CONFIG_FREERTOS_UNICORE 28 | 29 | #define _MEASURE_TASKCORE 1 30 | #define _MQTT_TASKCORE 1 31 | #define _WEBSOCK_TASKCORE 1 32 | #define _OTA_TASKCORE 1 33 | #define _WEBSERVER_TASKCORE 1 34 | #define _NTP_TASKCORE 1 35 | 36 | #else 37 | 38 | #define _MEASURE_TASKCORE 0 39 | #define _MQTT_TASKCORE 1 40 | #define _WEBSOCK_TASKCORE 1 41 | #define _OTA_TASKCORE 1 42 | #define _WEBSERVER_TASKCORE 1 43 | #define _NTP_TASKCORE 1 44 | 45 | #endif // CONFIG_FREERTOS_UNICORE 46 | /* 47 | * firmewareversion string 48 | */ 49 | #define __FIRMWARE__ "2022110101" 50 | 51 | #endif // _CONFIG_H 52 | -------------------------------------------------------------------------------- /src/config/display_config.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file display_config.cpp 3 | * @author Dirk Broßwick (dirk.brosswick@googlemail.com) 4 | * @brief 5 | * @version 1.0 6 | * @date 2022-10-03 7 | * 8 | * @copyright Copyright (c) 2022 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | */ 24 | #include "display_config.h" 25 | #include "measure.h" 26 | 27 | display_config_t::display_config_t() : BaseJsonConfig(DISPLAY_JSON_CONFIG_FILE) { 28 | } 29 | 30 | bool display_config_t::onSave(JsonDocument& doc) { 31 | doc["hardware"]["active"] = active; 32 | doc["hardware"]["sda"] = sda; 33 | doc["hardware"]["sck"] = sck; 34 | doc["hardware"]["flip"] = flip; 35 | doc["hardware"]["refreshinterval"] = refreshinterval; 36 | doc["infocount"] = DISPLAY_MAX_INFO; 37 | 38 | for( int i = 0 ; i < DISPLAY_MAX_INFO ; i++ ) { 39 | doc["info"][ i ]["info"] = i ; 40 | doc["info"][ i ]["name"] = displayinfo[ i ].name; 41 | doc["info"][ i ]["x"] = displayinfo[ i ].x; 42 | doc["info"][ i ]["y"] = displayinfo[ i ].y; 43 | doc["info"][ i ]["fontsize"] = displayinfo[ i ].fontsize; 44 | doc["info"][ i ]["value_channel"] = displayinfo[ i ].value_channel; 45 | doc["info"][ i ]["text"] = displayinfo[ i ].text; 46 | } 47 | 48 | return true; 49 | } 50 | 51 | bool display_config_t::onLoad(JsonDocument& doc) { 52 | active = doc["hardware"]["active"] | false; 53 | sda = doc["hardware"]["sda"] | 5; 54 | sck = doc["hardware"]["sck"] | 18; 55 | flip = doc["hardware"]["flip"] | false; 56 | refreshinterval = doc["hardware"]["refreshinterval"] | 5; 57 | infocount = doc["infocount"] | DISPLAY_MAX_INFO; 58 | 59 | for( int i = 0 ; i < DISPLAY_MAX_INFO ; i++ ) { 60 | 61 | int infonumber = doc["info"][ i ]["info"]; 62 | if ( infonumber >= DISPLAY_MAX_INFO ) 63 | continue; 64 | 65 | strncpy( displayinfo[ i ].name, doc["info"][ i ]["name"] | "", DISPLAY_MAX_INFO_TEXT_SIZE ); 66 | displayinfo[ infonumber ].x = doc["info"][ i ]["x"] | 0; 67 | displayinfo[ infonumber ].y = doc["info"][ i ]["y"] | 0; 68 | displayinfo[ infonumber ].fontsize = doc["info"][ i ]["fontsize"] | 0; 69 | displayinfo[ infonumber ].value_channel = doc["info"][ i ]["value_channel"] | 0; 70 | strncpy( displayinfo[ i ].text, doc["info"][ i ]["text"] | "", DISPLAY_MAX_INFO_TEXT_SIZE ); 71 | } 72 | 73 | return true; 74 | } 75 | 76 | bool display_config_t::onDefault( void ) { 77 | /* 78 | sda = 5; 79 | sck = 18; 80 | flip = false; 81 | refreshrate = 5; 82 | infocount = DISPLAY_MAX_INFO; 83 | 84 | for( int i = 0 ; i < DISPLAY_MAX_INFO ; i++ ) 85 | displayinfo[ i ].type = CHANNEL_NOT_USED; 86 | */ 87 | return true; 88 | } 89 | -------------------------------------------------------------------------------- /src/config/display_config.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file display_config.h 3 | * @author Dirk Broßwick (dirk.brosswick@googlemail.com) 4 | * @brief 5 | * @version 1.0 6 | * @date 2022-10-03 7 | * 8 | * @copyright Copyright (c) 2022 9 | * 10 | */ 11 | /* 12 | * This program is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation; either version 2 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License 23 | * along with this program; if not, write to the Free Software 24 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 25 | */ 26 | #ifndef _DISPLAY_CONFIG_H 27 | #define _DISPLAY_CONFIG_H 28 | 29 | #include "utils/basejsonconfig.h" 30 | 31 | #define DISPLAY_JSON_CONFIG_FILE "/display.json" /** @brief defines json config file name */ 32 | #define DISPLAY_MAX_INFO 6 33 | #define DISPLAY_MAX_INFO_TEXT_SIZE 32 34 | /** 35 | * @brief 36 | * 37 | */ 38 | typedef struct { 39 | char name[ DISPLAY_MAX_INFO_TEXT_SIZE ] = ""; 40 | int x = 0; 41 | int y = 0; 42 | uint16_t fontsize = 0; 43 | uint16_t value_channel = 0; 44 | char text[ DISPLAY_MAX_INFO_TEXT_SIZE ] = ""; 45 | } displayInfo_t; 46 | /** 47 | * @brief display config structure 48 | */ 49 | class display_config_t : public BaseJsonConfig { 50 | public: 51 | display_config_t(); 52 | bool active = false; 53 | int sda = 5; 54 | int sck = 18; 55 | bool flip = false; 56 | int refreshinterval = 5; 57 | int infocount = DISPLAY_MAX_INFO; 58 | displayInfo_t displayinfo[ DISPLAY_MAX_INFO ]; 59 | 60 | protected: 61 | ////////////// Available for overloading: ////////////// 62 | virtual bool onLoad(JsonDocument& document); 63 | virtual bool onSave(JsonDocument& document); 64 | virtual bool onDefault( void ); 65 | virtual size_t getJsonBufferSize() { return 2048; } 66 | }; 67 | #endif // _DISPLAYCONFIG_H 68 | -------------------------------------------------------------------------------- /src/config/ioport_config.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ioport_config.cpp 3 | * @author Dirk Broßwick (dirk.brosswick@googlemail.com) 4 | * @brief 5 | * @version 1.0 6 | * @date 2022-10-03 7 | * 8 | * @copyright Copyright (c) 2022 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | */ 24 | #include "ioport_config.h" 25 | #include "measure.h" 26 | 27 | ioport_config_t::ioport_config_t() : BaseJsonConfig( IOPORT_JSON_CONFIG_FILE ) { 28 | } 29 | 30 | bool ioport_config_t::onSave(JsonDocument& doc) { 31 | doc["ioportcount"] = IOPORT_MAX; 32 | 33 | for( int i = 0 ; i < IOPORT_MAX ; i++ ) { 34 | doc["ioport"][ i ]["info"] = i; 35 | doc["ioport"][ i ]["name"] = ioport[ i ].name; 36 | doc["ioport"][ i ]["start_state"] = ioport[ i ].start_state; 37 | doc["ioport"][ i ]["active"] = ioport[ i ].active; 38 | doc["ioport"][ i ]["gpio_pin_num"] = ioport[ i ].gpio_pin_num; 39 | doc["ioport"][ i ]["invert"] = ioport[ i ].invert; 40 | doc["ioport"][ i ]["value_channel"] = ioport[ i ].value_channel; 41 | doc["ioport"][ i ]["trigger"] = ioport[ i ].trigger; 42 | doc["ioport"][ i ]["value"] = ioport[ i ].value; 43 | } 44 | 45 | return true; 46 | } 47 | 48 | bool ioport_config_t::onLoad(JsonDocument& doc) { 49 | 50 | ioport_count = doc["ioportcount"];; 51 | 52 | for( int i = 0 ; i < IOPORT_MAX ; i++ ) { 53 | 54 | int infonumber = doc["ioport"][ i ]["info"]; 55 | if ( infonumber >= IOPORT_MAX ) 56 | continue; 57 | 58 | strncpy( ioport[ infonumber ].name, doc["ioport"][ i ]["name"], IOPORT_MAX_INFO_TEXT_SIZE ); 59 | ioport[ infonumber ].start_state = doc["ioport"][ i ]["start_state"]; 60 | ioport[ infonumber ].active = doc["ioport"][ i ]["active"]; 61 | ioport[ infonumber ].gpio_pin_num = doc["ioport"][ i ]["gpio_pin_num"]; 62 | ioport[ infonumber ].invert = doc["ioport"][ i ]["invert"]; 63 | ioport[ infonumber ].value_channel = doc["ioport"][ i ]["value_channel"]; 64 | ioport[ infonumber ].trigger = doc["ioport"][ i ]["trigger"]; 65 | ioport[ infonumber ].value = doc["ioport"][ i ]["value"]; 66 | } 67 | 68 | return true; 69 | } 70 | 71 | bool ioport_config_t::onDefault( void ) { 72 | /* 73 | sda = 5; 74 | sck = 18; 75 | flip = false; 76 | refreshrate = 5; 77 | infocount = DISPLAY_MAX_INFO; 78 | 79 | for( int i = 0 ; i < DISPLAY_MAX_INFO ; i++ ) 80 | displayinfo[ i ].type = CHANNEL_NOT_USED; 81 | */ 82 | return true; 83 | } 84 | -------------------------------------------------------------------------------- /src/config/ioport_config.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ioport_config.h 3 | * @author Dirk Broßwick (dirk.brosswick@googlemail.com) 4 | * @brief 5 | * @version 1.0 6 | * @date 2022-10-03 7 | * 8 | * @copyright Copyright (c) 2022 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | */ 24 | #ifndef _IOPORT_CONFIG_H 25 | #define _IOPORT_CONFIG_H 26 | 27 | #include "utils/basejsonconfig.h" 28 | 29 | typedef enum { 30 | IOPORT_TRIGGER_EQUAL = 0, 31 | IOPORT_TRIGGER_LOWER, 32 | IOPORT_TRIGGER_HIGHER, 33 | IOPORT_TRIGGER_FALLING_EDGE, 34 | IOPORT_TRIGGER_RAISING_EDGE 35 | } ioport_trigger_t; 36 | 37 | typedef enum { 38 | IOPORT_INACTIVE = 0, 39 | IOPORT_ACTIVE, 40 | } ioport_active_t; 41 | 42 | typedef enum { 43 | IOPORT_NORMAL = 0, 44 | IOPORT_INVERTED, 45 | } ioport_output_t; 46 | 47 | #define IOPORT_JSON_CONFIG_FILE "/ioport.json" /** @brief defines json config file name */ 48 | #define IOPORT_MAX 3 49 | #define IOPORT_MAX_INFO_TEXT_SIZE 32 50 | /** 51 | * @brief 52 | */ 53 | typedef struct { 54 | char name[ IOPORT_MAX_INFO_TEXT_SIZE ] = ""; 55 | ioport_active_t active; 56 | bool state; 57 | bool start_state; 58 | uint16_t gpio_pin_num; 59 | ioport_output_t invert; 60 | uint16_t value_channel; 61 | ioport_trigger_t trigger; 62 | float value; 63 | } ioport_t; 64 | /** 65 | * @brief ioport config structure 66 | */ 67 | class ioport_config_t : public BaseJsonConfig { 68 | public: 69 | ioport_config_t(); 70 | int ioport_count = IOPORT_MAX; 71 | ioport_t ioport[ IOPORT_MAX ]; 72 | 73 | protected: 74 | ////////////// Available for overloading: ////////////// 75 | virtual bool onLoad(JsonDocument& document); 76 | virtual bool onSave(JsonDocument& document); 77 | virtual bool onDefault( void ); 78 | virtual size_t getJsonBufferSize() { return 2048; } 79 | }; 80 | #endif // _IOPORT_CONFIG_H 81 | -------------------------------------------------------------------------------- /src/config/measure_config.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file measure_config.cpp 3 | * @author Dirk Broßwick (dirk.brosswick@googlemail.com) 4 | * @brief 5 | * @version 1.0 6 | * @date 2022-10-03 7 | * 8 | * @copyright Copyright (c) 2022 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | */ 24 | #include "measure_config.h" 25 | #include "measure.h" 26 | 27 | measure_config_t::measure_config_t() : BaseJsonConfig( MEASURE_JSON_CONFIG_FILE ) {} 28 | 29 | bool measure_config_t::onSave(JsonDocument& doc) { 30 | 31 | doc["samplerate_corr"] = samplerate_corr; 32 | doc["network_frequency"] = network_frequency; 33 | 34 | for( int i = 0 ; i < MAX_GROUPS ; i++ ) { 35 | doc["group"][ i ]["name"] = measure_get_group_name( i ); 36 | doc["group"][ i ]["active"] = measure_get_group_active( i ); 37 | } 38 | 39 | for( int i = 0 ; i < VIRTUAL_CHANNELS ; i++ ) { 40 | char microcode[ VIRTUAL_CHANNELS * 3 ] = ""; 41 | doc["channel"][ i ]["name"] = measure_get_channel_name( i ); 42 | doc["channel"][ i ]["type"] = measure_get_channel_type( i ); 43 | doc["channel"][ i ]["true_rms"] = measure_get_channel_true_rms( i ); 44 | doc["channel"][ i ]["report_exp"] = measure_get_channel_report_exp( i ); 45 | doc["channel"][ i ]["offset"] = measure_get_channel_offset( i ); 46 | doc["channel"][ i ]["ratio"] = measure_get_channel_ratio( i ); 47 | doc["channel"][ i ]["phaseshift"] = measure_get_channel_phaseshift( i ); 48 | doc["channel"][ i ]["group_id"] = measure_get_channel_group_id( i ); 49 | doc["channel"][ i ]["mircocode"] = measure_get_channel_opcodeseq_str( i, sizeof( microcode ), microcode ); 50 | } 51 | 52 | return true; 53 | } 54 | 55 | bool measure_config_t::onLoad(JsonDocument& doc) { 56 | 57 | samplerate_corr = doc["samplerate_corr"] | 0; 58 | network_frequency = doc["network_frequency"] | 50; 59 | 60 | for( int i = 0 ; i < MAX_GROUPS ; i++ ) { 61 | if( !doc["group"][ i ]["name"] ) 62 | continue; 63 | measure_set_group_name( i, doc["group"][ i ]["name"] ); 64 | measure_set_group_active( i, doc["group"][ i ]["active"] ); 65 | } 66 | 67 | for( int i = 0 ; i < VIRTUAL_CHANNELS ; i++ ) { 68 | measure_set_channel_name( i, (char*) doc["channel"][ i ]["name"].as().c_str() ); 69 | measure_set_channel_type( i, doc["channel"][ i ]["type"] | AC_CURRENT ); 70 | measure_set_channel_true_rms( i, doc["channel"][ i ]["true_rms"] | false ); 71 | measure_set_channel_report_exp( i, doc["channel"][ i ]["report_exp"] | 0 ); 72 | measure_set_channel_offset( i, doc["channel"][ i ]["offset"] | 0.0 ); 73 | measure_set_channel_ratio( i, doc["channel"][ i ]["ratio"] | 1.0); 74 | measure_set_channel_phaseshift( i, doc["channel"][ i ]["phaseshift"] | 0 ); 75 | measure_set_channel_group_id( i, doc["channel"][ i ]["group_id"] | 0 ); 76 | const char *opcodeseq_str = doc["channel"][ i ]["mircocode"].as().c_str() ; 77 | measure_set_channel_opcodeseq_str( i, opcodeseq_str ); 78 | } 79 | 80 | return true; 81 | } 82 | 83 | bool measure_config_t::onDefault( void ) { 84 | 85 | return true; 86 | } 87 | -------------------------------------------------------------------------------- /src/config/measure_config.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file measure_config.h 3 | * @author Dirk Broßwick (dirk.brosswick@googlemail.com) 4 | * @brief 5 | * @version 1.0 6 | * @date 2022-10-03 7 | * 8 | * @copyright Copyright (c) 2022 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | */ 24 | #ifndef _MEASURE_CONFIG_H 25 | #define _MEASURE_CONFIG_H 26 | 27 | #include "utils/basejsonconfig.h" 28 | 29 | #define MEASURE_JSON_CONFIG_FILE "/measure.json" /** @brief defines json config file name */ 30 | /** 31 | * @brief 32 | */ 33 | 34 | /** 35 | * @brief ioport config structure 36 | */ 37 | class measure_config_t : public BaseJsonConfig { 38 | public: 39 | measure_config_t(); 40 | float network_frequency = 50; 41 | int samplerate_corr = 0; 42 | bool true_rms = false; 43 | 44 | protected: 45 | ////////////// Available for overloading: ////////////// 46 | virtual bool onLoad(JsonDocument& document); 47 | virtual bool onSave(JsonDocument& document); 48 | virtual bool onDefault( void ); 49 | virtual size_t getJsonBufferSize() { return 8192; } 50 | }; 51 | #endif // _MEASURE_CONFIG_H 52 | -------------------------------------------------------------------------------- /src/config/mqtt_config.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file mqtt_config.cpp 3 | * @author Dirk Broßwick (dirk.brosswick@googlemail.com) 4 | * @brief 5 | * @version 1.0 6 | * @date 2022-10-03 7 | * 8 | * @copyright Copyright (c) 2022 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | */ 24 | #include "mqtt_config.h" 25 | #include "mqttclient.h" 26 | 27 | mqtt_config_t::mqtt_config_t() : BaseJsonConfig( MQTT_JSON_CONFIG_FILE ) { 28 | } 29 | 30 | bool mqtt_config_t::onSave(JsonDocument& doc) { 31 | 32 | doc["server"] = server; 33 | doc["port"] = port; 34 | doc["username"] = username; 35 | doc["password"] = password; 36 | doc["topic"] = topic; 37 | doc["interval"] = interval; 38 | doc["realtimestats"] = realtimestats; 39 | 40 | return true; 41 | } 42 | 43 | bool mqtt_config_t::onLoad(JsonDocument& doc) { 44 | 45 | strlcpy( server, doc["server"] | "", sizeof( server ) ); 46 | port = doc["port"] | 1883; 47 | strlcpy( username, doc["username"] | "", sizeof( username ) ); 48 | strlcpy( password, doc["password"] | "", sizeof( password ) ); 49 | strlcpy( topic, doc["topic"] | "", sizeof( topic ) ); 50 | interval = doc["interval"] | 15; 51 | realtimestats = doc["realtimestats"] | true; 52 | 53 | return true; 54 | } 55 | 56 | bool mqtt_config_t::onDefault( void ) { 57 | 58 | return true; 59 | } 60 | -------------------------------------------------------------------------------- /src/config/mqtt_config.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file mqtt_config.h 3 | * @author Dirk Broßwick (dirk.brosswick@googlemail.com) 4 | * @brief 5 | * @version 1.0 6 | * @date 2022-10-03 7 | * 8 | * @copyright Copyright (c) 2022 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | */ 24 | #ifndef _MQTT_CONFIG_H 25 | #define _MQTT_CONFIG_H 26 | 27 | #include "utils/basejsonconfig.h" 28 | 29 | #define MQTT_JSON_CONFIG_FILE "/mqtt.json" /** @brief defines json config file name */ 30 | /** 31 | * @brief 32 | */ 33 | #define MQTT_MAX_TEXT_SIZE 64 34 | /** 35 | * @brief ioport config structure 36 | */ 37 | class mqtt_config_t : public BaseJsonConfig { 38 | public: 39 | mqtt_config_t(); 40 | char server[ MQTT_MAX_TEXT_SIZE ] = ""; 41 | int port = 1883; 42 | char username[ MQTT_MAX_TEXT_SIZE ] = ""; 43 | char password[ MQTT_MAX_TEXT_SIZE ] = ""; 44 | char topic[ MQTT_MAX_TEXT_SIZE ] = ""; 45 | int interval = 15; 46 | bool realtimestats = true; 47 | 48 | protected: 49 | ////////////// Available for overloading: ////////////// 50 | virtual bool onLoad(JsonDocument& document); 51 | virtual bool onSave(JsonDocument& document); 52 | virtual bool onDefault( void ); 53 | virtual size_t getJsonBufferSize() { return 8192; } 54 | }; 55 | #endif // _MQTT_CONFIG_H 56 | -------------------------------------------------------------------------------- /src/config/wifi_config.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file wifi_config.cpp 3 | * @author Dirk Broßwick (dirk.brosswick@googlemail.com) 4 | * @brief 5 | * @version 1.0 6 | * @date 2022-10-03 7 | * 8 | * @copyright Copyright (c) 2022 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | */ 24 | #include 25 | #include "wifi_config.h" 26 | #include "wificlient.h" 27 | 28 | wificlient_config_t::wificlient_config_t() : BaseJsonConfig( WIFICLIENT_JSON_CONFIG_FILE ) { 29 | } 30 | 31 | bool wificlient_config_t::onSave(JsonDocument& doc) { 32 | 33 | doc["hostname"] = hostname; 34 | doc["ssid"] = ssid; 35 | doc["password"] = password; 36 | doc["enable_softap"] = enable_softap; 37 | doc["softap_ssid"] = softap_ssid; 38 | doc["softap_password"] = softap_password; 39 | doc["timeout"] = timeout; 40 | doc["low_bandwidth"] = low_bandwidth; 41 | doc["low_power"] = low_power; 42 | 43 | return true; 44 | } 45 | 46 | bool wificlient_config_t::onLoad(JsonDocument& doc) { 47 | /* 48 | * make an uniqe Hostname for the SoftAp SSID 49 | */ 50 | uint8_t mac[6]; 51 | char tmp_hostname[ WIFICLIENT_MAX_TEXT_SIZE] = ""; 52 | WiFi.macAddress( mac ); 53 | snprintf( tmp_hostname, sizeof( tmp_hostname ), "powermeter_%02x%02x%02x", mac[3], mac[4], mac[5] ); 54 | 55 | strlcpy( hostname, doc["hostname"] | tmp_hostname, sizeof( hostname ) ); 56 | strlcpy( ssid, doc["ssid"] | "", sizeof( ssid ) ); 57 | strlcpy( password, doc["password"] | "", sizeof( password ) ); 58 | enable_softap = doc["enable_softap"] | true; 59 | strlcpy( softap_ssid, doc["softap_ssid"] | tmp_hostname, sizeof( softap_ssid ) ); 60 | strlcpy( softap_password, doc["softap_password"] | "powermeter", sizeof( softap_password ) ); 61 | timeout = doc["timeout"] | 15; 62 | low_bandwidth = doc["low_bandwidth"] | false; 63 | low_power = doc["low_power"] | false; 64 | 65 | return true; 66 | } 67 | 68 | bool wificlient_config_t::onDefault( void ) { 69 | /* 70 | * make an uniqe Hostname for the SoftAp SSID 71 | */ 72 | uint8_t mac[6]; 73 | log_i("Write first config to SPIFFS\r\n"); 74 | WiFi.macAddress( mac ); 75 | snprintf( hostname, sizeof( hostname ), "powermeter_%02x%02x%02x", mac[3], mac[4], mac[5] ); 76 | snprintf( softap_ssid, sizeof( softap_ssid ), "powermeter_%02x%02x%02x", mac[3], mac[4], mac[5] ); 77 | 78 | return true; 79 | } 80 | -------------------------------------------------------------------------------- /src/config/wifi_config.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file wifi_config.h 3 | * @author Dirk Broßwick (dirk.brosswick@googlemail.com) 4 | * @brief 5 | * @version 1.0 6 | * @date 2022-10-03 7 | * 8 | * @copyright Copyright (c) 2022 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | */ 24 | #ifndef _WIFICLIENT_CONFIG_H 25 | #define _WIFICLIENT_CONFIG_H 26 | 27 | #include "utils/basejsonconfig.h" 28 | 29 | #define WIFICLIENT_JSON_CONFIG_FILE "/wifi.json" /** @brief defines json config file name */ 30 | /** 31 | * @brief 32 | */ 33 | #define WIFICLIENT_MAX_TEXT_SIZE 64 34 | /** 35 | * @brief ioport config structure 36 | */ 37 | class wificlient_config_t : public BaseJsonConfig { 38 | public: 39 | wificlient_config_t(); 40 | char hostname[ WIFICLIENT_MAX_TEXT_SIZE ] = "powermeter"; 41 | char ssid[ WIFICLIENT_MAX_TEXT_SIZE ] = ""; 42 | char password[ WIFICLIENT_MAX_TEXT_SIZE ] = ""; 43 | bool enable_softap = true; 44 | char softap_ssid[ WIFICLIENT_MAX_TEXT_SIZE ] = "powermeter"; 45 | char softap_password[ WIFICLIENT_MAX_TEXT_SIZE ] = "powermeter"; 46 | int timeout = 15; 47 | bool low_bandwidth = false; 48 | bool low_power = false; 49 | 50 | protected: 51 | ////////////// Available for overloading: ////////////// 52 | virtual bool onLoad(JsonDocument& document); 53 | virtual bool onSave(JsonDocument& document); 54 | virtual bool onDefault( void ); 55 | virtual size_t getJsonBufferSize() { return 8192; } 56 | }; 57 | #endif // _WIFICLIENT_CONFIG_H 58 | -------------------------------------------------------------------------------- /src/display.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file display.h 3 | * @author Dirk Broßwick (dirk.brosswick@googlemail.com) 4 | * @brief 5 | * @version 1.0 6 | * @date 2022-10-03 7 | * 8 | * @copyright Copyright (c) 2022 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | */ 24 | #ifndef _DISPLAY_H 25 | #define _DISPLAY_H 26 | 27 | #define SCREEN_WIDTH 128 28 | #define SCREEN_HEIGHT 64 29 | #define SCREEN_ADDRESS 0x3C 30 | /** 31 | * @brief SSD1306 display setup function 32 | */ 33 | void display_init( void ); 34 | /** 35 | * @brief display loop function 36 | */ 37 | void display_loop( void ); 38 | /** 39 | * @brief set display active/inactive 40 | * 41 | * @param active true measn active, false means inactive 42 | */ 43 | void display_set_active( bool active ); 44 | /** 45 | * @brief get display active/inactive state 46 | * 47 | * @return true active 48 | * @return false inactive 49 | */ 50 | bool display_get_active( void ); 51 | /** 52 | * @brief set display sda pin number 53 | * 54 | * @param pin sda pin number 55 | */ 56 | void display_set_sda_pin( int pin ); 57 | /** 58 | * @brief get display sda pin number 59 | * 60 | * @return pin number 61 | */ 62 | int display_get_sda_pin( void ); 63 | /** 64 | * @brief set display sck pin number 65 | * 66 | * @param pin sck pin number 67 | */ 68 | void display_set_sck_pin( int pin ); 69 | /** 70 | * @brief get display sck pin number 71 | * 72 | * @return pin number 73 | */ 74 | int display_get_sck_pin( void ); 75 | /** 76 | * @brief set display flip (rotate 180 degree) 77 | * 78 | * @param flip false no flip, true flip the display 79 | */ 80 | void display_set_flip( bool flip ); 81 | /** 82 | * @brief get display flip (rotate 180 degree) 83 | * 84 | * @return false no flip, true flip the display 85 | */ 86 | bool display_get_flip( void ); 87 | /** 88 | * @brief get display refresh interval 89 | * 90 | * @return int 91 | */ 92 | int display_get_refresh_interval( void ); 93 | /** 94 | * @brief set display refresh interval 95 | * 96 | * @param refresh_interval 97 | */ 98 | void display_set_refresh_interval( int refresh_interval ); 99 | /** 100 | * @brief get display infotext name 101 | * 102 | * @param channel display channel name 103 | * @return char* 104 | */ 105 | char *display_get_infotext_name( uint16_t channel ); 106 | /** 107 | * @brief set display infotext name 108 | * 109 | * @param channel display channel name 110 | * @param name 111 | */ 112 | void display_set_infotext_name( uint16_t channel, char *name ); 113 | /** 114 | * @brief get display infotext x coor 115 | * 116 | * @param channel dispplay channel number 117 | * @return int 118 | */ 119 | int display_get_infotext_x( uint16_t channel ); 120 | /** 121 | * @brief set display infotext x coor 122 | * 123 | * @param channel display channel number 124 | * @param x 125 | */ 126 | void display_set_infotext_x( uint16_t channel, int x ); 127 | /** 128 | * @brief get display infotext y coor 129 | * 130 | * @param channel dispplay channel number 131 | * @return int 132 | */ 133 | int display_get_infotext_y( uint16_t channel ); 134 | /** 135 | * @brief set display infotext y coor 136 | * 137 | * @param channel display channel number 138 | * @param x 139 | */ 140 | void display_set_infotext_y( uint16_t channel, int y); 141 | /** 142 | * @brief get infotext font size 143 | * 144 | * @param channel display channel number 145 | * @return int 146 | */ 147 | int display_get_infotext_fontsize( uint16_t channel ); 148 | /** 149 | * @brief set display infotext font size 150 | * 151 | * @param channel display channel number 152 | * @param fontsize fontsize from 0-2 153 | */ 154 | void display_set_infotext_fontsize( uint16_t channel, int fontsize ); 155 | /** 156 | * @brief get display infotext value channel 157 | * 158 | * @param channel display channel number 159 | * @return int value channel number 160 | */ 161 | int display_get_infotext_value_channel( uint16_t channel ); 162 | /** 163 | * @brief set display infotext value channel 164 | * 165 | * @param channel display channel number 166 | * @param value_channel value channel number 167 | */ 168 | void display_set_infotext_value_channel( uint16_t channel, uint16_t value_channel ); 169 | /** 170 | * @brief get display infotext prefix text 171 | * 172 | * @param channel display channel number 173 | * @return char* 174 | */ 175 | char *display_get_infotext_text( uint16_t channel ); 176 | /** 177 | * @brief set display infotext prefix text 178 | * 179 | * @param channel display channel number 180 | * @param text 181 | */ 182 | void display_set_infotext_text( uint16_t channel, char *text ); 183 | /** 184 | * @brief store all settings to display.json 185 | */ 186 | void display_save_settings( void ); 187 | #endif // _DISPLAY_H -------------------------------------------------------------------------------- /src/ioport.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ioport.h 3 | * @author Dirk Broßwick (dirk.brosswick@googlemail.com) 4 | * @brief 5 | * @version 1.0 6 | * @date 2022-10-03 7 | * 8 | * @copyright Copyright (c) 2022 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | */ 24 | #ifndef _IOPORT_H 25 | #define _IOPORT_H 26 | 27 | #include "config/ioport_config.h" 28 | /** 29 | * @brief 30 | */ 31 | void ioport_init( void ); 32 | /** 33 | * 34 | */ 35 | void ioport_loop( void ); 36 | /** 37 | * @brief get ioport channel name 38 | * 39 | * @param channel ioport channel number 40 | * @return char* ioport channel name as char array 41 | */ 42 | char *ioport_get_name( uint16_t channel ); 43 | /** 44 | * @brief set ioport channel name 45 | * 46 | * @param channel ioport channel number 47 | * @param name ioport channel name as char array 48 | */ 49 | void ioport_set_name( uint16_t channel, char *name ); 50 | /** 51 | * @brief get ioport channel start state after reset/start 52 | * 53 | * @param channel ioport channel number 54 | * @return true state after reset/start is set 55 | * @return false state after reset/start is clear 56 | * 57 | * @note the real state depends on invert config 58 | */ 59 | bool ioport_get_start_state( uint16_t channel ); 60 | /** 61 | * @brief get ioport start state after reset/start 62 | * 63 | * @param channel ioport channel number 64 | * @param start_state start state after reset/start 65 | * 66 | * @note the real state depends on invert config 67 | */ 68 | void ioport_set_start_state( uint16_t channel, uint16_t start_state ); 69 | /** 70 | * @brief get ioport channel is active or inactive 71 | * 72 | * @param channel ioport channel 73 | * @return true means ioport channel is active 74 | * @return false means ioport channel is inactive 75 | */ 76 | ioport_active_t ioport_get_active( uint16_t channel ); 77 | /** 78 | * @brief set ioport channel active or inactive 79 | * 80 | * @param channel ioport channel number 81 | * @param active true means active, false means inactive 82 | */ 83 | void ioport_set_active( uint16_t channel, ioport_active_t active ); 84 | /** 85 | * @brief get ioport channel output pin 86 | * 87 | * @param channel ioport channel number 88 | * @return uint16_t ioport channel output pin number 89 | */ 90 | uint16_t ioport_get_gpio_pin_num( uint16_t channel ); 91 | /** 92 | * @brief set ioport channel output pin 93 | * 94 | * @param channel ioport channel number 95 | * @param gpio_pin_num ioport channel output pin number 96 | */ 97 | void ioport_set_gpio_pin_num( uint16_t channel, uint16_t gpio_pin_num ); 98 | /** 99 | * @brief get ioport channel output pin is inverted 100 | * 101 | * @param channel ioport channel number 102 | * @return uint16_t 0 means normal, 1 means inverted 103 | */ 104 | ioport_output_t ioport_get_invert( uint16_t channel ); 105 | /** 106 | * @brief set ioport channel output is inverted 107 | * 108 | * @param channel ioport channel number 109 | * @param invert 0 means normal, 1 means inverted 110 | */ 111 | void ioport_set_invert( uint16_t channel, ioport_output_t invert ); 112 | /** 113 | * @brief get channel output value source 114 | * 115 | * @param channel ioport channel number 116 | * @return uint16_t value source 117 | */ 118 | uint16_t ioport_get_value_channel( uint16_t channel ); 119 | /** 120 | * @brief set channel output value source 121 | * 122 | * @param channel ioport channel number 123 | * @param value_channel value source 124 | */ 125 | void ioport_set_value_channel( uint16_t channel, uint16_t value_channel ); 126 | /** 127 | * @brief get channel output is set trigger type 128 | * 129 | * @param channel ioport channel number 130 | * @return uint16_t 131 | */ 132 | ioport_trigger_t ioport_get_trigger( uint16_t channel ); 133 | /** 134 | * @brief set channel output is set trigger type 135 | * 136 | * @param channel ioport channel number 137 | * @param trigger 138 | */ 139 | void ioport_set_trigger( uint16_t channel, ioport_trigger_t trigger ); 140 | /** 141 | * @brief get channl output trigger value 142 | * 143 | * @param channel ioport channel number 144 | * @return float 145 | */ 146 | float ioport_get_value( uint16_t channel ); 147 | /** 148 | * @brief set ioport channel trigger value 149 | * 150 | * @param channel ioport channel number 151 | * @param value ioport channel output trigger value 152 | */ 153 | void ioport_set_value( uint16_t channel, float value ); 154 | /** 155 | * @brief get channel output state 156 | * 157 | * @param channel ioport channel value 158 | * @return true 159 | * @return false 160 | */ 161 | bool ioport_get_state( uint16_t channel ); 162 | void ioport_save_settings( void ); 163 | #endif // _IOPORT_H -------------------------------------------------------------------------------- /src/mqttclient.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file mqttclient.h 3 | * @author Dirk Broßwick (dirk.brosswick@googlemail.com) 4 | * @brief 5 | * @version 1.0 6 | * @date 2022-10-03 7 | * 8 | * @copyright Copyright (c) 2022 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | */ 24 | #ifndef _MQTTCLIENT_H 25 | #define _MQTTCLIENT_H 26 | 27 | /** 28 | * @brief start the mqqt client background task 29 | */ 30 | void mqtt_client_StartTask( void ); 31 | /** 32 | * @brief publish a mqqt msg to a given topic 33 | * 34 | * @param topic topic 35 | * @param payload msg to send 36 | */ 37 | void mqtt_client_publish( char * topic, char * payload ); 38 | /** 39 | * @brief disable all mqtt connections 40 | */ 41 | void mqtt_client_disable( void ); 42 | /** 43 | * @brief enable all mqtt connections and reload all connection settings 44 | */ 45 | void mqtt_client_enable( void ); 46 | /** 47 | * @brief get mqtt server address 48 | * 49 | * @return server address as char array 50 | */ 51 | const char *mqtt_client_get_server( void ); 52 | /** 53 | * @brief set mqtt server 54 | * 55 | * @param server serveraddress as char array 56 | */ 57 | void mqtt_client_set_server( const char *server ); 58 | /** 59 | * @brief get mqtt username 60 | * 61 | * @return username as char array 62 | */ 63 | const char *mqtt_client_get_username( void ); 64 | /** 65 | * @brief set mqtt username 66 | * 67 | * @param username username as char array 68 | */ 69 | void mqtt_client_set_username( const char *username ); 70 | /** 71 | * @brief get mqtt password 72 | * 73 | * @return password as char array 74 | */ 75 | const char *mqtt_client_get_password( void ); 76 | /** 77 | * @brief set mqtt password 78 | * 79 | * @param password password as char array 80 | */ 81 | void mqtt_client_set_password( const char *password ); 82 | /** 83 | * @brief get mqtt topic prefix 84 | * 85 | * @return mqtt topix prefix as char array 86 | */ 87 | const char *mqtt_client_get_topic( void ); 88 | /** 89 | * @brief set mqtt topix prefix 90 | * 91 | * @param topic topix as char array 92 | */ 93 | void mqtt_client_set_topic( const char *topic ); 94 | /** 95 | * @brief get mqtt server port 96 | * 97 | * @return serverport 98 | */ 99 | int mqtt_client_get_port( void ); 100 | /** 101 | * @brief set server port 102 | * 103 | * @param port mqtt server port 104 | */ 105 | void mqtt_client_set_port( int port ); 106 | /** 107 | * @brief get mqtt msg interval 108 | * 109 | * @return mqtt msg interval in sec 110 | */ 111 | int mqtt_client_get_interval( void ); 112 | /** 113 | * @brief set mqtt msg interval 114 | * 115 | * @param interval mqtt msg interval in sec 116 | */ 117 | void mqtt_client_set_interval( int interval ); 118 | bool mqtt_client_get_realtimestats( void ); 119 | void mqtt_client_set_realtimestats( bool realtimestats ); 120 | /** 121 | * @brief store mqtt settings as .json 122 | * 123 | * @note all settings has a direct effect but was not stored, only here the a new json is written 124 | */ 125 | void mqtt_save_settings( void ); 126 | #endif // _MQTTCLIENT_H 127 | -------------------------------------------------------------------------------- /src/ntp.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ntp.cpp 3 | * @author Dirk Broßwick (dirk.brosswick@googlemail.com) 4 | * @brief 5 | * @version 1.0 6 | * @date 2022-10-03 7 | * 8 | * @copyright Copyright (c) 2022 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | */ 24 | #include 25 | #include 26 | #include 27 | 28 | #include "ntp.h" 29 | #include "config.h" 30 | 31 | TaskHandle_t _NTP_Task; 32 | const char* ntpServer = "pool.ntp.org"; 33 | const long gmtOffset_sec = 3600; 34 | const int daylightOffset_sec = 3600; 35 | 36 | static void ntp_Task( void * pvParameters ); 37 | 38 | void ntp_StartTask( void ) { 39 | xTaskCreatePinnedToCore( 40 | ntp_Task, /* Function to implement the task */ 41 | "ntp Task", /* Name of the task */ 42 | 2000, /* Stack size in words */ 43 | NULL, /* Task input parameter */ 44 | 1, /* Priority of the task */ 45 | &_NTP_Task, /* Task handle. */ 46 | _NTP_TASKCORE ); /* Core where the task should run */ 47 | } 48 | 49 | /** 50 | * @brief ntp update task 51 | * 52 | * @param pvParameters 53 | */ 54 | static void ntp_Task( void * pvParameters ) { 55 | struct tm timeinfo; 56 | static uint64_t NextMillis = millis(); 57 | 58 | log_i("Start NTP Task on Core: %d", xPortGetCoreID() ); 59 | 60 | while ( true ) { 61 | vTaskDelay( 10 ); 62 | if ( NextMillis < millis() ) { 63 | if ( WiFi.isConnected() ) { 64 | log_i( "NTP-client: renew time" ); 65 | 66 | configTime( gmtOffset_sec, daylightOffset_sec, ntpServer ); 67 | 68 | if( !getLocalTime(&timeinfo ) ) { 69 | log_e( "Failed to obtain time" ); 70 | NextMillis += 15 * 1000l; 71 | } 72 | else { 73 | Serial.println( &timeinfo, "NTP-client: %A, %B %d %Y %H:%M:%S" ); 74 | NextMillis += NTP_RENEW_INTERVAL * 1000l; 75 | } 76 | } 77 | else { 78 | NextMillis += 15 * 1000l; 79 | } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/ntp.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ntp.h 3 | * @author Dirk Broßwick (dirk.brosswick@googlemail.com) 4 | * @brief 5 | * @version 1.0 6 | * @date 2022-10-03 7 | * 8 | * @copyright Copyright (c) 2022 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | */ 24 | #ifndef _NTP_H 25 | #define _NTP_H 26 | 27 | #define NTP_RENEW_INTERVAL 3600 * 24 28 | /** 29 | * @brief start ntp time update background task 30 | */ 31 | void ntp_StartTask( void ); 32 | 33 | #endif // _NTP_H 34 | -------------------------------------------------------------------------------- /src/powermeter.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file powermeter.cpp 3 | * @author Dirk Broßwick (dirk.brosswick@googlemail.com) 4 | * @brief 5 | * @version 1.0 6 | * @date 2022-10-03 7 | * 8 | * @copyright Copyright (c) 2022 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | */ 24 | #include 25 | #include 26 | #include 27 | 28 | #include "config.h" 29 | #include "display.h" 30 | #include "ioport.h" 31 | #include "measure.h" 32 | #include "mqttclient.h" 33 | #include "ntp.h" 34 | #include "webserver.h" 35 | #include "wificlient.h" 36 | /** 37 | * @brief arduino setup function 38 | */ 39 | void setup( void ) { 40 | setCpuFrequencyMhz( 240 ); 41 | Serial.begin(115200); 42 | /* 43 | * hardware stuff and file system 44 | */ 45 | log_i("Start Main Task on Core: %d", xPortGetCoreID() ); 46 | if ( !SPIFFS.begin() ) { 47 | log_i("format SPIFFS ..." ); 48 | SPIFFS.format(); 49 | } 50 | ioport_init(); 51 | display_init(); 52 | wificlient_init(); 53 | /* 54 | * Setup Tasks 55 | */ 56 | measure_StartTask(); 57 | mqtt_client_StartTask(); 58 | asyncwebserver_StartTask(); 59 | ntp_StartTask(); 60 | } 61 | 62 | /** 63 | * @brief arduino main loop 64 | */ 65 | void loop() { 66 | display_loop(); 67 | ioport_loop(); 68 | } 69 | -------------------------------------------------------------------------------- /src/utils/basejsonconfig.cpp: -------------------------------------------------------------------------------- 1 | /**** 2 | * Copyright 2020 Skurydin Alexey under the MIT License. 3 | * http://github.com/anakod 4 | ****/ 5 | #include 6 | #include 7 | 8 | #include "basejsonconfig.h" 9 | 10 | BaseJsonConfig::BaseJsonConfig(const char* configFileName) { 11 | if (configFileName[0] == '/') 12 | strlcpy(fileName, configFileName, MAX_CONFIG_FILE_NAME_LENGTH); 13 | else 14 | { 15 | fileName[0] = '/'; 16 | strlcpy(fileName+1, configFileName, MAX_CONFIG_FILE_NAME_LENGTH); 17 | } 18 | } 19 | 20 | bool BaseJsonConfig::load() { 21 | bool result = false; 22 | /* 23 | * load config if exsits 24 | */ 25 | if ( SPIFFS.exists(fileName) ) { 26 | /* 27 | * open file 28 | */ 29 | fs::File file = SPIFFS.open(fileName, FILE_READ); 30 | /* 31 | * check if open was success 32 | */ 33 | if (!file) { 34 | log_e("Can't open file: %s!", fileName); 35 | } 36 | else { 37 | /* 38 | * get filesize 39 | */ 40 | int filesize = file.size(); 41 | /* 42 | * create json structure 43 | */ 44 | DynamicJsonDocument doc( filesize*4 ); 45 | DeserializationError error = deserializeJson( doc, file ); 46 | /* 47 | * check if create json structure was successfull 48 | */ 49 | if ( error || filesize == 0 ) { 50 | log_e("json config deserializeJson() failed: %s, file: %s", error.c_str(), fileName ); 51 | } 52 | else { 53 | log_d("json config deserializeJson() success: %s, file: %s", error.c_str(), fileName ); 54 | result = onLoad(doc); 55 | } 56 | doc.clear(); 57 | } 58 | file.close(); 59 | } 60 | /* 61 | * check if read from json is failed 62 | */ 63 | if ( !result ) { 64 | log_i("reading json failed, call defaults, file: %s", fileName ); 65 | result = onDefault(); 66 | } 67 | 68 | return result; 69 | } 70 | 71 | bool BaseJsonConfig::load( uint32_t size ) { 72 | bool result = false; 73 | /* 74 | * load config if exsits 75 | */ 76 | if ( SPIFFS.exists(fileName) ) { 77 | /* 78 | * open file 79 | */ 80 | fs::File file = SPIFFS.open(fileName, FILE_READ); 81 | /* 82 | * check if open was success 83 | */ 84 | if (!file) { 85 | log_e("Can't open file: %s!", fileName); 86 | } 87 | else { 88 | /* 89 | * create json structure 90 | */ 91 | DynamicJsonDocument doc( size ); 92 | DeserializationError error = deserializeJson( doc, file ); 93 | /* 94 | * check if create json structure was successfull 95 | */ 96 | if ( error || size == 0 ) { 97 | log_e("json config deserializeJson() failed: %s, file: %s", error.c_str(), fileName ); 98 | } 99 | else { 100 | log_d("json config deserializeJson() success: %s, file: %s", error.c_str(), fileName ); 101 | result = onLoad(doc); 102 | } 103 | doc.clear(); 104 | } 105 | file.close(); 106 | } 107 | /* 108 | * check if read from json is failed 109 | */ 110 | if ( !result ) { 111 | log_i("reading json failed, call defaults, file: %s", fileName ); 112 | result = onDefault(); 113 | } 114 | 115 | return result; 116 | } 117 | 118 | bool BaseJsonConfig::save( uint32_t size ) { 119 | bool result = false; 120 | fs::File file = SPIFFS.open(fileName, FILE_WRITE ); 121 | 122 | if (!file) { 123 | log_e("Can't open file: %s!", fileName); 124 | } 125 | else { 126 | DynamicJsonDocument doc( size ); 127 | result = onSave(doc); 128 | 129 | if ( doc.overflowed() ) { 130 | log_e("json to large, some value are missing. use another size"); 131 | } 132 | 133 | size_t outSize = 0; 134 | if (prettyJson) 135 | outSize = serializeJsonPretty(doc, file); 136 | else 137 | outSize = serializeJson(doc, file); 138 | 139 | if (result == true && outSize == 0) { 140 | log_e("Failed to write config file %s", fileName); 141 | result = false; 142 | } 143 | else { 144 | log_d("json config serializeJson() success: %s", fileName ); 145 | } 146 | 147 | doc.clear(); 148 | } 149 | file.close(); 150 | 151 | return result; 152 | } 153 | 154 | bool BaseJsonConfig::save() { 155 | bool result = false; 156 | fs::File file = SPIFFS.open(fileName, FILE_WRITE ); 157 | 158 | if (!file) { 159 | log_e("Can't open file: %s!", fileName); 160 | } 161 | else { 162 | auto size = getJsonBufferSize(); 163 | DynamicJsonDocument doc( size ); 164 | result = onSave(doc); 165 | 166 | if ( doc.overflowed() ) { 167 | log_e("json to large, some value are missing. use doc.save( uint32_t size )"); 168 | } 169 | 170 | size_t outSize = 0; 171 | if (prettyJson) 172 | outSize = serializeJsonPretty(doc, file); 173 | else 174 | outSize = serializeJson(doc, file); 175 | 176 | if (result == true && outSize == 0) { 177 | log_e("Failed to write config file %s", fileName); 178 | result = false; 179 | } 180 | else { 181 | log_d("json config serializeJson() success: %s", fileName ); 182 | } 183 | 184 | doc.clear(); 185 | } 186 | file.close(); 187 | 188 | return result; 189 | } 190 | 191 | void BaseJsonConfig::debugPrint() { 192 | auto size = getJsonBufferSize(); 193 | DynamicJsonDocument doc(size); 194 | bool result = onSave(doc); 195 | if ( result ) { 196 | serializeJsonPretty(doc, Serial); 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /src/utils/basejsonconfig.h: -------------------------------------------------------------------------------- 1 | /**** 2 | * Copyright 2020 Skurydin Alexey under the MIT License. 3 | * http://github.com/anakod 4 | ****/ 5 | 6 | #ifndef BASEJSONCONFIG_H_ 7 | #define BASEJSONCONFIG_H_ 8 | 9 | #define MAX_CONFIG_FILE_NAME_LENGTH 32 10 | 11 | #include "ArduinoJson.h" 12 | /** 13 | * @brief JSON configuration storage with bindings for variables and UI widgets 14 | */ 15 | class BaseJsonConfig { 16 | public: 17 | BaseJsonConfig(const char* configFileName); 18 | /** 19 | * @brief Load settings from file 20 | */ 21 | bool load(); 22 | /** 23 | * @brief Load settings from file with a custom json size 24 | */ 25 | bool load( uint32_t size ); 26 | /** 27 | * @brief Save settings to file 28 | */ 29 | bool save(); 30 | /** 31 | * @brief Save settings to file with a custom json size 32 | */ 33 | bool save( uint32_t size ); 34 | /** 35 | * @brief print out json 36 | */ 37 | void debugPrint(); 38 | 39 | protected: 40 | ////////////// Available for overloading: ////////////// 41 | virtual bool onSave(JsonDocument& document) = 0; 42 | virtual bool onLoad(JsonDocument& document) = 0; 43 | virtual bool onDefault( void ) = 0; 44 | 45 | virtual size_t getJsonBufferSize() { return 8192; } 46 | protected: 47 | char fileName[MAX_CONFIG_FILE_NAME_LENGTH]; 48 | bool prettyJson = true; 49 | }; 50 | #endif // BASEJSONCONFIG_H_ -------------------------------------------------------------------------------- /src/webserver.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file webserver.h 3 | * @author Dirk Broßwick (dirk.brosswick@googlemail.com) 4 | * @brief 5 | * @version 1.0 6 | * @date 2022-10-03 7 | * 8 | * @copyright Copyright (c) 2022 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | */ 24 | #ifndef _ASYNCWEBSERVER_H 25 | #define _ASYNCWEBSERVER_H 26 | 27 | #define WEBSERVERPORT 80 28 | 29 | void asyncwebserver_StartTask ( void ); 30 | 31 | #endif // _ASYNCWEBSERVER_H -------------------------------------------------------------------------------- /src/wificlient.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file wificlient.h 3 | * @author Dirk Broßwick (dirk.brosswick@googlemail.com) 4 | * @brief 5 | * @version 1.0 6 | * @date 2022-10-03 7 | * 8 | * @copyright Copyright (c) 2022 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | */ 24 | #ifndef _WIFICLIENT_H 25 | #define _WIFICLIENT_H 26 | /** 27 | * @brief init wifi client 28 | */ 29 | void wificlient_init( void ); 30 | /** 31 | * @brief get hostname 32 | * 33 | * @return const char* 34 | */ 35 | const char *wificlient_get_hostname( void ); 36 | /** 37 | * @brief set hostname 38 | * 39 | * @param hostname 40 | */ 41 | void wificlient_set_hostname( const char * hostname ); 42 | /** 43 | * @brief get wifi ssid 44 | * 45 | * @return const char* 46 | */ 47 | const char *wificlient_get_ssid( void ); 48 | /** 49 | * @brief set wifi ssid 50 | * 51 | * @param ssid 52 | */ 53 | void wificlient_set_ssid( const char * ssid ); 54 | /** 55 | * @brief get wifi ssid password 56 | * 57 | * @return const char* 58 | */ 59 | const char *wificlient_get_password( void ); 60 | /** 61 | * @brief set wifi ssid password 62 | * 63 | * @param password 64 | */ 65 | void wificlient_set_password( const char * password ); 66 | /** 67 | * @brief get wifi softAP ssid 68 | * 69 | * @return const char* 70 | */ 71 | const char *wificlient_get_softap_ssid( void ); 72 | /** 73 | * @brief set wifi softAP ssid 74 | * 75 | * @param softap_ssid 76 | */ 77 | void wificlient_set_softap_ssid( const char * softap_ssid ); 78 | /** 79 | * @brief get wifi softAP ssid password 80 | * 81 | * @return const char* 82 | */ 83 | const char *wificlient_get_softap_password( void ); 84 | /** 85 | * @brief set wifi softAP ssid password 86 | * 87 | * @param softap_password 88 | */ 89 | void wificlient_set_softap_password( const char * softap_password ); 90 | /** 91 | * @brief get wifi softAP enable state 92 | * 93 | * @return true 94 | * @return false 95 | */ 96 | bool wificlient_get_enable_softap( void ); 97 | /** 98 | * @brief set wifi softAP enable/disable 99 | * 100 | * @param enable_softap 101 | */ 102 | void wificlient_set_enable_softap( bool enable_softap ); 103 | /** 104 | * @brief get wifi connect timeout before softAP start 105 | * 106 | * @return int 107 | */ 108 | int wificlient_get_timeout( void ); 109 | /** 110 | * @brief set wifi connect timeout before softAP start 111 | * 112 | * @param timeout 113 | */ 114 | void wificlient_set_timeout( int timeout ); 115 | /** 116 | * @brief get wifi client low bandwidth 117 | * 118 | * @return true 20MHz bandwidth 119 | * @return false 40MHz bandwidth 120 | */ 121 | bool wificlient_get_low_bandwidth( void ); 122 | /** 123 | * @brief set wifi lient low bandwidth 124 | * 125 | * @param low_bandwidth true means 20MHz bandwidth, false means 40MHz bandwidth 126 | */ 127 | void wificlient_set_low_bandwidth( bool low_bandwidth ); 128 | /** 129 | * @brief get wifi client low power 130 | * 131 | * @return true low power enabled 132 | * @return false low power disabled 133 | */ 134 | bool wificlient_get_low_power( void ); 135 | /** 136 | * @brief set wifi client low power 137 | * 138 | * @param low_power true means low power, false means normals power 139 | */ 140 | void wificlient_set_low_power( bool low_power ); 141 | /** 142 | * @brief store current settings to wifi.json 143 | */ 144 | void wificlient_save_settings( void ); 145 | #endif // _IOPORT_H --------------------------------------------------------------------------------