ดิว.นินจา

ดิว.นินจา

Thursday, March 26, 2020

NETPIE 2020 : การอัพเดท Freeboard โดยไม่ผ่าน Shadow

ในตัวอย่างจากเว็บและ workshop ของ NETPIE จะใช้วิธีการเขียนข้อมูลลงบน Device Shadow ก่อน และใช้ข้อมูลนั้นในการแสดงผลหรืออัพเดทค่าบน Freeboard widgets ซึ่งเป็นวิธีการที่เหมาะสมหากต้องการที่จะเก็บข้อมูลนั้นในแบบอนุกรมเวลาเพื่อนำไปวิเคราะห์ต่อไป แต่สำหรับข้อมูลบางประเภทอาจไม่มีความจำเป็นที่จะเก็บค่าไว้ เช่นสถานะหรือพารามิเตอร์ที่ไม่มีความสำคัญอื่นใดนอกจกาการอัพเดท Freeboard widgets การเขียนค่าเหล่านี้ลงบน Shadow ทำให้ยุ่งยากและเปลืองทรัพยากร ตัวอย่างเช่นผู้ใช้ปรับค่าตัวควบคุม PID แบบบลองผิดลองถูก เราไม่อยากบันทึกค่าเหล่านี้ลงบน Shadow ทั้งหมดจนกว่าจะได้ค่าที่เหมาะสมแล้ว นอกจากนั้นในกรณีที่อัพเดทตัวแปรหลายตัว การสร้างข้อมูลตามรูปแบบ JSON จะค่อนข้างซับซ้อนและมีโอกาสผิดได้ง่าย ชื่อของตัวแปรไม่มีความสำคัญในการอัพเดทเมื่อสามารถแยกโดยตำแหน่งของค่าในสตริง

เราสามารถแสดงข้อมูลหรืออัพเดทค่าบน Freeboard ได้โดยไม่ต้องเขียนบน Device Shadow วิธีการคือส่งข้อมูลในรูปแบบของข้อความโดยหัวข้อที่ขึ้นต้นด้วย @msg ตัวอย่างเช่น @msg/update และข้อความอาจจะเป็นค่าที่คั่นโดยเครื่องหมายที่กำหนด เช่น , ส่วนทางด้าน Freeboard widgets ก็สามารถใช้คำสั่ง .split(",")[x] เพื่อแยกค่าที่ต้องการได้ โดย x คือตัวชี้ที่เริ่มจาก 0 ผู้ที่พัฒนาบน NETPIE 2015 จะคุ้นเคยกับรูปแบบนี้ ตัวอย่างเช่นสตริง 20, 30, 40, 50 ถ้าต่อท้ายคำสั่งในฟิลด์ VALUE หรือ AUTO UPDATED VALUE ของ Freeboard widgets ด้วย .split(",")[2] จะดึงค่า 40 ออกจากสตริงข้อมูล

หมายเหตุ : เนื้อหาในบทความนี้คัดมากจากบทที่ 2 ของหนังสือ "เน็ตพาย 2020 ภาคปฏิบัติ" (อยู่ระหว่างจัดทำ) ใช้ประกอบการสอนและฝึกอบรมเกี่ยวกับไอโอที คณะวิศวกรรมศาสตร์ ม.เกษตรศาสตร์

LAB 2.1 จากโจทย์เดิมใน LAB 1.6 จะใช้วิธีการอัพเดท slider และ toggle บน Freeboard โดยส่งข้อความหัวข้อ @msg/update ใช้โครงสร้างโปรแกรม LAB1_6_cmdparm.ino จัดเก็บในชื่อใหม่คือ LAB2_1_msgupdate.ino การแสดงผลค่า humidity, temperature, light บน gauge widgets จะยังคงเดิมเพราะเป็นข้อมูลที่ต้องการเก็บบน Shadow

จุดที่ต้องการแก้ไขคือส่วนรับคำสั่ง lamp, valve, fertilizer ที่เดิมหลังได้รับคำสั่งแล้วจะพับลิชค่าในหัวข้อ @shadow/data/update เพื่อเขียนค่าลงบน Shadow จะเปลี่ยนเป็นการพับลิชข้อความหัวข้อ @msg/update โดยจัดรูปค่าทั้งสามเป็นสตริงรวมคั่นด้วยเครื่องหมาย , ซึ่งจะเห็นว่าเมื่อได้รับคำสั่งใดใน 3 คำสั่งนี้จะส่งสตริงรวมนี้ให้กับ Freeboard ทุกครั้ง ดังนั้นจึงเหมาะสมที่จะสร้างเป็นฟังก์ชัน ตั้งชื่อว่า update_freeboard()


void update_freeboard(void)
{
   datastr = String(lamp)+","+String(valve)+","+fertilizer_state;
   Serial.print("Publishing to topic @msg/update ");
   Serial.println(datastr);
   datastr.toCharArray(msg, (datastr.length() + 1));
   client.publish("@msg/update", msg);  
}

ซึ่งนอกจากจะพับลิชข้อความแล้วยังพิมพ์ออกพอร์ตอนุกรมด้วยเพื่อตรวจสอบ ในส่วนของฟังก์ชัน cmdInt() เมื่อได้รับคำสั่ง 3 คำสั่งนี้ก็จะเรียกฟังก์ชัน update_freeboard() ตัวอย่างเช่นคำสั่ง lamp=x


parmvalint = parmstring.toInt(); 
if (parmvalint > 100) parmvalint = 100; // limit to 100%
else if (parmvalint<0) parmvalint = 0;
lamp = parmvalint;
lampvalue = map(lamp,0,100,0,1023);  
analogWrite(LAMP,lampvalue);
update_freeboard();

สำหรับทางด้าน Freeboard มีจุดที่ต้องแก้ไขเริ่มต้นจากการตั้งค่า datasource จะต้องใส่ในฟิลด์ SUBSCRIBED TOPICS ด้วยหัวข้อ @msg/update ดังในรูปที่ 1 เพื่อให้สามารถรับข้อความที่ส่งมาจาก NodeMCU และไปอัพเดทส่วน widgets ต่างๆ

รูปที่ 1 การตั้งค่า datasource

การตั้งค่าสำหรับ widgets จะแก้ไขเฉพาะในส่วน AUTO UPDATED VALUE โดยใส่คำสั่งดังนี้ลงในฟิลด์ AUTO UPDATED VALUE ของ lamp และ valve sliders ตามลำดับ


datasources["igrdatasource"]["msg"]["update"].split(",")[0]
datasources["igrdatasource"]["msg"]["update"].split(",")[1]

รูปที่ 2 แสดงการตั้งค่าสำหรับ lamp slider โดยตัดเฉพาะส่วนฟิลด์ที่แก้ไข

รูปที่ 2 การตั้งค่าฟิลด์ AUTO UPDATED VALUE ของ lamp slider

ส่วนการตั้งค่าสำหรับฟิลด์ AUTO UPDATED VALUE ของ fertilizer toggle จะใช้คำสั่ง


datasources["igrdatasource"]["msg"]["update"].split(",")[2]=='on'

ดังแสดงในรูปที่ 3

รูปที่ 3 การตั้งค่าฟิลด์ AUTO UPDATED VALUE ของ fertilizer toggle

เมื่อแก้ไขทั้งด้านอุปกรณ์และ Freeboard เรียบร้อยแล้วถึงขั้นตอนการทดสอบว่าใช้งานได้จริง คอมไพล์และโหลดโปรแกรม LAB2_1_msgupdate.ino ลงบน NodeMCU เมื่อโปรแกรมเริ่มต้นทำงานและเชื่อมต่อกับ NETPIE สำเร็จ ส่วนที่ต้องการทดสอบคือการอัพเดท slider และ toggle ในรูปที่ 4 เมื่อเลื่อน lamp slider จะเห็นข้อความบน Serial Monitor แสดงการรับคำสั่ง และต่อมาจะแสดงข้อความที่ถูกพับลิชให้กับ Freeboard ในหัวข้อ @msg/update ดังในรูปที่ 5 จากการทดสอบ widgets ทั้ง 3 ตัวพบว่าสามารถอัพเดทได้อย่างถูกต้อง

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

รูปที่ 4 ทดสอบการสั่งงานและอัพเดท widgets
รูปที่ 5 การแสดงข้อความที่พับลิชบน Serial Monitor

โปรแกรมประกอบบทความ : LAB2_1_msgupdate.ino

No comments:

Post a Comment

แนะนำหนังสือ “ตัวควบคุมป้อนกลับบนอินเทอร์เน็ตโดย ESP8266”

ปัจจุบันเมื่อกล่าวถึงอุปกรณ์ IoT (Internet of Things) คงมีน้อยคนที่จะไม่รู้จัก ในยุคที่การเข้าถึงอินเทอร์เน็ตเป็นกิจวัตรประจำวันของมนุษย์เ...