หน้าแรกคู่มือIoTสอนใช้ Telegram Notification กับ IoT HMI แทน Line Notify
IOTขั้นสูง · Advanced20 นาที

สอนใช้ 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

ชุดอุปกรณ์สำหรับบทความนี้

ราคาชุดอุปกรณ์

฿9,840

ทำไมต้อง Telegram

คลิปนี้ทำขึ้นเพราะ LINE Notify ประกาศยกเลิกบริการ มีผลตั้งแต่ 31 มีนาคม 2568 และให้ไปใช้ Messaging API แทน ซึ่งใช้ฟรีได้ระดับหนึ่ง ถ้าส่งข้อความเยอะอาจต้องเสียค่าใช้จ่าย ส่วน Telegram ณ ตอนทำคลิปยังส่ง Notification ได้ฟรีโดยไม่มีข้อจำกัด จึงเป็นทางเลือกที่ดี ตัวอย่างในคลิปคล้ายกับคลิป LINE Notification เดิม

ตัวอย่างที่ทำในคลิป

หน้าจอ IoT HMI 7 นิ้วต่อกับ PLC ที่จำลองเป็นเครื่องจักร ส่งแจ้งเตือน 3 กรณี

  1. Alarm / Error — เมื่อ PLC มี Error หน้าจอส่งชื่อ Error เข้า Telegram เช่น Machine Breakdown Error หรือ No Material Error
  2. ผลิตถึงเป้าหมาย — เมื่อยอดผลิตถึงเป้า ส่ง Target Achieved
  3. สรุปผลตามเวลา — เช่น ตั้งให้แจ้งทุก 8:00 น. หรือ 17:00 น. ตามกะการทำงาน ส่งจำนวนชิ้นที่ผลิตไปแล้ว

อุปกรณ์ที่ใช้

  • HMI: SK-070QE-G + WiFi Module (มี WiFi Module ให้มาด้วย ไม่มีพอร์ต LAN) ต่อกับ PLC ทาง COM2
  • PLC: FAs-32MT-AC-E
  • Postman สำหรับทดสอบ API

ฝั่ง PLC (จำลองเครื่องจักร)

ส่วนตำแหน่งหน้าที่
ErrorM0มี Error ค้างอยู่
M1Machine Breakdown
M2No Material
Y000Alarm Light ติดเมื่อ M0 กับ M1 หรือ M2 ติด
M200Reset Error (RST เริ่มที่ M0 จำนวน K3 คือ M0 ถึง M2)
ยอดผลิตM100Work Cycle เพิ่มค่า D0 ทีละ 1 (คำสั่ง INC แบบ P)
D0ยอดผลิตจริง (Actual)
D7500เป้าหมาย (ในคลิปตั้ง 5 ตัว)
M10Target Achieved Flag ติดเมื่อ D0 ≥ D7500
เวลาM8151 + TRD D10คัดลอก Real Time Clock ของ PLC ไปเริ่มที่ D10 (ชั่วโมง D13, นาที D14, วินาที D15)
D23 D24 D25ชั่วโมง นาที วินาที ที่ตั้งให้ส่งสรุป (ตั้งจากหน้าจอได้)
M20End 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

  1. ดาวน์โหลดแอป Telegram ลงคอมพิวเตอร์ (desktop.telegram.org) หรือมือถือ
  2. ค้นหา @BotFather ตัวที่มีเครื่องหมายถูก (Verified) แล้วกด Start นี่คือจุดเริ่มต้นการขอ Token
  3. พิมพ์หรือกด /newbot
  4. ตั้งชื่อ Bot ในคลิปใช้ factonation-bot
  5. ตั้ง Username ต้องลงท้ายด้วย bot และอาจซ้ำกับคนอื่นได้ (ในคลิป factonation_bot ถูกใช้ไปแล้ว จึงเปลี่ยนเป็น factonation_notify_bot)
  6. BotFather จะส่ง Token มาให้ คัดลอกเก็บไว้

2. หา Chat ID ด้วย Postman

Chat ID คือแชทที่จะรับแจ้งเตือน หาได้ด้วย HTTP Client ตัวไหนก็ได้ ในคลิปใช้ Postman (ดาวน์โหลดจาก postman.com)

  1. สร้าง GET Request ไปที่ URL ตามคู่มือ Telegram โดยวาง Token ของท่านต่อท้ายคำว่า bot
    https://api.telegram.org/bot<TOKEN>/getUpdates
  2. กด Send ถ้าได้ Status 200 OK แปลว่า Token ปกติ แต่ยังไม่มี Chat ID เพราะยังไม่เคยแชท
  3. เปิดลิงก์ t.me/<username ของ Bot> ที่ BotFather ให้มา กด Start แล้วส่งข้อความอะไรก็ได้ เช่น Test
  4. กลับมายิง Request เดิมอีกครั้ง จะได้ข้อมูล JSON กลับมา หา chat → id แล้วคัดลอกเก็บไว้

3. ทดสอบส่งข้อความใน Postman

URL ส่งข้อความใช้ Token เหมือนเดิม แต่ลงท้ายด้วย sendMessage แทน getUpdates และต้องระบุสองอย่างคือ Chat ID กับข้อความ (text)

  1. สร้าง Request ใหม่ เปลี่ยนจาก GET เป็น POST
    https://api.telegram.org/bot<TOKEN>/sendMessage
  2. แท็บ Body เลือก raw ชนิด JSON แล้วเขียน
    {
      "chat_id": "<CHAT_ID>",
      "text": "Test"
    }
  3. กด 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 = Address LW0

แท็บ 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 — ข้อความเริ่มต้น

Init
C · SKTool Macro
#include "MacroInit.h"
//#include "subFun1.c" //Example

void Macro_main(IN *p)
{
 MarcoInit
 char* message = "Default Message";

 memcpy((char*)&LocalWord[0], message, strlen(message));
}
ตำแหน่งข้อมูลที่ใช้
LW0

Trigger Script 1 — Alarm (M0 OFF→ON)

Alarm
C · SKTool Macro
#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;
  }
}
ตำแหน่งข้อมูลที่ใช้
M0M1M2LW0LB0

ล้างข้อความ เลือกข้อความตาม M1 หรือ M2 คัดลอกไปที่ LW0 แล้วสั่ง LB0 ติดเพื่อยิง Request

Trigger Script 2 — Target Achieved (M10 OFF→ON)

TargetAchieved
C · SKTool Macro
#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;
  }
}
ตำแหน่งข้อมูลที่ใช้
M10D0D7500LW0LB0

Trigger Script 3 — Schedule Report (M20 OFF→ON)

ScheduleReport
C · SKTool Macro
#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;
  }
}
ตำแหน่งข้อมูลที่ใช้
M20D0LW0LB0

ผูก Script กับเหตุการณ์

  • Init Script: Init
  • Trigger Script (Trigger mode = Address trigger, เงื่อนไข OFF->ON)
ScriptAddress
AlarmM0
TargetAchievedM10
ScheduleReportM20

แนวคิดเดียวกันทุก Script คือเอาข้อมูลมาต่อเป็นข้อความใน LW0 แล้วเปลี่ยน Local Bit 0 จาก 0 เป็น 1 เพื่อส่ง Notification

สรุป

ถ้ามีพื้นฐานโปรโตคอลมาตรฐานอย่าง HTTP หรือ MQTT เมื่อบริการหนึ่งประกาศปิดตัวอย่าง LINE Notify ก็ย้ายไปใช้บริการหรือ API ของเจ้าอื่นได้เอง

บทถัดไป

OPC Server คืออะไร

8 นาทีปานกลาง · Intermediate