إنتقل إلى المحتوى الرئيسي

HTTP API

تناسب واجهة HTTP API الأجهزة التي لا تستطيع إبقاء اتصال مفتوح، والشبكات التي لا تسمح إلا بحركة HTTPS العادية، ومراحل التطوير الأولى للبرنامج الثابت (firmware): فخلافاً لـ MQTT، يجيبك كل طلب بما فعلته المنصة بكل قراءة أرسلتها.

عنوان URL الأساسي

https://api.sensocan.com/api/v1

المصادقة

يحمل كل طلب رمز وصول الجهاز كرمز Bearer:

Authorization: Bearer {DEVICE_ACCESS_TOKEN}

احصل على الرمز من تفاصيل الجهازعرض الرمز. يخصّ الرمز جهازاً واحداً، ويجب أن يكون عنوان URL الذي ترسل إليه هو UUID الجهاز نفسه.

تفاصيل الجهاز بعد الضغط على عرض الرمز: مربع حوار رمز الجهاز مفتوح ورمز الوصول ظاهر إلى جانب زر النسخ، ليرى القارئ من أين يأتي رمز Bearer.
تفاصيل الجهاز بعد الضغط على عرض الرمز: مربع حوار رمز الجهاز مفتوح ورمز الوصول ظاهر إلى جانب زر النسخ، ليرى القارئ من أين يأتي رمز Bearer.
إعادة إنشاء الرمز تُخرِج الجهاز من الخدمة

يصدر إجراء إعادة الإنشاء في مربع الحوار نفسه رمزاً جديداً ويُبطل القديم في الحال. وكل جهاز يستخدم الرمز القديم يبدأ بتلقّي 401 حتى تبرمج الرمز الجديد عليه.

الترويسات (headers)

الترويسةالقيمةمطلوبة
AuthorizationBearer {DEVICE_ACCESS_TOKEN}نعم
Content-Typeapplication/jsonنعم
Acceptapplication/jsonمستحسنة: بدونها تعود استجابة حد المعدل (rate limit) صفحة HTML بدلاً من JSON

نقاط النهاية (endpoints)

1. قراءة واحدة لمستشعر واحد

POST /devices/{device_uuid}/sensors/{sensor}/readings

{sensor} هو إما المعرّف النصي (slug) للمستشعر أو UUID الخاص به، وكلاهما معروض في صفحة المستشعر.

{
"data": {
"value": 25.5,
"timestamp": "2026-09-03T10:00:00Z"
},
"battery_voltage": 3.7
}
الحقلالنوعمطلوبملاحظات
dataكائننعمقراءة واحدة فقط. استخدم نقطة النهاية المجمّعة لعدة قراءات
data.valueرقمنعمالقيم غير الرقمية مرفوضة
data.timestampنص بصيغة ISO 8601لاالقيمة الافتراضية هي وقت وصول الطلب
battery_voltageرقم (بالفولت)، 0–100لايأتي بجوار data لا داخله

يُحفظ أي مفتاح آخر داخل data كبيانات وصفية مرافقة للقراءة؛ راجع القواعد المشتركة لحمولة البيانات (payload).

2. عدة قراءات لمستشعر واحد

POST /devices/{device_uuid}/sensors/{sensor}/readings/bulk
{
"data": [
{ "value": 22.1, "timestamp": "2026-09-03T09:00:00Z" },
{ "value": 22.4, "timestamp": "2026-09-03T09:15:00Z" },
{ "value": 22.8, "timestamp": "2026-09-03T09:30:00Z" }
],
"battery_voltage": 3.6
}

يجب أن يكون data مصفوفة تضم عنصراً واحداً على الأقل، ويتبع كل عنصر القواعد نفسها الموضحة أعلاه لـ data.

3. قراءات لعدة مستشعرات

POST /devices/{device_uuid}/readings
{
"data": [
{
"sensor_slug": "temp_01",
"value": 25.5,
"timestamp": "2026-09-03T10:00:00Z"
},
{ "sensor_uuid": "7a8b9c0d-1234-5678-90ab-cdef12345678", "value": 60.2 },
{ "sensor_slug": "door_01", "value": 1 }
],
"battery_voltage": 3.7
}

يسمي كل عنصر مستشعره بنفسه عبر sensor_slug أو sensor_uuid، وأحدهما مطلوب. استخدم نقطة النهاية هذه مع جهاز يضم عدة مستشعرات: ثلاثة طلبات منفصلة تؤدي العمل نفسه ثلاث مرات.

ماذا تخبرك الاستجابة

كل طلب تمرّ منه قراءة واحدة على الأقل يجيب بـ 202 Accepted:

{
"message": "Readings accepted and queued for rule chain processing.",
"accepted": 3,
"duplicates": 0,
"rejected": {},
"sensor": "temp_01"
}
الحقلالمعنى
acceptedالقراءات التي سُلِّمت إلى سلسلة القواعد
duplicatesالقراءات التي تبيّن أنها تكرار لشيء أُرسل من قبل. تُحتسب نجاحاً، فإعادة إرسال المخزن المؤقت آمنة
rejectedأسباب الإهمال التي وقعت مع عدد كل سبب. تكون فارغة ({}) عندما لا يُهمَل شيء
sensorالمعرّف الذي وضعته في عنوان URL، معاداً إليك. يظهر فقط في نقطتَي النهاية الخاصتين بمستشعر واحد

النجاح الجزئي يبقى 202: خمس قراءات مرسلة، ثلاث منها مقبولة واثنتان مرفوضتان، تعطيك 202 مع التفصيل. اقرأ الأرقام، ولا تعتبر رمز الحالة وحده دليلاً على أن "كل شيء قد وصل".

"مقبول" تعني في قائمة الانتظار، لا مخزَّنة

تُسلَّم القراءة المقبولة إلى سلسلة القواعد التي تنطبق على ذلك المستشعر، والسلسلة هي التي تقرر ما يحدث لها، بما في ذلك حفظها من عدمه. وسلسلة بلا خطوة حفظ تنتج هذا بالضبط: استجابات 202 سليمة ولا بيانات في أي مكان في الواجهة. يبدأ كل حساب بـ سلسلة القواعد الافتراضية التي تحفظ القراءات؛ فإن بنيت سلسلتك الخاصة، فتحقق منها في الإدارة ← سلاسل القواعد.

أسباب الرفض

المفاتيح التي يمكن أن تظهر داخل rejected:

المفتاحما معناهكيف تعالجه
dropped_unknown_sensorالمعرّف لم يطابق أي مستشعر على هذا الجهازقارنه بقيمة slug وبـ UUID في صفحة المستشعر. المطابقة تامة وتراعي حالة الأحرف
dropped_missing_identifierعنصر في الدفعة لا يحمل sensor_slug ولا sensor_uuidامنح كل عنصر أحد المعرّفين
dropped_missing_valueقراءة بلا valueأرسل value مع كل قراءة، ولا ترسل null لعينة فاشلة بل تجاوزها
dropped_invalid_shapeبنية data لا تطابق نقطة النهايةأرسل كائناً إلى نقطة النهاية المفردة، ومصفوفة إلى المجمّعة وإلى نقطة الدفعات
dropped_future_timestampطابع زمني ظل متقدماً على وقت الخادم بعد تصحيح الساعةأرسل طابعاً زمنياً بصيغة ISO 8601، أو احذفه ليُستخدم وقت الوصول
dropped_duplicateالقيمة نفسها للمستشعر نفسه وصلت مرة أخرى ضمن نافذة كبت التكرارلا شيء تعالجه. يُبلَّغ عنها في duplicates ولا تظهر أبداً داخل rejected

الأخطاء

رمز الحالةجسم الاستجابةالسبب والحل
401{"message":"Device authentication token required.","error":"missing_token"}لا توجد ترويسة Authorization، أو أنها ليست بصيغة Bearer …
401{"message":"Invalid device authentication token.","error":"invalid_token"}الرمز لا يخص الجهاز المذكور في عنوان URL، أو أُعيد إنشاؤه
404{"message":"Device not found.","error":"device_not_found"}قيمة {device_uuid} في عنوان URL ليست جهازاً. انسخها مرة أخرى من تفاصيل الجهاز
404{"message":"No reading matched a sensor on this device.","error":"sensor_not_found","sensors":["temp_01"]}لا شيء في الحمولة يشير إلى مستشعر حقيقي. يسرد sensors المعرّفات التي لم تطابق شيئاً
422{"message":"Validation failed.","errors":{"data.value":["The sensor value is required."]}}جسم الطلب مشوّه البنية. يسمي errors الحقل المخالف
422{"message":"No readings were accepted.","error":"no_readings_accepted","rejected":{"dropped_missing_value":2}}الجسم صالح لكن كل القراءات أُهملت. يوضح rejected السبب
429{"message":"Too Many Attempts."}بلغت حد المعدل. تراجع وأعد المحاولة، وانظر أدناه

أسباب شائعة لفشل التحقق خلف 422 Validation failed: data مفقود أو فارغ، value مفقود أو ليس رقماً، timestamp بصيغة تاريخ غير قابلة للتحليل، عنصر في الدفعة بلا sensor_slug ولا sensor_uuid، battery_voltage خارج المدى 0–100.

حد المعدل

الحد هو 1000 طلب في الدقيقة. ويُحتسب لكل عنوان مصدر، لذا تتقاسم عدة أجهزة خلف اتصال إنترنت واحد الحصة نفسها.

الترويسةمتى تظهرالمعنى
X-RateLimit-Limitكل استجابةالسقف: 1000
X-RateLimit-Remainingكل استجابةالطلبات المتبقية في النافذة الحالية
Retry-After429 فقطعدد الثواني قبل إعادة المحاولة
X-RateLimit-Reset429 فقطموعد إعادة ضبط النافذة

التزم بـ Retry-After بدل إعادة المحاولة فوراً، وضاعف فترة الانتظار أسّياً إن ظللت تبلغ الحد. وإذا اقترب جهاز من الحد، فاجمع مستشعراته في طلب واحد بدل إرسال طلب لكل مستشعر.

مثال عملي

curl -X POST \
https://api.sensocan.com/api/v1/devices/a1b2c3d4-e5f6-7890-abcd-ef1234567890/readings \
-H "Authorization: Bearer your-device-access-token" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"data": [
{ "sensor_slug": "temp_01", "value": 25.5 },
{ "sensor_slug": "humidity_01", "value": 60.2 }
],
"battery_voltage": 3.7
}'
{
"message": "Readings accepted and queued for rule chain processing.",
"accepted": 2,
"duplicates": 0,
"rejected": {}
}

التعامل مع الاستجابات في البرنامج الثابت

  • 202: امسح من مخزنك المؤقت كل ما احتُسب في accepted وduplicates. القراءة الواردة في rejected لن تنجح عند إعادة المحاولة، فسجّلها بدل إعادة إرسالها بلا نهاية.
  • 401 و404: مشكلة في الإعدادات لا عطل عابر. أوقف إعادة المحاولة وأبلغ عنها حيث يراها مشغّل.
  • 422: خلل في البرنامج الثابت. سجّل جسم الاستجابة، فهو يسمي الحقل المخالف.
  • 429: انتظر عدد الثواني المذكور في Retry-After ثم أعد المحاولة.
  • 5xx أو بلا استجابة: عطل عابر. ضاعف فترة الانتظار أسّياً وأبقِ القراءات في المخزن المؤقت؛ فالطوابع الزمنية تجعل التعبئة اللاحقة دقيقة، والساعة المتقدمة لا تكلفك شيئاً.

استكشاف الأخطاء وإصلاحها

استجابات 202 لكن لا بيانات في أي مكان. افتح تفاصيل الجهاز. يعرض جدول المستشعرات لكل مستشعر القيمة الحالية وآخر تحديث.

جدول المستشعرات في تفاصيل الجهاز يعرض مستشعراً واحداً على الأقل له قيمة حالية وطابع زمني لآخر تحديث، ومستشعراً آخر ما زال يعرض «لا توجد بيانات»، ليظهر الفرق جنباً إلى جنب.
جدول المستشعرات في تفاصيل الجهاز يعرض مستشعراً واحداً على الأقل له قيمة حالية وطابع زمني لآخر تحديث، ومستشعراً آخر ما زال يعرض «لا توجد بيانات»، ليظهر الفرق جنباً إلى جنب.

إذا كان آخر اتصال يتحدث بينما تعرض كل المستشعرات "لا توجد بيانات"، فسلسلة القواعد لا تحفظ القراءات؛ تحقق من الإدارة ← سلاسل القواعد. وإذا تحدّث بعض المستشعرات دون بعضها، فمعرّفات الصامتة منها لا تطابق أي مستشعر على هذا الجهاز، وهذا ما كان يقوله جسم 404 وأعداد rejected.

كل شيء يعيد 401. تأكد من أن الرمز لم يُعَد إنشاؤه، وأن UUID الجهاز في عنوان URL يخص الجهاز الذي يعود إليه هذا الرمز. الرمز الذي يعمل مع جهاز يُرفض مع جهاز آخر.

القراءات المخزّنة مؤقتاً تعود بوصفها تكرارات. هذه هي الاستجابة المتوقعة لإعادة الإرسال. اعتبرها قد وصلت وتابع تفريغ مخزنك المؤقت.