from io_module import IO_Module
from modbus import Modbus
from log_reader import AnalogInputLogReader
import colorama
from colorama import Fore
from time import sleep
from serial import Serial
from mb_registers import AoReg

class IO_AnalogOutput(IO_Module):

    def __init__(self, modbus: Modbus):
        self.modbus = modbus
        super().__init__(self.modbus)

    '''Чтение параметров'''

    # Значения состояний выходов вкл./выкл. (битовое поле)
    def get_outputs_state(self):
        data = self.modbus.read_holding_registers(AoReg.OUT_STATE.value, 1)
        if self.DBG: 
            print(Fore.GREEN +  f'Read reg {[hex(AoReg.OUT_STATE.value)]} outputs state: {format(data[0], '04b')}')
        return format(data[0], '04b')

    # Значения состояний выходов вкл./выкл. в безопасном режиме (битовое поле)
    def get_outputs_state_save(self):
        data = self.modbus.read_holding_registers(AoReg.OUT_STATE_SAVE.value, 1)
        if self.DBG: 
            print(Fore.GREEN +  f'Read reg {[hex(AoReg.OUT_STATE_SAVE.value)]} outputs state (SAVE MODE): {format(data[0], '04b')}')
        return format(data[0], '04b')

    # Режим работы аналоговых выходов (0 - напряжение или 1 - ток. (битовое поле))
    def get_outputs_mode(self):
        data = self.modbus.read_holding_registers(AoReg.OUT_MODE.value, 1)
        if self.DBG: 
            print(Fore.GREEN +  f'Read reg {[hex(AoReg.OUT_MODE.value)]} outputs mode: {format(data[0], '04b')}')
        return format(data[0], '04b')

    # Режим работы аналоговых выходов (0 - напряжение или 1 - ток. (битовое поле))
    def get_outputs_mode_save(self):
        data = self.modbus.read_holding_registers(AoReg.OUT_MODE_SAVE.value, 1)
        if self.DBG: 
            print(Fore.GREEN +  f'Read reg {[hex(AoReg.OUT_MODE_SAVE.value)]} outputs mode (SAVE MODE): {format(data[0], '04b')}')
        return format(data[0], '04b')

    # Питание выходных каналов
    def get_outputs_power(self):
        data = self.modbus.read_holding_registers(AoReg.OUT_POWER.value, 1)
        if self.DBG: 
            print(Fore.GREEN +  f'Read reg {[hex(AoReg.OUT_POWER.value)]} outputs power: {format(data[0], '04b')}')
        return format(data[0], '04b')

    '''Установка параметров'''

    # Значения состояний выходов вкл./выкл. (битовое поле)
    def set_outputs_state(self, val):
        if self.DBG:
            print(Fore.BLUE +  f'Write reg {[hex(AoReg.OUT_STATE.value)]} outputs state: {format(val, '04b')}')
        self.modbus.write_holding_register(AoReg.OUT_STATE.value, val)

    # Значения состояний выходов вкл./выкл. в безопасном режиме (битовое поле)
    def set_outputs_state_save(self, val):
        if self.DBG:
            print(Fore.BLUE +  f'Write reg {[hex(AoReg.OUT_STATE_SAVE.value)]} outputs state (SAVE MODE): {format(val, '04b')}')
        self.modbus.write_holding_register(AoReg.OUT_STATE_SAVE.value, val)

    # Значения состояний выходов вкл./выкл. (битовое поле)
    def set_outputs_mode(self, val):
        if self.DBG:
            print(Fore.BLUE +  f'Write reg {[hex(AoReg.OUT_MODE.value)]} outputs mode: {format(val, '04b')}')
        self.modbus.write_holding_register(AoReg.OUT_MODE.value, val)

    # Значения состояний выходов вкл./выкл. в безопасном режиме (битовое поле)
    def set_outputs_mode_save(self, val):
        if self.DBG:
            print(Fore.BLUE +  f'Write reg {[hex(AoReg.OUT_MODE_SAVE.value)]} outputs mode (SAVE MODE): {format(val, '04b')}')
        self.modbus.write_holding_register(AoReg.OUT_MODE_SAVE.value, val)

    # Установка значения вы выходе (относительные единицы)
    def set_ouputs_value(self, channel, val):
        if self.DBG:
            print(Fore.BLUE +  f'Write reg {[hex(AoReg.OUT_VALUE.value + channel - 1)]} output {channel} value: {val}')
        self.modbus.write_holding_register(AoReg.OUT_VALUE.value + channel - 1, val)

    # Установка значения вы выходе в безопасном режиме (относительные единицы)
    def set_ouputs_value_save(self, channel, val):
        if self.DBG:
            print(Fore.BLUE +  f'Write reg {[hex(AoReg.OUT_VALUE_SAVE.value + channel - 1)]} output {channel} value: {val}')
        self.modbus.write_holding_register(AoReg.OUT_VALUE_SAVE.value + channel - 1, val)


def main():
    colorama.init(autoreset=True)
    serial_port = Serial('COM24', 115200, timeout=0.05, parity='N', xonxoff=False)
    ao_modbus = Modbus(serial_port, 8)
    ao_modbus.MB_DEBUG = True
    ao = IO_AnalogOutput(ao_modbus)
    # ao.DBG = True

    '''Тесты отдельного модуля аналоговых выходов'''
    ao.sys.get_system_vars()
        
    '''Настройка аналоговых выходов'''
    # ao.set_outputs_state(0b1111)
    # ao.set_outputs_state_save(0b1111)
    # ao.set_outputs_mode(0b0000)
    # ao.set_outputs_mode_save(0b0000)

    '''Чтение режимов работы аналоговых выходов'''
    # ao.get_outputs_state()
    # ao.get_outputs_state_save()
    # ao.get_outputs_mode()
    # ao.get_outputs_mode_save()
    # ao.get_outputs_power()

    '''Установка значений на выходах'''
    # values = [50000, 50000, 50000, 50000]
    # ao.set_ouputs_value(1, values[0])
    # ao.set_ouputs_value(2, values[1])
    # ao.set_ouputs_value(3, values[2])
    # ao.set_ouputs_value(4, values[3])
    
    '''
    while True:
        ao.set_ouputs_value(4, values[0])
        values[0] += 100
        if values[0] >= 50000:
            values[0] = 0
        sleep(0.1)
    '''

    '''
    ao.set_ouputs_value(1, 12)
    ao.set_ouputs_value(2, 13)
    ao.set_ouputs_value(3, 14)
    ao.set_ouputs_value(4, 15)

    ao.set_ouputs_value_save(1, 17)
    ao.set_ouputs_value_save(2, 18)
    ao.set_ouputs_value_save(3, 19)
    ao.set_ouputs_value_save(4, 20)
    '''

    '''Сохранение настроек'''
    # ao.sys.save_sattings()

    '''Обновление прошивки'''
    # ao_modbus.MB_DEBUG = True
    # ao.updater.update('fw.bin', 'MAO_4')


if __name__ == '__main__':
    main()

