MikroWizard.mikroman/py/libs/red.py

140 lines
4.9 KiB
Python
Raw Normal View History

#!/usr/bin/python
# -*- coding: utf-8 -*-
# red.py: read/write data in Redis
# - get/set key values with expiration time
# - simple list operations
# - atomic increment, getset
#
#
# https://redis.io/commands
# https://github.com/andymccurdy/redis-py
#
# MikroWizard.com , Mikrotik router management solution
# Author: Tomi.Mickelsson@iki.fi modified by sepehr.ha@gmail.com
import redis
import datetime
import time
from collections import defaultdict
import logging
log = logging.getLogger("RedisDB")
# --------------------------------------------------------------------------
# key values
class RedisDB(object):
def __init__(self, options):
self.dev_id = options.get('dev_id',False)
self.keys= options.get('keys',[])
self.current_time = datetime.datetime.now()
self.start_time = options.get('start_time',self.current_time + datetime.timedelta(days=-30))
self.end_time = options.get('end_time',self.current_time)
self.retention = options.get('retention',2629800000)
self.r = redis.Redis(host='localhost', port=6379, db=0)
self.delta = options.get('delta','')
def create_sensor_rts(self,sensor):
retention=self.retention
if "rx" in sensor or "tx" in sensor:
retention=3600000
if self.dev_id==False:
return
master_key="sensor::{}::{}".format(self.dev_id,sensor)
rule5m_key="sensor5m::{}::{}".format(self.dev_id,sensor)
rule1h_key="sensor1h::{}::{}".format(self.dev_id,sensor)
ruledaily_key="sensordaily::{}::{}".format(self.dev_id,sensor)
#Create master key for sensor data or change retention time
try:
self.r.ts().create(master_key,retention_msecs=retention,duplicate_policy="last")
except Exception as e:
self.r.ts().alter(master_key,retention_msecs=retention)
pass
#Create ryle keys for sensor avg data or change retention time
try:
#5m avg store for 24h
#1h avg store for 2weeks
#daily avg store for 3month
self.r.ts().create(rule5m_key,retention_msecs=3600000*24,duplicate_policy="last")
self.r.ts().create(rule1h_key,retention_msecs=3600000*336,duplicate_policy="last")
self.r.ts().create(ruledaily_key,retention_msecs=retention*2160,duplicate_policy="last")
except Exception as e:
self.r.ts().alter(rule5m_key,retention_msecs=3600000*24)
self.r.ts().alter(rule1h_key,retention_msecs=3600000*336)
self.r.ts().alter(ruledaily_key,retention_msecs=3600000*2160)
pass
#Create rule for 5m avg data or change retention time
try:
self.r.ts().createrule(master_key, rule5m_key, "avg" ,bucket_size_msec=300000)
except Exception as e:
pass
#Create rule for 1hour avg data or change retention time
try:
self.r.ts().createrule(master_key, rule1h_key, "avg" ,bucket_size_msec=3600000)
except Exception as e:
pass
#Create rule for daily avg data or change retention time
try:
self.r.ts().createrule(master_key, ruledaily_key, "avg" ,bucket_size_msec=86400000)
except Exception as e:
pass
return True
def dev_create_keys(self):
if self.dev_id==False:
return
for key in self.keys:
try:
self.create_sensor_rts(key)
except Exception as e:
log.error(e)
pass
return True
def add_dev_data(self,info=[]):
if self.dev_id==False:
return
datalist=[]
for key, val in info.items():
master_key="sensor::{}::{}".format(self.dev_id,key)
datalist.append((master_key , '*' , val))
self.r.ts().madd(datalist)
return True
def get_dev_data(self,sensor):
if self.dev_id==False:
return
start=int(time.mktime(self.start_time.timetuple())* 1000)
end=int(time.mktime(self.end_time.timetuple())* 1000)
if self.delta=='live':
master_key="sensor::{}::{}".format(self.dev_id,sensor)
else:
master_key="sensor{}::{}::{}".format(self.delta,self.dev_id,sensor)
if self.delta=='live':
return list(reversed(self.r.ts().revrange(master_key,start,end,count=30)))
return self.r.ts().range(master_key,start,end)
def get_dev_last_data(self,sensor):
if self.dev_id==False:
return
master_key="sensor::{}::{}".format(self.dev_id,sensor)
return self.r.ts().get(master_key)
def get_dev_data_keys(self):
if self.dev_id==False:
return
data = defaultdict(list)
for key in self.keys:
try:
data[key]=self.get_dev_data(key)
except Exception as e:
log.error(e)
pass
return data