สอนใช้ Telegram Notification กับ IoT HMI แทน Line Notify
สร้าง Telegram Bot ด้วย BotFather หา Chat ID ด้วย Postman แล้วให้ Samkoon SK-070QE-G + WiFi Module ส่ง HTTP POST ไปที่ sendMessage แจ้งเตือน Alarm, ยอดผลิตถึงเป้า และสรุปผลตามเวลาจาก PLC FAs-32MT-AC-E
สร้าง Bot กับ @BotFather เพื่อรับ Token หา Chat ID จาก getUpdates แล้วตั้ง HTTP Request ใน SKTool ให้ POST JSON ที่มี chat_id กับ text ไปที่ sendMessage ของ api.telegram.org (ต่อ Token หลังคำว่า bot) ทุกครั้งที่ LB0 เปลี่ยนจาก OFF เป็น ON
อัพเดทล่าสุด: 26 ตุลาคม 2569
ทำไมต้อง Telegram
คลิปนี้ทำขึ้นเพราะ LINE Notify ประกาศยกเลิกบริการ มีผลตั้งแต่ 31 มีนาคม 2568 และให้ไปใช้ Messaging API แทน ซึ่งใช้ฟรีได้ระดับหนึ่ง ถ้าส่งข้อความเยอะอาจต้องเสียค่าใช้จ่าย ส่วน Telegram ณ ตอนทำคลิปยังส่ง Notification ได้ฟรีโดยไม่มีข้อจำกัด จึงเป็นทางเลือกที่ดี ตัวอย่างในคลิปคล้ายกับคลิป LINE Notification เดิม
ตัวอย่างที่ทำในคลิป
หน้าจอ IoT HMI 7 นิ้วต่อกับ PLC ที่จำลองเป็นเครื่องจักร ส่งแจ้งเตือน 3 กรณี
- Alarm / Error — เมื่อ PLC มี Error หน้าจอส่งชื่อ Error เข้า Telegram เช่น Machine Breakdown Error หรือ No Material Error
- ผลิตถึงเป้าหมาย — เมื่อยอดผลิตถึงเป้า ส่ง Target Achieved
- สรุปผลตามเวลา — เช่น ตั้งให้แจ้งทุก 8:00 น. หรือ 17:00 น. ตามกะการทำงาน ส่งจำนวนชิ้นที่ผลิตไปแล้ว
อุปกรณ์ที่ใช้
- HMI: SK-070QE-G + WiFi Module (มี WiFi Module ให้มาด้วย ไม่มีพอร์ต LAN) ต่อกับ PLC ทาง COM2
- PLC: FAs-32MT-AC-E
- Postman สำหรับทดสอบ API
ฝั่ง PLC (จำลองเครื่องจักร)
| ส่วน | ตำแหน่ง | หน้าที่ |
|---|---|---|
| Error | M0 | มี Error ค้างอยู่ |
M1 | Machine Breakdown | |
M2 | No Material | |
Y000 | Alarm Light ติดเมื่อ M0 กับ M1 หรือ M2 ติด | |
M200 | Reset Error (RST เริ่มที่ M0 จำนวน K3 คือ M0 ถึง M2) | |
| ยอดผลิต | M100 | Work Cycle เพิ่มค่า D0 ทีละ 1 (คำสั่ง INC แบบ P) |
D0 | ยอดผลิตจริง (Actual) | |
D7500 | เป้าหมาย (ในคลิปตั้ง 5 ตัว) | |
M10 | Target Achieved Flag ติดเมื่อ D0 ≥ D7500 | |
| เวลา | M8151 + TRD D10 | คัดลอก Real Time Clock ของ PLC ไปเริ่มที่ D10 (ชั่วโมง D13, นาที D14, วินาที D15) |
D23 D24 D25 | ชั่วโมง นาที วินาที ที่ตั้งให้ส่งสรุป (ตั้งจากหน้าจอได้) | |
M20 | End of Work ติดเมื่อ D13 = D23, D14 = D24 และ D15 = D25 |
พื้นฐาน HTTP
หน้าจอ IoT รองรับหลายโปรโตคอล หนึ่งในนั้นคือ HTTP (Hypertext Transfer Protocol) ที่ใช้กันแพร่หลายในโลกของเว็บ มีสองฝั่ง
- Client ผู้ส่งคำขอ (Request)
- Server คอมพิวเตอร์อีกเครื่องที่รอรับคำสั่งและส่งทรัพยากรกลับ
Request ที่ใช้บ่อยในหน้าจอมีสองแบบ
- GET ขอข้อมูลเฉยๆ ไม่ได้แนบอะไรไป
- POST แนบข้อมูลไปด้วย
ในงานนี้หน้าจอเป็น HTTP Client ส่ง POST ไปที่ Server ของ Telegram เพื่อบอกว่าจะสร้างข้อความอะไร Server ตอบกลับ (Response) พร้อม Status Code เช่น 200 ปกติดี, 404 ส่งไปตำแหน่งที่ไม่มีทรัพยากร, 500 Server มีปัญหา
1. ติดตั้ง Telegram และสร้าง Bot
- ดาวน์โหลดแอป Telegram ลงคอมพิวเตอร์ (desktop.telegram.org) หรือมือถือ
- ค้นหา @BotFather ตัวที่มีเครื่องหมายถูก (Verified) แล้วกด Start นี่คือจุดเริ่มต้นการขอ Token
- พิมพ์หรือกด
/newbot - ตั้งชื่อ Bot ในคลิปใช้
factonation-bot - ตั้ง Username ต้องลงท้ายด้วย
botและอาจซ้ำกับคนอื่นได้ (ในคลิปfactonation_botถูกใช้ไปแล้ว จึงเปลี่ยนเป็นfactonation_notify_bot) - BotFather จะส่ง Token มาให้ คัดลอกเก็บไว้
2. หา Chat ID ด้วย Postman
Chat ID คือแชทที่จะรับแจ้งเตือน หาได้ด้วย HTTP Client ตัวไหนก็ได้ ในคลิปใช้ Postman (ดาวน์โหลดจาก postman.com)
- สร้าง GET Request ไปที่ URL ตามคู่มือ Telegram โดยวาง Token ของท่านต่อท้ายคำว่า bot
https://api.telegram.org/bot<TOKEN>/getUpdates - กด Send ถ้าได้ Status 200 OK แปลว่า Token ปกติ แต่ยังไม่มี Chat ID เพราะยังไม่เคยแชท
- เปิดลิงก์
t.me/<username ของ Bot>ที่ BotFather ให้มา กด Start แล้วส่งข้อความอะไรก็ได้ เช่น Test - กลับมายิง Request เดิมอีกครั้ง จะได้ข้อมูล JSON กลับมา หา
chat→idแล้วคัดลอกเก็บไว้
3. ทดสอบส่งข้อความใน Postman
URL ส่งข้อความใช้ Token เหมือนเดิม แต่ลงท้ายด้วย sendMessage แทน getUpdates และต้องระบุสองอย่างคือ Chat ID กับข้อความ (text)
- สร้าง Request ใหม่ เปลี่ยนจาก GET เป็น POST
https://api.telegram.org/bot<TOKEN>/sendMessage - แท็บ Body เลือก raw ชนิด JSON แล้วเขียน
{ "chat_id": "<CHAT_ID>", "text": "Test" } - กด Send ถ้าปกติจะได้ Response
"ok": trueและ Notification เด้งขึ้นใน Telegram
ถ้าทดสอบใน Postman ผ่าน การทำในหน้าจอจะเร็วมาก
4. ตั้ง HTTP Request ใน SKTool
ดับเบิลคลิก HTTP ใต้ System Setting ทางซ้าย แล้วกด New ในส่วน Request
แท็บ General
Name: post-request
Website: https://api.telegram.org/bot<TOKEN>/sendMessage
Mode: POST
Time out: 2000 ms
Encode: UTF-8
Header: Content-Type:application/json
Format: Json (Advance)
Send mode: Bit trigger Address: LB0 OFF->ON ติ๊ก Automatic reset
- ตั้ง Time out ให้สูงหน่อย ประมาณ 2000 ms
- อย่าลืม Header
Content-Type:application/jsonไม่อย่างนั้น Server จะไม่รู้ว่าข้อมูลที่ส่งไปเป็น JSON
แท็บ Send Json — คลิก Payload แล้วกด Add Value
chat_id— Data type String, Bytes 10, Data = Constant ใส่ Chat ID ที่คัดลอกมา (ในคลิปเป็นตัวเลข 10 หลัก ป้อนเป็นตัวอักษร)text— Data type String, Bytes 100 (เผื่อข้อความยาว), Data = AddressLW0
แท็บ Receive Json — Add Value ชื่อ ok Data type bool, Data = Address LB1 เพื่อเก็บสถานะ ok ที่ Server ตอบกลับ
เท่านี้ HTTP Request ก็พร้อมใช้ เมื่อ LB0 เปลี่ยนจาก OFF เป็น ON หน้าจอจะส่งข้อความใน LW0 ไปที่ Telegram
5. หน้าจอและ Script
บนหน้าจอในคลิปมีปุ่มเชื่อมต่อ Wi-Fi (Function Button → Network settings) แสดงสถานะ M0, M1, M2 จาก PLC ฝั่งซ้าย ส่วนฝั่งขวามีปุ่มทดสอบ LB0 (Trigger Send HTTP POST) ช่องข้อความ LW0 และ Bit Lamp LB1 (ok จาก HTTP Response)
ตัวแปร PLC ที่ใช้ใน Script (เช่น M10, D7500) สร้างไว้ใน Variable Setting ส่วน D0 สร้างเป็น Global variable เพราะใช้หลาย Script ถ้ายังไม่คล่องเรื่อง Script ดูได้ในซีรีส์ Complete HMI
ฟังก์ชันช่วย (Sub script)
สองฟังก์ชันนี้เขียนเองในภาษา C ต้องสร้างเป็น Sub script ก่อน แล้วค่อย #include ใน Script หลัก ถ้าเรียกใช้เลยโดยไม่สร้างจะ Compile ไม่ผ่าน
clearArray ล้างข้อมูล 100 Word เริ่มต้นก่อนเขียนข้อความใหม่
void clearArray(short unsigned* array)
{
int i;
for (i = 0; i < 100; ++i)
{
array[i] = 0; // Set each element to 0
}
}
appendShortToString ต่อค่าตัวเลขเข้าท้ายข้อความ
#include "MacroInit.h"
void appendShortToString(char string[], short number)
{
char numberString[6]; // Enough for a short and null-terminator
sprintf(numberString, "%d", number);
strcat(string, numberString);
}
Init Script — ข้อความเริ่มต้น
#include "MacroInit.h"
//#include "subFun1.c" //Example
void Macro_main(IN *p)
{
MarcoInit
char* message = "Default Message";
memcpy((char*)&LocalWord[0], message, strlen(message));
}Trigger Script 1 — Alarm (M0 OFF→ON)
#include "MacroInit.h"
//#include "subFun1.c" //Example
#include "clearArray.c"
void Macro_main(IN *p)
{
MarcoInit
if (M0 == 1)
{
clearArray(&LocalWord[0]);
char* message = "Default Error";
if (M1 == 1)
{
message = "Machine Breakdown Error";
}
else if (M2 == 1)
{
message = "No Material Error";
}
memcpy((char*)&LocalWord[0], message, strlen(message));
LocalBit[0] = 1;
}
}ล้างข้อความ เลือกข้อความตาม M1 หรือ M2 คัดลอกไปที่ LW0 แล้วสั่ง LB0 ติดเพื่อยิง Request
Trigger Script 2 — Target Achieved (M10 OFF→ON)
#include "MacroInit.h"
//#include "subFun1.c" //Example
#include "appendShortToString.c"
#include "clearArray.c"
void Macro_main(IN *p)
{
MarcoInit
if (M10 == 1)
{
clearArray(&LocalWord[0]);
short actual = D0;
short target = D7500;
char message[] = "Target Achieved: ";
appendShortToString(message, D0);
strcat(message, " of ");
appendShortToString(message, D7500);
memcpy((char*)&LocalWord[0], message, strlen(message));
LocalBit[0] = 1;
}
}Trigger Script 3 — Schedule Report (M20 OFF→ON)
#include "MacroInit.h"
//#include "subFun1.c" //Example
#include "appendShortToString.c"
#include "clearArray.c"
void Macro_main(IN *p)
{
MarcoInit
if (M20 == 1)
{
clearArray(&LocalWord[0]);
short actual = D0;
char message[] = "Current Actual: ";
appendShortToString(message, D0);
memcpy((char*)&LocalWord[0], message, strlen(message));
LocalBit[0] = 1;
}
}ผูก Script กับเหตุการณ์
- Init Script:
Init - Trigger Script (Trigger mode = Address trigger, เงื่อนไข OFF->ON)
| Script | Address |
|---|---|
| Alarm | M0 |
| TargetAchieved | M10 |
| ScheduleReport | M20 |
แนวคิดเดียวกันทุก Script คือเอาข้อมูลมาต่อเป็นข้อความใน LW0 แล้วเปลี่ยน Local Bit 0 จาก 0 เป็น 1 เพื่อส่ง Notification
สรุป
ถ้ามีพื้นฐานโปรโตคอลมาตรฐานอย่าง HTTP หรือ MQTT เมื่อบริการหนึ่งประกาศปิดตัวอย่าง LINE Notify ก็ย้ายไปใช้บริการหรือ API ของเจ้าอื่นได้เอง
บทถัดไป
OPC Server คืออะไร
มีคำถาม? ติดต่อทีมงาน

