import smbus
import time
import json
import sys

pruefer = 0x20
observer = 0x22


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():
    #adressen = [pruefer]

    # Schleife für alle Registeradressen (0x00 bis 0x15)
    #for register in range(0x00, 0x16):
    #    for adresse in adressen:
    #        time.sleep(0.05)
    #        #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...")
    time.sleep(0.05)
    bus.write_byte_data(pruefer, IODIRA, 0xFF)
    bus.write_byte_data(observer, IODIRA, 0xFF)
    
    bus.write_byte_data(pruefer, GPPUA, 0xFF)
    bus.write_byte_data(observer, GPPUA, 0xFF)
    #print("============= Reset erfolgreich! =============")
            
def main():
    try:
        default()
    except:
        logs["errorcode"] = 11
        return
    time.sleep(0.05)
    for pin in range(8):  # 0 bis 7
        wert = 0xFF & ~(1 << pin)  # Alle Bits auf 1, außer das eine gewünschte auf 0
        #print("======== Setze Pin " + str(pin) + " auf den Wert " +  format(wert, '08b'));
        

        bus.write_byte_data(pruefer, GPPUA, wert)
        bus.write_byte_data(pruefer, IODIRA, wert) # Setze einzeln als Ausgang    111011111 usw...
        bus.write_byte_data(pruefer, GPIOA, 0x00) # Deaktiviere alle pins (es reagiert sowieso nur der Ausgang, dh keine Bitmaske erforderlich)  00000000 usw..
        
        time.sleep(0.05)
        
        ##print(f"i2cget -y 1 0x20 0x12")
        Wert_pruefer = bus.read_byte_data(pruefer, GPIOA)
        Wert_observer = bus.read_byte_data(observer, GPIOA)
        
        #print(f"------>>>>Es konnte vom Pruefer der Wert   {format(Wert_pruefer, '08b')} festgetsellt werden")
        #print(f"------>>>>Es konnte vom Observer der Wert  {format(Wert_observer, '08b')} festgetsellt werden")
        
        ok = 0
        
        for j in range(8): # Lese 4*8=32 Pins
            bitmaske = 1 << j  # Erstelle eine Maske: 1, 2, 4, 8, 16, ...
            
            Bit_pruefer = bool(Wert_pruefer & bitmaske) 
            Bit_observer = bool(Wert_observer & bitmaske)

            if Bit_observer == False: # Prüfe, ob aktueller Pin wirklich 0 sein darf
                if j == pin:
                    ok = 1
            if Bit_pruefer == False and j != pin:
                #print("Gefunden: " + str(pin) + " <> " + str(j));
                if Bit_observer == False:
                    #print("Dies wurde vom Observer bestätigt!");
                    data.append([[pin ,j],0])
                else:
                    #print("Konnte NICHT bestätigen!");
                    data.append([[pin ,j],1])
            if Bit_pruefer == False and Bit_observer == True:
                data.append([[pin ,j],2])
                #print("Prüfer sagt NEIN, Observer sagt JA");
            if Bit_pruefer == True and Bit_observer == False:
                data.append([[pin ,j],3])
                #print("Prüfer sagt JA, Observer sagt NEIN");
                

        
        if ok != 1:
            #print("Fehler beim Aufruf von Pin " + str(pin) + "! Es konnte nicht bestätigt werden, dass dieser Pin tatsächlich LOW ist!");
            data.append([[pin ,"???"],4])

    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)



        
