ربط أجهزة الحضور بنظام Tarleaks ERP
أجهزة ZKTeco وeSSL (ADMS)، وأجهزة Hikvision، وبرنامج الربط المحلي لكل الأجهزة الأخرى، وواجهة البصمات البرمجية مع أمثلة، واستيراد ملفات السجل — وما لا يُحفظ أبداً.
آخر تحديث
هذا الدليل موجّه لمسؤول تقنية المعلومات أو شركة التكامل أو مسؤول الموارد البشرية الذي يربط أجهزة البصمة والوجه والبطاقات بنظام Tarleaks ERP. وفي كل صفحة جهاز داخل Tarleaks رابط إلى هذا الدليل من تبويب «الربط».
لمن هذا الدليل، والخلاصة في دقيقة
الأجهزة المبيعة في الإمارات ودول الخليج لا تستخدم معياراً واحداً للربط. لذلك يوفّر Tarleaks باباً آمناً واحداً لاستقبال البصمات — واجهة برمجية عبر HTTPS بمفتاح خاص لكل جهاز — وخمس طرق للوصول إليه. ابحث عن جهازك في الجدول واتبع القسم الخاص به.
| جهازك | ما المطلوب | القسم |
|---|---|---|
| ZKTeco أو eSSL أو جهاز مشابه في قائمته COMM ← Cloud Server Setting (أو ADMS) | اكتب عنواننا في قائمة الجهاز. لا حاجة لتثبيت أي برنامج. | أجهزة ZKTeco وeSSL (ADMS) |
| جهاز تحكم بالدخول من Hikvision (يُضبط من صفحته على المتصفح) | اضبط خادم HTTP فيه على عنواننا. لا حاجة لتثبيت أي برنامج. | أجهزة Hikvision |
| جهاز متوافق مع ZKTeco على شبكة مكتبك (منفذ TCP رقم 4370)، أو جهاز Hikvision لا يصل إلى الإنترنت، أو جهاز ZKTeco قديم لا يعمل إلا عبر http، أو أي علامة تجارية يحفظ برنامجها السجل في مجلد مشترك | ثبّت برنامج الربط المحلي الصغير على جهاز كمبيوتر في الموقع. | برنامج الربط المحلي |
| أي علامة تجارية أخرى | استورد ملفها المصدَّر، أو اجعل برنامجها يستدعي واجهة البصمات البرمجية. | استيراد ملف الجهاز، مرجع واجهة البصمات البرمجية |
| برنامجك الخاص أو برنامج شركة تكامل | استدعِ واجهة البصمات البرمجية. | مرجع واجهة البصمات البرمجية |
| جهاز لا يحفظ سجله إلا على ذاكرة USB | استورد الملف من وقت لآخر. | استيراد ملف الجهاز |
جهاز الكشك اللوحي الذي يعمل بتطبيق Tarleaks لا يتناوله هذا الدليل: اقرنه من الإعدادات ← الحضور ← الكشك.
كيف يعمل الربط
كل الطرق تنتهي في المكان نفسه: الجهاز ← (ربط مباشر، أو برنامج الربط المحلي، أو ملف، أو برنامجك) ← صندوق البصمات لذلك الجهاز في Tarleaks ← مطابقة الأشخاص (من هو مستخدم الجهاز رقم 1001؟) ← تسجيلات حضور في سجل وقت كل موظف، مع تنبيه للمراجعة عند وجود ما يستدعي ذلك.
ما يُحفظ لكل بصمة: الجهاز، ورقم المستخدم على الجهاز، والوقت، والدخول أو الخروج (إن حدده الجهاز)، وطريقة التحقق (بصمة إصبع، وجه، بطاقة، رقم سري، كف)، والعنوان الذي وصلت منه وطريقة وصولها. ولكل مستخدم على الجهاز: رقمه والاسم المسجّل على الجهاز ورقم البطاقة.
ما لا يُحفظ ولا يُطلب ولا يُقرأ أبداً: قوالب بصمات الأصابع، وقوالب الوجه، والصور، وقراءات الحرارة والكمامة، وكلمات مرور المستخدمين، وكلمات مرور الجهاز نفسه. تُبلَّغ أجهزة ZKTeco بعدم إرسال القوالب أو الصور، وأي شيء يرسله الجهاز رغم ذلك يُتلف دون قراءته، التزاماً بقانون حماية البيانات الشخصية في دولة الإمارات.
مدة الاحتفاظ:
| البيانات | مدة الاحتفاظ |
|---|---|
| البصمات التي أصبحت تسجيلات حضور، والقراءات المكررة، والبصمات التي تنتظر المراجعة | 24 شهراً افتراضياً (الإعدادات ← الحضور ← أجهزة الحضور ← إعدادات متقدمة: من 6 إلى 120 شهراً) |
| البصمات غير المطابقة لأي موظف، والبصمات المستبعدة، والبصمات المرفوضة | 90 يوماً |
| عنوان المرسِل والسطر الخام من الجهاز المحفوظان مع كل بصمة | يُحذفان بعد 90 يوماً |
| الأجهزة التي حاولت الاتصال ولم تُضف | 30 يوماً |
| أوامر الأجهزة المنتهية | 90 يوماً |
| مستخدمو الأجهزة غير المطابقين الذين لم يظهروا طوال مدة الاحتفاظ بالبصمات | يُحذفون |
أما تسجيلات الحضور نفسها فهي سجلات وقت عادية تتبع مدة الاحتفاظ المعتادة لديكم.
قبل أن تبدأ
- عنوان مساحة العمل. وهو
https://<company>.tarleaks.com— العنوان الذي تفتح به Tarleaks. في التثبيت على خوادمكم، هو عنوان التثبيت نفسه (TARLEAKS_URLفي ملف.env)، وتعرضه لك تبويبة الاتصال في صفحة الجهاز مع المنفذ الصحيح. وإذا كان العنوانhttp://عاديًا داخل شبكة المكتب، تذكر الخطوات ذلك ويبقى خيار HTTPS في الجهاز مُطفأً. - من يستطيع ذلك. إضافة الأجهزة وتعديلها تحتاج صلاحية الحضور — الأجهزة — تعديل (لدى دوري مدير المؤسسة ومدير الموارد البشرية). مطابقة مستخدمي الأجهزة بالموظفين تحتاج صلاحية بصمات الأجهزة — معالجة (مدير المؤسسة، مدير الموارد البشرية، أخصائي الموارد البشرية). استيراد ملف السجل يحتاج صلاحية بصمات الأجهزة — استيراد (مدير المؤسسة، مدير الموارد البشرية)، لأنه ينشئ تسجيلات حضور لموظفين آخرين. ويستطيع المدراء رؤية الأجهزة ومعرفة إن كانت متصلة.
- التفعيل. يجب أن يكون الإعدادات ← الميزات ← الحضور ← أجهزة الحضور مفعّلاً (وهو مفعّل افتراضياً). عند إيقافه تُرفض الأجهزة ولا تُستقبل بصماتها؛ وتبقى الأجهزة المضافة ظاهرة، ويمكنك أرشفة الجهاز أو استبدال مفتاحه.
- السماح بتسجيل الحضور من الأجهزة. يجب أن تتضمن الإعدادات ← الحضور ← المصادر المسموح بها خيار أجهزة الحضور. بدونه تصل البصمات لكنها تنتظر المراجعة بدل أن تصبح تسجيلات حضور.
- المنطقة الزمنية. تحتفظ الأجهزة بالتوقيت المحلي. يقرأ Tarleaks أوقات الجهاز بالمنطقة الزمنية للجهاز: المحددة في صفحة الجهاز، وإلا الافتراضية في الإعدادات ← الحضور ← أجهزة الحضور ← إعدادات متقدمة، وإلا منطقة مساحة العمل. اضبط ساعة الجهاز على المنطقة نفسها.
- الشبكة. الأجهزة وبرنامج الربط المحلي يفتحون اتصالات صادرة فقط عبر HTTPS على المنفذ 443 إلى عنوان مساحة العمل. لا حاجة لفتح أي منفذ وارد في جدار الحماية. ولا نقبل http العادي (المنفذ 80) — فالمفتاح يجب ألا يمر عبر الإنترنت دون تشفير. (أما التثبيت على خوادمكم داخل شبكة المكتب فيتبع عنوانه هو: تستخدم أجهزته البروتوكول والمنفذ اللذين تعرضهما تبويبة الاتصال.)
ثم انتقل إلى الحضور ← أجهزة الحضور ← إضافة جهاز. يسألك المعالج عن نوع الجهاز واسمه وموقع العمل، ثم يعرض مفتاح الاتصال للجهاز مرة واحدة، يليه الخطوات الدقيقة لذلك الجهاز.
نموذج الأمان
مفتاح الاتصال. لكل جهاز مفتاحه الخاص: atd_ يليها 48 حرفاً ورقماً (52 خانة). يُعرض مرة واحدة فقط عند إضافة الجهاز أو استبدال المفتاح. لا يحفظ Tarleaks إلا بصمة تشفير أحادية الاتجاه له (SHA-256)، فلا يستطيع أحد — ولا نحن — عرضه مرة أخرى. تبقى أول 12 خانة (مثل atd_k3v7q2ma) ظاهرة في صفحة الجهاز لتمييز المفاتيح عن بعضها. زر إصدار مفتاح جديد يستبدله فوراً: يتوقف المفتاح القديم عن العمل من الطلب التالي. وأرشفة الجهاز توقف مفتاحه كذلك.
احمِ قائمة الجهاز. يعرض جهاز ZKTeco عنوان الخادم — ومعه المفتاح — في قائمته. اضبط كلمة مرور للمسؤول على الجهاز (Menu ← User Mgt ← اجعل أحد المستخدمين Administrator) حتى لا يستطيع أحد قراءة المفتاح منه. وفي Hikvision اضبط كلمة مرور قوية لصفحة الإعدادات.
عنوان المفتاح وعنوان الرقم التسلسلي. تستخدم أجهزة ZKTeco عادة عنوان المفتاح (<company>.tarleaks.com/zk/<key>). بعض الطرازات القديمة فيها حقل لعنوان الخادم لا يقبل مساراً؛ ولهذه يوجد عنوان الرقم التسلسلي (<company>.tarleaks.com فقط). ولأن الرقم التسلسلي مطبوع على العلبة وليس سراً، فهذا العنوان معطّل افتراضياً، وعند تفعيله لا يعمل إلا لرقم تسلسلي أدخله مسؤول بنفسه ومن عناوين الإنترنت التي سمحت بها فقط. باختصار: «الرقم التسلسلي فقط» تعني من يعرف الرقم التسلسلي ويتصل من عنوان سمحت به. استخدم عنوان المفتاح متى قبله الجهاز.
العناوين المسموح بها. يمكن قصر أي جهاز على عنوان (أو عناوين) الإنترنت لمكتبك: صفحة الجهاز ← الربط ← العناوين المسموح بها (عنوان واحد أو نطاق مثل 94.56.10.0/24؛ حتى 20). يُرفض أي طلب من عنوان آخر. وعندما يصل طلب يستخدم الرقم التسلسلي لجهاز من عنوان لم تسمح به، تعرض صفحة الجهاز كل هذه العناوين (حتى 5، مع عدد المحاولات وتوقيتها). ويستطيع أي شخص يعرف الرقم التسلسلي إرسال مثل هذا الطلب، لذلك لا يُعرض للسماح بنقرة واحدة إلا العنوان الذي تستخدمه أنت؛ أما أي عنوان آخر فيجب كتابته مرة أخرى للتأكيد. ولا يُسمح بأي عنوان تلقائياً.
HTTPS فقط. كل مسارات الأجهزة تعمل عبر HTTPS فقط. الجهاز القديم الذي لا يدعم HTTPS يتصل عبر وسيط ADMS في برنامج الربط المحلي على شبكتك.
الحدود. لكل جهاز 120 طلباً في الدقيقة، ويُحسب الطلب الذي يحمل بصمات كثيرة أكثر من طلب (1 + 1 لكل 50 بصمة). ولكل عنوان إنترنت 300 طلب في الدقيقة و20 طلباً في الوقت نفسه كحد أقصى. ولكل جهاز حتى 50,000 بصمة جديدة و5,000 مستخدم جديد في اليوم، ولكل مساحة عمل 500,000 بصمة جديدة في اليوم. عند تجاوز الحد يكون الرد 429 مع ترويسة Retry-After، ولا يضيع شيء بالانتظار.
ما يُسجَّل. كل دفعة تُستقبل تُكتب في سجل تدقيق الحضور مع الجهاز وعنوان المرسل. سجلات الخادم تحفظ المسار العام، ولا تحفظ أبداً العنوان الذي يحمل المفتاح.
أجهزة تحاول الاتصال. جهاز ZKTeco مضبوط على عنوان الرقم التسلسلي قبل إضافته يظهر في الحضور ← أجهزة الحضور بعبارة «يحاول الاتصال» مع رقمه التسلسلي وعنوانه. لإضافته تكتب الرقم التسلسلي من ملصق الجهاز أو شاشة System Info بنفسك — فهو لا يُعبّأ تلقائياً.
أجهزة ZKTeco وeSSL (ADMS)
تعمل مع أجهزة ZKTeco وeSSL وغيرها مما يوفّر في برنامجه Cloud Server Setting أو ADMS مع HTTPS. تختلف أسماء القوائم قليلاً بين الطرازات وإصدارات البرامج.
- أضف الجهاز في Tarleaks: الحضور ← أجهزة الحضور ← إضافة جهاز ← ZKTeco أو eSSL أو مشابه. انسخ مفتاح الاتصال عند ظهوره.
- على الجهاز، اضبط كلمة مرور للمسؤول (Menu ← User Mgt ← اجعل أحد المستخدمين Administrator) حتى لا يقرأ أحد مفتاح الاتصال من قائمته.
- على الجهاز: Menu ← COMM ← Cloud Server Setting (في بعض الطرازات: Comm. ← ADMS).
- فعّل Enable Domain Name.
- Server Address:
<company>.tarleaks.com/zk/<key>— عنوان مساحة العمل، ثم/zk/، ثم مفتاح ربط الجهاز. طول العنوان كاملاً نحو 80 خانة (acme-uae.tarleaks.com/zk/atd_…طوله 77). والجهاز يضيف/iclock/…من تلقاء نفسه. - Server Port: 443.
- HTTPS: تشغيل. Proxy: إيقاف.
- Menu ← System ← Date/Time: اضبط المنطقة الزمنية الظاهرة في تبويب «الربط» للجهاز (في الإمارات: UTC+04:00).
- احفظ، ثم أعد تشغيل الجهاز. يظهر أول اتصال في صفحة الجهاز خلال دقيقة.
صيغ أخرى للعنوان. الصيغة الطويلة <company>.tarleaks.com/api/attendance/public/v1/adms/<key> تعمل بالطريقة نفسها. وإن كان حقل Server Address لا يقبل أي مسار، افتح صفحة الجهاز ← إعدادات متقدمة ← فعّل جهازي فيه حقل لعنوان الخادم فقط، واكتب الرقم التسلسلي للجهاز (من الملصق أو Menu ← System Info)، واسمح بعنوان الإنترنت لمكتبك، واجعل Server Address هو <company>.tarleaks.com فقط.
معلومات مفيدة.
- يجب أن يثق الجهاز بشهادتنا (شهادة Let's Encrypt عامة) وأن يدعم TLS 1.2. بعض البرامج القديمة لا تدعم ذلك؛ وتتصل هذه الأجهزة عبر وسيط ADMS في برنامج الربط المحلي.
- العناوين التي تنتهي بـ
.aspx(برامج eSSL) مدعومة. - Comm Key الخاص بالجهاز لا يُستخدم في هذا الربط.
- يحتفظ الجهاز ببصماته حتى يرد Tarleaks بكلمة «OK»، فالرفع المرفوض أو الفاشل لا يضيع شيئاً — يعيد الجهاز المحاولة ببساطة.
- في أول اتصال يرسل الجهاز البصمات المخزنة لديه؛ والبصمات السابقة للتاريخ الذي اخترته في «جلب البصمات بدءاً من» تُحفظ لكنها تُستبعد.
أجهزة Hikvision
تعمل مع أجهزة التحكم بالدخول والتعرف على الوجه من Hikvision التي تستطيع إرسال الأحداث إلى خادم HTTP (ISAPI «HTTP Listening» أو «Alarm Server»).
- أضف الجهاز في Tarleaks: الحضور ← أجهزة الحضور ← إضافة جهاز ← جهاز Hikvision. انسخ مفتاح الاتصال.
- اضبط كلمة مرور قوية للمسؤول في صفحة إعدادات الجهاز.
- في صفحة إعدادات الجهاز: Configuration ← Network ← Advanced ← HTTP Listening (في بعض الطرازات: Alarm Server).
- Protocol: HTTPS. Address type: domain name. Host:
<company>.tarleaks.com. Port: 443. - URL:
/api/attendance/public/v1/hikvision/<key>/events— ضع مفتاح ربط الجهاز مكان<key>. - Format: JSON. Authentication: none (المفتاح الموجود في العنوان هو بيانات الاعتماد).
- Event ← Access Control ← linkage: فعّل Upload to center (أو Notify surveillance center) لأحداث التحقق.
- System ← Time: خادم NTP هو
pool.ntp.org، والمنطقة الزمنية GMT+04:00 (أو منطقتك). - احفظ واضغط Test. يظهر أول حدث في صفحة الجهاز.
لشركات التكامل، الإعداد نفسه عبر ISAPI:
PUT /ISAPI/Event/notification/httpHosts
Content-Type: application/xml
<HttpHostNotificationList version="2.0" xmlns="http://www.isapi.org/ver20/XMLSchema">
<HttpHostNotification>
<id>1</id>
<url>/api/attendance/public/v1/hikvision/atd_REPLACE_WITH_THE_KEY/events</url>
<protocolType>HTTPS</protocolType>
<parameterFormatType>JSON</parameterFormatType>
<addressingFormatType>hostname</addressingFormatType>
<hostName>yourcompany.tarleaks.com</hostName>
<portNo>443</portNo>
<httpAuthenticationMethod>none</httpAuthenticationMethod>
</HttpHostNotification>
</HttpHostNotificationList>
أي الأحداث تُحتسب بصمة. حدث الدخول (النوع الرئيسي 5) الذي رمزه الفرعي 1 أو 38 أو 75 أو 113 ويحمل رقم موظف يصبح بصمة. أحداث الدخول الأخرى — رفض فتح الباب مثلاً — تُحفظ بوصف «ليس حدث مرور» لتراها؛ ولاحتساب رموز إضافية أضفها في صفحة الجهاز ← إعدادات متقدمة ← رموز الأحداث المقبولة. نبضات الاتصال تُسجَّل اتصالاً فقط. وتُحفظ حالة attendanceStatus في الجهاز (دخول، خروج، استراحة، عمل إضافي) كدخول أو خروج. ولا تُحفظ الصور أو قراءات الحرارة والكمامة أبداً.
جهاز Hikvision الذي لا يصل إلى الإنترنت يمكن لبرنامج الربط المحلي قراءته بدلاً من ذلك (adapter = hik_isapi).
مرجع واجهة البصمات البرمجية
هي الواجهة نفسها التي يستخدمها برنامج الربط المحلي. أي شيء يستطيع إرسال طلب HTTPS — برنامجك، أو منصة تكامل، أو سكربت — يستطيع إرسال البصمات بها.
العنوان الأساسي: https://<company>.tarleaks.com/api/attendance/public/v1
المصادقة. أضف جهازاً من نوع برنامجنا الخاص أو شركة تكامل لتحصل على مفتاح ربط، ثم أرسله مع كل طلب:
Authorization: Bearer atd_k3v7q2ma…
(تُقبل أيضاً الترويسة X-Attendance-Device-Token: atd_…؛ لكن الأفضل Authorization، لأن برامج HTTP لا تمررها إلى خادم آخر أبداً.) لا تتبع إعادات التوجيه: العنوان الصحيح لا يُعاد توجيهه أبداً، والبرنامج الذي يتبع إعادة التوجيه قد يرسل مفتاحك إلى جهة أخرى.
نقاط الاتصال
| الطريقة والمسار | محتوى الطلب | الرد (200) |
|---|---|---|
GET /device | — | الجهاز ومنطقته الزمنية وقاعدة الدخول والخروج، واسم مساحة العمل، ووقت الخادم، وحدودك |
POST /punches | دفعة من 1 إلى 500 بصمة (512 كيلوبايت كحد أقصى) | تقرير: المقبول، والمكرر، ونتيجة لكل بصمة، والبصمات المرفوضة |
POST /device-users | من 1 إلى 2,000 مستخدم للجهاز (1 ميغابايت كحد أقصى) | {"stored": n, "new": m} |
GET /commands | — | الأوامر المنتظرة لهذا الجهاز (وتُعلَّم بعدها كمرسَلة) |
POST /commands/{id}/result | {"ok": true, "message": "412 punches re-sent"} (16 كيلوبايت كحد أقصى) | {"recorded": true} |
رد GET /device:
{
"device": {"id": "8c1f…", "name": "Main entrance", "connection_type": "api",
"time_zone": "Asia/Dubai", "direction_policy": "first_last"},
"workspace": "ACME UAE",
"server_time": "2026-10-11T04:01:30Z",
"limits": {"max_batch": 500, "per_minute": 120, "per_day": 50000}
}
إرسال البصمات
{
"punches": [
{
"person": "1001",
"time": "2026-10-11 08:01:22",
"direction": "in",
"verify": "fingerprint",
"card": "0012345678",
"id": "zk1-778812"
}
]
}
| الحقل | إلزامي | المعنى |
|---|---|---|
person | نعم، من 1 إلى 64 خانة | من سجّل البصمة: رقم المستخدم على الجهاز افتراضياً. |
time | نعم | YYYY-MM-DD HH:MM:SS أو YYYY-MM-DDTHH:MM:SS ويُقرأ بالمنطقة الزمنية للجهاز (الطريقة الموصى بها — أرسل ما يعرضه الجهاز)، أو RFC 3339 مع فرق التوقيت مثل 2026-10-11T08:01:22+04:00 إن كنت تعرف اللحظة بدقة. |
person_kind | لا | device_user (افتراضي)، أو employee_number (الرقم الوظيفي في Tarleaks)، أو badge (رقم البطاقة). |
direction | لا | in أو out أو break_out أو break_in أو overtime_in أو overtime_out أو unknown. |
status_code | لا | رقم الحالة الخام من الجهاز، يُحفظ للرجوع إليه. |
verify | لا | fingerprint أو face أو card أو pin أو palm أو other. |
work_code | لا، حتى 32 خانة | رمز العمل في الجهاز إن وُجد. |
card | لا، حتى 64 خانة | رقم البطاقة المقروءة إن وُجدت. |
id | لا، من 1 إلى 160 خانة | معرّفك الفريد للبصمة. غير ضروري: الشخص والوقت هما المفتاح على أي حال. |
الحقول غير المعروفة تُتجاهل. أرسل التوقيت المحلي للجهاز نفسه لا توقيت خادمك: المنطقة الزمنية للجهاز في Tarleaks هي المرجع الوحيد، فتُعرف البصمة نفسها المرسلة بطريقتين على أنها بصمة واحدة.
الرد:
{
"accepted": 1,
"duplicates": 0,
"results": [{"index": 0, "id": "zk1-778812", "status": "processed", "punch_id": "5b0e…"}],
"rejected": [{"index": 3, "id": null, "code": "BAD_TIME", "message": "time is not a date and time"}],
"server_time": "2026-10-11T04:01:30Z"
}
index هو ترتيب البصمة في دفعتك (يبدأ من 0). البصمة الخاطئة لا تُفشل الدفعة أبداً: تظهر في rejected مع رمز — BAD_PERSON أو BAD_TIME أو BAD_DIRECTION أو BAD_ID أو TOO_LONG أو BAD_FIELD (حقل من نوع خاطئ، كأن يُرسل كائن مكان نص؛ وتذكر الرسالة اسم الحقل) — وتُحفظ البقية. ويُقبل الرقم حيث يُتوقع نص ("person": 1001 يُقرأ "1001"). ولكل بصمة محفوظة status:
| الحالة | المعنى |
|---|---|
received | حُفظت؛ وتصبح تسجيل حضور خلال دقائق. |
processed | أصبحت جزءاً من تسجيل حضور. |
unmatched | حُفظت، لكن لم يُطابَق أي موظف بمستخدم الجهاز هذا بعد (الحضور ← مستخدمو الأجهزة). |
needs_review | حُفظت، لكنها تنتظر مراجعة شخص (انظر رموز الأسباب في الملحق). |
ignored | حُفظت واستُبعدت (مثلاً لأنها قبل تاريخ بدء الجهاز). |
duplicate_read | سجّل الشخص نفسه بصمة أخرى خلال مهلة القراءة المكررة؛ تُحفظ ولا تُحتسب. |
duplicate | أرسلت هذه البصمة من قبل؛ لم يتغير شيء. |
rejected | حُفظت لكنها رُفضت، مثل وقت متقدم أكثر من 5 دقائق عن الخادم (تحقق من ساعة الجهاز). |
إعادة الإرسال آمنة دائماً. مفتاح البصمة هو الشخص والوقت، فإعادة إرسال دفعة بعد انتهاء المهلة أو تعطل أو رد 503 لا تنشئ تسجيل حضور ثانياً أبداً. وعند الشك، أعد الإرسال.
الأخطاء
للأخطاء شكل واحد: {"error": {"code": "…", "message": "…"}}.
| HTTP | الرمز | المعنى — وما العمل |
|---|---|---|
| 400 | BAD_BATCH | ليس JSON، أو punches مفقود أو فارغ أو أكثر من 500. صحّح محتوى الطلب. (الحقل الخاطئ النوع داخل بصمة واحدة لا يُفشل الدفعة: تظهر تلك البصمة في rejected بالرمز BAD_FIELD.) |
| 401 | DEVICE_TOKEN_INVALID | المفتاح مفقود أو خاطئ أو مستبدل، أو أُرشف الجهاز. انسخ المفتاح الحالي، أو أصدر مفتاحاً جديداً من صفحة الجهاز. |
| 402 | ATTENDANCE_NOT_LICENSED | مساحة العمل لا تملك ترخيص الحضور. تواصل مع ممثل Tarleaks. |
| 403 | WORKSPACE_SUSPENDED | مساحة العمل موقوفة. |
| 403 | DEVICE_INTEGRATIONS_OFF | خيار الإعدادات ← الميزات ← الحضور ← أجهزة الحضور متوقف (أو أوقفته المنصة). فعّله. |
| 403 | DEVICE_INACTIVE | الجهاز غير نشط أو مؤرشف. |
| 403 | DEVICE_ADDRESS_NOT_ALLOWED | للجهاز عناوين مسموح بها وهذا الطلب جاء من عنوان آخر. اسمح به من صفحة الجهاز. |
| 403 | WRONG_WORKSPACE_ADDRESS | المفتاح يخص مساحة عمل غير العنوان الذي استدعيته. استخدم عنوان مساحة عملك. |
| 408 | TRY_AGAIN | استغرق وصول محتوى الطلب أكثر من 15 ثانية. لم يُحفظ شيء؛ أرسل الدفعة نفسها مرة أخرى بعد عدد الثواني في Retry-After (وعلى اتصال بطيء أرسل دفعات أصغر). |
| 413 | BODY_TOO_LARGE | أرسل دفعات أصغر. |
| 429 | SLOW_DOWN أو DAILY_LIMIT | طلبات أو بصمات كثيرة جداً. انتظر عدد الثواني في Retry-After، ثم أعد إرسال الدفعة نفسها. |
| 503 | TRY_AGAIN | لم يُحفظ شيء. انتظر Retry-After ثانية وأعد إرسال الدفعة نفسها. |
عند خطأ في الشبكة أو أي رد 5xx آخر، انتظر وأعد المحاولة بمهلة متزايدة (مثلاً 5 ثوانٍ تتضاعف حتى 10 دقائق). وعند 401 أو 402 أو 403 توقف وعالج السبب؛ فإعادة المحاولة لن تفيد.
مستخدمو الجهاز والأوامر
إرسال POST /device-users بالمحتوى {"users": [{"person": "1001", "name": "Sara Ali", "card": "0012345678"}]} يعرّف Tarleaks بالأسماء المسجلة على الجهاز، فتسهل مطابقة الأشخاص (الحقل person وحده إلزامي). أرسل هذه الحقول الثلاثة فقط — وليس البصمات أو الوجوه أو كلمات المرور أبداً.
ويعيد GET /commands ما طلبه المسؤول من الجهاز في صفحته:
| النوع | البيانات | ما يجب أن يفعله برنامجك |
|---|---|---|
sync_time | — | ضبط ساعة الجهاز على الوقت الحالي في منطقته. |
repull_history | {"from": "2026-10-01", "to": "2026-10-11"} | إعادة إرسال كل البصمات بين التاريخين (إعادة الإرسال آمنة). |
fetch_users | — | إرسال قائمة مستخدمي الجهاز إلى POST /device-users. |
reboot | — | إعادة تشغيل الجهاز. |
أبلغ عن نتيجة كل أمر بـ POST /commands/{id}/result والمحتوى {"ok": true|false, "message": "…"}.
مرجع المطورين داخل Tarleaks (المطورون ← مرجع الواجهة البرمجية) وملف OpenAPI على https://<company>.tarleaks.com/api/auth/developer/openapi.json يصفان الواجهة التي تُستخدم بعد تسجيل الدخول لإدارة الأجهزة؛ أما نقاط اتصال الأجهزة أعلاه فموثقة هنا.
أمثلة
كل مثال يفعل الأشياء الأربعة نفسها: يتحقق من الاتصال، ويرسل دفعة، ويقرأ التقرير، ويعيد المحاولة عند 429 و503 باستخدام Retry-After. احفظ المفتاح في متغير بيئة (TARLEAKS_KEY) أو في ملف، ولا تكتبه في الكود أبداً.
curl (bash):
BASE="https://yourcompany.tarleaks.com/api/attendance/public/v1"
KEY="$(cat /etc/tarleaks/entrance.key)" # atd_…
# 1. Check the connection
curl -sS --proto =https --max-redirs 0 -H "Authorization: Bearer $KEY" "$BASE/device"
# 2-4. Send a batch, retrying on 429 / 503 / 5xx with Retry-After
cat > batch.json <<'JSON'
{"punches": [{"person": "1001", "time": "2026-10-11 08:01:22", "direction": "in", "verify": "fingerprint"}]}
JSON
for attempt in 1 2 3 4 5 6 7 8; do
code=$(curl -sS --proto =https --max-redirs 0 -o report.json -D headers.txt -w '%{http_code}' \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
--data-binary @batch.json "$BASE/punches") || code=000
case "$code" in
200) cat report.json; break ;;
429|5??|000)
wait=$(awk 'tolower($1)=="retry-after:" {print $2+0}' headers.txt)
sleep "${wait:-$((5 * attempt))}" ;;
*) echo "Refused ($code):"; cat report.json; break ;;
esac
done
Python (الإصدار 3.9 أو أحدث، مع requests):
import os
import time
import requests
BASE = "https://yourcompany.tarleaks.com/api/attendance/public/v1"
session = requests.Session()
session.headers["Authorization"] = "Bearer " + os.environ["TARLEAKS_KEY"]
def call(method, path, body=None, tries=8):
for attempt in range(tries):
backoff = min(600, 5 * 2 ** attempt)
try:
r = session.request(method, BASE + path, json=body, timeout=30, allow_redirects=False)
except requests.RequestException:
time.sleep(backoff)
continue
if r.status_code == 429 or r.status_code >= 500:
retry_after = r.headers.get("Retry-After", "")
time.sleep(int(retry_after) if retry_after.isdigit() else backoff)
continue
data = r.json() if r.content else {}
if r.status_code != 200:
err = data.get("error", {})
raise RuntimeError(f"{r.status_code} {err.get('code')}: {err.get('message')}")
return data
raise RuntimeError("Gave up for now; sending the same batch again later is safe.")
print(call("GET", "/device")["workspace"])
report = call("POST", "/punches", {"punches": [
{"person": "1001", "time": "2026-10-11 08:01:22", "direction": "in", "verify": "fingerprint"},
]})
print(report["accepted"], "accepted,", report["duplicates"], "duplicates")
for bad in report["rejected"]:
print("punch", bad["index"], "refused:", bad["code"], bad["message"])
Node.js (الإصدار 18 أو أحدث، مع fetch المدمج):
const BASE = "https://yourcompany.tarleaks.com/api/attendance/public/v1";
const KEY = process.env.TARLEAKS_KEY;
const sleep = (s) => new Promise((done) => setTimeout(done, s * 1000));
async function call(method, path, body) {
for (let attempt = 0; attempt < 8; attempt++) {
const backoff = Math.min(600, 5 * 2 ** attempt);
let res;
try {
res = await fetch(BASE + path, {
method,
redirect: "manual",
headers: { Authorization: `Bearer ${KEY}`, "Content-Type": "application/json" },
body: body ? JSON.stringify(body) : undefined,
signal: AbortSignal.timeout(30_000),
});
} catch {
await sleep(backoff);
continue;
}
if (res.status === 429 || res.status >= 500) {
await sleep(Number(res.headers.get("retry-after")) || backoff);
continue;
}
const data = await res.json().catch(() => ({}));
if (res.status !== 200) {
throw new Error(`${res.status} ${data.error?.code}: ${data.error?.message}`);
}
return data;
}
throw new Error("Gave up for now; sending the same batch again later is safe.");
}
const info = await call("GET", "/device");
console.log(`Connected to ${info.workspace} as ${info.device.name}`);
const report = await call("POST", "/punches", {
punches: [{ person: "1001", time: "2026-10-11 08:01:22", direction: "in", verify: "fingerprint" }],
});
console.log(`${report.accepted} accepted, ${report.duplicates} duplicates`);
for (const bad of report.rejected) console.log(`punch ${bad.index} refused: ${bad.code}`);
(احفظه باسم send.mjs، أو استخدمه داخل دالة async.)
C# (.NET 6 أو أحدث، مع HttpClient):
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
var http = new HttpClient(new HttpClientHandler { AllowAutoRedirect = false })
{
BaseAddress = new Uri("https://yourcompany.tarleaks.com/api/attendance/public/v1/"),
Timeout = TimeSpan.FromSeconds(30),
};
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("TARLEAKS_KEY"));
var json = new JsonSerializerOptions(); // keep the field names exactly as written
async Task<JsonElement> Call(HttpMethod method, string path, object? body = null)
{
for (var attempt = 0; attempt < 8; attempt++)
{
var backoff = TimeSpan.FromSeconds(Math.Min(600, 5 * Math.Pow(2, attempt)));
HttpResponseMessage res;
try
{
var req = new HttpRequestMessage(method, path);
if (body != null) req.Content = JsonContent.Create(body, options: json);
res = await http.SendAsync(req);
}
catch (Exception e) when (e is HttpRequestException || e is TaskCanceledException)
{
await Task.Delay(backoff);
continue;
}
var code = (int)res.StatusCode;
if (code == 429 || code >= 500)
{
await Task.Delay(res.Headers.RetryAfter?.Delta ?? backoff);
continue;
}
var text = await res.Content.ReadAsStringAsync();
if (code != 200)
throw new Exception($"{code}: {text}");
return JsonDocument.Parse(text).RootElement;
}
throw new Exception("Gave up for now; sending the same batch again later is safe.");
}
var info = await Call(HttpMethod.Get, "device");
Console.WriteLine($"Connected to {info.GetProperty("workspace")}");
var report = await Call(HttpMethod.Post, "punches", new
{
punches = new[] { new { person = "1001", time = "2026-10-11 08:01:22", direction = "in", verify = "fingerprint" } },
});
Console.WriteLine($"{report.GetProperty("accepted")} accepted, {report.GetProperty("duplicates")} duplicates");
لاحظ أن المسارات بلا / في أولها ("punches") لتُضاف إلى العنوان الأساسي.
PowerShell (الإصدار 7 أو أحدث):
$Base = "https://yourcompany.tarleaks.com/api/attendance/public/v1"
$Headers = @{ Authorization = "Bearer $env:TARLEAKS_KEY" }
function Invoke-Tarleaks([string]$Method, [string]$Path, $Body = $null) {
for ($attempt = 0; $attempt -lt 8; $attempt++) {
$backoff = [Math]::Min(600, 5 * [Math]::Pow(2, $attempt))
$params = @{ Method = $Method; Uri = "$Base$Path"; Headers = $Headers; TimeoutSec = 30
MaximumRedirection = 0; SkipHttpErrorCheck = $true }
if ($null -ne $Body) {
$params.Body = $Body | ConvertTo-Json -Depth 5
$params.ContentType = "application/json; charset=utf-8"
}
try { $r = Invoke-WebRequest @params } catch { Start-Sleep -Seconds $backoff; continue }
$code = [int]$r.StatusCode
if ($code -eq 429 -or $code -ge 500) {
$wait = 0
if (-not [int]::TryParse([string]($r.Headers["Retry-After"] | Select-Object -First 1), [ref]$wait)) { $wait = $backoff }
Start-Sleep -Seconds $wait
continue
}
$data = if ($r.Content) { $r.Content | ConvertFrom-Json } else { $null }
if ($code -ne 200) { throw "$code $($data.error.code): $($data.error.message)" }
return $data
}
throw "Gave up for now; sending the same batch again later is safe."
}
$info = Invoke-Tarleaks GET "/device"
"Connected to $($info.workspace) as $($info.device.name)"
$report = Invoke-Tarleaks POST "/punches" @{ punches = @(
@{ person = "1001"; time = "2026-10-11 08:01:22"; direction = "in"; verify = "fingerprint" }
) }
"$($report.accepted) accepted, $($report.duplicates) duplicates"
$report.rejected | ForEach-Object { "punch $($_.index) refused: $($_.code)" }
برنامج الربط المحلي
تنزيل برنامج الربط المحلي
الإصدار 0.1.0 لأنظمة Windows وLinux وDocker. يحتاج Python بالإصدار 3.9 أو أحدث.
تنزيل tarleaks-attendance-bridge-0.1.0.zip (157 KB)
بصمة التحقق SHA-256 — قارنها قبل التثبيت:
b0bb10f9f81fe53218175718c16991908f13b005bc4e08a97cc85061d68cb0ba tarleaks-attendance-bridge-0.1.0.zipWindows: Get-FileHash .\tarleaks-attendance-bridge-0.1.0.zip -Algorithm SHA256
Linux / macOS: sha256sum tarleaks-attendance-bridge-0.1.0.zipقراءة أجهزة ZKTeco عبر الشبكة (المحوّل zk_tcp) تحتاج أيضاً الحزمة الاختيارية pyzk ذات الرخصة GPL-2.0، وتثبّتها بنفسك من الملف المثبَّت الإصدارات داخل الحزمة؛ وهي غير مضمّنة في التنزيل.
برنامج الربط المحلي (الجسر) برنامج صغير لجهاز كمبيوتر في موقعك يبقى قيد التشغيل. يقرأ الأجهزة على شبكة مكتبك ويرسل بصماتها عبر واجهة البصمات البرمجية الموضحة أعلاه. ولا يتعامل إلا مع أربعة أنواع من المصادر (الجدول أدناه)؛ فجهاز علامة تجارية أخرى لا يصل إليه إلا عبر مجلد يحفظ فيه برنامج الجهاز سجلّه.
التنزيل. حزمة البرنامج ملف zip منشور مع بصمة التحقق SHA-256 في النسخة العامة من هذا الدليل، tarleaks.com/ar/developers/attendance-devices. تحقق من البصمة قبل التثبيت. يحتاج البرنامج Python بالإصدار 3.9 أو أحدث.
ما يقرؤه (قسم [machine:<name>] لكل جهاز في ملف bridge.ini):
| المحوّل (adapter) | لأي أجهزة | الإعدادات |
|---|---|---|
zk_tcp | ZKTeco وeSSL وFingerTec عبر منفذ TCP رقم 4370 | address، وport (4370)، وcomm_key_env أو comm_key_file إن كان للجهاز Comm Key، وfull_read_hours (6). يحتاج الحزمة الاختيارية pyzk: pip install --require-hashes -r requirements-zk.txt. رخصة pyzk هي GPL-2.0؛ تثبّتها أنت ولا تُدمج أبداً مع البرنامج. |
hik_isapi | أجهزة Hikvision التي لا تصل إلى الإنترنت | address، وusername، وpassword_env أو password_file، وpoll_seconds (60) |
adms_relay | أجهزة ZKTeco القديمة التي لا ترسل إلا عبر http العادي | listen (عنوان هذا الكمبيوتر على الشبكة المحلية ومنفذ، وليس 0.0.0.0 أبداً)، وserial (الجهاز الوحيد المقبول)، وmachine_ips (عنوانه) |
folder | ملفات USB المصدَّرة (attlog.dat و.txt) أو ملفات CSV في مجلد — من أي علامة تجارية يحفظ برنامجها السجل | path، وformat (attlog أو csv)، وattlog_layout، وcsv_columns، وdate_order |
يحتاج كل جهاز مفتاح ربط خاصاً به: أضفه في Tarleaks بنوع علامة تجارية أخرى، أو جهاز قديم على شبكة مكتبنا.
attlog_layout (folder مع format = attlog). تضع ملفات السجل حالة الدخول والخروج في أعمدة مختلفة. ملف USB المصدَّر من ZKTeco أو FingerTec (1_attlog.dat) ترتيبه: الشخص، الوقت، رقم الجهاز، الحالة، طريقة التحقق، رمز العمل، فاضبط attlog_layout = usb. والملف الذي ترتيبه الشخص، الوقت، الحالة، طريقة التحقق، رمز العمل هو attlog_layout = adms. وإن تُرك على auto يتعرّف البرنامج على كل ملف بنفسه (ملف USB فيه ستة أعمدة ورقم الجهاز نفسه في كل سطر)؛ أما الملف الذي لا يُعرف ترتيبه — سطر واحد، أو كل البصمات بالحالة نفسها — فيُنقل إلى failed\ مع ملاحظة بدلاً من قراءته معكوساً. اضبط الترتيب وأعد الملف إلى المجلد.
التثبيت على Windows. فك ضغط الحزمة، وافتح PowerShell كمسؤول داخل ذلك المجلد، وشغّل:
powershell -ExecutionPolicy Bypass -File .\attendance_bridge\service\install-windows.ps1
يستخدم ما هو موجود في Windows فقط: ينشئ بيئة Python بحزم يُتحقق من بصمتها، وحساباً محلياً مخصصاً، ومجلد إعدادات (C:\ProgramData\TarleaksBridge) لا يفتحه إلا ذلك الحساب والمسؤولون، ومهمة تعمل عند تشغيل الجهاز. ثم في نافذة PowerShell جديدة:
tarleaks-attendance-bridge init --url https://yourcompany.tarleaks.com --machine entrance --adapter zk_tcp --address 192.168.1.201
tarleaks-attendance-bridge test
Start-ScheduledTask -TaskName "Tarleaks Attendance Bridge"
التثبيت على Linux (systemd): اتبع الخطوات المكتوبة أعلى الملف attendance_bridge/service/tarleaks-attendance-bridge.service — حساب نظام، وبيئة Python، والإعدادات في /etc/tarleaks-bridge، ثم systemctl enable --now tarleaks-attendance-bridge.
Docker: الملف attendance_bridge/service/Dockerfile (يعمل دون صلاحيات root؛ اربط bridge.ini وملفات المفاتيح للقراءة فقط). ويحتاج وسيط ADMS الخيار --network host.
المفاتيح وكلمات المرور خارج bridge.ini. يطلب الأمر init المفتاح دون عرضه، ويحفظه في ملف مفتاح لا يقرؤه إلا حساب البرنامج (token_file). ويمكنك استخدام متغير بيئة بدلاً منه (token_env = TARLEAKS_KEY_ENTRANCE). وفي Windows يُحفظ ملف المفتاح في C:\ProgramData\TarleaksBridge، الذي لا يفتحه برنامج التثبيت إلا لحساب البرنامج نفسه وللمسؤولين. (يُقرأ token_dpapi أيضاً، لكن ملف DPAPI لا يفتحه إلا حساب Windows الذي كتبه — فلا تكتبه أبداً بحساب مسؤول لمهمة بدء التشغيل التي تعمل بحساب TarleaksBridge؛ ويُنبّه الأمر test إن فعلت.) وكلمات مرور الأجهزة وComm Key بالطريقة نفسها (password_file / password_env، وcomm_key_file / comm_key_env). ويرفض البرنامج العمل إن وجد مفتاحاً أو كلمة مرور مكتوبة في bridge.ini.
مثال كامل لملف bridge.ini:
[server]
url = https://yourcompany.tarleaks.com
; ca_bundle = C:\certs\company-proxy.pem ; only behind a proxy that inspects HTTPS
[machine:entrance]
adapter = zk_tcp
token_file = C:\ProgramData\TarleaksBridge\keys\entrance.key
address = 192.168.1.201
port = 4370
[machine:warehouse]
adapter = hik_isapi
token_env = TARLEAKS_KEY_WAREHOUSE
address = 192.168.1.64
username = admin
password_env = HIK_WAREHOUSE_PASSWORD
[machine:old-zk]
adapter = adms_relay
token_env = TARLEAKS_KEY_OLDZK
listen = 192.168.1.10:8080
serial = CJDE203760123
machine_ips = 192.168.1.205
[machine:usb-exports]
adapter = folder
token_env = TARLEAKS_KEY_USB
path = C:\AttendanceExports
format = attlog
وسيط ADMS. اضبط إعداد Cloud Server / ADMS في الجهاز القديم على كمبيوتر البرنامج (192.168.1.10، المنفذ 8080، وHTTPS متوقف). يستمع الوسيط على ذلك العنوان فقط، ولا يقبل إلا الرقم التسلسلي المحدد ومن عنوان الجهاز المحدد، ويرفض أي طلب يرسله متصفح ويب، ويرد بنفسه على تبادل بدء التشغيل للجهاز (طالباً البصمات وسجلات المستخدمين فقط)، ولا يرد بـ «OK» إلا بعد حفظ البصمات في قائمة الانتظار، ثم يرسلها إلى Tarleaks عبر HTTPS.
التحقق. الأمر tarleaks-attendance-bridge test يتحقق من الإعدادات والاتصال الآمن («Connected to ACME UAE as 'Entrance'») ويقرأ كل جهاز مرة واحدة دون إرسال أي شيء. والأمر tarleaks-attendance-bridge status يعرض ما ينتظر الإرسال وآخر مشكلة لكل جهاز. السجلات في logs\bridge.log بجانب ملف الإعدادات (وفي Linux: journalctl -u tarleaks-attendance-bridge)؛ ولا تظهر فيها المفاتيح أبداً.
ما يرسله، وما لا يرسله أبداً. يرسل حقول البصمة الواردة في مرجع الواجهة البرمجية، وقائمة مستخدمي الجهاز (الرقم والاسم والبطاقة). ولا يقرأ ولا يرسل أبداً قوالب البصمات أو الوجوه، أو الصور، أو كلمات مرور المستخدمين، أو Comm Key.
عند انقطاع الإنترنت. تنتظر البصمات في قائمة انتظار محلية وتُرسل عند عودة الاتصال — لا يضيع شيء، وإعادة الإرسال لا تضر. عند 429 ينتظر البرنامج المدة المطلوبة؛ وعند خطأ في الشبكة يعيد المحاولة من 5 ثوانٍ حتى كل 10 دقائق؛ وعند 401 أو 402 أو 403 يوقف ذلك الجهاز ويكتب السبب بكلمات واضحة في السجل ويعيد المحاولة كل 10 دقائق. وعند 400 أو 413 يكون الخادم قد رفض ما أُرسل لا الاتصال: فيقسم البرنامج الدفعة حتى تنفرد البصمة التي لا يقبلها الخادم، ويرسل كل ما عداها، وإذا رُفضت تلك البصمة وحدها مرتين وضعها جانباً وكتب سطر ERROR يذكر الشخص والوقت — فلا يعطّل سجلٌّ تالف واحد البصمات التي بعده. ويعدّ الأمر status البصمات الموضوعة جانباً؛ صحّح السجل (أو الملف) في الجهاز ثم استخدم جلب البصمات مرة أخرى لإرسالها. وكل 10 دقائق يتصل للتحقق، وينبّه إن كانت ساعة الجهاز مختلفة بأكثر من دقيقتين، وينفذ الأوامر المرسلة من صفحة الجهاز (ضبط الوقت، وجلب البصمات مرة أخرى، وقراءة قائمة المستخدمين، وإعادة التشغيل). والبصمة التي ردّ عليها الخادم لا تُرسل مرة أخرى لمدة 7 أيام (ويمحو جلب البصمات مرة أخرى هذه الذاكرة).
عندما تعود ساعة الجهاز إلى الوراء (تغيير المنطقة الزمنية، أو ضبط وقت الجهاز بعد أن كانت متقدمة) تستمر البصمات في الوصول: لا يُسقط البرنامج أي بصمة لأن وقتها أقدم من آخر بصمة قرأها. بل يلاحظ أن ساعة الجهاز متأخرة عن آخر بصمة، ويكتب ذلك في السجل، ويعيد قراءة اليوم الأخير؛ والبصمات المرسلة سابقاً لا تُرسل مرتين. ويحمل البرنامج بيانات المناطق الزمنية الخاصة به (tzdata في requirements.txt)، فيستخدم فحص الساعة وضبط وقت الجهاز منطقة الجهاز حتى على Windows.
التحديث. نزّل الحزمة الجديدة، وتحقق من SHA-256، واستبدل مجلد app (في Windows: C:\Program Files\TarleaksBridge\app)، ثم أعد تشغيل المهمة أو الخدمة. تبقى الإعدادات والمفاتيح وقائمة الانتظار كما هي.
استيراد ملف الجهاز
للأجهزة التي لا تحفظ سجلها إلا على ذاكرة USB، أو عند الحاجة لتحميل سجل قديم:
- صدّر السجل. أجهزة ZKTeco وما يشبهها: ضع ذاكرة USB في الجهاز، ثم Menu ← USB Manager (أو Pen Drive Mng) ← Download ← Attendance Data. ستحصل على ملف مثل
1_attlog.dat. الأجهزة الأخرى: صدّر سجل الحضور بصيغة CSV أو Excel من الجهاز أو برنامجه. - استورده. في صفحة الجهاز في Tarleaks (أضف جهازاً من نوع يصدّر ملفًا فقط (USB))، اختر استيراد ملف سجل أو جدول بيانات (في تبويب البصمات)، واختر الملف، وراجع الأعمدة في المعاينة — ترتيب الأعمدة في ملفات USB يختلف بين الطرازات، لذلك تُعرض الصفوف الأولى لتأكيدها — ثم استورد.
- المنطقة الزمنية. تُقرأ أوقات الملف بالمنطقة الزمنية للجهاز ما لم تختر غيرها أثناء الاستيراد. وعمود الدخول والخروج اختياري.
استيراد الملف نفسه مرة أخرى آمن: البصمات المحفوظة سابقاً تظهر كمكررة. ويحتاج الاستيراد صلاحية بصمات الأجهزة — استيراد، لأنه ينشئ تسجيلات حضور للأشخاص الواردين في الملف؛ ويُسجَّل اسم من قام بالاستيراد على كل بصمة.
مطابقة الأشخاص
يعرف الجهاز الأشخاص بأرقام المستخدمين الخاصة به. وعلى Tarleaks أن يعرف أي موظف هو مستخدم الجهاز رقم 1001.
- عند إضافة الجهاز يسأل المعالج: «هل رقم كل شخص على هذا الجهاز هو رقمه الوظيفي؟». إن أجبت بنعم، يطابق Tarleaks تلقائياً عندما يساوي رقم المستخدم على الجهاز رقماً وظيفياً (حتى بعد حذف الأصفار في البداية:
0042=42)، أو عندما يساوي رقم البطاقة رقم بطاقة الموظف. - ويمتنع عن المطابقة إذا أرسل الجهاز اسماً لذلك المستخدم لا يشترك في شيء مع اسم الموظف (مع مقارنة عادلة بين الكتابة العربية والإنجليزية). وتصبح هذه الحالات اقتراحات بدلاً من ذلك.
- تعرض الحضور ← مستخدمو الأجهزة كل مستخدمي الأجهزة. ويُظهر عامل التصفية غير مطابق من يحتاج مطابقة وعدد البصمات التي تنتظره. اختر مطابقة، واختر الموظف (أو أنشئه في المكان نفسه)، وأبقِ خيار الشخص نفسه على كل الأجهزة مفعّلاً إن كان الرقم نفسه مستخدماً على كل الأجهزة. وتتحول البصمات المنتظرة إلى تسجيلات حضور فوراً.
- المطابقات التلقائية تظهر بعبارة «طوبقت تلقائياً» مع تأكيد وتغيير. والمطابقة التي يجريها شخص تتقدم دائماً على المطابقة التلقائية.
- زر مطابقة تلقائية في تلك الصفحة يطبّق القواعد مرة واحدة عند الطلب، حتى لو كانت المطابقة التلقائية متوقفة.
- تغيير المطابقة أو إزالتها يؤثر في البصمات القادمة فقط؛ وتسجيلات الحضور السابقة تبقى كما هي.
كيف تتحول البصمات إلى تسجيلات حضور
قاعدة الدخول والخروج (الإعدادات ← الحضور ← أجهزة الحضور؛ ويمكن للجهاز تجاوزها):
| القاعدة | طريقة عملها | مثال: بصمات في 07:58 و13:02 و13:40 و17:05 |
|---|---|---|
| أول بصمة وآخر بصمة في اليوم (افتراضي) | أول بصمة في يوم العمل دخول، وآخر بصمة خروج. | فترة واحدة 07:58–17:05 |
| زر الدخول والخروج في الجهاز | تعتمد ما اختاره الشخص على الجهاز. | فترتان 07:58–13:02 و13:40–17:05 (إن ضُغط الزر صحيحاً) |
| بالتناوب | دخول، خروج، دخول، خروج… بغض النظر عن الأزرار. | فترتان 07:58–13:02 و13:40–17:05 |
معظم الأجهزة في المنطقة تُضبط دون زر الدخول والخروج، ولهذا القاعدة الافتراضية هي «أول بصمة وآخر بصمة». وإن ظهرت كل البصمات كدخول، فبدّل إلى هذه القاعدة.
- القراءة المكررة. البصمة الثانية للشخص نفسه خلال 60 ثانية (من 10 إلى 600، في الإعدادات) قراءة مكررة: تُحفظ ولا تُحتسب.
- أطول وردية ونسيان الخروج. لا تُنشأ فترة أطول من أطول وردية (16 ساعة افتراضياً، من 4 إلى 24). والدخول دون خروج حتى ذلك الحين يصبح تسجيلاً بصفر دقيقة مع تنبيه لم يُسجَّل خروج؛ والخروج دون دخول يُنبَّه إليه بعبارة لم يُسجَّل دخول. ويصححه الشخص بطلب تصحيح كأي حالة أخرى.
- أيام العمل والورديات الليلية. تنتمي البصمة إلى يوم العمل في وردية الشخص: فالوردية الليلية من 22:00 إلى 06:00 تبقى يوماً واحداً. ولمن ليست لهم وردية يبدأ يوم العمل الساعة 04:00 (الإعدادات ← إعدادات متقدمة)، فيُضم خروج الساعة 01:30 إلى المساء السابق.
- دخول بالجوال وخروج من الباب. إذا سجّل شخص دخوله من الجوال أو المتصفح وخرج عبر جهاز، فبصمة الجهاز تغلق ذلك الدخول.
- التعديلات لا تُستبدل أبداً. بمجرد أن يعدّل شخص تسجيل حضور جاء من جهاز، يتوقف Tarleaks عن تغيير ذلك اليوم؛ وتنتظر البصمات الجديدة له المراجعة.
- الإدخالات اليدوية. الإدخال اليدوي الذي يتداخل مع يوم من الجهاز يوقف ذلك اليوم أيضاً، بدل حذف أي شيء.
- الأسابيع المقفلة. بمجرد تقديم جدول ساعات الأسبوع أو اعتماده، تنتظر بصمات الأجهزة الخاصة به المراجعة — فالرواتب لا تستلم إلا الأسابيع المعتمدة.
- البصمات القديمة. البصمات لأيام مضى عليها أكثر من 35 يوماً (من 0 إلى 400، الإعدادات ← إعدادات متقدمة) تنتظر بسبب «قديمة جداً». ويستطيع صاحب صلاحية الاستيراد إطلاقها من صفحة الجهاز.
- ما يراه المدير. مشكلات الأجهزة (لم يُسجَّل خروج، لم يُسجَّل دخول، فترة طويلة جداً، استُبدلت) تظهر في الحضور ← تسجيلات الحضور المُنبَّه إليها مع التنبيهات الأخرى.
حل المشكلات
| ما تراه | ما العمل |
|---|---|
| صفحة الجهاز تعرض لم يتصل قط | تحقق من العنوان (بلا http:// وبلا مسافات)، والمنفذ 443، وتفعيل HTTPS. وتحقق من أن الجهاز يصل إلى الإنترنت (البوابة وDNS مضبوطان في قائمة الشبكة). البرامج القديمة قد لا تثق بشهادة Let's Encrypt أو لا تدعم TLS 1.2 — اربط الجهاز عبر وسيط ADMS في برنامج الربط المحلي. |
| 401 أو «UNAUTHORIZED» | المفتاح خاطئ أو مستبدل. انسخ المفتاح الحالي أو أصدر مفتاحاً جديداً، واكتبه في الجهاز من جديد. |
| 402 أو «NOT LICENSED» | مساحة العمل لا تملك ترخيص الحضور. |
403 «integrations off» أو DEVICE_INTEGRATIONS_OFF | خيار الإعدادات ← الميزات ← الحضور ← أجهزة الحضور متوقف. |
403 «ADDRESS NOT ALLOWED» أو DEVICE_ADDRESS_NOT_ALLOWED | جاء الطلب من عنوان لا يسمح به الجهاز. اسمح به من صفحة الجهاز (الربط ← العناوين المسموح بها). |
| 403 «serial mismatch» | الرقم التسلسلي المحفوظ في صفحة الجهاز يختلف عن رقم الجهاز الفعلي. صححه في الصفحة. |
| «يحاول الاتصال» في قائمة الأجهزة | جهاز يحاول الاتصال بعنوان الرقم التسلسلي ولم يُضف بعد. أضفه (اكتب رقمه التسلسلي) أو تجاهله. |
| «هذا الرقم التسلسلي مسجّل في مكان آخر» | استخدم عنوان المفتاح لهذا الجهاز بدلاً منه (تبويب الربط)، أو تواصل مع الدعم. |
| تصل البصمات لكن دون تسجيلات حضور | لم تُطابَق حسابات مستخدمي الجهاز بعد: الحضور ← مستخدمو الأجهزة ← غير مطابق. وتحقق كذلك من أن الإعدادات ← الحضور ← المصادر المسموح بها تتضمن أجهزة الحضور. |
| كل البصمات تظهر كدخول | بدّل قاعدة الدخول والخروج إلى أول بصمة وآخر بصمة في اليوم. |
| الأوقات مختلفة بساعات | المنطقة الزمنية للجهاز تختلف عن المحددة في Tarleaks. اضبطهما على المنطقة نفسها (صفحة الجهاز ← إعدادات متقدمة). |
رفض بصمات لأن الساعة متقدمة (time_in_future) | ساعة الجهاز متقدمة. استخدم ضبط وقت الجهاز في صفحته، أو صحح الساعة في الجهاز. |
| «مكررة» في التقرير | أمر طبيعي: تلك البصمات محفوظة من قبل. |
| أحداث Hikvision تظهر «ليس حدث مرور» | يرسل الجهاز رمز حدث مختلفاً. أضفه في صفحة الجهاز ← إعدادات متقدمة ← رموز الأحداث المقبولة. |
| 429 | طلبات كثيرة جداً: انتظر Retry-After، وأرسل دفعات أكبر على فترات أبعد. |
| بصمات قديمة تنتظر | هي أقدم من مهلة الاسترجاع. أطلقها من صفحة الجهاز. |
ما القادم
الربط المباشر مع المنصات السحابية للمصنّعين — ZKTeco BioTime وSuprema BioStar 2 / Air وAnviz CrossChex Cloud وHikvision HikCentral — غير متاح بعد. وحتى ذلك الحين، صدّر تقارير الحضور منها واستوردها، أو اطلب من شركة تكامل إرسالها عبر واجهة البصمات البرمجية.
الملحق
بروتوكول ADMS كما هو مطبّق
يُرد على تبادل بدء التشغيل للجهاز (GET /iclock/cdata?SN=…&options=all) بما يلي:
GET OPTION FROM: <serial>
ATTLOGStamp=<last stamp>
OPERLOGStamp=<last stamp>
ATTPHOTOStamp=None
Stamp=<last stamp>
OpStamp=<last stamp>
ErrorDelay=60
Delay=30
TransTimes=00:00;14:05
TransInterval=1
TransFlag=TransData AttLog OpLog EnrollUser ChgUser
TimeZone=4
Realtime=1
Encrypt=None
ServerVer=2.4.1
يطلب TransFlag البصمات وسجلات المستخدمين فقط. وتُكتب TimeZone بالساعات، أو بالدقائق إن لم تكن المنطقة عدداً صحيحاً من الساعات (330).
| الطلب | المعالجة |
|---|---|
POST cdata?table=ATTLOG | أسطر بالصيغة PIN, time, status, verify, work code, …؛ وتُقرأ الحقول الخمسة الأولى فقط. ولا يُرد بـ OK إلا بعد حفظ البصمات. |
POST cdata?table=OPERLOG أو USERINFO | أسطر USER فقط، ومنها PIN وName وCard فقط. |
POST cdata?table=ATTPHOTO وFINGERTMP وFACE وBIODATA وUSERPIC وBIOPHOTO وrtlog | تُتلف دون قراءة؛ ويُرد بـ OK. |
GET getrequest | نبضة اتصال؛ وتُعاد الأوامر المنتظرة بأسطر C:<id>:<command>. |
POST devicecmd | نتائج أوامر الجهاز. |
GET rtdata?type=time | DateTime=<encoded UTC time>,ServerTZ=+0400. |
الأوامر المرسلة إلى الجهاز: ضبط الوقت SET OPTION DateTime=…، وجلب البصمات مرة أخرى DATA QUERY ATTLOG StartTime=… EndTime=…، وقراءة قائمة المستخدمين DATA QUERY USERINFO، وإعادة التشغيل REBOOT.
رقم الحالة ← الدخول والخروج: 0 دخول، 1 خروج، 2 خروج للاستراحة، 3 عودة من الاستراحة، 4 دخول عمل إضافي، 5 خروج عمل إضافي، وأي رقم آخر غير معروف. رقم التحقق ← طريقته: 1 بصمة إصبع، 2 أو 4 بطاقة، 0 أو 3 رقم سري، 15 وجه، 25 كف، وأي رقم آخر «أخرى».
حقول أحداث Hikvision المقروءة
eventType (AccessControllerEvent؛ وأي قيمة أخرى نبضة اتصال)، وdateTime، ومن AccessControllerEvent: majorEventType وsubEventType وemployeeNoString وcardNo وname وattendanceStatus وserialNo وcurrentVerifyMode. ولا يُحفظ أي شيء آخر — لا pictureURL ولا الحرارة ولا الكمامة.
رموز حالات البصمة وأسبابها
| الحالة | الأسباب |
|---|---|
received | — (تنتظر المعالجة) |
unmatched | no_person_for_ref — لم يُطابَق أي موظف بمستخدم الجهاز هذا |
processed | — |
duplicate_read | double_read |
ignored | before_import_start (قبل تاريخ بدء الجهاز)، وnot_a_pass_event (حدث Hikvision ليس مروراً)، وignored_by_admin (استبعدها شخص) |
needs_review | too_old، وemployee_not_active (غير موظف في ذلك اليوم)، وbiometric_source_disabled (أجهزة الحضور ليست ضمن المصادر المسموح بها)، وweek_locked (جدول الساعات مقدَّم أو معتمد)، وentry_edited (عدّل شخص ذلك اليوم)، وoverlaps_other_entry (إدخال يدوي أو من المتصفح يتداخل معه)، وcorrection_pending (طلب تصحيح لذلك اليوم بانتظار القرار؛ يُعاد تلقائياً بعد البت فيه) |
rejected | time_in_future (متقدم أكثر من 5 دقائق عن الخادم) |
التنبيهات على تسجيلات الحضور الناتجة عن بصمات الأجهزة: missing_check_out وmissing_check_in وlong_session وsuperseded.