# Sensores y mediciones No hay sensores ubicados ni mediciones suministradas en el diseño inicial. La plantilla `datos/mediciones_plantilla.csv` contiene solamente cabecera. La posición, el instrumento y la calibración de cada sensor deben ser registrados por el investigador antes de importar datos. El porcentaje de polisombra se almacena en estructura y nunca se usa como humedad relativa. ## Registro del sensor En `sensors`, cada objeto requiere un ID S01, S02, …; `position` es un vector XYZ en metros, Z arriba. Es válido mantener `position=null` mientras se resuelve su ubicación, pero se rechazará la importación de mediciones para ese sensor. Un marcador gráfico no define el tamaño físico del instrumento y queda excluido de la prueba de colisiones. Los metadatos esperados son `variables` (lista de IDs de `measurement_variables`), `instrument_id`, `calibration_id` y `calibration={id,date,due_date,info}`. Las fechas de calibración usan `YYYY-MM-DD`; pueden permanecer `null` cuando no se conocen, con estado pendiente. El ID del registro de calibración debe coincidir con el del sensor y del CSV. Se guardan el registro y las coordenadas como copias en cada medición importada. La información del instrumento puede ampliarse con fabricante, modelo, número de serie, certificado, incertidumbre y protocolo, sin inferir esos campos. Las variables preparadas son `temperature` en `degC`, `relative_humidity` en `%`, `co2` en `ppm` e `illuminance` en `lx`. Son etiquetas de esquema; no constituyen rangos objetivo ni recomendaciones para el cultivo. El investigador puede añadir variables, definiendo un ID y una unidad no vacíos. Iluminancia no es una medida de irradiancia ni de radiación fotosintéticamente activa. La aplicación no convierte automáticamente unidades ni presupone equivalencias entre variables. ## Importación CSV La cabecera y su orden exacto son: ```csv timestamp,sensor_id,variable,value,unit,instrument_id,calibration_id,origin ``` `timestamp` requiere ISO 8601 con `T` y zona explícita, como formato `AAAA-MM-DDThh:mm:ss-05:00` o `AAAA-MM-DDThh:mm:ssZ`. Este patrón describe el formato, no una medición. Se conserva el desfase del tiempo recibido. El huso del navegador o del computador no se aplica a fechas sin zona; esas filas se rechazan. La fecha de la medición se comprueba contra la fecha y el vencimiento de calibración suministrados, usando la fecha local del sello recibido. Un protocolo que requiera otra zona de referencia debe normalizar los tiempos antes de la importación. `value` debe ser un número finito. `sensor_id`, variable, unidad, instrumento y calibración deben concordar con el diseño. Se rechazan columnas ausentes o adicionales, filas incompletas, coordenadas desconocidas, NaN/infinito, calibraciones registradas fuera de su vigencia y duplicados de `(tiempo UTC, sensor, variable, origen)` dentro del archivo. Un cambio en la unidad no convierte el valor. No se comprueba plausibilidad agronómica porque no se han definido protocolos o límites validados. `origin` acepta exactamente `measured` o `simulated`. Cada registro conserva este origen; una serie simulada nunca se reclasifica como real. Series con distinto origen se mantienen distinguibles aunque compartan sensor y tiempo. La interfaz debe filtrar y rotular ambos orígenes por separado antes de cualquier análisis o figura. El importador no sintetiza datos ni rellena huecos. La función `import_measurements(design,csv_text)` valida todo el archivo y devuelve una lista de registros enriquecidos con `coordinate_snapshot_m`, `calibration_snapshot`, `calibration_status`, `design_version` y `design_hash`. Si alguna fila es inválida, lanza `ValueError` con errores por fila y no devuelve una importación parcial. La función no escribe archivos. Si la fecha de calibración es desconocida, el registro indica `calibration_status=PENDIENTE DE VERIFICACIÓN`; disponer de un ID no demuestra trazabilidad metrológica ni calibración válida. La campaña debe conservar el diseño completo que corresponde al hash. La detección de duplicados abarca un archivo; para combinar campañas o importaciones sucesivas, el repositorio futuro debe aplicar una restricción de unicidad que incluya `campaign_id`. La función de dominio devuelve datos en memoria. La ruta local `/api/measurements` guarda los registros validados en `datos/importaciones/` con un nombre temporal único y la interfaz muestra esa ubicación. Las instantáneas de campaña se guardan mediante su acción independiente. No hay una base de datos ni se precargan automáticamente importaciones antiguas en el visor. Conserve las carpetas de datos junto con las versiones del diseño. ## Integración futura `integration` declara puntos previstos para ESP32/API HTTP y un adaptador MQTT. El tema previsto es `pleurotus/{campaign_id}/{sensor_id}/{variable}`. Esta versión no abre conexiones ni contiene un broker, firmware, servidor de ingestión, autenticación, sincronización de reloj o gestión de secretos. El JSON no almacena credenciales. El adaptador futuro deberá convertir mensajes al mismo contrato del CSV, validar metadatos contra la instantánea de campaña y conservar `origin` sin mezclar mediciones y simulaciones. La disponibilidad de una lectura requiere además comprobar instalación, ubicación real del sensor, protocolo de calibración, sincronización temporal y calidad de datos. Nada de ello ha sido validado físicamente por esta aplicación.