#!/usr/bin/env python3
# coding=utf-8
""" WiBotic Wrapper Sample"""

__copyright__ = "Copyright 2018 WiBotic Inc."
__version__ = "0.1"
__email__ = "info@wibotic.com"
__status__ = "Technology Preview"

from wiboticwrapper import WiboticWrapper
import asyncio
import packettools
import datetime

# Useful Charger states to know
# 0 Off
# 1 Charging - ramp up
# 2 Charging - constant current
# 3 Charging - constant voltage
# 4 battery full
# 5 stopping
# 6 alarm
# 7 stabilizing

class WiboticSample:

    def __init__(self, websocket_url, commandTimeout=5.0, adcTimeout=2.0):
        self.websocketUrl = websocket_url
        self.commandTimeout = commandTimeout
        self.adcTimeout = adcTimeout
        self.wibotic = WiboticWrapper(self.websocketUrl,  
                                        commandTimeout=self.commandTimeout,
                                        adcTimeout=self.adcTimeout)

    async def setup(self):
        # Connect to the transmitter
        await self.wibotic.connect()
        # wait a second for some ADC packets to come in
        await asyncio.sleep(1)

    async def shutdown(self):
        # set ChargeEnable to False
        response = await self.wibotic.updateParameter(packettools.DeviceID.TX, packettools.ParamID.ChargeEnable, False) 
        if response is not None and response.status == packettools.ParamStatus.SUCCESS:
            print('Successfully set the ChargeEnable setting to False')
        else:
            print('Command Failure')
            print (response)
        await self.wibotic.disconnect()   

    async def doSomeThings(self):
        # set ChargeEnable to True
        response = await self.wibotic.updateParameter(packettools.DeviceID.TX, packettools.ParamID.ChargeEnable, True) 
        if response is not None and response.status == packettools.ParamStatus.SUCCESS:
            print('Successfully set the ChargeEnable setting to True')
        else:
            print('Command Failure')
            print (response)

        # get the Build hash of the Transmitter firmware
        response = await self.wibotic.readParameter(packettools.DeviceID.TX, packettools.ParamID.BuildHash)
        if response is not None:
            print('Transmitter Build Hash: %x' % response.value)
        else:
            print('Failed to get buildhash from transmitter')

        # get the Build hash of the Receiver firmware
        if self.wibotic.receiverConnected():
            response = await self.wibotic.readParameter(packettools.DeviceID.RX_1, packettools.ParamID.BuildHash)
            if response is not None:
                print('Receiver Build Hash: %x' % response.value)
            else:
                print('Failed to get buildhash from receiver')

        # get the Transmitter MAC address
        txmacoui = 0
        txmacspecific = 0
        response = await self.wibotic.readParameter(packettools.DeviceID.TX, packettools.ParamID.DevMACOUI)
        if response is not None:
            txmacoui = response.value
        else:
            print('Failed to retrieve TX DevMACOUI setting')
        response = await self.wibotic.readParameter(packettools.DeviceID.TX, packettools.ParamID.DevMACSpecific)
        if response is not None:
            txmacspecific = response.value
        else:
            print('Failed to retrieve TX DevMACSpecific setting')
        if txmacoui != 0 and txmacspecific != 0:
            print('Transmitter MAC Address: %06x%06x' % (txmacoui,txmacspecific))

        # get the Receiver MAC address
        if self.wibotic.receiverConnected():
            rxmacoui = 0
            rxmacspecific = 0
            response = await self.wibotic.readParameter(packettools.DeviceID.RX_1, packettools.ParamID.DevMACOUI)
            if response is not None:
                rxmacoui = response.value
            else:
                print('Failed to retrieve RX_1 DevMACOUI setting')
            response = await self.wibotic.readParameter(packettools.DeviceID.RX_1, packettools.ParamID.DevMACSpecific)
            if response is not None:
                rxmacspecific = response.value
            else:
                print('Failed to retrieve RX_1 DevMACSpecific setting')
            if rxmacoui != 0 and rxmacspecific != 0:
                print('Receiver MAC Address: %06x%06x' % (rxmacoui,rxmacspecific))

        # now let us go in a loop and take a peek at the Adc data as it comes back
        while True:
            print('===================================================')
            await asyncio.sleep(1)
            timenow = datetime.datetime.now()
            txvalues =  self.wibotic.lastTxAdcUpdate.values

            # Any Tx ADC updates?
            if self.wibotic.transmitterConnected():
                # print all data if desired
                # print(wibotic.lastTxAdcUpdate)
                age = timenow - self.wibotic.lastTxAdcUpdateTime
                print('Transmitter data %dms old' % (age.total_seconds()*1000))
                print('Transmitter Power Level: %d' % txvalues[packettools.AdcID.PowerLevel])


            # Any Rx ADC updates
            if self.wibotic.receiverConnected():
                # print all data if desired
                # print(wibotic.lastRxAdcUpdate)
                rxvalues = self.wibotic.lastRxAdcUpdate.values
                age = timenow - self.wibotic.lastRxAdcUpdateTime
                print('Receiver data %dms old' % (age.total_seconds()*1000))            
                print('Receiver Battery Voltage: %0.2fV' % rxvalues[packettools.AdcID.VMonBatt])
                print('Receiver Battery Charge State: %d' % rxvalues[packettools.AdcID.ChargeState])
                print('Receiver Battery Charge Current: %0.2fA' % rxvalues[packettools.AdcID.IBattery])
                print('Receiver Temperature: %0.1fC' %  (rxvalues[packettools.AdcID.TBoard]/100))

            # if both transmitter and receiver are connected, and we're charging 
            # (either ramping up, constant current, or constant voltage)
            if (self.wibotic.transmitterConnected() and
                self.wibotic.receiverConnected() and
                    (rxvalues[packettools.AdcID.ChargeState] == 1 or
                    rxvalues[packettools.AdcID.ChargeState] == 2 or 
                    rxvalues[packettools.AdcID.ChargeState] == 3) and
                    (txvalues[packettools.AdcID.VMonPa] *
                    txvalues[packettools.AdcID.IMonPa]) > 0
                ):
                efficiency = (100 * (rxvalues[packettools.AdcID.VMonBatt] *
                                rxvalues[packettools.AdcID.IBattery]) /
                                (txvalues[packettools.AdcID.VMonPa] *
                                 txvalues[packettools.AdcID.IMonPa]))
                print('Charging efficiency: %0.1f%%' % efficiency)
            

if __name__ == "__main__":
    WIBOTIC_CHARGER_WS_URL = "ws://192.168.2.20/ws"
    WIBOTIC_COMMAND_TIMEOUT = 5
    WIBOTIC_ADC_TIMEOUT = 2
    sample = WiboticSample(WIBOTIC_CHARGER_WS_URL, 
            commandTimeout=WIBOTIC_COMMAND_TIMEOUT,
            adcTimeout=WIBOTIC_ADC_TIMEOUT)

    loop = asyncio.get_event_loop()
    loop.run_until_complete(sample.setup())
    try:
        loop.run_until_complete(sample.doSomeThings())
    except KeyboardInterrupt as e:
        print('CTRL-C detected - shutting down...')
        loop.run_until_complete(sample.shutdown())




