#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
    demeter web
    name:admin.py
    author:rabin
"""
import time
from demeter.core import *
from gevent import monkey; monkey.patch_socket()
import gevent
from pic import pic
from demeter.mqtt import *
# 处理定时命令、周期命令、条件控制、消息、设备状态等
timeSleep = 10

# 开关设备
def switch(value):
	Demeter.service('device').switchMul(value)
				

# 更改设备状态(离线)
def device():
	while 1:
		model = Demeter.model('device_info')
		cur = Demeter.time() - 1800
		model.cdate.assgin(cur, '<=')
		model.status = True
		data = model.select()
		for v in data:
			model.id = v['id']
			if v['hardware_type'] == 5:
				model.update(value='0', status=False)
			elif v['hardware_type'] != 7 and v['hardware_type'] != 6:
				model.update(status=False)
		gevent.sleep(60)

# 更改控制设备的超时状态
def control():
	while 1:
		model = Demeter.model('device_info')
		cur = Demeter.time() - 10
		model.operdate.assgin(cur, '<=')
		model.oper = True
		model.hardware_type = 3
		service = Demeter.service('device')
		data = model.select()
		if data:
			for v in data:
				model.id = v['id']
				if v['exp'] == '-1':
					msg = service.notice('timeout')
					service.mul(v, v['name'] + '失败:' + msg, False)
					model.update(exp=msg, oper=True, operdate=Demeter.time())
				else:
					msg = '1'
					service.mul(v, '', True)
					model.update(exp=msg, oper=False, operdate=Demeter.time())

		gevent.sleep(1)
		

# 批量控制的队列 这块有点乱，但时间太紧，只有两天时间，以后改造优化
def mulQueue():
	while 1:
		mul_model = Demeter.model('device_mul')
		device_model = Demeter.model('device_info')
		model = Demeter.model('device_mul_queue')

		model.status = 1
		data = model.select(type='fetchone', order='inorder asc,udate asc,hardware_id asc')
		service = Demeter.service('device')

		# 查看当前有没有正在执行的设备，如果有，不能继续执行了
		msg = service.notice('timeout')
		device_model.oper = True
		device_model.exp.nq(msg)
		device_model.hardware_type = 3
		device = device_model.select(type='fetchone')

		if not device and data and not data['operstate']:
			service.switch(data['device_id'], switch=data['value'], mul=False, queue=data['id'])
			model.id = data['id']
			model.update(operstate=True)
			#mul_model.id = data['mul_id']
			#mul_model.update(oper='')

		# 将执行完成的进行清理
		mul_model.oper.nq('')
		data = mul_model.select()
		if data:
			for v in data:
				devicesNum = len(tuple(eval(v['devices'])))
				model.status.ins((2,3))
				cur = Demeter.time() - 10
				model.operdate.assgin(cur, '<=')
				queue = model.select()
				num = len(queue)
				if num == devicesNum:
					errorNum = 0
					model.mul_id = v['id']
					model.update(status=4)
					for qv in queue:
						if qv['status'] == 3:
							errorNum = errorNum + 1
					mul_model.id = v['id']
					if errorNum == devicesNum:
						mul_model.update(oper='', value=v['old'])
					else:
						mul_model.update(oper='')

		gevent.sleep(1)

# 批量控制的队列清理，10小时清理一次24小时之前完成的数据
def mulQueueDrop():
	while 1:
		num = 3600*24
		model = Demeter.model('device_mul_queue')
		model.status = 4
		cur = Demeter.time() - num
		model.operdate.assgin(cur, '<=')
		model.delete()

		gevent.sleep(36000)

def timing():
	while 1:
		model = Demeter.model('device_set_timing')
		model.status = 0
		cur = Demeter.time()
		model.zdate.assgin(cur, '<=')
		data = model.select()
		if data:
			for value in data:
				switch(value)
				model.id = value['id']
				model.update(status=1)
		gevent.sleep(timeSleep)

def loop():
	while 1:
		model = Demeter.model('device_set_loop')
		cur = Demeter.time()
		date = Demeter.date(cur, '%Y-%m-%d-%w-%H-%M')
		date = date.split('-')
		week = date[3]
		day = date[2]
		model.status = True
		model.hour = date[4]
		model.minute = date[5]
		data = model.select()
		if data:
			for value in data:
				state = False
				value['loop'] = value['loop'].split(',')
				if value['looptype'] == 2:
					if week in value['loop']:
						state = True
				elif value['looptype'] == 3:
					if day in value['loop']:
						state = True
				if state:
					switch(value)
		gevent.sleep(timeSleep)

def savePic():
	while 1:
		pic()
		gevent.sleep(1800)

# 同步时间，24小时同步一次
def timeSync():
	while 1:
		pub = Pub()
		key = 'time/bh'
		value = Demeter.date(Demeter.time())
		pub.push(key, value)
		gevent.sleep(3600*24)

def handle():
	gevent.joinall([
		gevent.spawn(timing),
		gevent.spawn(loop),
		gevent.spawn(device),
		gevent.spawn(savePic),
		gevent.spawn(control),
		gevent.spawn(timeSync),
		gevent.spawn(mulQueue),
		gevent.spawn(mulQueueDrop),
	])

handle()