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))