| پوشه/فایل | توضیح |
|---|---|
editor.html |
فایل اصلی HTML - نقطه شروع برنامه |
editor.css |
استایلهای اصلی برنامه |
feature_registry.js |
رجیستری مرکزی برای ثبت تمام ویجتها |
js/ |
منطق اصلی برنامه (مدیریت state، canvas، export/import) |
features/ |
کتابخانه ویجتها (هر ویجت یک پوشه جدا) |
hardware/ |
پروفایلهای سختافزاری (YAML configuration) |
materialdesignicons-webfont.ttf |
فونت آیکونهای Material Design |
این پروژه از یک معماری ماژولار مبتنی بر Feature Registry استفاده میکند:
┌─────────────────────────────────────────────┐
│ editor.html │
│ (نقطه ورود - بارگذاری HTML/CSS/JS) │
└─────────────────┬───────────────────────────┘
│
┌─────────────┴─────────────┐
▼ ▼
┌─────────┐ ┌─────────────────┐
│ CSS │ │ JavaScript │
│ Styles │ │ Core Logic │
└─────────┘ └────────┬────────┘
│
┌────────────────────┼────────────────────┐
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐
│ Feature │ │ Core │ │ UI │
│ Registry │ │ Modules │ │ Components │
│ (ثبت ویجتها) │ │ (State, Canvas)│ │ (Settings, Modals) │
└────────┬────────┘ └────────┬────────┘ └──────────┬──────────┘
│ │ │
└───────────┬───────┴─────────────────────┘
▼
┌─────────────────┐
│ ویجتهای │
│ (features/) │
│ • lvgl_slider │
│ • button │
│ • progress_bar│
└─────────────────┘
-
js/core/- هسته اصلی برنامه:state.js- مدیریت state برنامهcanvas.js- مدیریت canvas و کشیدن/رها کردنwidget_factory.js- ایجاد ویجتهاproperties.js- پنل تنظیمات ویجتها
-
js/io/- عملیات ورودی/خروجی:yaml_export.js- تولید کد YAML از طراحیyaml_import.js- وارد کردن کد YAML به ویرایشگرhardware_generator.js- تولید کانفیگ سختافزاری
-
js/ui/- کامپوننتهای رابط کاربری:device_settings.js- تنظیمات دستگاهeditor_settings.js- تنظیمات ویرایشگرmodal_wiring.js- مدیریت مودالها
ویجتها در پوشههای جداگانه سازماندهی شدهاند. هر ویجت حداقل شامل:
render.js- تابع رندر ویجت در مرورگر- (برخی)
yaml_export.js- منطق تولید YAML برای آن ویجت
دستهبندی ویجتها:
- LVGL Widgets:
lvgl_button,lvgl_slider,lvgl_switch(26 نوع مختلف) - Data Widgets:
sensor_text,progress_bar,graph - Media Widgets:
image,icon,weather_icon - Layout Widgets:
shape_rect,rounded_rect,line - Templates:
template_nav_bar,template_sensor_bar
این پروژه یک برنامه تکصفحهای (SPA) خالص است که در مرورگر اجرا میشود:
# 1. فقط کافی است فایل HTML را در مرورگر باز کنید
firefox ./frontend/editor.html # یا
google-chrome ./frontend/editor.html
# 2. یا از یک سرور ساده استفاده کنید
cd ./frontend
python3 -m http.server 8000
# سپس در مرورگر: http://localhost:8000/editor.htmlgraph LR
A[User Drag & Drop] --> B[Canvas Module]
B --> C[State Manager]
C --> D[Feature Registry]
D --> E[Widget Renderer]
C --> F[YAML Generator]
F --> G[Output YAML]
E --> H[Browser Preview]
- طراحی بصری واسط کاربری ESPHome/LVGL
- پیشنمایش زنده در مرورگر
- تولید خودکار کد YAML برای ESPHome
- پشتیبانی از سختافزارهای متنوع (فایلهای YAML در
hardware/) - سیستم ماژولار ویجتها - افزودن ویجت جدید آسان است
- مدیریت state پیشرفته با undo/redo
./frontend/js/io/yaml_export.js # اصلیترین generator
./frontend/js/io/yaml_export_lvgl.js # generator مخصوص LVGL
./frontend/js/io/hardware_generator.js # generator سختافزار
./frontend/js/core/state.js # مدیریت state کلی
./frontend/js/core/constants.js # ثابتهای پروژه
./frontend/hardware/ # پوشه کانفیگهای سختافزاری (یک نمونه)
./frontend/features/lvgl_slider/render.js
./frontend/features/lvgl_slider/yaml_export.js (اگر وجود دارد)
frontend/
├── js/io/
│ ├── c_code_generator.js # ✅ جدید - تولید کننده کد C
│ ├── java_code_generator.js # ✅ جدید - تولید کننده کد Java
│ ├── live_preview.js # ✅ جدید - نمایش زنده متغیرها
│ └── variable_manager.js # ✅ جدید - مدیریت متغیرهای برد
├── core/
│ └── board_variables.js # ✅ جدید - تعریف متغیرهای خاص برد
└── ui/
└── code_preview_panel.js # ✅ جدید - پنل نمایش کد
- قالب خروجیهای شما (چطور کد C/Java تولید میکنید)
- ساختار دادههای ورودی (چه اطلاعاتی از state میگیرید)
- الگوی نامگذاری متغیرها
- نحوه مدیریت پینها و سختافزار
یک نمونه کوچک از کدی که میخواهید تولید شود بفرستید:
// مثال کد C مورد انتظار
#define TEMP_SENSOR_PIN 4
#define LED_PIN 5
int sensor_value = 0;
float temperature = 0.0;
void read_sensor() {
sensor_value = analogRead(TEMP_SENSOR_PIN);
temperature = sensor_value * 0.1;
}یا برای Java:
// مثال کد Java
public class ESP32Board {
private static final int TEMP_PIN = 4;
private float currentTemp;
public void readTemperature() {
// منطق خواندن دما
}
}سیستم فعلی این flow را دارد:
ویجتها → State → YAML Generator → خروجی YAML
ما میخواهیم به این تبدیل شود:
ویجتها → State → [YAML Generator, C Generator, Java Generator] → خروجیهای چندگانه
عالی! این کدهای نمونه بسیار باارزش هستند. حالا کاملاً متوجه شدم که چه نوع کدی میخواهید تولید کنید. این کدها یک سیستم embedded کامل با UI هستند که شامل:
- ماژولهای LVGL برای رابط کاربری
- مدیریت GPIO برای کنترل پینها
- خواندن سنسورها (ADC، DHT، DS18B20)
- منطق کنترل (ترموستات، PWM، etc.)
- ذخیرهسازی در فایلها (JSON)
- مدیریت تایمر و event loop
- مدیریت حالتها (state management)
frontend/
├── js/io/
│ ├── embedded_code_generator.js # ✅ جدید - تولید کننده کد embedded
│ ├── board_config_manager.js # ✅ جدید - مدیریت کانفیگ برد
│ ├── peripheral_manager.js # ✅ جدید - مدیریت پریفرالها
│ └── pin_manager.js # ✅ جدید - مدیریت پینها
├── core/
│ ├── embedded_state.js # ✅ جدید - state مخصوص embedded
│ └── module_registry.js # ✅ جدید - رجیستری ماژولها
└── ui/
├── embedded_preview_panel.js # ✅ جدید - پنل پیشنمایش کد
└── pin_assignments_modal.js # ✅ جدید - مودال تخصیص پینها
- ویجتهای UI (از طراحی بصری)
- پینهای اختصاص داده شده (GPIO, ADC, etc.)
- متغیرهای تعریف شده (sensors, states, etc.)
- منطق کنترل (event handlers, timers)
// 1. کد Embedded (شبیه نمونههای شما)
var lv = require('@native.lvgl');
var GPIO = require('@native.gpio');
// 2. کد تنظیمات Hardware
const CONFIG = {
TEMP_SENSOR_PIN: 21,
LED_PIN: 32,
ADC_CHANNEL: 5
};
// 3. کد UI با LVGL
// 4. کد منطق کسبوکار
// 5. کد ذخیرهسازی (اختیاری)بر اساس نمونههای شما، ساختار کد اینطور است:
var lv = require('@native.lvgl');
var GPIO = require('@native.gpio');
var Timer = require('@native.timer');
var fs = require('@native.fs');var CONFIG = {
TEMP_PIN: 21,
HUM_PIN: 22,
DHT_TYPE: 22,
INTERVAL: 2000
};// ایجاد صفحه و اجزای UI
var scr = lv.lv_scr_act();
var mainContainer = lv.lv_obj_create(scr);
// ...var currentTemp = 25.0;
var targetTemp = 22.0;
var relayState = false;
var mode_index = 2;lv.lv_obj_add_event_cb(btnPlus, function() {
targetTemp += 0.5;
updateDisplay();
}, lv.LV_EVENT_CLICKED, null);while (true) {
// خواندن سنسورها
// بهروزرسانی UI
// بررسی دکمهها
Timer.delay(100);
}برای پشتیبانی از این کدها، نیاز به ویجتهای جدید داریم:
features/
├── embedded_gpio/
│ ├── render.js
│ └── code_generator.js
├── embedded_sensor/
│ ├── render.js
│ └── code_generator.js
├── embedded_adc/
│ ├── render.js
│ └── code_generator.js
└── embedded_pwm/
├── render.js
└── code_generator.js
features/
├── embedded_timer/
├── embedded_loop/
├── embedded_state_machine/
└── embedded_file_storage/
// frontend/js/io/embedded_code_generator.js
class EmbeddedCodeGenerator {
constructor(stateManager) {
this.state = stateManager;
this.modules = new Set();
this.pins = new Map();
this.variables = new Map();
this.eventHandlers = [];
}
generateCode(projectData) {
const code = {
imports: this.generateImports(projectData),
config: this.generateConfig(projectData),
ui: this.generateUI(projectData),
variables: this.generateVariables(projectData),
functions: this.generateFunctions(projectData),
mainLoop: this.generateMainLoop(projectData)
};
return this.formatCode(code);
}
generateImports(projectData) {
const imports = ['var lv = require(\'@native.lvgl\');'];
if (this.hasGPIO(projectData)) {
imports.push('var GPIO = require(\'@native.gpio\');');
}
if (this.hasADC(projectData)) {
imports.push('var ADC = require(\'@native.adc\');');
}
if (this.hasTimer(projectData)) {
imports.push('var Timer = require(\'@native.timer\');');
}
if (this.hasStorage(projectData)) {
imports.push('var fs = require(\'@native.fs\');');
}
return imports.join('\n');
}
generateConfig(projectData) {
const configs = [];
// جمعآوری پینها
projectData.widgets.forEach(widget => {
if (widget.type === 'gpio_output') {
configs.push(` ${widget.name}_PIN: ${widget.pin},`);
} else if (widget.type === 'adc_input') {
configs.push(` ${widget.name}_PIN: ${widget.pin},`);
configs.push(` ${widget.name}_CHANNEL: ${widget.channel},`);
}
});
return `var CONFIG = {\n${configs.join('\n')}\n INTERVAL: 1000\n};`;
}
// ... ادامه توابع
}// frontend/js/io/board_config_manager.js
class BoardConfigManager {
constructor() {
this.boards = {
'esp32': {
name: 'ESP32',
pins: this.generateESP32Pins(),
peripherals: ['GPIO', 'ADC', 'DAC', 'I2C', 'SPI', 'UART'],
memory: {
flash: '4MB',
ram: '520KB',
psram: 'Optional'
}
},
'esp32-s3': {
name: 'ESP32-S3',
pins: this.generateESP32S3Pins(),
peripherals: ['GPIO', 'ADC', 'DAC', 'I2C', 'SPI', 'UART', 'USB'],
memory: {
flash: '8MB',
ram: '512KB',
psram: 'Optional'
}
}
// ... بردهای دیگر
};
}
generateESP32Pins() {
const pins = [];
// GPIO Pins
for (let i = 0; i <= 39; i++) {
if ([24, 28, 29, 30, 31].includes(i)) continue; // Pins not exposed
const pin = {
number: i,
type: 'GPIO',
functions: [],
restrictions: []
};
// Add functions based on pin number
if (i === 0 || i === 2) {
pin.restrictions.push('Boot configuration - use with caution');
}
if ([32, 33, 34, 35, 36, 39].includes(i)) {
pin.functions.push('ADC');
}
if ([25, 26].includes(i)) {
pin.functions.push('DAC');
}
pins.push(pin);
}
return pins;
}
getAvailablePin(boardType, pinType) {
return this.boards[boardType].pins
.filter(pin => pin.functions.includes(pinType))
.map(pin => pin.number);
}
validatePinAssignment(boardType, pinNumber, functionType) {
const pin = this.boards[boardType].pins.find(p => p.number === pinNumber);
if (!pin) {
return { valid: false, error: `Pin ${pinNumber} does not exist on ${boardType}` };
}
if (!pin.functions.includes(functionType)) {
return {
valid: false,
error: `Pin ${pinNumber} does not support ${functionType}`
};
}
return { valid: true, pin };
}
}- فایل
embedded_code_generator.js - فایل
board_config_manager.js - فایل
pin_manager.js
- ویجت GPIO Input/Output
- ویجت ADC Reader
- ویجت Sensor (DHT, DS18B20)
- ویجت Timer
- پنل کد Embedded
- مودال تخصیص پینها
- مدیریت ماژولها
- اضافه کردن تب جدید در خروجیها
- اتصال state manager به embedded generator
- تست کامل
لطفاً این فایلهای موجود را برای من بفرستید تا دقیقتر شروع کنیم:
yaml_export.js- برای فهمیدن ساختار generator فعلیstate.js- برای فهمیدن state management- هر فایلی که فکر میکنید مرتبط است
┌─────────────────────────────────────────────────┐ │ فاز ۱ │ │ تکمیل LVGL + تولید کد C/Java │ │ • اصلاح رابط کاربری + تبهای جدید │ │ • تولید کد C برای LVGL + ESP32 │ │ • تولید کد Java برای Android/LVGL │ │ • پنل پیشنمایش تعاملی کد │ └─────────────────┬───────────────────────────────┘ │ ┌─────────────────▼───────────────────────────────┐ │ فاز ۲ │ │ Embedded Code Generation │ │ • ویجتهای GPIO/ADC/Sensor │ │ • مدیریت پینها و سختافزار │ │ • تولید کد Embedded JavaScript │ │ • شبیهسازی در مرورگر │ └─────────────────────────────────────────────────┘
- آدرس گیتهاب: https://github.com/hadipic/evm-linux
برای اجرای شبیه ساز به شاخه bsp بروید و در انجا به شاخه سیمولیشن بروید ردمی رو بخوانید این یک راهنمای جامع برای کامپایل و اجرای EVM Simulator روی ویندوز است. در زیر تمام مراحل به زبان فارسی به صورت واضح و گامبهگام توضیح داده شده است :
- EVM چیست؟
EVM مخفف Embedded Virtual Machine (ماشین مجازی توکار) است، یک چارچوب سازگار موتور اسکریپتنویسی عمومی. موتورهای اسکریپتنویسی که در حال حاضر پشتیبانی میشوند:
pikascript: یک موتور اسکریپتنویسی پایتون فوق سبک.
quickjs: یک موتور جاوااسکریپت توکار.
mujs: یک موتور جاوااسکریپت توکار.
duktape: یک موتور جاوااسکریپت توکار.
jerryscript: یک موتور جاوااسکریپت توکار.
quickvm: یک موتور اسکریپتنویسی عمومی توکار با کارایی بالا که توسط تیم EVM توسعه یافته است.
- ساخت اکوسیستم برنامههای اینترنت اشیاء EVM
- چارچوب برنامه کوچک EVUE
EVUE مخفف Embedded VUE است، یک چارچوب برنامهنویسی با دستوراتی شبیه به VUE که توسط تیم EVM برای دستگاههای توکار طراحی شده است. EVUE نه تنها ویژگیهای برنامهنویسی کارآمد VUE را حفظ کرده، بلکه برای پلتفرمهای توکار بهینه و سازگار شده است.
کامپایل آنلاین، بدون کد C
پشتیبانی از چندین موتور اسکریپتنویسی
پشتیبانی از توسعه با چندین زبان مانند جاوااسکریپت و پایتون
چارچوب برنامهنویسی مبتنی بر داده، با معماری MVVM
پشتیبانی همزمان از توسعه سناریوهای با رابط کاربری و بدون رابط کاربری
-
چشمانداز EVM
اتصال همه چیز، به لطف ما ساده شد
شکستن مرزهای مهارتی بین اینترنت اشیاء و اینترنت، توانمندسازی شرکتها و توسعهدهندگان اینترنت اشیاء با مدل توسعهای کاملاً جدید، کاهش سطح پیچیدگی توسعه اینترنت اشیاء و افزایش سرعت توسعه به شدت. 5. ساختار دایرکتوری کد EVM فایل/پوشه توضیح bsp دایرکتوری سازگاری با بردهای توسعه components دایرکتوری کامپوننتهای شخص ثالث docs دایرکتوری منابع اسناد و تصاویر include دایرکتوری فایلهای هدر engines موتورهای اسکریپتنویسی modules دایرکتوری ماژولها test کدهای تست tools ابزارهای توسعه tutorial نمونههای آموزشی و راهنما 6. راهنمای توسعه
راهنمای آنلاین EVM در شاپ الکترونیک (www.shpelectronic.ir)
-
مشارکت در کد
پروژه متنباز EVM را در حساب گیتهاب خود Fork کنید. یک کپی از کد EVM را به صورت محلی Clone کنید. پس از ایجاد تغییرات یا افزودن ویژگی جدید، آن را به شاخه راهدور (remote) fork شده خود Push کنید. یک Pull Request ایجاد کنید و درخواست ادغام تغییرات خود را به شاخه توسعه اصلی EVM ارسال کنید. تیم توسعه EVM به طور منظم کدها را بررسی کرده و پس از عبور از تستها، آنها را ادغام میکند.
-
پیوستن به EVM
فناوری آینده را میسازد. تیم EVM به مشارکت شما نیاز دارد. تیم EVM در حال حاضر از توسعهدهندگان جامعه با انگیزه و رویاپرداز برای همکاری در ایجاد اکوسیستم جدید اینترنت اشیاء دعوت به عمل میآورد. صرف نظر از پیشینه فنی شما، میتوانید سهمی هرچند کوچک در رشد EVM داشته باشید. تیم EVM به گرمی از شما استقبال میکند! 8.1 اتحادیه توسعهدهندگان اکوسیستم EVM
اتحادیه توسعهدهندگان اکوسیستم EVM یک گروه عمیق از علاقهمندان و توسعهدهندگان است که توسط تیم EVM برای جامعه تشکیل شده است. در اینجا شما میتوانید:
همیشه از جدیدترین تحولات فنی EVM مطلع باشید و کارآمدترین روشهای توسعه اینترنت اشیاء را بیاموزید.
در تعیین استراتژی آینده و برنامهریزی مسیر توسعه EVM مشارکت کنید.
از تماس نزدیک و بدون واسطه با تیم EVM بهرهمند شوید و برای همکاری در آینده به EVM بپیوندید.
از پشتیبانی فنی رایگان نسخه سازمانی EVM و اشتراکگذاری آزادانه راهحلهای فنی متنوع بهرهمند شوید.

در صورت منقضی شدن QR کد گروه، لطفاً با شناسه تلگرام @hadipic تماس بگیرید و در یادداشت خود بنویسید: [نام شما] -- علاقهمند به ماشینهای مجازی -- [شهر شما]. شما در اولین فرصت به گروه اضافه خواهید شد. با تشکر!
8.2 فراخوان قهرمانان EVM (EVM Hero Recruitment)
EVM در مرحله رشد سریع استارتاپی قرار دارد. از افراد باانگیزه برای پیوستن و همکاری در گشودن افق جدیدی برای اکوسیستم اینترنت اشیاء استقبال میکند!
اگر به فناوری ماشینهای مجازی یا نحوه پیادهسازی یک زبان برنامهنویسی علاقهمندید، ما از شما استقبال میکنیم.
اگر درک و تجربه عمیقی از جاوااسکریپت، پایتون و زبان C دارید، ما از شما استقبال میکنیم.
اگر درک عمیقی از RTOSها دارید و یک توسعهدهنده حرفهای C هستید که هسته یک یا چند RTOS را به طور عمیق مطالعه کردهاید، ما از شما استقبال میکنیم.
اگر بر پروتکلهای مختلف اینترنت اشیاء و انتقال درایورها مسلط هستید، ما از شما استقبال میکنیم.
موقعیت مکانی: نیشابور، شهری که قهرمانان از آن برمیخیزند!
علاقهمندان میتوانند رزومه خود را به آدرس ایمیل ارسال کنند: hdi.bashniji@gmail.com. به پیوستن شما خوشآمد میگوییم! حقوق، سهام، اختیار معامله (آپشن)؛ انتخاب با شما!