Evotech Newlife Doc


คำ ความหมาย (test)
Brain evotech application
Device อุปกรณ์ต่าง ๆ ของบริษัท evotech เช่น dimmer, switch, ม่าน และ เครื่องปรับอากาศ
MQTT การเชื่อมต่อผ่าน protocol MQTT ซึ่งในบริบทของระบบ evotech คือโปรแกรม mosquitto
App โปรแกรมภายนอกที่ต้องการเชื่อมต่อกับ Brain เพื่อควบคุมการทำงานของ device

การเชื่อมต่อ

Brain จะมีการ broadcast message แบบ UDP ไปยัง multicast network interface ของ router (เช่น 192.168.1.255) โดยในเนื้อของ message คือ mac address ของ brain ทำให้ทุกอุปกรณ์ที่ต่อ router ตัวเดียวกันสามารถรู้ IP address ของ brain ได้จากการอ่าน message นี้

จากนั้น app ต้องต่อ MQTT มาที่ IP address ของ brain ที่ port 1883 ด้วย user และ password ที่กำหนด วิธีที่ app เชื่อมต่อกับ brain ผ่าน MQTT จะมี 2 ลักษณะ คือ

  1. Request / Response ทำงานในลักษณะที่ app ส่ง message สั่งการ brain แล้ว brain ส่ง message ตอบกลับ แบบ 1 ต่อ 1 เช่น การสั่งเปิดไฟและการสั่ง list devices
  2. Broadcast ทำงานในลักษณะที่เกิด event จาก device หรือตัว brain เอง แล้ว brain ส่ง message บอก app โดย app ไม่ต้องขอ เช่น ความสว่างของหลอดไฟเปลี่ยน (เพราะคนปรับด้วย physical switch) หรือ device ขาดการติดต่อกับ brain

การส่งข้อมูลผ่าน MQTT จะใช้ topic naming convention ในลักษณะ direction/source/clientId/refCode โดยแต่ละส่วนมีความหมายดังนี้

คำ ความหมาย
direction ประเภทของ message ได้แก่ evoRequest, evoResponse และ evoBroadcast
source ประเภทของผู้เริ่มก่อให้เกิด operation ได้แก่ local สำหรับการส่งคำสั่งในวง LAN และ internet สำหรับการส่งคำสั่งผ่าน cloud server
clientId รหัส client ซึ่งรหัสนี้ถูกกำหนดโดย app
refCode รหัสอ้างอิง ใช้ภายใน app เอง เพื่อให้รู้ว่าการที่ระบบตอบกลับ เป็นการตอบ request ครั้งใด

เช่น การส่งคำสั่งเปิดหลอดไฟ (dimmer) โดยผ่าน router ในบ้าน จะส่งคำสั่งไปที่ topic evoRequest/local/client001 /ref001 และระบบจะรายงานผลคำสั่งไปที่ topic evoResponse/local/client001/ref001 และทันทีที่ dimmer ทำงาน dimmer จะแจ้งสถานะล่าสุดกลับมาให้ brain ทราบ และ brain ก็จะ broadcast การเปลี่ยนสถานะของ dimmer ผ่าน topic evoBroadcast ต่อไป (ไม่มี part /local/clientId/refCode เนื่องจากเป็น event ที่เกิดจาก dimmer ไม่ใช่ app)

ภาพรวมคำสั่ง (ไม่อธิบายซ้ำใน section ถัดไป)

Request

  • ทุก request จะมี header ซึ่งใน header จะมี token เป็น JSON Web Token (JWT) สำหรับตรวจสอบสิทธิ์ของผู้สั่ง ซึ่งในปัจจุบันระหว่างการทำ PoC จะยังไม่มีการตรวจสอบ field นี้ แต่ app ยังจำเป็นต้องส่ง อาจส่งเป็น empty string ก็ได้
  • hwAddr คือ mac address ของ device เปรียบเสมือน key หรือชื่อที่ระบบใช้อ้างอิง

Response

โดยปกติ request แต่ละประเภทจะมี response แตกต่างกันออกไป แต่ในบางกรณีที่เกิดข้อผิดพลาด brain อาจตอบ error response มาตรฐานต่อไปนี้ได้ โดยระบบจะส่ง response กลับไปที่ topic evoResponse/local/clientId/refCode

ข้อผิดพลาด: คำสั่งผิด

เช่น ส่ง JSON ผิด format

{
  "type": "BAD_INPUT",
  "message": "Cannot deserialize value of type ..."
}

ข้อผิดพลาด: ระบบไม่รองรับคำสั่ง

เช่น ช่วง PoC อาจยังเปิด feature ไม่ครบ

{
  "type": "UNSUPPORTED"
}

ข้อผิดพลาด: timeout

เช่น device ทำงานไม่ทัน แล้ว drop message หรือ มี app การอ้างถึง device ที่ไม่มีอยู่ในระบบ (จึงไม่มี device ใดตอบ) โดยปกติ brain จะตั้งการ timeout ไว้ที่ 5 วินาที

{
  "type": "TIMEOUT"
}

ประเภทข้อมูลมาตรฐาน (ทั่วไป)

type ค่าที่เป็นไปได้
Power ON, OFF และ DO_NOT_CHANGE
Air Con Instruction Type NORMAL (สำหรับ device ที่สั่งงานตรง) และ IR_BOX (สำหรับ device ที่สั่งงานผ่านกล่อง infrared)
Fan Speed AUTO, HIGH, MED, LOW และ DO_NOT_CHANGE
AC Mode FAN, COOL, DRY, HEAT, AUTO และ DO_NOT_CHANGE
Sweep Status ON, OFF, CHAR8 และ DO_NOT_CHANGE
Motor Status STOP, UP, DOWN และ DO_NOT_CHANGE
Percentage 0 ถึง 100 เป็นจำนวนเต็มเท่านั้น
Temperature 15.0 ถึง 30.0 เป็นทศนิยม 1 ตำแหน่งเพิ่มลดทีละ 0.5
Decisecond ความยาว 1 ใน 10 ส่วนของวินาที เช่น 20 deciseconds คือ 2 วินาที

DeviceControlResult

มีได้ 4 รูปแบบ ได้แก่ SUCCESSFUL, DROPPED, CANCELED และ FAILED

SUCCESSFUL

คือ device ทำงานตามคำสั่งสำเร็จด้วยดี

{
  "type": "SUCCESSFUL"
}

DROPPED

คือ brain เลือกที่จะไม่ทำคำสั่งนี้ เพื่อป้องกัน device ทำงานไม่ทัน เช่น user เลื่อนแถบความสว่างจาก 0 ถึง 100 ในเวลา 2 วินาที กรณีนี้ brain จะ drop บางคำสั่งที่อยู่ตรงกลางระหว่าง 0 - 100

{
  "type": "DROPPED"
}

CANCELED

คือ brain ยกเลิกคำสั่ง เนื่องจากมีคำสั่งอื่นที่ priority สูงกว่าแทรกเข้ามา (กรณีนี้ยังไม่มีการใช้ระหว่าง PoC)

{
  "type": "CANCELED"
}

FAILED

{
  "type": "FAILED",
  "errorCode": ""
}

Device

มี 5 ประเภท แต่ในขั้นตอน PoC มี 4 ประเภท ได้แก่ dimmer, switch, air con และ curtain

Dimmer

{
  "type": "DIMMER",
  "power": "OFF",
  "brightness": 0
}

Switch

{
  "type": "SWITCH",
  "power": "OFF"
}

Air Con

{
  "type": "AIRCON",
  "power": "ON",
  "fanSpeed": "HIGH",
  "acMode": "COOL",
  "sweepStatus": "OFF",
  "settingTemp": 18.0,
  "roomTemp": 31.0
}

Curtain

{
  "type": "CURTAIN",
  "motorStatus": "STOP"
}

รายละเอียดคำสั่งแบบ Request / Response

app ต้องส่ง message (request) ไปที่ topic evoRequest/source/clientId/refCode และ ระบบจะตอบ (response) ไปที่ topic evoResponse/source/clientId/refCode

โดย source คือ "local" สำหรับการส่ง MQTT message ในวง LAN และ "internet" สำหรับการส่ง MQTT message ผ่าน cloud server ส่วน clientId และ refCode app เป็นผู้กำหนดการใช้งานเอง

แสดงข้อมูล place

Request

Field Type Value (only if fixed) Description
$.type fixed "PLACE_GET"
ตัวอย่าง
{
  "type": "PLACE_GET",
  "header": {
    "token": "JWT"
  }
}

Response

Field Type Value (only if fixed) Description
$.type fixed "PLACE_GET"
$.placeInfo.id UUID identity ของ place
$.placeInfo.hwAddr string mac address ของกล่อง brain
$.placeInfo.name string ชื่อที่ผู้ใช้ตั้ง
ตัวอย่าง
{
  "type": "PLACE_GET",
  "placeInfo": {
    "id": "7c5caeb4-ed9c-480f-8479-bbc735004653",
    "hwAddr": "020180590B00",
    "name": "Evotech Office"
  }
}

แสดงรายการข้อมูล zone

Request

Field Type Value (only if fixed) Description
$.type fixed "ZONE_LIST"
ตัวอย่าง
{
  "type": "ZONE_LIST",
  "header": {
    "token": "JWT"
  }
}

Response

Field Type Value (only if fixed) Description
$.type fixed "ZONE_LIST"
$.zoneInfos.id UUID identity ของ zone
$.zoneInfos.name string ชื่อที่ผู้ใช้ตั้ง
$.zoneInfos.deviceHwAddrs [ HwAddr ] device ใน zone
ตัวอย่าง
{
  "type": "ZONE_LIST",
  "zoneInfos": [
    {
      "id": "21681f11-eb36-49e6-84ec-49c6a77edef6",
      "name": "Basement",
      "deviceHwAddrs": ["5CCF7F09D1C4", "5CCF7F363137", "5CCF7F362A3A"]
    }
  ]
}

แสดงรายการข้อมูล scene

Request

Field Type Value (only if fixed) Description
$.type fixed "SCENE_LIST"
ตัวอย่าง
{
  "type": "SCENE_LIST",
  "header": {
    "token": "JWT"
  }
}

Response

Field Type Value (only if fixed) Description
$.type fixed "SCENE_LIST"
$.sceneInfos.id UUID identity ของ scene
$.sceneInfos.name string ชื่อที่ผู้ใช้ตั้ง
$.sceneInfos.zoneId string zone ที่ scene นี้อยู่
ตัวอย่าง
{
  "type": "SCENE_LIST",
  "sceneInfos": [
    {
      "id": "12a68df3-eedb-4791-aa75-faa64e89066c",
      "name": "All On",
      "zoneId": "21681f11-eb36-49e6-84ec-49c6a77edef6"
    },
    {
      "id": "dde66f7d-0cbb-4477-b603-b46c8f08d450",
      "name": "All Off",
      "zoneId": "21681f11-eb36-49e6-84ec-49c6a77edef6"
    },
    {
      "id": "0719464e-008a-4b2f-b129-d95a475e332a",
      "name": "Bedtime",
      "zoneId": null
    },
    {
      "id": "66ff6bf6-9d69-4bc1-89b0-ce8c1e74ee19",
      "name": "Zone 1 - Movie Time",
      "zoneId": "21681f11-eb36-49e6-84ec-49c6a77edef6"
    }
  ]
}

แสดงรายการข้อมูล device

Request

Field Type Value (only if fixed) Description
$.type fixed "DEVICE_LIST"
ตัวอย่าง
{
  "type": "DEVICE_LIST",
  "header": {
    "token": "JWT"
  }
}

Response

Field Type Value (only if fixed) Description
$.type fixed "DEVICE_LIST"
$.deviceInfos.hwAddr string mac address ของอุปกรณ์
$.deviceInfos.name string ชื่อที่ผู้ใช้ตั้ง
$.deviceInfos.alive boolean ยังติดต่อกับ brain ได้หรือไม่
$.deviceInfos.lastSeen timestamp เวลาครั้งล่าสุดที่ device มีการตอบสนองกับ brain
$.deviceInfos.device device รายละเอียด device (มีหลายประเภท)
ตัวอย่าง
{
  "type": "DEVICE_LIST",
  "deviceInfos": [
    {
      "hwAddr": "5CCF7F362A3A",
      "name": "Dimmer 1",
      "alive": true,
      "lastSeen": "2020-12-03T07:31:04.021Z",
      "device": {
        "type": "DIMMER",
        "power": "OFF",
        "brightness": 0
      }
    },
    {
      "hwAddr": "5CCF7F09CC8B",
      "name": "แอร์ตัวหลัก",
      "alive": true,
      "lastSeen": "2020-12-03T07:31:04.094Z",
      "device": {
        "type": "AIRCON",
        "power": "ON",
        "fanSpeed": "HIGH",
        "acMode": "COOL",
        "sweepStatus": "OFF",
        "settingTemp": 18.0,
        "roomTemp": 31.0
      }
    }
  ]
}

ควบคุม dimmer

Request

Field Type Value (only if fixed) Description
$.type fixed "DEVICE_CONTROL"
$.control.type fixed "DIMMER"
$.control.power power
$.control.brightness percentage ความสว่างของ dimmer
$.control.duration decisecond เวลาที่ใช้ในการปรับความสว่างจาก ความสว่างเดิมไปยังความสว่างใหม่ (เปลี่ยนช้า ๆ)
ตัวอย่าง
{
  "type": "DEVICE_CONTROL",
  "header": {
    "token": "JWT"
  },
  "control": {
    "type": "DIMMER",
    "hwAddr": "5CCF7F36313E",
    "power": "ON",
    "brightness": 100,
    "duration": 20
  }
}

Response

Field Type Value (only if fixed) Description
$.type fixed "DEVICE_CONTROL"
$.result DeviceControlResult
ตัวอย่าง
{
  "type": "DEVICE_CONTROL",
  "result": {
    "type": "SUCCESSFUL"
  }
}

ควบคุม switch

Request

Field Type Value (only if fixed) Description
$.type fixed "DEVICE_CONTROL"
$.control.type fixed "SWITCH"
$.control.power power
ตัวอย่าง
{
  "type": "DEVICE_CONTROL",
  "header": {
    "token": "JWT"
  },
  "control": {
    "type": "SWITCH",
    "hwAddr": "000000000000",
    "power": "OFF"
  }
}

Response

Field Type Value (only if fixed) Description
$.type fixed "DEVICE_CONTROL"
$.result DeviceControlResult
ตัวอย่าง
{
  "type": "DEVICE_CONTROL",
  "result": {
    "type": "SUCCESSFUL"
  }
}

ควบคุมเครื่องปรับอากาศ (air con)

Request

Field Type Value (only if fixed) Description
$.type fixed "DEVICE_CONTROL"
$.control.type fixed "AIRCON"
$.control.instructionType air con instruction type
$.control.power power
$.control.settingTemp temperature
$.control.acMode AC mode
$.control.fanSpeed fan speed
ตัวอย่าง
{
  "type": "DEVICE_CONTROL",
  "header": {
    "token": "JWT"
  },
  "control": {
    "type": "AIRCON",
    "hwAddr": "5CCF7F09CC8B",
    "instructionType": "NORMAL",
    "power": "OFF",
    "settingTemp": 25,
    "acMode": "COOL",
    "fanSpeed": "AUTO"
  }
}

Response

Field Type Value (only if fixed) Description
$.type fixed "DEVICE_CONTROL"
$.result DeviceControlResult
ตัวอย่าง
{
  "type": "DEVICE_CONTROL",
  "result": {
    "type": "SUCCESSFUL"
  }
}

ควบคุมม่าน (curtain)

Request

Field Type Value (only if fixed) Description
$.type fixed "DEVICE_CONTROL"
$.control.type fixed "CURTAIN"
$.control.motorStatus motor status ไม่มีการสั่งว่าเปิดหรือปิดถึงจุดใด มีแค่สั่งเปิด ปิด และ หยุด
ตัวอย่าง
{
  "type": "DEVICE_CONTROL",
  "header": {
    "token": "JWT"
  },
  "control": {
    "type": "CURTAIN",
    "hwAddr": "DEVICE",
    "motorStatus": "STOP"
  }
}

Response

Field Type Value (only if fixed) Description
$.type fixed "DEVICE_CONTROL"
$.result DeviceControlResult
ตัวอย่าง
{
  "type": "DEVICE_CONTROL",
  "result": {
    "type": "SUCCESSFUL"
  }
}

ควบคุม scene

Request

Field Type Value (only if fixed) Description
$.type fixed "SCENE_RUN"
$.cmd.sceneId UUID scene ที่ต้องการควบคุม
$.cmd.mode scene run mode ON คือเล่น scene ตามที่ตั้งค่า, OFF คือปิดทุก device ที่มีการตั้งค่าใน scene, และ TOGGLE คือสลับสถานะ scene จาก ON เป็น OFF และ OFF เป็น ON
ตัวอย่าง
{
  "type": "SCENE_RUN",
  "header": {
    "token": "JWT"
  },
  "cmd": {
    "sceneId": "dde66f7d-0cbb-4477-b603-b46c8f08d450",
    "mode": "ON"
  }
}

Response

Field Type Value (only if fixed) Description
$.type fixed "DEVICE_CONTROL"
$.result.type scene run result มี 4 ประเภท ได้แก่ SUCCESSFUL (สำเร็จ), PARTIALLY_SUCCESSFUL (สำเร็จบางส่วน), NOT_FOUND (ไม่พบ scene) และ TIMEOUT (device ไม่ตอบสนอง)
ตัวอย่าง
{
  "type": "SCENE_RUN",
  "result": {
    "type": "SUCCESSFUL"
  }
}

รายละเอียดการ broadcast

กรณีที่ข้อมูล place มีการเปลี่ยนแปลง

Topic

ระบบจะ broadcast ไปที่ topic ชื่อ evoBroadcast/source/clientId/refCode โดยค่าของ source, clientId และ refCode ขึ้นอยู่กับว่าผู้ที่ทำให้เกิดการเปลี่ยนแปลงได้กระทำการจากช่องทางใด (เช่น เปลี่ยนชื่อ place ผ่าน evotech mobile app)

โครงสร้าง

Field Type Value (only if fixed) Description
$.type fixed "PLACE_INFO_UPDATED"
$.placeInfo.id UUID identity ของ place
$.placeInfo.hwAddr string mac address ของกล่อง brain
$.placeInfo.name string ชื่อที่ผู้ใช้ตั้ง

ตัวอย่าง

{
  "type": "PLACE_INFO_UPDATED",
  "placeInfo": {
    "id": "7c5caeb4-ed9c-480f-8479-bbc735004653",
    "hwAddr": "020180590B00",
    "name": "Evotech Office"
  }
}

กรณีที่ข้อมูล device มีการเปลี่ยนแปลง

Topic

ระบบจะ broadcast ไปที่ topic ชื่อ evoBroadcast ไม่มี part ที่เหลือ เนื่องจากเป็นการเปลี่ยนแปลงที่เกิดจากตัว device เอง

โครงสร้าง

Field Type Value (only if fixed) Description
$.type fixed "DEVICE_STATUS_UPDATED"
$.deviceInfo.name string ชื่อที่ผู้ใช้ตั้ง
$.deviceInfo.alive boolean ยังติดต่อกับ brain ได้หรือไม่
$.deviceInfo.lastSeen timestamp เวลาครั้งล่าสุดที่ device มีการตอบสนองกับ brain
$.deviceInfo.device device รายละเอียด device (มีหลายประเภท)

ตัวอย่าง

{
  "type": "DEVICE_STATUS_UPDATED",
  "deviceInfo": {
    "hwAddr": "5CCF7F362A3A",
    "name": "Dimmer 1",
    "alive": true,
    "lastSeen": "2020-12-03T07:40:10.291Z",
    "device": {
      "type": "DIMMER",
      "power": "ON",
      "brightness": 100
    }
  }
}

กรณีที่ device ขาดการติดต่อ

Topic

ระบบจะ broadcast ไปที่ topic ชื่อ evoBroadcast ไม่มี part ที่เหลือ เนื่องจากเป็นการเปลี่ยนแปลงที่เกิดจากตัว device เอง

โครงสร้าง

Field Type Value (only if fixed) Description
$.type fixed "NEW_DEAD_DEVICES"
$.hwAddrs [ HwAddr ] device ที่ขาดการติดต่อ

ตัวอย่าง

{
  "type": "NEW_DEAD_DEVICES",
  "hwAddrs": ["5CCF7F362A3A", "5CCF7F09CC8B"]
}

Landometer. Made with in Bangkok, Thailand.


© 2021 Alice. All Rights Reserved.