1# -*- coding: utf-8 -*-
2# mqttwarn example function extensions
3import time
4import copy
5
6try:
7    import json
8except ImportError:
9    import simplejson as json
10
11def OwnTracksTopic2Data(topic):
12    try:
13        # owntracks/username/device
14        parts = topic.split('/')
15        username = parts[1]
16        deviceid = parts[2]
17    except:
18        deviceid = 'unknown'
19        username = 'unknown'
20    return dict(username=username, device=deviceid)
21
22def OwnTracksConvert(data):
23    if type(data) == dict:
24        # Better safe than sorry: Clone transformation dictionary to prevent leaking local modifications
25        # See also https://github.com/jpmens/mqttwarn/issues/219#issuecomment-271815495
26        data = copy.copy(data)
27        tst = data.get('tst', int(time.time()))
28        data['tst'] = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(int(tst)))
29        # Remove these elements to eliminate warnings
30        for k in ['_type', 'desc']:
31            data.pop(k, None)
32
33        return "{username} {device} {tst} at location {lat},{lon}".format(**data)
34
35# custom function to filter out any OwnTracks notifications which do
36# not contain the 'batt' parameter
37def OwnTracksBattFilter(topic, message):
38    data = dict(json.loads(message).items())
39    if 'batt' in data:
40        if data['batt'] is not None:
41            return int(data['batt']) > 20
42
43    return True     # Suppress message because no 'batt'
44
45def TopicTargetList(topic=None, data=None, srv=None):
46    """
47    Custom function to compute list of topic targets based on MQTT topic and/or transformation data.
48    Obtains MQTT topic, transformation data and service object.
49    Returns list of topic target identifiers.
50    """
51
52    # optional debug logger
53    if srv is not None:
54        srv.logging.debug('topic={topic}, data={data}, srv={srv}'.format(**locals()))
55
56    # Use a fixed list of topic targets for demonstration purposes.
57    targets = ['log:debug']
58
59    # In the real world, you would compute proper topic targets based on information
60    # derived from transformation data, which in turn might have been enriched
61    # by ``datamap`` or ``alldata`` transformation functions before, like that:
62    if 'condition' in data:
63
64        if data['condition'] == 'sunny':
65            targets.append('file:mqttwarn')
66
67        elif data['condition'] == 'rainy':
68            targets.append('log:warn')
69
70    return targets
71
72def publish_public_ip_address(srv=None):
73    """
74    Custom function used as a periodic task for publishing your public ip address to the MQTT bus.
75    Obtains service object.
76    Returns None.
77    """
78
79    import socket
80    import requests
81
82    hostname = socket.gethostname()
83    ip_address = requests.get('https://httpbin.org/ip').json().get('origin')
84
85    if srv is not None:
86
87        # optional debug logger
88        srv.logging.debug('Publishing public ip address "{ip_address}" of host "{hostname}"'.format(**locals()))
89
90        # publish ip address to mqtt
91        srv.mqttc.publish('test/ip/{hostname}'.format(**locals()), ip_address)
92