aboutsummaryrefslogtreecommitdiff
path: root/scan.py
blob: b55526c815e9ef5e4078a7c525062b2480c1a46f (plain)
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
#!/usr/bin/env python 
import logging
import asyncio
from asyncio_simple_http_server import HttpServeruri_mappingHttpHeadersHttpResponse
from datetime import datetimetimezone
from bleak import BleakScanner
from functools import partial
from atc_mi_interface import general_formatatc_mi_advertising_format
 
fields=['temperature','humidity','battery_level','battery_v']
 
def write_out_prometheus(collected):
    f = open("metrics""w"encoding="utf-8")
    for field in fields:
        print("# HELP therm_{0} {0}\n# TYPE therm_{0} gauge".format(field),file=f)
        for mac in collected:
            print("therm_{0}{{mac=\"{1}\"}} {2:f}".format(field,mac,collected[mac][field][0]),file=f)
 
class Prom:
    collected = {}
 
    @uri_mapping('/metrics')
    def expose(self) -> HttpResponse:
        output="" 
        for field in fields:
            output = output + "# HELP therm_{0} {0}\n# TYPE therm_{0} gauge\n".format(field) 
            for mac in self.collected:
                try:
                    output = output + "therm_{0}{{mac=\"{1}\"}} {2:f}\n".format(
                        fieldmacself.collected[mac][field][0]
                        ) 
                except E:
                    output = output + "# therm_{0}{{mac=\"{1}\"}} {2}\n".format(
                        fieldmacE
                        ) 
 
        headers = HttpHeaders() 
        headers.set('Content-type', 'text/plain; version=0.0.4charset=utf-8escaping=values') 
        return HttpResponse(200headersoutput.encode('utf-8')) 
 
async def main():
    stop_event = asyncio.Event()
    http_server = HttpServer()
 
    handler=Prom()
    http_server.add_handler(handler)
 
    async def detection_callback(deviceadvertisement_data):
        format_labeladv_data = atc_mi_advertising_format(advertisement_data)
        if not adv_data:
            return
        mac_address = bytes.fromhex(device.address.replace(":"""))
        atc_mi_data = general_format.parse(
            adv_data,
            mac_address=mac_address,
            bindkey=None,
        )
 
        data={ 
            "timestamp": datetime.now(timezone.utc).isoformat(), 
            "temperature": atc_mi_data.search_all("^temperature"), 
            "humidity": atc_mi_data.search_all("^humidity"), 
            "battery_level": atc_mi_data.search_all("^battery_level"), 
            "battery_v": atc_mi_data.search_all("^battery_v"), 
            "MAC": atc_mi_data.search_all("^MAC$"), 
        }
        handler.collected[data["MAC"][0]]=data
 
    await http_server.start('10.111.0.66',9003)
 
    async with BleakScanner(
        detection_callback=partial(detection_callback) 
    ) as scanner:
        await http_server.serve_forever()
    print("Stopped")
 
logging.basicConfig(level=logging.INFO,
                    format='%(asctime)-15s %(name)-5s %(levelname)-8s %(message)s')
server_logger = logging.getLogger('asyncio_simple_http_server')
def filterNoise(event):
    if event.msg == 'got a failure %s. disconnecting the client' and event.args[0] == asyncio.TimeoutError:
        return False
    return True
server_logger.addFilter(filterNoise)
 
 
asyncio.run(main())