Lorawan-stack: دعم عدة رسائل ناتجة من تنسيق واحد

تم إنشاؤها على ١٣ أغسطس ٢٠١٩  ·  12تعليقات  ·  مصدر: TheThingsNetwork/lorawan-stack

ملخص

يجب أن يكون بمقدور ttnpb.ApplicationUp أن ينتج عنه رسائل أمامية متعددة ، بدلاً من رسالة واحدة فقط.

لماذا نحتاج هذا؟

حاليًا ، يتم تنظيم ttnpb.ApplicationUp واحدًا في شريحة بايت واحدة فقط ينتج عنها رسالة واجهة أمامية واحدة (مكالمة HTTP واحدة ، رسالة MQTT واحدة وما إلى ذلك). ومع ذلك ، إذا كانت حمولة الارتباط الصاعد تحتوي على قياسات متعددة (فكر في أجهزة استشعار متعددة متصلة بجهاز واحد) ، فسيكون من المفيد السماح بتنسيقات معينة لإنشاء رسائل متعددة لكل قياس.

ما هو موجود بالفعل؟ ماذا ترى الآن؟

https://github.com/TheThingsNetwork/lorawan-stack/blob/9112dd7bcd3f1f03190055542908b427b27acd1c/pkg/applicationserver/io/formatters/formatter.go#L23
يعرض التنسيق حاليًا رسالة واحدة فقط ليتم إرسالها إلى الواجهات الأمامية.

ما المفقود؟ ماذا تريد ان ترى؟

يجب تغيير النتيجة من []byte إلى [][]byte .

بيئة

93ea01b4b5af2672da5883b570be825a54b8afc1

كيف تقترح تنفيذ هذا؟

تغيير واجهة Format . بعد ذلك ، يجب تغيير كل واجهة أمامية لإرسال جميع الرسائل بدلاً من رسالة واحدة فقط:

هل يمكنك القيام بذلك بنفسك وإرسال طلب سحب؟

نعم ، لكني سأترك هذا للمجتمع.

application server needtriage

ال 12 كومينتر

adriansmares أعمل حاليًا على
image
يرجى تقديم بعض الاقتراحات. شكرا لك.

@ mihirr93 نظرًا لأنك تقوم الآن بتعديل مواقع الاتصال لإرجاع شريحة من النتائج (كل نتيجة عبارة عن شريحة من البايت) ، يجب عليك التفاف الأماكن حيث يتم إرجاع نتيجة واحدة فقط بـ [][]byte{ slice-containing-result } .

مرحبا السيد adriansmares . أنا مرتبك قليلاً فيما يتعلق بنهجنا. نحن ملتزمون بتقسيم رسالة الواجهة الأمامية (حمولة خام) إلى رسائل متعددة. لكن في هذه الحالة ، تعتمد النقطة التي سيتم عندها تقطيع الرسالة على ترميزها (كايين أو أي ترميز مخصص) وهو أمر غير معروف لنا. لذلك ، للقيام بذلك نحتاج إلى استخدام الحمولة التي تم فك تشفيرها. بمجرد أن يدخل المستخدم وحدة فك التشفير في علامة تبويب تنسيق الحمولة النافعة في TTN ، يعرض التطبيق بالفعل القيم التي تم فك تشفيرها في JSON (كما هو موضح في الصورة). ألا يجب علينا تقسيم الحمولة النافعة المشفرة ودفعها أكثر باستخدام http؟
image
هل يمكنك إلقاء بعض الضوء على هذا الارتباك من فضلك؟
وهل نقوم فقط بتعديل ملفات pkg وسيتم تحديث ملفات .proto تلقائيًا؟
شكرا جزيلا لدعمك الكريم ووقتك.

_ ضع في اعتبارك أن هذا المستودع يحتوي على إصدار V3 من مكدس LoRaWAN الخاص بنا ، والصورة المقدمة من TTN ، التي تشغل الإصدار V2 .

يرجى أن تضع في اعتبارك أن هذه المشكلة تتعامل فقط مع دعم إنتاج حمولات متعددة من رسالة واحدة ، وأن مشكلة التنسيق الجديدة التي ربما تكون مهتمًا بها هي https://github.com/TheThingsNetwork/lorawan-stack/issues/1158. يرجى التحقق مما إذا كانت هذه المشكلة هي بالفعل المشكلة التي تبحث عنها.

ومع ذلك ، أقترح في هذه الحالة أن تقدم تنسيقًا جديدًا ، بناءً على تنسيق JSON ، والذي ينتج حمولات متعددة بناءً على المعلومات التي تم فك تشفيرها الموجودة داخل الارتباط الصاعد.
ربما ترغب في التعامل مع رسالة الارتباط الصاعد ApplicationUp_UplinkMessage وجه التحديد ، نظرًا لأنها تحتوي على الحقول التي تهتم بها كجزء من الحقل DecodedPayload .

لا يجب عليك تعديل الملفات الأولية لحالة الاستخدام هذه.

ما زلت أحاول فهم العمل الداخلي ورمز المكدس. حاليًا ، أركز على هذه المشكلة فقط وليس على # 1158. كما اقترحت تعديل ApplicationUp_Uplinkmessage ، فأنا أحاول معرفة ذلك. لدي استفسارات التالية في هذه اللحظة:
1) تم تعريف البنية ApplicationUplink و func ApplicationUp_UplinkMessage في ملف messages.pb.go في دليل ttnpb. ومع ذلك ، يذكر رأس الملف "عدم التحرير". هل يجب علي تجاهلها؟ أم أن هناك أي نهج بديل لتعديله؟
2) هل يمكنك وصف هذا بمزيد من التفصيل " introduce a new format, based on the JSON one "؟ اعتقدت أنه يتعين علينا فقط تعديل التنسيق الحالي بدلاً من إنشاء تنسيق جديد.
3) لقد ذكرت أيضًا التفاف النتائج حيث يتم إرجاع نتيجة واحدة فقط. ماذا سيفعل ذلك بالضبط؟ هل سيعيد دمج الرسائل المتعددة في رسالة واحدة ويعيد نتيجة واحدة فقط؟ وهل نحن بحاجة للقيام بذلك لرسالة Uplink فقط؟

[شكرًا لك adriansmares على

  • لا تحتاج إلى تحرير هذا الملف ، ولا أي ملفات *.pb.* . يتم إنشاؤها من ملفات *.proto تلقائيًا عند تشغيل mage proto:all . ومع ذلك ، لغرض هذه القضية ، لا يلزم إجراء مثل هذه التعديلات.
  • يرجى متابعة ذلك في القضية الأخرى.
  • يسمح لك اقتراح الالتفاف بالحفاظ على الكود الحالي كما هو (مع الاستمرار في إرجاع حمولة واحدة ليتم ترحيلها من رسالة ارتباط واحد).

اسمحوا لي أن أحاول شرح خط الأنابيب بالكامل بشكل أفضل ، ربما يلقي هذا بعض الضوء على كيفية عمل ذلك

  1. يرسل جهاز واحد ارتباطًا صاعدًا.
  2. تستقبل البوابة الارتباط الصاعد 1 وإرساله إلى خادم البوابة الذي يعيد توجيهه إلى خادم الشبكة ، والذي يعيد توجيهه بعد ذلك إلى خادم التطبيق. الرسالة التي تصل AS هي من النوع *ttnpb.ApplicationUplink .
  3. يأخذ AS هذا الارتباط الصاعد 1 ويحاول فك ترميز حمولته الثنائية في الحقول التي تم فك ترميزها (قم بتحويل البايتات الموجودة في الحقل FRMPayload إلى البنية المشفرة لـ DecodedPayload ) باستخدام مُنسق حمولة الجهاز.
  4. ثم يلفه في *ttnpb.ApplicationUp ويرسله إلى الواجهات الأمامية (MQTT ، webhooks ، PubSub ، حزم التطبيقات).
  5. تتلقى الواجهات الأمامية هذا 1 *ttnpb.ApplicationUp واستنادًا إلى إعداداتها (التنسيق) ، اختر المنسق الذي تريد استخدامه (يتم تحديد واجهة المنسق في pkg/applicationserver/io/formatters ).
  6. تستدعي الواجهة الأمامية formatter.FromUp مع 1 *ttnph.ApplicationUp وتتلقى شريحة من البايت ( []byte ) ، تمثل نص رسالة واحدة.

الآن ، فيما يتعلق بهذه المشكلة ، آمل أن يكون مرئيًا أن الخطوة 6 فقط تحتاج إلى تغييرات:

  • تغيير أنواع الإرجاع لكل من الواجهة والتطبيقات بحيث يمكن لـ FromUp إرجاع حمولات متعددة (شريحة من شرائح البايت).
  • يجب ألا تغير التنسيقات الحالية Protobuf و JSON سلوكها ، وعلى هذا النحو يجب أن تستمر في إرجاع حمولة واحدة فقط (وهذا هو السبب في أن التغليف مطلوب).
  • بعد تغيير هذين (الواجهة والمنسِّقات) لإرجاع [][]byte ستبدأ في رؤية أخطاء (نظرًا لأن معظم الأماكن التي تستدعي FromUp تتوقع استلام حمولة واحدة فقط - عليك التحديث مواقع الاتصال هذه وتجعلها تدور عبر قائمة الحمولات وترسل كل منها.

فقط بعد إصلاح هذه المشكلة ، التي لا تغير السلوك على الإطلاق ، يمكنك المضي قدمًا في تنفيذ المُنسق الخاص بك ، والذي سيعيد شريحة من حمولات متعددة ، واحدة لكل قياس (ولكن ضع في اعتبارك أن هذا التنسيق الجديد خارج نطاق هذه المشكلة!).

شكرًا جزيلاً adriansmares لك على هذا ./mage go:test js:test jsSDK:test ولا يعطي أي خطأ. يتم تمييز التغييرات الرئيسية التي تم إجراؤها في الكود أدناه:
منسق. go

type Formatter interface {
    FromUp(*ttnpb.ApplicationUp) ([][]byte, error)
    ToDownlinks([]byte) (*ttnpb.ApplicationDownlinks, error)
    ToDownlinkQueueRequest([]byte) (*ttnpb.DownlinkQueueRequest, error)
}

json.go

func (json) FromUp(msg *ttnpb.ApplicationUp) ([][]byte, error) {
    m, e := jsonpb.TTN().Marshal(msg)
    return [][]byte{m}, e
}

protobuf.go
كما ورد أعلاه

mqtt.go

buf, err := c.format.FromUp(up.ApplicationUp)
                if err != nil {
                    logger.WithError(err).Warn("Failed to marshal upstream message")
                    continue
                }
                logger.Debug("Publish upstream message")
                for _, v := range buf {
                    c.session.Publish(&packet.PublishPacket{
                        TopicName:  topic.Join(topicParts),
                        TopicParts: topicParts,
                        QoS:        qosUpstream,
                        Message:    v,
                    })
                }

pubsub.go
كما ورد أعلاه

webhooks.go

unc (w *webhooks) newRequest(ctx context.Context, msg *ttnpb.ApplicationUp, hook *ttnpb.ApplicationWebhook) ([]*http.Request, error) {
    var cfg *ttnpb.ApplicationWebhook_Message
    switch msg.Up.(type) {
    case *ttnpb.ApplicationUp_UplinkMessage:
        cfg = hook.UplinkMessage
    case *ttnpb.ApplicationUp_JoinAccept:
        cfg = hook.JoinAccept
    case *ttnpb.ApplicationUp_DownlinkAck:
        cfg = hook.DownlinkAck
    case *ttnpb.ApplicationUp_DownlinkNack:
        cfg = hook.DownlinkNack
    case *ttnpb.ApplicationUp_DownlinkSent:
        cfg = hook.DownlinkSent
    case *ttnpb.ApplicationUp_DownlinkFailed:
        cfg = hook.DownlinkFailed
    case *ttnpb.ApplicationUp_DownlinkQueued:
        cfg = hook.DownlinkQueued
    case *ttnpb.ApplicationUp_LocationSolved:
        cfg = hook.LocationSolved
    }
    if cfg == nil {
        return nil, nil
    }
    url, err := url.Parse(hook.BaseURL)
    if err != nil {
        return nil, err
    }
    url.Path = path.Join(url.Path, cfg.Path)
    expandVariables(url, msg)
    if err != nil {
        return nil, err
    }
    format, ok := formats[hook.Format]
    if !ok {
        return nil, errFormatNotFound.WithAttributes("format", hook.Format)
    }
    buf, err := format.FromUp(msg)
    if err != nil {
        return nil, err
    }
    var requests []*http.Request
    for i, v := range buf {
        req, err := http.NewRequest(http.MethodPost, url.String(), bytes.NewReader(v))
        requests[i] = req
        if err != nil {
            return nil, err
        }
        for key, value := range hook.Headers {
            req.Header.Set(key, value)
        }
        if hook.DownlinkAPIKey != "" {
            req.Header.Set(downlinkKeyHeader, hook.DownlinkAPIKey)
            req.Header.Set(downlinkPushHeader, w.createDownlinkURL(ctx, hook.ApplicationWebhookIdentifiers, msg.EndDeviceIdentifiers, "push"))
            req.Header.Set(downlinkReplaceHeader, w.createDownlinkURL(ctx, hook.ApplicationWebhookIdentifiers, msg.EndDeviceIdentifiers, "replace"))
        }
        req.Header.Set("Content-Type", format.ContentType)
        req.Header.Set("User-Agent", userAgent)
    }
    return requests, nil
}

يرجى تقديم ملاحظاتك وتعليقاتك. سأقوم بإجراء التصحيحات (تسمية المتغير ، والمسافة البادئة ، وما إلى ذلك) وفقًا لإرشادات نمط الكود بمجرد الانتهاء من المهمة تمامًا. وإذا كان هذا يبدو صحيحًا ، فهل يمكنك إرشادي أكثر للإصدار رقم 1158. شكرا لك مرة اخرى.

@ mihirr93 تبدو جيدة! الرجاء تنفيذ التغييرات الخاصة بك وتقديم طلب سحب لهذه المشكلة. بعد دمجها يمكننا المضي قدمًا إلى المُنسق الجديد المذكور في # 1158.

adriansmares بالتأكيد ، سأفعل ذلك. هل ينبغي أن يستند طلب السحب هذا إلى البيئة المذكورة أم على أحدث إصدار من المكدس؟

أوصيك بإعادة تحديد قاعدة التغييرات التي أجريتها فوق أحدث master لتجنب التعارضات لاحقًا.

كانت هذه المشكلة غير نشطة لفترة طويلة ، لذا دعنا نعيدها إلى الفرز لمعرفة ما إذا كان لا يزال هناك طلب على هذا ، أو أنه يجب علينا إسقاطه.

لم تعد هناك حاجة إلى هذا ، لأنه يتقلص بشكل سيئ.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات