# -*- coding: utf-8 -*-
"""
    demeter load
    author:rabin
"""
from demeter.web import *
from datetime import *

class Load(Base):
	KEYS = ('user', 'farm')

	def setting(self):
		self.user()

	def user(self):
		ajax = self.input('ajax')
		if ajax:
			self.data['ajax'] = True
		else:
			self.data['ajax'] = False
		self.data['auth'] = True
		if 'user' in self.data['setting'] and self.data['setting']['user']:
			self.data['setting']['userInfo'] = self.service('common').one('farm_user', id=self.data['setting']['user'].decode())
			self.data['setting']['farm'] = self.data['setting']['userInfo']['farm_id']
		else:
			return

		if 'farm' in self.data['setting'] and self.data['setting']['farm']:
			self.data['setting']['farmInfo'] = self.service('common').one('farm', id=self.data['setting']['farm'])
			self.data['setting']['farmInfo']['gateways'] = ''
			if self.data['setting']['farmInfo']['gateway']:
				self.data['setting']['farmInfo']['gateways'] = tuple(eval(self.data['setting']['farmInfo']['gateway']))
		self.data['setting']['msgNum'] = len(self.service('common').list('msg', search={'status':False, "farm_id":self.data['setting']['farm']}, limit='0,100'))
		if self.data['setting']['msgNum'] > 99:
			self.data['setting']['msgNum'] = str(99) + '+'

		#self.data['setting']['msg'] = self.service('common').one('msg', type_id=3)
		self.data['setting']['web'] = Demeter.config['web']['url']
		self.data['setting']['farmurl'] = Demeter.config['web']['farmurl']
		cur = 'main'
		if '/' in self.request.uri:
			temp = self.request.uri.split('/')
			slen = len(temp)
			if slen > 1 and temp[1]:
				cur = temp[1]
		self.data['setting']['cur'] = cur


class Device(object):
	@staticmethod
	def init(self, search={}):
		type = self.input('type')
		id = self.input('id')
		if not id:
			self.view('404.html')
			return (None, type)
		if 'stat' in self.request.uri:
			self.data['device_cur'] = 'stat'
		elif 'log' in self.request.uri:
			self.data['device_cur'] = 'log'
		elif 'pic' in self.request.uri:
			self.data['device_cur'] = 'pic'
		else:
			self.data['device_cur'] = 'data'
		self.data['show'] = True
		self.data['url'] = Device.url('type='+type+'&id=' + id)
		if not search:
			search = {}
		self.data['info'] = {}
		self.data['device'] = []

		if type == 'gateway':
			self.data['info'] = self.service('common').one('device_gateway', id=id)
			if not self.data['info']:
				self.view('404.html')
				return (None, type)
			search['gateway_id'] = id
			self.data['device'] = Device.get(self, search=search)
			if self.data['device_cur'] in ('stat', 'log'):
				self.data['pic'] = Device.get(self, search={'gateway_id':id, 'hardware_type':6})

		elif type == 'page':
			self.data['info'] = self.service('common').one('device_page', id=id)
			if not self.data['info']:
				self.view('404.html')
				return (None, type)
			search['page_id'] = id
			self.data['group'] = self.service('common').list('device_group', search={'page_id':id}, order='inorder asc,cdate desc')
			if self.data['group']:
				Device.group(self, search)
		else:
			self.data['info'] = self.data['setting']['farmInfo']
			if not self.data['info']:
				self.view('404.html')
				return (None, type)
			self.data['device'] = Device.get(self, search=search)

		if not self.data['device'] and not self.data['info']:
			self.view('404.html')
			return (None, type)
		self.data['input'] = {}
		self.data['input']['type'] = type
		self.data['input']['id'] = id
		return (id, type)
	@staticmethod
	def set(self):
		if 'condition' in self.request.uri:
			self.data['set_cur'] = 'condition'
		elif 'timing' in self.request.uri:
			self.data['set_cur'] = 'timing'
		elif 'loop' in self.request.uri:
			self.data['set_cur'] = 'loop'
		else:
			self.data['set_cur'] = 'mul'
		self.data['url'] = Device.setUrl()
	@staticmethod
	def setCronOper(self):
		self.data['oper'] = ({'id':1, 'name':'打开'},{'id':2, 'name':'关闭'})
		self.data['looptype'] = ({'id':1, 'name':'按日周期', 'list':'每天'},{'id':2, 'name':'按周周期', 'list':'每周'}, {'id': 3, 'name': '按月周期', 'list':'每月'})
		self.data['opers'] = ({'id':1, 'name':'无操作'}, {'id':2, 'name':'打开'},{'id':3, 'name':'关闭'})

		self.data['week'] = ({'id':1, 'name':'周一'},{'id':2, 'name':'周二'}, {'id': 3, 'name': '周三'}, {'id': 4, 'name': '周四'}, {'id': 5, 'name': '周五'}, {'id': 6, 'name': '周六'}, {'id': 7, 'name': '周日'})

		self.data['condition'] = ({'id':1, 'name':'大于', 'exp':'>'}, {'id':2, 'name':'小于', 'exp':'<'},{'id':3, 'name':'等于','exp':'='})

		self.data['day'] = []
		for i in range(31):
			i = i + 1
			self.data['day'].append({'id':i, 'name':i})

		self.data['hour'] = []
		for i in range(24):
			i = i + 1
			self.data['hour'].append({'id':i, 'name':Demeter.hour(i)})

		self.data['minute'] = []
		for i in range(60):
			self.data['minute'].append({'id':i, 'name':Demeter.hour(i)})

	@staticmethod
	def get(self, search):
		if 'id--ins' in search and search['id--ins']:
			search['id--ins'] = tuple(eval(search['id--ins']))
			#order='inorder asc, type_id asc,udate asc,id asc'
		return self.service('common').list('device_info', state=True, search=search, order='cdate desc,udate asc,hardware_id asc', limit='0,10000')

	@staticmethod
	def getByGateway(self, search={}):
		device = Device.get(self, search=search)
		result = {}
		if device:
			for value in device:
				if value['gateway_id'] not in result:
					result[value['gateway_id']] = []
				result[value['gateway_id']].append(value)
		return result

	@staticmethod
	def data(self):
		id, type = Device.init(self)
		if not id:
			return
		method = type + '_data'
		if hasattr(Device, method):
			func = getattr(Device, method)
			data = func(self, id)
		else:
			self.view('404.html')
			return
		#self.data = dict(self.data, **data)

	@staticmethod
	def gateway_data(self, id):
		power = []
		sensor = []
		control = []
		self.data['stat'] = {}
		self.data['pic'] = []
		self.data['camera'] = []
		if self.data['device']:
			for value in self.data['device']:
				if value['type_id']:
					type_info = self.service('common').one('setting_device_type', id=value['type_id'])
					value['unit'] = type_info['unit']
					value['typeName'] = type_info['name']
				# 获取网关状态
				if value['hardware_type'] == 5:
					power.append(value)
				# 获取电源设备
				if value['hardware_type'] == 4:
					#value['value'] = Demeter.exp(value['out_exp'], value['value'])
					power.append(value)
					"""
					if not self.data['stat']:
						self.data['stat'] = value
					"""
				# 获取采集设备
				if value['hardware_type'] == 2:
					#value['value'] = Demeter.exp(value['out_exp'], value['value'])
					sensor.append(value)
					if not self.data['stat']:
						self.data['stat'] = value
				# 获取控制设备
				if value['hardware_type'] == 3:
					if value['value'] == '1.0':
						value['value'] = '1'
					control.append(value)
				# 获取摄像头
				if value['hardware_type'] == 6:
					value['value'] = value['value'] + '?' + Demeter.date(Demeter.time(), '%Y%m%d%H')
					self.data['pic'].append(value)
				# 获取摄像机
				if value['hardware_type'] == 7:
					self.data['camera'].append(value)
		"""
		if power:
			power.reverse()
		"""
		self.data['list'] = ({'name': '设备状态', 'device': power}, {'name': '数据采集', 'device': sensor}, {'name': '实时设备控制', 'device': control})

	@staticmethod
	def page_data(self, id):
		self.data['list'] = self.data['group']

	@staticmethod
	def group(self, search):
		self.data['show'] = False
		self.data['pic'] = []
		self.data['camera'] = []
		self.data['stat'] = {}
		for key, value in enumerate(self.data['group']):
			if value['devices']:
				search['id--ins'] = value['devices']
				if self.data['device_cur'] == 'stat':
					search['hardware_type--ins'].append(6)
				self.data['group'][key]['device'] = Device.get(self, search=search)
				if self.data['group'][key]['device']:
					for k, v in enumerate(self.data['group'][key]['device']):
						if v['hardware_type'] == 2 or v['hardware_type'] == 4:
							#v['value'] = Demeter.exp(v['out_exp'], v['value'])
							if v['hardware_type'] == 2 and self.data['info']['stat'] == True and not self.data['stat']:
								self.data['stat'] = v
							self.data['show'] = True
						if v['type_id'] > 0:
							type_info = self.service('common').one('setting_device_type', id=v['type_id'])
							self.data['group'][key]['device'][k]['unit'] = type_info['unit']
							self.data['group'][key]['device'][k]['typeName'] = type_info['name']

						if self.data['device_cur'] == 'data':
							if v['hardware_type'] == 6:
								slen = len(self.data['group'][key]['device'])
								if slen < 2:
									del self.data['group'][key]['device']
									v['name'] = self.data['group'][key]['name']
								v['value'] = v['value'] + '?' + Demeter.date(Demeter.time(), '%Y%m%d%H')
								self.data['pic'].append(v)
							if v['hardware_type'] == 7:
								slen = len(self.data['group'][key]['device'])
								if slen < 2:
									del self.data['group'][key]['device']
									v['name'] = self.data['group'][key]['name']
								self.data['camera'].append(v)
						if self.data['device_cur'] == 'stat':
							if v['hardware_type'] == 6:
								self.data['pic'] = True
							else:
								self.data['device'].append(v)
						else:
							self.data['device'].append(v)

	@staticmethod
	def pic(self):
		id, type = Device.init(self, search={'hardware_type':6})
		if not id:
			return
		state = Device.get(self, search={'hardware_type--ins':(2,4)})
		if state:
			self.data['show'] = True
		device = self.input('device')
		if not device:
			#如果没有，就获取第一个
			self.data['deviceInfo'] = self.data['device'][0]
		else:
			self.data['deviceInfo'] = self.service('common').one('device_info', id=device)

		if not self.data['deviceInfo']:
			self.view('404.html')
			return
		self.data['pic'] = self.service('common').list('device_pic', search={'device_id':self.data['deviceInfo']['id']}, page={'num':12}, order='sdate desc')
		if self.data['pic']:
			for key, value in enumerate(self.data['pic']):
				self.data['pic'][key]['cdates'] = Demeter.date(value['sdate'])

	@staticmethod
	def statBase(self, deviceInfo={}, device = False):
		
		if not device:
			device = self.input('device')
		method = self.input('method', 'maxmin')
		if not device:
			#如果没有，就获取sensor的第一个
			self.data['deviceInfo'] = deviceInfo
		else:
			self.data['deviceInfo'] = self.service('common').one('device_info', id=device)

		if not self.data['deviceInfo']:
			self.view('404.html')
			return
		self.data['type'] = self.service('common').one('setting_device_type', id=self.data['deviceInfo']['type_id'])

		model = Demeter.model('data', 'tsdb')
		self.data['group'] = model.dateConfig()

		search_group = self.input('group')
		search_start = self.input('start')
		search_end = self.input('end')

		search = {}
		search['device'] = self.data['deviceInfo']['id']
		if search_group:
			search['group'] = search_group
		else:
			search['group'] = '1'
		if search_start:
			search['start'] = search_start
		if search_end:
			search['end'] = search_end
		search['type'] = type
		search['id'] = id
		self.data['search'] = search
		self.data['statList'] = model.getData(method, search, self.data['deviceInfo'])
		return self.data

	@staticmethod
	def stat(self):
		id, type = Device.init(self, search={'hardware_type--ins':[2,4]})
		if not id:
			return
		device = self.input('device')
		Device.statBase(self, self.data['device'][0], device)
		self.data['url'] = Device.url('type='+type+'&id=' + id)

	@staticmethod
	def out(self):
		id, type = Device.init(self, search={'hardware_type--ins':[2,4]})
		if not id:
			return

		out = self.input('out')
		if not out:
			device = self.inputs('device')
			data = []
			header = []
			datas = {}
			header.append('日期')
			for i in device:
				result = Device.statBase(self, self.data['device'][0], i)
				if result['statList']:
					header.append(result['deviceInfo']['name'])

					for t,v in result['statList'][0]['data']['rows']:
						if t not in datas:
							datas[t] = [t,v]
						else:
							datas[t].append(v)

			self.data['url'] = Device.url('type='+type+'&id=' + id)

			if datas:
				import csv,codecs
				import uuid

				dates = sorted(datas.keys())
				newData = []
				for i in dates:
					newData.append(datas[i])
				data = newData
				data.insert(0, header)
				fileData = data

				day = str(date.today())
				day = day.split('-')
				file_name =  self.data['info']['name'] + '.csv'
				file_path = day[0] + '/' + day[1] + '/' + day[2]
				file_path = File.mkdirs(os.path.join(Demeter.path, 'runtime','upload', file_path)) + '/' + file_name
				with open(file_path, 'w') as f:
					f.write(codecs.BOM_UTF8)
					writer = csv.writer(f)
					for row in fileData:
						writer.writerow(row)
				url = self.request.protocol + "://" + self.request.host
				file_path = url + file_path.replace(Demeter.path + 'runtime', '')
				self.set_header("Content-Type","text/csv,charset=UTF-8")
				self.set_header('Content-Disposition', 'attachment; filename=' + file_name)
				self.redirect(file_path)

		else:
			self.data['search'] = {}

	@staticmethod
	def log(self):
		id, type = Device.init(self)
		if not id:
			return
		ids = []
		device_type = {}
		device_hard = {}
		device_list = []
		for value in self.data['device']:
			ids.append(value['id'])
			value['cdates'] = Demeter.date(value['udate'], '%Y.%m.%d')
			if value['type_id']:
				info = self.service('common').one('setting_device_type', id=value['type_id'])
				if info['id'] not in device_type:
					device_type[info['id']] = {'name':info['name'], 'num':1, 'cdate':value['cdates']}
				else:
					num = device_type[info['id']]['num'] + 1
					device_type[info['id']] = {'name':info['name'], 'num':num, 'cdate':value['cdates']}
			elif '网关' in value['name']:
				value['name'] = '通讯网关'
				device_list.append({'name':value['name'], 'num':1, 'cdate':value['cdates']})
			elif value['hardware_type'] > 0:
				info = self.service('common').one('hardware_type', id=value['hardware_type'])
				if info['id'] not in device_hard:
					device_hard[info['id']] = {'name':info['name'], 'num':1, 'cdate':value['cdates']}
				else:
					num = device_hard[info['id']]['num'] + 1
					device_hard[info['id']] = {'name':info['name'], 'num':num, 'cdate':value['cdates']}
		if device_hard:
			for key, value in device_hard.items():
				device_list.append({'name':value['name'], 'num':value['num'], 'cdate':value['cdate']})

		if device_type:
			for key, value in device_type.items():
				device_list.append({'name':value['name'], 'num':value['num'], 'cdate':value['cdate']})
		

		self.data['list'] = device_list
		# 获取设备日志
		self.data['logs'] = self.service('common').list('msg', state=True, search={'device_id-input-ins':ids}, page={'num':6})
		if self.data['logs']:
			for key, value in enumerate(self.data['logs']):
				type_info = self.service('common').one('msg_type', id=value['type_id'])
				self.data['logs'][key]['type'] = type_info['name']
				self.data['logs'][key]['cdates'] = Demeter.date(value['cdate'])
	@staticmethod
	def url(param):
		config = {}
		config['data'] = '/device/data?' + param;
		config['stat'] = '/device/stat?' + param;
		config['log'] = '/device/log?' + param;
		config['pic'] = '/device/pic?' + param;
		config['out'] = '/device/out?' + param + '&out=1';
		return config

	@staticmethod
	def setUrl():
		config = {}
		config['mul'] = '/device/set_mul'
		config['timing'] = '/device/set_timing'
		config['loop'] = '/device/set_loop'
		config['condition'] = '/device/set_condition'
		return config
