Satu ttnpb.ApplicationUp
seharusnya dapat menghasilkan beberapa pesan front-end, bukan hanya satu.
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.
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.
Hasilnya harus diubah dari []byte
menjadi [][]byte
.
93ea01b4b5af2672da5883b570be825a54b8afc1
Ubah antarmuka Format
. Setelah itu, setiap front-end harus diubah untuk mengirim semua pesan, bukan hanya satu:
[]http.Request
bukannya http.Request
), dan hasil dari format.FromUp
harus digunakan untuk membuat permintaan ini.topic.Send
untuk setiap hasil i.format.FromUp
.[][]byte
, karena format JSON default hanya mengembalikan satu pesan.Ya, tapi saya akan menyerahkan ini kepada masyarakat.
@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:
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?
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]
*.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.Biarkan saya mencoba menjelaskan keseluruhan saluran dengan lebih baik, mungkin ini akan menjelaskan cara kerjanya
*ttnpb.ApplicationUplink
.FRMPayload
ke dalam struktur dekode DecodedPayload
) menggunakan pemformat muatan perangkat.*ttnpb.ApplicationUp
dan mengirimkannya ke frontend (MQTT, webhooks, PubSub, paket aplikasi).*ttnpb.ApplicationUp
dan berdasarkan pengaturannya (format) pilih formatter mana yang akan digunakan (antarmuka formatter didefinisikan dalam pkg/applicationserver/io/formatters
).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:
FromUp
dapat mengembalikan beberapa muatan (sepotong irisan byte).Protobuf
dan JSON
yang ada seharusnya tidak mengubah perilakunya, dan karena itu harus terus mengembalikan hanya 1 payload (itulah mengapa wrap diperlukan).[][]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.