English

ابدأ التجربة المجانيةاحجز عرضاً تجريبياً

ربط أجهزة الحضور بنظام 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 يوماً
مستخدمو الأجهزة غير المطابقين الذين لم يظهروا طوال مدة الاحتفاظ بالبصماتيُحذفون

أما تسجيلات الحضور نفسها فهي سجلات وقت عادية تتبع مدة الاحتفاظ المعتادة لديكم.

قبل أن تبدأ

  1. عنوان مساحة العمل. وهو https://<company>.tarleaks.com — العنوان الذي تفتح به Tarleaks. في التثبيت على خوادمكم، هو عنوان التثبيت نفسه (TARLEAKS_URL في ملف .env)، وتعرضه لك تبويبة الاتصال في صفحة الجهاز مع المنفذ الصحيح. وإذا كان العنوان http:// عاديًا داخل شبكة المكتب، تذكر الخطوات ذلك ويبقى خيار HTTPS في الجهاز مُطفأً.
  2. من يستطيع ذلك. إضافة الأجهزة وتعديلها تحتاج صلاحية الحضور — الأجهزة — تعديل (لدى دوري مدير المؤسسة ومدير الموارد البشرية). مطابقة مستخدمي الأجهزة بالموظفين تحتاج صلاحية بصمات الأجهزة — معالجة (مدير المؤسسة، مدير الموارد البشرية، أخصائي الموارد البشرية). استيراد ملف السجل يحتاج صلاحية بصمات الأجهزة — استيراد (مدير المؤسسة، مدير الموارد البشرية)، لأنه ينشئ تسجيلات حضور لموظفين آخرين. ويستطيع المدراء رؤية الأجهزة ومعرفة إن كانت متصلة.
  3. التفعيل. يجب أن يكون الإعدادات ← الميزات ← الحضور ← أجهزة الحضور مفعّلاً (وهو مفعّل افتراضياً). عند إيقافه تُرفض الأجهزة ولا تُستقبل بصماتها؛ وتبقى الأجهزة المضافة ظاهرة، ويمكنك أرشفة الجهاز أو استبدال مفتاحه.
  4. السماح بتسجيل الحضور من الأجهزة. يجب أن تتضمن الإعدادات ← الحضور ← المصادر المسموح بها خيار أجهزة الحضور. بدونه تصل البصمات لكنها تنتظر المراجعة بدل أن تصبح تسجيلات حضور.
  5. المنطقة الزمنية. تحتفظ الأجهزة بالتوقيت المحلي. يقرأ Tarleaks أوقات الجهاز بالمنطقة الزمنية للجهاز: المحددة في صفحة الجهاز، وإلا الافتراضية في الإعدادات ← الحضور ← أجهزة الحضور ← إعدادات متقدمة، وإلا منطقة مساحة العمل. اضبط ساعة الجهاز على المنطقة نفسها.
  6. الشبكة. الأجهزة وبرنامج الربط المحلي يفتحون اتصالات صادرة فقط عبر 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. تختلف أسماء القوائم قليلاً بين الطرازات وإصدارات البرامج.

  1. أضف الجهاز في Tarleaks: الحضور ← أجهزة الحضور ← إضافة جهاز ← ZKTeco أو eSSL أو مشابه. انسخ مفتاح الاتصال عند ظهوره.
  2. على الجهاز، اضبط كلمة مرور للمسؤول (Menu ← User Mgt ← اجعل أحد المستخدمين Administrator) حتى لا يقرأ أحد مفتاح الاتصال من قائمته.
  3. على الجهاز: Menu ← COMM ← Cloud Server Setting (في بعض الطرازات: Comm. ← ADMS).
  4. فعّل Enable Domain Name.
  5. Server Address: <company>.tarleaks.com/zk/<key> — عنوان مساحة العمل، ثم /zk/، ثم مفتاح ربط الجهاز. طول العنوان كاملاً نحو 80 خانة (acme-uae.tarleaks.com/zk/atd_… طوله 77). والجهاز يضيف /iclock/… من تلقاء نفسه.
  6. Server Port: 443.
  7. HTTPS: تشغيل. Proxy: إيقاف.
  8. Menu ← System ← Date/Time: اضبط المنطقة الزمنية الظاهرة في تبويب «الربط» للجهاز (في الإمارات: UTC+04:00).
  9. احفظ، ثم أعد تشغيل الجهاز. يظهر أول اتصال في صفحة الجهاز خلال دقيقة.

صيغ أخرى للعنوان. الصيغة الطويلة <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»).

  1. أضف الجهاز في Tarleaks: الحضور ← أجهزة الحضور ← إضافة جهاز ← جهاز Hikvision. انسخ مفتاح الاتصال.
  2. اضبط كلمة مرور قوية للمسؤول في صفحة إعدادات الجهاز.
  3. في صفحة إعدادات الجهاز: Configuration ← Network ← Advanced ← HTTP Listening (في بعض الطرازات: Alarm Server).
  4. Protocol: HTTPS. Address type: domain name. Host: <company>.tarleaks.com. Port: 443.
  5. URL: /api/attendance/public/v1/hikvision/<key>/events — ضع مفتاح ربط الجهاز مكان <key>.
  6. Format: JSON. Authentication: none (المفتاح الموجود في العنوان هو بيانات الاعتماد).
  7. Event ← Access Control ← linkage: فعّل Upload to center (أو Notify surveillance center) لأحداث التحقق.
  8. System ← Time: خادم NTP هو pool.ntp.org، والمنطقة الزمنية GMT+04:00 (أو منطقتك).
  9. احفظ واضغط 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الرمزالمعنى — وما العمل
400BAD_BATCHليس JSON، أو punches مفقود أو فارغ أو أكثر من 500. صحّح محتوى الطلب. (الحقل الخاطئ النوع داخل بصمة واحدة لا يُفشل الدفعة: تظهر تلك البصمة في rejected بالرمز BAD_FIELD.)
401DEVICE_TOKEN_INVALIDالمفتاح مفقود أو خاطئ أو مستبدل، أو أُرشف الجهاز. انسخ المفتاح الحالي، أو أصدر مفتاحاً جديداً من صفحة الجهاز.
402ATTENDANCE_NOT_LICENSEDمساحة العمل لا تملك ترخيص الحضور. تواصل مع ممثل Tarleaks.
403WORKSPACE_SUSPENDEDمساحة العمل موقوفة.
403DEVICE_INTEGRATIONS_OFFخيار الإعدادات ← الميزات ← الحضور ← أجهزة الحضور متوقف (أو أوقفته المنصة). فعّله.
403DEVICE_INACTIVEالجهاز غير نشط أو مؤرشف.
403DEVICE_ADDRESS_NOT_ALLOWEDللجهاز عناوين مسموح بها وهذا الطلب جاء من عنوان آخر. اسمح به من صفحة الجهاز.
403WRONG_WORKSPACE_ADDRESSالمفتاح يخص مساحة عمل غير العنوان الذي استدعيته. استخدم عنوان مساحة عملك.
408TRY_AGAINاستغرق وصول محتوى الطلب أكثر من 15 ثانية. لم يُحفظ شيء؛ أرسل الدفعة نفسها مرة أخرى بعد عدد الثواني في Retry-After (وعلى اتصال بطيء أرسل دفعات أصغر).
413BODY_TOO_LARGEأرسل دفعات أصغر.
429SLOW_DOWN أو DAILY_LIMITطلبات أو بصمات كثيرة جداً. انتظر عدد الثواني في Retry-After، ثم أعد إرسال الدفعة نفسها.
503TRY_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.zip
Windows: 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_tcpZKTeco وeSSL وFingerTec عبر منفذ TCP رقم 4370address، و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، أو عند الحاجة لتحميل سجل قديم:

  1. صدّر السجل. أجهزة ZKTeco وما يشبهها: ضع ذاكرة USB في الجهاز، ثم Menu ← USB Manager (أو Pen Drive Mng) ← Download ← Attendance Data. ستحصل على ملف مثل 1_attlog.dat. الأجهزة الأخرى: صدّر سجل الحضور بصيغة CSV أو Excel من الجهاز أو برنامجه.
  2. استورده. في صفحة الجهاز في Tarleaks (أضف جهازاً من نوع يصدّر ملفًا فقط (USB))، اختر استيراد ملف سجل أو جدول بيانات (في تبويب البصمات)، واختر الملف، وراجع الأعمدة في المعاينة — ترتيب الأعمدة في ملفات USB يختلف بين الطرازات، لذلك تُعرض الصفوف الأولى لتأكيدها — ثم استورد.
  3. المنطقة الزمنية. تُقرأ أوقات الملف بالمنطقة الزمنية للجهاز ما لم تختر غيرها أثناء الاستيراد. وعمود الدخول والخروج اختياري.

استيراد الملف نفسه مرة أخرى آمن: البصمات المحفوظة سابقاً تظهر كمكررة. ويحتاج الاستيراد صلاحية بصمات الأجهزة — استيراد، لأنه ينشئ تسجيلات حضور للأشخاص الواردين في الملف؛ ويُسجَّل اسم من قام بالاستيراد على كل بصمة.

مطابقة الأشخاص

يعرف الجهاز الأشخاص بأرقام المستخدمين الخاصة به. وعلى 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=timeDateTime=<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— (تنتظر المعالجة)
unmatchedno_person_for_ref — لم يُطابَق أي موظف بمستخدم الجهاز هذا
processed—
duplicate_readdouble_read
ignoredbefore_import_start (قبل تاريخ بدء الجهاز)، وnot_a_pass_event (حدث Hikvision ليس مروراً)، وignored_by_admin (استبعدها شخص)
needs_reviewtoo_old، وemployee_not_active (غير موظف في ذلك اليوم)، وbiometric_source_disabled (أجهزة الحضور ليست ضمن المصادر المسموح بها)، وweek_locked (جدول الساعات مقدَّم أو معتمد)، وentry_edited (عدّل شخص ذلك اليوم)، وoverlaps_other_entry (إدخال يدوي أو من المتصفح يتداخل معه)، وcorrection_pending (طلب تصحيح لذلك اليوم بانتظار القرار؛ يُعاد تلقائياً بعد البت فيه)
rejectedtime_in_future (متقدم أكثر من 5 دقائق عن الخادم)

التنبيهات على تسجيلات الحضور الناتجة عن بصمات الأجهزة: missing_check_out وmissing_check_in وlong_session وsuperseded.