IoT 및 제조업체를 위한 SVG 웹 페이지 구성 요소(2부)

게시 됨: 2022-03-10
빠른 요약 ↬ IoT 웹 페이지용 인터페이스를 디자인할 때 항상 많은 옵션이 있습니다. 이 기사의 이전 부분에서 Richard Leddy는 IoT의 의미와 Vue.js를 사용하여 IoT 인간-기계 인터페이스 그룹을 호스팅하는 방법에 대해 설명했습니다. 오늘은 지연 로딩 패널과 Vue 상태를 장치와 동기화하는 방법에 대해 자세히 살펴보겠습니다.

따라서 원하는 경우 패널을 로드하여 반응하도록 만든 SVG 아이콘 메뉴를 동적으로 로드하는 방법이 이미 있지만 아이콘은 실제 구성 요소가 아닙니다. 각 아이콘에 대해 SVG를 가져와서 Vue 애플리케이션에 전달하는 간단한 트릭을 사용할 수 있었습니다. 아이콘 목록을 생성하는 것은 간단했고 각 아이콘은 작은 데이터 차이를 제외하고는 유사한 방식으로 반응했습니다. 데이터 차이로 인해 아이콘의 버튼 클릭에 대한 핸들러가 전달할 수 있는 방식으로 패널 이름을 각 아이콘에 바인딩할 수 있었습니다.

패널이 Vue 구성 요소의 형태로 로드되면 패널과 해당 구성 요소, 템플릿, JavaScript 등 모든 것이 로드되어야 합니다. 따라서 패널 로드를 관리하는 작업은 이 토론에서 지금까지 발생한 것보다 더 큽니다.

Vue에서 비동기 로딩을 위한 후크를 제공하는 방법을 살펴보겠습니다. 다음 스니펫은 Vue 가이드에서 가져온 것입니다.

 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) })

가이드에서는 setTimeout 함수가 Vue 구성 요소와 동기화를 사용하는 방법의 예라고 알려줍니다. Vue.component 에 대한 두 번째 매개변수로 객체가 이전에 있던 곳에 이제 팩토리 함수라고 하는 함수가 있습니다. resolve 콜백 내에는 이전에 Vue.component 에 대한 두 번째 매개변수였던 구성요소 정의가 있습니다.

점프 후 더! 아래에서 계속 읽기 ↓

그래서 나는 이 예가 나에게 이해되기 전에 잠시 동안 응시해야 했습니다. 나에게 더 잘 맞는 또 다른 예는 다음과 같습니다.

 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 } );

이 형식을 둘러싸기 위해 보다 일반적인 기능을 만드는 것이 옳은 일인 것 같습니다.

 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 } ); }

따라서 일반적으로 구성 요소를 로드하려면 다음과 같은 줄이 필요합니다.

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

이제 로드되는 JSON은 무엇입니까? 구성 요소에 대한 모든 것을 포함할 수 있습니다. 이 경우 패널 구성 요소로 온도계, 기계 스위치, 슬라이더, 게이지 등이 포함될 수 있습니다. 웹 페이지에 구성 요소 부분을 유지하는 것이 더 좋아 보이지만 이전에 만든 '열 패널'과 유사하게 구성된 다른 패널에 대해 더 긴 예에 있는 하위 구성 요소 필드를 사용하는 것이 실제로 더 잘 작동할 수 있습니다. JSON에는 완전한 패널 구조가 포함됩니다.

그러나 독자가 transformJSONToJSObject 에 대한 함수 호출의 포함을 알아차린다면 그는 JSON이 전송을 더 쉽게 만들고 서버가 정의를 더 쉽게 처리할 수 있도록 어떤 방식으로든 코딩될 수 있다는 것을 이해할 것입니다. 결국 정의에는 완전한 SVG 템플릿, 함수 정의 및 기타 JavaScript 표현식이 포함됩니다. 또한 일부 정보는 단순히 부기 또는 유효성 검사에 도움이 될 수 있기 때문에 JSON 개체에는 패널 정의 이상의 것이 포함될 수 있습니다. 따라서 수령 시 개체에 대한 처리가 있을 것으로 예상할 수 있습니다.

인코딩의 경우 서버에서 들어오는 데이터는 여러 가지 방법으로 인코딩될 수 있습니다. 아마도 그것은 단순히 URL로 인코딩될 것입니다. 또는 더 안전하게 암호화될 수 있습니다. 이 토론에서는 URL 인코딩만 사용할 수 있습니다.

Vue 애플리케이션을 만드는 데 사용할 수 있는 일부 도구는 의심할 여지 없이 JSON 변환을 처리합니다. 그러나 이 논의에서는 지금까지 명령줄 도구의 사용을 피했습니다. 이 누락은 CDN을 참조하기 위해 하나의 스크립트 태그만 사용하여 최소한의 리소스로 Vue를 사용했기 때문에 그렇게 나쁘지 않습니다. 그러나 특히 프로젝트 구성을 위한 명령줄 도구를 살펴보는 것이 좋습니다.

JSON이 페이지에 도착하면 구성 요소가 하위 구성 요소와 완전히 어셈블되므로 부품을 가져오기 위해 더 이상 작업을 수행할 필요가 없습니다. 우리는 이 논의의 나머지 부분에서 모든 구성 요소가 완전히 정의될 것이라고 가정할 수 있습니다. 그러나 완전한 구성 요소 계층을 조립하려면 어느 시점에서 명령줄 도구가 필요합니다.

SVG 편집 프로세스에도 약간의 작업이 필요합니다. SVG 편집 프로세스를 통해 디자이너는 패널과 패널의 모든 구성 요소를 그릴 수 있습니다. 그러나 각 하위 구성 요소는 식별되거나 그룹으로 호출되거나 자리 표시자가 제공되어야 합니다. 드로잉을 사용하는 모든 접근 방식은 Vue 구성 요소 태그가 그룹이나 그래픽 요소를 대체할 수 있도록 SVG를 약간 처리해야 합니다. 이런 식으로 모든 아티스트 렌더링이 템플릿이 될 수 있습니다. 그리고 그려진 하위 구성 요소는 Vue 하위 구성 요소의 템플릿으로 분해되어야 합니다.

이러한 종류의 간결함은 대부분의 JavaScript 프레임워크의 워크플로와 반대입니다. 프레임워크는 페이지를 조합하는 것입니다. 그러나 편집이나 드로잉은 예술가가 이미 조립한 결과입니다. 실제로 편집 결과는 프레임워크 구성 요소 정의에 직접 해당하는 텍스트 파일을 제공하지 않습니다.

편집 과정에 대한 자세한 내용은 다른 토론에서 고려할 수 있습니다. 그것에는 많은 것이 있습니다. 그러나 현재로서는 계층 구성 요소를 로드하고 활성화하는 데 필요한 도구가 있습니다.

게으른 응용 프로그램

IoT 패널 구성을 위해 이미 검색에 응답하는 선택 막대가 있습니다. 그리고 필요할 때 구성 요소를 로드하는 방법이 있습니다. 우리는 이 부분들을 연결하기만 하면 됩니다. 그리고 마지막으로 패널이 표시되고 표시될 때 작동을 시작하는지 확인해야 합니다.

위의 비동기 코드에 의해 수행된 패널의 지연 로딩은 아이디어의 스케치를 제공합니다. 그러나 고맙게도 일부 사람들은 모든 종류의 구성 요소를 로드할 수 있는지 확인하는 방법을 찾기 위해 실험했습니다. 다양한 유형의 새 구성 요소로 Vue 앱을 업데이트하는 방법을 보여주는 하나의 codepen 항목이 있습니다. 페이지의 지정된 부분을 다른 유형의 패널로 업데이트하는 데 필요한 메커니즘입니다.

다양한 종류의 패널을 추가하고 해당 정의를 로드하는 간단한 메커니즘을 통해 마침내 패널 검색 페이지를 만들 수 있습니다.

Vue 앱이 동적으로 구성 요소를 배치할 수 있도록 페이지에 필요한 HTML은 다음과 같습니다.

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

component 태그는 Vue 메타 태그입니다. 동적 구성 요소에 대한 참조를 참조하세요. 이 경우 component 태그에 사용되는 속성, 특수 속성은 is 및 key입니다. is 속성은 동적 구성 요소에 대해 존재합니다. 그리고 key 는 새로운 아이들이 서로 다른 신원을 갖도록 하고 Vue가 무엇을 그릴지 결정하는 데 도움이 됩니다.

“같은 공통 부모의 자식은 고유한 키를 가져야 합니다. 키가 중복되면 렌더링 오류가 발생합니다."

template 태그는 애플리케이션의 panelList 데이터 필드에 제공된 구성 요소를 반복합니다.

따라서 아이콘 앱에 대한 애플리케이션 수준 Vue 정의부터 시작하여 데이터 요소에 panelList를 포함하도록 변경할 수 있습니다. (이제 이것을 panelApp이라고 부르겠습니다).

 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 */ }); } } });

패널에 추가하는 것 외에도 goGetPanel 은 이제 데이터베이스 또는 다른 저장소에서 구성 요소 정의를 가져오는 데 필요한 형식입니다. 서버 측에서는 JavaScript 코드를 올바른 형식으로 전달하는 데 주의해야 합니다. 객체가 서버에서 오는 것처럼 보이는 것에 관해서는 이미 보았습니다. Vue.component 에 대한 매개변수로 사용되는 객체의 종류입니다.

다음은 검색 결과로 메뉴를 제공하고 사용자가 아이콘을 클릭할 때 서버에서 가져온 패널을 넣을 위치를 제공하는 Vue 앱의 전체 본문입니다.

 <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>

마지막 div 에서 component 태그에는 이제 패널 이름에 바인딩된 ref 매개변수가 있습니다. ref 매개변수를 사용하면 Vue 앱이 데이터로 업데이트할 구성 요소를 식별하고 구성 요소를 별도로 유지할 수 있습니다. ref 매개변수를 사용하면 애플리케이션이 동적으로 로드된 새 구성 요소에 액세스할 수도 있습니다.

패널 앱의 한 테스트 버전에는 다음 간격 처리기가 있습니다.

 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)

이 코드는 온도계를 무작위로 변경하는 약간의 애니메이션을 제공합니다. 각 패널에는 두 개의 온도계가 있으며 앱을 통해 사용자는 패널을 계속 추가할 수 있습니다. (최종 버전에서는 일부 패널을 버려야 합니다.) 참조는 panelApp.$refs refs 사용하여 액세스되고 있습니다. 이 참조는 component 태그의 참조 정보에 따라 Vue가 생성하는 필드입니다.

따라서 무작위로 점프하는 온도계는 한 스냅샷에서 다음과 같이 보입니다.

온도계를 보여주는 한 유형의 패널(또는 구성요소)에 대한 애니메이션 패널 모음입니다.
한 가지 유형의 패널(또는 구성 요소)에 대한 애니메이션 패널 모음입니다. (큰 미리보기)

패널을 IoT 장치에 연결

따라서 코드의 마지막 부분은 2초마다 임의의 값으로 온도계를 업데이트하는 setInterval 테스트입니다. 그러나 우리가 원하는 것은 실제 기계에서 실제 데이터를 읽는 것입니다. 그러기 위해서는 어떤 형태의 의사소통이 필요합니다.

다양한 방법이 있습니다. 하지만 pub/sub 메시지 시스템인 MQTT를 사용해보자. SPWA는 언제든지 장치의 메시지를 구독할 수 있습니다. 이러한 메시지를 받으면 SPWA는 각 메시지를 메시지에서 식별된 장치에 매핑된 패널의 적절한 Data Handler로 보낼 수 있습니다.

따라서 기본적으로 우리가 해야 할 일은 setInterval 을 응답 핸들러로 바꾸는 것입니다. 그리고 그것은 하나의 패널에 대한 것입니다. 패널이 로드될 때 핸들러에 패널을 매핑하고 싶을 것입니다. 그리고 올바른 매핑이 전달되는지 확인하는 것은 웹 서버에 달려 있습니다.

웹 서버와 SPWA가 페이지를 작동할 준비가 되면 웹 서버는 더 이상 페이지와 장치 간의 메시징을 처리할 필요가 없습니다. MQTT 프로토콜은 게시/구독을 처리할 라우팅 서버를 지정합니다. 많은 MQTT 서버가 만들어졌습니다. 그들 중 일부는 오픈 소스입니다. 매우 인기 있는 것 중 하나는 Mosquito 이며 Node.js 위에 개발된 몇 가지가 있습니다.

페이지의 프로세스는 간단합니다. SPWA는 주제를 구독합니다. 주제의 좋은 버전 중 하나는 MAC 주소 또는 일련 번호와 같은 MCU의 식별자입니다. 또는 SPWA가 모든 온도 판독값을 구독할 수 있습니다. 그러나 페이지는 모든 장치에서 메시지를 필터링하는 작업을 수행해야 합니다. MQTT의 발행은 본질적으로 브로드캐스트 또는 멀티캐스트입니다.

SPWA가 MQTT와 인터페이스하는 방법을 살펴보겠습니다.

SPWA에서 MQTT 초기화

선택할 수 있는 여러 클라이언트 라이브러리가 있습니다. 예를 들어 하나는 MQTT.js입니다. 다른 하나는 이클립스 파호입니다. 물론 더 있습니다. 이클립스 Paho에는 CDN 저장 버전이 있으므로 사용해보자. 페이지에 다음 줄을 추가하기만 하면 됩니다.

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

MQTT 클라이언트는 메시지를 보내고 받기 전에 서버에 연결해야 합니다. 따라서 연결을 설정하는 행도 JavaScript에 포함되어야 합니다. 클라이언트와 연결 관리 및 메시지 수신을 위한 응답을 설정하는 MQTTinitialize 함수를 추가할 수 있습니다.

 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 }; }

구독 설정

연결이 준비되면 클라이언트는 메시지 채널을 구독하고 채널에 메시지를 보내는 등의 작업을 수행할 수 있습니다. 몇 가지 루틴으로 패널을 MQTT 경로와 연결하는 데 필요한 대부분의 작업을 수행할 수 있습니다.

패널 SPWA의 경우 구독 시점을 사용하여 패널과 주제인 MCU 식별자 간의 연결을 설정할 수 있습니다.

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

MCU가 해당 주제에 대해 게시하는 경우 SPWA는 메시지를 수신합니다. 여기에서 Paho 메시지의 압축을 풉니다. 그런 다음 메시지가 애플리케이션 메커니즘으로 전달됩니다.

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

따라서 이제 우리가 해야 할 일은 이전에 사용했던 간격 처리기와 다소 비슷해야 하는 deliverToPanel 을 만드는 것입니다. 단, 패널이 명확하게 식별되어 특정 메시지에서 전송된 키 데이터만 업데이트될 수 있습니다.

 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] } }

deliverToPanel 함수는 애니메이션을 위한 데이터 포인트 수에 관계없이 패널 정의를 허용할 만큼 충분히 추상적입니다.

메시지 보내기

MCU와 SPWA 간의 애플리케이션 루프를 완료하기 위해 메시지를 보내는 함수를 정의합니다.

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

sendPanelMessage 함수는 SPWA가 구독하는 동일한 주제 경로로 메시지를 보내는 것 이상을 수행하지 않습니다.

단일 MCU 클러스터에 대해 몇 개의 패널을 가져오는 역할을 하는 아이콘 버튼을 만들 계획이므로 처리해야 할 패널이 두 개 이상 있을 것입니다. 그러나 우리는 각 패널이 단일 MCU에 해당한다는 점을 염두에 두고 있으므로 맵과 역에 대해 두 개의 JavaScript 맵을 사용할 수 있는 일대일 매핑이 있습니다.

그래서 언제 메시지를 보내나요? 일반적으로 패널 응용 프로그램은 MCU의 상태를 변경하려고 할 때 메시지를 보냅니다.

장치와 동기화된 보기(Vue) 상태 유지

Vue의 가장 좋은 점 중 하나는 데이터 모델을 사용자의 활동과 동기화하기가 매우 쉽다는 것입니다. 사용자는 필드를 편집하고, 버튼을 클릭하고, 슬라이더를 사용하는 등의 작업을 할 수 있습니다. 구성 요소의 데이터 필드에 즉시 반영됩니다.

그러나 변경 사항이 발생하는 즉시 MCU에 메시지를 보내도록 변경 사항을 원합니다. 그래서 우리는 Vue가 관리할 수 있는 인터페이스 이벤트를 사용하려고 합니다. 우리는 이러한 이벤트에 응답하려고 하지만 Vue 데이터 모델이 현재 값으로 준비된 후에만 가능합니다.

나는 또 다른 종류의 패널을 만들었는데, 이것은 상당히 예술적으로 보이는 버튼이 있는 것입니다(아마도 잭슨 폴록에서 영감을 받은 것 같습니다). 그리고 클릭 시 해당 패널이 포함된 패널에 상태를 보고하는 것으로 전환하려고 했습니다. 그렇게 간단한 과정은 아니었습니다.

나를 실망시킨 한 가지는 SVG 관리에서 몇 가지 이상한 점을 잊어 버렸다는 것입니다. 먼저 CSS 스타일의 display 필드가 "None" 또는 "something"이 되도록 스타일 문자열을 변경하려고 했습니다. 그러나 브라우저는 스타일 문자열을 다시 작성하지 않았습니다. 하지만 그게 번거로워서 CSS 클래스를 변경해 보았습니다. 그것도 효과가 없었다. 그러나 visibility 속성은 우리 대부분이 오래된 HTML(버전 1.0)에서 기억하지만 SVG에서는 매우 최신 상태입니다. 그리고 잘 작동합니다. 버튼 클릭 이벤트가 전파되도록 하기만 하면 됩니다.

Vue는 부모에서 자식으로 한 방향으로 전파되는 속성을 설계했습니다. 따라서 애플리케이션이나 패널에서 데이터를 변경하려면 부모에게 변경 이벤트를 보내야 합니다. 그런 다음 데이터를 변경할 수 있습니다. 버튼을 제어하는 ​​데이터 요소의 변경으로 인해 Vue는 상태를 나타내기 위해 선택한 SVG 요소의 가시성에 영향을 미치는 속성을 업데이트합니다. 다음은 예입니다.

하나 이상의 패널 유형과 유형당 둘 이상의 애니메이션 인스턴스.
마지막으로 개별 MCU에 할당된 인스턴스가 있는 서로 다른 유형의 패널 모음입니다. (큰 미리보기)

구불구불한 버튼 패널의 각 인스턴스는 독립적입니다. 따라서 일부는 ON이고 일부는 OFF입니다.

이 SVG 스니펫에는 이상하게 보이는 노란색 표시기가 포함되어 있습니다.

 <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)" />

가시성은 상태 부울을 SVG용 문자열에 매핑하는 계산된 변수인 stateView 에 의해 채워집니다.

다음은 패널 구성요소 정의 템플릿입니다.

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

그리고 이것은 하위 구성 요소로 자식이 있는 Vue 패널의 JavaScript 정의입니다.

 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' } } }

이제 패널에 포함된 단일 버튼에 대한 메커니즘이 배치되었습니다. 그리고 MCU에 무언가가 발생했음을 알리는 후크가 있어야 합니다. 패널 구성 요소의 데이터 상태가 업데이트된 직후에 호출되어야 합니다. 여기에서 정의해 보겠습니다.

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

단 두 줄의 코드로 하드웨어에 대한 상태 변경이 있습니다.

그러나 이것은 상당히 간단한 경우입니다. 모든 스위치는 세계에 있는 하드웨어에 대한 함수 호출로 볼 수 있습니다. 따라서 문자열에는 스위치 이름과 기타 여러 데이터 요소가 포함될 수 있습니다. 따라서 변경 사항을 등록하는 구성 요소 메서드에는 패널의 모든 데이터 세트를 수집하고 하나의 명령 문자열로 보낼 수 있도록 일부 사용자 지정 처리가 있어야 합니다. 명령 문자열조차도 약간 간단합니다. MCU가 아주 작은 경우 명령 문자열을 코드로 변환해야 할 수 있습니다. MCU에 많은 기능이 있는 경우 명령 문자열은 실제로 JSON 구조이거나 패널이 호스팅하는 모든 데이터일 수 있습니다.

이 토론에서 아이콘 패널의 버튼에는 가져올 패널의 이름이 포함되어 있습니다. 이는 또한 상당히 단순화될 수 있습니다. 이 매개변수는 기업 데이터베이스에 저장될 수 있는 모든 패널을 나타낼 수 있습니다. 그러나 그것은 아마도 어떤 공식일 것입니다. 아마도 패널에 대한 정보는 서버에서 수신하는 패널 정의를 둘러싸고 있어야 합니다. 어쨌든 SVG가 클릭에 제대로 응답하도록 하는 것과 같은 특정 골칫거리가 해결되면 기본 사항을 쉽게 확장할 수 있습니다.

결론

이 토론에서는 IoT 장치와 인터페이스할 수 있는 SPWA(단일 페이지 웹 앱)의 실현으로 이어지는 몇 가지 기본 단계와 결정을 제시했습니다. 이제 웹 서버에서 패널을 가져와 MCU 인터페이스로 바꾸는 방법을 알게 되었습니다.

이 논의에 더 많은 것이 있으며 뒤따를 수 있는 몇 가지 다른 논의가 있습니다. Vue로 시작하는 것은 한 가지 생각해볼 문제입니다. 그러나 그 다음에는 전체 MCU 이야기가 있습니다. 우리는 이에 대해 간략하게만 다루었습니다.

특히, MQTT를 통신 기판으로 선택하여 다른 쪽 끝에 있는 IoT 장치가 어떻게든 MQTT에 의해 지배될 수 있다고 가정합니다. 그러나 항상 그런 것은 아닙니다. MQTT가 직렬 링크 또는 Bluetooth가 있는 장치에 액세스하려면 게이트웨이가 필요한 경우가 있습니다. 또는 웹 페이지에서 필요로 하는 모든 것이 WebSocket일 수도 있습니다. 그럼에도 불구하고 Vue가 장치와 데이터 상태를 동기화하면서 데이터를 수신하고 전송할 수 있는 방법을 보여주기 위해 MQTT를 예로 사용했습니다.

다시 한 번 우리는 이야기의 일부만 가지고 있습니다. 페이지가 경고를 처리할 수 있어야 하고 중요한 일이 발생하면 사용자를 귀찮게 할 수 있어야 하기 때문에 이번에는 동기화를 위한 것입니다. 때때로 메시지가 손실될 수 있습니다. 따라서 승인 메커니즘이 있어야 합니다.

마지막으로 Vue는 수신 시 데이터 업데이트를 매우 우아하게 만든다고 생각합니다. 그러나 상태 변경을 보내는 것은 그렇게 간단하지 않습니다. 이것은 바닐라 자바스크립트로 할 수 있는 것보다 훨씬 간단하게 작업을 만드는 것 같지 않습니다. 그러나 방법이 있고 의미가 있습니다.

모든 패널에 대한 보편적인 구성 요소 집합을 만들기 위해 깨끗한 라이브러리를 구축할 수 있습니다. 이러한 라이브러리를 만들고 데이터베이스에 저장하는 요소에 대해 간략하게 언급했습니다. SVG 사진을 만드는 것 이상의 도구를 개발해야 할 수도 있습니다. 어쨌든 다음 단계를 위해 수행할 수 있는 작업이 많이 있을 수 있습니다.