"""
Interface: esp32
Nom du projet: Nouveau projet
Description: 
Toolbox: vittascience
Mode: blocks

Blocks: <xml xmlns="https://developers.google.com/blockly/xml"><variables><variable id="$#kRv$P#1,db_2=jtn8h">image_data</variable></variables><block type="on_start" id="G[=T#8yqB70`NFgYq}GP" deletable="false" x="13" y="12"><statement name="DO"><block type="esp32Cam_setImageSize" id="bk#m.nx@FbG{@Ho(k%up"><field name="FRAMESIZE">VGA</field></block></statement></block><block type="forever" id="o[WN]+eeF.OUxGch67@8" x="13" y="187"><statement name="DO"><block type="variables_set" id="8b]$BUz_LV;e@4OCR+f="><field name="VAR" id="$#kRv$P#1,db_2=jtn8h">image_data</field><value name="VALUE"><shadow type="math_number" id="ML@[U:exUfwGPxFSD,45"><field name="NUM">0</field></shadow><block type="esp32Cam_getCaptureData" id="A~`dc_)}:/=xsdq89eo?"><field name="BASE">BASE64</field></block></value><next><block type="esp32Cam_SDcard_savePic" id="~uoYe[Hrf}U`+Z9n5rP+"><field name="BASE">BASE64</field><value name="DATA"><block type="variables_get" id="2/M;Kvc)5)-Iiv,zm)iB"><field name="VAR" id="$#kRv$P#1,db_2=jtn8h">image_data</field></block></value><next><block type="io_pause" id="EkvyV:hwq.r~1~s,Dkxe"><field name="UNIT">SEC</field><value name="TIME"><shadow type="math_number" id="Dn5t3]u*~b$5LE]QKtKd"><field name="NUM">10</field></shadow></value></block></next></block></next></block></statement></block></xml>

Projet généré par Vittascience.
Ce fichier contient le code textuel ainsi que le code blocs. Il peut être importé de nouveau
sur l'interface http://vittascience.com/esp32

"""

from machine import *
import camera
import utime
import binascii
import os
import sdcard

DISPLAY_RESOLUTIONS = [
  ('96X96', [96, 96]), ('QQVGA', [160, 120]), ('QCIF', [176, 144]), ('HQVGA', [240, 176]), ('240X240', [240, 240]), ('QVGA', [320, 240]),
  ('CIF', [400, 296]), ('HVGA', [480, 320]), ('VGA', [640, 480]), ('SVGA', [800, 600]), ('XGA', [1024, 768]), ('HD', [1280, 720]),
  ('SXGA', [1280, 1024]), ('UXGA', [1600, 1200]), ('FHD', [1920, 1080]), ('P_HD', [720, 1280]), ('P_3MP', [864, 1536]), ('QXGA', [2048, 1536])
]
CAM_FRAMESIZE = DISPLAY_RESOLUTIONS.index([i for i in DISPLAY_RESOLUTIONS if 'VGA' in i][0]) + 1

cameraStatus = False
spi = SPI(1, 1000000, sck=Pin(14), mosi=Pin(15), miso=Pin(2))
sd = sdcard.SDCard(spi, Pin(13))
rtc = RTC()

def ESP32CAM_initialize(size):
  global cameraStatus
  if not cameraStatus:
    try:
      print("Initialize ESP32 Camera ...")
      if 'JPEG' in dir(camera):
        status = camera.init(0, format=camera.JPEG)
      else:
        status = camera.init()
      if not status:
        reset()
    except OSError:
      print('Unable to initialize ESP32 Camera.')
      reset()
    camera.framesize(size)
    cameraStatus = True
    utime.sleep_ms(200)
  print("Camera ready.")

def ESP32CAM_capture(base64 = True):
  try:
    ESP32CAM_initialize(CAM_FRAMESIZE)
  except:
    ESP32CAM_initialize(DISPLAY_RESOLUTIONS.index([i for i in DISPLAY_RESOLUTIONS if 'VGA' in i][0]) + 1)
  for i in range(3):
    try:
      data = camera.capture()
      if data:
        if base64:
          return binascii.b2a_base64(data)
        else:
          return data
    except Exception as e:
      print(e)
    utime.sleep_ms(100)
  print("[ESP32-CAM] Unable to capture. The camera may need more light or was not initialized.")

def SDCard_writeFile(data, filename = "", mode = 'w', extension = 'txt', date = False, sd = False):
  if extension in ['jpeg', 'jpg', 'png']:
    mode = 'wb'
  if mode is 'wb' and not isinstance(data, bytes):
    print("[Storage_INFO] Data not available to store.")
  else:
    if date:
      try:
        rtc.datetime()
      except:
        rtc = RTC()
      filename += '_' + str(utime.time())
    else:
      fs = os.listdir()
      if (filename + '.' + extension) in fs:
        mode = 'a'
      else:
        mode = 'w'
    filename += '.' + extension
    with open(('/sd/' if sd else '') + filename, mode) as file:
      file.write(data if mode is 'wb' else str(data))
      file.close()
    print("[Storage_INFO] File '" + filename + "' in " + ("SD card." if sd else "ESP32 filestorage."))

try:
  os.mount(sd, '/sd')
except OSError as e:
  print("OSError: " + str(e))
  reset()
#Warning, the clock is recovered by browser when ESP32 is flashed.
#If ESP32 is powered off, time will not flow.
rtc.datetime((2026, 2, 3, 2, 14, 38, 57, 0))

while True:
  image_data = ESP32CAM_capture(True)
  SDCard_writeFile(binascii.a2b_base64(image_data), filename='esp32-cam', date=True, extension='jpg', sd = True)
  utime.sleep(10)
