import smbus
import time
import json
import sys

pruefer1  = 0x20
pruefer2  = 0x21
observer1 = 0x22
observer2 = 0x23
spurkabel1 = 0x24
spurkabel2 = 0x25

adressen = [pruefer1, pruefer2, observer1, observer2, spurkabel1, spurkabel2]

IODIRA = 0x00  # Eingang / Ausgang A
IODIRB = 0x01  # Eingang / Ausgang B
GPPUA = 0x0C  # Eingang / Ausgang A
GPPUB = 0x0D  # Eingang / Ausgang B
GPIOA = 0x12   # GPIO A
GPIOB = 0x13   # GPIO B

array = {}
logs = {}
data = []


try:
    # Initialisiere den I2C Bus
    bus = smbus.SMBus(1)
except:
    logs["errorcode"] = 12
    array["logs"] = logs
    json_output = json.dumps(array)
    print(json_output)
    sys.exit(0)

def default():

    #Schleife für alle Registeradressen (0x00 bis 0x15)
    for register in range(0x00, 0x16):
        for adresse in adressen:
            #print("Setze " + str(adresse) + " in Register " + str(register) + " auf Wert 0x00")
            bus.write_byte_data(adresse, register, 0x00)
    
    
    #print("Hallo! Es wird damit begonnen, alle Register zurpckzusetzen...")
    #Aktiviere alle Pullups und setze alle als Eingang
    time.sleep(0.05)
    for adresse in adressen:
        bus.write_byte_data(adresse, IODIRA, 0xFF)
        bus.write_byte_data(adresse, GPPUA, 0xFF)
        bus.write_byte_data(adresse, IODIRB, 0xFF)
        bus.write_byte_data(adresse, GPPUB, 0xFF)

    #print("============= Reset erfolgreich! =============")
            
def main():
    try:
        default()
    except:
        logs["errorcode"] = 11
        return
    for pin in range(32):  # 0 bis 31
        aktuellAn = pin
    
        for adresse in adressen:
            bus.write_byte_data(adresse, IODIRA, 0xFF)
            bus.write_byte_data(adresse, GPPUA, 0xFF)
            bus.write_byte_data(adresse, IODIRB, 0xFF)
            bus.write_byte_data(adresse, GPPUB, 0xFF)
    
        time.sleep(0.05)
        
        if pin < 16:
            # Setze den gewählten Pin auf HIGH
            if pin < 8:  # Pins A0-A7
            
                wert = 0xFF & ~(1 << pin)  # Alle Bits auf 1, außer das eine gewünschte auf 0
                
                bus.write_byte_data(pruefer1, GPPUA, wert)
                bus.write_byte_data(pruefer1, IODIRA, wert)
                bus.write_byte_data(pruefer1, GPIOA, 0x00)

            else:  # Pins B0-B7
                wert = 0xFF & ~(1 << pin - 8)  # Alle Bits auf 1, außer das eine gewünschte auf 0
                
                bus.write_byte_data(pruefer1, GPPUB, wert)
                bus.write_byte_data(pruefer1, IODIRB, wert)
                bus.write_byte_data(pruefer1, GPIOB, 0x00)
        else:
            # Setze den gewählten Pin auf HIGH
            if pin < 24:  # Pins A0-A7
                wert = 0xFF & ~(1 << pin - 16)  # Alle Bits auf 1, außer das eine gewünschte auf 0
                
                bus.write_byte_data(pruefer2, GPPUA, wert)
                bus.write_byte_data(pruefer2, IODIRA, wert)
                bus.write_byte_data(pruefer2, GPIOA, 0x00)
            else:  # Pins B0-B7
                wert = 0xFF & ~(1 << pin - 24)  # Alle Bits auf 1, außer das eine gewünschte auf 0
                
                bus.write_byte_data(pruefer2, GPPUB, wert)
                bus.write_byte_data(pruefer2, IODIRB, wert)
                bus.write_byte_data(pruefer2, GPIOB, 0x00)
        
        time.sleep(0.05)
        
        ##print(f"i2cget -y 1 0x20 0x12")
        pruefer1_A_value = bus.read_byte_data(pruefer1, GPIOA)
        pruefer1_B_value = bus.read_byte_data(pruefer1, GPIOB)
        pruefer2_A_value = bus.read_byte_data(pruefer2, GPIOA)
        pruefer2_B_value = bus.read_byte_data(pruefer2, GPIOB)
        
        observer1_A_value = bus.read_byte_data(observer1, GPIOA)
        observer1_B_value = bus.read_byte_data(observer1, GPIOB)
        observer2_A_value = bus.read_byte_data(observer2, GPIOA)
        observer2_B_value = bus.read_byte_data(observer2, GPIOB)
        
        spurkabel1_A_value = bus.read_byte_data(spurkabel1, GPIOA)
        spurkabel1_B_value = bus.read_byte_data(spurkabel1, GPIOB)
        spurkabel2_A_value = bus.read_byte_data(spurkabel2, GPIOA)
        spurkabel2_B_value = bus.read_byte_data(spurkabel2, GPIOB)
        
        #print(f"------>>>>Es konnte vom pruefer1_A_value der Wert  {format(pruefer1_A_value, '08b')} festgetsellt werden")
        #print(f"------>>>>Es konnte vom pruefer1_B_value der Wert  {format(pruefer1_B_value, '08b')} festgetsellt werden")
        #print(f"------>>>>Es konnte vom pruefer2_A_value der Wert  {format(pruefer2_A_value, '08b')} festgetsellt werden")
        #print(f"------>>>>Es konnte vom pruefer2_B_value der Wert  {format(pruefer2_B_value, '08b')} festgetsellt werden")
        
        #print(f"------>>>>Es konnte vom observer1_A_value der Wert  {format(observer1_A_value, '08b')} festgetsellt werden")
        #print(f"------>>>>Es konnte vom observer1_B_value der Wert  {format(observer1_B_value, '08b')} festgetsellt werden")
        #print(f"------>>>>Es konnte vom observer2_A_value der Wert  {format(observer2_A_value, '08b')} festgetsellt werden")
        #print(f"------>>>>Es konnte vom observer2_B_value der Wert  {format(observer2_B_value, '08b')} festgetsellt werden")
        
        #print(f"------>>>>Es konnte vom spurkabel1_A_value der Wert  {format(spurkabel1_A_value, '08b')} festgetsellt werden")
        #print(f"------>>>>Es konnte vom spurkabel1_B_value der Wert  {format(spurkabel1_B_value, '08b')} festgetsellt werden")
        #print(f"------>>>>Es konnte vom spurkabel2_A_value der Wert  {format(spurkabel2_A_value, '08b')} festgetsellt werden")
        #print(f"------>>>>Es konnte vom spurkabel2_B_value der Wert  {format(spurkabel2_B_value, '08b')} festgetsellt werden")
        
        #print("===========================================================================")
        
        
        for j in range(8): # Verarbeite 4*8=32 Pins + Jeweils 32 Observer- und Spurkabel-Daten
            bitmaske = 1 << j  # Erstelle eine Maske: 1, 2, 4, 8, 16, ...
            
            pruefer1_A_value_bit = bool(pruefer1_A_value & bitmaske) 
            pruefer1_B_value_bit = bool(pruefer1_B_value & bitmaske)
            pruefer2_A_value_bit = bool(pruefer2_A_value & bitmaske) 
            pruefer2_B_value_bit = bool(pruefer2_B_value & bitmaske)
            
            observer1_A_value_bit = bool(observer1_A_value & bitmaske) 
            observer1_B_value_bit = bool(observer1_B_value & bitmaske)
            observer2_A_value_bit = bool(observer2_A_value & bitmaske) 
            observer2_B_value_bit = bool(observer2_B_value & bitmaske)
            
            spurkabel1_A_value_bit = bool(spurkabel1_A_value & bitmaske) 
            spurkabel1_B_value_bit = bool(spurkabel1_B_value & bitmaske)
            spurkabel2_A_value_bit = bool(spurkabel2_A_value & bitmaske) 
            spurkabel2_B_value_bit = bool(spurkabel2_B_value & bitmaske)
            
            
            
            i = j
            


            if spurkabel1_A_value_bit == False:
                data.append([[pin ,i],0])

            if pruefer1_A_value_bit == False and observer1_A_value_bit == True:
                data.append([[pin ,i],2])
                #print("Prüfer sagt NEIN, Observer sagt JA");
            if pruefer1_A_value_bit == True and observer1_A_value_bit == False:
                data.append([[pin ,i],3])
                #print("Prüfer sagt JA, Observer sagt NEIN");
            
            
            i = j + 8
            

            if spurkabel1_B_value_bit == False:
                data.append([[pin ,i],0])

            if pruefer1_B_value_bit == False and observer1_B_value_bit == True:
                data.append([[pin ,i],2])
                #print("Prüfer sagt NEIN, Observer sagt JA");
            if pruefer1_B_value_bit == True and observer1_B_value_bit == False:
                data.append([[pin ,i],3])
                #print("Prüfer sagt JA, Observer sagt NEIN");
                
            
            i = j + 16


            if spurkabel2_A_value_bit == False:
                data.append([[pin ,i],0])

            if pruefer2_A_value_bit == False and observer2_A_value_bit == True:
                data.append([[pin ,i],2])
                #print("Prüfer sagt NEIN, Observer sagt JA");
            if pruefer2_A_value_bit == True and observer2_A_value_bit == False:
                data.append([[pin ,i],3])
                #print("Prüfer sagt JA, Observer sagt NEIN");

                
            i = j + 24

            if spurkabel2_B_value_bit == False:
                data.append([[pin ,i],0])

            if pruefer2_B_value_bit == False and observer2_B_value_bit == True:
                data.append([[pin ,i],2])
                #print("Prüfer sagt NEIN, Observer sagt JA");
            if pruefer2_B_value_bit == True and observer2_B_value_bit == False:
                data.append([[pin ,i],3])
                #print("Prüfer sagt JA, Observer sagt NEIN");

    logs["errorcode"] = 10
    
if __name__ == "__main__":
    try:
        main()
    except:
        logs["errorcode"] = 13
    array["logs"] = logs
    array["data"] = data
    json_output = json.dumps(array)
    print(json_output)



        
