IoT ve Yapıcılar için SVG Web Sayfası Bileşenleri (Bölüm 2)

Yayınlanan: 2022-03-10
Kısa özet ↬ IoT web sayfası için arayüzler tasarlarken, her zaman birçok seçeneğe sahiptir. Bu makalenin önceki bölümünde, Richard Leddy, IoT'nin anlamına ve Vue.js'nin IoT insan-makine arayüz gruplarını barındırmak için nasıl kullanılabileceğine ışık tuttu. Bugün, tembel yükleme panellerine ve Vue durumunun cihazlarla nasıl senkronize tutulacağına daha yakından bakalım.

Dolayısıyla, istersek panelleri yükleyerek tepki verecek şekilde yapılmış bir SVG simgeleri menüsünü dinamik olarak yükleme yollarımız zaten var, ancak simgeler gerçek bileşenler değildi. Her simge için SVG'yi getirme ve onu Vue uygulamasına geçirme gibi basit bir numara kullanabildik. Bir simgeler listesi oluşturmak yeterince basitti ve küçük veri farklılıkları dışında her simge benzer şekilde tepki verdi. Veri farkı, bir panelin adını, simgenin düğmesi tıklaması için işleyicinin iletebileceği şekilde her simgeye bağlamayı mümkün kıldı.

Bir panel Vue bileşeni biçiminde yüklendiğinde, panel ve bileşenleriyle ilgili her şeyin, şablonların, JavaScript'in ve daha fazlasının yüklenmesi gerekir. Bu nedenle, sadece paneli yüklemeyi yönetme işi, bu tartışmada şimdiye kadar karşılaştığımızdan daha büyük.

Vue'nun zaman uyumsuz yükleme için bir kanca sağlama yöntemine bakalım. Aşağıdaki snippet, Vue kılavuzundan alınmıştır.

 Vue.component('async-example', function (resolve, reject) { setTimeout(function () { // Pass the component definition to the resolve callback resolve({ template: '<div>I am async!</div>' }) }, 1000) })

Kılavuz bize setTimeout işlevinin, Vue bileşenleriyle eşzamanlılığın nasıl kullanılacağına dair bir örnek olduğunu söyler. Daha önce Vue.component ikinci parametresi olarak bir nesnenin olduğu yerde, şimdi fabrika işlevi olarak adlandırılan bir işlev olduğuna dikkat edin. resolve geri çağrısı içinde, daha önce Vue.component ikinci parametresi olan bir bileşen tanımı bulunur.

Atlamadan sonra daha fazlası! Aşağıdan okumaya devam edin ↓

Bu yüzden, bana mantıklı gelmeden önce bir süre bu örneğe bakmak zorunda kaldım. İşte bana daha çok uyan başka bir örnek:

 Vue.component('async-example', function (resolve, reject) { // Vue will call this function and promise itself to handle // it when it gets back with data. // this function can then call a promising object loader // here the 'loader' function is some abstract function. // Most likely the application will use 'fetch' // but it could be something else. loader('/my/resource/on/server.json'). then(function (JSON_data) { var object = transformJSONToJSObject(JSON_data); resolve(object) }).catch( (error) => { handle it } );

Bu formun etrafından dolaşmak için daha genel bir işlev yapmak için yapılacak doğru şey gibi görünüyor.

 function componentLoader(c_name,resource_url) { Vue.component(c_name, function (resolve, reject) { loader(resource_url). then(function (JSON_data) { var object = transformJSONToJSObject(JSON_data); resolve(object) }).catch( (error) => { handle it } ); }

Bu nedenle, genel olarak, bir bileşeni yüklemek için aşağıdaki gibi bir satıra ihtiyacımız var:

 componentLoader('ThermoPanel','./JSON/thermo-panel.json');

Peki şimdi, yüklenen JSON nedir? Bileşenle ilgili her şeyi içerebilir. Bu durumda, bir panel bileşeni olarak termometreler, makine anahtarları, kaydırıcılar, göstergeler ve daha fazlasını içerebilir. Bileşen kısımlarını web sayfasında tutmak daha hoş görünse de, daha önce yaptığımız 'termo-panel' için daha uzun örnekte olan alt bileşen alanını ve benzer şekilde yapılmış diğer paneller için kullanmak aslında daha iyi sonuç verebilir. JSON, eksiksiz bir panel yapısı içerecektir.

Bununla birlikte, okuyucu transformJSONToJSObject işlev çağrısının dahil edildiğini fark ederse, JSON'un taşımayı kolaylaştırmak ve bir sunucunun tanımı işlemesini kolaylaştırmak için bir şekilde kodlanabileceğini anlayacaktır. Sonuçta tanım, eksiksiz SVG şablonlarını, işlev tanımlarını ve diğer JavaScript ifadelerini içerecektir. Ayrıca, JSON nesnesi yalnızca panel tanımından fazlasını içerebilir, çünkü bazı bilgiler defter tutma veya doğrulamaya yardımcı olabilir. Bu nedenle, alındıktan sonra nesnenin bir miktar muamele göreceğini bekleyebiliriz.

Kodlamaya gelince, sunucudan gelen veriler çeşitli şekillerde kodlanabilir. Belki de basitçe URL kodlu olacaktır. Ya da daha güvenli bir şekilde, şifrelenmiş olabilir. Bu tartışma için sadece URL kodlamasını kullanabiliriz.

Vue uygulamaları oluşturmak için kullanılabilecek araçlardan bazıları şüphesiz JSON dönüşümüyle ilgilenir. Ancak, bu tartışma şimdiye kadar komut satırı araçlarının kullanımından kaçındı. Bu eksiklik o kadar da kötü değil çünkü Vue'yu minimum kaynakla ve CDN'ye atıfta bulunmak için yalnızca bir komut dosyası etiketi kullanarak da kullandık. Ancak, özellikle projeleri organize etmek için komut satırı araçlarına bakmanızı kesinlikle tavsiye ederim.

JSON sayfaya ulaştığında, bileşen tamamen alt bileşenlerle birleştirilmiş olduğu için, parçaları getirmek için daha fazla iş yapılması gerekmez. Bu tartışmanın geri kalanı için tüm bileşenlerin tam olarak tanımlanacağını varsayabiliriz. Ancak, eksiksiz bileşen hiyerarşilerini bir araya getirmek, bir noktada komut satırı araçları gerektirecektir.

SVG düzenleme süreci de biraz çalışma gerektirecektir. SVG düzenleme süreçleri, bir tasarımcının bir panel ve üzerindeki tüm bileşenleri çizmesine olanak tanır. Ancak, her bir alt bileşen tanımlanmalı, bir grupta seslendirilmeli veya bir yer tutucu verilmelidir. Çizimi kullanmaya yönelik herhangi bir yaklaşım, Vue bileşen etiketlerinin grupları veya grafik öğelerini değiştirebilmesi için SVG'nin biraz işlenmesini gerektirir. Bu şekilde, herhangi bir sanatçı sunumu bir şablon haline gelebilir. Ve çizilen alt bileşenlerin, Vue alt bileşenleri için şablonlara demonte edilmesi gerekecektir.

Bu tür bir tutum, JavaScript çerçevelerinin çoğunun iş akışına aykırıdır. Çerçeveler, sayfaları bir araya getirmekle ilgilidir. Ancak, düzenleme veya çizim, zaten bir sanatçı tarafından bir araya getirilmiş bir şeyle sonuçlanır. Uygulamada, düzenlemenin sonucu, doğrudan bir çerçeve bileşeni tanımına karşılık gelen bir metin dosyası sağlamaz.

Düzenleme süreci hakkında daha fazla bilgi başka bir tartışmada düşünülebilir. Bunun için çok şey var. Ancak şimdilik hiyerarşik bileşenleri yüklemek ve onları canlandırmak için ihtiyacımız olan araçlara sahibiz.

Tembel Uygulama

IoT panel yapımız için aramalara yanıt veren bir seçim çubuğumuz zaten var. Ve ihtiyacımız olduğunda bileşenleri yükleme yöntemimiz var. Sadece bu parçaları bağlamamız gerekiyor. Ve son olarak, panellerin göründüğünden ve çalıştıklarında çalışmaya başladıklarından emin olmalıyız.

Yukarıdaki zaman uyumsuz kod tarafından yapılan panellerin tembel yüklenmesi, bir fikir taslağı sağlar. Ancak, neyse ki, bazı insanlar her türlü bileşenin yüklenebildiğinden emin olmanın yollarını bulmaya çalıştılar. Farklı türlerdeki yeni bileşenlerle Vue uygulamalarının nasıl güncelleneceğini gösteren bir kod kalemi girişi vardır. Bu, sayfanın belirli bir bölümünü farklı panel türleri ile güncellemek için gereken mekanizmadır.

Farklı türde paneller ekleyebilme özelliği ve tanımlarını yüklemek için basit bir mekanizma ile nihayet panel arama sayfamıza sahip olabiliriz.

Vue uygulamasının bileşenleri dinamik olarak yerleştirebilmesi için sayfamızda ihtiyacımız olan HTML:

 <template v-for="(panel, index) in panelList"> <component :is="panel" :key="panel.name"></component> </template>

component etiketi bir Vue meta etiketidir. Dinamik bileşenler için referansa bakın. Bu durumda component etiketi için kullanılan özellikler, özel nitelikler is ve anahtardır. is özelliği dinamik bileşenler için mevcuttur. Ve key , yeni çocukların birbirinden farklı kimliklere sahip olmasını sağlar ve Vue'nin ne çizeceğine karar vermesine yardımcı olur.

“Aynı ortak ebeveynin çocukları benzersiz anahtarlara sahip olmalıdır. Yinelenen anahtarlar, oluşturma hatalarına neden olur."

template etiketi, uygulamanın panelList veri alanında sağlanan bileşenler arasında dolaşacaktır.

Böylece, simge uygulaması için uygulama düzeyi Vue tanımından başlayarak, panelList'i veri öğelerine dahil etmek için değişiklikler yapabiliriz. (Şimdi buna panelApp diyelim).

 var panelApp = new Vue({ el: '#PanelApp', data: { iconList: [ // Where is the data? Still on the server. ], panelList: [ ], queryToken : "Thermo Batches" // picked a name for demo }, methods : { goGetPanel: function (pname) { // var url = panelURL(pname); // this is custom to the site. fetch(url).then((response) => { // this is now browser native response.text().then((text) => { var newData = decodeURIComponent(text); eval(pHat); // widgdef = object def, must be assignment pHat = widgdef; var pnameHat = pname + pcount++; pHat.name = pnameHat; // this is needed for the key this.panelList.push(pHat); // now it's there. }).catch( error => { /* handle it */ }); } } });

Panele eklemenin yanı sıra, goGetPanel artık bir veritabanından veya başka bir mağazadan bileşen tanımı almak için gerekli bir formda. Sunucu tarafı, JavaScript kodunu doğru biçimde teslim etme konusunda dikkatli olmalıdır. Sunucudan gelen nesnenin nasıl göründüğüne gelince, onu zaten gördük. Vue.component için parametre olarak kullanılan nesne türüdür.

Arama sonucu olarak bir menü ve kullanıcı bir simgeye tıkladığında sunucudan alınan panelleri koymak için bir yer sağlayan Vue uygulamasının tam gövdesi burada.

 <div> <!-- Recognize the name from the Vue doc --> <div> <h2 itemprop="name">Request MCU Groups</h2> <p itemprop="description">These are groups satistfying this query: {{queryToken}}.</p> <button>Find All</button> <button>Find 5 Point</button> <button>Find 6 Point</button> </div> <!-- Here is a Vue loop for generating a lit --> <div class="entryart"> <button v-for="iconEntry in iconList" @click="goGetPanel(iconEntry.name)" > <div v-html="iconEntry.icon"> </div> </button> </div> <div class="entryart" > <template v-for="(panel, index) in panelList"> <component :is="panel" :key="panel.name" :ref="panel.name" ></component> </template> </div> </div>

Son div , component etiketi artık panel adına bağlı bir ref parametresine sahiptir. ref parametresi, Vue uygulamasının verilerle hangi bileşenin güncelleneceğini belirlemesini sağlar ve bileşenleri ayrı tutar. ref parametreleri, uygulamamızın dinamik olarak yüklenen yeni bileşenlere erişmesine de izin verir.

Panel uygulamasının bir test sürümünde aşağıdaki aralık işleyicisine sahibim:

 setInterval(() => { var refall = panelApp.$refs; // all named children that panels for ( var pname in refall ) { // in an object var pdata = refall[pname][0]; // off Vue translation, but it's there. pdata.temp1 = Math.round(Math.random()*100); // make thermos jump around. pdata.temp2 = Math.round(Math.random()*100); } },2000)

Kod, termometreleri rastgele değiştirerek küçük bir animasyon sağlar. Her panelde iki termometre bulunur ve uygulama, kullanıcının panel eklemeye devam etmesine izin verir. (Son sürümde, bazı paneller atılmalıdır.) panelApp.$refs kullanılarak erişilir, bu alan Vue tarafından component etiketindeki refs bilgileri verilerek oluşturulur.

Yani, rastgele zıplayan termometreler bir anlık görüntüde şöyle görünür:

Termometreleri gösteren bir tür panel (veya bileşen) için animasyonlu paneller koleksiyonu.
Bir tür panel (veya bileşen) için animasyonlu paneller koleksiyonu. (Büyük önizleme)

Paneli IoT Cihazına Bağlama

Bu nedenle, son kod parçası, termometreleri her iki saniyede bir rastgele değerlerle güncelleyen bir setInterval testidir. Ama bizim yapmak istediğimiz gerçek makinelerden gerçek verileri okumak. Bunu yapmak için, bir tür iletişime ihtiyacımız olacak.

Çeşitli yollar var. Ancak bir pub/sub mesaj sistemi olan MQTT'yi kullanalım. SPWA'mız herhangi bir zamanda cihazlardan gelen mesajlara abone olabilir. Bu mesajları aldığında SPWA, her mesajı mesajda tanımlanan cihazla eşlenen panel için uygun veri işleyicisine yönlendirebilir.

Yani, temelde yapmamız gereken setInterval bir yanıt işleyicisi ile değiştirmek. Ve bu bir panel için olacak. Muhtemelen panelleri yüklendikçe işleyicilere eşlemek istiyoruz. Ve doğru eşlemenin sağlandığını görmek web sunucusuna bağlıdır.

Web sunucusu ve SPWA, sayfayı çalışmaya hazır hale getirdikten sonra, web sunucusunun artık sayfa ile cihaz arasındaki mesajlaşmayla ilgilenmesine gerek kalmaz. MQTT protokolü, pub/sub işlemek için bir yönlendirme sunucusu belirtir. Bir dizi MQTT sunucusu yapılmıştır. Bazıları açık kaynak kodludur. Çok popüler olanlardan biri Mosquito ve Node.js üzerine geliştirilmiş birkaç tane var.

Sayfa için işlem basittir. SPWA bir konuya abone olur. Bir konunun iyi bir versiyonu, MAC adresi veya seri numarası gibi bir MCU tanımlayıcısıdır. Veya SPWA tüm sıcaklık okumalarına abone olabilir. Ancak, o zaman sayfanın tüm cihazlardan gelen mesajları filtreleme işini yapması gerekir. MQTT'de yayın, esasen bir yayın veya çok noktaya yayındır.

SPWA'nın MQTT ile nasıl arayüz oluşturacağına bir göz atalım.

SPWA'da MQTT'yi Başlatma

Aralarından seçim yapabileceğiniz birkaç istemci kitaplığı vardır. Örneğin biri, bir MQTT.js. Bir diğeri ise tutulma paho. Daha fazlası var tabii. Eclipse Paho'yu CDN'de depolanmış bir sürümü olduğu için kullanalım. Sayfamıza aşağıdaki satırı eklememiz yeterli.

 <script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js" type="text/javascript"></script>

MQTT istemcisinin mesaj gönderip alabilmesi için önce bir sunucuya bağlanması gerekir. Bu nedenle, bağlantıyı kuran satırların da JavaScript'e dahil edilmesi gerekir. İstemciyi ve bağlantı yönetimi ve mesaj alımı için yanıtları ayarlayan bir MQTTinitialize işlevi ekleyebiliriz.

 var messagesReady = false; var mqttClient = null; function MQTTinitialize() { mqttClient = new Paho.MQTT.Client(MQTTHostname, Number(MQTTPort), "clientId"); mqttClient.onMessageArrived = onMessageArrived; // connect the client mqttClient.connect({ onSuccess: () => { messagesReady = true; } }); // set callback handlers mqttClient.onConnectionLost = (response) => { // messagesReady = false; // if (response.errorCode !== 0) { console.log("onConnectionLost:"+response.errorMessage); } setTimeout(() => { MQTTinitialize() },1000); // try again in a second }; }

Aboneliği Ayarlama

Bağlantı hazır olduğunda, istemci mesaj kanallarına abone olabilir, bunlara mesaj gönderebilir, vb. Panelleri MQTT yollarına bağlamak için gereken işlerin çoğunu sadece birkaç rutin yapabilir.

Panel SPWA için, panel ile konu, MCU tanımlayıcısı arasındaki ilişkiyi kurmak için abonelik anı kullanılabilir.

 function panelSubcription(topic,panel) { gTopicToPanel[topic] = panel; gPanelToTopic[panel] = topic; mqttClient.subscribe(topic); }

Bir MCU'nun kendi konusu hakkında yayın yaptığı göz önüne alındığında, SPWA bir mesaj alacaktır. Burada, Paho mesajı paketten çıkarılmıştır. Ardından mesaj, uygulama mekaniğine iletilir.

 function onMessageArrived(pmessage) { // var topic = pmessage.destinationName; var message = pmessage.payloadString; // var panel = gTopicToPanel[topic]; deliverToPanel(panel,message); }

Şimdi tek yapmamız gereken, daha önce sahip olduğumuz aralık işleyicisine biraz benzer olması gereken deliverToPanel oluşturmak. Ancak, panel açıkça tanımlanmıştır ve yalnızca belirli mesajda gönderilen anahtarlanmış veriler güncellenebilir.

 function deliverToPanel(panel,message) { var refall = panelApp.$refs; // all named children that panels var pdata = refall[panel][0]; // off Vue translation, but it's there. var MCU_updates = JSON.parse(message); for ( var ky in MCU_updates ) { pdata[ky] = MCU_updates[ky] } }

Bu deliverToPanel işlevi, animasyon için herhangi bir sayıda veri noktasıyla herhangi bir panel tanımına izin verecek kadar soyuttur.

Mesaj gönderme

MCU ve SPWA arasındaki uygulama döngüsünü tamamlamak için mesaj gönderecek bir fonksiyon tanımlarız.

 function sendPanelMessage(panel,message) { var topic = gPanelToTopic[panel]; var pmessage = new Paho.MQTT.Message(message); pmessage.destinationName = topic; mqttClient.send(pmessage); }

sendPanelMessage işlevi, mesajı SPWA'nın abone olduğu aynı konu yolunda göndermekten fazlasını yapmaz.

Simge düğmelerini, tek bir MCU kümesi için belirli sayıda panel getirmekten sorumlu yapmayı planladığımızdan, ilgilenmemiz gereken birden fazla panel olacaktır. Ancak, her panelin tek bir MCU'ya karşılık geldiğini aklımızda tutuyoruz, bu nedenle harita ve tersi için iki JavaScript haritası kullanabileceğimiz bire bir eşlememiz var.

Peki, ne zaman mesaj göndeririz? Genellikle panel uygulaması, MCU'nun durumunu değiştirmek istediğinde bir mesaj gönderir.

Görünüm (Vue) Durumunu Cihazlarla Senkronize Etme

Vue ile ilgili harika şeylerden biri, veri modelini alanları düzenleyebilen, düğmelere tıklayabilen, kaydırıcıları kullanabilen vb. kullanıcının etkinliğiyle senkronize tutmanın çok kolay olmasıdır. Düğme ve alan değişikliklerinin olacağından emin olabilirsiniz. bileşenlerin veri alanlarına hemen yansıtılacaktır.

Ancak, değişiklikler gerçekleşir gerçekleşmez MCU'ya gönderilen mesajların gönderilmesini istiyoruz. Bu nedenle, Vue'nun yönetebileceği arayüz olaylarını kullanmaya çalışıyoruz. Böyle bir olaya yanıt vermeye çalışıyoruz, ancak yalnızca Vue veri modeli mevcut değerle hazır olduktan sonra.

Başka bir tür panel oluşturdum, bu oldukça sanatsal görünümlü bir düğme ile (belki Jackson Pollock'tan esinlenmiştir). Ve onu, tıklaması durumu onu içeren panele geri bildiren bir şeye dönüştürmeye başladım. Bu o kadar basit bir süreç değildi.

Beni hayal kırıklığına uğratan şeylerden biri, SVG'yi yönetmedeki bazı tuhaflıkları unutmuş olmamdı. İlk önce stil dizesini CSS stilinin display alanı "Hiçbiri" veya "bir şey" olacak şekilde değiştirmeye çalıştım. Ancak tarayıcı, stiller dizesini hiçbir zaman yeniden yazmadı. Ancak bu zahmetli olduğu için CSS sınıfını değiştirmeyi denedim. Bunun da etkisi olmadı. Ancak, çoğumuzun eski HTML'den hatırladığı (belki de sürüm 1.0) visibility özelliği var, ancak bu SVG'de çok güncel. Ve bu iyi çalışıyor. Tek yapmam gereken, yaymak için button click olayını almaktı.

Vue, ebeveynden çocuğa tek yönde yayılmak için özellikler tasarlamıştır. Bu nedenle, uygulamadaki veya paneldeki verileri değiştirmek için ebeveyne bir change olayı göndermeniz gerekir. Ardından, verileri değiştirebilirsiniz. Düğmeyi kontrol eden veri öğesinin değişmesi, Vue'nun durumu belirtmek için seçtiğimiz SVG öğesinin görünürlüğünü etkileyen özelliği güncellemesine neden olur. İşte bir örnek:

Birden fazla panel türü ve tür başına birden fazla animasyon örneği.
Son olarak, her biri ayrı MCU'lara atanmış örneklere sahip farklı türde panellerden oluşan bir koleksiyon. (Büyük önizleme)

Dalgalı düğme panelinin her örneği bağımsızdır. Yani, bazıları AÇIK ve bazıları KAPALI.

SVG'nin bu pasajı, tuhaf görünen sarı göstergeyi içerir:

 <path :visibility="stateView" d="m -36.544616,12.266886 c 19.953088,17.062165 5.07961,-19.8251069 5.317463,8.531597 0.237853,28.356704 13.440044,-8.847959 -3.230451,10.779678 -16.670496,19.627638 14.254699,-2.017715 -11.652451,3.586456 -25.90715,5.60417 10.847826,19.889979 -8.095928,-1.546575 -18.943754,-21.436555 -1.177383,14.210702 -4.176821,-12.416207 -2.999438,-26.6269084 -17.110198,8.030902 2.14399,-8.927709 19.254188,-16.9586105 -19.075538,-8.0837048 9.448721,-5.4384245 28.52426,2.6452804 -9.707612,-11.6309807 10.245477,5.4311845 z" transform="translate(78.340803,6.1372042)" />

Görünürlük, durum booleanını SVG için bir dizeye eşleyen hesaplanmış bir değişken olan stateView tarafından doldurulur.

İşte panel bileşeni tanım şablonu:

 <script type="text/x-template"> <div> <control-switch :state="bstate" v-on:changed="saveChanges" ></control-switch> <gauge :level="fluidLevel" ></gauge> </div> </script>

Ve bu, alt bileşenleri olarak alt bileşenleriyle birlikte Vue panelinin JavaScript tanımıdır:

 var widgdef = { data: function () { var currentPanel = { // at the top level, values controlling children bstate : true, fluidLevel : Math.round(Math.random()*100) } // return currentPanel }, template: '#mcu-control-panel-template', methods: { saveChanges: function() { // in real life, there is more specificity this.bstate = !this.bstate relayToMCU(this.name,"button",this.bstate) // to be defined } }, components: { 'control-switch' : { // the odd looking button props: ['state'], template: '#control-switch-template', // for demo it is in the page. computed: { // you saw this in the SVG above. stateView : function() { return ( this.state ) ? "visible" : "hidden" } }, methods : { // the button handler is in the SVG template at the top. stateChange : function () { // can send this.$emit('changed'); // tell the parent. See on the template instance } } }, 'gauge' : { // some other nice bit of SVG props: ['level'], template: '#gauge-template' } } }

Böylece, şimdi bir panele gömülü tek bir düğmenin mekanizması ortaya konmuştur. Ve MCU'ya bir şeyin gerçekleştiğini söylemek için bir kanca olmalı. Panel bileşeninin veri durumu güncellendikten hemen sonra çağrılmalıdır. Burada tanımlayalım:

 function relayToMCU(panel,switchName,bstate) { var message = switchName + ':' + bstate // a on element parameter string. sendPanelMessage(panel,message) }

Sadece iki kod satırında donanıma giden yolda bir durum değişikliği var.

Ancak bu oldukça basit bir durum. Herhangi bir anahtar, dünyadaki bir donanım parçasına yapılan bir işlev çağrısı olarak görülebilir. Bu nedenle, dize, anahtar adını ve diğer birkaç veri öğesini içerebilir. Bu nedenle, değişikliği kaydeden bileşen yönteminin, paneldeki tüm veri parçalarını bir araya getirebilmesi ve bunları tek bir komut dizesinde gönderebilmesi için bazı özel işlemlere sahip olması gerekecektir. Komut dizesi bile biraz basittir. MCU oldukça küçükse, komut dizesinin bir koda çevrilmesi gerekebilir. MCU'nun çok fazla yeteneği varsa, komut dizisi aslında bir JSON yapısı veya belki de panelin barındırdığı tüm veriler olabilir.

Bu tartışmada, simge panelindeki düğmeler getirilecek panelin adını içerir. Bu da oldukça basitleştirilebilir. Bu parametrenin bir kurumsal veritabanlarında depolanabilecek herhangi bir panel için geçerli olabileceği mantıklı görünüyor. Ama belki de bir formüldür. Belki de panel ile ilgili bilgiler sunucudan aldığımız panel tanımının etrafına sarılmalıdır. Her durumda, SVG'nin tıklamalara doğru şekilde yanıt vermesini sağlamak gibi belirli baş ağrıları ortadan kalktığında temel bilgiler kolayca genişletilebilir.

Çözüm

Bu tartışma, IoT cihazlarıyla arayüz oluşturabilen Tek Sayfa Web Uygulamasının (SPWA) gerçekleştirilmesine yol açan bazı temel adımları ve kararları ortaya koydu. Artık bir web sunucusundan panellerin nasıl alınacağını ve MCU arayüzüne nasıl dönüştürüleceğini biliyoruz.

Bunu takip edebilecek birkaç başka tartışmayla birlikte bu tartışmanın çok daha fazlası var. Vue ile başlamak, düşünülmesi gereken bir şeydir. Ancak bir de kısaca değindiğimiz MCU hikayesinin tamamı var.

Özellikle, bir iletişim alt katmanı olarak MQTT'yi seçerek, diğer uçtaki IoT cihazlarının bir şekilde MQTT tarafından yönetilebileceğini varsayıyoruz. Ancak bu her zaman böyle olmayabilir. MQTT'nin seri bağlantılara veya Bluetooth'a sahip bir cihaza erişmesi için bazen ağ geçitlerine ihtiyaç duyulur. Veya belki de web sayfasında ihtiyaç duyulan tek şey WebSockets'tir. Yine de, Vue'nun veri durumunu cihazlarla senkronize halde tutarken nasıl veri alıp gönderebileceğini göstermek için bir örnek olarak MQTT'yi kullandık.

Bir kez daha hikayenin sadece bir kısmına sahibiz. Bu sefer senkronizasyon içindir, çünkü sayfanın uyarılarla başa çıkabilmesi ve kritik bir şey olması durumunda kullanıcıyı rahatsız edebilmesi gerekir. Bazen mesajlar kaybolabilir. Bu nedenle, bir teşekkür mekanizmasına sahip olmamız gerekir.

Son olarak, bence Vue, alındıktan sonra verileri güncellemeyi oldukça zarif kılıyor. Ancak, durum değişikliklerini göndermek o kadar basit değil. İşi vanilya JavaScript ile yapılabilecekten çok daha basit hale getirmiyor gibi görünüyor. Ama bir yolu var ve mantıklı.

Belki de tüm paneller için evrensel bir bileşen seti oluşturmak için temiz bir kitaplık oluşturulabilir. Bu tür kütüphanelerin yapılması ve bir veri tabanında saklanmasının unsurlarına kısaca değinilmiştir. Sadece SVG resimleri yapmanın ötesine geçen araçların geliştirilmesi gerekebilir. Her durumda, sonraki adımlar için yapılabilecek pek çok şey vardır.