เชื่อมต่อ FlowEngine เข้ากับ Platform

NEXPIE ได้ทำการนำ FlowEngine เข้ามาใช้งานเพื่อให้ผู้ใช้งานสามารถสื่อสารและควบคุมอุปกรณ์ได้ผ่านหน้าต่างโปรแกรม FlowEngine โดยการตั้งค่าให้มีการรับค่าข้อมูลจากอุปกรณ์ที่สร้างเอาไว้ในหน้า https://portal.nexiiot.io ซึ่งการเชื่อมต่ออุปกรณ์เข้ามาใช้งานในหน้า FlowEngine นั้นสามารถทำได้ 2 วิธี ได้แก่ การเชื่อมต่ออุปกรณ์เข้ากับแพลตฟอร์ม NETPIE/NEXPIE/NEXIIOT และการเชื่อมต่ออุปกรณ์ผ่าน MQTT Broker โดยทั้ง 2 วิธีต่างก็นำโหนดที่อยู่ในหมวดหมู่ ‘Device’ มาใช้งาน

การสร้างอุปกรณ์

ภายในหน้าต่าง FlowEngine ผู้ใช้งานสามารถสร้างอุปกรณ์เสมือนขึ้นมาเพื่อใช้ในการรับและส่งค่าข้อมูลภายในโฟลว์ได้ โดยใช้หลักการเดียวกันกับการเชื่อมต่อกับอุปกรณ์ที่มีอยู่จริง ซึ่งผู้ใช้งานจำเป็นต้องใช้ค่า key จากอุปกรณ์ที่ถูกสร้างไว้ในหน้า https://portal.nexiiot.io มาใส่ลงไปในโหนดที่ผู้ใช้งานเลือกภายในโฟลว์ ซึ่งผู้ใช้งานสามารถสร้างอุปกรณ์ใหม่ขึ้นมาได้ 2 วิธี

MQTT

_images/node_mqtt1.png

‘MQTT’ คือ โหนดที่จะช่วยให้ผู้ใช้งานสามารถสร้างอุปกรณ์ใหม่ในโฟลว์ได้โดยใช้การเชื่อมต่อในลักษณะของ MQTT ซึ่งถูกออกแบบมาให้อุปกรณ์สามารถสื่อสารและเชื่อมต่อระหว่างกันได้โดยมีคนกลาง (Broker) ที่ทำหน้าที่รับข้อมูลจากอุปกรณ์หนึ่ง เพื่อส่งออกไปให้ยังอีกอุปกรณ์ที่อยู่ภายในหัวข้อการสนทนาเดียวกันได้อย่าง Real-time ผู้ใช้งานต้องนำค่า Client ID, Token, และ Secret จากอุปกรณ์ที่ถูกสร้างเอาไว้ภายใน https://portal.nexiiot.io มากรอกลงไปในโหนดนี้ โดยให้ใช้ Client ID แทนค่า Client ID, ใช้ Token แทนค่า Username, และใช้ Secret แทนค่า Password ซึ่งการใช้งานโหนดนี้นั้น ผู้ใช้งานจำเป็นต้องกำหนดตำแหน่งของ Host ที่ต้องการให้โหนดเชื่อมต่อด้วยตัวเอง ดังในรูปด้านล่างจะเป็นการเชื่อมต่อกับ NEXPIE ผ่านตำแหน่งของ Host ที่ mqtt://mqtt.nexiiot.io:1883

_images/node_mqtt2.png

Device

_images/node_device1.png

เช่นเดียวกับ MQTT โหนด ‘Device’ อนุญาตให้ผู้ใช้งานสร้างอุปกรณ์เสมือนใหม่ขึ้นมาในโฟลว์ได้ ซึ่งค่า key ที่นำมาใส่ลงไปในโหนดนี้นั้นคือค่า Client ID และ Token จากอุปกรณ์ที่ถูกสร้างเอาไว้ภายใน https://portal.nexiiot.io ซึ่งผู้ใช้งานต้องนำค่าเหล่านี้มากรอกลงไปในโหนดนี้ โดยให้ใช้ Client ID แทนค่า Device ID และใช้ Token แทนค่า Device Token จากนั้นให้ผู้ใช้งานกำหนดว่าค่าของอุปกรณ์นั้น ผู้ใช้งานได้มาจากอุปกรณ์ที่สร้างไว้ภายใน NETPIE หรือ NEXPIE หรือผู้ใช้งานสามารถกำหนดค่า MQTT Channel ที่นำมาใช้งานได้ด้วยตัวเอง

_images/node_device2.png

สถานะการเชื่อมต่อ

หากอุปกรณ์ที่สร้างเอาไว้สามารถเชื่อมต่อได้สำเร็จ โหนด ‘Device’ และ ‘MQTT’ จะขึ้นสถานะ ‘Connected’ อยู่ด้านล่างของโหนดนั้นพร้อมสัญญาณสีเขียว เช่นเดียวกับอุปกรณ์ที่จะขึ้นสถานะ ‘Online’ พร้อมสัญญาณไฟสีเขียวในหน้า https://portal.nexiiot.io

_images/node_status.png

ข้อจำกัดในการสร้างอุปกรณ์ใหม่

อย่างไรก็ดี ในการสร้างอุปกรณ์ขึ้นมาใหม่นั้น ผู้ใช้งานควรระวังไม่สร้างอุปกรณ์ที่ใช้ค่า key เดียวกันมากกว่าหนึ่งตัว ไม่ว่าอุปกรณ์นั้นจะเป็นอุปกรณ์เสมือนที่ถูกสร้างขึ้นในโฟลว์หรือเป็นอุปกรณ์ที่มีอยู่จริงก็ตาม ทั้งนี้เพื่อป้องกันไม่ให้เกิดปัญหาในการเชื่อมต่อของอุปกรณ์ต่าง ๆ ที่เมื่อต้องทำการพร้อมกันทั้งสองต่อ ระบบจะทำการผลักหนึ่งในอุปกรณ์ออกจากการเชื่อมต่อทันทีเพื่อให้มีอุปกรณ์เพียงตัวเดียวที่เชื่อมต่อกับแพลตฟอร์มโดยใช้ค่า key นั้น ซึ่งอาจจะก่อให้เกิดปัญหาถึงข้อมูลจากอุปกรณ์ที่ถูกส่งไปยังแพลตฟอร์มมีความผิดเพี้ยนไปได้

_images/limit_createdevice_new.png

อีกกรณีหนึ่งคือ หากอุปกรณ์ใดอุปกรณ์หนึ่งของผู้ใช้งานถูกเจาะระบบเข้ามาจนค้นพบค่า key ของอุปกรณ์นั้น อาจส่งผลให้ทุกอุปกรณ์ที่ใช้ key ถูกขโมยข้อมูลไปอย่างง่ายดายจากผู้ไม่หวังดีที่พึงประสงค์จะเจาะระบบเข้ามาดึงข้อมูลเหล่านี้ไปได้อีกด้วย เพราะฉะนั้นแล้ว หากผู้ใช้งานจำเป็นต้องเชื่อมต่อกับอุปกรณ์ที่ถูกนำ key ของเขาไปใช้ในพื้นที่อื่นอยู่แล้ว ผู้ใช้งานอาจใช้โหนด ‘Shadow’ หรือ ‘Messenger’ ในการเข้าถึงอุปกรณ์ต่าง ๆ เหล่านั้นแทนได้

เข้าถึงข้อมูลจากอุปกรณ์ที่มีอยู่

โดยปกติแล้ว ค่า key ของอุปกรณ์ที่ผู้ใช้งานสร้างเอาไว้ใน https://portal.nexiiot.io นั้นควรใช้ควบคู่กับอุปกรณ์เพียงตัวเดียวเท่านั้นเพื่อป้องกันปัญหาของการเชื่อมต่อระหว่างอุปกรณ์หลาย ๆ ชิ้นพร้อม ๆ กัน การเข้าถึงอุปกรณ์ที่ผู้ใช้งานเคยสร้างเอาไว้แล้วนั้นจึงไม่ควรเป็นการนำค่า key ของอุปกรณ์นั้นมาใส่ในโหนด ‘Device’ หรือ ‘MQTT’ ตรง ๆ เพื่อรับหรือส่งข้อมูลให้กับอุปกรณ์นั้น ในทางกลับกัน ผู้ใช้งานสามารถใช้โหนด ‘Shadow’ เพื่อรับและส่งข้อมูลให้กับอุปกรณ์ของผู้ใช้งาน และ ‘Messenger’ เพื่อรับและส่งข้อความของอุปกรณ์นั้นแทนได้ ซึ่งจะช่วยให้ผู้ใช้งานยังคงสามารถมีปฏิสัมพันธ์กับโหนดเดิมได้โดยไม่ก่อให้เกิดปัญหาการเชื่อมต่อในภายหลัง

Shadow

_images/node_shadow1.png

‘Shadow’ คือ โหนดที่อนุญาตให้ผู้ใช้งานสามารถดึงข้อมูล Shadow จากอุปกรณ์หรือนำค่า Shadow ใหม่ที่ถูกสร้างขึ้นมาภายในโฟลว์ส่งไปให้ยังอุปกรณ์ที่มีอยู่แล้วได้

_images/node_shadow2.png

Messenger

_images/node_messenger1.png

‘Messenger’ คือ โหนดที่รับข้อความผ่าน topic คำว่า @msg จะเป็นการดักฟังข้อความโดยใช้ DeviceID และ Token ของ Device ที่ต้องการได้

_images/node_messenger2.png

Feed

_images/node_feed1.png

‘Feed’ คือ โหนดที่รับข้อมูลจาก Timeseries Database ที่เป็นแบบกราฟข้อมูลโดยใช้ DeviceID และ Token ของ Device ที่ต้องการและสามารถกำหนดช่วงของข้อมูลที่จะรับได้ เช่น ดูค่าข้อมูลย้อนหลังในช่วงนาทีที่ 0-5 ได้

_images/node_feed2.png

การส่งข้อความระหว่างอุปกรณ์

อุปกรณ์แต่ละตัวจะส่งข้อความถึงกันและกันโดยยึดหลักการส่งข้อความในลักษณะของ MQTT ซึ่งจะเป็นการกระจายข้อความ (Publish) และติดตามข้อความ (Subscribe) ที่ถูกส่งไปยังหัวข้อต่าง ๆ (Topic) ที่ถูกกำหนดขึ้น โดยผู้รับสารที่ติดตามหัวข้อเดียวกันกับหัวข้อที่ผู้กระจายข้อความส่งมาเท่านั้นที่จะได้รับค่าข้อความ หลักการนี้คล้ายคลึงกับการส่งข้อความภายในกลุ่มสนทนาในแอพลิเคชั่นต่าง ๆ โดยหากเมื่อผู้ส่งสารส่งข้อความไปในกลุ่มการสนทนาใด จะมีเพียงผู้ที่อยู่ภายในกลุ่มสนทนานั้นเท่านั้นที่ได้รับข้อความดังกล่าว

_images/send_message_device1.png

ในการรับส่งข้อความด้วยหลักการนี้นั้นจะใช้หัวข้อ (Topic) แทนชื่อของกลุ่มการสนทนา ซึ่งภายในหัวข้อจะต้องเริ่มต้นด้วย ‘@msg’ ตามด้วยโครงสร้างของชื่อหัวข้อที่ต้องการ ประกอบด้วยคำต่าง ๆ ที่ถูกแยกด้วย ‘/’ ยกตัวอย่างเช่น ‘@msg/home/temp’ เป็นต้น อย่างไรก็ตาม หากผู้ใช้งานต้องการส่งข้อความไปให้ยังอุปกรณ์อื่น ๆ จำนวนมากที่ทำการ subscribe อยู่ในหัวข้อที่แตกต่างกัน ผู้ใช้งานสามารถนำ Wildcard มาช่วยในการเพิ่มความสะดวกสบายในการรับและส่งข้อความได้ โดยสามารถใช้ ‘#’ เพื่อใช้แทนค่าคำทุกคำที่อยู่หลัง ‘/’ และใช้ ‘+’ เพื่อแทนค่าคำหนึ่งคำที่อยู่ระหว่าง ‘/’ โดยผู้ใช้งานสามารถใช้ค่าทั้งสองค่าร่วมกันได้ แต่การใช้ ‘#’ จำเป็นต้องวางไว้หลังสุดเสมอ เช่น ‘/+/+/#’ เป็นต้น แต่ไม่สามารถใช้ ‘/#/+’ ได้

_images/send_message_device2.png

การส่งข้อความจากโฟลว์

หากผู้ใช้งานต้องการส่งข้อความจากอุปกรณ์ที่อยู่ภายในโฟลว์ไปยังอุปกรณ์อื่น ๆ ผู้ใช้งานสามารถทำได้โดยการนำโหนด ‘Publish msg’ ที่อยู่ภายในหมวดหมู่ ‘Command’ ลงมาใช้งาน ก่อนอื่น ก่อนการที่อุปกรณ์จะสามารถคุยกันและส่งข้อความหากันได้ อุปกรณ์แต่ละตัวนั้นจะต้องอยู่ภายในกลุ่มการสื่อสารเดียวกันเสียก่อน ซึ่งวิธีการทำให้อุปกรณ์แต่ละตัวอยู่ในกลุ่มการสื่อสารเดียวกันนั้น ผู้ใช้งานต้องไปที่หน้า https://portal.nexiiot.io แล้วทำการสร้างกลุ่มที่ต้องการให้อุปกรณ์เหล่านี้ไปอยู่รวมกันขึ้นมา โดยการคลิกที่ปุ่ม ‘⊕ Create’ ภายในหน้า ‘Device Groups’ เพื่อทำการสร้างกลุ่มใหม่ขึ้น

_images/send_message_flow1.png

หรือหากในกรณีที่มีกลุ่มที่ถูกสร้างไว้อยู่แล้ว ให้ผู้ใช้งานทำการรวมกลุ่มของอุปกรณ์เหล่านี้เข้าด้วยกัน โดยการคลิกเลือกอุปกรณ์ที่ต้องการรวมไว้ให้อยู่ในกลุ่มเดียวกันจาก checkbox ของอุปกรณ์นั้นภายในหน้า ‘Device Lists’ แล้วทำการคลิกที่ปุ่ม ‘☩ Move’ เพื่อให้ปรากฏรายชื่อของกลุ่มที่ผู้ใช้งานเคยสร้างเอาไว้ภายใน portal ขึ้นมา จากนั้นทำการคลิกเลือกกลุ่มที่ต้องการให้อุปกรณ์นี้ไปอยู่ ซึ่งเมื่อทำเช่นนี้เรียบร้อยแล้ว อุปกรณ์นั้นจะปรากฏชื่อของกลุ่มขึ้นมาบนแถบรายละเอียดของอุปกรณ์นั้นในหน้า ‘Device Lists’

_images/send_message_flow2.png

เงื่อนไขหลัก ๆ ของการรวมกลุ่มอุปกรณ์เข้าด้วยกันคือ อุปกรณ์แต่ละชิ้นสามารถถูกบรรจุอยู่ได้เพียงในกลุ่มเดียวกันเท่านั้นอุปกรณ์แต่ละชิ้นสามารถบรรจุอยู่ในกลุ่มได้เพียงกลุ่มเดียว และจะมีเพียงอุปกรณ์ที่อยู่ในกลุ่มเดียวกันเท่านั้นที่จะสามารถส่งข้อความเพื่อคุยกันได้ เมื่อทำการจัดกลุ่มให้อุปกรณ์เรียบร้อยแล้ว ในหน้าโฟลว์ ผู้ใช้งานสามารถนำโหนด ‘Publish msg’ มารับค่าข้อความที่ต้องการจะส่งออกไปได้ ซึ่งโหนดนี้นั้นสามารถทำหน้าที่ได้ทั้งเป็นตัวกลางในการรับค่าข้อความจาก msg ที่ถูกส่งมาจากโหนดอื่น ๆ หรือสร้างข้อความขึ้นมาเองในลักษณะของ JSON ข้อความ หรือตัวเลขก็ได้เช่นกัน

_images/send_message_flow3.png

อย่างไรก็ตาม การตั้งค่าในหมวด ‘Topic’ ของโหนดนี้จะแตกต่างจากคำว่า ‘topic’ ในโหนดอื่น ๆ เช่น โหนด ‘Inject’ อยู่พอสมควร ในขณะที่คำว่า topic ในโหนดเหล่านั้นคือการตั้งค่าข้อมูลเพิ่มเติม หรือค่าตัวแปรของข้อมูลที่จะถูกส่งไป แต่สำหรับการตั้งค่า Topic ในโหนดนี้คือชื่อของการสื่อสารที่จะทำการส่งออกไปจากโหนดนี้ ดังที่ได้อธิบายไปในหัวข้อของการส่งข้อความระหว่างอุปกรณ์ ยกตัวอย่างเช่นดังรูปคือการส่งข้อความออกไปยังอุปกรณ์ที่ทำการติดตามหัวข้อของข้อความที่ชื่อว่า ‘@msg/test’ เป็นต้น

การติดตามข้อความภายในโหนด

ในส่วนท้ายภายในโหนด ‘Device’ และ ‘MQTT’ มีช่องการตั้งค่าที่ตั้งชื่อว่า ‘Subscribe to’ เพื่อให้ผู้ใช้งานกำหนด topic ที่ต้องการให้อุปกรณ์เหล่านี้ไปติดตามข้อมูลที่ถูกส่งมาจากอุปกรณ์ต่าง ๆ ผ่าน topic นั้นเอาไว้อยู่ โดยค่าเริ่มต้นที่ทั้งสองโหนดได้ทำการติดตามเอาไว้อยู่คือ ‘@msg/#’ ซึ่งหมายถึงการติดตามทุกข้อความที่ถูกส่งผ่านมาในโหนดนี้ ในขณะที่โหนด ‘MQTT’ จะมีการติดตามเพิ่มอีกหนึ่ง topic ได้แก่ ‘@shadow/data/updated’ ซึ่งเป็นการติดตามค่าข้อมูลประเภท Shadow ที่จะถูกส่งเข้ามาภายในโหนดนี้แยกไว้อีกโหนดหนึ่งด้วย ซึ่งค่าข้อมูลประเภทนี้จะถูกอธิบายในหัวข้อถัดไป

_images/track_message_node.png

การส่งข้อมูลจากอุปกรณ์ไปยังแพลตฟอร์ม

เพื่อนำค่าข้อมูลที่ได้รับจากอุปกรณ์ไปใช้งาน หรือทำการกำหนดค่าใหม่ลงไปในตัวอุปกรณ์นั้น ผู้ใช้งานสามารถตั้งค่าให้อุปกรณ์ผูกเข้ากับแพลตฟอร์มเพื่อรับส่งค่าข้อมูลของกันและกันได้ผ่านตัวแปรที่เรียกว่า ‘Shadow’ ซึ่งจะเป็นตัวกำหนดลักษณะของค่าข้อมูลที่ได้รับและส่งออก

Shadow

Shadow คือฐานข้อมูลเสมือนเล็ก ๆ ของอุปกรณ์ที่อยู่คู่กับอุปกรณ์ทุกตัว ซึ่งใช้ในการเก็บค่าข้อมูล 2 ประเภท ได้แก่ ข้อมูลที่ระบุถึงคุณสมบัติของอุปกรณ์ (Device Shadow Data) เช่น ข้อมูลที่ได้รับเข้ามาจากเซนเซอร์ของอุปกรณ์ หรือข้อมูลการกำหนดค่าต่าง ๆ ของอุปกรณ์ เป็นต้น และข้อมูลที่บอกถึงสถานะของอุปกรณ์ (Device Shadow State) เช่น สถานะเปิด/ปิดของอุปกรณ์ เป็นต้น โดยค่าข้อมูลที่เข้ามาใน Shadow นั้นจะเป็นค่าของอุปกรณ์ ณ เวลาใดเวลาหนึ่งที่จะไม่มีการเก็บค่าย้อนหลังของอุปกรณ์เอาไว้เป็นอันขาด ลักษณะของค่าข้อมูลที่เข้ามาในรูปแบบ Shadow นั้นจะถูกห่อหุ้มไว้ด้วยค่าตัวแปร data คือ

{
    "data": {
        "field 1":  "value 1",
        "field 2":  "value 2",
        "field n":  "value n"
    }
}

โดย field จะหมายถึงชื่อของตัวแปรแต่ละตัวที่อยู่ภายใน Shadow ที่ส่งมา (เช่น ‘temperature’ เพื่อใช้แทนค่าอุณหภูมิ หรือ ‘humidity’ เพื่อใช้แทนค่าความชื้น เป็นต้น) และ value คือค่าข้อมูลของแต่ละตัวแปรนั้น

ตัวอย่าง

ผู้ใช้งานสามารถสร้างค่าข้อมูล Shadow ขึ้นมาในโฟลว์ได้ผ่านโหนด ‘Inject’ โดยให้กำหนดประเภทของ payload เป็น JSON เพื่อใส่ค่า Shadow ลงไป เช่น หากต้องการให้ค่าข้อมูลที่ใส่ลงไปมีค่าตัวแปร ‘temperature’ เพื่อแทนอุณหภูมิและ ‘humidity’ เพื่อแทนความชื้น ผู้ใช้งานสามารถเขียนลงไปในโหนด ‘Inject’ ได้ดังนี้

_images/node_shadow_ex1.png
[
    {
        "id": "4a4c9ed5.231f6",
        "type": "inject",
        "z": "8cfb1028.a0d6d",
        "name": "NEXIIOT Data",
        "topic": "",
        "payload": "{\"data\":{\"temperature\":25,\"humidity\":65}}",
        "payloadType": "json",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 171.00000762939453,
        "y": 1742.0000505447388,
        "wires": [["c075cb29.fb8738"]]
    }
]

ส่งค่าข้อมูล Shadow ไปยังแพลตฟอร์ม

ผู้ใช้งานสามารถเขียนค่าข้อมูล Shadow ไปยังแพลตฟอร์มได้โดยการนำโหนด ‘Write Shadow’ ที่อยู่ในหมวดหมู่ ‘Command’ มาใช้งาน โหนดนี้จะทำการนำค่าข้อมูลที่ได้รับมาแปลงให้กลายเป็นค่า Shadow เสียก่อนการจะนำเอาไปใช้งานต่อไป ซึ่งโหนดนี้สามารถรับค่าข้อมูลที่เข้ามาได้สองประเภท ได้แก่

_images/node_shadow_platform.png
  1. Shadow JSON คือการรับค่าข้อมูลจากโหนดก่อนหน้าที่ถูกส่งมาในลักษณะของ Shadow JSON อยู่แล้วเพื่อไปใช้งานโดยตรง

{
    "data": {
        "field 1":  "value 1",
        "field 2":  "value 2",
        "field n":  "value n"
    }
}
  1. Field คือรับค่าข้อมูลจากโหนดหลาย ๆ โหนดมารวมกันเพื่อสร้าง Shadow ใหม่ขึ้นมา จากนั้นจึงสามารถส่งค่าข้อมูลนั้นไปใช้งานอื่นต่อไป โดยการสร้างค่า Shadow นั้นจะอ้างอิงจากค่าข้อมูลในตัวแปรต่าง ๆ ที่อยู่ภายในโหนดก่อนหน้า

{
    "field 1":  "value 1",
    "field 2":  "value 2",
    "field n":  "value n"
}

หากผู้ใช้งานต้องการเลือกที่จะรับค่าข้อมูลในลักษณะ Field มาใช้งาน ค่าข้อมูลเหล่านั้นจะถูกแปลงให้กลายเป็นค่าข้อมูลในลักษณะ Shadow เสียก่อนเพื่อนำค่า Shadow ที่ได้ส่งไปยังแพลตฟอร์ม ซึ่งจะปรากฏการตั้งค่าเพิ่มเติมขึ้นมาดังนี้

  • Combine each จะช่วยในการผนวกรวมค่าข้อมูลเข้าด้วยกันเพื่อแปลงค่าข้อมูลเหล่านั้นให้กลายเป็นค่าข้อมูล Shadow ซึ่งจะแปลงเป็นค่าในลักษณะนี้

[
    {
        "id": "4a4c9ed5.231f6",
        "type": "inject",
        "z": "8cfb1028.a0d6d",
        "name": "NEXIIOT Data",
        "topic": "",
        "payload": "{\"data\":{\"temperature\":25,\"humidity\":65}}",
        "payloadType": "json",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 171.00000762939453,
        "y": 1742.0000505447388,
        "wires": [["c075cb29.fb8738"]]
    }
]
  • Key คือชื่อของตัวแปรหรือ field ที่จะถูกนำไปใส่ใน Shadow โดยค่าเริ่มต้นของค่านี้จะนำ topic ที่ถูกส่งมาจากโหนดก่อนหน้ามาใช้งาน

  • Value คือค่าของตัวแปรนั้นที่จะถูกนำไปใส่ใน Shadow ซึ่งค่าเริ่มต้นของค่านี้คือค่าข้อมูลจาก payload ที่ส่งมาจากโหนดก่อนหน้า

  • Write shadow คือส่วนการตั้งค่าเพิ่มเติมเกี่ยวกับการเขียนข้อมูลในลักษณะ Shadow ว่าจะมีการเขียนค่าข้อมูล Shadow นี้เมื่อตรงเงื่อนไขของเหตุการณ์ใดบ้าง ซึ่งประกอบไปด้วย 3 เหตุการณ์ ได้แก่

    • After a number of message parts คือการกำหนดว่าให้เขียน Shadow เมื่อมีได้รับข้อความมาทั้งหมดกี่ค่าแล้ว

    • After timeout following the first message คือการกำหนดระยะเวลาสิ้นสุด (timeout) หลังจากที่ได้รับข้อความแรกเข้ามา

    • After a message with the msg.complete property set จะไม่ได้ต้องการให้ผู้ใช้งานกำหนดค่าใด ๆ แต่เป็นการย้ำเตือนว่าจะทำการเขียนข้อมูล Shadow ลงไปในอุปกรณ์เมื่อค่าข้อความที่มีคุณสมบัติ msg.complete ได้ถูกตั้งค่าเอาไว้เรียบร้อยแล้ว

ตัวอย่าง

ผู้ใช้งานทำการสร้างโหนดที่จะส่งค่าอุณหภูมิและความชื้นขึ้นมาด้วยโหนด ‘Inject’ ซึ่งในที่นี้จะทำการแบ่งค่าข้อมูลทั้งสองตัวแปรนั้นออกเป็นสองโหนดที่แตกต่างกัน โดยให้กำหนดค่า payload เป็นค่าข้อมูล และใส่กำกับชื่อตัวแปรของค่าข้อมูลนั้นเอาไว้ที่ topic

_images/node_shadow_platformex1.png

ผู้ใช้งานทำการนำโหนด ‘Inject’ ลากเชื่อมเข้ากับโหนด ‘Write Shadow’ เพื่อรอรับค่าข้อมูลที่ออกมาและแปลงค่าเหล่านั้นที่เข้ามาให้อยู่ในลักษณะของ Shadow เพื่อเตรียมส่งค่าข้อมูลสุดท้ายเข้าไปยังอุปกรณ์ โดยให้ทำการลากเส้นจากโหนด ‘Write Shadow’ เข้าไปในโหนด ‘Device’ อีกที ในกรณีที่ต้องการตรวจสอบผลของค่าข้อมูลนั้นว่าเปฝ้นเช่นไร ผู้ใช้งานสามารถนำโหนด ‘Debug’ ไปเชื่อมต่อท้ายของโฟลว์นี้อีกทีได้

_images/node_shadow_platformex2.png

ภายในโหนด ‘Write Shadow’ นั้น เนื่องจากค่าข้อมูลที่เข้ามาภายในโหนดนี้ยังไม่ใช่ค่า Shadow แต่เป็นค่าข้อมูลที่กำกับตัวแปรเอาไว้และส่งมาจากโหนดที่แตกต่างกัน ผู้ใช้งานจึงจำเป็นต้องเลือก Input format ภายในโหนดนี้ว่าเป็น ‘Field’ ซึ่งมีค่า key คือ topic ซึ่งเป็นชื่อของตัวแปรที่กำหนดเอาไว้ก่อนหน้าและ value คือ payload ซึ่งเป็นค่าข้อมูล ของตัวแปรนี้นั่นเอง จากนั้นจึงทำการคลิกที่ปุ่ม ‘Done’ เพื่อบันทึกการเปลี่ยนแปลงนั้น

_images/node_shadow_platformex3.png
[
    {"id":"6256b780.d38588","type":"tab","label":"Flow 1","disabled":false,"info":""},
    {"id":"58c7f8c.d03f608","type":"write shadow","z":"6256b780.d38588","name":"write shadow","shadowproperty":"payload","shadowpropertyType":"msg","shadowformatmode":"auto","fieldkeyproperty":"topic","fieldkeypropertyType":"msg","fieldvalueproperty":"payload","fieldvaluepropertyType":"msg","timeout":0.2,"count":0,"inputformat":"field","x":670,"y":180,"wires":[["2009af4e.22fb1"]]},
    {"id":"ac501608.b884f8","type":"debug","z":"6256b780.d38588","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1010,"y":180,"wires":[]},
    {"id":"bc5b143c.9f9428","type":"inject","z":"6256b780.d38588","name":"Field Data Temperature","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"temperature","payload":"23","payloadType":"num","x":420,"y":160,"wires":[["58c7f8c.d03f608"]]},
    {"id":"2009af4e.22fb1","type":"device","z":"6256b780.d38588","name":"Device","deviceconfig":"40e80187.78937","topics":"@msg/#\n","active":true,"subshadow":true,"subprivate":true,"initshadow":true,"x":850,"y":180,"wires":[["ac501608.b884f8"]]},{"id":"a10ebe27.9c885","type":"inject","z":"6256b780.d38588","name":"Field Data Humidity","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"humidity","payload":"51","payloadType":"num","x":410,"y":220,"wires":[["58c7f8c.d03f608"]]},
    {"id":"40e80187.78937","type":"deviceconfig","devicename":"FLOWENGINE","devicenameType":"custom","deviceid":"","devicetoken":"","devicealias":"","platform":"4835b131.5b6bb"},
    {"id":"4835b131.5b6bb","type":"platform","platform":"","platformType":"NEXIIOT","platformname":"NEXIIOT","active":true,"profile":"nexpie","mqtthost":"mqtts://mqtt.nexiiot.io","apihost":"https://api.nexiiot.io","dshost":"https://ds.nexiiot.io","flowchannel":"","flowchannelType":"custom"}
]

เรียกดูค่าข้อมูลจากแพลตฟอร์ม

ผู้ใช้งานสามารถดูค่าข้อมูลปัจจุบันของอุปกรณ์ (Shadow) โดยการใช้โหนด ‘Get Shadow’ ที่อยู่ใหมวดหมู่ ‘Command’

_images/view_data_platform1.png

ผู้ใช้งานไม่จำเป็นต้องทำการตั้งค่าใด ๆ ภายในโหนดนี้ แต่ให้ทำการนำโหนดนี้เชื่อมต่อเข้าด้านหลังของโหนดอุปกรณ์ที่ผู้ใช้งานต้องการจะรับค่าข้อมูลดังรูปด้านบน เมื่อค่า Shadow ของอุปกรณ์ที่โหนดนี้ได้ไปทำการเชื่อมต่อมีการเปลี่ยนแปลงข้อมูลที่อยู่ด้านใน โหนด ‘Get Shadow’ จะทำการดึงค่าข้อมูล Shadow ของอุปกรณ์นั้นออกมาใช้งานในทันที

_images/view_data_platform2.png

ในทางกลับกัน หากผู้ใช้งานทำการย้ายโหนดนี้ไปไว้หน้าโหนดของอุปกรณ์ดังรูปด้านบน ผู้ใช้งานสามารถผลักค่า Shadow ของอุปกรณ์ให้ออกมาแสดงผลได้โดยการคลิกบนปุ่มที่อยุ่บนโหนดนี้ เปรียบเสมือนการกระทุ้งค่าข้อมูลให้ออกมาจากโหนดของอุปกรณ์นั้นนั่นเอง โดยการทำเช่นนี้จะทำให้ผู้ใช้งานสามารถดูค่าข้อมูล Shadow ปัจจุบันของอุปกรณ์ได้โดยไม่จำเป็นต้องรอให้มีการเปลี่ยนแปลงของค่า Shadow ของอุปกรณ์นั้น

_images/view_data_platform3.png

เรียกดูสถานะของอุปกรณ์

ผู้ใช้งานสามารถดูค่าสถานะปัจจุบันของอุปกรณ์ได้ว่ายังคงทำงานอยู่ (On) หรือยุติการทำงานไปเรียบร้อยแล้ว (Off) โดยการใช้โหนด ‘Get Status’ ที่อยู่ใหมวดหมู่ ‘Command’

_images/view_status_device.png

ข้อแตกต่างระหว่างโหนด ‘Get Status’ และโหนด ‘Get shadow’ นั้นคือ โหนดนี้จำเป็นต้องทำการเชื่อมต่อไว้ทางด้านหน้าของอุปกรณ์ที่ต้องการตรวจสอบสถานะการเชื่อมต่อเท่านั้น โดยวิธีการใช้งานของโหนดนี้นั้นจะเปรียบเสมือนการกระทุ้งค่าสถานะปัจจุบันให้ออกมาจากอุปกรณ์ที่ต้องการ ซึ่งผู้ใช้งานไม่จำเป็นต้องตั้งค่าให้กับโหนดนี้เช่นกันกับโหนด ‘Get Shadow’ แต่ให้นำโหนดนี้เชื่อมต่อเข้ากับจุดเชื่อมต่อขาเข้ากับอุปกรณ์ที่ต้องการนำค่าข้อมูลออกมา ในทุกครั้งที่ผู้ใช้งานทำการกดที่ปุ่มของโหนดนี้ จะเป็นการกระทุ้งค่าข้อมูลให้ออกมาจากโหนดของอุปกรณ์ที่โหนดนี้ไปเชื่อมต่ออยู่ โดยในที่นี้คือการกระทุ้งค่าข้อมูลสถานะปัจจุบันของอุปกรณ์ที่ถูกเชื่อมต่ออยู่ให้ออกมาแสดงผล โดยผลลัพธ์ที่ออกมานั้นจะอยู่ในลักษณะของค่า 0 และ 1 ซึ่งค่า 0 นั้นหมายถึงอุปกรณ์อยู่ในสถานะไม่พร้อมใช้งาน ในขณะที่ 1 หมายถึงอุปกรณ์ได้รับการเชื่อมต่อและอยู่ระหว่างการใช้งานนั่นเอง โดยรูปแบบของผลลัพธ์ที่ออกมาจะปรากฏว่า

{“status”: 1}

การจัดการข้อมูล

_images/manage_data1.png

ในบางกรณี ข้อมูลที่รับหรือส่งมาจากอุปกรณ์อาจจำเป็นต้องมีการตั้งค่าและ/หรือแก้ไขบางอย่างเพื่อความเหมาะสมของการใช้งาน โดย NEXPIE นั้นได้ทำการสร้างโหนดขึ้นมา 4 ชนิด ในหมวดหมู่ ‘Flow’ เพื่อใช้ควบคู่กับการตั้งค่าข้อมูลต่าง ๆ ที่ได้รับ ได้แก่ การคัดแยกค่าข้อมูล (Extract) การเปลี่ยนแปลงค่าข้อมูล (Transform) การแปลงข้อมูลที่ได้รับเมื่อถึงระดับที่กำหนด (Level Trigger) และการสลับผล (Toggle)

_images/manage_data2.png

Extract

_images/extract_data1.png

ในกรณีที่ค่าข้อมูลถูกส่งเข้ามาในลักษณะของ JSON หรือค่าข้อมูลในลักษณะ Shadow ผู้ใช้งานสามารถทำการคัดแยกข้อมูลเหล่านั้นออกจากกันได้ด้วยการใช้โหนดชื่อว่า ‘Extract’ ในการดึงค่าข้อมูลจากแต่ละ field ออกมา โดยจะส่งออกเป็นค่าข้อมูลหลายค่า (One-to-many) ออกมาจากโหนดนี้ ตามจำนวนที่ผู้ใช้งานกำหนดเอาไว้

ข้อมูลที่สามารถส่งเข้ามาภายในโหนดนี้ได้นั้นประกอบด้วยกัน 2 รูปแบบ

_images/extract_data2.png
  • NEXPIE Data หรือค่าข้อมูลในลักษณะ Shadow ซึ่งค่าข้อมูล payload ที่ถูกส่งเข้ามาภายในโหนดนี้นั้นต้องอยู่ในลักษณะ

{
    "data": {
        "field 1": "value 1",
        "field 2": "value 2",
        "field n": "value n",
    }
}

โดย field หมายถึงค่าตัวแปรต่าง ๆ และ value คือค่าข้อมูลของตัวแปรนั้น ๆ การใช้งานประเภทนี้เหมาะกับข้อมูล Shadow ที่ได้รับมาจากอุปกรณ์โดยตรง

  • JSON Data หรือค่าข้อมูลที่ถูกส่งมาในลักษณะของ JSON โดยตรงโดยต้องไม่จำเป็นต้องนำ ‘data’ มาคลุมค่าข้อมูลทั้งหมดเอาไว้อีกทีเหมือน Shadow

{
    "field 1":  "value 1",
    "field 2":  "value 2",
    "field n":  "value n"
}

ซึ่งในการรับค่าข้อมูลของโหนดนี้ ให้ผู้ใช้งานทำการเปลี่ยน drop-down ไปที่ ‘data.’ ในกรณีที่ค่าข้อมูลเป็น NEXPIE Data หรือ ‘json path’ ในกรณีที่ค่าข้อมูลเป็น JSON Data จากนั้นจึงเติมชื่อตัวแปรที่ได้รับมาจากค่าข้อมูลก่อนหน้าเพื่อดึงค่าข้อมูลนั้นออกมา

_images/extract_data3.png

จำนวนจุดสีเทาที่อยู่ด้านขวาจะถึงอยู่กับจำนวนค่าตัวแปรที่ผู้ใช้งานกำหนดและจะลำดับจากบนลงล่างตามลำดับของตัวแปรที่ตั้งค่าไว้ในโหนด ซึ่งผู้ใช้งานสามารถเพิ่มค่าตัวแปรอื่น ๆ ได้ด้วยการกดที่ปุ่ม ‘+ add’ ด้านล่าง และสามารถลบตัวแปรที่ไม่ต้องการดึงออกมาใช้งานได้ด้วยกดที่ปุ่มกากบาทบนแถบข้อมูลของตัวแปรนั้น

ตัวอย่าง

ข้อมูลจากโหนดก่อนหน้าถูกส่งเข้ามาในลักษณะของค่า Shadow ที่ประกอบไปด้วยตัวแปร ‘temperature’ และ ‘humidity’ ผู้ใช้งานต้องการแยกค่านี้ออกเป็นสองเส้นเพื่อนำไปส่งให้แก่อุปกรณ์ที่แตกต่างกัน โดยสามารถทำได้จากการลากข้อมูลจากโหนดที่ส่งค่า Shadow ออกมาเข้ากับโหนด ‘Extract’ และเปิดหน้าการตั้งค่าของโหนดขึ้นมา

_images/extract_data_ex1.png

ในหน้าการตั้งค่า ผู้ใช้งานทำการคลิกที่ปุ่ม ‘+ add’ เพื่อเพิ่มตัวแปรที่ต้องการคัดแยกออกจาก Shadow ขึ้นมาอีกค่าหนึ่ง จากนั้นทำการกรอกชื่อตัวแปรของค่าข้อมูลนั้นลงไป โดยตัวเลขทางด้านขวาที่กำกับชื่อตัวแปรที่ใส่ลงไป จะบอกถึงตำแหน่งของจุดเชื่อมต่อขาออกของโหนดนี้จากบนลงล่าง เริ่มต้นที่เลข 1 หลังจากนั้นให้ทำการคลิกที่ปุ่ม ‘Done’ เพื่อยืนยันการเปลี่ยนแปลง

_images/extract_data_ex2.png

เมื่อทำการบันทึกการเปลี่ยนแปลงของหน้าโฟลว์เรียบร้อยแล้ว หากลองนำโหนด ‘Debug’ มาเชื่อมต่อกับแต่ละจุดเชื่อมต่อขาออกของโหนดนี้ จะพบว่าค่าข้อมูลถูกส่งออกแยกเป็นสองค่าโดยไม่เหลือเค้าโครงของ Shadow อีกต่อไป

_images/extract_data_ex3.png
[
    {"id": "f4fb3b18.7352b8", "type": "inject", "z": "8cfb1028.a0d6d", "name": "NEXIIOT Data", "topic": "", "payload": "{\"data\":{\"temperature\":25,\"humidity\":65}}", "payloadType": "json", "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "x": 630, "y": 140, "wires": [["5506dd32.71d9a4"]]},
    {"id": "5506dd32.71d9a4", "type": "extract", "z": "8cfb1028.a0d6d", "name": "Extract Data", "property": "payload", "propertyType": "msg", "rules": [{"v": "temperature", "vt": "data.", "t": "eq"}, {"v": "humidity", "vt": "data.", "t": "eq"}], "outputs": 2, "x": 810, "y": 140, "wires": [["82c0b54.9b4f148"], ["d88d090b.7756e8"]]},
    {"id": "82c0b54.9b4f148", "type": "debug", "z": "8cfb1028.a0d6d", "name": "Temperature", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "x": 1030, "y": 100, "wires": []},
    {"id": "d88d090b.7756e8", "type": "debug", "z": "8cfb1028.a0d6d", "name": "Humidity", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "x": 1020, "y": 180, "wires": []}
]

ในการคัดแยกค่าข้อมูลจากค่า JSON ที่ไม่ใช่ Shadow ผู้ใช้งานสามารถทำได้โดยการเปลี่ยนจาก ‘data.’ ให้กลายเป็น ‘json path’ แล้วกรอกชื่อของตัวแปรลงไปตามเดิม


Tranform

_images/tranform_data1.png

โหนด ‘Transform’ จะเปลี่ยนแปลงค่าข้อมูลที่ได้รับเข้ามา ผ่านกระบวนการทางคณิตศาสตร์หรือสมการอื่น ๆ ที่สามารถเขียนขึ้นได้ในรูปแบบของ JSONata ซึ่งผู้ใช้งานสามารถกำหนดขึ้นมาเองได้ มักใช้ในกรณีที่ต้องการเปลี่ยนแปลงหน่วยของค่าข้อมูลต่าง ๆ หรือการเปลี่ยนแปลงลักษณะการแสดงผลของข้อมูลต่าง ๆ ให้เป็นอีกลักษณะเพื่อนำไปใช้งานในส่วนอื่น ๆ ต่อได้ เช่น การเปลี่ยนแปลงจากค่าอุณหภูมิจากแบบองศาเซลเซียสเป็นอุณหภูมิแบบองศาฟาเรนไฮต์ หรือเปลี่ยนแปลงจากหน่วยเวลานาทีให้กลายเป็นหน่วยเวลาแบบวินาที เป็นต้น

_images/tranform_data2.png

การตั้งค่าของโหนดนี้นั้นประกอบไปด้วย 5 ส่วน ดังนี้

  • Name คือการตั้งชื่อให้กับโหนดนี้

  • Input คือการเลือกประเภทของข้อมูลที่โหนดนี้ได้รับเข้ามา ซึ่งสามารถเลือกได้ 3 ประเภท ได้แก่

    • Raw input คือค่าข้อมูลที่เข้ามาในลักษณะข้อมูลดิบหรือค่าตัวเลขเพียงค่าเดียวโดยตรง

    • NEXPIE Data คือค่าข้อมูลที่เข้ามาในรูปแบบของ shadow ซึ่งผู้ใช้งานสามารถเข้าถึงข้อมูลของแต่ละตัวแปรด้วยการเลือก drop-down ไปที่ ‘data.’ แล้วทำการพิมพ์ชื่อตัวแปรที่ต้องการดึงค่ามาใช้งานลงไป

    • JSON Path คือค่าข้อมูลที่เข้ามาในรูปแบบ JSON โดยการเลือกที่ตัวเลือก drop-down ‘json path’ โดยผู้ใช้งานสามารถพิมพ์ชื่อของค่าตัวแปรที่ต้องการดึงออกมาจากค่าข้อความที่ถูกส่งเข้ามาไปใช้งานต่อได้โดยตรง

  • Expression คือการตั้งค่าสมการทางคณิตศาสตร์ โดยผู้ใช้งานสามารถใช้ ‘$value’ เพื่อเป็นตัวแปรแทนค่าข้อมูลที่เข้ามาภายในโหนดได้ เช่น หากผู้ใช้งานต้องตั้งสมการเพื่อเปลี่ยนค่าข้อมูลจากองศาเซลเซียส (℃) ให้กลายเป็งองศาฟาเรนไฮต์ (℉) ผู้ใช้งานสามารถเขียนค่าสมการลงไปได้ว่า (1.8 * $value) + 32

  • Assign to คือการตั้งค่าว่าผลลัพธ์ที่ออกไปนั้นจะออกไปยังตัวแปรใด โดยสามารถเลือกได้ว่าจะให้ข้อมูลออกไปในลักษณะของข้อมูลดิบ (Raw data) หรือในลักษณะของ shadow ก็ได้เช่นกัน

  • Output format คือการเลือกลักษณะของผลลัพธ์

    • Shadow JSON คือการส่งข้อมูลออกไปในลักษณะของ shadow

    • Field จะเป็นการส่งค่าข้อมูลในลักษณะของ payload ออกไป โดยภายในโหนดปลายทางจะได้รับข้อมูลในลักษณะของ ‘msg’

ตัวอย่าง

ค่าข้อมูลที่ถูกส่งเข้ามาในรูปแบบองศาเซลเซียส ผู้ใช้งานต้องการเปลี่ยนค่าข้อมูลนั้นให้อยู่ในรูปแบบขององศาฟาเรนไฮต์ โดยทำการนำโหนด ‘Transform’ มาลากต่อจากโหนดที่ทำการส่งข้อมูลอุณหภูมินั้นมา พร้อมด้วยโหนด ‘Debug’ ที่จะทำการตรวจสอบค่าข้อมูลที่ออกมาจากโหนด ‘Transform’ ว่าเป็นไปดังที่คาดการณ์หรือไม่ จากนั้นจึงทำการเปิดหน้าแก้ไขของโหนด ‘Transform’ ขึ้นมา

_images/tranform_data_ex1.png

ข้อมูลที่ถูกส่งเข้ามาในโหนดนี้เป็นค่าข้อมูลดิบ ดังนั้น Input ของโหนดนี้จึงต้องเลือกเป็น ‘raw input’ จากนั้นทำการตั้งค่าสมการของการเปลี่ยนแปลงค่าข้อมูลนี้ว่า (1.8 * $value) + 32 ซึ่งอ้างอิงมาจากค่าสมการ F=C 95+32โดยให้ $value แทนค่าข้อมูลในหน่วยองศาเซลเซียสที่ถูกส่งมาจากโหนดก่อนหน้า จากนั้นจึงทำการตั้งค่าให้เก็บโหนดนี้ในลักษณะของ Shadow ในตัวแปรที่ชื่อ temperatureFah โดยให้กำหนดลักษณะของค่าข้อมูลขาออกใน Output format ว่าเป็น ‘Shadow JSON’ จากนั้นตั้งชื่อตัวแปรของค่าข้อมูลขาออกให้กำกับโดยมี ‘data.’ อยู่ด้านหน้าชื่อของตัวแปรนั้น ทำการคลิกที่ปุ่ม ‘Done’ เมื่อทำทุกอย่างเรียบร้อยแล้ว

_images/tranform_data_ex2.png

ทำการบันทึกหน้าโฟลว์หลังการเปลี่ยนแปลงสำเร็จ เมื่อลองทำการส่งค่าข้อมูล 25 องศาเซลเซียสจากโหนดที่สร้างข้อมูลเข้าไปยังโหนดนี้ จะพบว่าข้อมูลที่ออกมานั้นมีค่าเท่ากับ 77 องศาฟาเรนไฮต์ ซึ่งค่าข้อมูลที่ออกมานั้นจะอยู่ในรูปลักษณะของต่า Shadow ที่มีตัวแปรชื่อ temperatureFah กำกับค่านี้เอาไว้

_images/tranform_data_ex3.png
[
    {"id": "88719d44.72ca5", "type": "inject", "z": "8cfb1028.a0d6d", "name": "Temperature", "topic": "temperature", "payload": "25", "payloadType": "json", "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "x": 450, "y": 2140, "wires": [["1267e7af.3407b8"]]},
    {"id": "1267e7af.3407b8", "type": "transform", "z": "8cfb1028.a0d6d", "name": "transform", "shadowproperty": "payload", "shadowpropertyType": "msg", "inputfieldproperty": "", "inputfieldpropertyType": "raw", "expression": "(1.8*$value)+32", "outputfieldproperty": "temperatureFah", "outputfieldpropertyType": "data.", "outputformat": "json", "x": 660, "y": 2140, "wires": [["41e759b8.a0f548"]]},
    {"id": "41e759b8.a0f548", "type": "debug", "z": "8cfb1028.a0d6d", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "x": 870, "y": 2140, "wires": []}
]

Level trigger

_images/tranform_data_limit1.png

หลายครั้งที่ผู้ใช้งานไม่ได้ต้องการจะรู้ค่าข้อมูลที่ได้รับจากอุปกรณ์นั้นโดยตรง แต่ต้องการจะรู้เพียงช่วงของค่าข้อมูลที่ส่งเข้ามาเสียมากกว่าว่ากำลังอยู่ในระดับใด เช่น ค่าข้อมูลที่ได้รับมานั้นสูงเกินไป หรืออยู่ต่ำกว่าค่ามาตรฐานที่ได้ทำการกำหนดเอาไว้ โหนด ‘Level Trigger’ ถูกสร้างขึ้นมาเพื่อตอบสนองความต้องการนี้ของผู้ใช้งาน โดยการแบ่งค่าข้อมูลออกเป็นสองระดับที่มีค่าขอบบนและขอบล่างของค่ามาตรฐานเป็นเกณฑ์ ในการแบ่งระดับของค่าข้อมูลเหล่านั้น ซึ่งค่าขอบบนและขอบล่างของค่ามาตรฐานนี้คือการกำหนดขอบเขตการเบี่ยงเบนของค่าข้อมูลที่อาจจะเกิดขึ้น เช่น ต้องการบอกว่า 25 องศาเซลเซียสของเครื่องปรับอากาศ คือค่าของอุณหภูมิกลางที่ใช้แบ่งระหว่างความเย็นและความร้อน ค่าขอบเขตนี้จึงเป็นการกำหนดความคลาดเคลื่อนที่อาจเป็นไปได้ของอุปกรณ์นั้นนั่นเอง

_images/tranform_data_limit2.png

เมื่อมีข้อมูลที่ไหลผ่านเข้ามาภายในโหนด โหนดนี้จะทำการตัดสินใจว่าค่าข้อมูลนี้ควรอยู่ในระดับใดที่กำหนดไว้ และจะส่งออกค่าข้อมูลที่ถูกตั้งเอาไว้ในระดับนั้นออกไป เช่น การส่งข้อความออกไปจากโหนดว่า ‘High’ ในกรณีที่ค่าข้อมูลที่เข้ามาในโหนดมีค่าสูงกว่าค่ามาตรฐานที่ตั้งเอาไว้ก่อนหน้า เป็นต้น โดยค่าที่ถูกส่งออกไปจากโหนดนี้จะยังคงเป็นผลลัพธ์เดิมไว้เสมอ จนกว่าจะมีค่าข้อมูลใดที่ลดลงจนต่ำกว่าขอบล่างของข้อมูล หรือเพิ่มสูงขึ้นจนสูงกว่าขอบบนของข้อมูล

ตัวอย่าง

หากผู้ใช้งานกำหนดให้ 25 องศาเซลเซียสคือค่ามาตรฐานโดยมีค่าความคลาดเคลื่อนของอุปกรณ์อยู่ที่ ±5 องศาเซลเซียส นั่นหมายถึง ผู้ใช้งานต้องกำหนดค่าขอบบนไว้ที่ 30 องศาเซลเซียสเพื่อแสดงผล ‘High’ และกำหนดค่าขอบล่างไว้ที่ 20 องศาเซลเซียสเพื่อแสดงผล ‘Low’ หลังจากนั้นจึงทำการส่งค่าของข้อมูลเข้ามายังโหนดนี้เรื่อย ๆ โดยให้มีการเปลี่ยนแปลงค่าของข้อมูลไปในแต่ละครั้งที่มีการส่งข้อมูลเข้ามา ซึ่งผลลัพธ์จะปรากฏดังตารางด้านล่าง

_images/tranform_data_limit_ex1.png

การส่งค่าข้อมูลใหม่เมื่อมีการเปลี่ยนแปลงของระดับการทำงานนั้นจะเป็นการตั้งค่าขอบล่างและขอบบนของการเปลี่ยนแปลง โดยค่าข้อมูลจะทำการเปลี่ยนแปลงไปใช้งานค่าข้อมูลในระดับบน (High Value) เมื่อค่าข้อมูลเพิ่มขึ้นจนเกินขอบบนไป (High Trigger) และใช้งานในระดับล่าง (Low Value) เมื่อค่าข้อมูลลดลงต่ำกว่าค่าระดับล่างที่ตั้งไว้ (Low Trigger) การเปลี่ยนแปลงของข้อมูลในลักษณะนี้ จะช่วยให้ค่าข้อมูลที่มีความกวัดแกว่งนั้นสามารถเปลี่ยนระดับของข้อมูลได้ดีขึ้นกว่าการตั้งค่ากลางเพียงค่าเดียว เพราะมีช่วงเผื่อของค่าข้อมูลเอาไว้ในกรณีที่ค่าข้อมูลยังลงไม่ถึงขอบล่าง หรือขึ้นไม่ถึงขอบบน ตัวอย่างการใช้งาน เช่น การตั้งค่าให้เครื่องปรับอากาศปิดการทำงานเมื่ออุณหภูมิลดลงต่ำกว่า 25 องศาเซลเซียส หรือการตั้งค่าให้ไฟปิดเมื่อพระอาทิตย์ขึ้น และเปิดอีกครั้งเมื่อไม่มีแสงจากภายนอกหรือพระอาทิตย์ เป็นต้น

_images/tranform_data_limit_ex2.png

ภายในโหนดนี้ มีการตั้งค่าประกอบไปด้วย 6 ส่วน ดังนี้

  • Name คือการตั้งชื่อให้กับโหนดนี้

  • Input คือการกำหนดลักษณะของค่าข้อมูลที่เข้ามาว่าต้องการรับค่าข้อมูลในลักษณะใด ระหว่างค่าข้อมูล shadow ด้วยการเลือก ‘data.’ หรือค่าข้อมูลที่มาจากไฟล์ JSON ด้วยการเลือก ‘json path’ หรือค่าข้อมูลดิบของตัวเลข (Raw data)

  • High/Low Trigger คือการตั้งค่าขอบบน (High Trigger) และขอบล่าง (Low Trigger) ของค่าข้อมูลที่จะทำให้มีการเปลี่ยนแปลงของผลลัพธ์ เช่น การตั้งค่าขอบบนไว้ที่ 80 หมายถึง หากค่าข้อมูลที่ได้รับเข้ามาเกิน 80 ค่าที่ตั้งไว้ในขอบบนนี้จะถูกนำไปใช้งาน

  • High/Low Value คือการตั้งค่าผลลัพธ์เมื่อค่าข้อมูลที่ได้รับเข้ามาสูงกว่าค่าขอบบนหรือลดต่ำกว่าค่าขอบล่างที่ตั้งเอาไว้ตามลำดับ เช่น เมื่อค่าข้อมูลที่ได้รับเข้ามาสูงเกินค่าขอบบนที่ตั้งเอาไว้ จะส่งค่าข้อมูลออกมาว่า ‘High’ เพื่อบอกว่าค่าข้อมูลยั้นสูงเกินไป เป็นต้น

  • Assign to คือการเลือกว่าผลลัพธ์ที่ได้คำนวณออกมานั้น จะถูกส่งออกไปยังค่าตัวแปรใด ระหว่างค่า shadow หรือออกไปในลักษณะ JSON หรือออกไปเป็นค่าข้อมูลดิบ (Raw data)

  • Output format คือการเลือกลักษณะของผลลัพธ์ที่ออกไป

    • Shadow JSON คือการส่งข้อมูลออกไปในลักษณะของ shadow

    • Field จะเป็นการส่งค่าข้อมูล payload ออกไป


ตัวอย่าง

เครื่องปรับอากาศถูกกำหนดให้มีการกำหนดระดับความเย็นไว้เมื่ออุณหภูมิลดลงถึง 25 องศาเซลเซียสว่าเป็นความเย็นจนเกินไป และอุณหภูมิที่สูงกว่า 30 องศาเซลเซียสว่าเป็นความร้อนจนมากเกินไป ซึ่งผู้ใช้งานสามารถตั้งค่าเงื่อนไขนี้ได้ โดยการกำหนด High Trigger เท่ากับ 30 และกำหนด Low Trigger ให้เท่ากับ 25 โดยหากค่าข้อมูลที่เข้ามานั้นสูงกว่าค่า High Trigger ที่ตั้งว่า ให้ตั้งค่าข้อความผลลัพธ์ใน High Value ออกมาว่า ‘Too Hot!’ ในทางกลับกันที่ข้อมูลต่ำกว่าค่า Low Trigger ที่ตั้งไว้ ให้ตั้งค่าข้อความใน Low Value ว่า ‘Too Cold!’

_images/tranform_data_limit_ex3.png

เมื่อทำการบันทึกหน้าโฟลว์นี้หลังจากเชื่อมต่อโหนดข้อมูลขาเข้าและโหนด ‘Debug’ ประกบกับโหนดนี้แล้ว เมื่อทำการส่งข้อมูลเข้ามาภายในโหนดนี้จะพบว่า หากข้อมูลที่ส่งเข้ามาภายในโหนดนี้อยู่สูงกว่ากว่า High Trigger ผลลัพธ์ที่แสดงออกมาจะเป็น ‘Too Hot!’ และจะแสดงผลว่า ‘Too Cold!’ ในกรณีที่ค่าข้อมูลที่ส่งมาอยู่ต่ำกว่า Low Trigger

_images/tranform_data_limit_ex4.png
[
    {"id": "85b44dfd.a9351", "type": "level trigger", "z": "6ad0365d.c70448", "name": "", "shadowproperty": "payload", "shadowpropertyType": "msg", "hightrigger": "30", "lowtrigger": "25", "outputformat": "field", "inputfieldproperty": "", "inputfieldpropertyType": "raw", "outputfieldproperty": "", "outputfieldpropertyType": "raw", "lowoutputproperty": "Too Cold!", "lowoutputpropertyType": "str", "highoutputproperty": "Too Hot!", "highoutputpropertyType": "str", "triggeronchange": true, "x": 430, "y": 1160, "wires": [["35318911.7a3446"]]},
    {"id": "35318911.7a3446", "type": "debug", "z": "6ad0365d.c70448", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "x": 690, "y": 1160, "wires": []},
    {"id": "1f83835e.ecbc6d", "type": "inject", "z": "6ad0365d.c70448", "name": "Temperature 23 Cels", "topic": "temperature", "payload": "23", "payloadType": "num", "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "x": 170, "y": 1120, "wires": [["85b44dfd.a9351"]]},
    {"id": "959e547e.d74c48", "type": "inject", "z": "6ad0365d.c70448", "name": "Temperature 32 Cels", "topic": "temperature", "payload": "32", "payloadType": "num", "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "x": 170, "y": 1200, "wires": [["85b44dfd.a9351"]]}
]

Toggle

_images/node_toggle1.png

การสลับค่าสถานะที่ต้องการส่งออก (Toggle) เช่น การสลับจากสถานะปิดและเปิดของสวิตช์ เป็นต้น โดยสถานะจะเปลี่ยนไปในแต่ละครั้งที่มีการส่งค่าข้อมูลใด ๆ ก็ตามเข้ามา

_images/node_toggle2.png

โหนดนี้ไม่จำเป็นต้องรับค่าข้อมูลใด ๆ เข้ามา แต่ให้ทำการตั้งค่าข้อมูลในแต่ละสถานะในโหนดนี้โดยตรง

_images/node_toggle3.png

ตัวอย่าง

เมื่อมีค่าข้อมูลเข้ามาแต่ละครั้ง จะแสดงผลค่าข้อมูลเป็น 1, 2, และ 3 ตามจำนวนครั้งที่มีการเข้ามาของข้อมูล และจะวนกลับไปที่เลข 1 อีกครั้งเมื่อมีข้อมูลเข้ามาเป็นครั้งที่ 4 และจะวนเช่นนี้ไปเรื่อย ๆ โดยไม่สนใจว่าค่าข้อมูลขาเข้าที่เข้ามาภายในโหนดนี้คือค่าใด

_images/node_toggle_ex1.png

ภายในโหนด ‘Toggle’ ให้ทำการกำหนดแต่ละสถานะที่จะมีการเปลี่ยนแปลงเข้าไป โดยให้คลิกที่ปุ่ม ‘+ add’ เพื่อเพิ่มค่าสถานะต่าง ๆ เพิ่มเติม จากนั้นทำการคลิกที่ปุ่ม ‘Done’ เพื่อบันทึกการตั้งค่าของโหนดนี้

_images/node_toggle_ex2.png

หลังจากเชื่อมต่อโหนดข้อความขาเข้าเข้ากับโหนดนี้ และเชื่อมต่อข้อมูลขาออกออกจากโหนดนี้ไปยังโหนด ‘Debug’ และทำการบันทึกหน้าโฟลว์นี้เรียบร้อยแล้ว เมื่อลองทำการส่งข้อความจากโหนดที่ทำการส่งข้อมูลเข้าไปทีละครั้ง จะพบว่าผลลัพธ์ที่ออกมาจะค่อย ๆ เปลี่ยนไปทีละเลข และวนกลับมาที่เลข 1 อีกครั้งเมื่อผ่านเลข 3 ไป

[
    {"id": "7b838286.4cb8dc", "type": "toggle", "z": "6ad0365d.c70448", "name": "Toggle", "rules": [{"v": "1", "vt": "str", "t": "eq"}, {"v": "2", "vt": "str", "t": "eq"}, {"v": "3", "vt": "str", "t": "eq"}], "x": 390, "y": 1040, "wires": [["96d245f.08cb8b8"]]},
    {"id": "848209cd.6a5f58", "type": "inject", "z": "6ad0365d.c70448", "name": "Switch", "topic": "", "payload": "", "payloadType": "str", "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "x": 110, "y": 1040, "wires": [["7b838286.4cb8dc"]]},
    {"id": "96d245f.08cb8b8", "type": "debug", "z": "6ad0365d.c70448", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "x": 670, "y": 1040, "wires": []}
]

Notify

_images/node_notify1.png

นอกเหนือจากการใช้งานเพื่อสร้างโปรแกรมตามปกติแล้วนั้น ผู้ใช้งานยังสามารถเชื่อมต่อโฟลว์เข้ากับแอปพลิเคชั่นที่ผู้ใช้งานมีเพื่อทำการส่งการแจ้งเตือนของข้อมูลไปยังอุปกรณ์อื่น ๆ ของผู้ใช้งานได้อีกด้วย ซึ่งแอปพลิเคชั่นหลัก ๆ ที่มักจะถูกนำมาใช้งานก็คือ LINE นั่นเอง ผู้ใช้งานสามารถนำโหนด ‘LINE Notify’ ในหมวด ‘Notify’ ลงมาวางในโฟลว์แล้วเชื่อมต่อกับ LINE โดยการนำ token ที่ได้รับมาจาก https://notify-bot.line.me/ มาใส่ลงไปในช่อง token โดยการคลิกที่รูปดินสอข้างกล่องการตั้งค่านี้เพื่อให้อุปกรณ์สามารถเชื่อมต่อกับบริการของ LINE ได้ การทำเช่นนี้จะสามารถทำให้ผู้ใช้งานสามารถส่งข้อความแจ้งเตือน พร้อมแนบรูปหรือสติกเกอร์ควบคู่ไปกับข้อความนั้นได้อีกด้วย

_images/node_notify2.png

ในการส่งข้อความไปพร้อมการแนบรูปไปนั้น ผู้ใช้งานจำเป็นต้องนำรูปนั้นอัปโหลดขึ้นบนเว็บไซต์ฝากรูปใดก็ได้ก่อน จากนั้นจึงนำ url ที่อ้างอิงถึงตำแหน่งของรูปภาพที่ผู้ใช้งานอัปโหลดขึ้นไปนั้นมากรอกลงไปบนช่องการ ตั้งค่าเพิ่มเติมด้านล่างของช่องกรอกข้อความ โดยรูปที่ใช้นั้นมีอยู่ด้วยกันสองประเภท คือรูปขนาดเต็ม (Full Size) ขนาดไม่เกิน 2048 x 2048 พิกเซล และรูปขนาดย่อ (Thumbnail) ขนาดไม่เกิน 240 x 240 พิกเซล ซึ่งถ้าหากไม่มีการกำหนดรูปขนาดย่อเอาไว้ รูปขนาดเต็มที่ระบุไว้จะถูกนำมาใช้งานในส่วนนี้แทน

_images/node_notify3.png

ส่วนสติกเกอร์นั้น ผู้ใช้งานสามารถกำหนดได้ว่าต้องการให้ใช้สติกเกอร์ที่กำหนดภายในโหนดนี้หรือจากค่าข้อมูลที่ถูกส่งมาจากโหนดก่อนหน้าที่มีตัวแปร msg.stickerImageId และ msg.stickerId ส่งควบคู่มากับค่าข้อมูลนั้นด้วย ซึ่งหากผู้ใช้งานต้องการให้ข้อความแนบค่าตัวแปรเหล่านี้มาด้วย ให้ทำการเลือก drop-down ในหมวดการตั้งค่า Sticker ให้กลายเป็น ‘Design on msg variable’ เพื่อให้ลักษณะการแสดงผลของสติกเกอร์นั้นขึ้นอยู่กับข้อความที่ถูกส่งมาจากโหนดก่อนหน้านั่นเอง สติกเกอร์ที่จะปรากฏขึ้นมานั้น ขึ้นอยู่กับค่า Package ID และ ID ที่ผู้ใช้งานสามารถกำหนดได้เองโดยอ้างอิงจากตัวเลขในตารางรายการสติกเกอร์ของไลน์ที่ https://devdocs.line.me/files/sticker_list.pdf

_images/node_notify4.png