#!/usr/bin/python

import types
import traceback
import binascii
import threading
import time
import thread
import os
import struct
import sys
import serial
import minimalmodbus
import pickle
import re
from device_base import deviceBase

import requests
try:
    import json
except:
    import simplejson as json

channels = {}
min_upload_time = 30
addr = 'http://192.168.1.30:3000'


def setupChannels():
    tagJSObj = json.loads(requests.get(addr + "/json/tag").text)
    if tagJSObj['status'] == "OK":
        for t in tagJSObj['tags']:
            channel_name = re.sub(r'\W+', '', t['vanityName']).lower()
            channels[str(channel_name)] = {
                'tagID': t['id'],
                'last_value': -999,
                'data_type': "float",
                'last_time_uploaded': 0,
                'change_amount': (t['maxExpected'] - t['minExpected']) / 20,
                'min_time_between_uploads': min_upload_time
            }

# channels = {
#     "DC_Bus_Voltage": {
#         "last_value": -999,
#         "data_type": "float",
#         "change_amount": 5,
#         "last_time_uploaded": 0,
#         "min_time_between_uploads": 30
#     },
#     "Output_Frequency": {
#         "last_value": -999,
#         "data_type": "float",
#         "change_amount": 1,
#         "last_time_uploaded": 0,
#         "min_time_between_uploads": 30
#     },
#     "Output_Current": {
#         "last_value": -999,
#         "data_type": "float",
#         "change_amount": .2,
#         "last_time_uploaded": 0,
#         "min_time_between_uploads": 30
#     },
#     "Output_Voltage": {
#         "last_value": -999,
#         "data_type": "float",
#         "change_amount": 5,
#         "last_time_uploaded": 0,
#         "min_time_between_uploads": 30
#     }
# }


class start(threading.Thread, deviceBase):
    def updateGPS(self):
        gps = self.mcu.gps
        print("GPS found me at {0}".format(gps))
        self.sendtodb("gps", gps, 0)

    def __init__(self, name=None, number=None, mac=None, Q=None, mcu=None, companyId=None, offset=None, mqtt=None, Nodes=None):
        threading.Thread.__init__(self)
        deviceBase.__init__(self, name=name, number=number, mac=mac, Q=Q, mcu=mcu, companyId=companyId, offset=offset, mqtt=mqtt, Nodes=Nodes)

        self.daemon = True
        self.version = "3"
        self.device_address = addr
        self.finished = threading.Event()
        threading.Thread.start(self)
        self.sendtodbJSON("device_address", self.device_address, 0)
        setupChannels()
        self.updateGPS()
    # this is a required function for all drivers, its goal is to upload some piece of data
    # about your device so it can be seen on the web
    def register(self):
        channels["status"]["last_value"] = ""

    def run(self):
        self.runLoopStatus = ""
        last_OK_state = 0
        while True:
            if len(channels) > 0:
                try:
                    for i in channels:
                        runLoopStatus = i
                        valData = self.checkTag(channels[i]['tagID'])
                        if valData:
                            nowVal = valData['val']
                            ch = channels[i]
                            if (abs(ch['last_value'] - nowVal) > ch['change_amount']) or ((time.time() - ch['last_time_uploaded']) > ch['min_time_between_uploads']):
                                self.sendtodbJSON(i, nowVal, 0)
                                ch['last_time_uploaded'] = time.time()
                                ch['last_value'] = nowVal

                    runLoopStatus = "Complete"
                    OK_state = 1
                    if not OK_state == last_OK_state:
                        self.sendtodbJSON("driver_ok", OK_state, 0)
                        last_OK_state = OK_state
                    time.sleep(3)
                except Exception, e:
                    OK_state = 0
                    if not OK_state == last_OK_state:
                        self.sendtodbJSON("driver_ok", OK_state, 0)
                        last_OK_state = OK_state
                    sleep_timer = 20
                    print "Error during {0} of run loop: {1}\nWill try again in {2} seconds...".format(runLoopStatus, e, sleep_timer)
                    time.sleep(sleep_timer)
            else:
                setupChannels()
                time.sleep(30)

    def checkTag(self, tagID):
        tagData = json.loads(requests.get(self.device_address + "/json/val/"+str(tagID)).text)
        # {u'tag_val': {u'tagID': 1, u'dateAdded': u'2015-12-08T23:43:38.000Z', u'id': 60, u'val': 56}}
        return(tagData["tag_val"])

    def tagserver_sync(self, name, value):
        self.sendtodb("connected", "true", 0)
        return True

    def tagserver_address(self, name, value):
        self.device_address = value
        return True


    def tagserver_gpsUpdate(self, name, value):
        updateGPS()
        return True
