Merge PR #396: New Plugin: Telegram
commit
7170f2b9bf
|
|
@ -693,6 +693,15 @@ Description: nymea.io plugin for Texas Instruments devices
|
|||
This package will install the nymea.io plugin for Texas Instruments devices
|
||||
|
||||
|
||||
Package: nymea-plugin-telegram
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends},
|
||||
nymea-plugins-translations,
|
||||
Description: nymea.io plugin for Telegram
|
||||
This plugin allows nymea to send messages to telegram via the bot API.
|
||||
|
||||
|
||||
Package: nymea-plugin-tplink
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends},
|
||||
|
|
@ -1128,6 +1137,7 @@ Depends: nymea-plugin-anel,
|
|||
nymea-plugin-lifx,
|
||||
nymea-plugin-mailnotification,
|
||||
nymea-plugin-texasinstruments,
|
||||
nymea-plugin-telegram,
|
||||
nymea-plugin-nanoleaf,
|
||||
nymea-plugin-netatmo,
|
||||
nymea-plugin-networkdetector,
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_integrationplugintelegram.so
|
||||
|
|
@ -57,6 +57,7 @@ PLUGIN_DIRS = \
|
|||
tado \
|
||||
tasmota \
|
||||
tcpcommander \
|
||||
telegram \
|
||||
texasinstruments \
|
||||
tplink \
|
||||
tuya \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
# Telegram
|
||||
|
||||
This plugin allows to send message to Telegram via the Telegram bot API.
|
||||
|
||||
https://core.telegram.org/bots/api
|
||||
|
||||
## Usage
|
||||
|
||||
In order to use the telegram plugin, a new bot must be created and the bot access token provided to nymea.
|
||||
|
||||
Instructions to create a telegram bot:
|
||||
|
||||
* Open a conversation to @BotFather
|
||||
|
||||
* Send the message `/newbot` to BotFather and follow the instructions until BotFather hands out the token for your bot.
|
||||
|
||||
* Now open a conversation to your bot and write it a message. The content of this message does not matter but it is important that at least one message has been sent to the bot in order for it to work.
|
||||
|
||||
* Alternatively, add the bot to a group chat and send a message to the group mentioning the bot with @<bot_name>. The content of this message does not matter as long as it contains a mention for the bot. This is required for the bot to see the message and allow nymea recognizing the group.
|
||||
|
||||
* Now return to nymea and set up a new telegram thing as usual, providing the token during the setup.
|
||||
|
|
@ -0,0 +1,182 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by
|
||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||
* reproduction, publication, editing and translation, are reserved. The use of
|
||||
* this project is subject to the terms of a license agreement to be concluded
|
||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||
* under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; version 3. This project is distributed in the hope that
|
||||
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "integrationplugintelegram.h"
|
||||
#include "plugininfo.h"
|
||||
|
||||
#include "network/networkaccessmanager.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
|
||||
IntegrationPluginTelegram::IntegrationPluginTelegram(QObject* parent): IntegrationPlugin (parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
IntegrationPluginTelegram::~IntegrationPluginTelegram()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void IntegrationPluginTelegram::discoverThings(ThingDiscoveryInfo *info)
|
||||
{
|
||||
QString token = info->params().paramValue(telegramDiscoveryTokenParamTypeId).toString();
|
||||
QUrl url(QString("https://api.telegram.org/bot%1/getUpdates").arg(token));
|
||||
QNetworkRequest request(url);
|
||||
QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
|
||||
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
|
||||
connect(reply, &QNetworkReply::finished, info, [=](){
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
qCWarning(dcTelegram()) << "Error fetching channels from telegram API:" << reply->error() << reply->errorString();
|
||||
info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("Error connecting to Telegram."));
|
||||
return;
|
||||
}
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(reply->readAll(), &error);
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcTelegram()) << "Error parsing JSON reply from telegram API:" << error.error << error.errorString();
|
||||
info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("Unexpected data from Telegram."));
|
||||
return;
|
||||
}
|
||||
if (!jsonDoc.toVariant().toMap().value("ok").toBool()) {
|
||||
qCWarning(dcTelegram()) << "Json reply doesn't contain OK" << qUtf8Printable(jsonDoc.toJson(QJsonDocument::Indented));
|
||||
info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("An error happened on the Telegram servers."));
|
||||
return;
|
||||
}
|
||||
QVariantList entries = jsonDoc.toVariant().toMap().value("result").toList();
|
||||
QList<int> addedChats;
|
||||
foreach (const QVariant &entry, entries) {
|
||||
QVariantMap messageMap = entry.toMap().value("message").toMap();
|
||||
int chatId = messageMap.value("chat").toMap().value("id").toInt();
|
||||
if (addedChats.contains(chatId)) {
|
||||
continue;
|
||||
}
|
||||
QString chatName = QString("%1 %2")
|
||||
.arg(messageMap.value("chat").toMap().value("first_name").toString())
|
||||
.arg(messageMap.value("chat").toMap().value("last_name").toString());
|
||||
QString type = messageMap.value("chat").toMap().value("type").toString();
|
||||
if (type == "group") {
|
||||
chatName = messageMap.value("chat").toMap().value("title").toString();
|
||||
}
|
||||
ThingDescriptor descriptor(telegramThingClassId, chatName, type == "group" ? "Group" : "Private");
|
||||
ParamList params;
|
||||
params << Param(telegramThingTokenParamTypeId, token);
|
||||
params << Param(telegramThingChatIdParamTypeId, chatId);
|
||||
descriptor.setParams(params);
|
||||
|
||||
Thing *existingThing = myThings().findByParams(params);
|
||||
if (existingThing) {
|
||||
descriptor.setThingId(existingThing->id());
|
||||
}
|
||||
addedChats.append(chatId);
|
||||
info->addThingDescriptor(descriptor);
|
||||
}
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
});
|
||||
}
|
||||
|
||||
void IntegrationPluginTelegram::setupThing(ThingSetupInfo *info)
|
||||
{
|
||||
Thing *thing = info->thing();
|
||||
|
||||
qCDebug(dcTelegram()) << "Setting up telegram chat" << thing->name() << thing->id().toString();
|
||||
|
||||
QString token = info->thing()->paramValue(telegramThingTokenParamTypeId).toString();
|
||||
// int chatId = info->thing()->paramValue(telegramThingChatIdParamTypeId).toInt();
|
||||
|
||||
QString url = QString("https://api.telegram.org/bot%1/getMe").arg(token);
|
||||
QNetworkRequest request(url);
|
||||
QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
|
||||
|
||||
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
|
||||
|
||||
connect(reply, &QNetworkReply::finished, info, [reply, info]() {
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
qCWarning(dcTelegram()) << "Error fetching user profile:" << reply->errorString() << reply->error();
|
||||
//: Error setting up thing
|
||||
info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("Error connecting to Telegram."));
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcTelegram()) << "Telegram" << info->thing()->name() << info->thing()->id().toString() << "setup complete";
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
});
|
||||
}
|
||||
|
||||
void IntegrationPluginTelegram::executeAction(ThingActionInfo *info)
|
||||
{
|
||||
Thing *thing = info->thing();
|
||||
Action action = info->action();
|
||||
|
||||
qCDebug(dcTelegram()) << "Executing action" << action.actionTypeId() << "for" << thing->name() << thing->id().toString();
|
||||
|
||||
QString token = info->thing()->paramValue(telegramThingTokenParamTypeId).toString();
|
||||
int chatId = info->thing()->paramValue(telegramThingChatIdParamTypeId).toInt();
|
||||
|
||||
QString title = action.paramValue(telegramNotifyActionTitleParamTypeId).toString();
|
||||
QString body = action.paramValue(telegramNotifyActionBodyParamTypeId).toString();
|
||||
QString message = title + "\n" + body;
|
||||
|
||||
QString url = QString("https://api.telegram.org/bot%1/sendMessage?chat_id=%2&text=%3").arg(token).arg(chatId).arg(message);
|
||||
|
||||
QNetworkRequest request(url);
|
||||
|
||||
QNetworkReply *reply = hardwareManager()->networkManager()->get(request);
|
||||
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
|
||||
connect(reply, &QNetworkReply::finished, info, [reply, info]{
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
qCWarning(dcTelegram()) << "Sending message failed for" << info->thing()->name() << info->thing()->id() << reply->errorString() << reply->error();
|
||||
emit info->finish(Thing::ThingErrorHardwareNotAvailable);
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray data = reply->readAll();
|
||||
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
qCWarning(dcTelegram()) << "Error reading reply from Telegram for" << info->thing()->name() << info->thing()->id().toString() << error.errorString();
|
||||
qCWarning(dcTelegram()) << qUtf8Printable(data);
|
||||
info->finish(Thing::ThingErrorHardwareFailure);
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap replyMap = jsonDoc.toVariant().toMap();
|
||||
if (!replyMap.value("ok").toBool()) {
|
||||
qCWarning(dcTelegram()) << "Error sending message." << info->thing()->name() << info->thing()->id().toString();
|
||||
info->finish(Thing::ThingErrorAuthenticationFailure, QT_TR_NOOP("The Telegram bot account seems to be disabled."));
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcTelegram()) << "Message sent successfully";
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by
|
||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||
* reproduction, publication, editing and translation, are reserved. The use of
|
||||
* this project is subject to the terms of a license agreement to be concluded
|
||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||
* under https://nymea.io/license
|
||||
*
|
||||
* GNU Lesser General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; version 3. This project is distributed in the hope that
|
||||
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef INTEGRATIONPLUGINPUSHBULLET_H
|
||||
#define INTEGRATIONPLUGINPUSHBULLET_H
|
||||
|
||||
#include "integrations/integrationplugin.h"
|
||||
|
||||
class IntegrationPluginTelegram: public IntegrationPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "integrationplugintelegram.json")
|
||||
Q_INTERFACES(IntegrationPlugin)
|
||||
|
||||
public:
|
||||
explicit IntegrationPluginTelegram(QObject *parent = nullptr);
|
||||
~IntegrationPluginTelegram() override;
|
||||
|
||||
void discoverThings(ThingDiscoveryInfo *info) override;
|
||||
void setupThing(ThingSetupInfo *info) override;
|
||||
void executeAction(ThingActionInfo *info) override;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"displayName": "Telegram",
|
||||
"name": "Telegram",
|
||||
"id": "bc95b5c8-f2f1-4bcb-bf88-8d165ee06114",
|
||||
"vendors": [
|
||||
{
|
||||
"displayName": "Telegram",
|
||||
"name": "telegram",
|
||||
"id": "45bb2595-4340-49df-8b88-8c6037c8d1c8",
|
||||
"thingClasses": [
|
||||
{
|
||||
"id": "f71bac7a-90e1-4810-9c31-531ac5f596fb",
|
||||
"name": "telegram",
|
||||
"displayName": "Telegram messages",
|
||||
"createMethods": ["discovery", "user"],
|
||||
"interfaces": ["notifications"],
|
||||
"discoveryParamTypes": [
|
||||
{
|
||||
"id": "2350bef6-d237-4bee-8e7e-6ab2c205f332",
|
||||
"name": "token",
|
||||
"displayName": "Bot access token",
|
||||
"type": "QString"
|
||||
}
|
||||
],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "28e4c161-f77a-4baa-b415-dc693330756f",
|
||||
"name": "token",
|
||||
"displayName": "Bot access token",
|
||||
"type": "QString"
|
||||
},
|
||||
{
|
||||
"id": "9c1f9d6c-e15a-4b76-a441-f1b96812cc28",
|
||||
"name": "chatId",
|
||||
"displayName": "Chat ID",
|
||||
"type": "QString"
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
{
|
||||
"id": "36b4ddf9-1a05-46c6-b0c9-2c3b8c835d42",
|
||||
"name": "notify",
|
||||
"displayName": "notify",
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "891772ed-45bc-402e-828a-5349bedc29e5",
|
||||
"name": "title",
|
||||
"displayName": "title",
|
||||
"type": "QString",
|
||||
"inputType": "TextLine",
|
||||
"defaultValue": ""
|
||||
},
|
||||
{
|
||||
"id": "374d059f-feab-4c49-8d91-e6066f80ed5a",
|
||||
"name": "body",
|
||||
"displayName": "body",
|
||||
"type": "QString",
|
||||
"inputType": "TextArea",
|
||||
"defaultValue": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"title": "Telegram",
|
||||
"tagline": "Send notifictions to Telegram.",
|
||||
"icon": "telegram.svg",
|
||||
"stability": "consumer",
|
||||
"offline": false,
|
||||
"technologies": [
|
||||
"cloud"
|
||||
],
|
||||
"categories": [
|
||||
"online-service",
|
||||
"notification"
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
include(../plugins.pri)
|
||||
|
||||
TARGET = $$qtLibraryTarget(nymea_integrationplugintelegram)
|
||||
|
||||
QT+= network
|
||||
|
||||
SOURCES += \
|
||||
integrationplugintelegram.cpp
|
||||
|
||||
HEADERS += \
|
||||
integrationplugintelegram.h
|
||||
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240"><defs><linearGradient id="a" x1=".667" x2=".417" y1=".167" y2=".75"><stop offset="0" stop-color="#37aee2"/><stop offset="1" stop-color="#1e96c8"/></linearGradient><linearGradient id="b" x1=".66" x2=".851" y1=".437" y2=".802"><stop offset="0" stop-color="#eff7fc"/><stop offset="1" stop-color="#fff"/></linearGradient></defs><circle cx="120" cy="120" r="120" fill="url(#a)"/><path fill="#c8daea" d="M98 175c-3.888 0-3.227-1.468-4.568-5.17L82 132.207 170 80"/><path fill="#a9c9dd" d="M98 175c3 0 4.325-1.372 6-3l16-15.558-19.958-12.035"/><path fill="url(#b)" d="M100.04 144.41l48.36 35.729c5.519 3.045 9.501 1.468 10.876-5.123l19.685-92.763c2.015-8.08-3.08-11.746-8.36-9.349l-115.59 44.571c-7.89 3.165-7.843 7.567-1.438 9.528l29.663 9.259 68.673-43.325c3.242-1.966 6.218-.91 3.776 1.258"/></svg>
|
||||
|
After Width: | Height: | Size: 855 B |
|
|
@ -0,0 +1,80 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1">
|
||||
<context>
|
||||
<name>IntegrationPluginTelegram</name>
|
||||
<message>
|
||||
<location filename="../integrationplugintelegram.cpp" line="58"/>
|
||||
<location filename="../integrationplugintelegram.cpp" line="119"/>
|
||||
<source>Error connecting to Telegram.</source>
|
||||
<extracomment>Error setting up thing</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../integrationplugintelegram.cpp" line="65"/>
|
||||
<source>Unexpected data from Telegram.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../integrationplugintelegram.cpp" line="70"/>
|
||||
<source>An error happened on the Telegram servers.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../integrationplugintelegram.cpp" line="169"/>
|
||||
<source>The Telegram bot account seems to be disabled.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Telegram</name>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/telegram/plugininfo.h" line="34"/>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/telegram/plugininfo.h" line="37"/>
|
||||
<source>Access token</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: telegram, Type: discovery, ID: {2350bef6-d237-4bee-8e7e-6ab2c205f332})
|
||||
----------
|
||||
The name of the ParamType (ThingClass: telegram, Type: thing, ID: {28e4c161-f77a-4baa-b415-dc693330756f})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/telegram/plugininfo.h" line="40"/>
|
||||
<source>Chat ID</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: telegram, Type: thing, ID: {9c1f9d6c-e15a-4b76-a441-f1b96812cc28})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/telegram/plugininfo.h" line="43"/>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/telegram/plugininfo.h" line="46"/>
|
||||
<source>Telegram</source>
|
||||
<extracomment>The name of the vendor ({45bb2595-4340-49df-8b88-8c6037c8d1c8})
|
||||
----------
|
||||
The name of the plugin Telegram ({bc95b5c8-f2f1-4bcb-bf88-8d165ee06114})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/telegram/plugininfo.h" line="49"/>
|
||||
<source>Telegram messages</source>
|
||||
<extracomment>The name of the ThingClass ({f71bac7a-90e1-4810-9c31-531ac5f596fb})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/telegram/plugininfo.h" line="52"/>
|
||||
<source>body</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: telegram, ActionType: notify, ID: {374d059f-feab-4c49-8d91-e6066f80ed5a})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/telegram/plugininfo.h" line="55"/>
|
||||
<source>notify</source>
|
||||
<extracomment>The name of the ActionType ({36b4ddf9-1a05-46c6-b0c9-2c3b8c835d42}) of ThingClass telegram</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../build-nymea-plugins-Desktop-Debug/telegram/plugininfo.h" line="58"/>
|
||||
<source>title</source>
|
||||
<extracomment>The name of the ParamType (ThingClass: telegram, ActionType: notify, ID: {891772ed-45bc-402e-828a-5349bedc29e5})</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
Loading…
Reference in New Issue