# حساب کاربری (/fa/docs/app/account)
اپلیکیشن برای نمایش دستگاهها و داشبوردهای شما به حساب فلووا نیاز دارد.
## ورود [#ورود]
اپلیکیشن **ورود امن با فلووا** را در مرورگر باز میکند. مراحل ورود را در همان
مرورگر کامل کنید تا دوباره به اپلیکیشن برگردید. اگر ورود کامل نشد، پنجرهٔ مرورگر
را نبندید و خطای نمایشدادهشده را بخوانید.
بعد از ورود، دستگاههای اضافهشده به حساب شما در صفحهٔ دستگاهها نمایش داده
میشوند. فضای کاری تیمی و تنظیمات ساخت دستگاه در [کنسول](../../console/overview)
مدیریت میشود.
## پروفایل و خروج [#پروفایل-و-خروج]
از نوار پیمایش **حساب** را باز کنید تا نام نمایشی و شمارهٔ تلفن ثبتشده را
ببینید. برای پایان دادن به نشست، **خروج از حساب کاربری** را بزنید.
بعد از خروج، برای دیدن دستگاهها و داشبوردها باید دوباره وارد شوید. اطلاعات ورود
و کد فعالسازی را در اختیار دیگران نگذارید.
# هشدارها و اعلانها (/fa/docs/app/alerts)
صفحهٔ **هشدارها** رخدادهای مهم دستگاهها و اتوماسیونهای شما را نشان میدهد.
برای دیدن آن، از نوار پایین یا نوار بالای اپلیکیشن **هشدارها** را انتخاب کنید.
هشدارهای خواندهنشده با نشان کنار بخش هشدارها مشخص میشوند. یک مورد را باز کنید
تا پیام، دستگاه مربوط و زمان رخداد را ببینید. برای دریافت موارد تازه، فهرست را
دوباره بارگذاری کنید.
## فعالسازی اعلان مرورگر [#فعالسازی-اعلان-مرورگر]
در صفحهٔ هشدارها، مدیریت اعلانها را باز کنید و **فعالسازی اعلان** را بزنید.
مرورگر از شما اجازه میخواهد. برای دریافت اعلان هنگام بسته بودن صفحه، اجازه را
تأیید کنید.
اگر قبلاً اعلانها را مسدود کردهاید، اجازهٔ این نشانی را از تنظیمات مرورگر
فعال کنید و دوباره به اپلیکیشن برگردید. اگر اعلان فوری در مرورگر یا دستگاه شما
در دسترس نباشد، هشدارها همچنان در صفحهٔ اپلیکیشن ذخیره و نمایش داده میشوند.
اعلان مرورگر جای صفحهٔ هشدارها را نمیگیرد. برای بررسی پیام کامل و زمان رخداد،
خود فهرست هشدارها را باز کنید.
# داشبوردها (/fa/docs/app/dashboards)
داشبورد تجربهای است که صاحب محصول در استودیو ساخته و منتشر کرده است. برای
دیدن آن، از صفحهٔ **دستگاهها** یک دستگاه را باز کنید.
## داشبورد منتشرشده [#داشبورد-منتشرشده]
اپلیکیشن نسخهٔ منتشرشده را بارگذاری میکند. تغییرات پیشنویس استودیو تا زمان
انتشار نسخهٔ جدید در اپلیکیشن دیده نمیشود.
داشبورد ممکن است شامل مقدارهای فعلی، نمودار، متن، وضعیت اتصال، کلیدهای روشن و
خاموش، فرمانها یا صفحههای دیگر باشد. اجزایی که میبینید به قالب دستگاه و
طراحی همان داشبورد بستگی دارد.
## خواندن و تغییر مقدارها [#خواندن-و-تغییر-مقدارها]
مقدارهای دستگاه با دادهٔ تازه بهروزرسانی میشوند. برای کنترل یک مقدار یا
فرمان، کنترل مربوط را در داشبورد انتخاب کنید و نتیجه را منتظر بمانید. اگر
دستگاه آفلاین باشد یا کانال دسترسی نوشتن نداشته باشد، تغییر ممکن است اجرا نشود.
بعضی داشبوردها تاریخچهٔ داده، پرسوجو یا زمانبندی را هم نمایش میدهند. این
گزینهها فقط وقتی دیده میشوند که صاحب محصول آنها را در نسخهٔ منتشرشده قرار
داده باشد.
## اگر داشبورد نمایش داده نشد [#اگر-داشبورد-نمایش-داده-نشد]
ابتدا آنلاین بودن دستگاه و اتصال اینترنت را بررسی کنید. سپس صفحهٔ دستگاه را
دوباره باز کنید. اگر هنوز داشبوردی وجود ندارد، صاحب محصول باید وجود نسخهٔ
منتشرشده و اتصال آن به قالب دستگاه را در استودیو بررسی کند.
# دستگاهها (/fa/docs/app/devices)
صفحهٔ **دستگاهها** فهرست دستگاههایی را نشان میدهد که به حساب اپلیکیشن شما
اضافه شدهاند. از همین صفحه میتوانید دستگاهی را باز کنید، دستگاهها را جستوجو
کنید و در صورت فعال بودن این قابلیت، گروههای دستگاه را مدیریت کنید.
## افزودن دستگاه [#افزودن-دستگاه]
۱. [اپلیکیشن فلووا](https://pwa.flova.ir/) را باز کنید و وارد شوید.
۲. **افزودن دستگاه** را بزنید.
۳. QR فعالسازی روی دستگاه یا بستهبندی را با دوربین مرورگر اسکن کنید.
۴. اگر اسکن ممکن نیست، **ورود دستی** را بزنید و کد فعالسازی را وارد کنید.
۵. یک نام برای دستگاه بنویسید و **تأیید و فعالسازی** را بزنید.
کد فعالسازی برای اضافه کردن دستگاه به حساب کاربری است. بعد از آن، راهاندازی
Wi‑Fi و اتصال دستگاه به فلووا مرحلهٔ جداگانهای است.
## پیدا کردن و باز کردن دستگاه [#پیدا-کردن-و-باز-کردن-دستگاه]
نام دستگاه را در جستوجو وارد کنید یا فهرست را بر اساس گروه ببینید. کارت دستگاه
وضعیت فعلی و اطلاعات اتصال را نشان میدهد. برای دیدن داشبورد، کارت دستگاه را
باز کنید.
اگر دستگاه در حال راهاندازی است، ابتدا [راهاندازی دستگاه](../setup) را
کامل کنید. وضعیت آنلاین فقط حضور تازهٔ دستگاه را نشان میدهد و بهتنهایی
تضمین نمیکند که همهٔ کانالها مقدار تازه گزارش کردهاند.
## مدیریت دستگاه [#مدیریت-دستگاه]
از منوی دستگاه، در صورت در دسترس بودن گزینهها، میتوانید نام دستگاه را تغییر
دهید، آن را از حساب حذف کنید یا بازنشانی کارخانهای را شروع کنید. قبل از
عملیات حذف یا بازنشانی، متن تأیید را بخوانید. بازنشانی کارخانهای ممکن است
تنظیمات شبکه و وضعیت اتصال دستگاه را تغییر دهد.
برای ساخت دستگاه و صدور QR فعالسازی به [دستگاهها در کنسول](../../console/devices)
مراجعه کنید.
# نمای کلی اپلیکیشن (/fa/docs/app/overview)
اپلیکیشن فلووا فضای کاربری شما برای دستگاههای متصل است. از طریق مرورگر به
`https://pwa.flova.ir/` بروید، وارد حساب شوید، دستگاه را به حساب خود اضافه کنید
و داشبورد منتشرشدهٔ آن را باز کنید.
اپلیکیشن فعلاً از طریق وب و نسخهٔ PWA در دسترس است. برای ساخت نوع دستگاه و
داشبورد، به [کنسول](../../console/overview) و [استودیو](../../studio/overview)
بروید. کاربر نهایی از اپلیکیشن برای افزودن دستگاه و استفاده از تجربهٔ منتشرشده
استفاده میکند.
## فضای کاربری و فضای کاری [#فضای-کاربری-و-فضای-کاری]
اپلیکیشن فضای کاربری شماست. دستگاههایی که با QR یا کد فعالسازی اضافه میکنید
در حساب شما دیده میشوند. فضای کاری در کنسول و استودیو برای تیمی است که قالب
دستگاه، دادهها و داشبورد را میسازد.
ذخیرهٔ پیشنویس در استودیو، داشبورد را برای کاربر قابل مشاهده نمیکند. داشبورد
باید منتشر شود تا اپلیکیشن بتواند آن را بارگذاری کند.
# شروع سریع (/fa/docs/app/quickstart)
برای استفادهٔ اول از اپلیکیشن فلووا، این مسیر را انجام دهید:
۱. به [اپلیکیشن فلووا](https://pwa.flova.ir/) بروید.
۲. با حساب فلووا وارد شوید.
۳. **افزودن دستگاه** را بزنید و QR فعالسازی را اسکن کنید. اگر دوربین در
دسترس نیست، کد فعالسازی را دستی وارد کنید.
۴. یک نام قابل تشخیص برای دستگاه بنویسید و فعالسازی را تأیید کنید.
۵. اگر دستگاه به راهاندازی شبکه نیاز دارد، به [راهاندازی دستگاه](../setup)
بروید و مراحل آن را کامل کنید.
۶. دستگاه را باز کنید و داشبورد منتشرشده را ببینید.
اپلیکیشن فقط داشبوردهای منتشرشده را نمایش میدهد. اگر دستگاه اضافه شده اما
داشبوردی نمیبینید، از صاحب محصول بخواهید نسخهٔ داشبورد را در استودیو منتشر
کند.
## پیشنیازها [#پیشنیازها]
- QR یا کد فعالسازی دستگاه را از سازنده یا مدیر محصول داشته باشید.
- برای راهاندازی Wi‑Fi، تلفن یا رایانه باید بتواند بین اینترنت و شبکهٔ موقت
دستگاه جابهجا شود.
- برای بارگذاری داشبورد و دریافت مقدارهای تازه، اتصال اینترنت لازم است.
برای جزئیات هر مرحله به [دستگاهها](../devices)، [راهاندازی](../setup) و
[داشبوردها](../dashboards) بروید.
# راهاندازی دستگاه (/fa/docs/app/setup)
بعد از افزودن دستگاه، اپلیکیشن وضعیت راهاندازی آن را نشان میدهد. روش انجام
کار به نوع اتصال دستگاه بستگی دارد.
## راهاندازی Wi‑Fi [#راهاندازی-wifi]
۱. در صفحهٔ دستگاه، **راهاندازی دستگاه** را باز کنید.
۲. تلفن یا رایانه را به شبکهای وصل کنید که نامش با `Flova-Setup-` شروع
میشود.
۳. به اپلیکیشن برگردید و نام و گذرواژهٔ Wi‑Fi معمولی را وارد کنید.
۴. **راهاندازی دستگاه** را بزنید و منتظر پذیرش اطلاعات بمانید.
۵. تلفن یا رایانه را دوباره به Wi‑Fi معمولی و اینترنت برگردانید.
اپلیکیشن صفحهٔ راهاندازی محلی دستگاه را باز میکند. پس از پذیرش اطلاعات،
دستگاه راهاندازی مجدد میشود و اپلیکیشن وضعیت اتصال آن را بررسی میکند.
## راهاندازی Ethernet [#راهاندازی-ethernet]
اگر دستگاه با Ethernet آماده شده باشد، اپلیکیشن اطلاعات شبکهٔ Wi‑Fi نمیخواهد.
کابل و اتصال اینترنت دستگاه را بررسی کنید و صبر کنید وضعیت آن بهصورت خودکار
بهروز شود.
## اگر وضعیت کامل نشد [#اگر-وضعیت-کامل-نشد]
- مطمئن شوید مرورگر هنوز به شبکهٔ `Flova-Setup-*` وصل است.
- اگر صفحهٔ محلی باز نمیشود، دسترسی مرورگر به شبکهٔ محلی را بررسی کنید.
- بعد از پذیرش اطلاعات، اتصال دستگاه را قطع نکنید تا راهاندازی مجدد تمام شود.
- پس از بازگشت به اینترنت، چند لحظه برای بررسی وضعیت runtime صبر کنید.
تا وقتی دستگاه به اینترنت وصل نشده باشد، داشبورد از دادهٔ ذخیرهشدهٔ آفلاین باز
نمیشود. اگر بعد از بازگشت اینترنت وضعیت تغییر نکرد، [رفع مشکل](../troubleshooting)
را ببینید.
# رفع مشکل (/fa/docs/app/troubleshooting)
## ورود کامل نمیشود [#ورود-کامل-نمیشود]
مرورگر را ببینید و مراحل ورود امن فلووا را کامل کنید. اگر نشست منقضی شده است،
از حساب خارج شوید و دوباره وارد شوید. اگر خطای ورود ادامه داشت، زمان خطا و متن
نمایشدادهشده را برای پشتیبانی نگه دارید.
## QR خوانده نمیشود [#qr-خوانده-نمیشود]
دسترسی دوربین مرورگر را فعال کنید، QR را روشن و کامل داخل کادر نگه دارید و
دوباره امتحان کنید. اگر دوربین در دسترس نیست، **ورود دستی** را انتخاب کنید و
کد فعالسازی را از کنسول یا مدیر محصول بگیرید.
## دستگاه به شبکه وصل نمیشود [#دستگاه-به-شبکه-وصل-نمیشود]
برای راهاندازی Wi‑Fi بررسی کنید که دستگاه و مرورگر در مرحلهٔ درست باشند:
- مرورگر باید به شبکهٔ `Flova-Setup-*` وصل باشد.
- نام و گذرواژهٔ Wi‑Fi معمولی را دقیق وارد کنید.
- بعد از پذیرش اطلاعات، دستگاه را تا پایان راهاندازی مجدد خاموش نکنید.
- سپس رایانه یا تلفن را به اینترنت برگردانید و برای بهروزرسانی وضعیت صبر کنید.
اگر دستگاه Ethernet دارد، کابل و دسترسی آن به اینترنت را بررسی کنید.
## داشبورد دیده نمیشود یا مقدار تغییر نمیکند [#داشبورد-دیده-نمیشود-یا-مقدار-تغییر-نمیکند]
آنلاین بودن دستگاه و اتصال اینترنت را بررسی کنید. اپلیکیشن فقط داشبورد منتشرشده
را بارگذاری میکند، پس صاحب محصول باید انتشار داشبورد و قالب درست دستگاه را در
استودیو بررسی کند. برای تغییر مقدار، کانال باید قابلیت نوشتن داشته باشد و خود
دستگاه باید بتواند فرمان را دریافت و اعمال کند.
## اعلان دریافت نمیکنم [#اعلان-دریافت-نمیکنم]
اجازهٔ اعلان برای `pwa.flova.ir` را در تنظیمات مرورگر بررسی کنید. اگر اعلان
فوری در دسترس نباشد، هشدارها را از صفحهٔ **هشدارها** در اپلیکیشن بخوانید.
برای خطاهای مربوط به قالب، دستگاه یا داشبورد، نام دستگاه، زمان رخداد و پیام
قابل مشاهده را به پشتیبانی بدهید. کد فعالسازی، گذرواژه و اطلاعات Wi‑Fi را
ارسال نکنید.
# اتوماسیونها و هشدارها (/fa/docs/console/automations)
اتوماسیون نموداری است که به قالب دستگاه وصل میشود. جریان آن با یک محرک شروع میشود، میتواند شرط داشته باشد و در پایان یک یا چند عمل را اجرا میکند. ویرایش اتوماسیون از صفحهٔ **اتوماسیونها** قالب انجام میشود.
## ساخت اتوماسیون [#ساخت-اتوماسیون]
۱. [کنسول](https://console.flova.ir/templates) را باز کنید، قالب را انتخاب و **اتوماسیونها** را باز کنید.
۲. یک محرک اضافه کنید و کانال یا زمان شروع را انتخاب کنید.
۳. اگر عمل فقط برای مقدار مشخصی باید اجرا شود، یک شرط اضافه کنید.
۴. عملی مثل نوشتن در کانال، ارسال وبهوک یا ارسال اعلان اضافه کنید.
۵. گرهها را در جهت اجرای جریان به هم وصل کنید.
۶. نمودار را ذخیره و نسخهٔ قالب را منتشر کنید.
| گره | کاربرد |
| --- | --- |
| بهروزرسانی داده | با تغییر کانال شروع میشود و تغییر دلخواه، فعال شدن یا غیرفعال شدن را میپذیرد. |
| زمانبندی | یکبار، روزانه یا هفتگی در زمان انتخابی شروع میشود. |
| بررسی کانال | مقدار کانال را با یک مقدار مقایسه میکند. |
| نوشتن در کانال | مقدار را مینویسد یا کانال را تغییر وضعیت میدهد. |
| ارسال وبهوک | به نشانی وب انتخابی درخواست HTTP میفرستد. |
| ارسال اعلان | پیامی با عنوان و متن در مرکز اعلانها میسازد. |
## استفاده از محرک تغییر کانال [#استفاده-از-محرک-تغییر-کانال]
در **بهروزرسانی داده** کانال را انتخاب و حالت محرک را مشخص کنید:
- **هر تغییر:** برای هر بهروزرسانی پذیرفتهشده اجرا میشود.
- **هنگام فعالشدن:** وقتی مقدار Boolean از خاموش به روشن میرود اجرا میشود.
- **هنگام غیرفعالشدن:** وقتی مقدار Boolean از روشن به خاموش میرود اجرا میشود.
برای رویدادهایی مثل باز شدن در یا تغییر گزارش دما از محرک کانال استفاده کنید. قانون مبتنی بر ساعت را با گره **زمانبندی** بسازید.
## بررسی مقدار [#بررسی-مقدار]
بعد از محرک، گره **بررسی کانال** را اضافه کنید. کانال، عملگر و مقدار مقایسه را انتخاب کنید. عملگرهای برابر، برابر نیست، بزرگتر، بزرگتر یا برابر، کوچکتر، کوچکتر یا برابر و تغییر کرد به در دسترس هستند.
شرط را با نوع کانال هماهنگ کنید. مقایسهٔ عددی برای متن یا شیء مناسب نیست و شرط Boolean باید مقدار روشن یا خاموش داشته باشد.
## نوشتن و ارسال هشدار [#نوشتن-و-ارسال-هشدار]
در **نوشتن در کانال** یک کانال قابل نوشتن را انتخاب کنید و مقدار را تنظیم یا وضعیت فعلی را تغییر دهید. کانال فقط خواندنی اتوماسیون را نامعتبر میکند.
در **ارسال اعلان** عنوان و متن را بنویسید. اعلان در مرکز اعلانهای کنسول دیده میشود. **ارسال وبهوک** به نشانی HTTP درخواست میفرستد، پس در دسترس بودن نشانی و نیازمندیهای احراز هویت آن را بررسی کنید.
## نسخهبندی و خطاهای اعتبارسنجی [#نسخهبندی-و-خطاهای-اعتبارسنجی]
تغییرات اتوماسیون با نسخهٔ قالب ذخیره میشود. ذخیرهٔ نمودار نسخهٔ قابل ویرایش را تغییر میدهد، اما تا زمان انتشار نسخه فعال نمیشود.
پیش از انتشار، کنسول بررسی میکند که:
- هر گره فیلدهای لازم را داشته باشد؛
- کانال انتخابشده هنوز در قالب وجود داشته باشد؛
- عمل نوشتن به کانال قابل نوشتن وصل باشد؛
- اتصالها از محرک به عمل مسیر قابل اجرا بسازند؛
- مقدارها با نوع کانال سازگار باشند.
گره نامعتبر در ویرایشگر مشخص میشود و پیام خطا راه اصلاح را نشان میدهد. اگر کانالی حذف یا تغییر داده شده است، اتوماسیون را با کلید جدید ویرایش کنید.
برای نوع دسترسی کانالها به [کانالهای داده](./datastreams) و برای انتشار به [قالبها و نسخهها](./templates) بروید. برای کوئریهای تلهمتری از [FlovaQL](https://console.flova.ir/flovaql) استفاده کنید.
# پلن و پرداخت (/fa/docs/console/billing)
صفحهٔ **پلن و پرداخت** پلن فعال، دورهٔ پرداخت، مصرف منابع و افزونههای موجود را نشان میدهد. پرداخت به workspace تعلق دارد و مقدارها برای منابع مشترک تیم محاسبه میشوند.
## خواندن مصرف [#خواندن-مصرف]
[تنظیمات > پلن و پرداخت](https://console.flova.ir/settings/billing) را باز کنید. کارت مصرف مقدار فعلی و سقف این موارد را نشان میدهد:
| شاخص | چه چیزی را میشمارد؟ |
| --- | --- |
| دستگاه فعال | دستگاههایی که از ظرفیت فعال workspace استفاده میکنند |
| تلهمتری | خوانشهای تلهمتری در دورهٔ فعلی |
| عضو تیم | اعضای workspace |
| قالب و داشبورد | منابعی که در محدودیت مشترک پلن حساب میشوند |
| فراخوانی MCP | فراخوانیهای ابزار MCP در دورهٔ ۳۰روزهٔ فعلی |
| اعتبار AI | اعتبار باقیماندهٔ شامل پلن و خریداریشدهٔ FlovaAI |
پایان دوره و وضعیت پلن هم در همین صفحه دیده میشود. مقدار را به شکل «مصرف فعلی از سقف» بخوانید؛ نوار پیشرفت فقط نمایش تصویری همین دو عدد است.
وقتی مصرف تلهمتری به ۸۰ درصد یا بیشتر برسد، هشدار نمایش داده میشود. رسیدن به سقف نمایشدادهشده فوراً مسیر داده را قطع نمیکند، اما باید پیش از دورهٔ بعد پلن را بررسی کنید.
## تغییر پلن [#تغییر-پلن]
فقط مالک workspace یا نقشی که مجوز مدیریت پرداخت دارد میتواند پلن را تغییر دهد یا افزونه بخرد. پلن پولی را از بخش قیمت انتخاب و پرداخت را کامل کنید. کاهش پلن تا پایان دورهٔ فعلی ممکن نیست.
پس از تأیید پرداخت، پلن یا افزونه فعال میشود. اگر پرداخت رد شود، مبلغی به workspace اضافه نمیشود و کنسول مسیر تلاش دوباره را نشان میدهد.
## خرید افزونه [#خرید-افزونه]
صفحه ممکن است این افزونهها را نشان دهد:
- ۱۰۰ اعتبار FlovaAI بدون تاریخ انقضا؛
- پنج دستگاه برای ۳۰ روز، در صورتی که workspace پلن پولی داشته باشد.
در هر زمان حداکثر ۱۰ بستهٔ افزونهٔ دستگاه میتواند فعال باشد. اگر کنسول بستهٔ دیگری را نپذیرفت، پیام پرداخت را بخوانید.
مصرف اضافه به صورت خودکار صورتحساب نمیشود. پیش از ساخت دستگاه یا افزایش ترافیک تلهمتری، شاخص مصرف و پلن را بررسی کنید.
## خطای محدودیت [#خطای-محدودیت]
- **ساخت دستگاه متوقف شده است:** دستگاههای فعال، سقف مؤثر و افزونهها را بررسی کنید.
- **دعوت عضو رد شده است:** سقف عضو تیم و دعوتنامههای فعلی را بررسی کنید.
- **قالب یا داشبورد ساخته نمیشود:** شاخص قالب و داشبورد را بررسی کنید.
- **فراخوانی ابزار MCP رد میشود:** شاخص فراخوانی MCP و سهمیهٔ ۳۰روزهٔ پلن را بررسی کنید.
- **FlovaAI پاسخ نمیدهد:** اعتبار AI باقیمانده را ببینید.
- **دکمهٔ خرید غیرفعال است:** مالک workspace یا مجوز مدیریت پرداخت بودن خود را بررسی کنید.
پیامهای سهمیه و پرداخت در [اعلانها](https://console.flova.ir/notifications) میآیند. برای خطای پرداخت از [پشتیبانی](https://console.flova.ir/support) با ذکر workspace و وضعیت پرداخت درخواست ثبت کنید.
# کانالهای داده (/fa/docs/console/datastreams)
کانال داده مقداری نامگذاریشده است که دستگاه گزارش میکند، دریافت میکند یا در تلهمتری ذخیره میشود. کنسول از آن در جزئیات دستگاه، داشبورد، اتوماسیون، تلهمتری و FlovaQL استفاده میکند.
## افزودن کانال داده [#افزودن-کانال-داده]
۱. [کنسول](https://console.flova.ir/templates) را باز کنید، یک قالب را انتخاب کنید و به **کانالهای داده** بروید.
۲. **افزودن کانال داده** را بزنید.
۳. نام نمایشی و کلید فنی را وارد کنید.
۴. نوع مقدار و نوع تبادل را انتخاب کنید.
۵. اگر مقدار به ورودی یا خروجی فیزیکی مربوط است، نوع اتصال سختافزار را انتخاب کنید.
۶. مقدار اولیه، مقدار امن، نمونهبرداری و محدودیتهای لازم را تنظیم کنید.
۷. کانال را ذخیره کنید و نسخهٔ قالب را از صفحهٔ **نسخهها** منتشر کنید.
کلید فنی شناسهٔ ثابتی است که فریمور، Studio، اتوماسیون، API و FlovaQL از آن استفاده میکنند. کلید باید با یک حرف انگلیسی شروع شود و فقط حروف انگلیسی، عدد و `_` داشته باشد و حداکثر ۶۴ نویسه باشد. کلیدی مثل `temperature_c` یا `LED` بنویسید و نام فارسی کانال را جایگزین آن نکنید.
## نوع مقدار و دسترسی [#نوع-مقدار-و-دسترسی]
| فیلد | گزینهها | کاربرد |
| --- | --- | --- |
| نوع مقدار | روشن / خاموش، عدد، متن، ساختاریافته | شکل مقدار ارسالی یا ذخیرهشده |
| نوع تبادل | فقط خواندن، فقط نوشتن، خواندن و نوشتن | مشخص میکند چه طرفی مقدار را گزارش یا تغییر دهد |
| واحد | برچسب کوتاه مثل `°C` یا `%` | نمایش و زمینهٔ کوئری |
| مقدار اولیه یا پیشفرض | مقدار هنگام شروع کانال | شروع قابل پیشبینی |
| مقدار امن | مقدار رفتار ایمن دستگاه | خروجی امن در شرایط لازم |
کنسول سازگاری اتصال سختافزار، نوع مقدار و دسترسی را بررسی میکند. ورودی و خروجی دیجیتال مقدار روشن یا خاموش دارند. ورودی آنالوگ و خروجی PWM عددی هستند. وضعیت مجازی RGB یک مقدار ساختاریافتهٔ دوطرفه است.
برای سنسوری که فقط گزارش میدهد **فقط خواندن** را انتخاب کنید. برای فرمانی که دستگاه میپذیرد **فقط نوشتن** مناسب است. وقتی دستگاه وضعیت فعلی را گزارش میدهد و فلووا هم میتواند مقدار جدید بفرستد، **خواندن و نوشتن** را انتخاب کنید.
برای کانالهای قابل نوشتن میتوانید زمانبندی در وب اپلیکیشن را فعال کنید تا کاربر نهایی مقدار یا فرمان را برای زمان دیگری تنظیم کند.
## اتصال کانال به سختافزار [#اتصال-کانال-به-سختافزار]
در **نوع اتصال** مشخص کنید فریمور با کانال چه کند:
- **ورودی دیجیتال:** خواندن سیگنال روشن و خاموش از پایه.
- **خروجی دیجیتال:** نوشتن سیگنال روشن و خاموش روی پایه.
- **ورودی آنالوگ:** خواندن مقدار عددی ADC.
- **خروجی PWM:** نوشتن مقدار عددی شدت یا duty.
- **وضعیت نرمافزاری** و **فرمان نرمافزاری:** بدون نگاشت مستقیم GPIO.
- **رنگ RGB:** ذخیرهٔ رنگ ساختاریافته که مؤلفههای `r`، `g` و `b` آن بین صفر تا ۲۵۵ هستند.
در **پایهٔ سختافزار** مرجع پایهٔ برد را وارد کنید. بسته به فریمور میتوانید مقداری مثل `D32`، `GPIO32`، `A0` یا `ADC1_CH4` بنویسید. یک پایهٔ فیزیکی را در یک قالب به دو کانال ندهید. اگر مدار pull-up، pull-down یا فعالسازی با LOW دارد، همان گزینه را در فرم انتخاب کنید.
**تنظیمات سختافزار** برای گزینههای عمومی برد است، مثل چراغ وضعیت و منبع بازنشانی کارخانهای. این گزینهها مستقل از کانال داده هستند.
## مقدار فعلی و تاریخچه [#مقدار-فعلی-و-تاریخچه]
کنسول دو نوع داده را نشان میدهد:
| نما | به چه پرسشی پاسخ میدهد؟ |
| --- | --- |
| مقدار فعلی | اکنون برای این دستگاه و کانال چه مقداری در دسترس است؟ |
| تاریخچه | در بازهٔ انتخابی چه مقدارها و رخدادهایی ثبت شدهاند؟ |
مقدار فعلی ممکن است بدون ایجاد ردیف تاریخچه تغییر کند. آنلاین بودن دستگاه هم فقط حضور دستگاه را نشان میدهد و ثابت نمیکند که کانال مشخصی مقدار فرستاده است. برای تأیید ذخیره شدن تلهمتری، تاریخچه یا [FlovaQL](https://console.flova.ir/flovaql) را بررسی کنید.
## خطاهای اعتبارسنجی [#خطاهای-اعتبارسنجی]
- **کلید نامعتبر:** با حرف انگلیسی شروع کنید و فقط از حروف انگلیسی، عدد و `_` استفاده کنید.
- **کلید تکراری:** کلید هر کانال در همان قالب باید یکتا باشد.
- **نوع مقدار نادرست:** کانال دیجیتال را Boolean و کانال آنالوگ یا PWM را عددی انتخاب کنید.
- **پایهٔ تکراری:** پایهٔ استفادهشده را از کانال قبلی بردارید یا نگاشت دیگری انتخاب کنید.
- **بازهٔ عددی نامعتبر:** بیشینه باید از کمینه بزرگتر باشد و مقدار اولیهٔ PWM داخل همین بازه قرار بگیرد.
- **تغییر نکردن دستگاه:** کانال را ذخیره، نسخهٔ قالب را منتشر و یکسان بودن کلید فریمور و کنسول را بررسی کنید.
مثالهای SDK و فریمور را در [مخزن فریمور فلووا](https://github.com/flova-platform/flova-firmware/) ببینید. [Studio](https://studio.flova.ir/) تعریف منتشرشدهٔ کانال را هنگام اتصال ویجت میخواند.
# API و برنامههای توسعهدهندگان (/fa/docs/console/developers)
کنسول برای دو نوع یکپارچهسازی دو نوع اعتبار دارد:
- **کلید API** برای دسترسی مستقیم و محدود یک سرویس به عملیات Console و دادههاست.
- **برنامهٔ توسعهدهندگان** یک کلاینت OAuth ثبت میکند تا برنامهٔ دیگر بتواند کاربر را وارد کند و scopeهای لازم را بگیرد.
## ساخت کلید API [#ساخت-کلید-api]
۱. [تنظیمات > کلیدهای API](https://console.flova.ir/settings/api-keys) را باز کنید.
۲. **کلید جدید** را بزنید و نام وارد کنید.
۳. در صورت نیاز تاریخ انقضا بگذارید.
۴. فقط scopeهای موردنیاز یکپارچهسازی را انتخاب کنید.
۵. کلید را بسازید و همان لحظه کپی کنید.
کنسول secret را فقط یکبار نشان میدهد. آن را در secret manager یا متغیر محیطی نگه دارید و داخل bundle مرورگر، مخزن عمومی، داشبورد یا تصویر پشتیبانی قرار ندهید.
| scope | کاربرد |
| --- | --- |
| `devices:read` و `devices:write` | خواندن یا مدیریت دستگاهها |
| `templates:read` و `templates:write` | خواندن یا مدیریت قالب و نگاشتها |
| `datastreams:read`، `datastreams:write` و `datastreams:manage` | خواندن مقدار، نوشتن مقدار یا مدیریت تعریف کانال |
| `provisioning:read` و `provisioning:write` | خواندن یا صدور اطلاعات فعالسازی |
| `mqtt:manage` | مدیریت اطلاعات اتصال MQTT دستگاهها |
| `flovaql:read` و `telemetry:read` | اجرای FlovaQL و خواندن تلهمتری |
وقتی یکپارچهسازی تمام شد، secret احتمالاً افشا شده است یا مالک آن عوض شده، کلید را از صفحهٔ کلیدهای API لغو کنید. برای چرخش بدون قطعی، ابتدا کلید جایگزین بسازید.
## ثبت برنامهٔ OAuth [#ثبت-برنامهٔ-oauth]
۱. [تنظیمات > برنامههای توسعهدهندگان](https://console.flova.ir/settings/developer-apps) را باز کنید.
۲. نام برنامه را وارد کنید.
۳. محل اجرای برنامه را انتخاب کنید: سرور یا backend، مرورگر، یا موبایل و دسکتاپ.
۴. scopeهای مجاز را انتخاب کنید.
۵. برای برنامهٔ مرورگری، نشانیهای بازگشت HTTPS را وارد کنید. `localhost` برای توسعه مجاز است.
۶. برای برنامهٔ native، scheme اختصاصی مثل `my-app://oauth/callback` وارد کنید.
۷. برنامه را بسازید و Client ID و هر Client Secret نمایشدادهشده را ذخیره کنید.
برنامهٔ سرور callback نمیخواهد و Client Secret دارد. برنامهٔ مرورگری و native حداقل به یک نشانی بازگشت معتبر نیاز دارند. حذف برنامه tokenهای فعال آن را باطل میکند. با چرخش Client Secret، secret قبلی دیگر معتبر نیست.
برای یکپارچهسازی کاربرمحور از OAuth استفاده کنید. برای سرویس کنترلشدهای که از قبل workspace مشخص دارد و دسترسی مستقیم محدود میخواهد، کلید API مناسب است.
## مستندات توسعهدهندگان [#مستندات-توسعهدهندگان]
- [مستندات API](https://api-docs.flova.ir/) قرارداد HTTP و مثالها را توضیح میدهد.
- [FlovaQL در کنسول](https://console.flova.ir/flovaql) محیط اجرای کوئری تلهمتری است.
- [FlovaAI در کنسول](https://console.flova.ir/) برای بررسی عملیات پشتیبانیشدهٔ داده و دستگاه در workspace فعال استفاده میشود.
- [مخزن فریمور فلووا](https://github.com/flova-platform/flova-firmware/) SDK و بخش دستگاهی اتصال را توضیح میدهد.
اگر درخواست رد شد، نوع اعتبار، scope، workspace فعال و انقضا یا لغو شدن کلید و secret را بررسی کنید.
# دستگاهها (/fa/docs/console/devices)
کنسول دو نمای دستگاه دارد. صفحهٔ **دستگاهها** همهٔ دستگاههای workspace را نشان میدهد. صفحهٔ **دستگاهها** درون یک قالب، همان فهرست را برای دستگاههای متصل به آن قالب فیلتر میکند. دستگاه یک منبع workspace است و قالب تعریف کانال و پیکربندی فریمور آن را تأمین میکند.
## ساخت دستگاه [#ساخت-دستگاه]
۱. [کنسول](https://console.flova.ir/templates) را باز کنید، قالب را انتخاب و صفحهٔ **دستگاهها**ی آن را باز کنید. در صفحهٔ workspace هم میتوانید پس از انتخاب قالب فعال از نوار کناری، دستگاه بسازید.
۲. **افزودن دستگاه** و سپس **افزودن تکی** را بزنید.
۳. نام دستگاه را وارد کنید. کنسول روش راهاندازی تنظیمشده روی قالب را به کار میبرد.
۴. دستگاه را بسازید و QR یا کد دستی فعالسازی را نگه دارید.
۵. در [وب اپلیکیشن فلووا](https://pwa.flova.ir/) دستگاه را claim کنید و تنظیمات شبکه را بفرستید.
قالب بدون نسخهٔ منتشرشده نمیتواند دستگاه جدید بسازد. اگر ظرفیت دستگاه فعال پلن پر شده باشد، کنسول پیش از تکمیل ساخت پیام پلن را نشان میدهد.
## QR فعالسازی [#qr-فعالسازی]
QR برای claim کردن دستگاه در وب اپلیکیشن است. این مرحله با تنظیم Wi-Fi و اتصال بعدی دستگاه به فلووا فرق دارد.
از ردیف دستگاه، **QR فعالسازی** را باز کنید تا کد فعلی را ببینید، کد دستی را کپی کنید یا QR را به صورت SVG دریافت کنید. وضعیت کد میتواند آمادهٔ فعالسازی، استفادهشده، لغوشده، منقضیشده یا ثبتنشده باشد. با صدور QR جدید، QR فعلی همان لحظه لغو میشود. QR جدید را به کسی بدهید که قرار است دستگاه را claim کند.
در وب اپلیکیشن از اسکنر QR یا کد دستی نمایشدادهشده در کنسول استفاده کنید.
## ساخت دستهٔ دستگاه [#ساخت-دستهٔ-دستگاه]
برای ساخت دسته، صفحهٔ **دستگاهها**ی یک قالب را باز کنید و از **افزودن دستگاه** گزینهٔ **ساخت دستهای** را بزنید. در صفحهٔ دستگاههای workspace ابتدا قالب فعال را از نوار کناری انتخاب کنید. پیشوند نام و تعداد ۱ تا ۱۰۰ دستگاه را وارد کنید. کنسول نامهایی مثل `lamp-001` میسازد و فایل ZIP کدهای QR فعالسازی را دریافت میکند.
از **فهرست دستهها** در صفحهٔ دستگاههای workspace برای دیدن دستههای قبلی، تعداد QRهای استفادهنشده و claimشده و دریافت دوبارهٔ فایل ZIP استفاده کنید. فایل QR را کنار برچسب فیزیکی همان دستگاه نگه دارید تا کاربر درست آن را claim کند.
## خواندن وضعیت دستگاه [#خواندن-وضعیت-دستگاه]
فهرست دستگاهها قالب، وضعیت فعلی و آخرین اطلاعات اتصال را نشان میدهد.
| وضعیت | معنی |
| --- | --- |
| آنلاین | اخیراً یک سیگنال حضور از دستگاه دریافت شده است. |
| آفلاین | دستگاه اکنون حضور خود را گزارش نمیکند. |
| در حال اتصال یا راهاندازی | اتصال اولیه یا اتصال فریمور هنوز کامل نشده است. |
| خطا | دستگاه مشکلی گزارش کرده است. |
| غیرفعال | عملیات دستگاه از کنسول غیرفعال شده است. |
| بایگانیشده | دستگاه از فهرست فعال خارج شده است. |
صفحهٔ جزئیات دستگاه مقدار گزارششده و مقدار درخواستی هر کانال، وضعیت همگامسازی، شناسهها، اطلاعات فریمور و timeline را نشان میدهد. **آخرین اتصال** فقط جزئیات حضور است و ثابت نمیکند که همهٔ کانالها تلهمتری فرستادهاند.
## دسترسی و عملیات دستگاه [#دسترسی-و-عملیات-دستگاه]
در جزئیات دستگاه، بسته به نقش شما، عملیات بازنشانی دسترسی، فعال یا غیرفعال کردن، آرشیو و بازیابی، بازنشانی کارخانهای و چرخش اعتبار MQTT قرار دارد. پیش از عملیات مخرب متن تأیید را بخوانید.
برای تغییر مالکیت یا متوقف کردن مسیر فعالسازی قدیمی از بازنشانی دسترسی استفاده کنید. بازنشانی کارخانهای فقط وقتی نتیجهٔ موردنظر را میدهد که فریمور آن فرمان را پشتیبانی کند. بعد از هر عملیات، timeline را بررسی کنید و منتظر وضعیت جدید دستگاه بمانید.
برای مقدار فعلی و رخدادها به [پایش زنده](./monitor) و برای مسیر کامل ESP32 به [شروع سریع](./quickstart) بروید.
# پایش زنده (/fa/docs/console/monitor)
صفحهٔ **پایش زنده** به یک قالب تعلق دارد و دستگاههای همان قالب را در یک نما نشان میدهد. تعداد دستگاههای آنلاین و آفلاین، روند کانالهای عددی و رخدادها را میبینید. برای مقایسهٔ آخرین مقدار گزارششده با مقدار درخواستی، جزئیات همان دستگاه را باز کنید.
## باز کردن پایش [#باز-کردن-پایش]
۱. [کنسول](https://console.flova.ir/templates) را باز کنید.
۲. یک قالب را انتخاب و **پایش زنده** را باز کنید.
۳. دستگاه، کانال و بازهٔ زمانی را برای محدود کردن نمودارها و رخدادها انتخاب کنید.
۴. برای دریافت بهروزرسانیها بازهٔ **زنده** را انتخاب کنید. اگر اتصال زنده برقرار نیست، دستی صفحه را تازه کنید.
بازهٔ زنده ۱۵ دقیقهٔ اخیر را پوشش میدهد. برای بازهٔ طولانیتر از انتخابگر زمان استفاده کنید. رخدادهای زنده از اتصال بلادرنگ میرسند و اگر این اتصال برقرار نباشد، کنسول وضعیت آن را نشان میدهد.
## خواندن وضعیت فعلی [#خواندن-وضعیت-فعلی]
خلاصهٔ پایش تعداد کل، آنلاین و آفلاین دستگاهها، تعداد رخدادها و خطاهای بازه را نشان میدهد. این صفحه جدول آخرین مقدار همهٔ کانالها را ندارد. از **دستگاهها**، جزئیات دستگاه را باز کنید و بخش **دیتاستریمها** را ببینید تا مقدار گزارششده، مقدار درخواستی، وضعیت همگامسازی و زمان آخرین تغییر را مقایسه کنید. ممکن است دستگاه آنلاین باشد ولی کانالی هنوز مقداری گزارش نکرده باشد.
برای عیبیابی این ترتیب را دنبال کنید:
۱. وضعیت دستگاه و آخرین اتصال.
۲. مقدار گزارششده و درخواستی در بخش **دیتاستریمها**ی جزئیات دستگاه.
۳. روند کانال در پایش زنده یا خوانشهای ذخیرهشده در FlovaQL.
۴. رخدادهای راهاندازی، فرمان، خطا و تغییر حضور.
## بررسی تاریخچه [#بررسی-تاریخچه]
یک بازهٔ زمانی انتخاب کنید تا تلهمتری ذخیرهشده را ببینید. کانال عددی برای مقایسهٔ روند و کانال Boolean یا متنی برای دیدن مقدارهای ثبتشده مناسب است. برای فیلتر، گروهبندی یا نتیجهٔ قابل دریافت از [FlovaQL](https://console.flova.ir/flovaql) استفاده کنید.
نمودار عددی و فهرست رخدادها از بازهٔ انتخابی استفاده میکنند. تاریخچه با آخرین مقدار صفحهٔ دستگاه فرق دارد: تاریخچه خوانشهای ذخیرهشده در مسیر تلهمتری را دارد و جزئیات دستگاه مقدار گزارششده و درخواستی runtime را نشان میدهد. اگر دستگاه آنلاین است ولی تاریخچه خالی است، کلید فنی، گزارش فریمور، بازه و تنظیم تلهمتری را بررسی کنید.
## رخدادها [#رخدادها]
فهرست رخدادها تغییر حضور، راهاندازی، عملیات مدیریتی، تغییر کانال، نوشتن از کنسول، نوشتن از وب اپلیکیشن، نوشتن از اتوماسیون، تأیید دستگاه، اعمال مقدار و خطای دستگاه را نشان میدهد. رخدادها را بر اساس دسته یا شدت فیلتر کنید و جزئیات ساختاریافتهٔ هر مورد را باز کنید.
timeline دستگاه در صفحهٔ جزئیات دستگاه هم در دسترس است. رخدادهای تکراری تلهمتری که نزدیک به هم رخ دادهاند گروهبندی میشوند تا فهرست قابل خواندن بماند. برای رخدادهای قدیمیتر، بارگذاری موارد قدیمی را بزنید.
## وقتی مقدار دیده نمیشود [#وقتی-مقدار-دیده-نمیشود]
- **دستگاه آفلاین است:** شبکه، لاگ فریمور و آخرین رخداد حضور را بررسی کنید.
- **دستگاه آنلاین است ولی مقدار خالی است:** کلید فنی فریمور را با نسخهٔ منتشرشدهٔ قالب مقایسه کنید.
- **مقدار در صفحهٔ دستگاه هست ولی در نمودار نیست:** نمودار سریهای عددی را نشان میدهد. دستگاه، کانال و بازه را بررسی کنید و برای خوانشهای ذخیرهشده از FlovaQL کمک بگیرید.
- **نوشتن ثبت میشود ولی دستگاه تغییر نمیکند:** نوع دسترسی، نگاشت پایه، تأیید دستگاه و timeline را بررسی کنید.
برای تعریف کانالها به [کانالهای داده](./datastreams) و برای QR و عملیات دستگاه به [دستگاهها](./devices) بروید.
# بهروزرسانی از راه دور (OTA) (/fa/docs/console/ota)
OTA فایل فریمور را منتشر میکند و آن را از طریق شبکه به دستگاههای سازگار میفرستد. **نسخه** همان فایل فریمور ثبتشده است و **rollout** عملیاتی است که دستگاهها را انتخاب و نسخه را برای آنها ارسال میکند.
## انتشار نسخهٔ فریمور [#انتشار-نسخهٔ-فریمور]
۱. [کنسول](https://console.flova.ir/ota) یا صفحهٔ **OTA** یک قالب را باز کنید.
۲. **ایجاد** و سپس **انتشار نسخهٔ OTA** را بزنید.
۳. یک فایل `.bin` انتخاب کنید. کنسول حجم فایل را با سقف عمومی و سقف دستگاه هدف مقایسه میکند.
۴. برای بستهٔ فریمور فلووا اجازه دهید نسخه و هدف از فایل خوانده شود. برای فایل سفارشی، گزینهٔ فایل بدون اطلاعات Flova را فعال و نسخه و هدف را وارد کنید.
۵. در صورت نیاز یادداشت انتشار بنویسید و فایل را منتشر کنید.
بارگذاری سه مرحله دارد: آمادهسازی، ارسال فایل و ثبت نسخه. اگر یک مرحله خطا داد، شبکه و فایل را بررسی و دوباره تلاش کنید. فایل ارسالشده تا وقتی ثبت نسخه موفق نشده باشد rollout محسوب نمیشود.
## ساخت rollout [#ساخت-rollout]
۱. **ایجاد** و سپس **ایجاد rollout** را بزنید.
۲. نسخهٔ OTA را انتخاب کنید.
۳. صبر کنید بررسی سازگاری تمام شود.
۴. قالب سازگار را انتخاب کنید. در صفحهٔ OTA یک قالب، همان قالب از قبل انتخاب میشود.
۵. دستگاههای سازگار را ببینید، با نام، شناسه یا نسخهٔ فعلی جستوجو کنید و مواردی را که نباید فعلاً بهروزرسانی شوند از انتخاب خارج کنید.
۶. شروع فوری یا زمانبندیشده را انتخاب کنید.
۷. rollout را بسازید.
کنسول هدف OTA، نسخهٔ boot layout، فریمور فعلی، قالب و وضعیت دستگاه را بررسی میکند. اگر دستگاه سازگاری باقی نمانده باشد، rollout ساخته نمیشود.
## تنظیمات ایمنی rollout [#تنظیمات-ایمنی-rollout]
تنظیمات پیشرفته سرعت انتشار را کنترل میکنند:
| تنظیم | مقدار پیشفرض کنسول | کاربرد |
| --- | ---: | --- |
| اندازهٔ batch | ۱۰ | تعداد دستگاههای هر مرحله |
| فاصله | ۳۰۰ ثانیه | مکث بین batchها |
| توقف با خطا | ۲۰٪ | توقف وقتی سهم خطا به این مقدار برسد |
| توقف با آفلاین | ۵۰٪ | توقف وقتی سهم دستگاههای در دسترس نبودن به این مقدار برسد |
زمان شروع بر اساس منطقهٔ زمانی تهران تنظیم میشود. دستگاههای legacy فقط وقتی وارد rollout میشوند که ریسک نداشتن rollback خودکار را صریحاً بپذیرید.
## پیگیری و کنترل rollout [#پیگیری-و-کنترل-rollout]
ردیف rollout را باز کنید تا دستگاهها، فریمور فعلی، نتیجهٔ بهروزرسانی و جزئیات خطا را ببینید. وضعیت rollout میتواند زمانبندیشده، در حال اجرا، متوقفشده، کاملشده، ناموفق یا لغوشده باشد.
- **توقف:** ارسال به دستگاههای باقیمانده را متوقف میکند.
- **ادامه:** rollout متوقفشده را ادامه میدهد.
- **لغو:** کار باقیمانده را متوقف میکند. دستگاههای قبلاً بهروزشده برنمیگردند.
- **تلاش مجدد خطاها:** برای دستگاههای ناموفق دوباره تلاش میکند.
نتیجهٔ rollout فقط عملیات بهروزرسانی را توصیف میکند. برای بررسی اتصال دوباره و گزارش بعد از نصب، نتیجه را با [پایش](./monitor) و timeline دستگاه مقایسه کنید.
## خطاهای رایج [#خطاهای-رایج]
- **قالب سازگار پیدا نشد:** هدف یا boot layout نسخه با دستگاهها همخوان نیست.
- **فایل رد شد:** فایل `.bin` را داخل سقف عمومی و سقف دستگاه هدف نگه دارید.
- **دستگاه سازگار وجود ندارد:** دستگاه ممکن است آفلاین، قبلاً روی همین نسخه، غیرفعال یا خارج از قالب انتخابی باشد.
- **rollout خودکار متوقف شد:** آستانهٔ خطا و آفلاین را بررسی کنید و بعد ادامه دهید.
- **دستگاه نصب کرده ولی آنلاین نیست:** timeline، نسخهٔ فعلی فریمور و لاگ شبکه یا boot را بررسی کنید.
جزئیات بسته و بخش دستگاه OTA در [مخزن فریمور فلووا](https://github.com/flova-platform/flova-firmware/) آمده است.
# کنسول (/fa/docs/console/overview)
کنسول محل مدیریت و پایش دستگاهها در فلوواست. از اینجا میتوانید دستگاههای
متصل به محصولاتتان را دنبال کنید، وضعیت فعلی آنها را ببینید و کارهای روزمرهٔ
مربوط به دستگاهها را انجام دهید. اگر کارتان با دستگاهها شروع میشود، از کنسول
آغاز کنید و از فهرست زیر به بخش موردنیاز بروید.
## انتخاب محصول [#انتخاب-محصول]
# شروع سریع (/fa/docs/console/quickstart)
در این راهنما یک برد ESP32 را به فلووا وصل میکنید و LED داخلی آن را از داشبورد
روشن و خاموش میکنید.
پیش از شروع، این موارد را آماده کنید:
- یک برد ESP32 که LED داخلی آن روی `GPIO2` قرار دارد
- کابل USB دارای انتقال داده
- تلفن یا رایانهٔ متصل به Wi-Fi
- PlatformIO یا Arduino IDE برای نصب و فلش میانافزار
## ۱. حساب و قالب دستگاه را بسازید [#۱-حساب-و-قالب-دستگاه-را-بسازید]
به [کنسول فلووا](https://console.flova.ir/) بروید و یک حساب بسازید. در فلووا،
نوع دستگاه (Device Type) همان قالب دستگاه (template) است که بخشهای مختلف
پلتفرم را به هم وصل میکند. دستگاهها، داشبوردها، کوئریها، اتوماسیونها و
همهٔ بخشهای دیگر پلتفرم به همین قالب متصل هستند.
پس از ورود، یک نوع دستگاه با نام `ESP32 LED` بسازید و روش راهاندازی را روی Wi-Fi بگذارید.
این روش همان SoftAP (اتصال موقت) است که در ادامه برای فرستادن اطلاعات Wi-Fi
استفاده میکنیم.
در صفحهٔ کانالهای داده، یک کانال با مشخصات زیر اضافه کنید:
| فیلد | مقدار |
| --- | --- |
| نام کانال | LED داخلی |
| کلید فنی | `LED` |
| نوع مقدار | روشن / خاموش |
| نوع تبادل | خواندن و نوشتن |
| نوع اتصال | خروجی دیجیتال |
| پایهٔ سختافزار | `GPIO2` |
| سطح فعال | HIGH |
| وضعیت اولیه و امن | خاموش |
کلید فنی را دقیقاً `LED` وارد کنید. داشبورد بعداً با همین کلید به LED دستگاه
وصل میشود. سپس روی **انتشار نسخه** بزنید و بعد ادامه دهید. فلووا تا وقتی نوع
دستگاه منتشر نشده باشد، اجازهٔ ساخت دستگاهی از آن را نمیدهد.
## ۲. میانافزار عمومی را روی ESP32 نصب کنید [#۲-میانافزار-عمومی-را-روی-esp32-نصب-کنید]
ابتدا یک پوشهٔ پروژه بسازید، بستهٔ منتشرشدهٔ `FlovaSDK` را نصب کنید، کد
میانافزار عمومی را در پروژه بگذارید و سپس برد را از طریق USB فلش کنید. مسیر
مناسب خود را انتخاب کنید.
برای اطلاعات بیشتر و دیدن مثالها به [مخزن فریمور فلووا](https://github.com/flova-platform/flova-firmware/)
مراجعه کنید.
برای پروژه یک پوشه بسازید و یک پروژهٔ ESP32 را با PlatformIO آماده کنید:
```bash
mkdir flova-esp32
cd flova-esp32
pio project init --board esp32dev
```
در فایل `platformio.ini`، وابستگی `FlovaSDK` را اضافه کنید:
```ini
[env:esp32dev]
platform = espressif32@7.0.1
board = esp32dev
framework = arduino
lib_deps = flova-platform/FlovaSDK@^0.3.12
```
فایل `src/main.cpp` را با این کد جایگزین کنید:
```cpp
#include
#include
FlovaUniversalEsp32 device;
void setup() {
Serial.begin(115200);
device.begin();
}
void loop() {
device.run();
}
```
برد را با یک کابل USB داده وصل کنید. PlatformIO در بیشتر موارد درگاه سریال را
خودکار پیدا میکند. اگر درگاه پیدا نشد، مقدار `upload_port` را در
`platformio.ini` با درگاه برد تنظیم کنید. سپس میانافزار را فلش کنید:
```bash
pio run -t upload
```
یک اسکچ جدید Arduino بسازید و آن را در یک پوشهٔ جدید، مثلاً `flova-esp32`،
ذخیره کنید. پیش از نصب SDK، از مسیر **Tools → Board → Boards Manager** عبارت
`esp32` از Espressif Systems را جستوجو و بستهٔ پشتیبانی بردهای ESP32 را نصب
کنید. سپس از مسیر **Tools → Manage Libraries** عبارت `FlovaSDK` را جستوجو و
آن را نصب کنید.
از مسیر **Tools → Board** برد ESP32 متناسب با سختافزار خود را انتخاب کنید و
در مسیر **Tools → Port** درگاه سریال USB را انتخاب کنید. کد اسکچ را با این
کد جایگزین کنید:
```cpp
#include
#include
FlovaUniversalEsp32 device;
void setup() {
Serial.begin(115200);
device.begin();
}
void loop() {
device.run();
}
```
برد را با یک کابل USB داده وصل کنید و روی **Upload** بزنید. Arduino IDE اسکچ
را کامپایل میکند و تصویر کامل میانافزار، شامل bootloader و جدول پارتیشن،
را روی برد فلش میکند.
این میانافزار در اولین اجرا یک شبکهٔ موقت با نامی شبیه `Flova-Setup-*` میسازد.
نام و گذرواژهٔ Wi-Fi را در مرحلهٔ راهاندازی وارد میکنید، پس لازم نیست آنها را
داخل کد بنویسید.
## ۳. دستگاه را بسازید [#۳-دستگاه-را-بسازید]
به [صفحهٔ دستگاهها در کنسول](https://console.flova.ir/devices) برگردید، همان نوع
دستگاه را باز کنید و **افزودن دستگاه** را انتخاب کنید.
یک نام مثل `چراغ آزمایشی` وارد کنید و دستگاه را بسازید. کنسول برای آن یک QR و
یک کد دستی فعالسازی نشان میدهد.
## ۴. دستگاه را در وب اپلیکیشن به حساب خود اضافه کنید [#۴-دستگاه-را-در-وب-اپلیکیشن-به-حساب-خود-اضافه-کنید]
به [وب اپلیکیشن فلووا](https://pwa.flova.ir/) بروید و وارد حساب کاربری شوید. این
وب اپلیکیشن *فضای کاربری (user space)* فلوواست و با *فضای کاری (workspace)*
شما در کنسول و استودیو فرق دارد. شما در فضای کاری نوع دستگاه و داشبورد را
میسازید؛ مشتریان و کاربران نهایی از وب اپلیکیشن برای اضافه کردن دستگاههایشان
و دیدن داشبوردهایی استفاده میکنند که برای محصولات و تجربههای شما ساختهاید.
از بخش **افزودن دستگاه** دوربین را باز کنید، QR ساختهشده در کنسول را اسکن کنید،
نامی برای دستگاه انتخاب کنید و ادامه دهید.
اگر دوربین در دسترس نیست، گزینهٔ ورود دستی فعالسازی را انتخاب کنید و کدی را که
کنسول نشان میدهد وارد کنید.
دستگاه به حساب کاربری واردشده اضافه میشود. برای تنظیم Wi-Fi، وقتی وب اپلیکیشن
وارد مرحلهٔ راهاندازی شد، تلفن یا رایانه را به شبکهای که نامش با
`Flova-Setup-` شروع میشود وصل کنید. سپس به وب اپلیکیشن برگردید، نام و گذرواژهٔ
Wi-Fi معمولی خود را در فرم وارد کنید و ارسال را بزنید.
وب اپلیکیشن صفحهٔ راهاندازی محلی دستگاه را باز میکند و اطلاعات را به ESP32
میفرستد. پس از دیدن پیام پذیرش، تلفن یا رایانه را دوباره به Wi-Fi معمولی و
اینترنت برگردانید.
ESP32 تنظیمات را ذخیره میکند، راهاندازی مجدد میشود و به فلووا وصل میشود.
در کنسول، وضعیت دستگاه باید از راهاندازی و همگامسازی به آنلاین برسد.
اگر وب اپلیکیشن دستگاه را پیدا نکرد، بررسی کنید که تلفن یا رایانه هنوز به شبکهٔ
`Flova-Setup-*` وصل باشد. مرورگر باید روی همان شبکهٔ محلی باشد تا به صفحهٔ
راهاندازی ESP32 دسترسی داشته باشد.
## ۵. داشبورد کنترل LED را بسازید [#۵-داشبورد-کنترل-led-را-بسازید]
به [استودیو](https://studio.flova.ir/) بروید و **داشبورد جدید** را انتخاب کنید.
یک نام وارد کنید، در بخش **قالب دستگاه**، `ESP32 LED` را انتخاب کنید و در بخش
**طرح آغازین**، گزینهٔ **نمای کلی دستگاه** را بگذارید. سپس داشبورد را ایجاد کنید.
در ویرایشگر، پنل **ویجتها** را باز کنید و یک **Toggle** به صفحه اضافه کنید.
Toggle را انتخاب کنید، به تنظیمات اتصال داده بروید و در **انتخاب منبع مقدار**،
گزینهٔ `LED داخلی` را انتخاب کنید. توضیح این گزینه باید کلید فنی `LED`، نوع
روشن / خاموش و دسترسی خواندن و نوشتن را نشان دهد. این کانال با همین تنظیمات در
بخش ۱ ساخته شد.
صبر کنید پیشنویس ذخیره شود و سپس روی **انتشار** بزنید. وب اپلیکیشن فقط
داشبوردهای منتشرشده را نمایش میدهد؛ ذخیره شدن پیشنویس بهتنهایی آن را روی
دستگاه در دسترس نمیکند.
به [وب اپلیکیشن فلووا](https://pwa.flova.ir/) برگردید، دستگاهی را که به حساب
اضافه کردید باز کنید و داشبورد آن را ببینید. Toggle را تغییر دهید و روشن و خاموش
شدن LED داخلی را بررسی کنید. وب اپلیکیشن نوشتن مقدار `LED` را از طریق فلووا لینک
به دستگاه میفرستد و میانافزار عمومی آن را روی `GPIO2` اعمال میکند.
اگر `LED` در فهرست انتخاب منبع مقدار دیده نمیشود، منتشر بودن نسخهٔ نوع دستگاه
`ESP32 LED` و یکسان بودن قالب دستگاه داشبورد با همان نوع دستگاه را بررسی کنید.
اگر داشبورد در صفحهٔ دستگاه دیده نمیشود، انتشار داشبورد و بارگذاری دوبارهٔ صفحهٔ
دستگاه را بررسی کنید.
## اگر چیزی درست پیش نرفت [#اگر-چیزی-درست-پیش-نرفت]
اگر دستگاه آنلاین نمیشود، اول اتصال Wi-Fi و برگشتن از شبکهٔ `Flova-Setup-*` به
اینترنت را بررسی کنید. اگر Toggle تغییر نمیکند، منتشر بودن نوع دستگاه و داشبورد
و یکسان بودن کلید `LED` در نوع دستگاه و اتصال استودیو را بررسی کنید. برای خطاهای
مراحل بعدی، وضعیت دستگاه را در کنسول ببینید.
# اعلانها و پشتیبانی (/fa/docs/console/support)
کنسول پیامهای محصول و گفتگوهای پشتیبانی را داخل workspace واردشده نگه میدارد. اعلانها برای رویدادهای نیازمند توجه هستند و پشتیبانی برای گفتگو با تیم فلووا استفاده میشود.
## خواندن اعلانها [#خواندن-اعلانها]
از منوی کنسول [اعلانها](https://console.flova.ir/notifications) را باز کنید. اعلانها میتوانند دربارهٔ وضعیت پلن، مصرف سهمیه، پرداخت یا پشتیبانی باشند. اعلان تازه برچسب **جدید** دارد. اگر اعلان لینک دارد، **مشاهده** را بزنید و سپس آن را خواندهشده کنید. برای بقیهٔ موارد از **خواندن همه** استفاده کنید.
اعلانها به workspace مربوطاند. اگر پیامی را نمیبینید، workspace رخداد و صفحههای بعدی فهرست را بررسی کنید.
## ثبت درخواست پشتیبانی [#ثبت-درخواست-پشتیبانی]
۱. [پشتیبانی](https://console.flova.ir/support) را باز کنید.
۲. موضوع کوتاه بنویسید.
۳. دسته را انتخاب کنید: پرداخت و پلن، حساب کاربری، دستگاه و فریمور، مشکل فنی یا سایر.
۴. اتفاق، دستگاه یا قالب مربوط و کاری را که پیش از خطا انجام دادید توضیح دهید.
۵. اگر لاگ یا تصویر به بررسی کمک میکند، پیوست کنید.
۶. درخواست را ارسال کنید.
کلید API، Client Secret، گذرواژه، اطلاعات Wi-Fi و کدهای فعالسازی را در متن یا پیوست قرار ندهید. نام دستگاه، نام قالب، زمان رخداد و جزئیات امن خطا برای شروع بررسی کافی است.
## ادامهٔ گفتوگو [#ادامهٔ-گفتوگو]
صفحهٔ پشتیبانی درخواستهای workspace را با دسته، آخرین تغییر و وضعیت نشان میدهد. یک درخواست را باز کنید تا گفتگو و پیوستها را بخوانید. اگر پشتیبانی اطلاعات بیشتری خواست، پاسخ را در همان صفحه بنویسید.
| وضعیت | معنی |
| --- | --- |
| در انتظار پشتیبانی | تیم فلووا باید درخواست را بررسی یا پاسخ دهد. |
| در انتظار پاسخ شما | جزئیات خواستهشده را اضافه کنید. |
| حلشده | درخواست بسته شده است. ارسال پیام جدید گفتگو را باز میکند. |
## نوشتن گزارش قابل بررسی [#نوشتن-گزارش-قابل-بررسی]
مسیر دقیق صفحهٔ Console، نام قالب یا دستگاه، زمان خطا، پیام قابل مشاهده و رفتار مورد انتظار را بنویسید. برای مشکل تلهمتری، کلید فنی کانال و آنلاین بودن دستگاه را ذکر کنید. برای مشکل OTA، نسخه، وضعیت rollout و نتیجهٔ دستگاه را بنویسید.
گزارش دقیق timeline را سریعتر از جملهای مثل «کار نمیکند» میشود بررسی کرد. هنگام نوشتن timeline، secret ارسال نکنید.
برای راهاندازی و رفتار دستگاه به [شروع سریع](./quickstart)، [دستگاهها](./devices) و [پایش زنده](./monitor) هم مراجعه کنید.
# قالبها و نسخهها (/fa/docs/console/templates)
قالب مشخص میکند دستگاههای یک گروه چه ورودی، خروجی، فرمان و تنظیمات فریموری دارند. داشبوردهای [Studio](https://studio.flova.ir/)، کوئریهای FlovaQL، اتوماسیونها و انتشارهای OTA از همین قالب استفاده میکنند.
## ساخت قالب [#ساخت-قالب]
۱. [کنسول فلووا](https://console.flova.ir/templates) را باز کنید و **ساخت قالب** را بزنید.
۲. نامی وارد کنید که سختافزار یا محصول را توضیح دهد، مثل `ESP32 LED` یا `کنترلر اتاق`.
۳. روش راهاندازی را انتخاب کنید: Wi-Fi، BLE یا Ethernet.
۴. قالب را بسازید. کانالهای داده را از صفحهٔ **کانالهای داده** قالب اضافه کنید.
روش راهاندازی مشخص میکند دستگاه اطلاعات اولیهٔ شبکه را چطور دریافت کند. این گزینه جای فریمور و روش اتصال آن را نمیگیرد. فریمور باید جریان راهاندازی انتخابشده را پشتیبانی کند.
## ارتباط قالب با بخشهای دیگر [#ارتباط-قالب-با-بخشهای-دیگر]
| بخش | چیزی که قالب در اختیار آن میگذارد |
| --- | --- |
| دستگاهها | تعریف کانالها و سختافزار مشترک دستگاهها |
| داشبوردهای Studio | فهرست کانالهایی که ویجتها میخوانند یا مینویسند |
| FlovaQL | زمینهٔ قالب و کانال برای کوئری تلهمتری |
| اتوماسیونها | کانالهای قابل استفاده در محرک، شرط و عمل |
| OTA | خانوادهٔ دستگاه برای بررسی سازگاری و rollout |
هنگام ساخت داشبورد در [Studio](https://studio.flova.ir/)، همین قالب را انتخاب کنید. داشبوردی که به قالب دیگری وصل است نمیتواند از کانالهای این قالب استفاده کند.
## تنظیمات قالب [#تنظیمات-قالب]
از صفحهٔ **تنظیمات** قالب، نام آن را تغییر دهید یا قالب را آرشیو کنید. آرشیو قالب، دستگاههای فعال آن را هم آرشیو میکند؛ پیش از تأیید، فهرست دستگاهها را بررسی کنید. در صفحهٔ **کانالهای داده**، بخش **تنظیمات فریمور** برای پارامترهایی است که فریمور از قالب میخواند. هر پارامتر یک کلید، نوع و مقدار اولیه دارد. پیش از انتشار نسخه، پارامتر را ذخیره کنید.
در **تنظیمات سختافزار** گزینههایی مثل چراغ وضعیت و منبع بازنشانی کارخانهای قرار دارند. چراغ وضعیت یک کانال عادی نیست و تنظیم جداگانهای دارد. نام پایه را با فریمور یکسان نگه دارید، مثلاً `GPIO2` یا `D32`.
## انتشار نسخه [#انتشار-نسخه]
تغییرات قالب در یک نسخه نگهداری میشوند تا هر ویرایش بلافاصله به دستگاههای فعال نرسد.
۱. کانالها، پارامترهای فریمور یا نمودار اتوماسیون را ویرایش کنید.
۲. صفحهٔ **نسخهها** را باز کنید و شماره و وضعیت اعتبارسنجی نسخه را ببینید.
۳. نسخهای را که وضعیت **آمادهٔ انتشار** دارد منتشر کنید.
۴. انتشار را تأیید کنید. کنسول پیکربندی منتشرشده را برای دستگاههای فعال این قالب ارسال میکند.
| وضعیت | معنی |
| --- | --- |
| پیشنویس | نسخه هنوز در حال ویرایش است. |
| آمادهٔ انتشار | اعتبارسنجی موفق بوده و نسخه آمادهٔ انتشار است. |
| منتشرشده | این نسخه پیکربندی فعال قالب است. |
| آرشیوشده | نسخه در تاریخچه نگه داشته شده و قابل بازگردانی است. |
انتشار نسخهٔ قالب، داشبورد Studio را منتشر نمیکند. داشبورد را جداگانه در [Studio](https://studio.flova.ir/) منتشر کنید.
## بازگردانی نسخه [#بازگردانی-نسخه]
در **نسخهها**، یک نسخهٔ آرشیوشده را پیدا و **بازگردانی نسخه** را انتخاب کنید. کنسول نسخه را اعتبارسنجی میکند، آن را نسخهٔ منتشرشده قرار میدهد و پیکربندی آن را برای دستگاههای فعال قالب میفرستد. بازگردانی، پیکربندی قالب را تغییر میدهد و تلهمتری ذخیرهشده یا فریمور نصبشده را برنمیگرداند.
## خطاهای رایج [#خطاهای-رایج]
- **دستگاه ساخته نمیشود:** قالب نسخهٔ منتشرشده ندارد. ابتدا یک نسخه منتشر کنید.
- **کانال در Studio دیده نمیشود:** یکسان بودن قالب داشبورد و نسخهٔ منتشرشده را بررسی کنید.
- **نسخه منتشر نمیشود:** پیام اعتبارسنجی را باز کنید و کانال ناقص، کلید تکراری، پایهٔ نامعتبر یا نمودار ناقص اتوماسیون را اصلاح کنید.
- **قالب نباید در کارهای روزمره دیده شود:** آن را از **تنظیمات** آرشیو کنید. این کار دستگاههای فعال قالب را هم آرشیو میکند، پس ابتدا فهرست دستگاهها را ببینید.
برای جزئیات فیلدهای کانال به [کانالهای داده](./datastreams) بروید. مسیر کامل اتصال ESP32 در [شروع سریع](./quickstart) آمده است.
# تیم و workspace (/fa/docs/console/workspace)
workspace فضای مشترک Console و Studio است که تیم در آن قالبها، دستگاهها، داشبوردها، دادهها، کوئریها، اتوماسیونها و پرداخت را مدیریت میکند. workspace با فضای کاربری [وب اپلیکیشن فلووا](https://pwa.flova.ir/) فرق دارد. کاربر نهایی در وب اپلیکیشن دستگاه را claim میکند و داشبورد منتشرشده را میبیند.
## دعوت و مدیریت اعضا [#دعوت-و-مدیریت-اعضا]
۱. در کنسول **تیم** را باز کنید.
۲. **دعوت عضو** یا **مشاهده اعضا** را بزنید. کنسول صفحهٔ مدیریت workspace را در Flova Auth باز میکند.
۳. ایمیل فرد را وارد کنید، نقش را انتخاب و دعوتنامه را بفرستید.
۴. دعوتهای در انتظار را ببینید یا لغو کنید، نقش اعضا را تغییر دهید یا عضوی را از همان صفحهٔ سازمان حذف کنید.
اعضا داخل workspace کار میکنند. نقش آنها مشخص میکند قالب، دستگاه، اتوماسیون، تنظیمات، پرداخت و منابع دیگر را ببینند یا مدیریت کنند. برای هر شخص کمترین نقش لازم برای کارش را بدهید.
## تنظیمات workspace [#تنظیمات-workspace]
از **تنظیمات > workspace** نام و نشان workspace را تغییر دهید. این پیوند صفحهٔ سازمان را در Flova Auth باز میکند. نام در کنسول و بخشهای دیگر فلووا که از هویت workspace استفاده میکنند مشترک است.
تنظیمات workspace روی سازمان مشترک اثر میگذارد. تنظیمات حساب فقط به کاربر واردشده مربوط است، مثل مشخصات شخصی یا جزئیات احراز هویت. پیوند **حساب کاربری** نمایهٔ شما را در Flova Auth باز میکند.
## تفاوت دو فضا [#تفاوت-دو-فضا]
| فضا | کاربرد |
| --- | --- |
| workspace در Console و Studio | قالب، دستگاه، داشبورد، داده، دسترسی تیم و پرداخت |
| فضای کاربری در وب اپلیکیشن | دستگاههای claimشده و تجربهٔ منتشرشده برای کاربر نهایی |
ساخت دستگاه در Console آن را به حساب شخصی شما در وب اپلیکیشن اضافه نمیکند. دستگاه وقتی در دسترس کاربر نهایی قرار میگیرد که او QR یا کد دستی فعالسازی را در وب اپلیکیشن استفاده کند.
## همکاری تیمی [#همکاری-تیمی]
تغییرات قالب و کانال را داخل workspace انجام دهید تا Studio، FlovaQL، اتوماسیون و OTA از یک تعریف مشترک استفاده کنند. برای پیامهای workspace، سهمیه و پشتیبانی، [اعلانها](https://console.flova.ir/notifications) را ببینید. برای کمک از [پشتیبانی](https://console.flova.ir/support) درخواست ثبت کنید.
اگر صفحه یا عملیاتی را نمیبینید، ابتدا workspace فعال و نقش خود را بررسی کنید. ورود موفق بهتنهایی دسترسی همهٔ workspaceها و مجوزها را ایجاد نمیکند.
# Firmware پیشرفته (/fa/docs/sdk/advanced)
وقتی ترکیب استاندارد ESP32 یا ESP8266 با Hardware یا مدل سرویس محصول
هماهنگ نیست، از مسیرهای پیشرفته استفاده کنید. قاعدهٔ اصلی در همهٔ این مسیرها
این است که مرزهای مالکیت روشن بماند: برنامه Network و Hardware را اداره کند،
SDK قرارداد Flova و Connection را اجرا کند و Adapter فقط همان بخش مورد نیاز را
به هم متصل کند.
## Linux [#linux]
برنامههای Linux از FlovaLinux و بستهٔ CMake استفاده میکنند:
~~~cpp
#include
FlovaLinux device;
auto relay = FLOVA_DATASTREAM(device, bool, "relay");
int main() {
FLOVA_ON_WRITE(relay, applyRelay);
if (!device.begin()) return 1;
for (;;) device.run();
}
~~~
برنامه مالک Process، Event Loop و اتصال Hardware است. Service Supervisor شروع
Process، Restart و فعالسازی بستهٔ OTA مرحلهبندیشده را مدیریت میکند. اگر
برنامه در Linux به خواب یا Restart میرود، پیش از آن کارهای Link و Storage را
تمام کند و سپس سیاست خودش را اجرا کند.
## بردهای سفارشی و هستهٔ قابل انتقال [#بردهای-سفارشی-و-هستهٔ-قابل-انتقال]
هستهٔ قابل انتقال چهار مرز سرویس دارد:
~~~cpp
flova::Device device(link, storage, clock, logger);
auto relay = device.datastream("relay");
~~~
برای برد یا Gateway، flova::Link، flova::Storage،
flova::Clock و flova::Logger را پیادهسازی کنید.
Device::run() نقطهای است که پیامهای صفشده را به Context برنامه
و Hardware میرساند.
Transport میتواند Network، Serial، CAN، BLE یا یک Carrier محدود دیگر باشد.
Carrier را از منطق Datastream و Hardware جدا نگه دارید. Adapter نباید منطق
محصول، تبدیل نوع مقدار یا سیاست ایمنی خروجی را در خود پنهان کند.
## Ethernet [#ethernet]
پروژههای ESP32 با LAN8720 میتوانند از
FlovaEsp32Ethernet استفاده کنند. برنامه پارامترهای PHY،
Power و Startup وابسته به برد را فراهم میکند و Facade، Network و Connection
Flova را آماده میسازد. برای Ethernet Chip یا TCP/IP Stack متفاوت، Adapter
محدود و اعتبارسنجیشدهٔ خودتان را فراهم کنید.
پیش از راهاندازی، Schematic برد را برای Boot Pin، پایههای RMII، Power،
DHCP و Clock مربوط به PHY بررسی کنید. سپس این موارد را جداگانه آزمایش کنید:
Link فیزیکی، دریافت IP، آماده بودن TLS، برقرار شدن Connection، پیوند Template
و پذیرفته شدن فرمان Hardware. کامپایل موفق هیچکدام از این مراحل را ثابت
نمیکند.
## Bluetooth و مسیرهای دیگر Provisioning [#bluetooth-و-مسیرهای-دیگر-provisioning]
Bluetooth معمولاً برای Provisioning است و Transport دائمی Telemetry نیست.
Adapter مربوط به BLE میتواند Pairing، Framing، Timeout و تعامل با Mobile App
را مدیریت کند و سپس ProvisioningHandoff را به SDK بدهد. SDK
Handoff محدود، اعتبارسنجی، ذخیرهٔ Session و ادامهٔ چرخهٔ Runtime را مدیریت
میکند.
همین الگو برای Serial، ابزار Factory، صفحهٔ راهاندازی Ethernet و Cellular
کار میکند. ورودی این مسیر باید کوتاهعمر و قابل اعتبارسنجی باشد. پس از
پذیرش ماندگار Handoff، منابع موقت Provisioning را آزاد کنید و Flova Link یا
MQTT را برای کار عادی شروع کنید. توکن راهاندازی و Secret را در Log یا پاسخ
Diagnostic چاپ نکنید.
## Provisioning تحت مالکیت برنامه [#provisioning-تحت-مالکیت-برنامه]
یک Web Server موجود میتواند Routeها و Mode شبکهٔ خودش را نگه دارد و SDK فقط
Handoff محدود Flova را به آن اضافه کند. برنامه مسئول Authentication ورودی،
حفاظت از Route و نگهداری Wi-Fi یا Ethernet است. SDK نباید Web Server شما را
جایگزین کند یا بدون درخواست برنامه SoftAP راه بیندازد.
در برنامهٔ Arduino، ساختار معمول چنین است:
~~~cpp
WebServer server(80);
FlovaEsp32 device;
void setup() {
device.attachProvisioning(server);
server.begin();
}
void loop() {
server.handleClient();
device.run();
}
~~~
Provisioning را با درخواست فرم یکی نگیرید. پس از ارسال فرم باید Session
Commit شود، Connection احراز هویت شود، Template پیوند بخورد و نخستین Report
پذیرفته شود. این مراحل را جداگانه در Device و Console بررسی کنید.
## مرز برنامهٔ سفارشی Arduino [#مرز-برنامهٔ-سفارشی-arduino]
Facade سفارشی Passive است. خودش SoftAP شروع نمیکند، Web Server را جایگزین
نمیکند، GPIO را کنترل نمیکند و بدون تصمیم برنامه Device را Restart نمیکند.
برنامه انتخاب میکند چه زمانی Wi-Fi یا Ethernet شروع شود، کدام Pinها استفاده
شوند و خطای Hardware چگونه بازیابی شود.
~~~cpp
FlovaEsp32 device;
auto sensor = FLOVA_DATASTREAM(device, float, "temperature");
void setup() {
startApplicationNetwork();
attachHardwareHandlers();
device.begin();
}
void loop() {
serviceApplicationHardware();
device.run(applicationNetworkReady());
}
~~~
حلقه را همکارانه نگه دارید. Handler باید وضعیت برنامه را تغییر دهد یا کاری را
در صف قرار دهد و نباید برای درخواست Network دوم، File یا عملیات طولانی منتظر
بماند.
## Status و Callbackهای چرخهٔ اجرا [#status-و-callbackهای-چرخهٔ-اجرا]
وقتی محصول به تغییرهای مرزی مانند Network Ready، Flova Link Connected،
Runtime Ready یا Error Code نیاز دارد، از Status Listener استفاده کنید.
Listener باید کوتاه باشد؛ جزئیات را پس از آن از Facade بخوانید.
برای ابزار Maintenance، فیلدهای محدودی مانند آمادگی Network، آمادگی TLS،
آمادگی Runtime، Firmware Target و Lifecycle فعلی را نشان دهید. Token، Secret،
Payload کامل یا کلیدهای خصوصی Storage را نمایش ندهید.
## مالکیت Hardware [#مالکیت-hardware]
وقتی Universal Firmware باید ورودی و خروجی استاندارد را اعمال کند، از
Mappingهای Template استفاده کنید. وقتی محصول به Debounce، Sensor Calibration،
Interlock، Power Sequencing یا قانون Pin مخصوص نیاز دارد، Handler را در خود
برنامه نگه دارید.
فرمان معتبر Cloud را مستقیماً امن فرض نکنید. پیش از تغییر خروجی، وضعیت فعلی
Hardware، Limitها، شرایط Power و سیاست Emergency را بررسی کنید. اگر Hardware
فرمان را نپذیرفت، همان وضعیت واقعی را Report کنید و نتیجهٔ رد شدن را پنهان
نکنید.
## مرور پیش از تحویل [#مرور-پیش-از-تحویل]
پیش از تحویل یک Integration سفارشی، مدل Universal یا Custom را صریح انتخاب
کنید، Datastream و Settingها را پیش از begin() تعریف کنید و
Storageای فراهم کنید که با Reset مورد انتظار محصول باقی بماند. سپس
run() را در حلقهٔ همکارانه اجرا کنید و Handlerها را کوتاه و
آگاه از Hardware نگه دارید.
در نهایت Provisioning، Connection دوباره، Template Binding، فرمان، Report،
MQTT یا Flova Link، OTA و مسیر Recovery سیمی را جداگانه بررسی کنید. برای
اولین Image و Update ناموفق همیشه یک مسیر بازیابی قابل اتکا نگه دارید.
# Configuration و Settingها (/fa/docs/sdk/configuration)
Setting به برنامه اجازه میدهد مقدار Typeدار تنظیمشده در Flova را بخواند.
Setting را یکبار در Firmware تعریف کنید، Default Value بدهید و از Cache محلی
آن در منطق برنامه استفاده کنید.
## تعریف Setting [#تعریف-setting]
~~~cpp
auto dryThreshold = FLOVA_SETTING(device, double, "dry_threshold", 35.0);
auto dryCalibration = FLOVA_SETTING(device, int64_t, "dry_adc", 3000);
~~~
Key باید با Setting موجود در Template منتشرشده یکی باشد. تا زمان رسیدن یک
Value معتبر از راه دور، Default Value استفاده میشود.
برای خواندن Setting و محدود کردن آن به دامنهٔ امن Hardware:
~~~cpp
int32_t boundedCalibration(const flova::Setting& setting) {
const int64_t value = setting.value();
return static_cast(value < 0 ? 0 : value > 4095 ? 4095 : value);
}
~~~
تحویل Configuration ناهمگام است. تا زمان اعمال Update معتبر، از Value فعلی
استفاده کنید. Getter نباید درخواست Network بفرستد.
## Hardware Mapping و Safety [#hardware-mapping-و-safety]
Configuration Template میتواند Digital Input، Digital Output، Analog Input،
PWM Output، Default، Limit، Debounce، Sampling و Safety Rule را توصیف کند.
Universal Firmware Mappingهای پشتیبانیشده را خودکار اعمال میکند. برنامهٔ
سفارشی میتواند Configuration را بخواند و Safety Policy نهایی را در کد خود
نگه دارد.
Value را در مرز Hardware دوباره Validate کنید. مقداری که برای Template معتبر
است ممکن است برای Sensor، Motor، Power Stage یا Revision خاص Board ایمن نباشد.
## مسیر Configuration [#مسیر-configuration]
فرایند را چنین نگه دارید: Setting یا Datastream نوعدار را در Firmware تعریف
کنید؛ مورد متناظر را در Device Template بسازید؛ Version Template را Publish
کنید؛ Value را در Console تنظیم کنید؛ اجازه دهید Device آن را از Loop عادی
run() دریافت کند؛ و پس از پذیرفتن آن توسط Hardware، وضعیت حاصل
را Report کنید.
برای هر Setting یک Source of Truth داشته باشید. تکرار Calibration در Template،
Constantهای Firmware و رابط برنامه، تغییر میدانی را دشوار و خطا را پنهان میکند.
## تفاوت Setting و Datastream [#تفاوت-setting-و-datastream]
برای مقداری که در مدل زندهٔ Device دیده میشود، مانند دما، وضعیت Relay،
Counter یا Command کاربر، از Datastream استفاده کنید. برای مقداری که شیوهٔ
کار Firmware را تنظیم میکند، مانند Threshold، Calibration Point، Sampling
Interval یا Feature Switch، از Setting استفاده کنید.
این دو میتوانند کنار هم باشند. یک کنترلر رطوبت میتواند wet_adc
و dry_adc را بهعنوان Setting بخواند، درصد را محلی حساب کند و
نتیجه را در Datastream فقطخواندنی MOISTURE Report کند. Dashboard
Datastream را نشان میدهد و Console مقدار Setting را تغییر میدهد.
## رفتار Update [#رفتار-update]
Configuration از Loop عادی Device اعمال میشود. داخل Transport Callback، GPIO
را تغییر ندهید و Calibration طولانی را شروع نکنید. Value جدید را بگیرید،
در Loop برنامه تغییر آن را ببینید، آن را با Hardware متصل Validate کنید، رفتار
تازه را در یک مرز امن اعمال کنید و اگر Datastream نمایندهٔ آن رفتار است، State
حاصل را Report کنید.
اگر Value خارج از دامنهٔ امن برنامه بود، Value قبلی را نگه دارید و یک
Rejection یا Diagnostic محدود برگردانید. Limit موجود در Template ورودی مفیدی
است اما جای Validation در سطح Hardware را نمیگیرد.
## برنامهریزی ظرفیت [#برنامهریزی-ظرفیت]
Buildهای Embedded برای Datastream، Parameter، Text، History، جلوگیری از
تکرار Command، ورودی و خروجی Hardware و Schedule ظرفیت ثابت رزرو میکنند.
پیش از افزودن موارد زیاد به Template، این ظرفیت را برای Board برنامهریزی کنید.
وقتی Build به ظرفیت رسید، سطح تعریفشده را کوچک کنید، Resource صریح Target را
افزایش دهید یا Composition بزرگتری انتخاب کنید. روی Board کوچک Map پویا
اضافه نکنید تا مصرف حافظه پنهان نماند.
## بررسی نهایی Setting [#بررسی-نهایی-setting]
پیش از تحویل، Stable و lowercase بودن Technical Key، وجود Default قابل استفاده
برای Device تازه، یکسان بودن Type و Default در Template، نگهداری Calibration
و Product Limit در مدل Setting، Validation دوباره پیش از تماس با Hardware،
Update در حالت Online و پس از Connection دوباره، و بازیابی درست پس از Power
Cycle را بررسی کنید.
# Datastreamها (/fa/docs/sdk/datastreams)
Datastream یک مقدار Typeدار است که میان Firmware، Console، Studio و Dashboard
منتشرشدهٔ Device مشترک میشود. Technical Key آن قرارداد میان این بخشهاست و
باید دقیقاً با Key موجود در Template منتشرشده یکسان باشد.
## تعریف Datastream [#تعریف-datastream]
توابع کمکی Arduino برنامه را کوتاه نگه میدارند:
~~~cpp
auto temperature = FLOVA_DATASTREAM(device, float, "temperature");
auto relay = FLOVA_DATASTREAM(device, bool, "relay");
~~~
API قابل انتقال همین Typeها را ارائه میکند:
~~~cpp
auto relay = device.datastream("relay");
~~~
Datastreamها را پیش از begin() تعریف کنید. SDK هنگام Connection
Device، Keyهای تعریفشده را با Template منتشرشده Bind میکند. تعریف شدن یک
Datastream در Firmware بدون وجود همان Key در Template، آن را در Console قابل
مشاهده نمیکند.
## چهار مسیر کار با وضعیت [#چهار-مسیر-کار-با-وضعیت]
~~~cpp
FLOVA_ON_WRITE(relay, setRelay); // فرمان راه دور
FLOVA_WRITE(relay, true); // فرمان محلی برنامه
FLOVA_REPORT(temperature, 23.4f); // مشاهدهٔ حسگر یا Hardware
bool enabled = FLOVA_READ(relay); // مقدار Cache محلی
~~~
FLOVA_READ و value() Cache محلی را میخوانند و
درخواست Network نمیفرستند. FLOVA_REPORT یک مشاهده را ثبت
میکند و Handler نوشتن را اجرا نمیکند.
پیش از خواندن مقداری که ممکن است هنوز Restore یا دریافت نشده باشد،
FLOVA_HAS_VALUE را بررسی کنید:
~~~cpp
if (FLOVA_HAS_VALUE(relay) && FLOVA_READ(relay)) {
digitalWrite(2, HIGH);
}
~~~
## اعمال امن فرمان راه دور [#اعمال-امن-فرمان-راه-دور]
فرمانها از مسیر run() به Handler میرسند:
~~~cpp
flova::WriteResult setRelay(bool enabled) {
digitalWrite(2, enabled ? HIGH : LOW);
return flova::accept();
}
void setup() {
FLOVA_ON_WRITE(relay, setRelay);
}
void loop() {
device.run();
}
~~~
اگر Hardware فرمان را نمیپذیرد، بهجای تغییر وضعیت محلی یک Rejection برگردانید.
Handler باید کوتاه باشد. کار طولانی را در State برنامه قرار دهید تا حلقهٔ
اصلی آن را انجام دهد و پردازش Connection متوقف نشود.
## Typeهای مقدار [#typeهای-مقدار]
سطح Typeدار عمومی از Boolean، عدد صحیح، عدد اعشاری، Double و متن محدود
پشتیبانی میکند. Type زبان C++ باید با Type تعریفشده در Template یکی باشد.
طول متن به ظرفیت Build وابسته است؛ اگر متن از کاربر میگیرید، نتیجه و محدودیت
آن را پیش از اعمال به Hardware بررسی کنید.
## Offline و Connection دوباره [#offline-و-connection-دوباره]
Cache محلی اجازه میدهد Hardware هنگام قطع Network از آخرین مقدار Accepted
استفاده کند. سیاست Offline به نوع Stream و Configuration Firmware بستگی دارد.
پس از Connection دوباره، SDK بر اساس همان سیاست وضعیت را Sync میکند.
اگر Report رد شد، Network، Connection، Technical Key، Type مقدار و Version
Template را بررسی کنید. Online بودن Device بهتنهایی Accepted بودن Report را
ثابت نمیکند.
## طراحی قرارداد Template [#طراحی-قرارداد-template]
Datastream را ابتدا در Console تعریف کنید و بعد Declaration متناظر Firmware را
بنویسید. انتخابهای Template رفتار برنامه را مشخص میکنند:
| انتخاب Template | نتیجه در Firmware |
| --- | --- |
| Boolean، Integer، Float، Double یا Text | از Type متناظر C++ استفاده کنید. |
| Read-only | Observation را Report کنید و Handler فرمان نسازید. |
| Read/write | فرمان راه دور را اعمال و نتیجهٔ واقعی Hardware را Report کنید. |
| Default Value | فقط مقدار اولیه است؛ Hardware هنوز به Safe State نیاز دارد. |
| Hardware Mapping | در Universal Firmware اعمال یا در برنامهٔ سفارشی خوانده میشود. |
| Minimum و Maximum | پیش از اعمال به Hardware دوباره Validate کنید. |
Technical Key به حروف بزرگ و کوچک حساس است. temperature،
Temperature و TEMPERATURE سه Key متفاوتاند. تغییر
Key باید همزمان در Template، Firmware، Dashboard، Automation و Clientهای
بیرونی انجام شود.
## State، Sample، Command و Event [#state-sample-command-و-event]
برای مقدار فعلی Device یا Actuator از State استفاده کنید؛ برای اندازهگیری
در یک لحظه از Sample؛ برای دستوری که Device باید اعمال کند از Command؛ و برای
وقوعی مانند فشردن Button یا Alarm از Event. یک Relay که باید پس از Restart
بازیابی شود معمولاً State است، در حالی که دمای حسشده Sample و یک Trigger
یکبارمصرف Command یا Event است.
این انتخاب روی Restore، History، Dashboard و رفتار Offline اثر میگذارد.
پیش از ساخت Template مشخص کنید که مقدار باید «آخرین وضعیت» باشد یا «یک
اندازهگیری مستقل».
## خواندن نمای کامل Datastream [#خواندن-نمای-کامل-datastream]
Handle قابل انتقال میتواند اطلاعاتی بیشتر از Value بدهد:
~~~cpp
auto snapshot = relay.snapshot();
if (snapshot.hasValue && snapshot.quality == flova::Quality::Good) {
applyRelay(snapshot.value);
}
~~~
Snapshot میتواند زمان آخرین تغییر، Origin، Quality، Dirty بودن و Revision را
شامل شود. وقتی برنامه باید مقدار Restoreشده را از Sensor تازه یا Command راه
دور جدا کند، از Snapshot استفاده کنید.
## Report کردن وضعیت واقعی Hardware [#report-کردن-وضعیت-واقعی-hardware]
برای یک خروجی فیزیکی، ابتدا Command را اعمال کنید و سپس چیزی را Report کنید
که Hardware واقعاً پذیرفته است:
~~~cpp
flova::WriteResult setRelay(bool requested) {
const bool applied = writeRelayHardware(requested);
if (!applied) return flova::reject("hardware_rejected");
return flova::accept();
}
void loop() {
device.run();
const bool measured = readRelayHardware();
FLOVA_REPORT(relay, measured, flova::Origin::PhysicalInput);
}
~~~
به این ترتیب Value در Cloud با خروجی واقعی Relay، Driver یا Power Controller
هماهنگ میماند، حتی اگر Hardware به دلیل خطای برق یا محدودیت مکانیکی فرمان را
نپذیرد.
## ظرفیت و History [#ظرفیت-و-history]
Buildهای Embedded برای Datastream، Text، نتیجهٔ Command و History ظرفیت
محدود دارند. ظرفیت را برای Board و محصول برنامهریزی کنید و Container بدون
حدی اضافه نکنید. Queue Overflow، History حذفشده یا خطای Storage نشانهٔ آن
است که باید Resource Plan یا نرخ Report را بررسی کنید.
Sensor را در هر دور Loop Report نکنید. با نرخ مناسب Sample بگیرید، تغییرهای
معنادار را Report کنید و زمان کافی برای Network و Hardware باقی بگذارید.
## بررسی یک Value گمشده [#بررسی-یک-value-گمشده]
مسیر را به همین ترتیب بررسی کنید: Device Online باشد و Template انتخابشده
منتشر شده باشد؛ Key Firmware با Key Template بایتبهبایت یکی باشد؛ C++ Type
با Value Type هماهنگ باشد؛ نتیجهٔ Report Accepted باشد؛ Latest Value در Console
دیده شود؛ و در بازهٔ زمانی انتخابشده یک ردیف در History وجود داشته باشد.
Online بودن، Queue Acceptance، Latest Value و History بخشهای متفاوت مسیر را
ثابت میکنند. Device میتواند Online باشد اما Datastream تعریفنشده یا Report
ردشده داشته باشد.
# نصب و انتخاب Target (/fa/docs/sdk/install)
FlovaSDK برای ESP32 و ESP8266 بهصورت Library برای Arduino و PlatformIO
منتشر میشود. برنامههای Linux از Package مربوط به CMake استفاده میکنند.
یک Device قابل انتقال میتواند Core تعبیهشده را با Serviceهای Platform خودش
به کار بگیرد.
## ابتدا مدل Integration را انتخاب کنید [#ابتدا-مدل-integration-را-انتخاب-کنید]
| چیزی که دارید | از اینجا شروع کنید | مالکیت برنامه |
| --- | --- | --- |
| Board بدون برنامهٔ Device | FlovaUniversalEsp32 یا FlovaUniversalEsp8266 | Template و Dashboard محصول |
| برنامهٔ موجود Arduino | FlovaEsp32 یا FlovaEsp8266 | Wi-Fi، GPIO، Sensor، Provisioning و Main Loop |
| Raspberry Pi یا Host لینوکسی | FlovaLinux | Process، Event Loop، Service Supervisor و Hardware |
| Board یا Gateway دیگر با C++11 | flova::Device | Link، Storage، Clock، Logger و اتصال Board |
برای یک Device آمادهٔ ESP32 از [شروع سریع](./quickstart) شروع کنید. این صفحه
برای انتخاب Target، ساخت Project تازه و شناخت مرز مالکیت هر مدل است.
## Arduino IDE و PlatformIO [#arduino-ide-و-platformio]
این دو مسیر در یک مجموعهٔ تب قرار دارند تا انتخاب ابزار و انتخاب Board از هم
جدا نشوند. تب پیشفرض Arduino IDE است.
### ESP32 و ESP8266 [#esp32-و-esp8266]
۱. **Tools > Board > Boards Manager** را باز کنید.
۲. Package مربوط به esp32 از Espressif Systems را نصب کنید.
۳. از **Tools > Manage Libraries**، Library با نام FlovaSDK را نصب کنید.
۴. Board و USB Serial Port را از **Tools > Board** و **Tools > Port** انتخاب کنید.
۵. نقطهٔ ورود عمومی را وارد کنید:
~~~cpp
#include
~~~
این Header Facade مربوط به ESP32 را در اختیار میگذارد. برای یک Device کامل
از FlovaUniversalEsp32 و برای برنامهٔ موجود از
FlovaEsp32 استفاده کنید.
۱. **Tools > Board > Boards Manager** را باز کنید.
۲. Package مربوط به esp8266 از ESP8266 Community را نصب کنید.
۳. از **Tools > Manage Libraries**، Library با نام FlovaSDK را نصب کنید.
۴. Profile برد ESP8266 و USB Serial Port را انتخاب کنید.
۵. نقطهٔ ورود عمومی را وارد کنید:
~~~cpp
#include
~~~
با همان مدل مالکیت ESP32، از FlovaUniversalEsp8266 یا
FlovaEsp8266 استفاده کنید.
ESP8266 از BearSSL استاندارد استفاده میکند. اتصال TLS و کار OTA ممکن است
Loop برنامه را برای چند ثانیه متوقف کند و به یک Heap پیوسته نیاز داشته باشد.
Memory Profile توصیهشدهٔ SDK را انتخاب کنید و Bufferهای بزرگ را از Sketch دور
نگه دارید.
### ESP32 و ESP8266 [#esp32-و-esp8266-1]
Library را به platformio.ini اضافه کنید:
~~~ini
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
lib_deps = flova-platform/FlovaSDK@^0.3.12
~~~
برای Build و Upload:
~~~sh
pio run
pio run -t upload
~~~
از Profile بستهبندیشدهٔ ESP8266 در SDK استفاده کنید یا Board و Memory Layout
توصیهشدهٔ Target را تنظیم کنید. وابستگی پروژه:
~~~ini
lib_deps = flova-platform/FlovaSDK@^0.3.12
~~~
Build و Upload با همین دستورها انجام میشود:
~~~sh
pio run
pio run -t upload
~~~
هنگام تنظیم TLS، Memory یا OTA، مسیر Upload سیمی را در دسترس نگه دارید.
## Universal Firmware [#universal-firmware]
وقتی میخواهید Flova کل Composition مربوط به Device را مدیریت کند، از
Universal Firmware استفاده کنید:
~~~cpp
#include
#include
FlovaUniversalEsp32 device;
void setup() {
Serial.begin(115200);
device.begin();
}
void loop() {
device.run();
}
~~~
برای ESP8266 از FlovaUniversalEsp8266 استفاده کنید. Universal
Firmware Composition برد، مسیر Provisioning، Hardware Mapping، سیاست OTA و
سیاست Restart مربوط به Target را فراهم میکند و برای یک محصول استاندارد
Wi-Fi کوتاهترین مسیر است.
## Linux و Raspberry Pi [#linux-و-raspberry-pi]
Dependencyهای بومی را از ریشهٔ Repository مربوط به Firmware نصب و Package را
Build کنید:
~~~sh
sudo apt install cmake libssl-dev
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr/local
cmake --build build
sudo cmake --install build
~~~
Package نصبشده را به برنامه Link کنید:
~~~cmake
find_package(FlovaLinux CONFIG REQUIRED)
target_link_libraries(my_device PRIVATE Flova::Linux)
~~~
سپس از همان مدل Typeدار Datastream استفاده کنید:
~~~cpp
#include
FlovaLinux device;
auto relay = FLOVA_DATASTREAM(device, bool, "relay");
int main() {
if (!device.begin()) return 1;
for (;;) device.run();
}
~~~
run() یک گام محدود انجام میدهد. آن را در Poll یا Event Loop
برنامه قرار دهید و مالکیت Process را به SDK ندهید.
## Boardهای قابل انتقال [#boardهای-قابل-انتقال]
Core قابل انتقال در Include عمومی خود به Arduino، ESP، Wi-Fi، File System،
Exception یا RTTI نیاز ندارد. برای Port سفارشی، این Serviceها را فراهم کنید:
flova::Link، flova::Storage، flova::Clock
و flova::Logger؛ سپس flova::Device را بسازید.
اگر Target به Network سفارشی، Gateway، Ethernet Chip یا Service Supervisor
نیاز دارد، [Firmware پیشرفته](./advanced) را بخوانید.
## بررسی نصب [#بررسی-نصب]
پس از نصب و پیش از Debug منطق برنامه، هماهنگ بودن Board Package با Board
فیزیکی، تغییر کردن Serial Port هنگام جدا و وصل کردن Board، Compile شدن یک
Sketch خالی با #include <FlovaSDK.h>، یکسان بودن Class
برنامه با Target انتخابشده و Publish بودن Template Device را بررسی کنید.
اگر Library پیدا میشود اما Device وصل نمیشود، Wi-Fi یا Ethernet، زمان و TLS،
وضعیت Provisioning، Session و Status Device را جداگانه بررسی کنید.
# چرخهٔ Firmware (/fa/docs/sdk/lifecycle)
چرخهٔ Firmware فقط ساخت یک Image نیست. Target، Version، Boot Layout، Logهای
Runtime، مسیر OTA، Provisioning و روش Recovery باید در یک تصمیم Release کنار
هم دیده شوند. Console هنگام پیشنهاد OTA از همین اطلاعات برای سازگاری Device
استفاده میکند.
## Build Metadata [#build-metadata]
هر Release باید Firmware Target و Version روشن داشته باشد. Target را برای
Board و Boot Layout سازگار ثابت نگه دارید. Version SDK و Version برنامهٔ
Firmware دو مقدار جدا هستند؛ نصب نسخهٔ جدید SDK بهتنهایی Device نصبشده را
بهروزرسانی نمیکند و باید Image تازه بسازید و تحویل دهید.
Metadata را پیش از بارگذاری بررسی کنید. اشتباه در Target میتواند باعث شود
Image روی Board درست Compile شود اما برای Boot Layout، حافظه یا مسیر Recovery
Device مناسب نباشد.
## Logging و Diagnostic [#logging-و-diagnostic]
Diagnosticهای Flova را میتوان هنگام Compile فیلتر کرد:
~~~ini
build_flags =
-DFLOVA_LOGGING_ENABLED=1
-DFLOVA_LOG_LEVEL=FLOVA_LOG_LEVEL_DEBUG
~~~
Levelهای پشتیبانیشده ERROR، WARN،
INFO، DEBUG و TRACE هستند. در Image
Production میتوانید Log Flova را خاموش کنید. Credential، Provisioning Token،
Device Secret و Payload حساس کامل را هرگز Log نکنید.
برای Diagnostic میدانی، نام Event، Error Code محدود، Target و Lifecycle را
ثبت کنید. اگر Log از محیط Device خارج میشود، Identityها را Mask کنید و
اطلاعات ورود را چاپ نکنید.
## OTA [#ota]
Console یک Firmware Release میگیرد، Target و اندازهٔ Image را بررسی میکند
و آن را برای Deviceهای سازگار در یک Rollout میفرستد. Firmware باید OTA
Capability و Boot Layout متناسب با همان Target را داشته باشد.
Imageهای Universal در ESP32 از Boot Layout پشتیبانیشدهٔ Target استفاده
میکنند. OTA در ESP8266 از Staged Copy استفاده میکند و Rollback خودکار
ندارد؛ برای Boot ناموفق پس از Update، مسیر Upload سیمی را نگه دارید.
Upload شدن OTA، تمام شدن Rollout و Connection زمان اجرا پس از Restart سه
بررسی جدا هستند. بعد از Update، Timeline Device، Metadata Version فعلی،
Online بودن، Template Binding و یک Report تازه را بررسی کنید.
## Recovery [#recovery]
برای نصب نخستین و Boardی که Image جدید را Boot نمیکند، مسیر Upload سیمی
لازم است. قطع Network را با پاک کردن Provisioning پاسخ ندهید. ابتدا Status و
Log Device را بررسی کنید و سپس Image را از مسیر پشتیبانیشدهٔ Board بازیابی
کنید.
اگر OTA ناموفق شد، Version قبلی، Image Recovery، کابل و درگاه Upload را
در دسترس نگه دارید. Recovery را به شرطی وابسته نکنید که فقط پس از برقراری
Connection آنلاین قابل اجرا باشد.
## سیاست Version و Target [#سیاست-version-و-target]
Version Firmware، Target، Boot Layout و قرارداد Template را یک تصمیم Release
بدانید. Imageی که برای یک Board Compile میشود لزوماً برای همهٔ Deviceهای آن
خانواده امن نیست.
برای تغییر در Partition یا Boot Layout، Capability یا رفتار Rollback، Memory
Profile یا محدودیت TLS، Pinهای لازم، Wiring ابزار جانبی یا قابلیتی که Device
نمیتواند ایمن خاموش کند، Target جدا بسازید. برای Releaseهای سازگار نام Target
را ثابت نگه دارید و وقتی روش Image یا Recovery عوض شد، Target تازه منتشر کنید.
## آمادهسازی OTA Release [#آمادهسازی-ota-release]
پیش از بارگذاری Release در Console این مسیر را کامل کنید:
۱. دقیقاً همان Target مورد استفادهٔ Deviceهای انتخابشده را Build کنید.
۲. Version و Target را در Metadata Image بررسی کنید.
۳. اندازهٔ Image را با ظرفیت Flash و OTA مقایسه کنید.
۴. Image سیمی Recovery و آخرین Release سالم را نگه دارید.
۵. Boot، Restore شدن Provisioning، Connection دوباره و یک Datastream را آزمایش کنید.
۶. Release را بارگذاری و نتیجهٔ سازگاری را بررسی کنید.
پس از موفق شدن ثبت Release، Rollout را برای گروه کوچک بسازید. Connection
پس از Restart، Template Binding، فرمان و Report را ببینید. وقتی خطا یا
Offline شدن به آستانهٔ محصول رسید، Rollout را متوقف کنید و پیش از تلاش دوباره
علت را بررسی کنید.
## بررسی پس از OTA [#بررسی-پس-از-ota]
تمام شدن عملیات OTA فقط پایان Update را ثابت میکند. برای هر Device آزمایشی
Version جدید، Target و Boot Layout سازگار، Connection دوباره، Template Binding،
رسیدن فرمان به Hardware، Report تازه در Latest Value و History و ماندن
Provisioning و Configuration را بررسی کنید.
اگر Device Update شد اما برنگشت، پیش از Retry کردن Rollout نتیجهٔ Boot،
حافظه، آمادگی TLS، Session ذخیرهشده و Timeline را بررسی کنید. در این مرحله
پاک کردن Session معمولاً علت اصلی را پنهان میکند و Recovery را دشوارتر
میسازد.
## Power Down و کار طولانی [#power-down-و-کار-طولانی]
اگر Target متد آمادهسازی خاموشی دارد، پیش از Sleep یا قطع برق آن را صدا بزنید.
ابتدا کار Flova Link یا MQTT و Storage را تمام یا آرام کنید. زمان Sleep و
سیاست Power Management را خود Board و برنامه تعیین میکنند؛ SDK جای آن را
نمیگیرد.
## Logging بر اساس محیط [#logging-بر-اساس-محیط]
برای Log دستگاه در Production از ERROR یا WARN،
برای Diagnostic کنترلشدهٔ میدانی از INFO و در توسعه از
DEBUG یا TRACE استفاده کنید. Error Code محدود و
Metadata Target را نگه دارید و اطلاعات ورود یا مادهٔ Provisioning را چاپ
نکنید.
# نمای کلی SDK (/fa/docs/sdk/overview)
FlovaSDK لایهٔ مشترک میان برنامهٔ دستگاه و Flova است. این لایه Connection،
Identity، Datastreamهای نوعدار، فرمانهای راه دور، Settingها، وضعیت محلی و
چرخهٔ `run()` را در اختیار برنامه میگذارد. برنامه همچنان مالک حسگر، خروجی،
منطق محصول و رفتار ایمن دستگاه است.
SDK روی ESP32، ESP8266، Linux و بردهای C++11 قابل انتقال کار میکند. کد
Datastream در این مدلها ثابت میماند و فقط Transport تغییر میکند: در حالت
معمول از **Flova Link** استفاده کنید و اگر محصول از قبل زیرساخت MQTT دارد،
MQTT را بهعنوان Transport انتخاب کنید.
## از کجا شروع کنیم؟ [#از-کجا-شروع-کنیم]
اگر اولین دستگاه را میسازید، [شروع سریع](./quickstart) یک نمونهٔ ESP32 را از
ساخت Template تا مشاهدهٔ اولین مقدار در Console پیش میبرد. پس از آن،
[Datastreamها](./datastreams) قرارداد میان Firmware و Template را توضیح
میدهد و [Provisioning](./provisioning) هویت و راهاندازی نخستین دستگاه را
پوشش میدهد.
برای پروژهٔ موجود، ابتدا ببینید کدام بخش در اختیار برنامه است:
| مدل | انتخاب مناسب | برنامه مالک چیست؟ |
| --- | --- | --- |
| Universal Firmware | `FlovaUniversalEsp32` یا `FlovaUniversalEsp8266` | Template، راهاندازی اولیه، نگاشت Hardware و سیاست OTA را خود SDK مدیریت میکند. |
| برنامهٔ سفارشی Arduino | `FlovaEsp32` یا `FlovaEsp8266` | Wi-Fi، GPIO، حسگرها، Web Server، Provisioning و حلقهٔ اصلی را برنامه مدیریت میکند. |
| دستگاهٔ Linux | `FlovaLinux` | Process، Event Loop، Hardware و Service Supervisor با برنامه است. |
| برد یا Gateway سفارشی | `flova::Device` | Link، Storage، Clock، Logger و اتصال Hardware را Port فراهم میکند. |
## مدل اتصال [#مدل-اتصال]
در Universal Firmware، SDK مسیر Wi-Fi، Provisioning، ذخیرهٔ Session و اتصال
Flova Link را تا حدی که آن Target پشتیبانی میکند آماده میکند. این مسیر برای
دستگاهی مناسب است که میخواهید رفتار عمومی آن از روی Template و Console
مدیریت شود.
در برنامهٔ سفارشی، شما Wi-Fi یا Ethernet را شروع میکنید، زمان آماده شدن
شبکه را تشخیص میدهید و سپس SDK را وارد حلقهٔ برنامه میکنید. میتوانید از
Flova Link استفاده کنید یا یک MQTT Client موجود را به SDK بدهید. در هر دو
حالت، تعریف Datastream، Handler فرمان و گزارش مقدار یکسان میماند.
Bluetooth، Serial، Ethernet و حتی یک Gateway میتوانند برای رساندن اطلاعات
Provisioning به دستگاه به کار بروند. این مسیر موقت است؛ پس از پذیرفته شدن
دادهٔ تحویل و ذخیره شدن Session، دستگاه باید برای کار عادی از Flova Link یا
MQTT استفاده کند.
## سطح عمومی SDK [#سطح-عمومی-sdk]
بیشتر پروژههای Arduino با یک Include آغاز میشوند:
```cpp
#include
```
توابع کمکی پرکاربرد عبارتاند از `FLOVA_DATASTREAM`، `FLOVA_SETTING`،
`FLOVA_WRITE`، `FLOVA_READ`، `FLOVA_REPORT`، `FLOVA_ON_WRITE` و
`FLOVA_HAS_VALUE`.
```cpp
auto relay = device.datastream("relay");
relay.onWrite(setRelay);
relay.write(true);
relay.report(readRelay());
bool current = relay.value();
```
کلید Datastream باید دقیقاً با نسخهٔ منتشرشدهٔ Template یکی باشد. حروف بزرگ
و کوچک در کلید تفاوت دارند. برنامه Hardware را اداره میکند و SDK فرمانهای
دریافتی را در `run()` به Handler میرساند؛ بنابراین Handler باید کوتاه باشد و
کار طولانی را به حلقهٔ اصلی برنامه بسپارد.
## جایگاه SDK در محصول [#جایگاه-sdk-در-محصول]
در یک محصول کامل، پنج بخش با هم کار میکنند. برنامهٔ شما حسگرها را میخواند،
خروجیها را کنترل میکند و دربارهٔ رفتار امن پس از قطع برق یا شبکه تصمیم
میگیرد. SDK قرارداد Datastream، Setting، Provisioning و Connection را اجرا
میکند. Transport فرمان، Report و وضعیت اتصال را جابهجا میکند. Template
کلیدها، نوع مقدار، دسترسی و نگاشت Hardware را مشخص میکند. Console و Studio
هم Template، Device، Dashboard، Telemetry و انتشار Firmware را مدیریت
میکنند.
SDK بهتنهایی یک پروژهٔ GPIO را به محصول تبدیل نمیکند. هنوز باید برای قطع
شبکه، مقدار نامعتبر، خطای حسگر، راهاندازی دوباره و وضعیت اضطراری تصمیم
مشخص داشته باشید.
## حلقهٔ اجرای دستگاه [#حلقهٔ-اجرای-دستگاه]
در `setup()` سرویسهایی را که برنامه مالک آنهاست شروع کنید و سپس
`device.begin()` را صدا بزنید. در `loop()` کار حسگر و Hardware را انجام دهید
و `device.run()` را مرتب اجرا کنید. `run()` یک گام محدود از اتصال، دریافت
فرمان، اعمال وضعیت و ارسال داده را انجام میدهد و نباید با یک کار طولانی
جایگزین حلقهٔ اصلی شود.
پس از آماده شدن Connection، SDK کلیدهای تعریفشده را با Template منتشرشده
مطابقت میدهد. پیش از تکیه بر مقدار بازیابیشده، آماده بودن Datastream را
بررسی کنید. وصل بودن Socket یا Online بودن Device بهتنهایی پذیرفته شدن یک
Report را ثابت نمیکند؛ نتیجهٔ Report، Latest Value و History را در Console
بررسی کنید.
## ترتیب پیشنهادی مطالعه [#ترتیب-پیشنهادی-مطالعه]
۱. [شروع سریع](./quickstart) برای ساخت اولین Device و Dashboard.
۲. [Datastreamها](./datastreams) برای مقدار، فرمان، Report و قرارداد Template.
۳. [Provisioning](./provisioning) برای Identity، Session و مسیرهای Wi-Fi، BLE و Web.
۴. [Configuration](./configuration) برای Settingهای نوعدار و مرز ایمنی Hardware.
۵. [Transportها](./transports) برای Flova Link، MQTT، Connection و Adapter سفارشی.
۶. [چرخهٔ Firmware](./lifecycle) برای Logging، OTA، Release و Recovery.
۷. [Firmware پیشرفته](./advanced) برای Linux، Ethernet، Bluetooth و بردهای سفارشی.
برای نام کلاسها، توابع عمومی و متدهای وضعیت از [مرجع API](./reference)
استفاده کنید. این مرجع سطح عمومی SDK را پوشش میدهد و به جزئیات خصوصی
پیادهسازی وابسته نیست.
# Provisioning و Identity (/fa/docs/sdk/provisioning)
Provisioning یک واحد فیزیکی را به یک Device Record در Flova متصل میکند.
در این فرایند، یک Handoff کوتاهعمر به Device میرسد، Identity زمان اجرا
ساخته یا دریافت میشود و SDK آن را برای Bootهای بعدی در Storage انتخابشده
نگه میدارد.
Provisioning را با اتصال معمول اشتباه نگیرید. Wi-Fi، Ethernet، Bluetooth یا
Serial میتوانند کانال رساندن اطلاعات اولیه باشند؛ پس از تکمیل Handoff،
Device باید با Flova Link یا MQTT احراز هویت شود و وارد مسیر عادی Telemetry
شود.
## Universal Firmware [#universal-firmware]
Universal Firmware در ESP32 و ESP8266 مسیر Setup را در خود دارد. کاربر Flow
راهاندازی را کامل میکند، Device اطلاعات Network و Handoff Flova را میگیرد
و Firmware وضعیت نهایی را ذخیره میکند. در Boot بعدی، Session ذخیرهشده
بازیابی میشود و Device بدون تکرار Flow نخستین به Flova وصل میشود.
این مسیر برای محصولی مناسب است که SDK مالک SoftAP، فرم Setup، نگاشت Hardware
و رفتار عمومی Restart باشد. پیش از انتشار، نام Wi-Fi راهاندازی، محدودیت
زمانی Token و رفتار Reset را با Mobile App یا Web App واقعی بررسی کنید.
## برنامهٔ سفارشی [#برنامهٔ-سفارشی]
در Firmware سفارشی، برنامه مالک Wi-Fi، Web Server، BLE، Ethernet یا هر کانال
Setup دیگری است. برنامه Handoff محدود Flova را به SDK میدهد؛ SDK اعتبارسنجی،
Bootstrap، Commit کردن Session و ادامهٔ Connection را انجام میدهد.
Handoff شامل Link URL و Token کوتاهعمر مربوط به استقرار است:
~~~cpp
flova::ProvisioningHandoff handoff(linkUrl, shortLivedToken);
client.provision(handoff);
~~~
کانال Setup ورودی و Transport خودش را مدیریت میکند. SDK Handoff محدود و
Lifecycle مربوط به Session Flova را مدیریت میکند. Token، Device Secret،
Credentialهای Wi-Fi و Payload کامل Provisioning را در Source Code، Log یا
صفحهٔ وضعیت قرار ندهید.
## کانالهای Provisioning [#کانالهای-provisioning]
یک Factory Tool میتواند از Serial استفاده کند. Mobile App میتواند از BLE
برای Pairing و انتقال Handoff استفاده کند. یک محصول صنعتی میتواند یک صفحهٔ
Setup روی Ethernet یا Web Server خودش داشته باشد. در همهٔ این حالتها، کانال
فقط دادهٔ تحویل اولیه را حمل میکند و نباید Secret زمان اجرا را برای هر Boot
دوباره ارسال کند.
Adapter هر کانال مسئول Framing، Timeout، Authentication ورودی و آزاد کردن
منابع موقت است. SDK مسئول محدود نگه داشتن Handoff، ذخیرهٔ Session، اتصال به
Flova و گزارش نتیجه است. پس از Commit شدن Session، BLE یا SoftAP را ببندید و
Transport دائمی انتخابشده را شروع کنید.
## چیزی که Provisioning ذخیره میکند [#چیزی-که-provisioning-ذخیره-میکند]
نتیجهٔ Handoff یک Session Flovaست که Identity دستگاه، ارتباط آن با
Organization و Template، Link URL و Secret زمان اجرا را در بر میگیرد. SDK
این Session را از طریق Storage انتخابشده نگه میدارد. برنامه نباید Secret را
در Configuration File دیگری کپی کند یا در Status Page نمایش دهد.
Activation Token فقط ورودی Bootstrap است. این Token گذرواژهٔ Runtime نیست و
نباید در هر Boot ارسال شود. پس از Commit، Bootهای بعدی Session ذخیرهشده را
بازیابی و با Identity زمان اجرا احراز هویت میکنند.
## Statusهای Provisioning [#statusهای-provisioning]
Setup را یک State Machine بدانید، نه یک درخواست HTTP منفرد:
| Status | رفتار برنامه |
| --- | --- |
| Waiting | کانال Setup را در دسترس نگه دارید و SDK را طبق معمول اجرا کنید. |
| Bootstrapping | از حلقهٔ عادی بررسی کنید و Session دوم شروع نکنید. |
| Committing | برق و Storage را تا ماندگار شدن Session حفظ کنید. |
| Ready | منابع موقت Setup را ببندید و کار عادی Device را شروع کنید. |
| Failed | خطای محدود نمایش دهید، Recovery را باز بگذارید و آگاهانه دوباره تلاش کنید. |
نام دقیق Status در Facadeهای مختلف ممکن است فرق کند، اما مرزها ثابت هستند.
ارسال موفق Form به معنی آماده بودن Device نیست. Session ذخیرهشده، Connection
احراز هویتشده، Template Binding و نخستین Accepted Report را جداگانه بررسی
کنید.
## Web Setup تحت مالکیت برنامه [#web-setup-تحت-مالکیت-برنامه]
اگر برنامهٔ Arduino از قبل Web Server دارد، Provisioning را به همان Server
وصل کنید:
~~~cpp
WebServer server(80);
FlovaEsp32 device;
void setup() {
device.attachProvisioning(server);
server.begin();
}
void loop() {
server.handleClient();
device.run();
}
~~~
SDK Handlerهای محدود Status و Provisioning را ثبت میکند. Server را شروع یا
جایگزین نمیکند، Mode مربوط به Wi-Fi را تغییر نمیدهد و Routeهای دیگر برنامه
را در اختیار نمیگیرد. حلقهٔ Server و device.run() را در یک Loop
غیرمسدودکننده نگه دارید.
## Reset و Recovery [#reset-و-recovery]
وقتی محصول باید Identity Flova را عوض کند، از
startProvisioning() یا عملیات Factory Reset مربوط به Facade
استفاده کنید. Trigger را روشن تعریف کنید؛ برای نمونه نگه داشتن یک Button
فیزیکی یا یک Maintenance Command احراز هویتشده.
Reset باید State خصوصی Flova را پاک کند و Device را به Setup برگرداند. Wi-Fi،
Web Server، GPIO یا دادهٔ محصول را بیدلیل پاک نکنید، مگر اینکه محصول صریحاً
چنین رفتاری بخواهد.
اگر Bootstrap شکست خورد، Setup Channel، URL از نوع HTTPS یا WSS، زمان سیستم،
عمر Token، دسترسی Storage و Device Claim را جدا بررسی کنید. خطا را محدود نگه
دارید و Token یا Secret را در پیام Diagnostic قرار ندهید.
## بررسی پس از Provisioning [#بررسی-پس-از-provisioning]
پس از پایان Flow، در Console این مسیر را مرحلهبهمرحله بررسی کنید: Device
به Record درست متصل شده باشد، Template مورد انتظار را داشته باشد، Firmware
Target درست گزارش شود، Connection Online باشد، Datastreamها Bind شده باشند و
یک Report واقعی به Latest Value و History رسیده باشد.
وجود Device در Console یا Online بودن آن بهتنهایی موفقیت Provisioning را ثابت
نمیکند. این بررسیها را برای Universal Firmware، Web Setup، BLE و Factory
Tool یکسان انجام دهید.
# شروع سریع (/fa/docs/sdk/quickstart)
این سریعترین مسیر برای راهاندازی یک دستگاهٔ Flovaست. یک قالب ESP32 میسازید،
Universal Firmware را روی برد میریزید، برد را راهاندازی میکنید و LED داخلی
آن را از یک Dashboard منتشرشده تغییر میدهید.
به یک برد ESP32 با LED روی `GPIO2`، کابل USB داده، تلفن یا رایانهٔ متصل به Wi-Fi
و یکی از PlatformIO یا Arduino IDE نیاز دارید. پیش از شروع یک فضای کاری در Flova
بسازید.
## ۱. قالب دستگاه را بسازید [#۱-قالب-دستگاه-را-بسازید]
به [Console Flova](https://console.flova.ir/) بروید، یک نوع دستگاه بسازید و نام آن
را `ESP32 LED` بگذارید. روش راهاندازی را روی Wi-Fi بگذارید و یک Datastream با
مشخصات زیر اضافه کنید:
| فیلد | مقدار |
| --- | --- |
| نام | LED داخلی |
| کلید فنی | `LED` |
| نوع مقدار | بولی |
| دسترسی | خواندن و نوشتن |
| رفتار | خروجی دیجیتال |
| پایهٔ سختافزار | `GPIO2` |
| سطح فعال | HIGH |
| وضعیت اولیه و امن | خاموش |
کلید فنی را دقیقاً `LED` وارد کنید. پیش از ساخت دستگاه، نسخهٔ نوع دستگاه را
منتشر کنید.
## ۲. Universal Firmware را نصب و فلش کنید [#۲-universal-firmware-را-نصب-و-فلش-کنید]
ترکیب یونیورسال راهاندازی، اتصال دستگاه، نگاشت سختافزار و چرخهٔ معمول
Firmware را مدیریت میکند. ابزار خود را انتخاب کنید:
بستهٔ برد ESP32 را نصب کنید:
۱. **Tools > Board > Boards Manager** را باز کنید.
۲. `esp32` از Espressif Systems را جستوجو و نصب کنید.
۳. از **Tools > Manage Libraries**، `FlovaSDK` را جستوجو و نصب کنید.
۴. برد ESP32 خود را از **Tools > Board** انتخاب کنید.
۵. درگاه Serial USB آن را از **Tools > Port** انتخاب کنید.
یک برنامهٔ تازه بسازید و آن را با این کد جایگزین کنید:
```cpp
#include
#include
FlovaUniversalEsp32 device;
void setup() {
Serial.begin(115200);
device.begin();
}
void loop() {
device.run();
}
```
روی **Upload** بزنید. Arduino IDE بستهٔ کامل Target انتخابشده را میسازد و
روی برد مینویسد.
یک پروژه بسازید و SDK را اضافه کنید:
```sh
mkdir flova-esp32
cd flova-esp32
pio project init --board esp32dev
```
این محیط را به `platformio.ini` اضافه کنید:
```ini
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
lib_deps = flova-platform/FlovaSDK@^0.3.12
```
فایل `src/main.cpp` را با این کد جایگزین کنید:
```cpp
#include
#include
FlovaUniversalEsp32 device;
void setup() {
Serial.begin(115200);
device.begin();
}
void loop() {
device.run();
}
```
برد را وصل و بارگذاری کنید:
```sh
pio run -t upload
pio device monitor -b 115200
```
اگر PlatformIO برد را پیدا نکرد، مقدار `upload_port` را در `platformio.ini` با
درگاه Serialی که سیستمعامل به برد داده تنظیم کنید.
## ۳. دستگاه را بسازید و راهاندازی کنید [#۳-دستگاه-را-بسازید-و-راهاندازی-کنید]
در [صفحهٔ دستگاههای Console](https://console.flova.ir/devices)، قالب `ESP32
LED` را باز کنید، **افزودن دستگاه** را بزنید، نام وارد کنید و دستگاه را بسازید.
Console یک QR code و کد فعالسازی دستی نشان میدهد.
به [Web App Flova](https://pwa.flova.ir/) بروید، وارد شوید، **افزودن دستگاه**
را بزنید و QR code را اسکن کنید. اگر دوربین در دسترس نیست، گزینهٔ فعالسازی
دستی را انتخاب کنید.
برد تازه شبکهای با نامی شبیه `Flova-Setup-*` میسازد. وقتی Web App در حالت
راهاندازی است:
۱. تلفن یا رایانه را به `Flova-Setup-*` وصل کنید.
۲. به Web App برگردید.
۳. نام و رمز Wi-Fi معمول را وارد کنید.
۴. فرم راهاندازی را بفرستید.
۵. تلفن یا رایانه را دوباره به شبکهٔ معمول وصل کنید.
برد نتیجه را ذخیره، راهاندازی دوباره و به Flova وصل میشود. در Console وضعیت آن باید از
راهاندازی و sync به Online برسد.
## ۴. LED را آزمایش کنید [#۴-led-را-آزمایش-کنید]
در [Studio](https://studio.flova.ir/) یک Dashboard برای قالب `ESP32 LED` بسازید.
یک کلید دوحالته اضافه کنید، آن را به `LED داخلی` وصل کنید و Dashboard را منتشر
کنید.
دستگاه را در Web App Flova باز کنید و کلید دوحالته را تغییر دهید. LED باید
همان تغییر را نشان دهد. اگر تغییر نکرد:
- مطمئن شوید نسخهٔ نوع دستگاه منتشر شده است.
- بررسی کنید Dashboard از همان قالب `ESP32 LED` استفاده میکند.
- کلید فنی را دقیقاً `LED` بررسی کنید.
- وضعیت و timeline دستگاه را در Console ببینید.
- هنگام راهاندازی اولیه، مرورگر را به شبکهٔ راهاندازی متصل نگه دارید.
## رفتن به Custom Firmware [#رفتن-به-custom-firmware]
Universal Firmware برای اولین دستگاه و محصولی مناسب است که ترکیب کامل آن
را Flova مدیریت میکند. وقتی برنامه باید مالک Wi-Fi، GPIO، حسگرها، Web Server یا
کانال راهاندازی دیگری باشد، از `FlovaEsp32` استفاده کنید.
```cpp
#include
#include
#include
FlovaEsp32 device;
auto relay = FLOVA_DATASTREAM(device, bool, "relay");
void setRelay(bool enabled) {
digitalWrite(2, enabled ? HIGH : LOW);
}
void setup() {
pinMode(2, OUTPUT);
WiFi.begin("your-wifi", "your-password");
FLOVA_ON_WRITE(relay, setRelay);
device.begin();
}
void loop() {
device.run(WiFi.status() == WL_CONNECTED);
}
```
برای ادامه، [Datastreamها](./datastreams)، [Provisioning](./provisioning) و
[Transportها](./transports) را بخوانید.
# مرجع عمومی API (/fa/docs/sdk/reference)
این صفحه سطح عمومی برنامه را که در راهنماها استفاده شده فهرست میکند. برای
امضای دقیق و Overloadهای مخصوص هر Target، Headerهای ارائهشده در نسخهٔ
FlovaSDK را ببینید. به Classها و Typeهای داخلی که در این صفحه نیامدهاند
وابسته نشوید.
## Facadeهای برد [#facadeهای-برد]
| Type | کاربرد |
| --- | --- |
| FlovaEsp32 | برنامهٔ سفارشی ESP32 با Flova Link یا MQTT اختیاری. |
| FlovaEsp8266 | برنامهٔ سفارشی ESP8266 با همان مدل Typeدار Datastream. |
| FlovaUniversalEsp32 | ترکیب کامل ESP32 با Provisioning و رفتار Device تحت مدیریت Flova. |
| FlovaUniversalEsp8266 | ترکیب کامل ESP8266. |
| FlovaLinux | Process دستگاه در Linux یا Raspberry Pi. |
| flova::Device | هستهٔ قابل انتقال برای برد یا Gateway سفارشی. |
## متدهای چرخهٔ اجرا [#متدهای-چرخهٔ-اجرا]
| متد | کاربرد |
| --- | --- |
| begin() | Facade انتخابشده را آماده میکند و Session را بازیابی یا آغاز میکند. |
| run() | یک گام محدود از Connection، Configuration و پردازش فرمان را انجام میدهد. |
| connected() | وضعیت فعلی Connection مربوط به Transport را گزارش میکند. |
| datastream<T>(key) | یک مرجع Typeدار برای Datastream میدهد. |
| value() | مقدار موجود در Cache محلی را میخواند. |
| write(value) | یک فرمان محلی از طرف برنامه را اعمال میکند. |
| report(value) | مشاهدهٔ حسگر یا وضعیت واقعی Hardware را Report میکند. |
| onWrite(handler) | Handler مرز Hardware برای فرمان راه دور را ثبت میکند. |
## توابع کمکی Arduino [#توابع-کمکی-arduino]
~~~cpp
FLOVA_DATASTREAM(device, bool, "relay")
FLOVA_SETTING(device, double, "threshold", 35.0)
FLOVA_ON_WRITE(relay, setRelay)
FLOVA_WRITE(relay, true)
FLOVA_READ(relay)
FLOVA_REPORT(temperature, 23.4f)
FLOVA_HAS_VALUE(relay)
~~~
توابع کمکی را پس از تعریف Device و پیش از begin() استفاده کنید.
کلید فنی را در یک محل ثابت نگه دارید تا بین Firmware و Template تغییر نکند.
اگر برنامه به Type یا رفتار مخصوص Target نیاز ندارد، از
<FlovaSDK.h> شروع کنید.
## نتیجه و وضعیت نوشتن [#نتیجه-و-وضعیت-نوشتن]
flova::WriteResult وضعیتهای Accepted،
Rejected، NoChange و Failed را گزارش
میکند. وقتی برنامه باید بداند مقدار واقعاً پذیرفته شده است یا نه، نتیجه را
بررسی کنید. فرمان ردشدهٔ Hardware نباید وضعیت برنامه یا SDK را بهطور بیصدا
تغییر دهد.
Typeهای عمومی مقدار شامل Boolean، int64_t، float،
double و متن محدود هستند. Enumهای عمومی Lifecycle و Diagnostic
در Headerهای SDK تعریف شدهاند. به Protocolهای تولیدشده یا Classهای خصوصی
Adapter وابسته نشوید.
## متدهای وضعیت [#متدهای-وضعیت]
برنامههای سفارشی Arduino میتوانند بدون ورود به پیادهسازی Transport، مرزهای
چرخهٔ اجرا را بررسی کنند:
| متد | کاربرد |
| --- | --- |
| networkConnected() | Network برنامه در دسترس است. |
| tlsReady() | پیشنیازهای TLS یا Transport امن آماده هستند. |
| runtimeReady() | Runtime احراز هویتشدهٔ Flova آماده است. |
| ready() | Facade برای کار عادی Device آماده است. |
| status(output) | یک نمای لحظهای محدود برای Diagnostic مینویسد. |
| setStatusListener(...) | تغییرهای Lifecycle را مشاهده میکند. |
| startProvisioning() | Session Flova را پاک و منتظر Handoff تازه میماند. |
| factoryReset() | وضعیت خصوصی Flova را از مسیر Facade بازنشانی میکند. |
وضعیت برای نشانگر محصول یا صفحهٔ Maintenance مفید است، اما جای Accepted
Command یا Telemetry تازه را نمیگیرد.
## متدهای Firmware و توان [#متدهای-firmware-و-توان]
Facadeهای Target ممکن است این عملیات Lifecycle را ارائه کنند:
| متد | کاربرد |
| --- | --- |
| setFirmwareTarget(target) | شناسهٔ Target گزارششدهٔ Image را تعیین میکند. |
| enableOta(enabled) | مسیر OTA مربوط به Target را فعال یا غیرفعال میکند. |
| setOtaProfile(...) | روش OTA و Boot Layout را مشخص میکند. |
| setRestartHandler(...) | اجرای Restart را به برنامه میسپارد. |
| restartRequired() | بررسی میکند Runtime به Restart نیاز دارد یا نه. |
| prepareForPowerDown() | پیش از Sleep یا قطع برق کار SDK را آرام میکند. |
فقط از متدهای Target انتخابشده استفاده کنید. Service Supervisor در Linux،
Boot Layout در ESP32 و Staged Update در ESP8266 مرزهای مالکیت یکسانی ندارند.
## مدیریت نتیجهها [#مدیریت-نتیجهها]
~~~cpp
const flova::WriteResult result = FLOVA_REPORT(sensor, value);
if (!result.accepted()) {
logReportFailure(result.status, result.reason);
}
~~~
نتیجهٔ Accepted یعنی SDK عملیات را در مرز خودش پذیرفته است. در MQTT همچنان
run() را اجرا کنید و Latest Value یا History را در Console
بررسی کنید. در نوشتن Hardware، Accepted باید به معنی پذیرفته شدن وضعیت واقعی
توسط Handler محصول باشد.
## انتخاب Header [#انتخاب-header]
| Include | کاربرد |
| --- | --- |
| <FlovaSDK.h> | برنامههای سادهٔ Arduino و نقطهٔ ورود عمومی. |
| <FlovaEsp32.h> | دسترسی مستقیم به Facade مربوط به ESP32. |
| <FlovaEsp8266.h> | دسترسی مستقیم به Facade مربوط به ESP8266. |
| <FlovaUniversalEsp32.h> | ترکیب مستقیم Universal برای ESP32. |
| <FlovaUniversalEsp8266.h> | ترکیب مستقیم Universal برای ESP8266. |
| <FlovaLinux.h> | برنامههای Device در Linux. |
| <FlovaDevice.h> | اتصالهای قابل انتقال به هسته. |
تا وقتی به Constructor یا متد مخصوص Target نیاز ندارید، Header عمومی
<FlovaSDK.h> را ترجیح دهید.
# Transportها و Connection (/fa/docs/sdk/transports)
Transport دادههای Identity، فرمان، Report، Configuration و Presence را میان
دستگاه و Flova جابهجا میکند. انتخاب Transport به شیوهٔ استقرار مربوط است و
نباید کلیدهای Datastream، نوع مقدار، Handlerهای Hardware یا قرارداد Dashboard
را تغییر دهد.
مسیر پیشفرض و بومی **Flova Link** است. MQTT زمانی مناسب است که محصول از قبل
MQTT Client، Gateway یا ابزارهای عملیاتی مبتنی بر Broker داشته باشد. در هر دو
مسیر باید Network، Connection احراز هویتشده، اتصال به Template، Report
پذیرفتهشده، Latest Value و History را جداگانه بررسی کنید.
## Flova Link [#flova-link]
FlovaEsp32 و FlovaEsp8266 بهصورت پیشفرض از Flova Link
استفاده میکنند. SDK Session احراز هویتشدهٔ Device، پیامهای محدود، اتصال
Datastreamها، Cache محلی، رساندن فرمان و Connection دوباره را مدیریت میکند.
برنامه بسته به Facade انتخابشده مالک Wi-Fi، Ethernet، GPIO، حسگرها، سیاست
توان و کارهای طولانی است.
~~~cpp
FlovaEsp32 device;
auto relay = FLOVA_DATASTREAM(device, bool, "relay");
void loop() {
serviceHardware();
device.run();
}
~~~
برقرار بودن Link به معنی آماده بودن همهٔ Datastreamها نیست. پس از پذیرفته شدن
Runtime و Template منتشرشده، به مقدار بازیابیشده تکیه کنید. هنگام بررسی مقدار
گمشده، کلید دقیق، نوع مقدار، نتیجهٔ Report، Latest Value و History را در
Console کنترل کنید.
## Wi-Fi با Flova Link [#wi-fi-با-flova-link]
Universal Firmware در ESP32 و ESP8266 میتواند مسیر راهاندازی Wi-Fi را
مدیریت کند. در برنامهٔ سفارشی، این مالکیت با خود برنامه است:
~~~cpp
#include
#include
FlovaEsp32 device;
void setup() {
WiFi.begin("your-wifi", "your-password");
device.begin();
}
void loop() {
device.run(WiFi.status() == WL_CONNECTED);
}
~~~
اطلاعات Wi-Fi را در Source Code ثبت نکنید. برنامه باید برای نبودن Network،
تغییر Access Point و دستگاهی که هنوز Provisioning نشده است، رفتار مشخصی
داشته باشد. SDK میتواند Connection Flova را دوباره برقرار کند، اما نمیتواند
Credential معتبر بسازد یا مشکل آنتن، برق، DHCP یا Radio را برطرف کند.
اگر محصول Captive Portal یا Web Server خودش را دارد، همان مسیر را در برنامه
نگه دارید و پس از پایان آن، Provisioning Handoff Flova را به SDK بدهید. بعد
از Commit شدن Handoff، منابع موقت راهاندازی را ببندید و Telemetry عادی را
شروع کنید.
## Ethernet با Flova Link [#ethernet-با-flova-link]
Ethernet برای نصبهای ثابت، برق پایدار یا شبکههایی مناسب است که Wi-Fi را
اجازه نمیدهند. در پروژهٔ ESP32 با LAN8720، Facade مربوط به Ethernet شبکه را
برای FlovaEsp32Ethernet فراهم میکند و برنامه تنظیمات PHY و
راهاندازی وابسته به برد را تعیین میکند.
~~~cpp
FlovaEsp32Ethernet device(EthernetConfig{
.phyAddress = 1,
.powerPin = 16,
.clockMode = ETH_CLOCK_GPIO0_IN,
});
~~~
نام Constructor با Target انتخابشده فرق میکند. پیش از انتخاب Boot Pin، پایههای
RMII، کنترل برق، DHCP و Clock مربوط به PHY را از Schematic برد بررسی کنید.
کامپایل موفق، وجود Link فیزیکی، دریافت IP، آماده بودن TLS یا پذیرفته شدن
فرمان Hardware را ثابت نمیکند.
اگر برد از Chip Ethernet یا TCP/IP Stack دیگری استفاده میکند، Driver را بیرون
از لایهٔ Datastream نگه دارید. از Facade پشتیبانیشده یا یک Link Adapter
محدود استفاده کنید و کد Datastream را به Driver وابسته نکنید.
## MQTT؛ مسیر کامل از Client تا Flova [#mqtt-مسیر-کامل-از-client-تا-flova]
MQTT یک Transport سازگار اختیاری است. وقتی محصول از قبل MQTT Client دارد،
Gateway ترافیک Device را از MQTT عبور میدهد یا تیم عملیات Broker و ابزار
پایش مخصوصی دارد، این انتخاب منطقی است. در عوض، مسئولیتهای Network، TLS،
Broker و Reconnect با برنامه میماند؛ بنابراین MQTT را آگاهانه انتخاب کنید.
برنامه مالک Wi-Fi یا Ethernet Client، DNS، طول عمر Socket، Trust Store مربوط
به TLS، MQTT Client، سیاست Reconnect و Watchdog محلی است. SDK Topicهای Flova،
Presence، دریافت فرمان، قالب JSON مربوط به Datastream، صف محدود و اتصال این
مسیر به Facade نوعدار را فراهم میکند.
~~~cpp
#include
#include
#include
WiFiClientSecure socket;
PubSubClient mqtt(socket);
FlovaEsp32 device(mqtt);
void setup() {
socket.setCACert(FLOVA_ROOT_CA);
mqtt.setServer("mqtt.flova.ir", 8883);
device.begin(deviceId, deviceSecret);
}
void loop() {
maintainWifi();
device.run();
}
~~~
در MQTT نام کاربری، UUID دستگاه و گذرواژه، Secret همان دستگاه است. نشانی
Broker برابر mqtts://mqtt.flova.ir:8883 است. بررسی Certificate را
روشن نگه دارید. Workspace API Key گذرواژهٔ Device نیست و نباید در Firmware یا
Bundle مربوط به Dashboard قرار بگیرد.
Device فقط در سمت up منتشر میکند و در سمت down مشترک
میشود. SDK Topicها و Envelope مستند Flova را مدیریت میکند. برنامه باید
Datastream و Handler نوعدار ثبت کند و فقط وقتی به Message API سطح پایین برود
که یک نیاز واقعی محصول با Facade عمومی قابل بیان نباشد.
### زنجیرهٔ Connection در MQTT [#زنجیرهٔ-connection-در-mqtt]
موفق شدن MQTT یک مرحلهٔ واحد نیست. ابتدا Wi-Fi یا Ethernet باید مسیر Network و
IP قابل استفاده بسازد. سپس DNS، TCP، بررسی Certificate در TLS و Session MQTT
باید موفق شوند. بعد SDK Identity دستگاه را احراز میکند، Session را بازیابی
میکند، Template منتشرشده را میخواند و مسیر فرمان و Report را آماده میسازد.
این مراحل را در Diagnostic جدا نگه دارید. Socket باز فقط وجود مسیر Network را
ثابت میکند. Presence نشان میدهد Session با Broker برقرار است. Runtime Ready
یعنی Identity دستگاه پذیرفته شده است. Datastream Ready یعنی کلیدهای تعریفشده
با Template تطبیق دارند. Accepted Report یعنی یک مقدار مشخص از اعتبارسنجی
عبور کرده و وارد مسیر Transport شده است. Latest Value و History رسیدن داده به
مسیر ذخیرهسازی Flova را نشان میدهند.
### حلقهٔ MQTT و Connection دوباره [#حلقهٔ-mqtt-و-connection-دوباره]
device.run() را در حلقهٔ عادی و همکارانهٔ برنامه اجرا کنید. آن را
فقط پس از تغییر حسگر صدا نزنید و پشت تأخیر طولانی قرار ندهید. SDK برای دریافت
فرمان، پیش بردن Reconnect، انتشار Presence و تخلیهٔ صف به اجرای مرتب نیاز دارد.
نگهداری Wi-Fi یا Ethernet را از منطق Datastream جدا کنید. Reconnect نباید
Cache محلی یا خروجی Hardware را پاک کند، مگر آنکه محصول عمداً چنین سیاستی
داشته باشد. پس از Connection دوباره، بررسی کنید سیاست Stream مقدار پذیرفتهشدهٔ
قبلی را بازیابی میکند یا به Report تازه از Hardware نیاز دارد.
هنگام قطع Broker، برنامه را پاسخگو نگه دارید و وضعیت Offline محدودی نمایش
دهید. در حلقهٔ Reconnect بینهایت سریع نچرخید. Backoff و Watchdog مناسب Target
را رعایت کنید و هنگام توسعهٔ TLS، حافظه یا Broker، مسیر Upload سیمی را نگه
دارید.
### اندازهٔ پیام و صف MQTT [#اندازهٔ-پیام-و-صف-mqtt]
اندازهٔ هر پیام MQTT دستگاه حداکثر ۲٬۰۴۸ بایت است. Report بزرگتر از این
حد، پیامی که هنگام در دسترس نبودن Adapter تولید شود یا پیامی که صف محدود را
پر کند، نتیجهٔ خطا میدهد. پذیرفته شدن Enqueue فقط یعنی SDK پیام را محلی
قبول کرده است؛ رسیدن آن به Broker، Engine، Latest Value یا History را ثابت
نمیکند.
برای مقدارهای مستقل از Datastreamهای نوعدار جدا استفاده کنید و با نرخ
معقول Report بفرستید. متن و فیلدهای JSON غیرضروری را از Template حذف کنید.
با کوتاه کردن بیصدا یا بریدن مقدار، مشکل اندازه را پنهان نکنید. خطای محدود
ثبت کنید و وقتی Report وارد صف نمیشود، وضعیت پذیرفتهشدهٔ قبلی را نگه دارید.
### امنیت و مالکیت MQTT [#امنیت-و-مالکیت-mqtt]
از TLS و Identity مخصوص هر Device استفاده کنید. Secret دستگاه را در Storage
انتخابشده محافظت کنید و آن را در Log، صفحهٔ وضعیت، Payload MQTT یا Diagnostic
Provisioning چاپ نکنید. تعویض Identity باید از مسیر رسمی Provisioning یا
Maintenance محصول انجام شود.
MQTT Client متعلق به برنامه است. Buffer، Keepalive، محدودیت Callback و زمان
Reconnect را با حافظه و بودجهٔ توان Target هماهنگ کنید. Callback باید کوتاه
باشد؛ کار را به حلقهٔ برنامه بسپارد و داخل Callback به حسگر، File یا درخواست
طولانی Network دست نزند.
## Bluetooth و کانالهای Provisioning [#bluetooth-و-کانالهای-provisioning]
Bluetooth معمولاً کانال راهاندازی است، نه Transport دائمی Telemetry. مسیر
BLE در ESP32 میتواند Provisioning Handoff کوتاهعمر را حمل کند، در حالی که
Pairing، قالب پیام، Timeout و تعامل کاربر در اختیار برنامه است. پس از پذیرش
ماندگار Handoff، منابع BLE را آزاد کنید و Wi-Fi، Ethernet، Flova Link یا
MQTT را برای کار عادی شروع کنید.
همین مرز برای Serial، ابزار Factory یا صفحهٔ راهاندازی محلی Ethernet هم
برقرار است. کانال راهاندازی فقط Handoff محدود را منتقل میکند و جای
Connection احراز هویتشدهٔ زمان اجرا را نمیگیرد. Activation Token را در Log
ثبت نکنید و در هر Boot دوباره نفرستید.
## مستقل نگه داشتن کد برنامه از Transport [#مستقل-نگه-داشتن-کد-برنامه-از-transport]
Datastreamها و Handlerها را یکبار تعریف کنید و سپس Constructor مناسب استقرار
را انتخاب کنید:
~~~cpp
auto temperature = FLOVA_DATASTREAM(device, float, "temperature");
auto relay = FLOVA_DATASTREAM(device, bool, "relay");
void loop() {
FLOVA_REPORT(temperature, readTemperature());
device.run();
}
~~~
کلیدها، Typeها، Callbackها، Cache محلی و قرارداد Dashboard با تغییر Transport
عوض نمیشوند. راهاندازی Wi-Fi، پیکربندی Ethernet، Certificateهای TLS،
ساخت MQTT Client و Provisioning با Bluetooth باید بیرون از منطق Datastream
بماند.
## مرزهای آمادگی Connection [#مرزهای-آمادگی-connection]
برای رابط محصول و Diagnostic این مرزها را جدا نمایش دهید:
| بررسی | چه چیزی را ثابت میکند؟ |
| --- | --- |
| Network Ready | Wi-Fi یا Ethernet شرایط لازم برنامه را دارد. |
| Transport Connected | Flova Link یا Session مربوط به MQTT برقرار است. |
| Runtime Ready | Identity دستگاه و Runtime Flova احراز شده است. |
| Datastream Ready | کلیدهای تعریفشده به Template منتشرشده متصل شدهاند. |
| Accepted Report | یک مقدار مشخص اعتبارسنجی شده و وارد مسیر Transport شده است. |
| Latest Value و History | مقدار به مسیر دادهٔ Flova رسیده و طبق انتظار ذخیره شده است. |
برای نشانگرها از متدهای وضعیت Facade یا Status Listener استفاده کنید. برچسب
«متصل» را فقط به دلیل باز شدن Socket سبز نکنید.
## انتخاب Transport [#انتخاب-transport]
برای Connection عادی و کمترین مسئولیت برنامه از Flova Link استفاده کنید. MQTT
را زمانی انتخاب کنید که محصول از قبل MQTT Client یا مسیر Broker دارد. اگر
برد یا Gateway حامل محدود دیگری دارد، یک Link Adapter با مرز عمومی SDK
بسازید. flova::Device قابل انتقال را به APIهای Arduino و Network
وابسته نکنید.
تغییر Transport، Template در Console را تغییر نمیدهد؛ فقط Connection دستگاه،
مالکیت سرویسهای Network و بررسیهای عملیاتی زمان استقرار را تغییر میدهد.
# نمای کلی استودیو (/fa/docs/studio/overview)
در استودیو داشبورد بسازید.
# Account (/en/docs/app/account)
The app needs a Flova account to show your devices and dashboards.
## Sign in [#sign-in]
The app opens **Secure sign-in with Flova** in your browser. Complete the sign-in
there and return to the app. If sign-in does not finish, keep the browser
window open and read the displayed error.
After sign-in, devices added to your account appear in the Devices view. Team
workspace settings and device creation are managed in [Console](../../console/overview).
## Profile and sign-out [#profile-and-sign-out]
Open **Account** in the app navigation to see your display name and registered
phone number. Choose **Sign out** to end the session.
After signing out, you must sign in again to view devices and dashboards. Do not
share sign-in details or activation codes.
# Alerts and notifications (/en/docs/app/alerts)
The **Alerts** view shows important events from your devices and automations.
Choose **Alerts** from the app navigation to open it.
Unread alerts are marked beside the Alerts section. Open an item to see its
message, device, and event time. Refresh the list to load newer items.
## Enable browser notifications [#enable-browser-notifications]
Open notification management on the Alerts page and choose **Enable
notifications**. Your browser will ask for permission. Allow it if you want
alerts while the page is closed.
If you previously blocked notifications, allow them for this site in your
browser settings and return to the app. If push notifications are unavailable
in your browser or device, alerts remain available in the app.
Browser notifications do not replace the Alerts page. Open the alert list when
you need the full message and event time.
# Dashboards (/en/docs/app/dashboards)
A dashboard is an experience created and published by the product owner in
Studio. Open a device from the **Devices** view to see its dashboard.
## Published dashboards [#published-dashboards]
The app loads the published version. Studio draft changes do not appear in the
app until a new version is published.
A dashboard can include current values, charts, text, connection status,
toggles, commands, or other pages. What you see depends on the device type and
the dashboard design.
## Read and change values [#read-and-change-values]
Device values update when new data arrives. To control a value or command,
choose the matching control in the dashboard and wait for the result. A change
may not be applied when the device is offline or the channel is not writable.
Some dashboards also include data history, queries, or scheduling. These options
appear only when the product owner adds them to the published version.
## If the dashboard is missing [#if-the-dashboard-is-missing]
Check that the device is online and that your internet connection works. Then
reopen the device page. If there is still no dashboard, the product owner must
check the published version and its device type in Studio.
# Devices (/en/docs/app/devices)
The **Devices** view lists devices added to your app account. From here you can
open a device, search by name, and manage device groups when that feature is
available.
## Add a device [#add-a-device]
1. Open the [Flova app](https://pwa.flova.ir/) and sign in.
2. Choose **Add device**.
3. Scan the activation QR code on the device or its packaging with your
browser camera.
4. If scanning is not possible, choose **Enter manually** and enter the
activation code.
5. Name the device and choose **Confirm and activate**.
The activation code adds the device to your user account. Wi-Fi setup and the
device's later connection to Flova are separate steps.
## Find and open a device [#find-and-open-a-device]
Search by device name or filter the list by group. A device card shows its
current status and connection information. Open the card to view its
dashboard.
If the device is still being set up, complete [Device setup](../setup). An
online status only means that the device has reported recent presence. It does
not by itself prove that every channel has reported a current value.
## Manage a device [#manage-a-device]
Depending on the available actions, the device menu lets you rename a device,
remove it from your account, or start a factory reset. Read the confirmation
text before removing or resetting a device. A factory reset can change the
device's network settings and connection state.
See [Devices in Console](../../console/devices) to create devices and issue
activation QR codes.
# App overview (/en/docs/app/overview)
The Flova app is your user space for connected devices. Open
`https://pwa.flova.ir/` in a browser, sign in, add a device to your account, and
open its published dashboard.
The app is currently available on the web through the Flova PWA. Use
[Console](../../console/overview) and [Studio](../../studio/overview) to create
device types and dashboards. End users use the app to claim devices and use the
published experience.
## User space and workspace [#user-space-and-workspace]
The app is your user space. Devices that you add with an activation QR code or
manual code appear in your account. The workspace in Console and Studio belongs
to the team that creates the device type, data, and dashboard.
Saving a Studio draft does not make a dashboard visible to users. The dashboard
must be published before the app can load it.
# Quick start (/en/docs/app/quickstart)
Follow these steps the first time you use the Flova app:
1. Open the [Flova app](https://pwa.flova.ir/).
2. Sign in with your Flova account.
3. Choose **Add device** and scan the activation QR code. If the camera is not
available, enter the activation code manually.
4. Give the device a recognizable name and confirm activation.
5. If the device needs network setup, follow [Device setup](../setup).
6. Open the device and view its published dashboard.
The app only shows published dashboards. If the device is available but no
dashboard appears, ask the product owner to publish a dashboard version in
Studio.
## Before you start [#before-you-start]
- Get the device activation QR code or manual code from the product owner.
- For Wi-Fi setup, your phone or computer must be able to switch between the
internet and the device's temporary setup network.
- An internet connection is required to load dashboards and receive current
values.
See [Devices](../devices), [Device setup](../setup), and [Dashboards](../dashboards)
for details about each step.
# Device setup (/en/docs/app/setup)
After you add a device, the app shows its setup state. The steps depend on the
device connection method.
## Wi-Fi setup [#wi-fi-setup]
1. Open **Device setup** on the device page.
2. Connect your phone or computer to the network whose name starts with
`Flova-Setup-`.
3. Return to the app and enter the name and password of your usual Wi-Fi
network.
4. Choose **Set up device** and wait for the device to accept the details.
5. Switch your phone or computer back to its normal Wi-Fi network and the
internet.
The app opens the device's local setup page. After the device accepts the
details, it reboots and the app checks its connection state.
## Ethernet setup [#ethernet-setup]
If the device is prepared for Ethernet, the app does not ask for Wi-Fi details.
Check the device cable and internet connection, then wait for its status to
update automatically.
## If setup does not finish [#if-setup-does-not-finish]
- Make sure the browser is still connected to `Flova-Setup-*`.
- If the local page does not open, check the browser's local network access.
- After the device accepts the details, keep it powered until the reboot ends.
- After returning to the internet, wait for the runtime status check to finish.
The app does not open a cached dashboard while the device is offline. If the
status does not change after internet access returns, see
[Troubleshooting](../troubleshooting).
# Troubleshooting (/en/docs/app/troubleshooting)
## Sign-in does not finish [#sign-in-does-not-finish]
Check your browser and complete Flova's secure sign-in flow. If the session has
expired, sign out and sign in again. If the error continues, keep the time and
visible error message for support.
## The QR code is not scanned [#the-qr-code-is-not-scanned]
Allow camera access for the browser, keep the full QR code clear and inside the
scanner, and try again. If the camera is unavailable, choose **Enter manually**
and get the activation code from Console or the product owner.
## The device does not connect to the network [#the-device-does-not-connect-to-the-network]
For Wi-Fi setup, check that the device and browser are at the correct step:
- The browser must be connected to `Flova-Setup-*`.
- Enter the usual Wi-Fi name and password exactly.
- Keep the device powered until its reboot finishes after accepting the details.
- Return your computer or phone to the internet and wait for the status check.
For Ethernet, check the cable and the device's internet access.
## The dashboard is missing or a value does not change [#the-dashboard-is-missing-or-a-value-does-not-change]
Check that the device is online and your internet connection works. The app
loads only published dashboards, so the product owner must check the published
version and device type in Studio. A control also needs a writable channel, and
the device must be able to receive and apply the command.
## I do not receive notifications [#i-do-not-receive-notifications]
Check the browser permission for `pwa.flova.ir`. If push notifications are not
available, review alerts from the **Alerts** view in the app.
For template, device, or dashboard problems, send support the device name, event
time, and visible message. Do not send activation codes, passwords, or Wi-Fi
credentials.
# Automations and alerts (/en/docs/console/automations)
An automation is a graph attached to a device template. It starts from a trigger, can check a condition, and then runs one or more actions. Edit it from the template's **Automations** page.
## Build an automation [#build-an-automation]
1. Open [Console](https://console.flova.ir/templates), select a template, and open **Automations**.
2. Add a trigger and choose the channel or schedule that starts the rule.
3. Add a condition when the action should run only for a specific value.
4. Add an action such as a channel write, webhook request, or notification.
5. Connect the nodes in the direction of execution.
6. Save the graph, then publish the template version.
The editor has these node types:
| Node | Purpose |
| --- | --- |
| Datastream update | Starts when a channel changes. Choose any change, rising, or falling. |
| Schedule | Starts once, daily, or weekly at a selected time. |
| Channel check | Compares a channel with a value. |
| Channel write | Writes a value or toggles a writable channel. |
| Webhook request | Sends an HTTP request to a configured URL. |
| Notification | Creates an alert with a title and message. |
## Use a channel trigger [#use-a-channel-trigger]
Select **Datastream update**, choose a channel, and choose the trigger mode:
- **Any change** runs for every accepted update.
- **When activated** runs when a Boolean value becomes true.
- **When deactivated** runs when a Boolean value becomes false.
Use a channel trigger for events such as a door opening or a temperature report changing. If you need a time based rule, use **Schedule** instead.
## Check a value [#check-a-value]
Add **Channel check** after the trigger. Choose a channel, an operator, and a comparison value. Supported comparisons include equal, not equal, greater than, greater than or equal, less than, less than or equal, and changed to. Connect the condition's output to the action that should run when it passes.
Use a condition that matches the channel type. A numeric comparison cannot evaluate a text or structured object as a number. A Boolean condition should use `true` or `false`.
## Write to a channel or send an alert [#write-to-a-channel-or-send-an-alert]
For **Channel write**, choose a writable channel and either set a value or toggle the current value. The channel must allow writing in its published definition. A read-only channel makes the automation invalid.
For **Notification**, enter a title and message. The notification is shown in Console's notification center. A **Webhook request** sends an HTTP request to the URL in the node. Keep the endpoint available and check its authentication requirements before enabling the rule.
## Versioning and validation [#versioning-and-validation]
Automation changes are stored with the template version. Saving the graph updates the editable version; it does not make the new rule active until you publish that version.
Before publication, Console validates that:
- every node has the fields required for its type;
- every channel still exists in the template;
- a write action points to a writable channel;
- connections form a usable path from a trigger to an action;
- values match the selected channel type.
An invalid node is marked in the editor and the validation message explains what to fix. If a channel was renamed or removed, update the automation to use its new key. Publishing an older template version can also leave a rule pointing at a channel that is absent from that version.
See [Datastreams](./datastreams) for access modes and [Templates and versions](./templates) for publication behavior. Use [FlovaQL](https://console.flova.ir/flovaql) when a rule needs a query rather than a single channel comparison.
# Plans and billing (/en/docs/console/billing)
The **Plans and billing** page shows the active plan, billing period, resource usage, and available add-ons. Billing belongs to the workspace, so the values apply to the team's shared resources.
## Read usage [#read-usage]
Open [Settings > Billing](https://console.flova.ir/settings/billing). The usage card reports the current value and limit for:
| Meter | What it counts |
| --- | --- |
| Active devices | Devices counted against the workspace's active device capacity |
| Telemetry | Telemetry readings counted in the current period |
| Team members | Members in the workspace |
| Templates and dashboards | The resources counted by the plan's shared limit |
| MCP calls | MCP tool calls in the current 30-day period |
| AI credits | Included and purchased FlovaAI credit remaining |
The page also shows the period end and the current plan status. Read a meter as `current from limit`; the progress bar is a visual version of the same values.
Telemetry warnings appear when consumption reaches 80 percent or more. Reaching the displayed telemetry limit does not immediately stop the data path, but it is a signal to review the plan before the next period.
## Change a plan [#change-a-plan]
Only the workspace owner or a role with billing management permission can change the plan or buy an add-on. Select a paid plan in the pricing section and complete the payment flow. A paid plan cannot be downgraded before the current period ends.
If the payment succeeds, the plan or add-on becomes active after the payment is confirmed. If payment fails, Console does not add the amount to the workspace and shows a retry path.
## Buy an add-on [#buy-an-add-on]
The page can offer add-ons for:
- 100 FlovaAI credits with no expiration;
- five devices for 30 days, when the workspace uses a paid plan.
Console allows up to 10 active device add-on packages at a time. Check the billing message if it rejects another package.
Extra usage is not charged automatically. Review the meter and plan before adding devices or increasing telemetry traffic.
## Troubleshoot a limit [#troubleshoot-a-limit]
- **Device creation is blocked:** review active devices and the effective device limit, including add-ons.
- **A team invitation is rejected:** review the team member limit and current invitations.
- **A template or dashboard cannot be created:** review the shared templates and dashboards meter.
- **An MCP tool call is rejected:** review the MCP calls meter and the plan's 30-day quota.
- **FlovaAI stops responding:** review the remaining AI credits.
- **The purchase button is unavailable:** check that you are the workspace owner or have billing management permission.
Use [Notifications](https://console.flova.ir/notifications) for quota and payment messages. Contact [Support](https://console.flova.ir/support) with the workspace and payment status when the billing page shows an error.
# Datastreams (/en/docs/console/datastreams)
A datastream is a named value that a device reports, receives, or stores. Console uses it in device details, dashboards, automations, telemetry, and FlovaQL.
## Add a datastream [#add-a-datastream]
1. Open [Console](https://console.flova.ir/templates) and select a template.
2. Open **Datastreams** and select **Add datastream**.
3. Enter a display name and a technical key.
4. Choose the value type and exchange mode.
5. Choose a hardware connection when the value belongs to a physical input or output.
6. Set the default, safe value, sampling, and other limits where the form provides them.
7. Save the datastream, then publish the template version from **Versions**.
The technical key is the stable identifier used by firmware, Studio, automations, API calls, and FlovaQL. It must start with an English letter and can contain English letters, numbers, and underscores, up to 64 characters. Use a key such as `temperature_c` or `LED`; do not use a translated label as the key.
## Choose the value and access [#choose-the-value-and-access]
| Field | Options | Use it for |
| --- | --- | --- |
| Value type | Boolean, number, text, structured object | The shape of the value sent or stored |
| Exchange mode | Read only, write only, read and write | Which side can report or change the value |
| Unit | A short label such as `°C` or `%` | Display and query context |
| Default or initial value | The value used when the channel starts | A predictable initial state |
| Safe value | The value used by the device safety behavior | A safe output when the device needs one |
Console checks the combination of hardware connection, value type, and access. Digital input and digital output channels use Boolean values. Analog input and PWM output channels use numbers. A virtual state is a read and write structured value, such as an RGB object.
Use **Read only** for a sensor that reports data. Use **Write only** for a command that the device accepts. Use **Read and write** when the device reports the current state and Flova can send a new state.
For writable channels, you can enable scheduling in the web application. This lets an end user schedule a value or command for a later time.
## Map a channel to hardware [#map-a-channel-to-hardware]
The **Connection type** selects how the firmware should handle the channel:
- **Digital input** reads a Boolean signal from a pin.
- **Digital output** writes a Boolean signal to a pin.
- **Analog input** reads a numeric ADC value.
- **PWM output** writes a numeric duty or intensity value.
- **Software status** and **software command** have no direct GPIO mapping.
- **RGB color** stores a structured color value. Its `r`, `g`, and `b` components are between 0 and 255.
Enter the board's pin reference in **Hardware pin**. The reference can be a label such as `D32`, `GPIO32`, `A0`, or `ADC1_CH4`, depending on the firmware. A pin cannot be assigned to two physical channels in the same template. If the board uses a pull-up, pull-down, or active-low circuit, set that in the channel form.
The **Hardware settings** panel also contains board-level settings. Use it for the status LED, factory reset source, and other firmware settings that are independent of a channel.
## Live values and history [#live-values-and-history]
Console shows two different kinds of data:
| View | What it answers |
| --- | --- |
| Current value | What value is available now for this device and channel? |
| History | What values and events were recorded over a selected time range? |
The current value can change without creating the history row you expect, depending on the device transport and channel behavior. Use **Monitor** to inspect current channel values, then use the history or FlovaQL path to confirm stored telemetry. A device being online only proves presence, not that a particular channel has reported a value.
## Common validation errors [#common-validation-errors]
- **Invalid key:** start with an English letter and use only English letters, numbers, and `_`.
- **Duplicate key:** every channel key in one template must be unique.
- **Wrong value type:** match Boolean channels to digital I/O, and numeric channels to analog or PWM I/O.
- **Pin already used:** assign each physical pin once, or remove the older mapping.
- **Invalid numeric range:** the maximum must be greater than the minimum, and a PWM initial value must be inside its range.
- **No change on the device:** save the channel, publish the template version, and make sure the firmware uses the same key and pin.
The [Flova Firmware repository](https://github.com/flova-platform/flova-firmware/) contains the SDK and firmware examples. [Studio](https://studio.flova.ir/) reads the published channel definition when you connect a widget.
# API and developer apps (/en/docs/console/developers)
Console has two credential types for different integrations:
- An **API key** gives a service direct access to selected Console and data operations.
- A **developer app** registers an OAuth client so another application can sign users in and request the scopes it needs.
## Create an API key [#create-an-api-key]
1. Open [Settings > API keys](https://console.flova.ir/settings/api-keys).
2. Select **New key** and enter a name.
3. Set an optional expiration date.
4. Select only the scopes the integration needs.
5. Create the key and copy it immediately.
Console shows the secret only once. Store it in a secret manager or environment variable. Do not put it in a browser bundle, a public repository, a dashboard, or a support screenshot.
Common scopes include:
| Scope | Use |
| --- | --- |
| `devices:read` and `devices:write` | Read or manage devices |
| `templates:read` and `templates:write` | Read or manage templates and mappings |
| `datastreams:read`, `datastreams:write`, and `datastreams:manage` | Read values, write values, or manage channel definitions |
| `provisioning:read` and `provisioning:write` | Read or issue activation material |
| `mqtt:manage` | Manage device MQTT connection data |
| `flovaql:read` and `telemetry:read` | Run FlovaQL and read telemetry |
Revoke a key from the API keys page when the integration is retired, the secret may have leaked, or the owner changes. Create a replacement first when you need a zero downtime rotation.
## Register an OAuth application [#register-an-oauth-application]
1. Open [Settings > Developer apps](https://console.flova.ir/settings/developer-apps).
2. Enter the application name.
3. Choose where the application runs: server or backend, browser, or mobile and desktop.
4. Select the allowed scopes.
5. For a browser app, add HTTPS redirect URIs. `localhost` is allowed for development.
6. For a native app, add a custom scheme such as `my-app://oauth/callback`.
7. Create the app and save the Client ID and any Client Secret shown.
Server applications do not use a callback URI and receive a Client Secret. Browser and native applications need at least one valid redirect URI. Deleting an application revokes its active tokens. Rotating a Client Secret makes the previous secret invalid.
Use OAuth for a user-facing integration. Use an API key for a controlled service that already has a workspace owner and needs direct scoped access.
## Continue with the developer docs [#continue-with-the-developer-docs]
- [API documentation](https://api-docs.flova.ir/) describes the HTTP contract and examples.
- [FlovaQL in Console](https://console.flova.ir/flovaql) is the query workspace for device telemetry.
- [FlovaAI in Console](https://console.flova.ir/) can help explore supported device and data operations when it is enabled for the workspace.
- The [Flova Firmware repository](https://github.com/flova-platform/flova-firmware/) documents the SDK and device side integration.
If a request is rejected, check the credential type, selected scope, active workspace, and whether the key or secret has expired or been revoked.
# Devices (/en/docs/console/devices)
Console has two useful device views. **Devices** shows the workspace's devices. A template's **Devices** page filters that list to devices connected to one template. The device remains a workspace resource, while the template supplies its channel and firmware configuration.
## Create a device [#create-a-device]
1. Open [Console](https://console.flova.ir/templates) and select the template, then open its **Devices** page. You can also use the workspace **Devices** page after selecting the active template in the sidebar.
2. Select **Add device**, then **Add one**.
3. Enter a device name. Console uses the provisioning method configured on the template.
4. Create the device and keep the activation QR or manual code available.
5. Claim the device in the [Flova web application](https://pwa.flova.ir/), then provision its network settings.
The device cannot use a template that has no published version. If the plan has reached its active device limit, Console shows a billing message before creation finishes.
## Use activation QR codes [#use-activation-qr-codes]
The QR code is for claiming a device in the web application. It is separate from Wi-Fi provisioning and from the device's later runtime connection.
From a device row, open **Activation QR** to view the current code, copy the manual activation value, or download the QR as an SVG file. A code can be unused, claimed, revoked, expired, or missing. When you issue a new code, Console immediately revokes the current code. Give the new QR to the person who will claim the device.
The web application does not need the internal transport prefix shown by the Console implementation. Use the QR scanner or the manual code displayed by Console.
## Create device batches [#create-device-batches]
To create a batch, open a template's **Devices** page, select **Add device**, then **Build batch**. On the workspace **Devices** page, first select the active template in the sidebar. Enter a name prefix and a quantity from 1 to 100. Console creates names such as `lamp-001` and downloads a ZIP of the activation QR codes.
Open **Device batch list** from the workspace Devices page to review previous batches, see unused and claimed QR counts, and download a batch's ZIP again. Keep each QR file with its physical device label so the intended user claims the right device.
## Read a device's status [#read-a-devices-status]
The device list shows its template, current state, and latest connection information. Common states include:
| State | Meaning |
| --- | --- |
| Online | A recent presence signal is available. |
| Offline | The device is not currently reporting presence. |
| Connecting or provisioning | Setup or runtime connection is still in progress. |
| Error | The device reported a problem that needs attention. |
| Disabled | Console has disabled device operations. |
| Archived | The device is outside the active list. |
Open a device to inspect its reported and desired channel values, sync status, identifiers, firmware information, and timeline. **Last connection** is a presence detail. It does not confirm that every channel has reported telemetry.
## Manage access and device actions [#manage-access-and-device-actions]
The device detail page contains actions for access reset, enabling or disabling, archiving and restoring, factory reset, and MQTT credential rotation when the current role has permission. Read the confirmation text before using a destructive action.
Use access reset when a device changes ownership or an old activation path must stop working. Use factory reset when the firmware supports the requested command and you want to return the device to its setup flow. After either action, check the timeline and wait for the device to report the resulting state.
See [Monitor](./monitor) for current values and events, and [Quick start](./quickstart) for a complete ESP32 setup.
# Live monitoring (/en/docs/console/monitor)
The **Live monitor** page belongs to a template and gives you one view of its devices. It shows online and offline counts, numeric channel trends, and device events. Open a device's detail page to compare the latest value reported by the device with the value Flova wants it to apply.
## Open the monitor [#open-the-monitor]
1. Open [Console](https://console.flova.ir/templates).
2. Select a template and open **Live monitor**.
3. Choose devices, channels, and a time range to narrow the charts and events.
4. Select **Live** for incoming updates. Refresh manually if the live connection is unavailable.
The live range covers the most recent 15 minutes. For a longer period, choose a history range. Live events arrive over a realtime connection; Console shows when that connection is unavailable.
## Read the current state [#read-the-current-state]
The monitor summary includes total, online, and offline device counts, event count, and errors in the selected range. It does not show a latest-value table for every channel. Open **Devices**, then a device, and find **Datastreams** to compare reported values, desired values, sync state, and last change time. A device can be online while a channel has no reported value.
When you are debugging a device, check these fields in order:
1. Device status and last connection.
2. The reported and desired values in the device's **Datastreams** section.
3. The channel's trend in Live monitor or its stored readings in FlovaQL.
4. The event list for provisioning, commands, errors, and presence changes.
## Inspect history [#inspect-history]
Choose a time range to review stored telemetry. Numeric channels can be compared over time, while Boolean and text channels show the values that were recorded. Use [FlovaQL](https://console.flova.ir/flovaql) when you need a filtered query, grouping, or an exportable result.
The numeric chart and event list use the selected time range. History is different from the latest-value view on a device page: history contains readings stored by the telemetry path, while device details show reported and desired runtime values. If a device is online but history is empty, check the channel key, firmware reports, selected range, and telemetry configuration.
## Read events [#read-events]
The event list includes presence changes, provisioning, administrative actions, channel updates, console writes, app writes, automation writes, device acknowledgements, applied values, and device errors. Filter by category or severity and open an event to see its structured details.
The device timeline is also available from the device detail page. It groups repeated telemetry events that are close together so a busy channel is easier to scan. Load older events when you need more history.
## Troubleshoot a missing value [#troubleshoot-a-missing-value]
- **The device is offline:** check its network, firmware logs, and the last presence event.
- **The device is online but the value is empty:** confirm the firmware reports the exact technical key from the published template.
- **A value appears on the device page but not in the chart:** the chart covers numeric series. Check the selected device, channel, and time range; use FlovaQL to inspect stored readings.
- **A write appears but the device does not change:** check the channel access mode, hardware pin mapping, firmware acknowledgement, and the event timeline.
See [Datastreams](./datastreams) for channel definitions and [Devices](./devices) for access, QR codes, and device actions.
# Remote updates (OTA) (/en/docs/console/ota)
OTA lets you publish a firmware binary and send it to compatible devices over the network. A release is the uploaded firmware package. A rollout is the operation that selects devices and sends that release.
## Publish a firmware release [#publish-a-firmware-release]
1. Open [Console](https://console.flova.ir/ota) or a template's **OTA** page.
2. Select **Create** and then **Publish OTA release**.
3. Choose a `.bin` file. Console checks the file size against the general and target device limits.
4. Let Console read the version and target from a Flova firmware package, or enable the custom file option and enter the version and target details.
5. Add release notes if needed and publish the file.
The upload has separate preparation, file upload, and release registration stages. If a stage fails, use the retry action after checking the network and the file. A file that was uploaded to storage is not a rollout until the release registration succeeds.
## Create a rollout [#create-a-rollout]
1. Select **Create** and then **Create rollout**.
2. Choose the OTA release.
3. Wait for the compatibility check to finish.
4. Choose a compatible device template. The template page opens this form with that template already selected.
5. Review the eligible devices, search by name, ID, or current firmware version, and exclude any device that should wait.
6. Choose an immediate or scheduled start.
7. Create the rollout.
Console checks the release target, boot layout, current firmware, template, and device state before enabling the rollout button. If no eligible device remains, the rollout cannot start.
## Use rollout safety settings [#use-rollout-safety-settings]
Advanced settings control how quickly the release moves through devices:
| Setting | Default in Console | Purpose |
| --- | ---: | --- |
| Batch size | 10 | Devices processed in one batch |
| Interval | 300 seconds | Wait between batches |
| Stop on failure | 20% | Pause when failed updates reach this share |
| Stop on offline | 50% | Pause when devices are unavailable at this share |
You can schedule a start time in the Tehran time zone. Legacy devices may be eligible only when you explicitly accept that they do not support automatic rollback.
## Follow and control a rollout [#follow-and-control-a-rollout]
Open the rollout row to inspect its devices, current firmware, update result, and error details. A rollout can be **scheduled**, **running**, **paused**, **completed**, **failed**, or **cancelled**.
- **Pause** stops sending to the remaining devices.
- **Resume** continues a paused rollout.
- **Cancel** stops the remaining work. Devices already updated stay updated.
- **Retry failed** creates another attempt for devices with a failed result when the rollout allows it.
Use the device list and [Monitor](./monitor) together. The rollout result describes the update operation. Monitor shows whether the device reconnects and reports after the update.
## Common errors [#common-errors]
- **No compatible template:** the release target or boot layout does not match the template's devices.
- **File rejected:** choose a `.bin` file within the general and target specific size limits.
- **No eligible devices:** the devices may be offline, already on the release, disabled, or outside the selected template.
- **Rollout pauses itself:** inspect the failure and offline thresholds before resuming.
- **The device updated but is not online:** check the device timeline, current firmware, and boot or network logs. OTA completion does not prove that the new runtime connected.
The [Flova Firmware repository](https://github.com/flova-platform/flova-firmware/) documents the firmware package and runtime side of OTA.
# Console (/en/docs/console/overview)
Console is where you manage and monitor devices in Flova. It gives you one place
to follow the devices connected to your products, review their current status,
and handle day-to-day device work. Start here when your work begins with devices,
then use the product links below to continue.
## Choose a product [#choose-a-product]
# Quick start (/en/docs/console/quickstart)
In this guide, you'll connect an ESP32 to Flova and switch its built-in LED from a dashboard. Before you begin, have an ESP32 board with an LED on `GPIO2`, a USB data cable, and a phone or computer with Wi-Fi. You can use PlatformIO or Arduino IDE to install and flash the firmware.
## 1. Create the account and device template [#1-create-the-account-and-device-template]
Open the [Flova Console](https://console.flova.ir/) and create an account. In Flova, the Device Type is the *device template* that connects the rest of the platform. Devices, dashboards, queries, automations, and everything else in the platform are connected to this template.
After you sign in, create a Device Type named `ESP32 LED` and choose Wi-Fi as its setup method.
Add one datastream with these values:
| Field | Value |
| --- | --- |
| Name | Internal LED |
| Technical key | `LED` |
| Value type | Boolean |
| Access | Read/write |
| Behavior | Digital output |
| Hardware pin | `GPIO2` |
| Active level | HIGH |
| Default and safe value | Off |
Use the technical key `LED` exactly as shown. The dashboard will use this key to reach the device later. Publish the Device Type version before you continue. Flova cannot create a device from an unpublished version.
## 2. Upload the universal firmware [#2-upload-the-universal-firmware]
Create a project folder, install the published `FlovaSDK` package, add the universal firmware code, then connect the board over USB and upload it. Choose the instructions for your tool:
See the [Flova Firmware repository](https://github.com/flova-platform/flova-firmware/) for more information and examples.
Create a folder for the project and initialize a PlatformIO ESP32 project:
```bash
mkdir flova-esp32
cd flova-esp32
pio project init --board esp32dev
```
Add `FlovaSDK` to `platformio.ini`:
```ini
[env:esp32dev]
platform = espressif32@7.0.1
board = esp32dev
framework = arduino
lib_deps = flova-platform/FlovaSDK@^0.3.12
```
Replace `src/main.cpp` with:
```cpp
#include
#include
FlovaUniversalEsp32 device;
void setup() {
Serial.begin(115200);
device.begin();
}
void loop() {
device.run();
}
```
Connect the ESP32 with a USB data cable. PlatformIO detects the serial port in most cases. If it does not, set `upload_port` in `platformio.ini` to the port assigned to your board. Then upload the firmware:
```bash
pio run -t upload
```
Create a new Arduino sketch and save it in a new project folder, for example `flova-esp32`. Before installing the SDK, open **Tools → Board → Boards Manager**, search for `esp32` by Espressif Systems, and install the ESP32 board support package. Then open **Tools → Manage Libraries**, search for `FlovaSDK`, and install it.
Select the ESP32 board that matches your hardware under **Tools → Board**, then select the USB serial port under **Tools → Port**. Replace the sketch with:
```cpp
#include
#include
FlovaUniversalEsp32 device;
void setup() {
Serial.begin(115200);
device.begin();
}
void loop() {
device.run();
}
```
Connect the ESP32 with a USB data cable and click **Upload**. Arduino IDE compiles the sketch and flashes the complete firmware image, including the bootloader and partition table.
On its first run, the firmware creates a temporary network named like `Flova-Setup-*`. You'll enter the Wi-Fi credentials during setup, so keep them out of the source code.
## 3. Create the device [#3-create-the-device]
In [Console's Devices page](https://console.flova.ir/devices), open the same Device Type and choose **Add Device**. Give the device a name and create it. Console will show a QR code and a manual activation code for the device.
## 4. Claim the device in the web application [#4-claim-the-device-in-the-web-application]
Open the [Flova web application](https://pwa.flova.ir/) and sign in. This is the *user space* for Flova. It is separate from your *workspace* in Console and Studio, where you create Device Types and dashboards. Customers and end users use the web application to claim their devices and view the dashboards you create for your products and experiences.
Choose **Add device**, scan the QR code from Console, give the device a name, and confirm.
If the camera is unavailable, choose the manual activation option and enter the code shown in Console.
The device is now assigned to the signed-in account. Configure its Wi-Fi while the web application is in setup mode. Connect the phone or computer to the network whose name starts with `Flova-Setup-`, return to the web application, enter the name and password of your usual Wi-Fi network, and submit the form.
The local setup page sends the network settings to the ESP32. After the device accepts them, reconnect the phone or computer to its usual network. The ESP32 saves the settings, restarts, and connects to Flova. In Console, its status should move from setup and sync to online.
If the web application cannot find the board, check that the browser is still connected to `Flova-Setup-*` and that the device and browser are on the same local network.
## 5. Build the LED dashboard [#5-build-the-led-dashboard]
Open [Studio](https://studio.flova.ir/) and choose **New dashboard**. Enter a name, select `ESP32 LED` as the device template, choose the **Device overview** starter, and create the dashboard.
In the editor, open the **Widgets** panel and add a **Toggle** to the page. Select the Toggle, open its data connection settings, and choose the option labeled `Internal LED`. Check that its description includes the technical key `LED`, the Boolean type, and read/write access. The datastream appears because section 1 created it with those settings.
Wait for the draft to save, then choose **Publish**. The web application loads published dashboards, so saving the draft alone does not make this control available on the device.
Return to the [Flova web application](https://pwa.flova.ir/), open the device you claimed, and open its dashboard. Change the Toggle and watch the built-in LED. The web application sends the `LED` write through FlovaLink, and the universal firmware applies it to `GPIO2`.
If `LED` is not available in the Toggle's value source list, check that the `ESP32 LED` Device Type version is published and that the dashboard uses that same device template. If the dashboard is missing from the device, publish the dashboard and refresh the device page.
## If something goes wrong [#if-something-goes-wrong]
If the device never comes online, check the setup network first. Then check the Wi-Fi credentials and the device status in Console. If the toggle does not change, make sure the Device Type version is published and that the `LED` key matches in Console and Studio.
# Notifications and support (/en/docs/console/support)
Console keeps product messages and support conversations inside the signed-in workspace. Use notifications for events that need your attention and support for a conversation with the Flova team.
## Read notifications [#read-notifications]
Open [Notifications](https://console.flova.ir/notifications) from the Console navigation. Notifications can cover plan status, quota usage, payment, and support. A new notification has a **New** marker. Select **View** when the message links to billing or another page, then mark it read. Use **Mark all as read** for the remaining messages.
Notifications are workspace scoped. If an expected message is missing, check that you are in the workspace where the event happened and move through the notification pages.
## Open a support request [#open-a-support-request]
1. Open [Support](https://console.flova.ir/support).
2. Enter a short subject.
3. Choose a category: billing, account, device and firmware, technical issue, or other.
4. Describe what happened, the device or template involved, and the action that led to the problem.
5. Add an attachment when a log or screenshot helps.
6. Send the request.
Keep API keys, Client Secrets, passwords, Wi-Fi credentials, and activation codes out of the message and attachments. Share the device name, template name, timestamp, and safe diagnostic details instead.
## Continue a conversation [#continue-a-conversation]
The Support page lists your workspace's requests with their category, last update, and status. Open a request to read the full conversation and attachments. Reply from the same page when support asks for more information.
The status tells you who should act next:
| Status | Meaning |
| --- | --- |
| Waiting for support | Flova support will review or answer the request. |
| Waiting for your reply | Add the requested details to continue. |
| Resolved | The request is closed. Sending another message reopens the conversation. |
## Write a useful report [#write-a-useful-report]
Include the exact Console page, the template or device name, the time of the failure, the visible error, and what you expected to happen. For telemetry issues, include the channel's technical key and whether the device was online. For OTA issues, include the release version, rollout status, and the affected device result.
Support can investigate a clear timeline more quickly than a general report such as "it does not work". Do not send secrets while providing that timeline.
For setup and device behavior, also see [Quick start](./quickstart), [Devices](./devices), and [Live monitoring](./monitor).
# Templates and versions (/en/docs/console/templates)
A template describes the inputs, outputs, commands, and firmware settings that a group of devices shares. Dashboards in [Studio](https://studio.flova.ir/), FlovaQL queries, automations, and OTA releases use the template as their connection point.
## Create a template [#create-a-template]
1. Open [Console](https://console.flova.ir/templates) and select **Create template**.
2. Enter a name that describes the hardware or product, such as `ESP32 LED` or `Room controller`.
3. Choose the provisioning method: Wi-Fi, BLE, or Ethernet.
4. Create the template. Add its data channels from the template's **Datastreams** page.
The provisioning method tells Flova how a device receives its first network settings. It does not replace the firmware transport. The firmware still needs to implement the selected setup flow.
## Connect the template to a product [#connect-the-template-to-a-product]
Use the same template when you create the following resources:
| Resource | What the template provides |
| --- | --- |
| Devices | The channel and hardware definition used by each device |
| Studio dashboards | The list of channels that widgets can read or write |
| FlovaQL | The template and channel context for telemetry queries |
| Automations | The channels available to triggers, conditions, and actions |
| OTA | The device family used for compatibility checks and rollouts |
Choose the template before building a dashboard in [Studio](https://studio.flova.ir/). A dashboard attached to another template cannot use this template's channels.
## Set template options [#set-template-options]
Open the template's **Settings** page to change its name or archive it. Archiving a template also archives its active devices, so review those devices before confirming. On the **Datastreams** page, use **Firmware settings** for parameters that the firmware reads from the template. A parameter has a key, a type, and an initial value. Save the parameter before publishing a version.
The **Hardware settings** panel contains board-level options such as the status LED and factory reset source. A status LED is separate from a normal data channel. Keep the pin names consistent with the firmware, for example `GPIO2` or `D32`.
## Publish a version [#publish-a-version]
Console keeps changes in a version instead of applying every edit immediately to active devices.
1. Add or edit the channels, firmware parameters, and automation graph.
2. Open **Versions** and review the version number and validation status.
3. Publish a version marked **Ready to publish**.
4. Confirm the publication. Console sends the published configuration to active devices that use the template.
The version list uses these states:
| State | Meaning |
| --- | --- |
| Draft | The version is still being edited. |
| Ready to publish | Validation passed and the version can be published. |
| Published | This version is the active template configuration. |
| Archived | The version is kept in history and can be restored. |
Publishing a template version does not publish a Studio dashboard. Publish the dashboard separately in [Studio](https://studio.flova.ir/).
## Roll back a version [#roll-back-a-version]
Open **Versions**, find an archived version, and choose **Restore version**. Console validates the selected version, makes it the published version, and sends its configuration to active devices in the template. A rollback changes the template configuration. It does not undo telemetry already stored or a firmware image already installed by OTA.
## Common problems [#common-problems]
- **No device can be created:** the template has no published version. Publish one first.
- **A channel is missing in Studio:** check that the dashboard uses the same template and that the channel exists in the published version.
- **A version cannot be published:** open the validation message, then fix missing channels, duplicate keys, invalid pins, or an incomplete automation graph.
- **A template should disappear from daily work:** archive it from **Settings**. This also archives its active devices, so review the affected device list first.
For the channel fields used in a template, see [Datastreams](./datastreams). For the first complete device flow, see [Quick start](./quickstart).
# Team and workspace (/en/docs/console/workspace)
A workspace is the shared Console and Studio area where a team manages templates, devices, dashboards, queries, automations, and billing. It is separate from the user space in the [Flova web application](https://pwa.flova.ir/), where an end user claims devices and uses published dashboards.
## Invite and manage members [#invite-and-manage-members]
1. Open **Team** in Console.
2. Select **Invite member** or **View members**. Console opens the workspace management page in Flova Auth.
3. Enter the person's email address, choose a role, and send the invitation.
4. Review or cancel pending invitations, change member roles, or remove a member from the same organization page.
Members work inside the workspace. Their permissions decide whether they can read or manage templates, devices, automations, settings, billing, and other resources. Give a person the smallest role that lets them do their work.
## Change workspace settings [#change-workspace-settings]
Open **Settings > Workspace** to change the workspace name and its logo. This link opens the organization page in Flova Auth. The new name is shared across Console and other Flova product surfaces that use the workspace identity.
Workspace settings affect the shared organization. Account settings affect only your signed-in user, such as your personal profile or authentication details. The **Account** link opens your profile in Flova Auth.
## Understand the two spaces [#understand-the-two-spaces]
| Space | Used for |
| --- | --- |
| Workspace in Console and Studio | Templates, devices, dashboards, data, team access, and billing |
| User space in the web application | Claimed devices and the published experience for an end user |
Creating a device in Console does not claim it for your personal web application account. The device becomes available to an end user after that person uses the activation QR or manual code in the web application.
## Team work in practice [#team-work-in-practice]
Keep template and datastream changes in the workspace so Studio, FlovaQL, automation, and OTA users share one definition. Use [notifications](https://console.flova.ir/notifications) to follow workspace events, quota messages, and support updates. Use [support](https://console.flova.ir/support) when the team needs help from Flova.
If a page or action is missing, check the active workspace and your role first. A successful login does not by itself grant access to every workspace or permission.
# Advanced firmware (/en/docs/sdk/advanced)
Use the advanced paths when the standard ESP32 or ESP8266 composition does not
match the product's hardware or service model.
## Linux [#linux]
Linux applications use `FlovaLinux` with a CMake package:
```cpp
#include
FlovaLinux device;
auto relay = FLOVA_DATASTREAM(device, bool, "relay");
int main() {
FLOVA_ON_WRITE(relay, applyRelay);
if (!device.begin()) return 1;
for (;;) device.run();
}
```
The application owns the event loop and hardware integration. A service
supervisor owns process startup, restart, and activation of a staged OTA image.
## Custom boards [#custom-boards]
The portable core has four service boundaries:
```cpp
flova::Device device(link, storage, clock, logger);
auto relay = device.datastream("relay");
```
Implement `flova::Link`, `flova::Storage`, `flova::Clock`, and `flova::Logger`
for the board or gateway. `Device::run()` remains the point where queued
messages reach application hardware.
The transport can be a network connection or a gateway such as serial, CAN,
BLE, or another bounded carrier. Keep the carrier adapter separate from the
datastream and hardware logic.
## Ethernet [#ethernet]
ESP32 LAN8720 projects can use `FlovaEsp32Ethernet`. The application supplies
the PHY parameters and hardware handlers while the composition provides the
ESP32 network and Flova connection. A different Ethernet chip or TCP/IP stack
needs its own validated socket adapter.
Check the board schematic for boot pins, RMII reservations, power, DHCP, and
certificate setup. A successful compile does not prove physical link, TLS, or
hardware command acceptance.
## Application-owned provisioning [#application-owned-provisioning]
An existing web server can keep its routes and network mode while the SDK adds
the bounded provisioning handoff. BLE, serial, factory, and cellular setup
paths can use the same handoff contract. The application remains responsible
for authenticating and transporting its setup input.
Keep advanced integrations small: use the public facade first, inject a custom
service only when the product actually owns that boundary.
## Custom Arduino application boundary [#custom-arduino-application-boundary]
The custom board facade is passive. It does not start a SoftAP, replace your
web server, control GPIO, or reboot the board on its own. Your application
chooses when to start Wi-Fi, which pins to use, and how to recover from a
hardware fault.
The normal structure is:
```cpp
FlovaEsp32 device;
auto sensor = FLOVA_DATASTREAM(device, float, "temperature");
void setup() {
startApplicationNetwork();
attachHardwareHandlers();
device.begin();
}
void loop() {
serviceApplicationHardware();
device.run(applicationNetworkReady());
}
```
Keep the loop cooperative. A handler should update or queue application state,
not wait for a second network request or perform a long blocking operation.
## Status and lifecycle callbacks [#status-and-lifecycle-callbacks]
Use the status listener when the product needs edge-triggered changes such as
network ready, Link connected, runtime ready, or an error code. Keep the
listener short and read detailed state from the facade after the callback.
For maintenance tools, expose bounded status fields such as network readiness,
TLS readiness, runtime readiness, firmware target, and current lifecycle state.
Do not expose tokens, secrets, full payloads, or private storage keys.
## BLE and other setup channels [#ble-and-other-setup-channels]
Provisioning transport is a firmware capability. A BLE, serial, Ethernet,
cellular, or factory adapter can decode its own input and pass a
`ProvisioningHandoff` to the client. The adapter owns pairing, framing, and
transport-specific timeouts. The SDK owns the bounded Flova handoff and runtime
session.
Keep the setup channel separate from normal telemetry. Once the handoff is
durably accepted, release temporary setup resources before starting normal Link
or MQTT work.
## Hardware ownership [#hardware-ownership]
Use template mappings when the universal composition should apply standard
inputs and outputs. Use application-owned handlers when the product needs custom
debounce, calibration, interlocks, power sequencing, or board-specific pin
rules.
Never assume that a valid cloud command is safe to apply directly. Check the
current hardware state, limits, power conditions, and emergency policy before
changing an output.
## Custom integration checklist [#custom-integration-checklist]
- Choose universal or custom composition explicitly.
- Keep the public umbrella include in simple examples.
- Declare datastreams and settings before `begin()`.
- Provide storage that survives the reset behavior the product expects.
- Call `run()` from the normal cooperative loop.
- Keep callbacks bounded and hardware-aware.
- Verify provisioning, reconnect, template binding, command, report, and OTA
separately.
- Keep wired recovery for the first image and failed updates.
# Configuration and settings (/en/docs/sdk/configuration)
Firmware settings let an application read typed values configured from Flova.
Declare the setting once in firmware, give it a default, and use the cached
value in the application logic.
## Declare a setting [#declare-a-setting]
```cpp
auto dryThreshold = FLOVA_SETTING(device, double, "dry_threshold", 35.0);
auto dryCalibration = FLOVA_SETTING(device, int64_t, "dry_adc", 3000);
```
The key must match the setting declared in the published device template. The
default is used until a valid remote value is available.
Read the setting from the local firmware state and clamp values when the
hardware has a narrower safe range:
```cpp
int32_t boundedCalibration(const flova::Setting& setting) {
const int64_t value = setting.value();
return static_cast(value < 0 ? 0 : value > 4095 ? 4095 : value);
}
```
Configuration delivery is asynchronous. Keep using the current cached value
until the SDK applies a valid update. Do not make a network request from a
getter.
## Hardware mappings and safety [#hardware-mappings-and-safety]
Template configuration can describe digital inputs, digital outputs, analog
inputs, PWM outputs, defaults, limits, debounce, sampling, and safety rules.
The universal compositions can apply supported mappings automatically. A custom
application can read the configuration and keep the final hardware policy in
its own code.
Always validate values again at the hardware boundary. A setting that is valid
for the template may still be unsafe for a particular sensor, motor, power
stage, or board revision.
## Configuration flow [#configuration-flow]
1. Declare the typed setting or datastream in firmware.
2. Create the matching item in the device template.
3. Publish the template version.
4. Configure the value in Console.
5. Let the device receive and apply the update from its normal `run()` loop.
6. Report the resulting hardware state when the application accepts it.
Use one source of truth for each setting. Duplicating the same calibration in
the template, firmware constants, and application UI makes field changes hard
to reason about.
## Settings and datastreams are different [#settings-and-datastreams-are-different]
Use a datastream for a value that belongs in the live device model, such as a
temperature, relay state, counter, or user command. Use a setting for a value
that configures how the firmware works, such as a threshold, calibration point,
sampling interval, or feature switch.
The two can work together. A moisture controller might read `wet_adc` and
`dry_adc` as settings, calculate a percentage locally, and report that result
through a read-only `MOISTURE` datastream. The dashboard can display the
datastream while Console changes the settings.
## Update behavior [#update-behavior]
Configuration is applied from the normal device loop. Do not change GPIO or
start a long calibration operation inside a transport callback. Instead:
1. Let the SDK validate and cache the new value.
2. Notice the changed value from the application loop.
3. Validate it against the connected hardware.
4. Apply the new behavior at a safe boundary.
5. Report the resulting state if a datastream represents it.
If a value is outside the application's safe range, keep the previous value and
return a bounded rejection or diagnostic. A template limit is useful input, but
it does not replace hardware-level validation.
## Resource and capacity planning [#resource-and-capacity-planning]
Embedded builds reserve fixed capacity for datastreams, parameters, text,
history, command deduplication, hardware inputs, hardware outputs, and schedule
occurrences. Plan those capacities before adding many template items.
When a build reaches a capacity, the correct fix is usually to reduce the
declared surface, increase the target's explicit resource budget, or choose a
larger composition. Avoid adding a dynamic map that hides memory use on a small
board.
## Settings checklist [#settings-checklist]
- Use a stable, lowercase technical key.
- Give the setting a useful default for a fresh device.
- Define the same type and default in the published template.
- Keep calibration and product limits in the setting model.
- Validate again before touching hardware.
- Test a remote update while the device is online and after a reconnect.
- Confirm that a power cycle restores the expected setting and output state.
# Datastreams (/en/docs/sdk/datastreams)
A datastream is a typed value shared by firmware, Console, Studio, and the
published device dashboard. Its technical key is the contract between those
parts. Use the exact key from the published template in firmware.
## Declare a stream [#declare-a-stream]
The Arduino helpers keep a sketch compact:
```cpp
auto temperature = FLOVA_DATASTREAM(device, float, "temperature");
auto relay = FLOVA_DATASTREAM(device, bool, "relay");
```
The portable API uses the same types:
```cpp
auto relay = device.datastream("relay");
```
Declare streams before `begin()`. The SDK binds the declared keys when the
device connects to the published template.
## Four directions of state [#four-directions-of-state]
```cpp
FLOVA_ON_WRITE(relay, setRelay); // remote command
FLOVA_WRITE(relay, true); // local application command
FLOVA_REPORT(temperature, 23.4f); // sensor or hardware observation
bool enabled = FLOVA_READ(relay); // local cached value
```
`FLOVA_READ` and `value()` read the local cache. They do not make a network
request. `FLOVA_REPORT` records an observation. It does not call the write
handler.
Use `FLOVA_HAS_VALUE` before reading a value that may not have been restored or
received yet:
```cpp
if (FLOVA_HAS_VALUE(relay) && FLOVA_READ(relay)) {
digitalWrite(2, HIGH);
}
```
## Apply remote writes safely [#apply-remote-writes-safely]
Remote commands arrive through `run()`:
```cpp
flova::WriteResult setRelay(bool enabled) {
digitalWrite(2, enabled ? HIGH : LOW);
return flova::accept();
}
void setup() {
FLOVA_ON_WRITE(relay, setRelay);
}
void loop() {
device.run();
}
```
If hardware cannot accept a command, return a rejection instead of changing
the local state. Keep the handler short. Queue long work for the application
loop and return without blocking network processing.
## Value types [#value-types]
The public typed surface supports Boolean, integer, floating point, double, and
text values. The C++ type must match the template's value type. Text values are
bounded by the SDK build configuration, so check the returned value when your
application accepts user-provided text.
## Offline behavior [#offline-behavior]
The local cache lets hardware continue using the latest accepted value while
the network is unavailable. The exact offline policy belongs to the stream and
firmware configuration. After reconnecting, the SDK synchronizes the state that
the selected policy keeps.
If a report is rejected, check the connection, the exact technical key, the
value type, and the published template version. Presence alone does not prove
that a datastream report was accepted.
## Design the template contract [#design-the-template-contract]
Define the stream in Console before writing the firmware declaration. The
following fields affect how the application should use the value:
| Template choice | Firmware consequence |
| --- | --- |
| Boolean, integer, float, double, or text | Use the matching C++ type. |
| Read-only | Report observations; do not attach a user command handler. |
| Read/write | Apply remote writes and report the hardware result. |
| Default value | Use it as an initial value only; the board still needs a safe hardware state. |
| Hardware mapping | Let universal firmware apply it or read it in a custom application. |
| Minimum and maximum | Validate again before driving hardware. |
A datastream key is case-sensitive. `temperature`, `Temperature`, and
`TEMPERATURE` are different keys. Renaming a key requires updating the template,
firmware, dashboard bindings, automations, and any external clients together.
## State, sample, command, and event [#state-sample-command-and-event]
The SDK supports different stream modes for different device behavior:
- **State** represents the current value of a device or actuator.
- **Sample** represents a measurement taken at a point in time.
- **Command** represents an instruction for the device to apply.
- **Event** represents an occurrence such as a button press or alarm.
Use state for a relay that should be restored, sample for a temperature sensor,
command for a one-shot action, and event for a notification that does not need
to become the current value.
## Inspect a stream [#inspect-a-stream]
The portable handle can expose more than the value:
```cpp
auto snapshot = relay.snapshot();
if (snapshot.hasValue && snapshot.quality == flova::Quality::Good) {
applyRelay(snapshot.value);
}
```
A snapshot can include the last update time, origin, quality, dirty state, and
revision. Use it when the application needs to distinguish a restored value
from a fresh sensor reading or a remote command.
## Report accepted hardware state [#report-accepted-hardware-state]
For a writable physical output, apply the command first and report the state
that the hardware actually accepted:
```cpp
flova::WriteResult setRelay(bool requested) {
const bool applied = writeRelayHardware(requested);
if (!applied) return flova::reject("hardware_rejected");
return flova::accept();
}
void loop() {
device.run();
const bool measured = readRelayHardware();
FLOVA_REPORT(relay, measured, flova::Origin::PhysicalInput);
}
```
This keeps the cloud value aligned with the physical output when a relay,
driver, or power controller refuses a request.
## Capacity and retained history [#capacity-and-retained-history]
Embedded builds use bounded storage for datastreams, text, command results, and
history. Set the build capacities for the board and product instead of adding
unbounded containers. If the device reports queue overflow, dropped history, or
storage failures, inspect the resource plan and the frequency of reports.
Do not report a sensor on every loop iteration. Sample at the rate the sensor
needs, report meaningful changes, and keep the main loop available for network
and hardware work.
## Debugging a missing value [#debugging-a-missing-value]
Check the path in this order:
1. The device is online and the selected template is published.
2. The firmware key matches the template key byte for byte.
3. The C++ type matches the template value type.
4. The report result is accepted.
5. The latest value appears in Console.
6. History contains a row in the selected time range.
An online device can still have an undeclared or rejected datastream. Presence,
queue acceptance, latest value, and history prove different parts of the path.
# Install and choose a target (/en/docs/sdk/install)
FlovaSDK is distributed as an Arduino and PlatformIO library for ESP32 and
ESP8266. Linux applications use the CMake package. A portable device can use
the embedded core with its own platform services.
## Pick the integration model first [#pick-the-integration-model-first]
| You have | Start with | The application owns |
| --- | --- | --- |
| A board and no device application | `FlovaUniversalEsp32` or `FlovaUniversalEsp8266` | Your template and product dashboard |
| An existing Arduino application | `FlovaEsp32` or `FlovaEsp8266` | Wi-Fi, GPIO, sensors, setup, and the main loop |
| A Raspberry Pi or Linux host | `FlovaLinux` | The process, event loop, service supervisor, and hardware |
| Another C++11 board or gateway | `flova::Device` | Link, storage, clock, logger, and board integration |
Use the [Quick start](./quickstart) if you want a working ESP32 device first.
Use this page when you need to select a target or set up a new project.
## Arduino IDE and PlatformIO [#arduino-ide-and-platformio]
### ESP32 and ESP8266 [#esp32-and-esp8266]
1. Open **Tools > Board > Boards Manager**.
2. Search for `esp32` by Espressif Systems and install the board package.
3. Open **Tools > Manage Libraries** and install `FlovaSDK`.
4. Select the board and USB port under **Tools > Board** and **Tools > Port**.
5. Include the common entry point:
```cpp
#include
```
The header selects the ESP32 facade for the selected board. Use
`FlovaUniversalEsp32` for a complete device or `FlovaEsp32` for an existing
application.
1. Open **Tools > Board > Boards Manager**.
2. Search for `esp8266` by ESP8266 Community and install the board package.
3. Open **Tools > Manage Libraries** and install `FlovaSDK`.
4. Select the board's ESP8266 profile and USB port.
5. Include the common entry point:
```cpp
#include
```
Use `FlovaUniversalEsp8266` or `FlovaEsp8266` according to the same ownership
model as ESP32.
ESP8266 uses stock BearSSL. TLS connect and OTA work can pause the application
loop for seconds and require a contiguous heap block. Use the memory profile
recommended by the SDK and keep large buffers out of the sketch.
### ESP32 and ESP8266 [#esp32-and-esp8266-1]
Add the library to `platformio.ini`:
```ini
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
lib_deps = flova-platform/FlovaSDK@^0.3.12
```
Build or upload with:
```sh
pio run
pio run -t upload
```
Use the SDK's packaged ESP8266 PlatformIO profile or set the board and memory
layout recommended for your target. A normal project still includes:
```ini
lib_deps = flova-platform/FlovaSDK@^0.3.12
```
Build or upload with the same commands:
```sh
pio run
pio run -t upload
```
Keep a wired upload path available while tuning TLS, memory, or OTA behavior.
## Universal firmware [#universal-firmware]
Use a universal composition when Flova should own the complete device image:
```cpp
#include
#include
FlovaUniversalEsp32 device;
void setup() {
Serial.begin(115200);
device.begin();
}
void loop() {
device.run();
}
```
For ESP8266, use `FlovaUniversalEsp8266`. Universal firmware includes the board
composition, setup path, hardware mapping, OTA policy, and restart policy
provided by that target. It is the shortest path for a standard Wi-Fi product.
## Linux and Raspberry Pi [#linux-and-raspberry-pi]
Install the native dependencies and build the package from the firmware
repository:
```sh
sudo apt install cmake libssl-dev
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr/local
cmake --build build
sudo cmake --install build
```
Link the installed package from your application:
```cmake
find_package(FlovaLinux CONFIG REQUIRED)
target_link_libraries(my_device PRIVATE Flova::Linux)
```
Then use the same typed datastream model:
```cpp
#include
FlovaLinux device;
auto relay = FLOVA_DATASTREAM(device, bool, "relay");
int main() {
if (!device.begin()) return 1;
for (;;) device.run();
}
```
`run()` performs one bounded step. Put it in the application's poll or event
loop instead of giving the SDK ownership of the process.
## Portable boards [#portable-boards]
The portable core has no Arduino, ESP, Wi-Fi, filesystem, exception, or RTTI
requirement in its public include path. A custom port supplies
`flova::Link`, `flova::Storage`, `flova::Clock`, and `flova::Logger`, then
constructs `flova::Device`.
Use [Advanced firmware](./advanced) when the target needs a custom network,
gateway, Ethernet chip, or service supervisor.
## Installation checks [#installation-checks]
After installation, check the following before debugging application logic:
1. The board package matches the physical board.
2. The selected serial port changes when you unplug and reconnect the board.
3. The project can compile an empty sketch with `#include `.
4. The selected target matches the class in the sketch.
5. The device has a published template before it tries to bind datastreams.
If the library is found but the board does not connect, inspect Wi-Fi readiness,
time or TLS readiness, provisioning state, and the device status separately.
# Firmware lifecycle (/en/docs/sdk/lifecycle)
The firmware lifecycle covers the image you build, the target it declares, the
runtime logs it emits, and the OTA release that Console offers to compatible
devices.
## Build metadata [#build-metadata]
Every release should identify its firmware target and version. Keep the target
stable for the board and boot layout that can install it. Console uses this
metadata when it checks OTA compatibility.
The SDK version and the firmware application version are separate values. A
new SDK package does not update an installed device until you build and deliver
a firmware image.
## Logging [#logging]
Flova diagnostics can be filtered at compile time:
```ini
build_flags =
-DFLOVA_LOGGING_ENABLED=1
-DFLOVA_LOG_LEVEL=FLOVA_LOG_LEVEL_DEBUG
```
Supported levels are `ERROR`, `WARN`, `INFO`, `DEBUG`, and `TRACE`. Production
images can disable Flova logging. Never log credentials, provisioning tokens,
device secrets, or complete sensitive payloads.
## OTA [#ota]
Console accepts a firmware release, checks its target and size, and sends it in
a rollout to compatible devices. The firmware must provide the matching OTA
capability and boot layout for that target.
ESP32 universal images use the target's supported boot layout. ESP8266 OTA
uses staged copying and has no automatic rollback, so keep wired recovery
available for a failed post-update boot.
An OTA upload, rollout completion, and post-update runtime connection are
separate checks. After an update, verify the device timeline, current firmware
metadata, online status, and a fresh datastream report.
## Recovery [#recovery]
Keep a wired upload path for the first installation and for boards whose OTA
image cannot boot. Do not erase provisioning state as a first response to a
network failure. Inspect the device status and logs, then recover the image
through the board's supported upload path.
## Version and target policy [#version-and-target-policy]
Treat the firmware version, firmware target, boot layout, and template contract
as one release decision. A binary that compiles for a board is not necessarily
safe to offer to every device of that board family.
Use a distinct target when any of these change:
- Flash partition or boot layout.
- OTA capability or rollback behavior.
- Board memory profile or TLS constraints.
- Required hardware pins or peripheral wiring.
- Runtime features that the device cannot disable safely.
Keep the target name stable for compatible releases. Publish a new target when
the device needs a different image or recovery procedure.
## Prepare an OTA release [#prepare-an-ota-release]
Before uploading a release to Console:
1. Build the exact target used by the selected devices.
2. Confirm the version and target metadata in the binary.
3. Check the image size against the target's flash and OTA limits.
4. Keep a wired recovery image and the previous known-good release.
5. Test boot, provisioning restore, network reconnect, and one datastream.
6. Upload the release and review the compatibility result.
Create a rollout only after the release registration succeeds. Start with a
small eligible group, watch post-update reconnection, and stop when failures or
offline devices reach the rollout thresholds.
## What to verify after OTA [#what-to-verify-after-ota]
OTA completion only proves that the update operation finished. For each test
device verify:
- The reported firmware version is the new version.
- The target and boot layout remain compatible.
- The device reconnects after restart.
- The template binding completes.
- A command reaches the hardware.
- A fresh sensor or state report appears in latest value and history.
- The device keeps its provisioning and configuration.
If the device updated but does not reconnect, inspect the boot result, memory,
TLS readiness, stored session, and device timeline before retrying the rollout.
## Power-down and long work [#power-down-and-long-work]
Call the facade's power-down preparation method before a board-owned sleep or
power cut when the target provides one. Finish or quiesce Link and storage work
first. The SDK does not decide when your board sleeps and does not replace the
board's power-management policy.
## Logging by environment [#logging-by-environment]
Use `ERROR` or `WARN` for production device logs, `INFO` for controlled field
diagnostics, and `DEBUG` or `TRACE` during development. Log event names, bounded
error codes, and target metadata. Redact identifiers when logs leave the device
environment and never print credentials or provisioning material.
# SDK overview (/en/docs/sdk/overview)
FlovaSDK connects an application or firmware image to Flova. It gives your code
typed datastreams, local cached state, remote commands, configuration, device
identity, and a `run()` loop that fits the board's normal event loop.
The SDK supports ESP32, ESP8266, Linux, and portable C++11 applications. The
same datastream code can use Flova Link or the optional MQTT adapter.
## Choose an integration model [#choose-an-integration-model]
| Model | Use it when |
| --- | --- |
| Universal firmware | Flova should own provisioning, networking, hardware mappings, OTA, and restart behavior. |
| Custom Arduino client | Your application already owns Wi-Fi, GPIO, sensors, and its web server. |
| Linux device | A Raspberry Pi or Linux host runs the device process and its own service supervisor. |
| Portable device | Your board supplies the SDK's link, storage, clock, and logger services. |
Start with [Quick start](./quickstart) for an ESP32. Then read [Datastreams](./datastreams)
to connect application state to Console and Studio.
## Public SDK surface [#public-sdk-surface]
Most Arduino projects need one include:
```cpp
#include
```
The common application helpers are `FLOVA_DATASTREAM`, `FLOVA_WRITE`,
`FLOVA_READ`, `FLOVA_REPORT`, `FLOVA_ON_WRITE`, and `FLOVA_HAS_VALUE`.
Advanced applications can use the typed C++ API directly:
```cpp
auto relay = device.datastream("relay");
relay.onWrite(setRelay);
relay.write(true);
relay.report(sensorValue);
bool current = relay.value();
```
Datastream keys must match the published device template. The application owns
the hardware action. The SDK delivers remote writes from `run()`, so callbacks
should be short and should not block the board loop.
## How the SDK fits into a Flova product [#how-the-sdk-fits-into-a-flova-product]
The device side usually has five layers:
1. **Your application** reads sensors, drives outputs, owns product rules, and
decides how the board starts and recovers.
2. **The SDK facade** exposes typed datastreams, settings, provisioning, status,
and the normal `run()` lifecycle.
3. **The transport** carries bounded commands, reports, configuration, and
presence to Flova.
4. **The published template** defines the keys, value types, access rules,
mappings, settings, and limits that the device can use.
5. **Console and Studio** manage the template, device, dashboard, telemetry,
automation, and firmware rollout.
The SDK does not turn an arbitrary GPIO project into a product automatically.
Your code still decides what a sensor reading means, whether an output is safe,
and what should happen when power or network access disappears.
## The device loop [#the-device-loop]
In `setup()`, start the board services your application owns, then call
`device.begin()`. In the regular `loop()`, run your sensor and hardware work and
call `device.run()` often. The SDK handles connection work and applies remote
commands from this normal application context.
After connecting, the SDK matches the declared datastream keys to the published
device template. Wait for that binding before treating the streams as ready. A
connected device does not by itself prove that a particular report was
accepted; check the report result and the resulting value in Console.
## What to learn in order [#what-to-learn-in-order]
1. [Quick start](./quickstart) gets one ESP32 device online.
2. [Datastreams](./datastreams) explains the contract between code and template.
3. [Provisioning](./provisioning) covers identity and first boot.
4. [Configuration](./configuration) adds remote settings and hardware policy.
5. [Transports](./transports) explains Link, MQTT, readiness, and limits.
6. [Firmware lifecycle](./lifecycle) covers logging, OTA, versions, and recovery.
7. [Advanced firmware](./advanced) covers Linux, Ethernet, and custom boards.
Use the [API reference](./reference) while reading the examples. It lists the
public names without exposing the SDK's private implementation.
# Provisioning and identity (/en/docs/sdk/provisioning)
Provisioning connects a physical unit to a Flova device record. It supplies a
short-lived handoff, then the device receives or creates the runtime identity it
stores for later boots.
## Universal firmware [#universal-firmware]
Universal ESP32 and ESP8266 firmware includes a setup path. The user completes
the setup flow, the device receives its network and Flova handoff, and the
firmware stores the resulting runtime state. Later boots restore the stored
identity and connect without repeating the first-boot flow.
## Custom applications [#custom-applications]
Custom firmware keeps ownership of Wi-Fi, the web server, BLE, Ethernet, or
another setup channel. The application passes the bounded Flova handoff to the
SDK. For an application-owned Arduino server, the provisioning adapter can
register the status and provision routes without replacing that server.
The handoff contains the deployment's Link URL and a short-lived token. The
device uses it to bootstrap and stores the resulting session. Do not commit
tokens, device secrets, Wi-Fi passwords, or complete provisioning payloads.
## A custom provisioning channel [#a-custom-provisioning-channel]
The same model works for a factory tool, serial adapter, BLE flow, or Ethernet
setup path:
```cpp
flova::ProvisioningHandoff handoff(linkUrl, shortLivedToken);
client.provision(handoff);
```
The channel owns its input and transport. The SDK owns the bounded handoff and
the Flova session lifecycle. Network credentials remain with the application or
the selected universal composition.
## Factory reset [#factory-reset]
Use the SDK's factory reset entry point when the product needs to clear Flova
identity and wait for another handoff. Resetting Flova state does not silently
change the application's Wi-Fi, web server, GPIO, or other network state.
After provisioning, verify the device in Console. Check its online status,
template, firmware target, and first datastream report separately.
## What provisioning stores [#what-provisioning-stores]
The completed handoff results in a Flova session containing the device identity,
organization and template association, Link URL, and runtime secret. The SDK
stores the session through the selected storage service. Your application should
not copy that secret into a second configuration file or expose it through a
status page.
The activation token is a bootstrap input. It is not the runtime password and
should not be sent on every boot. After the session is committed, later boots
restore the session and authenticate with the stored runtime identity.
## Provisioning states [#provisioning-states]
Treat setup as a state machine rather than a single HTTP request:
| State | Application behavior |
| --- | --- |
| Waiting | Keep the setup channel available and run the SDK normally. |
| Bootstrapping | Continue polling from the normal loop; do not start another session. |
| Committing | Keep power and storage available until the session is durable. |
| Ready | Close temporary setup resources and start normal device operation. |
| Failed | Show a bounded error, keep recovery available, and retry deliberately. |
The exact status names differ between facades, but the boundaries are the same.
Do not treat a submitted form as proof that the device is ready. Confirm the
stored session, authenticated Link connection, template binding, and first
accepted report.
## Application-owned web setup [#application-owned-web-setup]
An Arduino application that already has a web server can attach provisioning to
that server:
```cpp
WebServer server(80);
FlovaEsp32 device;
void setup() {
device.attachProvisioning(server);
server.begin();
}
```
The SDK registers its bounded status and provisioning handlers. It does not
start or replace the server, change the application's Wi-Fi mode, or take over
the application's other routes. Keep the server loop and `device.run()` in the
same nonblocking application loop.
## Recovery and reset [#recovery-and-reset]
Use `startProvisioning()` or the facade's factory reset operation when a product
needs to replace the Flova identity. Define the user action clearly, such as a
physical button hold or an authenticated maintenance command. A reset should
clear Flova-private state and return to setup; it should not silently erase
application data or Wi-Fi credentials unless the product explicitly chooses to
do that.
If bootstrap fails, check the setup channel, HTTPS or WSS URL, token lifetime,
clock readiness, storage availability, and device claim separately. Keep error
messages bounded and never include the token or secret.
# Quick start (/en/docs/sdk/quickstart)
This is the fastest path to a working Flova device. You will create an ESP32
template, flash the universal firmware, provision the board, and switch its
built-in LED from a published dashboard.
You need an ESP32 board with an LED on `GPIO2`, a USB data cable, a phone or
computer with Wi-Fi, and either PlatformIO or Arduino IDE. Create a Flova
workspace before you begin.
## 1. Create a device template [#1-create-a-device-template]
Open [Flova Console](https://console.flova.ir/), create a Device Type, and name
it `ESP32 LED`. Choose Wi-Fi as its setup method. Add one datastream with these
values:
| Field | Value |
| --- | --- |
| Name | Internal LED |
| Technical key | `LED` |
| Value type | Boolean |
| Access | Read/write |
| Behavior | Digital output |
| Hardware pin | `GPIO2` |
| Active level | HIGH |
| Default and safe value | Off |
Use `LED` exactly as the technical key. Publish the Device Type version before
creating a device from it.
## 2. Install and flash universal firmware [#2-install-and-flash-universal-firmware]
The universal composition owns the setup flow, device connection, hardware
mapping, and normal firmware lifecycle. Choose your tool:
Install the ESP32 board package:
1. Open **Tools > Board > Boards Manager**.
2. Search for `esp32` by Espressif Systems and install it.
3. Open **Tools > Manage Libraries**, search for `FlovaSDK`, and install it.
4. Select your ESP32 board under **Tools > Board**.
5. Select its USB serial port under **Tools > Port**.
Create a new sketch and replace it with:
```cpp
#include
#include
FlovaUniversalEsp32 device;
void setup() {
Serial.begin(115200);
device.begin();
}
void loop() {
device.run();
}
```
Click **Upload**. Arduino IDE builds and flashes the complete image for the
selected board.
Create a project and add the SDK:
```sh
mkdir flova-esp32
cd flova-esp32
pio project init --board esp32dev
```
Add this environment to `platformio.ini`:
```ini
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
lib_deps = flova-platform/FlovaSDK@^0.3.12
```
Replace `src/main.cpp` with:
```cpp
#include
#include
FlovaUniversalEsp32 device;
void setup() {
Serial.begin(115200);
device.begin();
}
void loop() {
device.run();
}
```
Connect the board and upload:
```sh
pio run -t upload
pio device monitor -b 115200
```
If PlatformIO cannot find the board, set `upload_port` in `platformio.ini` to
the serial port assigned by your operating system.
## 3. Create and provision the device [#3-create-and-provision-the-device]
In [Console's Devices page](https://console.flova.ir/devices), open `ESP32 LED`,
choose **Add Device**, enter a name, and create the device. Console shows a QR
code and a manual activation code.
Open the [Flova web application](https://pwa.flova.ir/), sign in, choose **Add
device**, and scan the QR code. Use the manual activation option if the camera
is unavailable.
The fresh board starts its setup network with a name like `Flova-Setup-*`.
While the web application is in setup mode:
1. Connect your phone or computer to `Flova-Setup-*`.
2. Return to the web application.
3. Enter the usual Wi-Fi name and password.
4. Submit the setup form.
5. Reconnect your phone or computer to its normal network.
The board stores the setup result, restarts, and connects to Flova. In Console,
its status should move from setup and sync to online.
## 4. Test the LED [#4-test-the-led]
Open [Studio](https://studio.flova.ir/) and create a dashboard for the `ESP32
LED` template. Add a Toggle, connect it to `Internal LED`, and publish the
dashboard.
Open the device in the Flova web application and change the Toggle. The LED
should follow the command. If it does not:
- Confirm that the Device Type version is published.
- Confirm that the dashboard uses the same `ESP32 LED` template.
- Check that the datastream key is exactly `LED`.
- Check the device status and timeline in Console.
- Keep the browser connected to the setup network while provisioning.
## Move to custom firmware [#move-to-custom-firmware]
Universal firmware is useful for the first device and for products where Flova
owns the complete device composition. Use `FlovaEsp32` when your application
must own Wi-Fi, GPIO, sensors, a web server, or another setup channel.
```cpp
#include
#include
#include
FlovaEsp32 device;
auto relay = FLOVA_DATASTREAM(device, bool, "relay");
void setRelay(bool enabled) {
digitalWrite(2, enabled ? HIGH : LOW);
}
void setup() {
pinMode(2, OUTPUT);
WiFi.begin("your-wifi", "your-password");
FLOVA_ON_WRITE(relay, setRelay);
device.begin();
}
void loop() {
device.run(WiFi.status() == WL_CONNECTED);
}
```
Continue with [Datastreams](./datastreams), [Provisioning](./provisioning), and
[Transports](./transports) when you are ready to build an application around
the SDK.
This sketch shows the datastream and network loop. A custom product must also
provide its provisioning handoff; see [Provisioning](./provisioning) before
flashing it to a new device.
# Public API reference (/en/docs/sdk/reference)
This page lists the public application surface used by the guides. For exact
signatures and target-specific overloads, use the exported headers in the
FlovaSDK release.
## Board facades [#board-facades]
| Type | Use |
| --- | --- |
| `FlovaEsp32` | Custom ESP32 application using Flova Link or optional MQTT. |
| `FlovaEsp8266` | Custom ESP8266 application using the same typed datastream model. |
| `FlovaUniversalEsp32` | Complete ESP32 composition with Flova-owned setup and device behavior. |
| `FlovaUniversalEsp8266` | Complete ESP8266 composition. |
| `FlovaLinux` | Linux or Raspberry Pi device process. |
| `flova::Device` | Portable core for a custom board or gateway. |
## Lifecycle methods [#lifecycle-methods]
| Method | Meaning |
| --- | --- |
| `begin()` | Initialize the selected device composition and restore or start its session. |
| `run()` | Perform one bounded connection, configuration, and command-processing step. |
| `connected()` | Report the current transport connection state. |
| `datastream(key)` | Return a typed datastream handle in the portable API. |
| `value()` | Read the local cached value. |
| `write(value)` | Apply a local application command. |
| `report(value)` | Report an observation from a sensor or hardware state. |
| `onWrite(handler)` | Register the hardware boundary for remote writes. |
## Arduino helpers [#arduino-helpers]
```cpp
FLOVA_DATASTREAM(device, bool, "relay")
FLOVA_SETTING(device, double, "threshold", 35.0)
FLOVA_ON_WRITE(relay, setRelay)
FLOVA_WRITE(relay, true)
FLOVA_READ(relay)
FLOVA_REPORT(temperature, 23.4f)
FLOVA_HAS_VALUE(relay)
```
Use the helpers only after declaring the device and before calling `begin()`.
Keep the technical key in one place so it cannot drift from the template.
## Results and state [#results-and-state]
`flova::WriteResult` reports `Accepted`, `Rejected`, `NoChange`, or `Failed`.
Use `accepted()` when the application needs to know whether the value may be
treated as applied. A rejected hardware command must leave the application and
SDK state unchanged.
The public value types are Boolean, `int64_t`, `float`, `double`, and bounded
text. Public lifecycle and diagnostic enums are defined in the exported SDK
headers. Avoid depending on generated protocol types or private adapter
classes.
## Facade status methods [#facade-status-methods]
Custom Arduino applications can inspect lifecycle boundaries without reaching
into the transport implementation:
| Method | Use |
| --- | --- |
| `networkConnected()` | The application network is available. |
| `tlsReady()` | The TLS or secure transport prerequisites are ready. |
| `runtimeReady()` | The authenticated Flova runtime is ready. |
| `ready()` | The facade can perform normal device work. |
| `status(output)` | Copy a bounded status snapshot for diagnostics. |
| `setStatusListener(...)` | Observe edge-triggered lifecycle changes. |
| `startProvisioning()` | Clear the Flova session path and wait for a new handoff. |
| `factoryReset()` | Reset Flova-owned device state through the facade. |
Status is useful for a product indicator or maintenance screen. It does not
replace an accepted command or a fresh telemetry check.
## Firmware and power methods [#firmware-and-power-methods]
Target facades may expose these product lifecycle operations:
| Method | Use |
| --- | --- |
| `setFirmwareTarget(target)` | Set the target identifier reported by the image. |
| `enableOta(enabled)` | Enable or disable the target's OTA path. |
| `setOtaProfile(...)` | Describe the target's OTA strategy and boot layout. |
| `setRestartHandler(...)` | Let the application own the restart action. |
| `restartRequired()` | Check whether the runtime requests a restart. |
| `prepareForPowerDown()` | Quiesce SDK work before board-owned sleep or power loss. |
Use only methods supported by the selected target. A Linux supervisor, ESP32
boot layout, and ESP8266 staged updater have different ownership boundaries.
## Common result handling [#common-result-handling]
```cpp
const flova::WriteResult result = FLOVA_REPORT(sensor, value);
if (!result.accepted()) {
logReportFailure(result.status, result.reason);
}
```
An accepted result means the SDK accepted the operation at its boundary. For
MQTT, continue calling `run()` and verify the resulting latest value or history
in Console. For a hardware write, acceptance should mean that the handler
accepted the requested state.
## Header selection [#header-selection]
| Include | Use |
| --- | --- |
| `` | Simple Arduino sketches and the normal public entry point. |
| `` | Direct ESP32 facade access. |
| `` | Direct ESP8266 facade access. |
| `` | Direct ESP32 universal composition. |
| `` | Direct ESP8266 universal composition. |
| `` | Linux device applications. |
| `` | Portable core integrations. |
Prefer the umbrella header until the application needs a target-specific
constructor or lifecycle method.
# Transports and connection (/en/docs/sdk/transports)
A Transport carries identity, commands, reports, configuration, and presence
between the device and Flova. The Transport is a deployment decision. It should
not change Datastream keys, value types, hardware handlers, or the Dashboard
contract used by the application.
The normal native path is **Flova Link**. MQTT is available when an existing
MQTT architecture, gateway, or operational tool is part of the product. Both
paths still require separate checks for network readiness, authenticated
Connection, Template binding, accepted Report, Latest Value, and History.
## Flova Link [#flova-link]
FlovaEsp32 and FlovaEsp8266 use Flova Link by default.
The SDK manages the authenticated device session, bounded messages, Datastream
binding, cached state, command delivery, and reconnect work. The application
owns Wi-Fi, Ethernet, GPIO, sensors, power policy, and long-running work
according to the selected facade.
~~~cpp
FlovaEsp32 device;
auto relay = FLOVA_DATASTREAM(device, bool, "relay");
void loop() {
serviceHardware();
device.run();
}
~~~
A connected Link session does not mean every Datastream is ready. Wait until
the runtime and the published Template have been accepted before depending on a
restored value. When debugging a missing value, verify the exact key, value
type, Report result, Latest Value, and History in Console.
## Wi-Fi with Flova Link [#wi-fi-with-flova-link]
Universal ESP32 and ESP8266 compositions can own the Wi-Fi setup path. A
custom application owns it explicitly:
~~~cpp
#include
#include
FlovaEsp32 device;
void setup() {
WiFi.begin("your-wifi", "your-password");
device.begin();
}
void loop() {
device.run(WiFi.status() == WL_CONNECTED);
}
~~~
The application must keep credentials out of source control and decide how to
handle a missing network, a changed access point, and a device that has never
completed Provisioning. The SDK can reconnect its Flova session, but it cannot
invent a valid Wi-Fi credential or repair an antenna, power, DHCP, or radio
problem.
For a product that owns its own captive portal or Web Server, keep that setup
flow in the application and pass the completed Flova Provisioning handoff to
the SDK. Once the handoff is committed, close temporary setup resources before
starting normal telemetry.
## Ethernet with Flova Link [#ethernet-with-flova-link]
Ethernet is useful when the product has stable power, a wired installation, or
a network policy that does not allow Wi-Fi. An ESP32 LAN8720 composition can
provide the network to FlovaEsp32Ethernet; the application still
supplies PHY configuration and board-specific startup.
~~~cpp
FlovaEsp32Ethernet device(EthernetConfig{
.phyAddress = 1,
.powerPin = 16,
.clockMode = ETH_CLOCK_GPIO0_IN,
});
~~~
The exact constructor depends on the target facade. Validate the board
schematic before choosing boot pins, RMII pins, power control, DHCP behavior,
and the PHY clock. A successful compile proves none of physical link, IP
assignment, TLS readiness, or accepted hardware commands.
If the board uses another Ethernet chip or TCP/IP stack, keep that driver
outside the Datastream layer. Supply a bounded Link implementation or use the
supported Ethernet facade rather than changing application Datastream code.
## MQTT [#mqtt]
MQTT is an optional compatibility Transport. It fits a product that already
has a maintained MQTT Client, a Gateway that routes device traffic through
MQTT, or established broker tooling and observability. It adds application
owned responsibilities, so use it deliberately.
The application owns the Wi-Fi or Ethernet Client, DNS, socket lifetime, TLS
trust store, MQTT Client, broker reconnect policy, and local watchdog. The SDK
supplies Flova device topics, presence behavior, command delivery, the
Datastream JSON envelope, a bounded queue, and integration with the typed
Datastream facade.
~~~cpp
#include
#include
#include
WiFiClientSecure socket;
PubSubClient mqtt(socket);
FlovaEsp32 device(mqtt);
void setup() {
socket.setCACert(FLOVA_ROOT_CA);
mqtt.setServer("mqtt.flova.ir", 8883);
device.begin(deviceId, deviceSecret);
}
void loop() {
maintainWifi();
device.run();
}
~~~
Use the device UUID as the MQTT username and the device secret as the
password. The broker endpoint is mqtts://mqtt.flova.ir:8883. Keep
certificate verification enabled. A Workspace API key is not a device
password and must not be placed in a firmware bundle or used as the MQTT
password.
The device publishes on its up side and subscribes on its
down side. The SDK handles the documented Flova topics and message
envelope. Application code should register typed Datastreams and handlers
rather than constructing private topics. Use the lower level message API only
when the public facade cannot express a real product requirement.
### MQTT connection sequence [#mqtt-connection-sequence]
An MQTT connection has more than one successful step. First, the application
must bring up Wi-Fi or Ethernet and obtain a usable network path. Next, DNS,
TCP, TLS certificate verification, and the MQTT session must succeed. The SDK
then authenticates the device identity, restores session state, binds the
published Template, and starts the normal command and Report path.
Keep these steps visible in diagnostics. An open socket proves only that a
network path exists. MQTT presence proves a broker session. Runtime readiness
proves that the device identity is accepted. Datastream readiness proves that
declared keys match the published Template. An accepted Report proves that a
particular value entered the SDK path. Latest Value and History prove that the
value reached the Flova data path.
### MQTT loop and reconnect behavior [#mqtt-loop-and-reconnect-behavior]
Call device.run() from the normal cooperative loop. Do not call it
only after a sensor changes or place it behind a long delay. The SDK needs
regular execution to process commands, advance reconnect work, publish
presence, and flush queued messages.
Keep Wi-Fi or Ethernet maintenance separate from Datastream logic. A reconnect
attempt should not erase the local cache or reset hardware outputs unless the
product explicitly chooses that policy. After reconnecting, verify whether the
stream policy restores the last accepted value or requires a fresh hardware
Report.
If the broker is unavailable, keep the application responsive and expose a
bounded offline state. Do not spin in a tight reconnect loop. Use the target's
backoff and watchdog policy, and keep a wired recovery path while developing
TLS, memory, or broker configuration.
### MQTT boundaries and message size [#mqtt-boundaries-and-message-size]
Device MQTT messages are limited to 2,048 bytes. A Report that exceeds the
limit, arrives while the adapter is unavailable, or exhausts the bounded queue
returns a failure result. A successful enqueue means that the SDK accepted the
message locally; it does not prove that the broker, Engine, Latest Value, or
History received it.
Use several typed Datastreams for independent values and report at a sensible
rate. Reduce text and JSON fields that do not belong in the public Template.
Never solve a message size problem by silently truncating a command or sensor
value. Log a bounded error and keep the previous accepted state when a Report
cannot be queued.
### MQTT security and ownership [#mqtt-security-and-ownership]
Use TLS certificate verification and a device specific identity. Protect the
device secret in the selected Storage service and never print it in logs,
status pages, MQTT payloads, or Provisioning diagnostics. Rotate or replace
the identity through the product's supported Provisioning or maintenance flow.
The MQTT Client belongs to the application. Choose its socket buffer, keepalive,
callback limits, and reconnect timing for the target's memory and power budget.
Keep callbacks short; hand work to the application loop instead of performing
sensor access, file writes, or long network requests inside an MQTT callback.
## Bluetooth and other Provisioning channels [#bluetooth-and-other-provisioning-channels]
Bluetooth is normally a setup channel, not the device's long term telemetry
Transport. An ESP32 BLE flow can carry a short lived Provisioning handoff while
the application owns pairing, framing, timeout, and user interaction. After
the handoff is durably accepted, release BLE resources and start Wi-Fi,
Ethernet, Flova Link, or MQTT.
The same boundary applies to Serial, a factory tool, or a local Ethernet setup
page. The setup channel carries the bounded handoff; it does not replace the
authenticated runtime Connection. Keep the activation token out of logs and
do not send it again on every boot.
## Keep application code Transport neutral [#keep-application-code-transport-neutral]
Declare Datastreams and handlers once, then choose the constructor that matches
the deployment:
~~~cpp
auto temperature = FLOVA_DATASTREAM(device, float, "temperature");
auto relay = FLOVA_DATASTREAM(device, bool, "relay");
void loop() {
FLOVA_REPORT(temperature, readTemperature());
device.run();
}
~~~
The keys, types, callbacks, local cache, and Dashboard contract do not change
when the Transport changes. Keep Wi-Fi setup, Ethernet configuration, TLS
certificates, MQTT Client construction, and Bluetooth setup outside Datastream
logic.
## Connection readiness [#connection-readiness]
Use separate readiness boundaries in product UI and diagnostics:
| Check | What it proves |
| --- | --- |
| Network ready | Wi-Fi or Ethernet has the conditions required by the application. |
| Transport connected | Flova Link or the MQTT session is connected. |
| Runtime ready | Device identity and the Flova runtime are authenticated. |
| Datastream ready | Declared keys are bound to the published Template. |
| Accepted Report | One specific value passed validation and entered the Transport path. |
| Latest Value and History | The value reached the Flova data path and was stored as expected. |
Use facade status methods or a status listener for indicators. Do not show a
green “connected” label when the application has only opened a socket.
## Choosing a Transport [#choosing-a-transport]
Use Flova Link for the normal native device Connection and the smallest
application surface. Use MQTT when the product already owns a broker Client or
requires MQTT routing. Use a custom Link Adapter when a board or Gateway has a
different bounded carrier and can implement the public service boundary. Keep
portable flova::Device independent from Arduino and network APIs.
Changing Transport does not change the Console Template. It changes the device
Connection, ownership of network services, and the operational checks required
during deployment.
# Studio overview (/en/docs/studio/overview)
Build dashboards in Studio.