Compare commits
2 Commits
1741bb0b53
...
936c52e0e7
Author | SHA1 | Date | |
---|---|---|---|
936c52e0e7 | |||
aad1dbd458 |
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"board": {
|
"board": {
|
||||||
"active_layer": 37,
|
"active_layer": 31,
|
||||||
"active_layer_preset": "",
|
"active_layer_preset": "",
|
||||||
"auto_track_width": false,
|
"auto_track_width": false,
|
||||||
"hidden_netclasses": [],
|
"hidden_netclasses": [],
|
||||||
|
@ -58,14 +58,32 @@
|
|||||||
"width": 0.0
|
"width": 0.0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"drc_exclusions": [],
|
"drc_exclusions": [
|
||||||
|
"footprint_symbol_mismatch|177050000|59025000|a624af3d-bffa-4ff7-9554-e16d3c677f69|00000000-0000-0000-0000-000000000000",
|
||||||
|
"footprint_symbol_mismatch|237580000|53970000|c9d8d35b-26b7-4992-9d25-be9130d57b1a|00000000-0000-0000-0000-000000000000",
|
||||||
|
"footprint_symbol_mismatch|256580000|49370000|b33af7ef-63da-4a51-8d8a-183cadd974de|00000000-0000-0000-0000-000000000000",
|
||||||
|
"net_conflict|177050000|59025000|09cad967-1882-4dd3-8900-445282e228e5|00000000-0000-0000-0000-000000000000",
|
||||||
|
"net_conflict|177050000|59025000|20ab85c0-b3f3-4826-a86d-065fee01e11f|00000000-0000-0000-0000-000000000000",
|
||||||
|
"net_conflict|177050000|59025000|3da9717d-9800-42f9-97d1-56d23bf085aa|00000000-0000-0000-0000-000000000000",
|
||||||
|
"net_conflict|177050000|59025000|444aab2b-3a9b-444e-b60c-b5b5ff830942|00000000-0000-0000-0000-000000000000",
|
||||||
|
"net_conflict|177050000|59025000|6b067fd3-d374-4937-8779-958994d9163b|00000000-0000-0000-0000-000000000000",
|
||||||
|
"net_conflict|177050000|59025000|9839c562-7672-4ea8-a74d-bea83ae26677|00000000-0000-0000-0000-000000000000",
|
||||||
|
"net_conflict|177050000|59025000|9ce2df19-edf4-40d2-8e85-8c33008b8df0|00000000-0000-0000-0000-000000000000",
|
||||||
|
"net_conflict|177050000|59025000|a8ab716a-cd1e-4842-ad8e-3d6d1db9770b|00000000-0000-0000-0000-000000000000",
|
||||||
|
"net_conflict|177050000|59025000|aaf09ae3-4ace-49d7-a050-44cb4c93d63b|00000000-0000-0000-0000-000000000000",
|
||||||
|
"net_conflict|177050000|59025000|af55e8a2-ba8d-462e-807f-99ca5906f801|00000000-0000-0000-0000-000000000000",
|
||||||
|
"net_conflict|177050000|59025000|c36efd78-869f-40e7-86fc-97e5ed683fec|00000000-0000-0000-0000-000000000000",
|
||||||
|
"net_conflict|177050000|59025000|d668fda0-e4be-4e1f-95b8-8cd59a67cb21|00000000-0000-0000-0000-000000000000",
|
||||||
|
"net_conflict|177050000|59025000|d99401c6-2b75-46f7-8616-cdd7755709ee|00000000-0000-0000-0000-000000000000",
|
||||||
|
"net_conflict|177050000|59025000|f1fd5816-e8bd-4ba6-9d53-54b58d25e2dc|00000000-0000-0000-0000-000000000000"
|
||||||
|
],
|
||||||
"meta": {
|
"meta": {
|
||||||
"filename": "board_design_settings.json",
|
"filename": "board_design_settings.json",
|
||||||
"version": 2
|
"version": 2
|
||||||
},
|
},
|
||||||
"rule_severities": {
|
"rule_severities": {
|
||||||
"annular_width": "ignore",
|
"annular_width": "ignore",
|
||||||
"clearance": "warning",
|
"clearance": "error",
|
||||||
"connection_width": "warning",
|
"connection_width": "warning",
|
||||||
"copper_edge_clearance": "error",
|
"copper_edge_clearance": "error",
|
||||||
"copper_sliver": "warning",
|
"copper_sliver": "warning",
|
||||||
@ -80,7 +98,6 @@
|
|||||||
"footprint_type_mismatch": "ignore",
|
"footprint_type_mismatch": "ignore",
|
||||||
"hole_clearance": "error",
|
"hole_clearance": "error",
|
||||||
"hole_near_hole": "error",
|
"hole_near_hole": "error",
|
||||||
"holes_co_located": "warning",
|
|
||||||
"invalid_outline": "error",
|
"invalid_outline": "error",
|
||||||
"isolated_copper": "warning",
|
"isolated_copper": "warning",
|
||||||
"item_on_disabled_layer": "error",
|
"item_on_disabled_layer": "error",
|
||||||
@ -446,8 +463,8 @@
|
|||||||
"no_connect_dangling": "warning",
|
"no_connect_dangling": "warning",
|
||||||
"pin_not_connected": "error",
|
"pin_not_connected": "error",
|
||||||
"pin_not_driven": "error",
|
"pin_not_driven": "error",
|
||||||
"pin_to_pin": "ignore",
|
"pin_to_pin": "error",
|
||||||
"power_pin_not_driven": "ignore",
|
"power_pin_not_driven": "error",
|
||||||
"similar_labels": "warning",
|
"similar_labels": "warning",
|
||||||
"simulation_model_issue": "ignore",
|
"simulation_model_issue": "ignore",
|
||||||
"unannotated": "error",
|
"unannotated": "error",
|
||||||
@ -1222,19 +1239,13 @@
|
|||||||
"label": "Description",
|
"label": "Description",
|
||||||
"name": "Description",
|
"name": "Description",
|
||||||
"show": false
|
"show": false
|
||||||
},
|
|
||||||
{
|
|
||||||
"group_by": false,
|
|
||||||
"label": "LCSC Part",
|
|
||||||
"name": "LCSC Part",
|
|
||||||
"show": false
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"filter_string": "",
|
"filter_string": "",
|
||||||
"group_symbols": true,
|
"group_symbols": true,
|
||||||
"name": "",
|
"name": "",
|
||||||
"sort_asc": true,
|
"sort_asc": true,
|
||||||
"sort_field": "Value"
|
"sort_field": "LCSC_PART_NUMBER"
|
||||||
},
|
},
|
||||||
"connection_grid_size": 50.0,
|
"connection_grid_size": 50.0,
|
||||||
"drawing": {
|
"drawing": {
|
||||||
@ -1270,7 +1281,7 @@
|
|||||||
"meta": {
|
"meta": {
|
||||||
"version": 0
|
"version": 0
|
||||||
},
|
},
|
||||||
"model_mode": 4,
|
"model_mode": 0,
|
||||||
"workbook_filename": ""
|
"workbook_filename": ""
|
||||||
},
|
},
|
||||||
"page_layout_descr_file": "",
|
"page_layout_descr_file": "",
|
||||||
|
@ -9311,12 +9311,6 @@
|
|||||||
(color 0 0 0 0)
|
(color 0 0 0 0)
|
||||||
(uuid "5aef8b40-8452-4805-a5e4-da8d93469853")
|
(uuid "5aef8b40-8452-4805-a5e4-da8d93469853")
|
||||||
)
|
)
|
||||||
(junction
|
|
||||||
(at 461.01 532.13)
|
|
||||||
(diameter 0)
|
|
||||||
(color 0 0 0 0)
|
|
||||||
(uuid "5daa4784-f5ea-45b1-b6e6-5ed7605a4fd9")
|
|
||||||
)
|
|
||||||
(junction
|
(junction
|
||||||
(at 604.52 85.09)
|
(at 604.52 85.09)
|
||||||
(diameter 0)
|
(diameter 0)
|
||||||
@ -9647,6 +9641,12 @@
|
|||||||
(color 0 0 0 0)
|
(color 0 0 0 0)
|
||||||
(uuid "95e16490-1476-42b0-b339-2eae951bab1c")
|
(uuid "95e16490-1476-42b0-b339-2eae951bab1c")
|
||||||
)
|
)
|
||||||
|
(junction
|
||||||
|
(at 468.63 537.21)
|
||||||
|
(diameter 0)
|
||||||
|
(color 0 0 0 0)
|
||||||
|
(uuid "96c7bb99-d9fa-47f7-b3d9-aa357eb350aa")
|
||||||
|
)
|
||||||
(junction
|
(junction
|
||||||
(at 151.13 307.34)
|
(at 151.13 307.34)
|
||||||
(diameter 0)
|
(diameter 0)
|
||||||
@ -10257,18 +10257,10 @@
|
|||||||
(at 38.1 364.49)
|
(at 38.1 364.49)
|
||||||
(uuid "133b7027-41a1-4e09-a1e6-24d8bb033b2a")
|
(uuid "133b7027-41a1-4e09-a1e6-24d8bb033b2a")
|
||||||
)
|
)
|
||||||
(no_connect
|
|
||||||
(at 396.24 523.24)
|
|
||||||
(uuid "16bd24e1-85b5-4789-83d0-c7b0f2148660")
|
|
||||||
)
|
|
||||||
(no_connect
|
(no_connect
|
||||||
(at 128.27 50.8)
|
(at 128.27 50.8)
|
||||||
(uuid "16cd29f7-51e5-42c3-ada2-8a4c178b95ad")
|
(uuid "16cd29f7-51e5-42c3-ada2-8a4c178b95ad")
|
||||||
)
|
)
|
||||||
(no_connect
|
|
||||||
(at 468.63 535.94)
|
|
||||||
(uuid "4e457355-1d35-45ea-8f21-39e64314e210")
|
|
||||||
)
|
|
||||||
(no_connect
|
(no_connect
|
||||||
(at 184.15 67.31)
|
(at 184.15 67.31)
|
||||||
(uuid "6d645bf1-339f-4b38-a26a-bdd168ca591e")
|
(uuid "6d645bf1-339f-4b38-a26a-bdd168ca591e")
|
||||||
@ -12687,16 +12679,6 @@
|
|||||||
)
|
)
|
||||||
(uuid "50f6b5b1-5983-4df6-ba22-5686c3cfdbfe")
|
(uuid "50f6b5b1-5983-4df6-ba22-5686c3cfdbfe")
|
||||||
)
|
)
|
||||||
(wire
|
|
||||||
(pts
|
|
||||||
(xy 461.01 532.13) (xy 464.82 532.13)
|
|
||||||
)
|
|
||||||
(stroke
|
|
||||||
(width 0)
|
|
||||||
(type default)
|
|
||||||
)
|
|
||||||
(uuid "51a32a10-8287-45f0-bd16-12558c588428")
|
|
||||||
)
|
|
||||||
(wire
|
(wire
|
||||||
(pts
|
(pts
|
||||||
(xy 299.72 281.94) (xy 299.72 284.48)
|
(xy 299.72 281.94) (xy 299.72 284.48)
|
||||||
@ -12947,6 +12929,16 @@
|
|||||||
)
|
)
|
||||||
(uuid "5b5c70bc-6004-4d9b-97c5-d20d6b356f63")
|
(uuid "5b5c70bc-6004-4d9b-97c5-d20d6b356f63")
|
||||||
)
|
)
|
||||||
|
(wire
|
||||||
|
(pts
|
||||||
|
(xy 468.63 535.94) (xy 468.63 537.21)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(uuid "5b6446c7-78ac-4155-9abd-2e5b3ce82fb9")
|
||||||
|
)
|
||||||
(wire
|
(wire
|
||||||
(pts
|
(pts
|
||||||
(xy 330.2 505.46) (xy 336.55 505.46)
|
(xy 330.2 505.46) (xy 336.55 505.46)
|
||||||
@ -13257,26 +13249,6 @@
|
|||||||
)
|
)
|
||||||
(uuid "6b202dc2-b63b-453a-99cf-d34483dfd672")
|
(uuid "6b202dc2-b63b-453a-99cf-d34483dfd672")
|
||||||
)
|
)
|
||||||
(wire
|
|
||||||
(pts
|
|
||||||
(xy 400.05 527.05) (xy 396.24 527.05)
|
|
||||||
)
|
|
||||||
(stroke
|
|
||||||
(width 0)
|
|
||||||
(type default)
|
|
||||||
)
|
|
||||||
(uuid "6d716335-4a7d-41d3-9dc9-0ba195c48d5f")
|
|
||||||
)
|
|
||||||
(wire
|
|
||||||
(pts
|
|
||||||
(xy 396.24 527.05) (xy 396.24 537.21)
|
|
||||||
)
|
|
||||||
(stroke
|
|
||||||
(width 0)
|
|
||||||
(type default)
|
|
||||||
)
|
|
||||||
(uuid "6d76ff3e-5cf8-43c9-abe4-9c585ba56935")
|
|
||||||
)
|
|
||||||
(wire
|
(wire
|
||||||
(pts
|
(pts
|
||||||
(xy 311.15 403.86) (xy 311.15 405.13)
|
(xy 311.15 403.86) (xy 311.15 405.13)
|
||||||
@ -13297,6 +13269,16 @@
|
|||||||
)
|
)
|
||||||
(uuid "6dd8ab4a-b6ee-4931-9278-1bb300c309de")
|
(uuid "6dd8ab4a-b6ee-4931-9278-1bb300c309de")
|
||||||
)
|
)
|
||||||
|
(wire
|
||||||
|
(pts
|
||||||
|
(xy 396.24 513.08) (xy 396.24 537.21)
|
||||||
|
)
|
||||||
|
(stroke
|
||||||
|
(width 0)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(uuid "6e7e6080-ead4-43ea-9a9a-d463e4617905")
|
||||||
|
)
|
||||||
(wire
|
(wire
|
||||||
(pts
|
(pts
|
||||||
(xy 266.7 476.25) (xy 266.7 482.6)
|
(xy 266.7 476.25) (xy 266.7 482.6)
|
||||||
@ -14339,7 +14321,7 @@
|
|||||||
)
|
)
|
||||||
(wire
|
(wire
|
||||||
(pts
|
(pts
|
||||||
(xy 396.24 487.68) (xy 396.24 515.62)
|
(xy 396.24 487.68) (xy 396.24 505.46)
|
||||||
)
|
)
|
||||||
(stroke
|
(stroke
|
||||||
(width 0)
|
(width 0)
|
||||||
@ -16807,16 +16789,6 @@
|
|||||||
)
|
)
|
||||||
(uuid "f3c38e30-f3c3-4495-9009-c4501c56511e")
|
(uuid "f3c38e30-f3c3-4495-9009-c4501c56511e")
|
||||||
)
|
)
|
||||||
(wire
|
|
||||||
(pts
|
|
||||||
(xy 400.05 519.43) (xy 400.05 527.05)
|
|
||||||
)
|
|
||||||
(stroke
|
|
||||||
(width 0)
|
|
||||||
(type default)
|
|
||||||
)
|
|
||||||
(uuid "f4ba49cb-64ac-4d0d-8f8a-e57afcab26ce")
|
|
||||||
)
|
|
||||||
(wire
|
(wire
|
||||||
(pts
|
(pts
|
||||||
(xy 396.24 537.21) (xy 396.24 541.02)
|
(xy 396.24 537.21) (xy 396.24 541.02)
|
||||||
@ -44278,87 +44250,6 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(symbol
|
|
||||||
(lib_id "Device:R_Potentiometer")
|
|
||||||
(at 396.24 519.43 0)
|
|
||||||
(unit 1)
|
|
||||||
(exclude_from_sim no)
|
|
||||||
(in_bom yes)
|
|
||||||
(on_board yes)
|
|
||||||
(dnp no)
|
|
||||||
(uuid "84b2b2be-2dbf-4c20-aa55-1957eb031b82")
|
|
||||||
(property "Reference" "RV2"
|
|
||||||
(at 393.7 518.16 0)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(justify right)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(property "Value" "50k"
|
|
||||||
(at 393.7 520.7 0)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(justify right)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(property "Footprint" "Potentiometer_THT:Potentiometer_Bourns_3299W_Vertical"
|
|
||||||
(at 396.24 519.43 0)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(hide yes)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(property "Datasheet" "~"
|
|
||||||
(at 396.24 519.43 0)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(hide yes)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(property "Description" ""
|
|
||||||
(at 396.24 519.43 0)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(hide yes)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(property "LCSC_PART_NUMBER" "C118911"
|
|
||||||
(at 396.24 519.43 0)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(hide yes)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(pin "1"
|
|
||||||
(uuid "eed82135-b2b2-4e54-bd28-10a7e16d3475")
|
|
||||||
)
|
|
||||||
(pin "2"
|
|
||||||
(uuid "9568b812-3f8b-4083-8f2d-597e20f6d7ca")
|
|
||||||
)
|
|
||||||
(pin "3"
|
|
||||||
(uuid "decf576a-9dba-4f35-b79f-af87ec95b2d1")
|
|
||||||
)
|
|
||||||
(instances
|
|
||||||
(project "PlantCtrlESP32"
|
|
||||||
(path "/c26e8d55-0b6e-4c4e-b7c8-b1fed973201c"
|
|
||||||
(reference "RV2")
|
|
||||||
(unit 1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(symbol
|
(symbol
|
||||||
(lib_id "Device:R")
|
(lib_id "Device:R")
|
||||||
(at 455.93 168.91 90)
|
(at 455.93 168.91 90)
|
||||||
@ -49321,88 +49212,6 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(symbol
|
|
||||||
(lib_id "Device:R_Potentiometer")
|
|
||||||
(at 468.63 532.13 0)
|
|
||||||
(mirror y)
|
|
||||||
(unit 1)
|
|
||||||
(exclude_from_sim no)
|
|
||||||
(in_bom yes)
|
|
||||||
(on_board yes)
|
|
||||||
(dnp no)
|
|
||||||
(uuid "b332c31b-5371-4806-9189-268fb6732856")
|
|
||||||
(property "Reference" "RV3"
|
|
||||||
(at 471.17 530.86 0)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(justify right)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(property "Value" "50k"
|
|
||||||
(at 471.17 533.4 0)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(justify right)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(property "Footprint" "Potentiometer_THT:Potentiometer_Bourns_3299W_Vertical"
|
|
||||||
(at 468.63 532.13 0)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(hide yes)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(property "Datasheet" "~"
|
|
||||||
(at 468.63 532.13 0)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(hide yes)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(property "Description" ""
|
|
||||||
(at 468.63 532.13 0)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(hide yes)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(property "LCSC_PART_NUMBER" "C118911"
|
|
||||||
(at 468.63 532.13 0)
|
|
||||||
(effects
|
|
||||||
(font
|
|
||||||
(size 1.27 1.27)
|
|
||||||
)
|
|
||||||
(hide yes)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(pin "1"
|
|
||||||
(uuid "7d4215e3-1540-4495-b06d-f0ce9c684265")
|
|
||||||
)
|
|
||||||
(pin "2"
|
|
||||||
(uuid "ad14874f-5a05-4695-b1a8-1273fccc40e1")
|
|
||||||
)
|
|
||||||
(pin "3"
|
|
||||||
(uuid "3d1aa074-5e83-4f3a-a188-1b671f6f6aaf")
|
|
||||||
)
|
|
||||||
(instances
|
|
||||||
(project "PlantCtrlESP32"
|
|
||||||
(path "/c26e8d55-0b6e-4c4e-b7c8-b1fed973201c"
|
|
||||||
(reference "RV3")
|
|
||||||
(unit 1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(symbol
|
(symbol
|
||||||
(lib_id "Device:R")
|
(lib_id "Device:R")
|
||||||
(at 425.45 97.79 180)
|
(at 425.45 97.79 180)
|
||||||
@ -51857,6 +51666,76 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
(symbol
|
||||||
|
(lib_id "Device:R")
|
||||||
|
(at 468.63 532.13 0)
|
||||||
|
(unit 1)
|
||||||
|
(exclude_from_sim no)
|
||||||
|
(in_bom yes)
|
||||||
|
(on_board yes)
|
||||||
|
(dnp no)
|
||||||
|
(fields_autoplaced yes)
|
||||||
|
(uuid "cb9bb05b-678c-4bc9-b5e7-565616fe994f")
|
||||||
|
(property "Reference" "R42"
|
||||||
|
(at 471.17 530.8599 0)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(justify left)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Value" "~27K for 14.7v Bat V"
|
||||||
|
(at 471.17 533.3999 0)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(justify left)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Footprint" "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P2.54mm_Vertical"
|
||||||
|
(at 466.852 532.13 90)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(hide yes)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Datasheet" "~"
|
||||||
|
(at 468.63 532.13 0)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(hide yes)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Description" "Resistor"
|
||||||
|
(at 468.63 532.13 0)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(hide yes)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(pin "2"
|
||||||
|
(uuid "11d19adf-8b79-4b76-8c72-5a0b587fccb9")
|
||||||
|
)
|
||||||
|
(pin "1"
|
||||||
|
(uuid "135bdf41-3993-41ad-aa61-26216fd8a4c7")
|
||||||
|
)
|
||||||
|
(instances
|
||||||
|
(project "PlantCtrlESP32"
|
||||||
|
(path "/c26e8d55-0b6e-4c4e-b7c8-b1fed973201c"
|
||||||
|
(reference "R42")
|
||||||
|
(unit 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
(symbol
|
(symbol
|
||||||
(lib_id "ESP32-DEVKITC-32D:SL2300")
|
(lib_id "ESP32-DEVKITC-32D:SL2300")
|
||||||
(at 350.52 405.13 0)
|
(at 350.52 405.13 0)
|
||||||
@ -55142,6 +55021,76 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
(symbol
|
||||||
|
(lib_id "Device:R")
|
||||||
|
(at 396.24 509.27 0)
|
||||||
|
(unit 1)
|
||||||
|
(exclude_from_sim no)
|
||||||
|
(in_bom yes)
|
||||||
|
(on_board yes)
|
||||||
|
(dnp no)
|
||||||
|
(fields_autoplaced yes)
|
||||||
|
(uuid "f2f19577-b00b-42f7-98ed-238cf6ad418d")
|
||||||
|
(property "Reference" "R39"
|
||||||
|
(at 398.78 507.9999 0)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(justify left)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Value" "~33K for 17.1v MPPT"
|
||||||
|
(at 398.78 510.5399 0)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(justify left)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Footprint" "Resistor_THT:R_Axial_DIN0207_L6.3mm_D2.5mm_P2.54mm_Vertical"
|
||||||
|
(at 394.462 509.27 90)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(hide yes)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Datasheet" "~"
|
||||||
|
(at 396.24 509.27 0)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(hide yes)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Description" "Resistor"
|
||||||
|
(at 396.24 509.27 0)
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
)
|
||||||
|
(hide yes)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(pin "2"
|
||||||
|
(uuid "8568f007-2f46-4313-b905-dc9d5ce34576")
|
||||||
|
)
|
||||||
|
(pin "1"
|
||||||
|
(uuid "81fdebab-ba58-4c97-8317-1a2dd42e8715")
|
||||||
|
)
|
||||||
|
(instances
|
||||||
|
(project ""
|
||||||
|
(path "/c26e8d55-0b6e-4c4e-b7c8-b1fed973201c"
|
||||||
|
(reference "R39")
|
||||||
|
(unit 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
(symbol
|
(symbol
|
||||||
(lib_id "Diode:BAS40-04")
|
(lib_id "Diode:BAS40-04")
|
||||||
(at 561.34 129.54 90)
|
(at 561.34 129.54 90)
|
||||||
|
File diff suppressed because one or more lines are too long
@ -28,7 +28,9 @@ command = [
|
|||||||
"save-image",
|
"save-image",
|
||||||
"--chip",
|
"--chip",
|
||||||
"esp32c6",
|
"esp32c6",
|
||||||
"image.bin"
|
"image.bin",
|
||||||
|
"--partition-table",
|
||||||
|
"partitions.csv"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -66,7 +68,7 @@ once_cell = "1.19.0"
|
|||||||
anyhow = { version = "1.0.75", features = ["std", "backtrace"] }
|
anyhow = { version = "1.0.75", features = ["std", "backtrace"] }
|
||||||
average = { version = "0.14.1" , features = ["std"] }
|
average = { version = "0.14.1" , features = ["std"] }
|
||||||
bit_field = "0.10.2"
|
bit_field = "0.10.2"
|
||||||
strum = { version = "0.26.1", features = ["derive"] }
|
strum = { version = "0.27.0", features = ["derive"] }
|
||||||
measurements = "0.11.0"
|
measurements = "0.11.0"
|
||||||
schemars = "0.8.16"
|
schemars = "0.8.16"
|
||||||
|
|
||||||
@ -82,6 +84,8 @@ url = "2.5.3"
|
|||||||
crc = "3.2.1"
|
crc = "3.2.1"
|
||||||
bincode = "1.3.3"
|
bincode = "1.3.3"
|
||||||
ringbuffer = "0.15.0"
|
ringbuffer = "0.15.0"
|
||||||
|
text-template = "0.1.0"
|
||||||
|
strum_macros = "0.27.0"
|
||||||
|
|
||||||
|
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
|
158
rust/src/log/mod.rs
Normal file
158
rust/src/log/mod.rs
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
use std::{collections::HashMap, sync::Mutex};
|
||||||
|
use serde::Serialize;
|
||||||
|
use strum_macros::IntoStaticStr;
|
||||||
|
|
||||||
|
use esp_idf_svc::systime::EspSystemTime;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use ringbuffer::{ConstGenericRingBuffer, RingBuffer};
|
||||||
|
use text_template::Template;
|
||||||
|
|
||||||
|
const TXT_SHORT_LENGTH:usize = 8;
|
||||||
|
const TXT_LONG_LENGTH:usize = 32;
|
||||||
|
|
||||||
|
const BUFFER_SIZE:usize = 210;
|
||||||
|
|
||||||
|
#[link_section = ".rtc.data"]
|
||||||
|
static mut BUFFER:ConstGenericRingBuffer::<LogEntry, BUFFER_SIZE> = ConstGenericRingBuffer::<LogEntry, BUFFER_SIZE>::new();
|
||||||
|
|
||||||
|
static BUFFER_ACCESS: Lazy<Mutex<&mut ConstGenericRingBuffer::<LogEntry, BUFFER_SIZE>>> = Lazy::new(|| unsafe { Mutex::new(&mut BUFFER) });
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Serialize, Debug, Clone)]
|
||||||
|
pub struct LogEntry {
|
||||||
|
pub timestamp: u64,
|
||||||
|
pub message_id: u32,
|
||||||
|
pub a: u32,
|
||||||
|
pub b: u32,
|
||||||
|
pub txt_short: heapless::String<TXT_SHORT_LENGTH>,
|
||||||
|
pub txt_long: heapless::String<TXT_LONG_LENGTH>
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init(){
|
||||||
|
unsafe {
|
||||||
|
BUFFER = ConstGenericRingBuffer::<LogEntry, BUFFER_SIZE>::new();
|
||||||
|
};
|
||||||
|
let mut access = BUFFER_ACCESS.lock().unwrap();
|
||||||
|
access.drain().for_each(|_| {});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn limit_length <const LIMIT:usize> (input: &str, target: &mut heapless::String<LIMIT>){
|
||||||
|
for char in input.chars() {
|
||||||
|
match target.push(char) {
|
||||||
|
Ok(_) => {}, //continue adding chars
|
||||||
|
Err(_) => {
|
||||||
|
//clear space for two asci chars
|
||||||
|
while target.len()+2 >= LIMIT {
|
||||||
|
target.pop().unwrap();
|
||||||
|
}
|
||||||
|
//add .. to shortened strings
|
||||||
|
target.push('.').unwrap();
|
||||||
|
target.push('.').unwrap();
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_log() -> Vec<LogEntry>{
|
||||||
|
let buffer = BUFFER_ACCESS.lock().unwrap();
|
||||||
|
let mut read_copy = Vec::new();
|
||||||
|
for entry in buffer.iter() {
|
||||||
|
let copy = entry.clone();
|
||||||
|
read_copy.push(copy);
|
||||||
|
}
|
||||||
|
drop(buffer);
|
||||||
|
return read_copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn log(message_key: LogMessage, number_a: u32, number_b: u32, txt_short:&str, txt_long:&str){
|
||||||
|
let mut txt_short_stack:heapless::String<TXT_SHORT_LENGTH> = heapless::String::new();
|
||||||
|
let mut txt_long_stack:heapless::String<TXT_LONG_LENGTH> = heapless::String::new();
|
||||||
|
|
||||||
|
limit_length(txt_short, &mut txt_short_stack);
|
||||||
|
limit_length(txt_long, &mut txt_long_stack);
|
||||||
|
|
||||||
|
let time = EspSystemTime {}.now().as_millis() as u64;
|
||||||
|
|
||||||
|
let template_string:&str = message_key.into();
|
||||||
|
|
||||||
|
|
||||||
|
let mut values: HashMap<&str, &str> = HashMap::new();
|
||||||
|
let number_a_str = number_a.to_string();
|
||||||
|
let number_b_str = number_b.to_string();
|
||||||
|
|
||||||
|
values.insert("number_a", &number_a_str);
|
||||||
|
values.insert("number_b", &number_b_str);
|
||||||
|
values.insert("txt_short", txt_short);
|
||||||
|
values.insert("txt_long", txt_long);
|
||||||
|
|
||||||
|
let template = Template::from(template_string);
|
||||||
|
let serial_entry = template.fill_in(&values);
|
||||||
|
|
||||||
|
println!("{serial_entry}");
|
||||||
|
|
||||||
|
|
||||||
|
let entry = LogEntry{
|
||||||
|
timestamp: time,
|
||||||
|
message_id: 1,
|
||||||
|
a: number_a,
|
||||||
|
b: number_b,
|
||||||
|
txt_short: txt_short_stack,
|
||||||
|
txt_long: txt_long_stack,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
let mut buffer = BUFFER_ACCESS.lock().unwrap();
|
||||||
|
buffer.push(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn within_limit() {
|
||||||
|
let test = "12345678";
|
||||||
|
|
||||||
|
let mut txt_short_stack:heapless::String<TXT_SHORT_LENGTH> = heapless::String::new();
|
||||||
|
let mut txt_long_stack:heapless::String<TXT_LONG_LENGTH> = heapless::String::new();
|
||||||
|
limit_length(test, &mut txt_short_stack);
|
||||||
|
limit_length(test, &mut txt_long_stack);
|
||||||
|
|
||||||
|
assert_eq!(txt_short_stack.as_str(), test);
|
||||||
|
assert_eq!(txt_long_stack.as_str(), test);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(IntoStaticStr)]
|
||||||
|
pub enum LogMessage {
|
||||||
|
#[strum(serialize = "Reset due to {{txt_long}} requires rtc clear {{a}} and force config mode {{b}}")]
|
||||||
|
reset_reason,
|
||||||
|
#[strum(serialize = "Current restart to conf mode {{a}}")]
|
||||||
|
restart_to_config,
|
||||||
|
#[strum(serialize = "Current low voltage detection is {{a}}")]
|
||||||
|
low_voltage,
|
||||||
|
#[strum(serialize = "Error communicating with battery!! {{txt_long}}")]
|
||||||
|
battery_communication_error,
|
||||||
|
#[strum(serialize = "Tank sensor raw {{a}} percent {{b}}")]
|
||||||
|
sensor_tank_raw,
|
||||||
|
#[strum(serialize = "raw measure unscaled {{a}} hz {{b}}, plant {{txt_short}} sensor {{txt_long}}")]
|
||||||
|
raw_measure,
|
||||||
|
#[strum(serialize = "IP info: {{txt_long}}")]
|
||||||
|
wifi_info,
|
||||||
|
#[strum(serialize = "Plant:{{txt_short}} a:{{a}} b:{{b}}")]
|
||||||
|
test_sensor,
|
||||||
|
#[strum(serialize = "Stay alive topic is {{txt_long}}")]
|
||||||
|
stay_alive,
|
||||||
|
#[strum(serialize = "Connecting mqtt {{txt_short}} with id {{txt_long}}")]
|
||||||
|
mqtt_info,
|
||||||
|
#[strum(serialize = "Received stay alive with value {{txt_short}}")]
|
||||||
|
mqtt_stay_alive_rec,
|
||||||
|
#[strum(serialize = "Unknown topic recieved {{txt_long}}")]
|
||||||
|
unknown_topic,
|
||||||
|
}
|
@ -3,7 +3,7 @@ use std::{
|
|||||||
sync::{atomic::AtomicBool, Arc, Mutex},
|
sync::{atomic::AtomicBool, Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::{bail, Result};
|
||||||
use chrono::{DateTime, Datelike, TimeDelta, Timelike, Utc};
|
use chrono::{DateTime, Datelike, TimeDelta, Timelike, Utc};
|
||||||
use chrono_tz::{Europe::Berlin, Tz};
|
use chrono_tz::{Europe::Berlin, Tz};
|
||||||
|
|
||||||
@ -22,7 +22,6 @@ use esp_idf_sys::{
|
|||||||
esp_ota_img_states_t_ESP_OTA_IMG_VALID,
|
esp_ota_img_states_t_ESP_OTA_IMG_VALID,
|
||||||
vTaskDelay
|
vTaskDelay
|
||||||
};
|
};
|
||||||
use log::error;
|
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use plant_hal::{PlantCtrlBoard, PlantHal, PLANT_COUNT};
|
use plant_hal::{PlantCtrlBoard, PlantHal, PLANT_COUNT};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -32,10 +31,12 @@ use crate::{
|
|||||||
espota::{mark_app_valid, rollback_and_reboot},
|
espota::{mark_app_valid, rollback_and_reboot},
|
||||||
webserver::webserver::httpd,
|
webserver::webserver::httpd,
|
||||||
};
|
};
|
||||||
|
mod log;
|
||||||
mod config;
|
mod config;
|
||||||
pub mod espota;
|
pub mod espota;
|
||||||
pub mod plant_hal;
|
pub mod plant_hal;
|
||||||
|
|
||||||
|
|
||||||
const TIME_ZONE: Tz = Berlin;
|
const TIME_ZONE: Tz = Berlin;
|
||||||
|
|
||||||
const MOIST_SENSOR_MAX_FREQUENCY: u32 = 250000; // 60kHz (500Hz margin)
|
const MOIST_SENSOR_MAX_FREQUENCY: u32 = 250000; // 60kHz (500Hz margin)
|
||||||
@ -72,9 +73,9 @@ struct LightState {
|
|||||||
#[derive(Debug, PartialEq, Default)]
|
#[derive(Debug, PartialEq, Default)]
|
||||||
struct PlantState {
|
struct PlantState {
|
||||||
a: Option<u8>,
|
a: Option<u8>,
|
||||||
a_raw: Option<i32>,
|
a_raw: Option<u32>,
|
||||||
b: Option<u8>,
|
b: Option<u8>,
|
||||||
b_raw: Option<i32>,
|
b_raw: Option<u32>,
|
||||||
consecutive_pump_count: u32,
|
consecutive_pump_count: u32,
|
||||||
after_p: Option<u8>,
|
after_p: Option<u8>,
|
||||||
do_water: bool,
|
do_water: bool,
|
||||||
@ -142,14 +143,14 @@ fn safe_main() -> anyhow::Result<()> {
|
|||||||
esp_idf_svc::log::EspLogger::initialize_default();
|
esp_idf_svc::log::EspLogger::initialize_default();
|
||||||
|
|
||||||
if esp_idf_sys::CONFIG_MAIN_TASK_STACK_SIZE < 25000 {
|
if esp_idf_sys::CONFIG_MAIN_TASK_STACK_SIZE < 25000 {
|
||||||
error!(
|
bail!(
|
||||||
"stack too small: {} bail!",
|
"stack too small: {} bail!",
|
||||||
esp_idf_sys::CONFIG_MAIN_TASK_STACK_SIZE
|
esp_idf_sys::CONFIG_MAIN_TASK_STACK_SIZE
|
||||||
);
|
);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
log::info!("Startup Rust");
|
println!("Startup Rust");
|
||||||
|
|
||||||
let mut to_config = false;
|
let mut to_config = false;
|
||||||
|
|
||||||
@ -186,6 +187,7 @@ fn safe_main() -> anyhow::Result<()> {
|
|||||||
};
|
};
|
||||||
println!("{}", ota_state_string);
|
println!("{}", ota_state_string);
|
||||||
|
|
||||||
|
|
||||||
println!("Board hal init");
|
println!("Board hal init");
|
||||||
let mut board: std::sync::MutexGuard<'_, PlantCtrlBoard<'_>> = BOARD_ACCESS.lock().unwrap();
|
let mut board: std::sync::MutexGuard<'_, PlantCtrlBoard<'_>> = BOARD_ACCESS.lock().unwrap();
|
||||||
board.general_fault(false);
|
board.general_fault(false);
|
||||||
@ -207,7 +209,7 @@ fn safe_main() -> anyhow::Result<()> {
|
|||||||
match time {
|
match time {
|
||||||
Ok(cur) => cur,
|
Ok(cur) => cur,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
log::error!("time error {}", err);
|
bail!("time error {}", err);
|
||||||
DateTime::from_timestamp_millis(0).unwrap()
|
DateTime::from_timestamp_millis(0).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -284,7 +286,7 @@ fn safe_main() -> anyhow::Result<()> {
|
|||||||
ip_address = Some(ip_info.ip.to_string());
|
ip_address = Some(ip_info.ip.to_string());
|
||||||
wifi = true;
|
wifi = true;
|
||||||
|
|
||||||
match board.sntp(1000 * 5) {
|
match board.sntp(1000 * 10) {
|
||||||
Ok(new_time) => {
|
Ok(new_time) => {
|
||||||
println!("Using time from sntp");
|
println!("Using time from sntp");
|
||||||
let _ = board.set_rtc_time(&new_time);
|
let _ = board.set_rtc_time(&new_time);
|
||||||
|
@ -2,6 +2,7 @@ use bq34z100::{Bq34Z100Error, Bq34z100g1, Bq34z100g1Driver};
|
|||||||
|
|
||||||
use chrono_tz::Tz;
|
use chrono_tz::Tz;
|
||||||
use ds323x::{DateTimeAccess, Ds323x};
|
use ds323x::{DateTimeAccess, Ds323x};
|
||||||
|
use crate::log::{init, LogMessage};
|
||||||
|
|
||||||
use eeprom24x::{Eeprom24x, Eeprom24xTrait, SlaveAddr};
|
use eeprom24x::{Eeprom24x, Eeprom24xTrait, SlaveAddr};
|
||||||
use embedded_hal_bus::i2c::MutexDevice;
|
use embedded_hal_bus::i2c::MutexDevice;
|
||||||
@ -22,6 +23,7 @@ use esp_idf_svc::mqtt::client::{EspMqttClient, LwtConfiguration, MqttClientConfi
|
|||||||
use esp_idf_svc::nvs::EspDefaultNvsPartition;
|
use esp_idf_svc::nvs::EspDefaultNvsPartition;
|
||||||
use esp_idf_svc::wifi::config::{ScanConfig, ScanType};
|
use esp_idf_svc::wifi::config::{ScanConfig, ScanType};
|
||||||
use esp_idf_svc::wifi::EspWifi;
|
use esp_idf_svc::wifi::EspWifi;
|
||||||
|
use log::logger;
|
||||||
use measurements::Temperature;
|
use measurements::Temperature;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use plant_ctrl2::sipo::ShiftRegister40;
|
use plant_ctrl2::sipo::ShiftRegister40;
|
||||||
@ -46,7 +48,7 @@ use std::time::Duration;
|
|||||||
|
|
||||||
use embedded_hal::digital::OutputPin;
|
use embedded_hal::digital::OutputPin;
|
||||||
use esp_idf_hal::delay::Delay;
|
use esp_idf_hal::delay::Delay;
|
||||||
use esp_idf_hal::gpio::{AnyInputPin, Gpio18, Gpio5, Gpio7, Gpio8, IOPin, InputOutput, Level, PinDriver, Pull};
|
use esp_idf_hal::gpio::{AnyInputPin, Gpio18, Gpio5, IOPin, InputOutput, Level, PinDriver, Pull};
|
||||||
use esp_idf_hal::pcnt::{
|
use esp_idf_hal::pcnt::{
|
||||||
PcntChannel, PcntChannelConfig, PcntControlMode, PcntCountMode, PcntDriver, PinIndex,
|
PcntChannel, PcntChannelConfig, PcntControlMode, PcntCountMode, PcntDriver, PinIndex,
|
||||||
};
|
};
|
||||||
@ -54,11 +56,12 @@ use esp_idf_hal::prelude::Peripherals;
|
|||||||
use esp_idf_hal::reset::ResetReason;
|
use esp_idf_hal::reset::ResetReason;
|
||||||
use esp_idf_svc::sntp::{self, SyncStatus};
|
use esp_idf_svc::sntp::{self, SyncStatus};
|
||||||
use esp_idf_svc::systime::EspSystemTime;
|
use esp_idf_svc::systime::EspSystemTime;
|
||||||
use esp_idf_sys::{esp, esp_spiffs_check, gpio_hold_dis, gpio_hold_en, vTaskDelay, EspError};
|
use esp_idf_sys::{gpio_hold_dis, gpio_hold_en, vTaskDelay, EspError};
|
||||||
use one_wire_bus::OneWire;
|
use one_wire_bus::OneWire;
|
||||||
|
|
||||||
use crate::config::{self, PlantControllerConfig};
|
use crate::config::{self, PlantControllerConfig};
|
||||||
use crate::espota::mark_app_valid;
|
use crate::espota::mark_app_valid;
|
||||||
|
use crate::log::log;
|
||||||
use crate::{plant_hal, to_string, STAY_ALIVE};
|
use crate::{plant_hal, to_string, STAY_ALIVE};
|
||||||
|
|
||||||
//Only support for 8 right now!
|
//Only support for 8 right now!
|
||||||
@ -80,14 +83,15 @@ const PUMP5_BIT: usize = 5;
|
|||||||
const PUMP6_BIT: usize = 6;
|
const PUMP6_BIT: usize = 6;
|
||||||
const PUMP7_BIT: usize = 7;
|
const PUMP7_BIT: usize = 7;
|
||||||
|
|
||||||
|
|
||||||
const MS_0: usize = 8;
|
const MS_0: usize = 8;
|
||||||
const MS_4: usize = 9;
|
const MS_4: usize = 9;
|
||||||
const MS_2: usize = 10;
|
const MS_2: usize = 10;
|
||||||
const MS_3: usize = 11;
|
const MS_3: usize = 11;
|
||||||
const SENSOR_ON: usize = 12;
|
const SENSOR_ON: usize = 12;
|
||||||
const MS_1: usize = 13;
|
const MS_1: usize = 13;
|
||||||
//unused 14
|
const CHARGING: usize = 14;
|
||||||
//unused 15
|
const AWAKE: usize = 15;
|
||||||
|
|
||||||
const FAULT_3: usize = 16;
|
const FAULT_3: usize = 16;
|
||||||
const FAULT_8: usize = 17;
|
const FAULT_8: usize = 17;
|
||||||
@ -128,10 +132,6 @@ static mut LOW_VOLTAGE_DETECTED: bool = false;
|
|||||||
#[link_section = ".rtc.data"]
|
#[link_section = ".rtc.data"]
|
||||||
static mut RESTART_TO_CONF: bool = false;
|
static mut RESTART_TO_CONF: bool = false;
|
||||||
|
|
||||||
const BUFFER_SIZE:usize = 120;
|
|
||||||
const ENTRY_SIZE:usize = 120;
|
|
||||||
#[link_section = ".rtc.data"]
|
|
||||||
static mut BUFFER:ConstGenericRingBuffer::<heapless::String<ENTRY_SIZE>, BUFFER_SIZE> = ConstGenericRingBuffer::<heapless::String<ENTRY_SIZE>, BUFFER_SIZE>::new();
|
|
||||||
|
|
||||||
|
|
||||||
pub struct FileSystemSizeInfo {
|
pub struct FileSystemSizeInfo {
|
||||||
@ -266,9 +266,7 @@ impl PlantCtrlBoard<'_> {
|
|||||||
OkStd(_) => {},
|
OkStd(_) => {},
|
||||||
Err(err) => bail!("Error reading eeprom header {:?}", err),
|
Err(err) => bail!("Error reading eeprom header {:?}", err),
|
||||||
};
|
};
|
||||||
println!("Raw header is {:?} with size {}", header_page_buffer , store);
|
|
||||||
let header:BackupHeader = bincode::deserialize(&header_page_buffer)?;
|
let header:BackupHeader = bincode::deserialize(&header_page_buffer)?;
|
||||||
println!("Reading eeprom header {header:?}");
|
|
||||||
|
|
||||||
let data_start_address = 1*self.eeprom.page_size() as u32;
|
let data_start_address = 1*self.eeprom.page_size() as u32;
|
||||||
let mut data_buffer = vec![0_u8; header.size];
|
let mut data_buffer = vec![0_u8; header.size];
|
||||||
@ -282,19 +280,6 @@ impl PlantCtrlBoard<'_> {
|
|||||||
bail!("Invalid checksum, got {} but expected {}", checksum, header.crc16 );
|
bail!("Invalid checksum, got {} but expected {}", checksum, header.crc16 );
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let value = heapless::String::try_from("dummy").unwrap();
|
|
||||||
BUFFER.push(value);
|
|
||||||
}
|
|
||||||
unsafe {
|
|
||||||
for entry in BUFFER.iter() {
|
|
||||||
let test = entry.as_bytes().to_owned();
|
|
||||||
for p in test {
|
|
||||||
data_buffer.push(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(data_buffer)
|
Ok(data_buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,9 +302,7 @@ impl PlantCtrlBoard<'_> {
|
|||||||
bail!("Size limit reached header is {}, but firest page is only {}",encoded.len(), page_size)
|
bail!("Size limit reached header is {}, but firest page is only {}",encoded.len(), page_size)
|
||||||
}
|
}
|
||||||
let as_u8:&[u8] = &encoded;
|
let as_u8:&[u8] = &encoded;
|
||||||
|
|
||||||
println!("Raw header is {:?} with size {}", as_u8 , as_u8.len());
|
|
||||||
|
|
||||||
match self.eeprom.write_page(0, as_u8) {
|
match self.eeprom.write_page(0, as_u8) {
|
||||||
OkStd(_) => {},
|
OkStd(_) => {},
|
||||||
Err(err) => bail!("Error writing eeprom {:?}", err),
|
Err(err) => bail!("Error writing eeprom {:?}", err),
|
||||||
@ -375,13 +358,11 @@ impl PlantCtrlBoard<'_> {
|
|||||||
let mut iter_error = None;
|
let mut iter_error = None;
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
|
|
||||||
println!("Filename {filename}");
|
|
||||||
let filepath = Path::new(BASE_PATH);
|
let filepath = Path::new(BASE_PATH);
|
||||||
let read_dir = fs::read_dir(filepath);
|
let read_dir = fs::read_dir(filepath);
|
||||||
match read_dir {
|
match read_dir {
|
||||||
OkStd(read_dir) => {
|
OkStd(read_dir) => {
|
||||||
for item in read_dir {
|
for item in read_dir {
|
||||||
println!("start loop");
|
|
||||||
match item {
|
match item {
|
||||||
OkStd(file) => {
|
OkStd(file) => {
|
||||||
let f = FileInfo {
|
let f = FileInfo {
|
||||||
@ -392,7 +373,6 @@ impl PlantCtrlBoard<'_> {
|
|||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
as usize,
|
as usize,
|
||||||
};
|
};
|
||||||
println!("fileinfo {f:?}");
|
|
||||||
result.push(f);
|
result.push(f);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@ -503,8 +483,8 @@ impl PlantCtrlBoard<'_> {
|
|||||||
let r2 = median * 50.0 / (3.3 - median);
|
let r2 = median * 50.0 / (3.3 - median);
|
||||||
let mut percent = r2 / 190_f32 * 100_f32;
|
let mut percent = r2 / 190_f32 * 100_f32;
|
||||||
percent = percent.clamp(0.0, 100.0);
|
percent = percent.clamp(0.0, 100.0);
|
||||||
|
log(LogMessage::sensor_tank_raw, median as u32, percent as u32, "","");
|
||||||
|
|
||||||
println!("Tank sensor raw {} percent {}", median, percent);
|
|
||||||
return Ok(percent as u16);
|
return Ok(percent as u16);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -620,7 +600,7 @@ impl PlantCtrlBoard<'_> {
|
|||||||
self.time()
|
self.time()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn measure_moisture_hz(&mut self, plant: usize, sensor: Sensor) -> Result<i32> {
|
pub fn measure_moisture_hz(&mut self, plant: usize, sensor: Sensor) -> Result<u32> {
|
||||||
let sensor_channel = match sensor {
|
let sensor_channel = match sensor {
|
||||||
Sensor::A => match plant {
|
Sensor::A => match plant {
|
||||||
0 => SENSOR_A_1,
|
0 => SENSOR_A_1,
|
||||||
@ -646,7 +626,7 @@ impl PlantCtrlBoard<'_> {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut results = [0; REPEAT_MOIST_MEASURE];
|
let mut results = [0_u32; REPEAT_MOIST_MEASURE];
|
||||||
for repeat in 0..REPEAT_MOIST_MEASURE {
|
for repeat in 0..REPEAT_MOIST_MEASURE {
|
||||||
self.signal_counter.counter_pause()?;
|
self.signal_counter.counter_pause()?;
|
||||||
self.signal_counter.counter_clear()?;
|
self.signal_counter.counter_clear()?;
|
||||||
@ -675,13 +655,9 @@ impl PlantCtrlBoard<'_> {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
delay.delay_ms(10);
|
delay.delay_ms(10);
|
||||||
let unscaled = self.signal_counter.get_counter_value()? as i32;
|
let unscaled = self.signal_counter.get_counter_value()? as i32;
|
||||||
let hz = (unscaled as f32 * factor) as i32;
|
let hz = (unscaled as f32 * factor) as u32;
|
||||||
println!(
|
log(LogMessage::raw_measure, unscaled as u32, hz as u32, &plant.to_string(), &format!("{sensor:?}"));
|
||||||
"raw measure unscaled {} hz {}, plant {} sensor {:?}",
|
|
||||||
unscaled, hz, plant, sensor
|
|
||||||
);
|
|
||||||
results[repeat] = hz;
|
results[repeat] = hz;
|
||||||
//println!("Measuring {:?} @ {} with {}", sensor, plant, hz);
|
|
||||||
}
|
}
|
||||||
results.sort();
|
results.sort();
|
||||||
|
|
||||||
@ -745,7 +721,6 @@ impl PlantCtrlBoard<'_> {
|
|||||||
let delay = Delay::new_default();
|
let delay = Delay::new_default();
|
||||||
let mut counter = 0_u32;
|
let mut counter = 0_u32;
|
||||||
while !self.wifi_driver.is_connected()? {
|
while !self.wifi_driver.is_connected()? {
|
||||||
println!("Waiting for station connection");
|
|
||||||
delay.delay_ms(250);
|
delay.delay_ms(250);
|
||||||
counter += 250;
|
counter += 250;
|
||||||
if counter > max_wait {
|
if counter > max_wait {
|
||||||
@ -758,7 +733,6 @@ impl PlantCtrlBoard<'_> {
|
|||||||
println!("Should be connected now");
|
println!("Should be connected now");
|
||||||
|
|
||||||
while !self.wifi_driver.is_up()? {
|
while !self.wifi_driver.is_up()? {
|
||||||
println!("Waiting for network being up");
|
|
||||||
delay.delay_ms(250);
|
delay.delay_ms(250);
|
||||||
counter += 250;
|
counter += 250;
|
||||||
if counter > max_wait {
|
if counter > max_wait {
|
||||||
@ -770,7 +744,7 @@ impl PlantCtrlBoard<'_> {
|
|||||||
}
|
}
|
||||||
//update freertos registers ;)
|
//update freertos registers ;)
|
||||||
let address = self.wifi_driver.sta_netif().get_ip_info()?;
|
let address = self.wifi_driver.sta_netif().get_ip_info()?;
|
||||||
println!("IP info: {:?}", address);
|
log(LogMessage::wifi_info, 0 ,0,"", &format!("{address:?}"));
|
||||||
Ok(address)
|
Ok(address)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -908,9 +882,16 @@ impl PlantCtrlBoard<'_> {
|
|||||||
for plant in 0..PLANT_COUNT {
|
for plant in 0..PLANT_COUNT {
|
||||||
let a = self.measure_moisture_hz(plant, plant_hal::Sensor::A);
|
let a = self.measure_moisture_hz(plant, plant_hal::Sensor::A);
|
||||||
let b = self.measure_moisture_hz(plant, plant_hal::Sensor::B);
|
let b = self.measure_moisture_hz(plant, plant_hal::Sensor::B);
|
||||||
print!("P:{} a:{:?} b:{:?}", plant, a, b)
|
let aa = match a {
|
||||||
|
OkStd(a) => a as u32,
|
||||||
|
Err(_) => u32::MAX
|
||||||
|
};
|
||||||
|
let bb = match b {
|
||||||
|
OkStd(b) => b as u32,
|
||||||
|
Err(_) => u32::MAX
|
||||||
|
};
|
||||||
|
log(LogMessage::test_sensor, aa ,bb,&plant.to_string(), "");
|
||||||
}
|
}
|
||||||
println!();
|
|
||||||
Delay::new_default().delay_ms(10);
|
Delay::new_default().delay_ms(10);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -958,18 +939,15 @@ impl PlantCtrlBoard<'_> {
|
|||||||
let round_trip_ok = Arc::new(AtomicBool::new(false));
|
let round_trip_ok = Arc::new(AtomicBool::new(false));
|
||||||
let round_trip_topic = format!("{}/internal/roundtrip", base_topic);
|
let round_trip_topic = format!("{}/internal/roundtrip", base_topic);
|
||||||
let stay_alive_topic = format!("{}/stay_alive", base_topic);
|
let stay_alive_topic = format!("{}/stay_alive", base_topic);
|
||||||
println!("Stay alive topic is {}", stay_alive_topic);
|
log(LogMessage::stay_alive, 0 ,0,"", &stay_alive_topic);
|
||||||
|
|
||||||
let mqtt_connected_event_received_copy = mqtt_connected_event_received.clone();
|
let mqtt_connected_event_received_copy = mqtt_connected_event_received.clone();
|
||||||
let mqtt_connected_event_ok_copy = mqtt_connected_event_ok.clone();
|
let mqtt_connected_event_ok_copy = mqtt_connected_event_ok.clone();
|
||||||
let stay_alive_topic_copy = stay_alive_topic.clone();
|
let stay_alive_topic_copy = stay_alive_topic.clone();
|
||||||
let round_trip_topic_copy = round_trip_topic.clone();
|
let round_trip_topic_copy = round_trip_topic.clone();
|
||||||
let round_trip_ok_copy = round_trip_ok.clone();
|
let round_trip_ok_copy = round_trip_ok.clone();
|
||||||
println!(
|
let client_id = mqtt_client_config.client_id.unwrap_or("not set");
|
||||||
"Connecting mqtt {} with id {}",
|
log(LogMessage::mqtt_info, 0 ,0,client_id, &mqtt_url);
|
||||||
mqtt_url,
|
|
||||||
mqtt_client_config.client_id.unwrap_or("not set")
|
|
||||||
);
|
|
||||||
let mut client = EspMqttClient::new_cb(&mqtt_url, &mqtt_client_config, move |event| {
|
let mut client = EspMqttClient::new_cb(&mqtt_url, &mqtt_client_config, move |event| {
|
||||||
let payload = event.payload();
|
let payload = event.payload();
|
||||||
match payload {
|
match payload {
|
||||||
@ -987,10 +965,10 @@ impl PlantCtrlBoard<'_> {
|
|||||||
} else if topic.eq(stay_alive_topic_copy.as_str()) {
|
} else if topic.eq(stay_alive_topic_copy.as_str()) {
|
||||||
let value =
|
let value =
|
||||||
data.eq_ignore_ascii_case("true") || data.eq_ignore_ascii_case("1");
|
data.eq_ignore_ascii_case("true") || data.eq_ignore_ascii_case("1");
|
||||||
println!("Received stay alive with value {}", value);
|
log(LogMessage::mqtt_stay_alive_rec, 0 ,0,&data, "");
|
||||||
STAY_ALIVE.store(value, std::sync::atomic::Ordering::Relaxed);
|
STAY_ALIVE.store(value, std::sync::atomic::Ordering::Relaxed);
|
||||||
} else {
|
} else {
|
||||||
println!("Unknown topic recieved {}", topic);
|
log(LogMessage::unknown_topic, 0 ,0,"", &topic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1327,6 +1305,38 @@ impl PlantHal {
|
|||||||
pub fn create() -> Result<Mutex<PlantCtrlBoard<'static>>> {
|
pub fn create() -> Result<Mutex<PlantCtrlBoard<'static>>> {
|
||||||
let peripherals = Peripherals::take()?;
|
let peripherals = Peripherals::take()?;
|
||||||
|
|
||||||
|
let mut clock = PinDriver::input_output(peripherals.pins.gpio15.downgrade())?;
|
||||||
|
clock.set_pull(Pull::Floating).unwrap();
|
||||||
|
let mut latch = PinDriver::input_output(peripherals.pins.gpio3.downgrade())?;
|
||||||
|
latch.set_pull(Pull::Floating).unwrap();
|
||||||
|
let mut data = PinDriver::input_output(peripherals.pins.gpio23.downgrade())?;
|
||||||
|
data.set_pull(Pull::Floating).unwrap();
|
||||||
|
let shift_register = ShiftRegister40::new(clock.into(), latch.into(), data.into());
|
||||||
|
//disable all
|
||||||
|
for mut pin in shift_register.decompose() {
|
||||||
|
pin.set_low().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let awake = &mut shift_register.decompose()[AWAKE];
|
||||||
|
awake.set_high()?;
|
||||||
|
|
||||||
|
|
||||||
|
let charging = &mut shift_register.decompose()[CHARGING];
|
||||||
|
charging.set_high()?;
|
||||||
|
|
||||||
|
let ms0 = &mut shift_register.decompose()[MS_0];
|
||||||
|
ms0.set_low()?;
|
||||||
|
let ms1 = &mut shift_register.decompose()[MS_1];
|
||||||
|
ms1.set_low()?;
|
||||||
|
let ms2 = &mut shift_register.decompose()[MS_2];
|
||||||
|
ms2.set_low()?;
|
||||||
|
let ms3 = &mut shift_register.decompose()[MS_3];
|
||||||
|
ms3.set_low()?;
|
||||||
|
|
||||||
|
let ms4 = &mut shift_register.decompose()[MS_4];
|
||||||
|
ms4.set_high()?;
|
||||||
|
|
||||||
|
|
||||||
println!("Init battery driver");
|
println!("Init battery driver");
|
||||||
let mut battery_driver = Bq34z100g1Driver {
|
let mut battery_driver = Bq34z100g1Driver {
|
||||||
i2c: MutexDevice::new(&I2C_DRIVER),
|
i2c: MutexDevice::new(&I2C_DRIVER),
|
||||||
@ -1345,6 +1355,10 @@ impl PlantHal {
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut one_wire_pin = PinDriver::input_output_od(peripherals.pins.gpio18)?;
|
||||||
|
one_wire_pin.set_pull(Pull::Floating).unwrap();
|
||||||
|
|
||||||
|
|
||||||
let rtc_time = rtc.datetime();
|
let rtc_time = rtc.datetime();
|
||||||
match rtc_time {
|
match rtc_time {
|
||||||
OkStd(tt) => {
|
OkStd(tt) => {
|
||||||
@ -1363,33 +1377,6 @@ impl PlantHal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut clock = PinDriver::input_output(peripherals.pins.gpio15.downgrade())?;
|
|
||||||
clock.set_pull(Pull::Floating).unwrap();
|
|
||||||
let mut latch = PinDriver::input_output(peripherals.pins.gpio3.downgrade())?;
|
|
||||||
latch.set_pull(Pull::Floating).unwrap();
|
|
||||||
let mut data = PinDriver::input_output(peripherals.pins.gpio23.downgrade())?;
|
|
||||||
data.set_pull(Pull::Floating).unwrap();
|
|
||||||
let shift_register = ShiftRegister40::new(clock.into(), latch.into(), data.into());
|
|
||||||
for mut pin in shift_register.decompose() {
|
|
||||||
pin.set_low().unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut one_wire_pin = PinDriver::input_output_od(peripherals.pins.gpio18)?;
|
|
||||||
one_wire_pin.set_pull(Pull::Floating).unwrap();
|
|
||||||
|
|
||||||
//disable all
|
|
||||||
let ms0 = &mut shift_register.decompose()[MS_0];
|
|
||||||
ms0.set_low()?;
|
|
||||||
let ms1 = &mut shift_register.decompose()[MS_1];
|
|
||||||
ms1.set_low()?;
|
|
||||||
let ms2 = &mut shift_register.decompose()[MS_2];
|
|
||||||
ms2.set_low()?;
|
|
||||||
let ms3 = &mut shift_register.decompose()[MS_3];
|
|
||||||
ms3.set_low()?;
|
|
||||||
|
|
||||||
let ms4 = &mut shift_register.decompose()[MS_4];
|
|
||||||
ms4.set_high()?;
|
|
||||||
|
|
||||||
//init,reset rtc memory depending on cause
|
//init,reset rtc memory depending on cause
|
||||||
let mut init_rtc_store: bool = false;
|
let mut init_rtc_store: bool = false;
|
||||||
let mut to_config_mode: bool = false;
|
let mut to_config_mode: bool = false;
|
||||||
@ -1430,13 +1417,13 @@ impl PlantHal {
|
|||||||
init_rtc_store = true
|
init_rtc_store = true
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
println!("Reset due to {:?} requires rtc clear {} and force config mode {}", reasons, init_rtc_store, to_config_mode);
|
log(LogMessage::reset_reason, init_rtc_store as u32, to_config_mode as u32, "",&format!("{reasons:?}"));
|
||||||
if init_rtc_store {
|
if init_rtc_store {
|
||||||
unsafe {
|
unsafe {
|
||||||
LAST_WATERING_TIMESTAMP = [0; PLANT_COUNT];
|
LAST_WATERING_TIMESTAMP = [0; PLANT_COUNT];
|
||||||
CONSECUTIVE_WATERING_PLANT = [0; PLANT_COUNT];
|
CONSECUTIVE_WATERING_PLANT = [0; PLANT_COUNT];
|
||||||
LOW_VOLTAGE_DETECTED = false;
|
LOW_VOLTAGE_DETECTED = false;
|
||||||
BUFFER = ConstGenericRingBuffer::<heapless::String<ENTRY_SIZE>, BUFFER_SIZE>::new();
|
crate::log::init();
|
||||||
RESTART_TO_CONF = to_config_mode;
|
RESTART_TO_CONF = to_config_mode;
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
@ -1444,12 +1431,8 @@ impl PlantHal {
|
|||||||
if to_config_mode{
|
if to_config_mode{
|
||||||
RESTART_TO_CONF = true;
|
RESTART_TO_CONF = true;
|
||||||
}
|
}
|
||||||
println!("Current restart to conf mode{:?}", RESTART_TO_CONF);
|
log(LogMessage::restart_to_config, RESTART_TO_CONF as u32, 0, "","");
|
||||||
|
log(LogMessage::low_voltage, LOW_VOLTAGE_DETECTED as u32, 0, "","");
|
||||||
println!(
|
|
||||||
"Current low voltage detection is {:?}",
|
|
||||||
LOW_VOLTAGE_DETECTED
|
|
||||||
);
|
|
||||||
for i in 0..PLANT_COUNT {
|
for i in 0..PLANT_COUNT {
|
||||||
println!(
|
println!(
|
||||||
"LAST_WATERING_TIMESTAMP[{}] = UTC {}",
|
"LAST_WATERING_TIMESTAMP[{}] = UTC {}",
|
||||||
@ -1473,8 +1456,6 @@ impl PlantHal {
|
|||||||
Option::<AnyInputPin>::None,
|
Option::<AnyInputPin>::None,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
println!("Channel config start");
|
|
||||||
|
|
||||||
counter_unit1.channel_config(
|
counter_unit1.channel_config(
|
||||||
PcntChannel::Channel0,
|
PcntChannel::Channel0,
|
||||||
PinIndex::Pin0,
|
PinIndex::Pin0,
|
||||||
@ -1489,8 +1470,6 @@ impl PlantHal {
|
|||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
println!("Wifi start");
|
|
||||||
|
|
||||||
let sys_loop = EspSystemEventLoop::take()?;
|
let sys_loop = EspSystemEventLoop::take()?;
|
||||||
let nvs = EspDefaultNvsPartition::take()?;
|
let nvs = EspDefaultNvsPartition::take()?;
|
||||||
let wifi_driver = EspWifi::new(peripherals.modem, sys_loop, Some(nvs))?;
|
let wifi_driver = EspWifi::new(peripherals.modem, sys_loop, Some(nvs))?;
|
||||||
@ -1525,15 +1504,15 @@ impl PlantHal {
|
|||||||
let one_wire_bus = OneWire::new(one_wire_pin)
|
let one_wire_bus = OneWire::new(one_wire_pin)
|
||||||
.map_err(|err| -> anyhow::Error { anyhow!("Missing attribute: {:?}", err) })?;
|
.map_err(|err| -> anyhow::Error { anyhow!("Missing attribute: {:?}", err) })?;
|
||||||
|
|
||||||
println!("After stuff");
|
|
||||||
|
|
||||||
let status = print_battery(&mut battery_driver);
|
let status = print_battery(&mut battery_driver);
|
||||||
if status.is_err() {
|
match status {
|
||||||
println!("Error communicating with battery!! {:?}", status.err());
|
OkStd(_) => {
|
||||||
} else {
|
|
||||||
println!("Managed to comunnicate with battery");
|
},
|
||||||
|
Err(err) => {
|
||||||
|
log(LogMessage::battery_communication_error, 0 as u32, 0, "",&format!("{err:?})"));
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
let shift_register_enable_invert = PinDriver::output(peripherals.pins.gpio21.downgrade())?;
|
let shift_register_enable_invert = PinDriver::output(peripherals.pins.gpio21.downgrade())?;
|
||||||
|
|
||||||
let rv = Mutex::new(PlantCtrlBoard {
|
let rv = Mutex::new(PlantCtrlBoard {
|
||||||
|
@ -9,6 +9,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
use chrono::DateTime;
|
use chrono::DateTime;
|
||||||
|
use esp_idf_sys::{esp_set_time_from_rtc, settimeofday, timeval, vTaskDelay};
|
||||||
use core::result::Result::Ok;
|
use core::result::Result::Ok;
|
||||||
use embedded_svc::http::Method;
|
use embedded_svc::http::Method;
|
||||||
use esp_idf_hal::delay::Delay;
|
use esp_idf_hal::delay::Delay;
|
||||||
@ -24,11 +25,6 @@ struct SSIDList<'a> {
|
|||||||
ssids: Vec<&'a String<32>>,
|
ssids: Vec<&'a String<32>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Debug)]
|
|
||||||
struct FileList {
|
|
||||||
file: Vec<FileInfo>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Debug)]
|
#[derive(Serialize, Debug)]
|
||||||
struct LoadData<'a> {
|
struct LoadData<'a> {
|
||||||
rtc: &'a str,
|
rtc: &'a str,
|
||||||
@ -64,6 +60,12 @@ fn write_time(
|
|||||||
let time: SetTime = serde_json::from_slice(&actual_data)?;
|
let time: SetTime = serde_json::from_slice(&actual_data)?;
|
||||||
let parsed = DateTime::parse_from_rfc3339(time.time).map_err(|err| anyhow::anyhow!(err))?;
|
let parsed = DateTime::parse_from_rfc3339(time.time).map_err(|err| anyhow::anyhow!(err))?;
|
||||||
let mut board = BOARD_ACCESS.lock().unwrap();
|
let mut board = BOARD_ACCESS.lock().unwrap();
|
||||||
|
|
||||||
|
let now = timeval {
|
||||||
|
tv_sec: parsed.to_utc().timestamp(),
|
||||||
|
tv_usec: 0
|
||||||
|
};
|
||||||
|
unsafe { settimeofday(&now, core::ptr::null_mut()) };
|
||||||
board.set_rtc_time(&parsed.to_utc())?;
|
board.set_rtc_time(&parsed.to_utc())?;
|
||||||
anyhow::Ok(None)
|
anyhow::Ok(None)
|
||||||
}
|
}
|
||||||
@ -205,6 +207,13 @@ fn get_battery_state(
|
|||||||
anyhow::Ok(Some(battery_json))
|
anyhow::Ok(Some(battery_json))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_log(
|
||||||
|
_request: &mut Request<&mut EspHttpConnection>,
|
||||||
|
) -> Result<Option<std::string::String>, anyhow::Error> {
|
||||||
|
let output = crate::log::get_log();
|
||||||
|
anyhow::Ok(Some(serde_json::to_string(&output)?))
|
||||||
|
}
|
||||||
|
|
||||||
fn get_version_web(
|
fn get_version_web(
|
||||||
_request: &mut Request<&mut EspHttpConnection>,
|
_request: &mut Request<&mut EspHttpConnection>,
|
||||||
) -> Result<Option<std::string::String>, anyhow::Error> {
|
) -> Result<Option<std::string::String>, anyhow::Error> {
|
||||||
@ -352,6 +361,11 @@ pub fn httpd(reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
|||||||
handle_error_to500(request, get_version_web)
|
handle_error_to500(request, get_version_web)
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
server
|
||||||
|
.fn_handler("/log", Method::Get, |request| {
|
||||||
|
handle_error_to500(request, get_log)
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
server
|
server
|
||||||
.fn_handler("/battery", Method::Get, |request| {
|
.fn_handler("/battery", Method::Get, |request| {
|
||||||
handle_error_to500(request, get_battery_state)
|
handle_error_to500(request, get_battery_state)
|
||||||
@ -440,6 +454,8 @@ pub fn httpd(reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
|||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
unsafe { vTaskDelay(1) };
|
||||||
|
|
||||||
let reboot_now_for_exit = reboot_now.clone();
|
let reboot_now_for_exit = reboot_now.clone();
|
||||||
server
|
server
|
||||||
.fn_handler("/exit", Method::Post, move |_| {
|
.fn_handler("/exit", Method::Post, move |_| {
|
||||||
@ -462,19 +478,16 @@ pub fn httpd(reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
|||||||
let mut buffer: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
|
let mut buffer: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
|
||||||
let mut total_read: usize = 0;
|
let mut total_read: usize = 0;
|
||||||
loop {
|
loop {
|
||||||
|
unsafe { vTaskDelay(1) };
|
||||||
let read = std::io::Read::read(&mut file_handle, &mut buffer)?;
|
let read = std::io::Read::read(&mut file_handle, &mut buffer)?;
|
||||||
total_read += read;
|
total_read += read;
|
||||||
println!(
|
|
||||||
"sending {read} bytes of {total_read} for file {}",
|
|
||||||
&filename
|
|
||||||
);
|
|
||||||
let to_write = &buffer[0..read];
|
let to_write = &buffer[0..read];
|
||||||
response.write(to_write)?;
|
response.write(to_write)?;
|
||||||
println!("wrote {read} bytes of {total_read} for file {filename}");
|
|
||||||
if read == 0 {
|
if read == 0 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
println!("wrote {total_read} for file {filename}");
|
||||||
drop(file_handle);
|
drop(file_handle);
|
||||||
response.flush()?;
|
response.flush()?;
|
||||||
}
|
}
|
||||||
@ -588,6 +601,7 @@ pub fn httpd(reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
|
|||||||
anyhow::Ok(())
|
anyhow::Ok(())
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
unsafe { vTaskDelay(1) };
|
||||||
server
|
server
|
||||||
.fn_handler("/", Method::Get, move |request| {
|
.fn_handler("/", Method::Get, move |request| {
|
||||||
let mut response = request.into_ok_response()?;
|
let mut response = request.into_ok_response()?;
|
||||||
|
74
website/.github/workflows/pages.yml
vendored
Normal file
74
website/.github/workflows/pages.yml
vendored
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
# Sample workflow for building and deploying a Hugo site to GitHub Pages
|
||||||
|
name: Blowfish Docs Deploy
|
||||||
|
|
||||||
|
on:
|
||||||
|
# Runs on pushes targeting the default branch
|
||||||
|
push:
|
||||||
|
branches: ["main"]
|
||||||
|
|
||||||
|
# Allows you to run this workflow manually from the Actions tab
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pages: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
# Allow one concurrent deployment
|
||||||
|
concurrency:
|
||||||
|
group: "pages"
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
# Default to bash
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# Build job
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Hugo setup
|
||||||
|
uses: peaceiris/actions-hugo@v2.6.0
|
||||||
|
with:
|
||||||
|
hugo-version: 0.140.2
|
||||||
|
extended: true
|
||||||
|
env:
|
||||||
|
ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true'
|
||||||
|
|
||||||
|
- name: Check out code into the Go module directory
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: true # Fetch Hugo themes (true OR recursive)
|
||||||
|
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
|
||||||
|
|
||||||
|
- name: Setup Pages
|
||||||
|
id: pages
|
||||||
|
uses: actions/configure-pages@v2
|
||||||
|
|
||||||
|
- name: Build with Hugo
|
||||||
|
env:
|
||||||
|
# For maximum backward compatibility with Hugo modules
|
||||||
|
HUGO_ENVIRONMENT: production
|
||||||
|
HUGO_ENV: production
|
||||||
|
run: |
|
||||||
|
hugo --minify -d ./public --baseURL https://nunocoracao.github.io/blowfish_template/
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-pages-artifact@v1
|
||||||
|
with:
|
||||||
|
path: ./public
|
||||||
|
|
||||||
|
# Deployment job
|
||||||
|
deploy:
|
||||||
|
environment:
|
||||||
|
name: github-pages
|
||||||
|
url: https://nunocoracao.github.io/blowfish_template/
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
steps:
|
||||||
|
- name: Deploy to GitHub Pages
|
||||||
|
id: deployment
|
||||||
|
uses: actions/deploy-pages@v1
|
4
website/.gitmodules
vendored
Normal file
4
website/.gitmodules
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
[submodule "themes/blowfish"]
|
||||||
|
path = themes/blowfish
|
||||||
|
url = https://github.com/nunocoracao/blowfish.git
|
||||||
|
branch = main
|
21
website/LICENSE
Normal file
21
website/LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 Nuno Coração
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
6
website/README.md
Normal file
6
website/README.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Blowfish Template
|
||||||
|
This is a template for the Blowfish Hugo Theme. Feel free to use this repo as a quick way to get started with Blowfish. Please visit [Blowfish's main website](https://github.com/nunocoracao/blowfish) to read the complete documentation.
|
||||||
|
|
||||||
|
The template was built using the [Git option](https://nunocoracao.github.io/blowfish/docs/installation/#install-using-git) from Blowfish's installations instructions.
|
||||||
|
|
||||||
|

|
BIN
website/logo.png
Normal file
BIN
website/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 98 KiB |
20
website/package.json
Normal file
20
website/package.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "blowfish_template",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Blowfish Template",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "hugo server --minify -D -E -F"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/nunocoracao/blowfish_template.git"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/nunocoracao/blowfish_template/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/nunocoracao/blowfish_template#readme"
|
||||||
|
}
|
5
website/update.sh
Normal file
5
website/update.sh
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
git submodule update --remote --merge
|
||||||
|
git add *
|
||||||
|
git commit -m "updated theme"
|
||||||
|
git push
|
Loading…
x
Reference in New Issue
Block a user