import network,aioespnow,asyncio,time,json,cryptolib,uselect,sys,os,ubinascii;from machine import Pin,Timer
oddaj={"izvor":"vrstnik","izvor_mac":"","cilj":"vrstnik_cilj","cilj_mac":b'\xff\xff\xff\xff\xff\xff',"dbm":"-7","ttl":"4","no":"1","podatek":""}
stanje={"telegram":"ne","poslano":"ne","telegrami":"ne","vrstniki":"ne","aktiven":"0"}
vrstniki=[]#vrstnik={"vrstnik-mac":"","vrstnik-ime":"","vrstnik-ttl":"","posrednik-mac":"","posrednik-dbm":""}
def stanje_zapis():
 f = open('/oddaj.txt', 'w');f.write(str(oddaj));f.close()
try:f = open("/oddaj.txt", "r");f.close();found = True
except:found = False
if found:f = open("/oddaj.txt", "r");oddaj=eval(f.read(256));f.close();
else:stanje_zapis()
def telegram(kljuc,podatek):oddaj[kljuc]=podatek;datoteka = open('oddaj.txt', 'w');datoteka.write(json.dumps(oddaj));datoteka.close()
def naredi_geslo(length=16):random_bytes = os.urandom(length);return ubinascii.hexlify(random_bytes).decode()
geslo = naredi_geslo()
podatki = b'0123456789012345'
šifra1 = cryptolib.aes(geslo,1)
šifra2 = cryptolib.aes(geslo,1)
kodirani_podatki = šifra1.encrypt(podatki)
odkodirani_podatki = šifra2.decrypt(kodirani_podatki)
tipka=Pin(9,Pin.IN);rdeca=Pin(3,Pin.OUT, Pin.PULL_DOWN);zelena=Pin(4,Pin.OUT);modra=Pin(5,Pin.OUT);#ESP32-S3 tipka=Pin(9,Pin.IN);modra=Pin(8,Pin.OUT, Pin.PULL_DOWN);#ESP32-C3_Mini_V1
def funkcija():modra.value(False);časovnik.deinit()
časovnik = Timer(0);časovnik.init(period=100, mode=Timer.PERIODIC, callback=lambda t:funkcija())
sta = network.WLAN(network.STA_IF);sta.active(True);mac = sta.config('mac');Izvor_mac=':'.join('%02x' % b for b in mac);oddaj['izvor_mac']=Izvor_mac
sta.config(channel=1);sta.disconnect();e = aioespnow.AIOESPNow()
try:e.active(True)
except OSError as err:print("Napaka AIOESPNow:", err);raise
def dodaj_mac(mac):
  try:e.add_peer(mac)
  except OSError as err:print("Napaka:", err);raise
dodaj_mac(b'\xff\xff\xff\xff\xff\xff')
async def oddaja(e, peer):
            if await e.asend(peer, json.dumps(stanje), sync=True):
                if stanje["telegrami"]=="da":print(f"Poslano : {telegram}")
            else:print("Napaka")
async def sprejem(e):
    while True:
        try:
            async for mac, msg in e:
                telegram = json.loads(msg.decode('ascii'))
                if stanje["telegrami"]=="da":print(f"Sprejem:{mac.hex()} : {e.peers_table} : {telegram}")
                časovnik.init(period=100, mode=Timer.PERIODIC, callback=lambda t:funkcija());modra.value(True)
        except OSError as err:
            print("Error:", err);await asyncio.sleep(5)
async def sekunda(e):
    while True:
        await oddaja(e,b'\xff\xff\xff\xff\xff\xff')
        if stanje["telegram"]=="da" or stanje["poslano"]=="da":print('----------------------------------------');print('stanje= '+str(stanje))
        if stanje["telegram"]=="da":print('telegram=',oddaj)
        if stanje["vrstniki"]=="da":print('vrstnik=',vrstniki)
        if stanje["poslano"]=="da":stats = e.stats();print('poslano= '+str(stats[0])+' dostavljeno= '+str(stats[1])+' nedostavljeno= '+str(stats[2])+' sprejeto= '+str(stats[3])+' nesprejeto= '+str(stats[4]))
        stanje["aktiven"]=str(int(stanje["aktiven"])+1)  
        await asyncio.sleep(1)
def izpis(x):
        if   len(x)>1 :#ukaz in parameter
           if   x[0]=='telegram':stanje['telegram']=x[1];print(stanje)
           elif x[0]=='telegrami':stanje['telegrami']=x[1];print(stanje)
           elif x[0]=='poslano':stanje['poslano']=x[1];print(stanje)
           elif x[0]=='vrstniki':stanje['vrstniki']=x[1];print(stanje)
           elif x[0]=='izvor':oddaj['izvor']=x[1];stanje_zapis();print(oddaj)
           else               :print("neznan ukaz(poskusi stanje), Ctrl-C Konec")
        elif len(x)==1:#samo  ukaz   
           if   x[0]=='stanje' or x[0]=='s':
             print('-----------------------------------------------------------');print('stanje= '+str(stanje));stats = e.stats();print('poslano= '+str(stats[0])+' dostavljeno= '+str(stats[1])+' nedostavljeno= '+str(stats[2])+' sprejeto= '+str(stats[3])+' nesprejeto= '+str(stats[4]))
             for vrstnik in vrstniki:print('vrstniki=',vrstnik)
        else:print("neznan ukaz(poskusi stanje, Ctrl-c Konec)")
poll = uselect.poll();poll.register(sys.stdin, uselect.POLLIN)
async def vhod(e):
    while True:
      try:
       if poll.poll(0):vhod = sys.stdin.readline().strip();x=vhod.split();izpis(x)
      except OSError as err:print("Napaka:", err)
      await asyncio.sleep(0.001)
async def main(e):await asyncio.gather(sprejem(e), sekunda(e),vhod(e))
try:asyncio.run(main(e))
except KeyboardInterrupt:
    e.active(False);sta.active(False)