wirestudio 0.44.0__tar.gz → 0.46.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {wirestudio-0.44.0/wirestudio.egg-info → wirestudio-0.46.0}/PKG-INFO +5 -4
- {wirestudio-0.44.0 → wirestudio-0.46.0}/README.md +4 -3
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_api_route.py +6 -0
- wirestudio-0.46.0/tests/test_board_check.py +205 -0
- wirestudio-0.46.0/tests/test_community.py +387 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_compatibility.py +83 -19
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_firmware_gen.py +73 -5
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_kicad.py +29 -12
- wirestudio-0.46.0/tests/test_kicad_drc.py +112 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_kicad_erc.py +29 -5
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_kicad_pcb.py +51 -8
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_kicad_route.py +73 -1
- wirestudio-0.46.0/tests/test_lorawan_fragments.py +279 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_mcp_server.py +3 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_migrate.py +50 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/__init__.py +1 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/agent/agent.py +1 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/agent/tools.py +135 -6
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/api/app.py +90 -11
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/api/community.py +160 -10
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/api/schemas.py +18 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/csp/compatibility.py +37 -0
- wirestudio-0.46.0/wirestudio/kicad/drc.py +145 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/kicad/erc.py +19 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/kicad/fab.py +3 -3
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/kicad/generator.py +29 -14
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/kicad/netlist.py +85 -13
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/kicad/pcb.py +29 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/kicad/pcbnew_bridge.py +5 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/kicad/route.py +138 -17
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/__init__.py +100 -48
- wirestudio-0.46.0/wirestudio/library/board_check.py +376 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/esp32-c3-devkitm-1.yaml +24 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/esp32-s3-devkitc-1.yaml +31 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/ttgo-lora32-v2.yaml +8 -2
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/check.py +6 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/apa102.yaml +2 -2
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/bh1750.yaml +1 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/bl0906.yaml +164 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/cse7766.yaml +58 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/esp32_rmt_led_strip.yaml +1 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/hc-sr501.yaml +1 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/hlw8012.yaml +3 -3
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/ili9xxx.yaml +3 -3
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/ld2410.yaml +57 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/ld2420.yaml +64 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/max31855.yaml +38 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/max98357a.yaml +1 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/mcp23008.yaml +2 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/mcp23017.yaml +2 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/mcp23s17.yaml +2 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/mcp3008.yaml +17 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/mcp3008_channel.yaml +22 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/mhz19.yaml +36 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/modbus.yaml +54 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/pca9685.yaml +1 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/pcf8574.yaml +2 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/pmsx003.yaml +56 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/pzemac.yaml +71 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/rc522.yaml +1 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/rcwl-0516.yaml +1 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/remote_receiver.yaml +3 -2
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/sdm_meter.yaml +78 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/servo.yaml +1 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/sn74hc595.yaml +5 -4
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/ssd1306.yaml +1 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/st7789.yaml +3 -3
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/sx127x.yaml +2 -2
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/tm1637.yaml +2 -2
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/uart_gps.yaml +2 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/vl53l0x.yaml +2 -2
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/wiegand.yaml +2 -2
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/ws2812b.yaml +1 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/xpt2046.yaml +1 -1
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/mcp/server.py +53 -3
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/migrate.py +59 -2
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/targets/lorawan/codec.py +13 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/targets/lorawan/firmware_gen.py +99 -57
- {wirestudio-0.44.0 → wirestudio-0.46.0/wirestudio.egg-info}/PKG-INFO +5 -4
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio.egg-info/SOURCES.txt +5 -0
- wirestudio-0.44.0/tests/test_community.py +0 -191
- {wirestudio-0.44.0 → wirestudio-0.46.0}/LICENSE +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/LICENSES.md +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/pyproject.toml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/setup.cfg +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_active_design.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_agent.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_agent_eval.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_agent_stream.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_api.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_api_auth.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_ascii_gen.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_build_backend.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_check_upgrade.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_chirpstack.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_circuitpython.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_codec.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_compile.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_component_corpus.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_connectors.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_coverage_baseline.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_design_events.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_designs.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_designs_seed.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_display_intent.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_electrical.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_enclosure.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_enclosure_gate.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_enclosure_search.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_errors.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_esphome_dashboard.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_esphome_support.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_fleet.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_footprints.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_framework_baseline.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_hardware_gate.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_intent.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_inventory.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_jlcpcb.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_kicad_fab.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_kicad_import.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_kicad_render.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_kicad_sch.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_library_check.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_library_hbridge.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_library_rtttl.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_lorawan.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_lorawan_api.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_lorawan_sugar_migration.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_mcp_auth.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_mcp_client.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_mcp_hardware.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_mcp_jobs.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_mcp_resources.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_meshtastic.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_micropython.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_micropython_registers.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_modules.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_pin_protocols.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_pin_solver.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_printwarden.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_python_blocks.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_recommend.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_register_code.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_rf_ook.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_schema.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_schema_doc.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_schematics_gate.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_security_cors.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_seed_onboard.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_serve.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_sqlite_store.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_sqlite_stores.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_strict.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_targets.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_tasmota.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_tbeam_lorawan_example.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_tools_add_bus.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_tools_add_component.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_tools_solve_pins.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_uart_frames.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_validate.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_wled.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_workbench.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_workbench_boot.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_workbench_images.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_workbench_provision.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_workbench_serial.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_ws2812_method.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/tests/test_yaml_gen.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/agent/__init__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/agent/eval.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/agent/eval_tasks.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/agent/session.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/api/__init__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/api/__main__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/api/auth.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/api/circuitpython.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/api/design_input.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/api/meshtastic.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/api/micropython.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/api/serve.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/api/workbench.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/csp/__init__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/csp/pin_solver.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/designs/__init__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/designs/active.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/designs/events.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/designs/seed.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/designs/store.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/enclosure/__init__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/enclosure/openscad.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/enclosure/search.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/enclosure/yapp/LICENSE +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/enclosure/yapp/YAPPgenerator_v3.scad +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/errors.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/esphome_dashboard/__init__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/__init__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/access-panel.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/actuator-harness.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/air-quality-station.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/analog-node.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/atom-echo.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/atom-lite.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/atom-matrix.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/atoms3-lcd.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/atoms3-lite.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/atoms3-onboard.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/atomu-onboard.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/atomu.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/attic-logger.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/awning-control.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/bench-io.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/bl0906-mainmeter.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/blind-stepper.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/bluemotion.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/bluesonoff.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/button-toggles-light.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/c3-supermini.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/c6-supermini.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/co2-display.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/desk-climate.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/desk-matrix.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/distance-sensor.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/encoder-drives-stepper.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/energy-monitor.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/esp32-audio.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/esp32cam-wrover.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/esp32cam.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/flow-meter.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/garage-motion.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/grill-probe.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/guarded-button-light.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/heltec-v4-gnss-tracker.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/keypad.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/kitchen-scale.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/led-display.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/lorawan-battery-uplink.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/motion-turns-on-light.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/motor-position.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/multi-temp.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/nextion-thermostat.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/oled-knob.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/oled.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/output-hub.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/parking-distance.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/presence-media-node.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/presence-rf.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/rc522.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/room-climate.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/rs485-energy.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/s3-devkitc.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/s3-supermini.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/securitypanel.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/smart-plug-v1.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/smart-plug.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/solder-fan.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/spi-io-node.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/subghz-rfid.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/t-beam-lorawan.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/t-beam.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/temp-above-turns-on-fan.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/temp-turns-on-fan.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/tft-touch.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/ttgo-lora32.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/tuya-smart-plug.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/usbc-led-strip.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/vent-damper.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/wasserpir.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/weather-station.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/wemosgps.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/wled-sensor-strip.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/examples/xiao-grove-climate.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/fleet/__init__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/fleet/client.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/generate/__init__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/generate/__main__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/generate/ascii_gen.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/generate/circuitpython_gen.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/generate/display_intent.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/generate/micropython_gen.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/generate/yaml_gen.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/intent.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/inventory/__init__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/inventory/buy.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/inventory/check.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/inventory/csv_io.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/inventory/match.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/inventory/store.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/jlcpcb/__init__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/jlcpcb/__main__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/jlcpcb/check.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/jlcpcb/client.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/kicad/__init__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/kicad/import.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/kicad/importer.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/kicad/render.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/kicad/schematic.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/kicad/symbol_parser.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/esp01_1m.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/esp32-c3-supermini.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/esp32-c6-supermini.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/esp32-devkitc-v4.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/esp32-s3-supermini.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/esp32-wrover-cam.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/esp32cam-ai-thinker.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/esp8285-1m.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/heltec-wifi-lora32-v2.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/heltec-wifi-lora32-v3.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/heltec-wifi-lora32-v4.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/m5stack-atom-echo.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/m5stack-atom-matrix.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/m5stack-atom.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/m5stack-atoms3-lite.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/m5stack-atoms3.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/m5stack-atomu.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/nodemcu-32s.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/nodemcu-v2.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/seeed-xiao-esp32c3.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/ttgo-lora32-v1.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/ttgo-t-beam.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/boards/wemos-d1-mini.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/adc.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/ads1115.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/ads1115_channel.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/aht10.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/axp192.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/battery_adc.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/bme280.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/bme680.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/bmp180.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/bmp280.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/cc1101.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/connector_1x02.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/connector_1x03.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/connector_1x04.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/connector_1x05.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/connector_1x06.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/connector_1x07.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/connector_1x08.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/connector_2x05_idc.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/ct_clamp.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/dht.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/ds18b20.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/esp32_camera.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/gpio_input.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/gpio_output.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/grove-aht20.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/hbridge.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/hbridge_mosfet.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/hc-sr04.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/htu21d.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/hx711.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/i2s_microphone.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/ina219.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/lcd_pcf8574.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/led_indicator.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/level_shifter.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/max7219.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/mosfet_low_side_driver.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/mpu6050.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/mpu6886.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/nextion.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/npn_low_side_driver.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/pn532.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/potentiometer.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/pulse_counter.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/pwm_fan.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/rdm6300.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/remote_transmitter.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/rf_bridge.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/rotary_encoder.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/rtttl.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/scd4x.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/sgp4x.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/sht3xd.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/sht4x.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/tm1638.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/tsl2561.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/tuya.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/tuya_sensor.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/tuya_switch.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/uln2003.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/usb_c_power_in.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/veml7700.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/components/voltage_divider.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/electrical.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/modules/env-display.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/modules/fan-controller.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/modules/motion-light.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/modules/oled-knob-13.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/library/modules/relay-4ch.yaml +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/mcp/__init__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/mcp/auth.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/mcp/hardware.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/mcp/jobs.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/model.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/printwarden/__init__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/printwarden/client.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/recommend/__init__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/recommend/recommender.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/schema/__init__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/schema/design.schema.json +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/seed.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/sqlite_store.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/targets/__init__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/targets/base.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/targets/build_backend.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/targets/esphome.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/targets/lorawan/__init__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/targets/lorawan/__main__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/targets/lorawan/api.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/targets/lorawan/build_local.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/targets/lorawan/chirpstack.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/targets/lorawan/compile.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/targets/lorawan/templates/main.cpp.j2 +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/targets/lorawan/templates/platformio.ini.j2 +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/targets/lorawan/workbench_provision.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/targets/tasmota.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/targets/wled.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/targets/wled_build.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/validate.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/workbench/__init__.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/workbench/boot.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/workbench/client.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/workbench/gate.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/workbench/images.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio/workbench/serial.py +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio.egg-info/dependency_links.txt +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio.egg-info/entry_points.txt +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio.egg-info/requires.txt +0 -0
- {wirestudio-0.44.0 → wirestudio-0.46.0}/wirestudio.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: wirestudio
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.46.0
|
|
4
4
|
Summary: Agent-driven IoT device design tool that produces ESPHome YAML.
|
|
5
5
|
Author: wirestudio contributors
|
|
6
6
|
License: MIT
|
|
@@ -147,8 +147,8 @@ Tiers, in priority order:
|
|
|
147
147
|
| **Verified** | CSP pin solver + compat checker | assign legal pins, surface boot-strap / ADC2-WiFi / voltage / locked-pin issues | unit tests + property checks in `tests/test_pin_solver.py` + `tests/test_compatibility.py` |
|
|
148
148
|
| **Verified** | Fleet handoff | push YAML to `fleet-for-esphome` ha-addon, optional compile + log relay | round-trip tests in `tests/test_fleet.py` |
|
|
149
149
|
| **Verified** | KiCad schematic | write a KiCad 8 `.kicad_sch` the studio draws itself (board, peripherals, subcircuits drawn as circuits from their library layouts; symbols embedded), plus a SKiDL script for the same design | every bundled example builds a KiCad netlist against the pinned upstream symbol libraries, every PR ([gate](.github/workflows/kicad-schematic.yml)) — no unresolved symbols or pins; kicad-cli reads the netlist back from every written sheet's geometry and it must match the design's, then `kicad-cli sch erc` runs on all of them against a baseline of the violation types the writer cannot avoid ([gate](.github/workflows/kicad-render.yml)). Parts KiCad ships no symbol for (sensor/module breakouts) render as labeled generic headers |
|
|
150
|
-
| **Verified** | KiCad PCB layout | emit a placed, unrouted `.kicad_pcb` — footprints, nets, ratsnest, edge cuts | every bundled example emits a structurally sound board, every PR ([gate](.github/workflows/pcb-layout.yml)); a DRC tier opens each board in real KiCad ([gate](.github/workflows/pcb-drc.yml)) |
|
|
151
|
-
| **Verified** | Fab outputs | JLCPCB upload bundle — BOM, CPL, Gerber + drill (`/design/fab/*`) | CPL positions match the `.kicad_pcb` placement; the DRC tier smoke-tests the Gerber export.
|
|
150
|
+
| **Verified** | KiCad PCB layout | emit a placed, unrouted `.kicad_pcb` — footprints, nets, ratsnest, edge cuts, and a GND pour on the bottom layer that the route step fills | every bundled example emits a structurally sound board, every PR ([gate](.github/workflows/pcb-layout.yml)); a DRC tier opens each board in real KiCad ([gate](.github/workflows/pcb-drc.yml)) |
|
|
151
|
+
| **Verified** | Fab outputs | JLCPCB upload bundle — BOM, CPL, Gerber + drill (`/design/fab/*`) | CPL positions match the `.kicad_pcb` placement; the DRC tier smoke-tests the Gerber export. `?route=true` routes the board first; without it Gerbers carry pads but no tracks or pour (`is_routed` flags it). The routed gate checks a routed board's B.Cu Gerber carries the GND pour ([gate](.github/workflows/pcb-route.yml)) |
|
|
152
152
|
| **Verified** | Subcircuits + building blocks | a component built from discrete parts (five bundled blocks, two H-bridges) expands into the schematic, PCB, BOM, CPL and inventory check; part values are parametric; each block's `verify.checks` rule runs at `validate` with the real params and rails | goldens for every subcircuit example pin YAML + BOM; `component_check` fails a block whose defaults break its own rule (`tests/test_electrical.py`); the schematic and PCB gates cover the expanded parts like any other |
|
|
153
153
|
| **Verified** | Inventory check | cross-check a design's BOM against the drawer (library modules + discrete parts), propose same-package substitutes ranked by pinout, package, rating headroom and stock, accept one or all of them as `part_overrides` that every fab output honours, pick list by location, buy list priced on JLCPCB | matching, substitution and coverage tests in `tests/test_inventory.py` against the real drawer CSV; JLCPCB pricing is mocked and degrades to an unpriced list when the parts API is down |
|
|
154
154
|
| **Verified** | Parametric enclosure | OpenSCAD `.scad` from board mount-hole metadata, built on [YAPP_Box](https://github.com/mrWheel/YAPP_Box): base and lid with standoffs, port cutouts, a ridge and snap joins | every enclosure-capable board renders through real OpenSCAD to a non-empty, manifold (closed, printable) solid, every PR ([gate](.github/workflows/enclosure-render.yml)) |
|
|
@@ -160,12 +160,13 @@ Tiers, in priority order:
|
|
|
160
160
|
| **Works (lighter checks)** | Meshtastic flashing + config | proxy the official release factory image (`/meshtastic/firmware`) for the radio boards, flash it via the unified WebSerial dialog, then push region, modem preset, owner and primary channel as protobufs over the same port | endpoint tests with mocked upstream; board-to-variant map checked against `meshtastic/firmware` variants; config push tested against a fake device; no live-flash gate |
|
|
161
161
|
| **Works (lighter checks)** | MicroPython flashing + main.py | proxy the official release image for the board's chip (`/micropython/firmware`; every library board maps to a generic port image, ESP8266 included), flash via the unified dialog, generate `main.py` from the design over the `machine` API (`/micropython/code`) and push it through the raw REPL over the same serial port | endpoint tests with a captured download page; every board's starter and every example's main.py parse as Python; the raw-REPL push is tested against a fake board; the micropython.org page format could not be fetched from the build session, so the first live flash validates it; no live-flash gate |
|
|
162
162
|
| **Verified** | Component authoring | write a component YAML in the studio or through `component_create`; the same gate as `component_check` (schema, subcircuit nets, template render, KiCad symbols / pins / footprint) before it lands in the user library | a user-authored component goes through the gate and its synthetic design through upstream `esphome config`, every PR ([gate](.github/workflows/esphome-config.yml)); the gate rejects every file in a corpus of bad components for the named reason (`tests/test_component_corpus.py`); KiCad resolution runs only where the toolchain is present |
|
|
163
|
+
| **Verified** | Board authoring | write a board YAML in the studio or through `board_create`; the same gate as `board_check` (schema, every bus / onboard / radio pin against `gpio_capabilities`, KiCad symbol pins and footprint, enclosure geometry, ESPHome's board table, an ESPHome render with the onboard peripherals) before it lands in the user library | every bundled board passes the gate (`tests/test_board_check.py`); a user-authored board with its onboard peripherals goes through upstream `esphome config`, every PR ([gate](.github/workflows/esphome-config.yml)); the pinout is not checked against the datasheet |
|
|
163
164
|
| **Verified** | ESPHome dashboard compile | push the rendered YAML to a running ESPHome Device Builder (`/esphome/push`), start a compile there, stream the log and serve the firmware, with the same job shapes as the fleet path | nightly, against a live Device Builder (ESPHome 2026.10.0) open and password-protected: push, compile over the WebSocket API, fetch the image, with the client's wire assumptions asserted ([dashboard](.github/workflows/esphome-compile.yml)); client + route tests against a fake of the same in `tests/test_esphome_dashboard.py` |
|
|
164
165
|
| **Works (lighter checks)** | CircuitPython flashing | proxy the official release image (`/circuitpython/firmware`) for ESP32/S3/C3/C6 boards, flash via the unified dialog, serve a generated starter `code.py` (`/circuitpython/code`) | endpoint tests with mocked upstream; every board-id mapping verified against downloads.circuitpython.org; generated starters parse as valid Python; no live-flash gate |
|
|
165
166
|
| **Verified** | MCP server | 53 tools over the Model Context Protocol: 31 design / library / inventory / fab, plus 22 that reach hardware — workbench flash and boot verification, LoRaWAN compile / provision / activation, fleet and dashboard push + build status, and job polling for the long ones | the `mcp` package's own client connects to the mounted server over Streamable HTTP with the bearer token, lists the tools, drives a design from `create_design` to `render` and reads a resource, every PR (`tests/test_mcp_client.py`); tool / auth / resource tests in `tests/test_mcp_*.py`; the hardware tools drive the real clients against wire-level fakes, and were exercised against a live bench, ChirpStack and fleet during bring-up |
|
|
166
167
|
| **Experimental** | Thingiverse search relay | rank community models for a board | smoke-tested; depends on a third-party search API that ranks unevenly |
|
|
167
168
|
| **Verified** | Agent (Claude tool-using) | natural-language design driving | scored nightly against the 28-task list in `wirestudio/agent/eval_tasks.yaml`: the design it hands back passes `esphome config`, carries the asked-for change, and the turn stayed within its tool-call budget ([gate](.github/workflows/agent-eval.yml)); every task's reference solution passes the same scorer on every PR (`tests/test_agent_eval.py`). The nightly run drives the studio through Claude Code over MCP with the `CLAUDE_CODE_OAUTH_TOKEN` secret (a subscription); the embedded agent is scored too when `ANTHROPIC_API_KEY` is set. Each driver's first scored run sets its gate |
|
|
168
|
-
| **Verified** | PCB autorouting | Freerouting roundtrip — board → Specctra DSN → routed → SES import; SSE route endpoint, `route_pcb` MCP/agent tool, web-UI Route button, `?route=true` fab exports, `-pcb` image variant | representative examples route with zero unconnected items and
|
|
169
|
+
| **Verified** | PCB autorouting | Freerouting roundtrip — board → Specctra DSN → routed → SES import, GND pour filled; via cost and keepout rectangles as parameters; KiCad's DRC of the routed board reported back; SSE route endpoint, `route_pcb` MCP/agent tool, web-UI Route button, `?route=true` fab exports, `-pcb` image variant | representative examples route with zero unconnected items, a filled pour and a clean routed DRC; a high via cost must remove vias and a keepout must clear the track under it ([gate](.github/workflows/pcb-route.yml)) |
|
|
169
170
|
|
|
170
171
|
The **Verified** tier is the bar the project is asking to be judged
|
|
171
172
|
on. Everything else is offered with the caveat that's spelled out in
|
|
@@ -113,8 +113,8 @@ Tiers, in priority order:
|
|
|
113
113
|
| **Verified** | CSP pin solver + compat checker | assign legal pins, surface boot-strap / ADC2-WiFi / voltage / locked-pin issues | unit tests + property checks in `tests/test_pin_solver.py` + `tests/test_compatibility.py` |
|
|
114
114
|
| **Verified** | Fleet handoff | push YAML to `fleet-for-esphome` ha-addon, optional compile + log relay | round-trip tests in `tests/test_fleet.py` |
|
|
115
115
|
| **Verified** | KiCad schematic | write a KiCad 8 `.kicad_sch` the studio draws itself (board, peripherals, subcircuits drawn as circuits from their library layouts; symbols embedded), plus a SKiDL script for the same design | every bundled example builds a KiCad netlist against the pinned upstream symbol libraries, every PR ([gate](.github/workflows/kicad-schematic.yml)) — no unresolved symbols or pins; kicad-cli reads the netlist back from every written sheet's geometry and it must match the design's, then `kicad-cli sch erc` runs on all of them against a baseline of the violation types the writer cannot avoid ([gate](.github/workflows/kicad-render.yml)). Parts KiCad ships no symbol for (sensor/module breakouts) render as labeled generic headers |
|
|
116
|
-
| **Verified** | KiCad PCB layout | emit a placed, unrouted `.kicad_pcb` — footprints, nets, ratsnest, edge cuts | every bundled example emits a structurally sound board, every PR ([gate](.github/workflows/pcb-layout.yml)); a DRC tier opens each board in real KiCad ([gate](.github/workflows/pcb-drc.yml)) |
|
|
117
|
-
| **Verified** | Fab outputs | JLCPCB upload bundle — BOM, CPL, Gerber + drill (`/design/fab/*`) | CPL positions match the `.kicad_pcb` placement; the DRC tier smoke-tests the Gerber export.
|
|
116
|
+
| **Verified** | KiCad PCB layout | emit a placed, unrouted `.kicad_pcb` — footprints, nets, ratsnest, edge cuts, and a GND pour on the bottom layer that the route step fills | every bundled example emits a structurally sound board, every PR ([gate](.github/workflows/pcb-layout.yml)); a DRC tier opens each board in real KiCad ([gate](.github/workflows/pcb-drc.yml)) |
|
|
117
|
+
| **Verified** | Fab outputs | JLCPCB upload bundle — BOM, CPL, Gerber + drill (`/design/fab/*`) | CPL positions match the `.kicad_pcb` placement; the DRC tier smoke-tests the Gerber export. `?route=true` routes the board first; without it Gerbers carry pads but no tracks or pour (`is_routed` flags it). The routed gate checks a routed board's B.Cu Gerber carries the GND pour ([gate](.github/workflows/pcb-route.yml)) |
|
|
118
118
|
| **Verified** | Subcircuits + building blocks | a component built from discrete parts (five bundled blocks, two H-bridges) expands into the schematic, PCB, BOM, CPL and inventory check; part values are parametric; each block's `verify.checks` rule runs at `validate` with the real params and rails | goldens for every subcircuit example pin YAML + BOM; `component_check` fails a block whose defaults break its own rule (`tests/test_electrical.py`); the schematic and PCB gates cover the expanded parts like any other |
|
|
119
119
|
| **Verified** | Inventory check | cross-check a design's BOM against the drawer (library modules + discrete parts), propose same-package substitutes ranked by pinout, package, rating headroom and stock, accept one or all of them as `part_overrides` that every fab output honours, pick list by location, buy list priced on JLCPCB | matching, substitution and coverage tests in `tests/test_inventory.py` against the real drawer CSV; JLCPCB pricing is mocked and degrades to an unpriced list when the parts API is down |
|
|
120
120
|
| **Verified** | Parametric enclosure | OpenSCAD `.scad` from board mount-hole metadata, built on [YAPP_Box](https://github.com/mrWheel/YAPP_Box): base and lid with standoffs, port cutouts, a ridge and snap joins | every enclosure-capable board renders through real OpenSCAD to a non-empty, manifold (closed, printable) solid, every PR ([gate](.github/workflows/enclosure-render.yml)) |
|
|
@@ -126,12 +126,13 @@ Tiers, in priority order:
|
|
|
126
126
|
| **Works (lighter checks)** | Meshtastic flashing + config | proxy the official release factory image (`/meshtastic/firmware`) for the radio boards, flash it via the unified WebSerial dialog, then push region, modem preset, owner and primary channel as protobufs over the same port | endpoint tests with mocked upstream; board-to-variant map checked against `meshtastic/firmware` variants; config push tested against a fake device; no live-flash gate |
|
|
127
127
|
| **Works (lighter checks)** | MicroPython flashing + main.py | proxy the official release image for the board's chip (`/micropython/firmware`; every library board maps to a generic port image, ESP8266 included), flash via the unified dialog, generate `main.py` from the design over the `machine` API (`/micropython/code`) and push it through the raw REPL over the same serial port | endpoint tests with a captured download page; every board's starter and every example's main.py parse as Python; the raw-REPL push is tested against a fake board; the micropython.org page format could not be fetched from the build session, so the first live flash validates it; no live-flash gate |
|
|
128
128
|
| **Verified** | Component authoring | write a component YAML in the studio or through `component_create`; the same gate as `component_check` (schema, subcircuit nets, template render, KiCad symbols / pins / footprint) before it lands in the user library | a user-authored component goes through the gate and its synthetic design through upstream `esphome config`, every PR ([gate](.github/workflows/esphome-config.yml)); the gate rejects every file in a corpus of bad components for the named reason (`tests/test_component_corpus.py`); KiCad resolution runs only where the toolchain is present |
|
|
129
|
+
| **Verified** | Board authoring | write a board YAML in the studio or through `board_create`; the same gate as `board_check` (schema, every bus / onboard / radio pin against `gpio_capabilities`, KiCad symbol pins and footprint, enclosure geometry, ESPHome's board table, an ESPHome render with the onboard peripherals) before it lands in the user library | every bundled board passes the gate (`tests/test_board_check.py`); a user-authored board with its onboard peripherals goes through upstream `esphome config`, every PR ([gate](.github/workflows/esphome-config.yml)); the pinout is not checked against the datasheet |
|
|
129
130
|
| **Verified** | ESPHome dashboard compile | push the rendered YAML to a running ESPHome Device Builder (`/esphome/push`), start a compile there, stream the log and serve the firmware, with the same job shapes as the fleet path | nightly, against a live Device Builder (ESPHome 2026.10.0) open and password-protected: push, compile over the WebSocket API, fetch the image, with the client's wire assumptions asserted ([dashboard](.github/workflows/esphome-compile.yml)); client + route tests against a fake of the same in `tests/test_esphome_dashboard.py` |
|
|
130
131
|
| **Works (lighter checks)** | CircuitPython flashing | proxy the official release image (`/circuitpython/firmware`) for ESP32/S3/C3/C6 boards, flash via the unified dialog, serve a generated starter `code.py` (`/circuitpython/code`) | endpoint tests with mocked upstream; every board-id mapping verified against downloads.circuitpython.org; generated starters parse as valid Python; no live-flash gate |
|
|
131
132
|
| **Verified** | MCP server | 53 tools over the Model Context Protocol: 31 design / library / inventory / fab, plus 22 that reach hardware — workbench flash and boot verification, LoRaWAN compile / provision / activation, fleet and dashboard push + build status, and job polling for the long ones | the `mcp` package's own client connects to the mounted server over Streamable HTTP with the bearer token, lists the tools, drives a design from `create_design` to `render` and reads a resource, every PR (`tests/test_mcp_client.py`); tool / auth / resource tests in `tests/test_mcp_*.py`; the hardware tools drive the real clients against wire-level fakes, and were exercised against a live bench, ChirpStack and fleet during bring-up |
|
|
132
133
|
| **Experimental** | Thingiverse search relay | rank community models for a board | smoke-tested; depends on a third-party search API that ranks unevenly |
|
|
133
134
|
| **Verified** | Agent (Claude tool-using) | natural-language design driving | scored nightly against the 28-task list in `wirestudio/agent/eval_tasks.yaml`: the design it hands back passes `esphome config`, carries the asked-for change, and the turn stayed within its tool-call budget ([gate](.github/workflows/agent-eval.yml)); every task's reference solution passes the same scorer on every PR (`tests/test_agent_eval.py`). The nightly run drives the studio through Claude Code over MCP with the `CLAUDE_CODE_OAUTH_TOKEN` secret (a subscription); the embedded agent is scored too when `ANTHROPIC_API_KEY` is set. Each driver's first scored run sets its gate |
|
|
134
|
-
| **Verified** | PCB autorouting | Freerouting roundtrip — board → Specctra DSN → routed → SES import; SSE route endpoint, `route_pcb` MCP/agent tool, web-UI Route button, `?route=true` fab exports, `-pcb` image variant | representative examples route with zero unconnected items and
|
|
135
|
+
| **Verified** | PCB autorouting | Freerouting roundtrip — board → Specctra DSN → routed → SES import, GND pour filled; via cost and keepout rectangles as parameters; KiCad's DRC of the routed board reported back; SSE route endpoint, `route_pcb` MCP/agent tool, web-UI Route button, `?route=true` fab exports, `-pcb` image variant | representative examples route with zero unconnected items, a filled pour and a clean routed DRC; a high via cost must remove vias and a keepout must clear the track under it ([gate](.github/workflows/pcb-route.yml)) |
|
|
135
136
|
|
|
136
137
|
The **Verified** tier is the bar the project is asking to be judged
|
|
137
138
|
on. Everything else is offered with the caveat that's spelled out in
|
|
@@ -99,3 +99,9 @@ def test_fab_gerbers_route_unavailable_is_503(client, monkeypatch):
|
|
|
99
99
|
def test_fab_status_reports_route(client):
|
|
100
100
|
body = client.get("/design/fab/status").json()
|
|
101
101
|
assert "route" in body and "route_reason" in body
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def test_route_bad_params_are_422(client, toolchain):
|
|
105
|
+
for query in ("keepout=1,2,3", "keepout=1,2,3,4,pads", "via_costs=-5", "passes=0"):
|
|
106
|
+
resp = client.post(f"/design/kicad/route?{query}", json=_design())
|
|
107
|
+
assert resp.status_code == 422, query
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"""Checking and creating library boards at runtime."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
import pytest
|
|
7
|
+
from fastapi.testclient import TestClient
|
|
8
|
+
|
|
9
|
+
from wirestudio.api.app import create_app
|
|
10
|
+
from wirestudio.library import Library
|
|
11
|
+
from wirestudio.library.board_check import check_board_yaml, create_board
|
|
12
|
+
|
|
13
|
+
BUNDLED = Path(__file__).resolve().parent.parent / "wirestudio" / "library"
|
|
14
|
+
DRAFT = (Path(__file__).resolve().parent / "fixtures" / "boards" / "lolin-s2-mini.yaml").read_text()
|
|
15
|
+
DEVKIT = (BUNDLED / "boards" / "esp32-devkitc-v4.yaml").read_text()
|
|
16
|
+
C3 = (BUNDLED / "boards" / "esp32-c3-devkitm-1.yaml").read_text()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@pytest.fixture
|
|
20
|
+
def lib(tmp_path):
|
|
21
|
+
return Library(BUNDLED, tmp_path / "user")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@pytest.fixture
|
|
25
|
+
def client(tmp_path):
|
|
26
|
+
return TestClient(create_app(library=Library(BUNDLED, tmp_path / "user")))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _errors(text: str, lib: Library) -> str:
|
|
30
|
+
return " | ".join(check_board_yaml(text, lib).errors)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_every_bundled_board_passes(lib):
|
|
34
|
+
for path in sorted((BUNDLED / "boards").glob("*.yaml")):
|
|
35
|
+
report = check_board_yaml(path.read_text(), lib)
|
|
36
|
+
assert report.ok, (path.stem, report.errors)
|
|
37
|
+
assert report.exists == "bundled"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def test_draft_passes_and_renders_its_onboard_parts(lib):
|
|
41
|
+
report = check_board_yaml(DRAFT, lib)
|
|
42
|
+
assert report.ok, report.errors
|
|
43
|
+
assert report.library_id == "lolin-s2-mini" and report.exists == ""
|
|
44
|
+
assert any("gpio_output, gpio_input" in v for v in report.verified)
|
|
45
|
+
assert any("34.3 x 25.4" in v for v in report.verified)
|
|
46
|
+
assert any("no kicad: block" in w for w in report.warnings)
|
|
47
|
+
assert any("datasheet" in n for n in report.not_checked)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def test_unparseable_and_invalid_files_are_reported(lib):
|
|
51
|
+
assert "not valid YAML" in _errors("id: [", lib)
|
|
52
|
+
assert "top level must be a mapping" in _errors("- a", lib)
|
|
53
|
+
assert "platformio_board" in _errors(DRAFT.replace("platformio_board: lolin_s2_mini\n", ""), lib)
|
|
54
|
+
assert "names the file" in _errors(DRAFT.replace("id: lolin-s2-mini", "id: Lolin S2"), lib)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def test_platform_fields_must_agree(lib):
|
|
58
|
+
assert "not an ESP32 variant" in _errors(DRAFT.replace("chip_variant: esp32s2", "chip_variant: esp32s9"), lib)
|
|
59
|
+
assert "needs mcu esp32" in _errors(DRAFT.replace("mcu: esp32\n", "mcu: esp8266\n"), lib)
|
|
60
|
+
assert "not an ESPHome platform" in _errors(DRAFT.replace("chip_variant: esp32s2", "chip_variant: stm32"), lib)
|
|
61
|
+
assert "framework" in _errors(DRAFT.replace("framework: arduino", "framework: zephyr"), lib)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def test_every_named_pin_must_be_a_gpio(lib):
|
|
65
|
+
errors = _errors(DRAFT.replace("sda: GPIO33", "sda: GPIO34").replace("pin: GPIO15", "pin: GPIO14"), lib)
|
|
66
|
+
assert "default_buses.i2c.sda: GPIO34 is not in gpio_capabilities" in errors
|
|
67
|
+
assert "onboard_peripherals.led.pin: GPIO14 is not in gpio_capabilities" in errors
|
|
68
|
+
assert "no scl pin" in _errors(DRAFT.replace(", scl: GPIO35", ""), lib)
|
|
69
|
+
assert "unknown bus type" in _errors(DRAFT.replace(" spi: {", " qspi: {"), lib)
|
|
70
|
+
assert "no GND rail" in _errors(DRAFT.replace(' - {name: "GND", voltage: 0.0}\n', ""), lib)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def test_an_input_only_pin_cannot_drive_a_bus_line(lib):
|
|
74
|
+
text = DRAFT.replace("GPIO33: [gpio, pwm, i2c_sda]", "GPIO33: [gpio, input_only]")
|
|
75
|
+
assert "GPIO33 is input_only and cannot drive sda" in _errors(text, lib)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def test_radio_pins_are_cross_checked(lib):
|
|
79
|
+
heltec = (BUNDLED / "boards" / "heltec-wifi-lora32-v2.yaml").read_text()
|
|
80
|
+
assert check_board_yaml(heltec, lib).ok
|
|
81
|
+
broken = heltec.replace("pins: {cs: GPIO18", "pins: {cs: GPIO99")
|
|
82
|
+
assert broken != heltec
|
|
83
|
+
assert "radio.pins.cs: GPIO99" in _errors(broken, lib)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def test_enclosure_geometry_stays_on_the_pcb(lib):
|
|
87
|
+
off = DRAFT.replace("offset_mm: 8.95", "offset_mm: 20.0")
|
|
88
|
+
assert "runs off the 25.4 mm short_a edge" in _errors(off, lib)
|
|
89
|
+
edge = DRAFT.replace("edge: short_a", "edge: top")
|
|
90
|
+
assert "edge 'top'" in _errors(edge, lib)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def test_pin_map_is_checked_against_the_symbol(lib, tmp_path, monkeypatch):
|
|
94
|
+
symdir = tmp_path / "symbols"
|
|
95
|
+
symdir.mkdir()
|
|
96
|
+
pins = " ".join(
|
|
97
|
+
f'(pin passive line (at 0 0 0) (length 2.54) (name "Pin_{n}") (number "{n}"))' for n in range(1, 31))
|
|
98
|
+
(symdir / "Connector_Generic.kicad_sym").write_text(
|
|
99
|
+
'(kicad_symbol_lib (version 20231120) (generator kicad_symbol_editor)'
|
|
100
|
+
f' (symbol "Conn_02x15_Odd_Even" {pins}))')
|
|
101
|
+
monkeypatch.setenv("KICAD8_SYMBOL_DIR", str(symdir))
|
|
102
|
+
report = check_board_yaml(C3, lib)
|
|
103
|
+
assert report.ok, report.errors
|
|
104
|
+
assert any("has every pin_map pin" in v for v in report.verified)
|
|
105
|
+
|
|
106
|
+
assert "has no pin '31'" in _errors(C3.replace('GPIO1: "19"', 'GPIO1: "31"'), lib)
|
|
107
|
+
assert "GPIO1 and GPIO0 share pin 17, which would short them" in _errors(C3.replace('GPIO1: "19"', 'GPIO1: "17"'), lib)
|
|
108
|
+
assert "no symbol 'Conn_02x20'" in _errors(C3.replace("Conn_02x15_Odd_Even", "Conn_02x20"), lib)
|
|
109
|
+
assert "symbol library 'RF_Module' not found" in _errors(DEVKIT, lib)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def test_create_saves_into_the_user_library_only(lib, tmp_path):
|
|
113
|
+
report = create_board(DRAFT, lib)
|
|
114
|
+
assert report.ok and report.saved.endswith("user/boards/lolin-s2-mini.yaml")
|
|
115
|
+
assert Path(report.saved).read_text() == DRAFT
|
|
116
|
+
assert lib.board_source("lolin-s2-mini") == "user"
|
|
117
|
+
assert lib.board("lolin-s2-mini").chip_variant == "esp32s2"
|
|
118
|
+
assert "lolin-s2-mini" in [b.id for b in lib.list_boards()]
|
|
119
|
+
|
|
120
|
+
again = create_board(DRAFT, lib)
|
|
121
|
+
assert not again.ok and any("already exists" in e for e in again.errors)
|
|
122
|
+
assert create_board(DRAFT, lib, overwrite=True).ok
|
|
123
|
+
|
|
124
|
+
bundled = create_board(DEVKIT, lib)
|
|
125
|
+
assert not bundled.ok and any("bundled board" in e for e in bundled.errors)
|
|
126
|
+
assert not (tmp_path / "user" / "boards" / "esp32-devkitc-v4.yaml").exists()
|
|
127
|
+
|
|
128
|
+
with pytest.raises(PermissionError):
|
|
129
|
+
lib.delete_board("esp32-devkitc-v4")
|
|
130
|
+
lib.delete_board("lolin-s2-mini")
|
|
131
|
+
assert lib.board_source("lolin-s2-mini") == ""
|
|
132
|
+
with pytest.raises(FileNotFoundError):
|
|
133
|
+
lib.board("lolin-s2-mini")
|
|
134
|
+
|
|
135
|
+
assert not create_board(DRAFT, Library(BUNDLED)).ok # no user dir configured
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def test_a_bundled_board_wins_over_a_user_file(lib, tmp_path):
|
|
139
|
+
(tmp_path / "user" / "boards").mkdir(parents=True)
|
|
140
|
+
(tmp_path / "user" / "boards" / "esp32-devkitc-v4.yaml").write_text(DRAFT.replace("lolin-s2-mini", "esp32-devkitc-v4"))
|
|
141
|
+
assert lib.board_source("esp32-devkitc-v4") == "bundled"
|
|
142
|
+
assert lib.board("esp32-devkitc-v4").chip_variant == "esp32"
|
|
143
|
+
assert [b.id for b in lib.list_boards()].count("esp32-devkitc-v4") == 1
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def test_user_board_flows_into_a_design(lib):
|
|
147
|
+
from wirestudio.generate.yaml_gen import render_yaml
|
|
148
|
+
from wirestudio.model import Design
|
|
149
|
+
|
|
150
|
+
assert create_board(DRAFT, lib).ok
|
|
151
|
+
design = Design.model_validate({
|
|
152
|
+
"schema_version": "0.1", "id": "t", "name": "t",
|
|
153
|
+
"board": {"library_id": "lolin-s2-mini", "mcu": "esp32"},
|
|
154
|
+
"power": {"supply": "usb-5v", "rail_voltage_v": 5.0, "budget_ma": 500},
|
|
155
|
+
"components": [{"id": "led", "library_id": "gpio_output", "label": "LED"}],
|
|
156
|
+
"buses": [], "requirements": [], "warnings": [],
|
|
157
|
+
"connections": [
|
|
158
|
+
{"component_id": "led", "pin_role": "OUT", "target": {"kind": "gpio", "pin": "GPIO15"}},
|
|
159
|
+
],
|
|
160
|
+
})
|
|
161
|
+
rendered = render_yaml(design, lib)
|
|
162
|
+
assert "board: lolin_s2_mini" in rendered and "variant: ESP32S2" in rendered
|
|
163
|
+
assert "pin: GPIO15" in rendered
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def test_api_round_trip(client):
|
|
167
|
+
check = client.post("/library/boards/check", json={"yaml": DRAFT})
|
|
168
|
+
assert check.status_code == 200 and check.json()["ok"]
|
|
169
|
+
|
|
170
|
+
created = client.post("/library/boards", json={"yaml": DRAFT})
|
|
171
|
+
assert created.status_code == 201 and created.json()["saved"]
|
|
172
|
+
listed = {b["id"]: b for b in client.get("/library/boards").json()}
|
|
173
|
+
assert listed["lolin-s2-mini"]["source"] == "user"
|
|
174
|
+
assert listed["esp32-devkitc-v4"]["source"] == "bundled"
|
|
175
|
+
assert client.get("/library/boards/lolin-s2-mini").json()["chip_variant"] == "esp32s2"
|
|
176
|
+
assert client.get("/library/boards/lolin-s2-mini/yaml").text == DRAFT
|
|
177
|
+
|
|
178
|
+
assert client.post("/library/boards", json={"yaml": DRAFT}).status_code == 409
|
|
179
|
+
assert client.post("/library/boards", json={"yaml": DEVKIT}).status_code == 409
|
|
180
|
+
bad = client.post("/library/boards", json={"yaml": DRAFT.replace("pin: GPIO15", "pin: GPIO14")})
|
|
181
|
+
assert bad.status_code == 422 and not bad.json()["ok"]
|
|
182
|
+
|
|
183
|
+
assert client.delete("/library/boards/esp32-devkitc-v4").status_code == 409
|
|
184
|
+
assert client.delete("/library/boards/lolin-s2-mini").status_code == 200
|
|
185
|
+
assert client.delete("/library/boards/lolin-s2-mini").status_code == 404
|
|
186
|
+
assert "lolin-s2-mini" not in {b["id"] for b in client.get("/library/boards").json()}
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def test_agent_tools(lib):
|
|
190
|
+
from wirestudio.agent.tools import _run_board_check, _run_board_create, _run_board_delete, _run_list_boards
|
|
191
|
+
|
|
192
|
+
assert _run_board_check({}, lib, yaml=DRAFT)["ok"]
|
|
193
|
+
assert _run_board_create({}, lib, yaml=DRAFT)["saved"]
|
|
194
|
+
sources = {b["library_id"]: b["source"] for b in _run_list_boards({}, lib)["boards"]}
|
|
195
|
+
assert sources["lolin-s2-mini"] == "user"
|
|
196
|
+
assert _run_board_delete({}, lib, library_id="lolin-s2-mini")["ok"]
|
|
197
|
+
assert not _run_board_delete({}, lib, library_id="esp32-devkitc-v4")["ok"]
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def test_platformio_board_is_looked_up_in_esphome(lib):
|
|
201
|
+
pytest.importorskip("esphome")
|
|
202
|
+
assert any("lolin_s2_mini is an ESPHome esp32 board" in v for v in check_board_yaml(DRAFT, lib).verified)
|
|
203
|
+
unknown = check_board_yaml(DRAFT.replace("lolin_s2_mini", "no_such_board"), lib)
|
|
204
|
+
assert unknown.ok and any("not in ESPHome's esp32 board list" in w for w in unknown.warnings)
|
|
205
|
+
assert "is an esp32c3 board in ESPHome, not esp32s2" in _errors(DRAFT.replace("lolin_s2_mini", "esp32-c3-devkitm-1"), lib)
|