Spaces:
Build error
Build error
| import json | |
| from datetime import datetime | |
| def get_esp32_templates(): | |
| """Get predefined ESP32 code templates""" | |
| return { | |
| "basic": { | |
| "includes": ["Arduino.h"], | |
| "setup": "Serial.begin(115200);\n", | |
| "loop": "// Your code here\n" | |
| }, | |
| "wifi_sta": { | |
| "includes": ["WiFi.h"], | |
| "setup": "Serial.begin(115200);\nWiFi.begin(ssid, password);\nwhile (WiFi.status() != WL_CONNECTED) {\n delay(1000);\n Serial.println(\"Connecting to WiFi...\");\n}\nSerial.println(\"Connected to WiFi\");\n", | |
| "loop": "// WiFi connected code\n" | |
| }, | |
| "webserver": { | |
| "includes": ["WiFi.h", "WebServer.h"], | |
| "setup": "Serial.begin(115200);\nWiFi.begin(ssid, password);\nwhile (WiFi.status() != WL_CONNECTED) {\n delay(1000);\n Serial.println(\"Connecting to WiFi...\");\n}\nserver.begin();\n", | |
| "loop": "server.handleClient();\n" | |
| } | |
| } | |
| def get_component_libraries(): | |
| """Get required libraries for different components""" | |
| return { | |
| "led": [], | |
| "button": [], | |
| "dht22": ["DHT sensor library"], | |
| "bme280": ["Adafruit BME280 Library", "Adafruit Unified Sensor"], | |
| "oled": ["Adafruit GFX Library", "Adafruit SSD1306"], | |
| "servo": ["Servo"], | |
| "stepper": ["Stepper"], | |
| "ultrasonic": [], | |
| "pir": [], | |
| "relay": [], | |
| "mqtt": ["PubSubClient"], | |
| "webserver": ["WebServer", "WiFi"], | |
| "webclient": ["HTTPClient", "WiFi"], | |
| "bluetooth": ["BluetoothSerial"], | |
| "lora": ["LoRa"], | |
| "gps": ["TinyGPS++"], | |
| "sdcard": ["SD"], | |
| "camera": ["esp32-camera"], | |
| "audio_i2s": ["I2S"], | |
| "neopixel": ["Adafruit NeoPixel"] | |
| } | |
| def generate_esp32_code(config): | |
| """Generate complete ESP32 Arduino code""" | |
| code_parts = [] | |
| # Header comment | |
| code_parts.append(f"""/* | |
| * Project: {config['project_info']['name']} | |
| * Description: {config['project_info']['description']} | |
| * Author: {config['project_info']['author']} | |
| * Version: {config['project_info']['version']} | |
| * Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} | |
| */ | |
| """) | |
| # Includes | |
| includes = set(["Arduino.h"]) | |
| if config['wifi']['enabled']: | |
| includes.add("WiFi.h") | |
| if 'webserver' in config['components']: | |
| includes.add("WebServer.h") | |
| if 'webclient' in config['components']: | |
| includes.add("HTTPClient.h") | |
| for component in config['components']: | |
| libs = get_component_libraries().get(component, []) | |
| for lib in libs: | |
| if '.' in lib: | |
| include_name = lib.replace(' ', '').replace('.', '.h') | |
| else: | |
| include_name = lib.replace(' ', '').replace('Library', '') + '.h' | |
| includes.add(include_name) | |
| for include in sorted(includes): | |
| code_parts.append(f"#include <{include}>") | |
| code_parts.append("") | |
| # WiFi credentials | |
| if config['wifi']['enabled']: | |
| code_parts.append(f"const char* ssid = \"{config['wifi']['ssid']}\";") | |
| code_parts.append(f"const char* password = \"{config['wifi']['password']}\";") | |
| code_parts.append("") | |
| # Global variables | |
| for var_name, var_info in config['variables'].items(): | |
| code_parts.append(f"{var_info['type']} {var_name} = {var_info['value']};") | |
| if config['variables']: | |
| code_parts.append("") | |
| # Pin definitions | |
| for pin_name, pin_num in config['pins'].items(): | |
| code_parts.append(f"const int {pin_name} = {pin_num};") | |
| if config['pins']: | |
| code_parts.append("") | |
| # Component objects | |
| if 'dht22' in config['components']: | |
| code_parts.append("DHT dht(DHT_PIN, DHT22);") | |
| if 'bme280' in config['components']: | |
| code_parts.append("Adafruit_BME280 bme;") | |
| if 'oled' in config['components']: | |
| code_parts.append("Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);") | |
| if 'servo' in config['components']: | |
| code_parts.append("Servo myServo;") | |
| if 'neopixel' in config['components']: | |
| code_parts.append("Adafruit_NeoPixel pixels(NUMPIXELS, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);") | |
| # Setup function | |
| code_parts.append("void setup() {") | |
| # Serial | |
| code_parts.append(" Serial.begin(115200);") | |
| # WiFi setup | |
| if config['wifi']['enabled']: | |
| if config['wifi']['mode'] == "STA (Station)": | |
| code_parts.extend([ | |
| " WiFi.begin(ssid, password);", | |
| " while (WiFi.status() != WL_CONNECTED) {", | |
| " delay(1000);", | |
| " Serial.println(\"Connecting to WiFi...\");", | |
| " }", | |
| " Serial.println(\"Connected to WiFi\");", | |
| " Serial.print(\"IP address: \");", | |
| " Serial.println(WiFi.localIP());" | |
| ]) | |
| # Component setup | |
| if 'dht22' in config['components']: | |
| code_parts.append(" dht.begin();") | |
| if 'bme280' in config['components']: | |
| code_parts.append(" if (!bme.begin(0x76)) { Serial.println(\"BME280 not found\"); }") | |
| if 'oled' in config['components']: | |
| code_parts.extend([ | |
| " if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {", | |
| " Serial.println(F(\"SSD1306 allocation failed\"));", | |
| " }", | |
| " display.clearDisplay();", | |
| " display.display();" | |
| ]) | |
| if 'servo' in config['components']: | |
| code_parts.append(" myServo.attach(SERVO_PIN);") | |
| if 'neopixel' in config['components']: | |
| code_parts.append(" pixels.begin();") | |
| # Custom setup code | |
| if config.get('custom_code', {}).get('setup'): | |
| for line in config['custom_code']['setup'].split('\n'): | |
| if line.strip(): | |
| code_parts.append(f" {line}") | |
| code_parts.append("}") | |
| code_parts.append("") | |
| # Loop function | |
| code_parts.append("void loop() {") | |
| # Custom loop code | |
| if config.get('custom_code', {}).get('loop'): | |
| for line in config['custom_code']['loop'].split('\n'): | |
| if line.strip(): | |
| code_parts.append(f" {line}") | |
| else: | |
| code_parts.append(" // Your main code here") | |
| code_parts.append("}") | |
| code_parts.append("") | |
| # Helper functions | |
| if config.get('custom_code', {}).get('helpers'): | |
| code_parts.append("// Helper Functions") | |
| code_parts.append(config['custom_code']['helpers']) | |
| return '\n'.join(code_parts) | |
| def validate_pin_config(pins): | |
| """Validate pin configuration for conflicts""" | |
| used_pins = set() | |
| conflicts = [] | |
| for pin_name, pin_num in pins.items(): | |
| if pin_num in used_pins: | |
| conflicts.append(f"Pin {pin_num} is used multiple times") | |
| used_pins.add(pin_num) | |
| return conflicts | |
| def format_code(code): | |
| """Basic code formatting""" | |
| lines = code.split('\n') | |
| formatted = [] | |
| indent_level = 0 | |
| for line in lines: | |
| stripped = line.strip() | |
| if not stripped: | |
| formatted.append('') | |
| continue | |
| if stripped.startswith('}') or stripped.startswith(')'): | |
| indent_level = max(0, indent_level - 1) | |
| formatted.append(' ' * indent_level + stripped) | |
| if stripped.endswith('{') or stripped.endswith('('): | |
| indent_level += 1 | |
| return '\n'.join(formatted) | |
| def generate_libraries_txt(config): | |
| """Generate libraries.txt file content""" | |
| libraries = set() | |
| for component in config['components']: | |
| comp_libs = get_component_libraries().get(component, []) | |
| libraries.update(comp_libs) | |
| libraries.update(config.get('libraries', [])) | |
| return '\n'.join(sorted(libraries)) |