ogghst / grownode Goto Github PK
View Code? Open in Web Editor NEWGrowNode is a vertical framework to build esp32 based devices targeted to growing plants in a controlled environment.
License: Apache License 2.0
GrowNode is a vertical framework to build esp32 based devices targeted to growing plants in a controlled environment.
License: Apache License 2.0
actually the responsibility to initiate a protocol or a service is on the leaf itself. this is preventing eg to create two leaves with i2c protocol. the initiation should be in the framework code instead
Use target = "_ blank" in HTML links to outside the site
There is no explicit "shopping list" of what one should buy to get started. Now we go from "The Platform" (general architecture) to "Install" (download the software) but one has yet to buy things, or at least they haven't been told explicitly. You can refer to the list of supported sensors
Board connected to Wifi and correctly sending MQTT messages.
WiFi goes down for some minutes.
The board tries to reconnect to WiFi three times and shows the messages:
gn_network: Disconnected. Connecting to the AP again.
gn_network: retry to connect to the AP
Then, it shows for a fourth time the only message:
gn_network: Disconnected. Connecting to the AP again.
and never tries again to reconnect.
If WiFi is back after this sequence of messages, the board stays disconnected.
this will simplify the code as the two calls are always coupled
find a naming convention
make private unnecessary functions
A provisioned board starts and correctly connects to WiFi when the MQTT server is not available.
The board continuously shows the message "gn_main: grownode startup sequence code: 4" and periodically also some MQTT errors.
This behavior is ok and expected.
At a certain point the MQTT server becomes available.
The board subscribes to "general" topics but it never starts sending sensor status and keeps showing the aforementioned message, and no MQTT errors.
Example of output after MQTT server comes back online:
I (58451) gn_main: grownode startup sequence code: 4
I (59451) gn_main: grownode startup sequence code: 4
D (60131) gn_mqtt_protocol: Event dispatched from event loop base=MQTT_EVENTS, event_id=7
D (60131) gn_mqtt_protocol: Other event id:7
D (60291) gn_mqtt_protocol: Event dispatched from event loop base=MQTT_EVENTS, event_id=1
D (60291) gn_mqtt_protocol: MQTT_EVENT_CONNECTED
D (60291) gn_mqtt_protocol: subscribing default topic /grownode/test/cmd, msg_id=61933
D (60301) gn_mqtt_protocol: sent publish successful, msg_id=0, topic=/grownode/test/sts, payload={"msgtype":"online"}
D (60311) gn_mqtt_protocol: Event dispatched from event loop base=MQTT_EVENTS, event_id=3
D (60321) gn_mqtt_protocol: MQTT_EVENT_SUBSCRIBED, msg_id=61933
I (60451) gn_main: grownode startup sequence code: 4
I (61451) gn_main: grownode startup sequence code: 4
I (62451) gn_main: grownode startup sequence code: 4
I (63451) gn_main: grownode startup sequence code: 4
I (64451) gn_main: grownode startup sequence code: 4
I (65451) gn_main: grownode startup sequence code: 4
I (66451) gn_main: grownode startup sequence code: 4
I (67451) gn_main: grownode startup sequence code: 4
I (68451) gn_main: grownode startup sequence code: 4
I (69451) gn_main: grownode startup sequence code: 4
I (70451) gn_main: grownode startup sequence code: 4
I (71451) gn_main: grownode startup sequence code: 4
I (72451) gn_main: grownode startup sequence code: 4
I (73451) gn_main: grownode startup sequence code: 4
I (74451) gn_main: grownode startup sequence code: 4
I (75451) gn_main: grownode startup sequence code: 4
I (76451) gn_main: grownode startup sequence code: 4
I (77451) gn_main: grownode startup sequence code: 4
I (78451) gn_main: grownode startup sequence code: 4
I (79451) gn_main: grownode startup sequence code: 4
I (80451) gn_main: grownode startup sequence code: 4
I (81451) gn_main: grownode startup sequence code: 4
I (82451) gn_main: grownode startup sequence code: 4
I (83451) gn_main: grownode startup sequence code: 4
I (84451) gn_main: grownode startup sequence code: 4
I (85451) gn_main: grownode startup sequence code: 4
I (86451) gn_main: grownode startup sequence code: 4
I (87451) gn_main: grownode startup sequence code: 4
I (88451) gn_main: grownode startup sequence code: 4
I (89451) gn_main: grownode startup sequence code: 4
The idea would be to avoid using menuconfig except for advanced stuff, making the code the single point of configuration for a general "basic" user, who wouldn't even need to know about menuconfig.
Setting the "Reset Flash at every startup" flag seems to create inconsistencies in the use of the leaf INIT functions.
A dedicated branch has been created to reproduce the problem here:
https://github.com/ogghst/grownode/tree/test_parameter-store_and_gpio-3
when rebooting, leaves are not keeping last state
if you select "Enable Networking" in menuconfig but you don't enable "Provisioning security", then the provisioning app fails although it connects the device. Make "Provisioning security" mandatory?
Probably due to a bug in SoftAP app.
A low priority enhancement...
Example:
A board controls 5 temperature sensors of the same type but only one shows some strange measures.
In order to debug it the user now has the only option to activate debug messages for all temperature sensors all together, making debugging difficult.
The possibility to activate debug only on a specific leaf would ease debugging of complex systems.
when raised log level with
esp_log_level_set("gn_mqtt_protocol", ESP_LOG_DEBUG);
the board seems not to be able to keep wifi connection. Possible bug in ESP-IDF MQTT implementation (see #5876 )
...
I (3708) grownode: _gn_leaf_start blink
D (3808) gn_mqtt_protocol: publishing leaf blink
D (3808) gn_mqtt_protocol: subscribing leaf. topic: /grownode/test/blink/cmd
D (3808) gn_mqtt_protocol: sent subscribe successful, topic = /grownode/test/blink/cmd
D (3818) gn_mqtt_protocol: Event dispatched from event loop base=MQTT_EVENTS, event_id=3
D (3818) gn_mqtt_protocol: MQTT_EVENT_SUBSCRIBED, msg_id=26691
I (3828) grownode: _gn_start_leaf blink completed
D (3838) gn_mqtt_protocol: gn_mqtt_send_leaf_param status
D (3838) gn_mqtt_protocol: sent publish successful, msg_id=0, topic=/grownode/test/blink/status/sts, payload=0
D (3848) gn_mqtt_protocol: gn_mqtt_send_leaf_param inverted
D (3858) gn_mqtt_protocol: sent publish successful, msg_id=0, topic=/grownode/test/blink/inverted/sts, payload=0
D (3868) gn_mqtt_protocol: gn_mqtt_send_leaf_param gpio
D (3868) gn_mqtt_protocol: sent publish successful, msg_id=0, topic=/grownode/test/blink/gpio/sts, payload=2.000000
I (4588) wifi:state: run -> init (0)
I (4588) wifi:pm stop, total sleep time: 1109972 us / 2272570 us
W (4588) wifi:<ba-del>idx
I (4588) wifi:new:<11,0>, old:<11,0>, ap:<255,255>, sta:<11,0>, prof:1
E (4598) gn_network: Wifi disconnected. reason: 8
I (4598) gn_network: Retry to connect - attempt 0 of 5
W (4608) wifi:hmac tx: ifx0 stop, discard
W (4608) wifi:hmac tx: ifx0 stop, discard
E (4618) TRANSPORT_BASE: poll_read select error 113, errno = Software caused connection abort, fd = 54
E (4628) MQTT_CLIENT: Poll read error: 119, aborting connection
D (4628) gn_mqtt_protocol: Event dispatched from event loop base=MQTT_EVENTS, event_id=2
D (4638) gn_mqtt_protocol: MQTT_EVENT_DISCONNECTED
D (4648) gn_mqtt_protocol: _gn_mqtt_on_disconnected
D (4648) gn_mqtt_protocol: _GN_MQTT_CONNECTED_KO_EVENT_BIT
I (4698) wifi:flush txq
I (4698) wifi:stop sw txq
I (4698) wifi:lmac stop hw txq
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:6608
load:0x40078000,len:14780
load:0x40080400,len:3792
0x40080400: _init at ??:?
entry 0x40080694
I (27) boot: ESP-IDF v4.4-rc1 2nd stage bootloader
I (27) boot: compile time 12:18:20
I (27) boot: chip revision: 1
I (30) boot_comm: chip revision: 1, min. bootloader chip revision: 0
I (37) boot.esp32: SPI Speed : 40MHz
I (42) boot.esp32: SPI Mode : DIO
I (46) boot.esp32: SPI Flash Size : 4MB
...
in order to make sure every parameter change is reflected to the grownode control layer, the leaf parameter structure need to be obuscated
Make a page of main supported sensors, relevant for growing plants, with links
an high level scheduler is needed to support leaves.
An user can choose to have messages from/to sensors in json format. This could allow to include more data like timestamps. Eg to turn on a relay {v="0"}, to receive status {t="12345678",v="0"}
this is useful when a controller leaf has to control other leaves, instead of hard coding the leaf name into the controller it should be referenced in the leaf init code
Separate the "idea" and the "story" from the first page (right now one has to read them almost by force)
once the board gets into manageable error it should raise it internally as event and send to the controller.
error handling should be
Interesting project.
I use LILYGO TTGO T-Display ESP32 for simple project, and want display temperature, time, humidity on OLED display using this component. Could you show example code how to do it?
When you want to add a leaf you need to use several commands which could probably be summarized in simple one-line ones.
Example.
To add a moisture capacity sensor this is the way now:
//creates the moisture sensor
moist = gn_leaf_create(node, "moist", gn_capacitive_moisture_sensor_config,
4096);
//set the channel 4
gn_leaf_param_init_double(moist, GN_CMS_PARAM_ADC_CHANNEL, 4); //GPIO12
//set update time
gn_leaf_param_init_double(moist, GN_CMS_PARAM_UPDATE_TIME_SEC, 5);
//set initial status to active (on)
gn_leaf_param_init_bool(moist, GN_CMS_PARAM_ACTIVE, true);
It could be summarized with something like:
moist = gn_cms_fastcreate(node, "moist", 4, 5)
where implicitly "under the hood" all the other parameters are set. E.g., probably nobody would change that "4096" and a standard user when creates a leaf wants it active.
It could be:
In case 1, leaf should have a standard and common "name" to use in every function/parameter definition/file names, in order to make it easy to know the name of the "fastcreate" function.
For example capacity moisture sensors have file names and config called "capacity_moisture_sensor" but parameters called "CMS". This may generate confusion.
Temperature ds18b20 sensors, instead, maintain the same name everywhere.
actually the functions that handles config (node, leaf) are not thread safe. potentially, two tasks working on same config can produce undefined behavior
leaves parameters can be read only (commands) or write only (sensors) or read-write (??)
Landing page with summary idea and links to the other main sections (immediately the possibility of going to the point)
add functionality to send messages across leaves and modify parameters
a message is composed by an ID, a level and a description. the message will be dispatched to internal event and collected by default by mqtt service to be sent through the network in the /log channel - JSON message
Device connected at start. Then network went down.
Besides a warning given by MQTT_CLIENT, gn_mqtt_protocol continued reporting "publish successful" in debug mode, e.g.:
D (1707201) gn_leaf_ds18b20: gn_ds18b20_temp_sensor_collect
D (1707201) gn_leaf_ds18b20: reading from GPIO 4..
D (1707971) gn_leaf_ds18b20: Sensor 9e000004fb122628 (DS18B20) reports 20.375 �C (68.675 �F)
D (1707971) gn_mqtt_protocol: gn_mqtt_send_leaf_param temp1
W (1707971) MQTT_CLIENT: Publish: Losing qos0 data when client not connected
**D (1707981) gn_mqtt_protocol: sent publish successful, msg_id=0, topic=/grownode/test/EMMENTHAL_SENSOR/temp1/sts, payload=20.375000**
Debug messages generated by leaves only show the leaf type but not the leaf name. So, it's not possible to know which particular leaf generated a certain debug message if there are more leaves of the same type.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.