Lorawan-stack: Mendukung beberapa pesan yang dihasilkan dari satu format

Dibuat pada 13 Agu 2019  ·  12Komentar  ·  Sumber: TheThingsNetwork/lorawan-stack

Ringkasan

Satu ttnpb.ApplicationUp seharusnya dapat menghasilkan beberapa pesan front-end, bukan hanya satu.

Mengapa kita memerlukan ini?

Saat ini, satu ttnpb.ApplicationUp disusun menjadi hanya satu irisan byte yang menghasilkan satu pesan front-end (satu panggilan HTTP, satu pesan MQTT, dll.). Namun, jika muatan uplink berisi beberapa pengukuran (pikirkan beberapa sensor yang terpasang pada satu perangkat), akan sangat membantu jika format tertentu membuat beberapa pesan untuk setiap pengukuran.

Apa yang sudah ada? Apa yang kamu lihat sekarang?

https://github.com/TheThingsNetwork/lorawan-stack/blob/9112dd7bcd3f1f03190055542908b427b27acd1c/pkg/applicationserver/io/formatters/formatter.go#L23
Format saat ini hanya mengembalikan satu pesan untuk dikirim ke front-end.

Apa yang hilang? Apa yang ingin kau lihat?

Hasilnya harus diubah dari []byte menjadi [][]byte .

Lingkungan

93ea01b4b5af2672da5883b570be825a54b8afc1

Bagaimana Anda mengusulkan untuk menerapkan ini?

Ubah antarmuka Format . Setelah itu, setiap front-end harus diubah untuk mengirim semua pesan, bukan hanya satu:

Bisakah Anda melakukannya sendiri dan mengajukan Permintaan Tarik?

Ya, tapi saya akan menyerahkan ini kepada masyarakat.

application server needtriage

Semua 12 komentar

@adriansmares Saya sedang mengerjakan masalah ini. Setelah mengubah dari []byte menjadi [][]byte untuk fungsi *ttnpb.ApplicationUp di file formatter.go, saya juga mengubahnya di file json.go dan protobuf.go. Tapi sekarang, ini memberikan kesalahan berikut:
image
Mohon memberikan beberapa saran. Terima kasih.

@mihirr93 Karena Anda sekarang memodifikasi situs panggilan untuk mengembalikan sepotong hasil (setiap hasil menjadi sepotong byte), Anda harus membungkus tempat di mana hanya satu hasil yang dikembalikan dengan [][]byte{ slice-containing-result } .

Halo Pak @adriansmares . Saya agak bingung dengan pendekatan kami. Kami mengikat untuk mengiris pesan front-end (muatan mentah) menjadi beberapa pesan. Namun dalam kasus ini, titik di mana pesan akan dipotong tergantung pada penyandiannya (Cayenne atau penyandian khusus lainnya) yang tidak kita ketahui. Jadi, untuk melakukan ini kita perlu menggunakan payload yang didekodekan. Setelah pengguna memasukkan dekoder di tab format muatan TTN, aplikasi benar-benar menunjukkan nilai dekode dalam JSON (seperti yang terlihat pada gambar). Bukankah seharusnya kita langsung membagi muatan yang didekodekan ini dan mendorongnya lebih jauh menggunakan http?
image
Bisakah Anda menjelaskan kebingungan ini?
Dan, apakah kita hanya memodifikasi file pkg dan file .proto akan diperbarui secara otomatis?
Terima kasih banyak atas dukungan dan waktunya yang baik.

_Keep diingat bahwa repositori ini berisi versi V3 tumpukan LoRaWAN kami, dan gambar yang disediakan adalah dari TTN, yang menjalankan V2 version._

Harap diingat bahwa masalah ini hanya berkaitan dengan dukungan untuk menghasilkan banyak muatan dari satu pesan, dan masalah format baru yang mungkin menarik bagi Anda adalah https://github.com/TheThingsNetwork/lorawan-stack/issues/1158. Silakan periksa apakah masalah ini benar-benar yang Anda cari.

Meskipun demikian, saya menyarankan dalam kasus ini agar Anda memperkenalkan format baru, berdasarkan format JSON , yang menghasilkan banyak muatan berdasarkan informasi yang didekodekan yang ditemukan di dalam uplink.
Anda mungkin ingin menangani pesan uplink ApplicationUp_UplinkMessage secara khusus, karena berisi bidang yang Anda minati sebagai bagian dari bidang DecodedPayload .

Anda tidak perlu memodifikasi file proto untuk kasus penggunaan ini.

Saya masih mencoba memahami kerja internal dan kode tumpukan. Saat ini, saya hanya fokus pada masalah ini, dan bukan #1158. Seperti yang Anda sarankan untuk memodifikasi ApplicationUp_Uplinkmessage , saya mencoba mencari tahu. Saya memiliki pertanyaan berikut saat ini:
1) struct ApplicationUplink dan func ApplicationUp_UplinkMessage didefinisikan dalam file messages.pb.go di direktori ttnpb. Namun header file menyebutkan "JANGAN EDIT". Haruskah saya mengabaikannya? atau adakah pendekatan alternatif untuk memodifikasinya?
2) Bisakah Anda menjelaskan ini lebih detail " introduce a new format, based on the JSON one "? Saya pikir kita hanya perlu mengubah format yang ada daripada membuat yang baru.
3) Anda juga menyebutkan pembungkus hasil di mana hanya satu hasil yang dikembalikan. Apa sebenarnya yang akan dilakukan? Apakah akan menggabungkan kembali beberapa pesan menjadi satu dan hanya mengembalikan satu hasil? Dan apakah kita perlu melakukan itu hanya untuk pesan Uplink?

[Terima kasih @adriansmares atas bimbingan Anda yang berkelanjutan. Meskipun, saya mengambil tutorial golang, ini adalah interaksi pertama saya dengan bahasa GO, maaf karena mengganggu Anda dengan begitu banyak keraguan]

  • Anda tidak perlu mengedit file itu, atau file *.pb.* . Ini dihasilkan dari file *.proto secara otomatis saat Anda menjalankan mage proto:all . Meskipun demikian, untuk tujuan masalah ini tidak ada modifikasi seperti itu yang harus dilakukan.
  • Silakan ikuti itu di edisi lain.
  • Saran untuk membungkus memungkinkan Anda untuk menjaga kode yang ada tetap utuh (masih mengembalikan satu muatan untuk diposting dari satu pesan uplink).

Biarkan saya mencoba menjelaskan keseluruhan saluran dengan lebih baik, mungkin ini akan menjelaskan cara kerjanya

  1. Sebuah perangkat mengirimkan 1 uplink.
  2. Uplink 1 diterima oleh gateway dan dikirim ke Server Gateway yang meneruskannya ke Server Jaringan, yang kemudian meneruskannya ke Server Aplikasi. Pesan yang mencapai AS bertipe *ttnpb.ApplicationUplink .
  3. AS mengambil 1 uplink ini dan mencoba mendekode payload binernya ke dalam bidang yang didekode (ubah byte di bidang FRMPayload ke dalam struktur dekode DecodedPayload ) menggunakan pemformat muatan perangkat.
  4. Kemudian membungkusnya dalam *ttnpb.ApplicationUp dan mengirimkannya ke frontend (MQTT, webhooks, PubSub, paket aplikasi).
  5. Frontend menerima 1 *ttnpb.ApplicationUp dan berdasarkan pengaturannya (format) pilih formatter mana yang akan digunakan (antarmuka formatter didefinisikan dalam pkg/applicationserver/io/formatters ).
  6. Frontend memanggil formatter.FromUp dengan 1 *ttnph.ApplicationUp dan menerima sepotong byte ( []byte ), yang mewakili isi 1 pesan.

Sekarang, mengenai masalah ini, saya harap terlihat bahwa hanya langkah 6 yang perlu diubah:

  • Mengubah tipe pengembalian antarmuka dan implementasi sedemikian rupa sehingga FromUp dapat mengembalikan beberapa muatan (sepotong irisan byte).
  • Format Protobuf dan JSON yang ada seharusnya tidak mengubah perilakunya, dan karena itu harus terus mengembalikan hanya 1 payload (itulah mengapa wrap diperlukan).
  • Setelah mengubah 2 ini (antarmuka dan pemformat) untuk mengembalikan [][]byte Anda akan mulai melihat kesalahan (karena sebagian besar tempat yang memanggil FromUp mengharapkan hanya satu muatan yang akan diterima - Anda harus memperbarui situs panggilan ini dan buat mereka mengulang daftar muatan dan mengirim masing-masing.

Hanya setelah masalah ini, yang tidak mengubah perilaku sama sekali, telah diperbaiki, Anda dapat melanjutkan dengan menerapkan formatter Anda sendiri, yang akan mengembalikan sepotong beberapa muatan, satu untuk setiap pengukuran (tetapi perlu diingat bahwa format baru ini berada di luar cakupan untuk masalah ini!).

Terima kasih banyak @adriansmares atas penjelasan dan panduan yang begitu mendetail. Saya pikir saya telah berhasil menyelesaikan masalah ini sekarang. Saya juga mengujinya dengan ./mage go:test js:test jsSDK:test dan tidak memberikan kesalahan. Perubahan besar yang dibuat dalam kode disorot di bawah ini:
formatter.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
Sama seperti di atas

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
Sama seperti di atas

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
}

Mohon berikan tanggapan dan komentar Anda. Saya akan melakukan koreksi (penamaan Var, lekukan, dll) sesuai dengan pedoman gaya kode setelah tugas selesai sepenuhnya. Dan jika ini terlihat benar, bisakah Anda membimbing saya lebih lanjut untuk masalah #1158 . Terima kasih sekali lagi.

@mihirr93 terlihat bagus! Harap komit perubahan Anda dan kirimkan permintaan tarik untuk masalah ini. Setelah menggabungkannya, kita dapat melanjutkan ke formatter baru yang disebutkan di #1158.

@adriansmares Tentu, saya akan melakukannya. Haruskah permintaan tarik itu didasarkan pada lingkungan yang disebutkan atau pada versi terbaru dari tumpukan?

Saya sarankan Anda mengubah basis perubahan Anda di atas master untuk menghindari konflik nanti.

Masalah ini telah tidak aktif cukup lama, jadi mari kita kembalikan ke triase untuk melihat apakah masih ada permintaan untuk ini, atau sebaiknya kita batalkan saja.

Ini tidak lagi diperlukan, karena skalanya buruk.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

johanstokking picture johanstokking  ·  6Komentar

htdvisser picture htdvisser  ·  4Komentar

ecities picture ecities  ·  5Komentar

adriansmares picture adriansmares  ·  9Komentar

johanstokking picture johanstokking  ·  8Komentar