59 lines
2.0 KiB
Python
59 lines
2.0 KiB
Python
from base import Base
|
|
import collections
|
|
import requests
|
|
import datetime
|
|
|
|
class Logger(Base):
|
|
def initialize(self):
|
|
super().initialize()
|
|
|
|
self.q = collections.deque()
|
|
self.listen_event(self.log_event, 'LOG_WRITE')
|
|
|
|
self.listen_event(self.event)
|
|
self.listen_state(self.state)
|
|
|
|
self.log_write("Appdaemon logger started")
|
|
|
|
def send(self, kwargs):
|
|
# Send messages from the queue, but keep track of the rate limit
|
|
while len(self.q):
|
|
msg = self.q.popleft()
|
|
url = self.args['channels'][msg.get('channel', 'log')]
|
|
if url:
|
|
res = requests.post(url, json={
|
|
"content": msg['message'],
|
|
"username": "Appdaemon",
|
|
})
|
|
if res.status_code == 429 or (res.status_code == 200 and res.headers['X-RateLimit-Remaining'] == 0):
|
|
# If rate limit exceeded or nearly so
|
|
if res.status_code == 429:
|
|
self.q.appendleft(msg)
|
|
next_try = datetime.datetime.fromtimestamp(int(res.headers['X-RateLimit-Reset']))
|
|
self.run_at(self.send, next_try)
|
|
break
|
|
|
|
def log_write(self, message, channel = 'log'):
|
|
if not message:
|
|
return
|
|
self.q.append({
|
|
'message': message,
|
|
'channel': channel,
|
|
})
|
|
if len(self.q) == 1:
|
|
self.run_in(self.send, 1)
|
|
def log_event(self, ev, data, kwargs):
|
|
self.log_write(data['message'], data.get('channel', 'log'))
|
|
|
|
|
|
def event(self, name, data, kwargs):
|
|
if name == 'call_service' and data['service'] == 'discord_log':
|
|
return
|
|
self.log_write("EVENT: {} {}".format(name, data))
|
|
|
|
def state(self, entity, attribute, old, new, kwargs):
|
|
tracked_domains = ['light', 'switch', 'device_tracker', 'binary_sensor']
|
|
domain = entity.split('.')[0]
|
|
if domain in tracked_domains:
|
|
self.log_write("STATE: {} {} {} =>{}".format(entity, attribute, old, new))
|