شروع به کار #
آشنایی با MQTT #
MQTT یک پروتکل ارتباطی سبک مبتنی بر publish-subscribe هست که برای دستگاههای IoT بسیار مناسب است. برای اطلاعات بیشتر در رابطه با پروتکل MQTT به سایت mqtt.org مراجعه فرمایید. پلتفرم ویرالینک به عنوان یک سرور MQTT (Broker) عمل میکند.
نصب کتابخانههای MQTT #
برای اتصال به سرورهای MQTT پلتفرم ویرالینک، شما نیاز به کتابخانههای سمت کاربر (MQTT Client Libraries) دارید. بسته به بستری که در آن کار میکنید کتابخانههای متعددی وجود دارد که میتوانید به سادگی پیدا کنید. در مثالهای این مستندات از کتابخانه Mosquitto و MQTT.js استفاده میشود. برای نصب این ابزار ها میتوانید به بخش شروع به کار با ویرالینک مراجعه فرمایید.
وصل شدن به MQTT #
ما برای اتصال به MQTT از توکن دسترسی (access token) استفاده خواهیم کرد که جلوتر در مثالها ACCESS_TOKEN$ مینامیم. برنامههایی که میخواهند به MQTT متصل شوند بایستی به جای username توکن دسترسی خود یعنی ACCESS_TOKEN$ قرار دهند. همچنین در صورت تمایل میتوانید به جای توکن از Basic MQTT Credentials استفاده نمایید که شامل id, username و password می باشد.
مقادیری که ممکن در هنگام اتصال باز گردانده شود:
- 0x00 Connected – با موفقیت به سرور MQTT پلتفرم وصل شد.
- 0x04 Connection Refused, bad user name or password – username خالی است.
- 0x05 Connection Refused, not authorized – توکن دسترسی غیر معتبر است.
فرمت کلید-مقدار (Key-value format) #
به صورت پیشفرض ویرالینک محتوای کلید-مقدار در قالب json را پشتیبانی میکند. کلید همیشه به صورت یک رشته متن (String) بوده و نام صفت را مشخص میکند. مقدار یک صفت میتواند شامل string (رشته), boolean (منطقی), double (عدد اعشاری) , integer (عدد صحیح) و یا json باشد. برای مثال:
{
"stringKey":"value1",
"booleanKey":true,
"doubleKey":42.0,
"longKey":73,
"jsonKey": {
"someNumber": 42,
"someArray": [1,2,3],
"someNestedObject": {"key": "value"}
}
}
در صورت تمایل میتوانید از Protocol Buffers برای ارسال دادهها استفاده کنید. برای پیکربندی به قسمت MQTT transport type در مستندات پروفایلهای دستگاه مراجعه بفرمایید.
API ارسال داده های سری زمانی #
برای ارسال دادههای سری زمانی به سرور کافیست پیام PUBLISH را به تاپیک زیر ارسال کنید.
v1/devices/me/telemetry
سادهترین شکل فرمت دادهها
{"key1":"value1", "key2":"value2"}
یا
[{"key1":"value1"}, {"key2":"value2"}]
توجه داشته باشید که در هنگام دریافت پیام به صورت پیشفرض زمان timestamp لحظه دریافت پیام در سرور ثبت خواهد شد. در صورتی که بخواهید زمان timestamp دلخواه خود و یا دستگاه را برای پیام مد نظر ثبت کنید میتوانید آن را با فرمت زیر ارسال نمایید.
{"ts":1451649600512, "values":{"key1":"value1", "key2":"value2"}}
در مثال بالا مقدار 1451649600512 زمان timestamp در واحد میلی ثانیه است. بنابراین این زمان معادل است با Fri, 01 Jan 2016 12:00:00.512 GMT.
{
"ts": 1451649600512,
"values": {
"stringKey": "value1",
"booleanKey": true,
"doubleKey": 42.0,
"longKey": 73,
"jsonKey": {
"someNumber": 42,
"someArray": [1, 2, 3],
"someNestedObject": {
"key": "value"
}
}
}
}
[{"key1":"value1"}, {"key2":true}]
{
"stringKey": "value1",
"booleanKey": true,
"doubleKey": 42.0,
"longKey": 73,
"jsonKey": {
"someNumber": 42,
"someArray": [1,2,3],
"someNestedObject": {"key": "value"}
}
}
# Publish data as an object without timestamp (server-side timestamp will be used)
mqtt pub -v -q 1 -h "console.viralink.ir" -t "v1/devices/me/telemetry" -u '$ACCESS_TOKEN' -s -m "{"temperature":42}"
# Publish data as an object without timestamp (server-side timestamp will be used)
cat telemetry-data-as-object.json | mqtt pub -v -h "console.viralink.ir" -t "v1/devices/me/telemetry" -u '$ACCESS_TOKEN' -s
# Publish data as an array of objects without timestamp (server-side timestamp will be used)
cat telemetry-data-as-array.json | mqtt pub -v -h "console.viralink.ir" -t "v1/devices/me/telemetry" -u '$ACCESS_TOKEN' -s
# Publish data as an object with timestamp (telemetry timestamp will be used)
cat telemetry-data-with-ts.json | mqtt pub -v -h "console.viralink.ir" -t "v1/devices/me/telemetry" -u '$ACCESS_TOKEN' -s
# Publish data as an object without timestamp (server-side timestamp will be used)
mosquitto_pub -d -q 1 -h "console.viralink.ir" -t "v1/devices/me/telemetry" -u "$ACCESS_TOKEN" -m "{"temperature":42}"
# Publish data as an object without timestamp (server-side timestamp will be used) using data from file
mosquitto_pub -d -q 1 -h "console.viralink.ir" -t "v1/devices/me/telemetry" -u "$ACCESS_TOKEN" -f "telemetry-data-as-object.json"
# Publish data as an array of objects without timestamp (server-side timestamp will be used) using data from file
mosquitto_pub -d -q 1 -h "console.viralink.ir" -t "v1/devices/me/telemetry" -u "$ACCESS_TOKEN" -f "telemetry-data-as-array.json"
# Publish data as an object with timestamp (telemetry timestamp will be used) using data from file
mosquitto_pub -d -q 1 -h "console.viralink.ir" -t "v1/devices/me/telemetry" -u "$ACCESS_TOKEN" -f "telemetry-data-with-ts.json"
API صفت ها #
به کمک API صفت ها میتوانید:
- ارسال صفتهای سمت کاربر (client-side attributes) به سرور
- درخواست مقادیر صفتهای سمت کاربر و مشترک (shared attributes) از سرور
- مشترک شدن (subscribe) به صفت های مشترک از سرور (تا در زمان تغییر صفتها در لحظه با خبر شوید).
ارسال صفتها به سرور #
برای ارسال صفتهای سمت کاربر (یا همان صفت های سمت دستگاه) به سرور کافیست پیام PUBLISH را به تاپیک زیر ارسال کنید.
v1/devices/me/attributes
{
"attribute1": "value1",
"attribute2": true,
"attribute3": 42.0,
"attribute4": 73,
"attribute5": {
"someNumber": 42,
"someArray": [1,2,3],
"someNestedObject": {"key": "value"}
}
}
# Publish client-side attributes update
cat new-attributes-values.json | mqtt pub -d -h "console.viralink.ir" -t "v1/devices/me/attributes" -u '$ACCESS_TOKEN' -s
# Publish client-side attributes update
mosquitto_pub -d -h "console.viralink.ir" -t "v1/devices/me/attributes" -u "$ACCESS_TOKEN" -m "{"attribute1": "value1", "attribute2": true}"
# Publish client-side attributes update from file
mosquitto_pub -d -h "console.viralink.ir" -t "v1/devices/me/attributes" -u "$ACCESS_TOKEN" -f "new-attributes-values.json"
API درخواست مقادیر صفتها از سرور #
برای درخواست مقادیر صفتهای سمت کاربر و یا صفتهای مشترک از سرور کافیست پیام PUBLISH را به تاپیک زیر ارسال کنید.
v1/devices/me/attributes/request/$request_id
request_id$ شناسه هر درخواست میباشد که سرور با همان شناسه به شما پاسخ خواهد داد.
توجه کنید که قبل از ارسال درخواست PUBLISH بایستی به تاپیک زیر مشترک شوید (subscribe کنید) تا پاسخها را دریافت نمایید.
v1/devices/me/attributes/response/+
در ادامه مثالی از ارسال درخواست و دریافت پاسخ آن از سمت سرور خواهیم داشت. توجه داشته باشید که مثال در زبان javascript نوشته شده است و مثال command-line آن وجود ندارد. به دلیل آنکه درخواست و پاسخ آن باید در یک session ارتباطی باشد.
{"key1":"value1"}
var mqtt = require('mqtt')
var client = mqtt.connect('mqtt://console.viralink.ir',{
username: process.env.TOKEN
})
client.on('connect', function () {
console.log('connected')
client.subscribe('v1/devices/me/attributes/response/+')
client.publish('v1/devices/me/attributes/request/1', '{"clientKeys":"attribute1,attribute2", "sharedKeys":"shared1,shared2"}')
})
client.on('message', function (topic, message) {
console.log('response.topic: ' + topic)
console.log('response.body: ' + message.toString())
client.end()
})
export TOKEN=$ACCESS_TOKEN
node mqtt-js-attributes-request.js
توجه کنید که صفتهای سمت کاربر، مشترک و حتی صفتهای سرور، میتوانند کلیدهایی با نام یکسان داشته باشند. اما توصیه میشود از تشابه نام کلیدها اجتناب کنید.
مشترک شدن (Subscribe) به بروزرسانی های صفت های مشترک #
برای مشترک شدن (subscribe) به مقادیر صفتهای مشترک از سرور کافیست پیام SUBSCRIBE را به تاپیک زیر ارسال کنید.با این کار هنگام تغییر مقادیر صفتها در همان لحظه به شما اطلاع داده میشود.
v1/devices/me/attributes
زمانیکه که مقدار یک صفت مشترک توسط برنامههای سرور (از قبیل REST API یا زنجیره قواعد) تغییر پیدا کند، کاربر یا همان برنامه دستگاه در فرمت زیر آن تغییرات را دریافت خواهد کرد.
{"key1":"value1"}
# Subscribes to attribute updates
mqtt sub -v "console.viralink.ir" -t "v1/devices/me/attributes" -u '$ACCESS_TOKEN'
# Subscribes to attribute updates
mosquitto_sub -d -h "console.viralink.ir" -t "v1/devices/me/attributes" -u "$ACCESS_TOKEN"
RPC API #
RPC سمت سرور (Server-side RPC) #
RPCهای سمت سرور دستورات RPC درخواستی از سمت سرور هستند که به دستگاه ارسال میشوند. دستگاه بایستی پس از اجرای دستورات نتیجه آن را به سرور ارسال کند.
برای مشترک شدن (subscribe) دستورات RPC از سرور کافیست پیام SUBSCRIBE را به تاپیک زیر ارسال کنید. با این کار دستورات RPC درخواستی از سمت سرور را در همان لحظه دریافت خواهید کرد.
v1/devices/me/rpc/request/+
پس از مشترک شدن (subscribe) کاربر، دستورات RPC درخواستی که به تاپیک زیر به عنوان پیام PUBLISH ارسال شده اند، را دریافت خواهد کرد.
v1/devices/me/rpc/request/$request_id
پارامتر request_id$ شناسه درخواست میباشد که کاربر (برنامه / firmware دستگاه) بایستی با همان شناسه و به تاپیک زیر پاسخ دهد.
v1/devices/me/rpc/response/$request_id
در ادامه مثالی از دریافت درخواست و ارسال پاسخ آن از سمت خواهیم داشت. توجه داشته باشید که مثال در زبان javascript نوشته شده است و مثال command-line آن وجود ندارد. به دلیل آنکه درخواست و پاسخ آن باید در یک session ارتباطی باشد.
var mqtt = require('mqtt');
var client = mqtt.connect('mqtt://console.viralink.ir',{
username: process.env.TOKEN
});
client.on('connect', function () {
console.log('connected');
client.subscribe('v1/devices/me/rpc/request/+')
});
client.on('message', function (topic, message) {
console.log('request.topic: ' + topic);
console.log('request.body: ' + message.toString());
var requestId = topic.slice('v1/devices/me/rpc/request/'.length);
//client acts as an echo service
client.publish('v1/devices/me/rpc/response/' + requestId, message);
});
export TOKEN=$ACCESS_TOKEN
node mqtt-js-rpc-from-server.js
RPC سمت کاربر (Client-side RPC) #
RPC های سمت کاربر دستورات RPC درخواستی از سمت دستگاه هستند که به سرور ارسال می شود. برنامههای سرور پس از پردازش آن نتیجه را به دستگاه باز می گردانند.
برای ارسال دستورات RPC به سرور کافیست پیام PUBLISH را به تاپیک زیر ارسال کنید.
v1/devices/me/rpc/request/$request_id
request_id$ شناسه هر درخواست میباشد که سرور با همان شناسه به شما پاسخ خواهد داد.
توجه کنید که قبل از ارسال درخواست PUBLISH بایستی به تاپیک زیر مشترک شوید (subscribe کنید) تا پاسخ ها را دریافت نمایید.
v1/devices/me/rpc/response/$request_id
در ادامه مثالی از ارسال دستور RPC به سرور و دریافت نتیجه آن از سمت سرور را خواهیم داشت. توجه داشته باشید که مثال در زبان javascript نوشته شده است و مثال command-line آن وجود ندارد. به دلیل آنکه درخواست و پاسخ آن باید در یک session ارتباطی باشد.
var mqtt = require('mqtt');
var client = mqtt.connect('mqtt://console.viralink.ir', {
username: process.env.TOKEN
});
client.on('connect', function () {
console.log('connected');
client.subscribe('v1/devices/me/rpc/response/+');
var requestId = 1;
var request = {
"method": "getTime",
"params": {}
};
client.publish('v1/devices/me/rpc/request/' + requestId, JSON.stringify(request));
});
client.on('message', function (topic, message) {
console.log('response.topic: ' + topic);
console.log('response.body: ' + message.toString());
});
export TOKEN=$ACCESS_TOKEN
node mqtt-js-rpc-from-client.js
درخواست تخصیص دستگاه #
در صورتی که با ویژگی تخصیص خودکار دستگاه آشنایی ندارید، ابتدا آن را مطالعه بفرمایید.
برای درخواست تخصیص دستگاه پیام PUBLISH را به تاپیک زیر ارسال نمایید.
v1/devices/me/claim
فرمت پشتیانی شده برای محتوای پیام
{"secretKey":"value", "durationMs":60000}
توجه نمایید که فیلدهای بالا اختیاری است. در صورتی که secretKey در پیام وجود نداشته باشد، یک رشته متن (string) خالی به عنوان مقدار پیشفرض ارسال میشود و همچنین در صورتی که durationMs وجود نداشته باشد، مقدار پیشفرض device.claim.duration استفاده خواهد شد.