Thomas Buck пре 2 година
родитељ
комит
a4019fe52e

+ 126
- 0
input/projects/smarthome/mqtt_telegram.md Прегледај датотеку

@@ -0,0 +1,126 @@
1
+title: MQTT Telegram Bot
2
+description: Go server to control stuff from anywhere in the world
3
+parent: smarthome
4
+position: 500
5
+git: https://git.xythobuz.de/thomas/lights-telegram
6
+date: 2022-08-23
7
+comments: true
8
+---
9
+
10
+<!--% backToParent() %-->
11
+
12
+After creating my [MQTT Web UI](mqtt_web.html) I had some troubles getting it to work on all devices.
13
+My server at home is using a self-signed SSL certificate.
14
+I imported the certificate authority into my desktop, which Chromium accepts fine there.
15
+But on Android the connection is still considered insecure, even with the CA cert imported, so the JS can not communicate with the MQTT broker.
16
+
17
+To work around that problem I decided to create a simple Telegram Bot that can fulfill the same task of switching the lights.
18
+
19
+<!--%
20
+lightgallery([
21
+    [ "img/mqtt_telegram.png", "Screenshot of chat with bot" ],
22
+])
23
+%-->
24
+
25
+You can [find the source code on my Gitea](https://git.xythobuz.de/thomas/lights-telegram), as well as installation and setup instructions.
26
+
27
+This was my first time doing something with Go.
28
+I think the language is interesting and I will probably continue using it in the future.
29
+On one hand it was quite easy to find some suitable libraries that simplified the main tasks of the application greatly!
30
+But also the language features I found out about impressed me.
31
+
32
+One good example is reading the config file.
33
+You can simply define a struct that holds all configuration variables, with additional markup to control how it is marshalled and unmarshalled into different formats, in my case yaml.
34
+
35
+<pre class="sh_go">
36
+type Mqtt struct {
37
+    Url string `yaml:"url"`
38
+    User string `yaml:"username"`
39
+    Pass string `yaml:"password"`
40
+}
41
+
42
+type Registration struct {
43
+    Name string `yaml:"name"`
44
+    Topic string `yaml:"topic"`
45
+    Values []string `yaml:"values"`
46
+}
47
+
48
+type Config struct {
49
+    // Telegram Bot API key
50
+    Key string `yaml:"api_key"`
51
+
52
+    // Telegram UserID (int64) of admin account
53
+    Admin int64 `yaml:"admin_id"`
54
+
55
+    // MQTT credentials
56
+    Mqtt Mqtt
57
+
58
+    // Telegram UserIDs (int64) of allowed users
59
+    // (does not need to be modified manually)
60
+    Users []int64 `yaml:"authorized_users"`
61
+
62
+    // Available MQTT topics
63
+    // (does not need to be modified manually)
64
+    Registration []Registration
65
+}
66
+
67
+// default values
68
+var config = Config {
69
+    Key: "API_KEY_GOES_HERE",
70
+    Admin: 0,
71
+    Mqtt: Mqtt {
72
+        Url: "wss://MQTT_HOST:MQTT_PORT",
73
+        User: "MQTT_USERNAME",
74
+        Pass: "MQTT_PASSWORD",
75
+    },
76
+}
77
+</pre>
78
+
79
+Using simple functions to read and write files according to this format, you can then get a file looking something like this.
80
+
81
+<pre class="sh_yaml">
82
+api_key: API_KEY_REDACTED
83
+admin_id: ADMIN_ID_REDACTED
84
+mqtt:
85
+    url: wss://iot.fritz.box:8083
86
+    username: USERNAME_REDACTED
87
+    password: PASSWORD_REDACTED
88
+authorized_users: []
89
+registration:
90
+    - name: kitchen
91
+      topic: livingroom/light_kitchen
92
+      values:
93
+        - "on"
94
+        - "off"
95
+    - name: bathroom
96
+      topic: bathroom/force_light
97
+      values:
98
+        - none
99
+        - big
100
+        - small
101
+        - "off"
102
+    - name: pc
103
+      topic: livingroom/light_pc
104
+      values:
105
+        - "on"
106
+        - "off"
107
+    - name: workbench
108
+      topic: livingroom/light_bench
109
+      values:
110
+        - "on"
111
+        - "off"
112
+    - name: box
113
+      topic: livingroom/light_box
114
+      values:
115
+        - "on"
116
+        - "off"
117
+    - name: amp
118
+      topic: livingroom/light_amp
119
+      values:
120
+        - "on"
121
+        - "off"
122
+</pre>
123
+
124
+I'm using this file both to store static configuration data, like the API key, as well as runtime configuration data entered by the admin user, like available MQTT topics.
125
+
126
+All in all I was able to implement a basic working prototype in less than 500 LOC and in just a single evening!

BIN
static/img/mqtt_telegram.png Прегледај датотеку


BIN
static/img/mqtt_telegram_small.png Прегледај датотеку


+ 1
- 0
static/js/sh/sh_go.min.js Прегледај датотеку

@@ -0,0 +1 @@
1
+if(!this.sh_languages){this.sh_languages={}}sh_languages.go=[[[/\/\/\//g,"sh_comment",1],[/\/\//g,"sh_comment",7],[/\/\*\*/g,"sh_comment",8],[/\/\*/g,"sh_comment",9],[/^[ \t]*[A-Za-z0-9]+:[ \t]*$/g,"sh_label",-1],[/(\b(?:interface|struct))([ \t]+)([A-Za-z0-9_]+)/g,["sh_keyword","sh_normal","sh_classname"],-1],[/"/g,"sh_string",10],[/'/g,"sh_string",11],[/`/g,"sh_string",12],[/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go|goto|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/g,"sh_keyword",-1],[/\b(?:bool|uint8|uint16|uint32|uint64|int8|int16|int32|int64|float32|float64|complex64|complex128|byte|rune|string)\b/g,"sh_type",-1],[/\b[+-]?(?:(?:0x[A-Fa-f0-9]+)|(?:(?:[\d]*\.)?[\d]+(?:[eE][+-]?[\d]+)?))u?(?:(?:int(?:8|16|32|64))|L)?\b/g,"sh_number",-1],[/\+|-|\*|\/|%|&|\||\^|<<|>>|&\^|\+=|-=|\*=|\/=|%=|&=|\|=|\^=|<<=|>>=|&\^=|&&|\|\||<-|\+\+|--|==|<|>|=|!|!=|<=|>=|:=|\.\.\.|\(|\)|\[|\]|,|\.|;|:/g,"sh_symbol",-1],[/\{|\}/g,"sh_cbracket",-1],[/(?:[A-Za-z]|_)[A-Za-z0-9_:]*(?=\()/g,"sh_function",-1]],[[/$/g,null,-2],[/(?:<?)[A-Za-z0-9_\.\/\-_~]+@[A-Za-z0-9_\.\/\-_~]+(?:>?)|(?:<?)[A-Za-z0-9_]+:\/\/[A-Za-z0-9_\.\/\-_~]+(?:>?)/g,"sh_url",-1],[/<\?xml/g,"sh_preproc",2,1],[/<!DOCTYPE/g,"sh_preproc",4,1],[/<!--/g,"sh_comment",5],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)/g,"sh_keyword",6,1],[/&(?:[A-Za-z0-9]+);/g,"sh_preproc",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*/g,"sh_keyword",6,1],[/@[A-Za-z]+/g,"sh_type",-1],[/(?:TODO|FIXME|BUG)(?:[:]?)/g,"sh_todo",-1]],[[/\?>/g,"sh_preproc",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",3]],[[/\\(?:\\|")/g,null,-1],[/"/g,"sh_string",-2]],[[/>/g,"sh_preproc",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",3]],[[/-->/g,"sh_comment",-2],[/<!--/g,"sh_comment",5]],[[/(?:\/)?>/g,"sh_keyword",-2],[/([^=" \t>]+)([ \t]*)(=?)/g,["sh_type","sh_normal","sh_symbol"],-1],[/"/g,"sh_string",3]],[[/$/g,null,-2]],[[/\*\//g,"sh_comment",-2],[/(?:<?)[A-Za-z0-9_\.\/\-_~]+@[A-Za-z0-9_\.\/\-_~]+(?:>?)|(?:<?)[A-Za-z0-9_]+:\/\/[A-Za-z0-9_\.\/\-_~]+(?:>?)/g,"sh_url",-1],[/<\?xml/g,"sh_preproc",2,1],[/<!DOCTYPE/g,"sh_preproc",4,1],[/<!--/g,"sh_comment",5],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z](?:[A-Za-z0-9_:.-]*)/g,"sh_keyword",6,1],[/&(?:[A-Za-z0-9]+);/g,"sh_preproc",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*(?:\/)?>/g,"sh_keyword",-1],[/<(?:\/)?[A-Za-z][A-Za-z0-9]*/g,"sh_keyword",6,1],[/@[A-Za-z]+/g,"sh_type",-1],[/(?:TODO|FIXME|BUG)(?:[:]?)/g,"sh_todo",-1]],[[/\*\//g,"sh_comment",-2],[/(?:<?)[A-Za-z0-9_\.\/\-_~]+@[A-Za-z0-9_\.\/\-_~]+(?:>?)|(?:<?)[A-Za-z0-9_]+:\/\/[A-Za-z0-9_\.\/\-_~]+(?:>?)/g,"sh_url",-1],[/(?:TODO|FIXME|BUG)(?:[:]?)/g,"sh_todo",-1]],[[/\\(?:\\|")/g,null,-1],[/"/g,"sh_string",-2],[/\\./g,"sh_specialchar",-1]],[[/\\(?:\\|')/g,null,-1],[/'/g,"sh_string",-2],[/\\./g,"sh_specialchar",-1]],[[/`/g,"sh_string",-2]]];

+ 1
- 0
static/js/sh/sh_yaml.min.js Прегледај датотеку

@@ -0,0 +1 @@
1
+if(!this.sh_languages){this.sh_languages={}}sh_languages.yaml=[[[/#/g,"sh_comment",1],[/\b[+-]?(?:(?:0x[A-Fa-f0-9]+)|(?:(?:[\d]*\.)?[\d]+(?:[eE][+-]?[\d]+)?))u?(?:(?:int(?:8|16|32|64))|L)?\b/g,"sh_number",-1],[/\b(?:true|false|null)\b/g,"sh_keyword",-1],[/^---/g,"sh_section",1],[/(^[ \t-]*)([A-Za-z0-9_]+)(:)/g,["sh_symbol","sh_name","sh_symbol"],-1],[/^[ \t]*-/g,"sh_symbol",-1],[/"/g,"sh_string",2],[/'/g,"sh_string",3]],[[/$/g,null,-2]],[[/$/g,null,-2],[/\\(?:\\|")/g,null,-1],[/"/g,"sh_string",-2]],[[/$/g,null,-2],[/\\(?:\\|')/g,null,-1],[/'/g,"sh_string",-2]]];

Loading…
Откажи
Сачувај