1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
import paho.mqtt.client as paho
import threading
import argparse
import getpass
import docker_net
import time
import json
SENT_EVENT = threading.Event()
class MQTTClient:
switch_energy = None
switch_power = None
def __init__(self, host, friendlyname, username, password, message = None):
self.host = host
self.friendlyname = friendlyname
self.username = username
self.password = password
self.message = message
# print("Instantiated. Message:", message)
self.mqtt_c = paho.Client("tasmota-cli", clean_session = True)
self.mqtt_c.on_connect = self._on_connect_cb
if message is None:
self.mqtt_c.on_message = self._on_message_cb
self.mqtt_c.username_pw_set(username = username, password = password)
self.mqtt_c.connect(self.host, 1883, 60)
self.mqtt_c.loop_forever()
def _on_connect_cb(self, mqtt, userdata, flags, rc):
# print("Connected to broker")
topic = "tele/TasmotaPlug/%s/SENSOR" % self.friendlyname
if self.message is None:
print("Waiting for '%s'" % topic)
self.mqtt_c.subscribe(topic)
else:
self.mqtt_c.publish("cmnd/TasmotaPlug/%s/Power" % self.friendlyname, payload = self.message)
print("Sent message '%s' to topic 'cmnd/TasmotaPlug/%s/Power'" % (self.message, self.friendlyname))
SENT_EVENT.set()
self.mqtt_c.disconnect()
def _on_message_cb(self, mqtt, userdata, msg):
# print('Topic: {0} | Message: {1}'.format(msg.topic, msg.payload))
if msg.topic.split("/")[1] == self.friendlyname:
if msg.topic.split("/")[2] == "SENSOR":
self.switch_energy = json.loads(msg.payload.decode())["ENERGY"]
elif msg.topic.split("/")[2] == "STATE":
self.switch_power = json.loads(msg.payload.decode())["POWER"]
if self.switch_power is not None and self.switch_energy is not None:
self.mqtt_c.disconnect()
parser = argparse.ArgumentParser()
parser.add_argument(
"-m", "--mqtt-host",
type = str,
help = "MQTT Server",
default = docker_net.get_mqtt_addr()[0]
)
parser.add_argument(
"-u", "--user",
type = str,
help = "Username to login with",
required = True
)
parser.add_argument(
"-t", "--toggle",
action = "store_true",
help = "Toggle current power status"
)
parser.add_argument(
"-n", "--friendlyname",
help = "Device friendly name",
type = str,
required = True
)
if __name__ == "__main__":
args = vars(parser.parse_args())
if args["user"] is not None:
args["password"] = getpass.getpass("Input password for %s@%s: " % (args["user"], args["mqtt_host"]))
else:
args["password"] = None
if args["toggle"]:
client = MQTTClient(args["mqtt_host"], args["friendlyname"], args["user"], args["password"], "TOGGLE")
# print("Waiting for event...")
SENT_EVENT.wait()
# print("Done waiting.")
client = MQTTClient(args["mqtt_host"], args["friendlyname"], args["user"], args["password"])
print(json.dumps(client.switch_energy, indent = 4))
print("'%s' is currently %s" % (client.friendlyname, client.switch_power))
|