or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

device-motion.mdenvironmental-sensors.mdindex.mdmagnetic-sensors.mdmotion-sensors.mdpedometer.md
tile.json

environmental-sensors.mddocs/

Environmental Sensors

Barometer and light sensor capabilities for measuring atmospheric pressure, altitude, and ambient light conditions.

Capabilities

Barometer

Provides access to the device's barometer for measuring atmospheric pressure and calculating relative altitude.

/**
 * Barometer sensor instance providing access to atmospheric pressure data
 * @platform android
 * @platform ios
 */
declare const Barometer: BarometerSensor;

interface BarometerSensor extends DeviceSensor<BarometerMeasurement> {
  /**
   * Subscribe for updates to the barometer
   * @param listener - Callback invoked when barometer update is available
   * @returns Subscription that can be removed when done
   */
  addListener(listener: Listener<BarometerMeasurement>): Subscription;
  
  /**
   * Check the availability of the device barometer. Requires at least Android 2.3 (API Level 9) and iOS 8
   * @returns Promise resolving to boolean denoting availability
   */
  isAvailableAsync(): Promise<boolean>;
}

interface BarometerMeasurement {
  /** Measurement in hectopascals (hPa) */
  pressure: number;
  /** Measurement in meters (m) - iOS only */
  relativeAltitude?: number;
  /** Timestamp of the measurement in seconds */
  timestamp: number;
}

Usage Examples:

import { Barometer } from "expo-sensors";

// Check availability
const isAvailable = await Barometer.isAvailableAsync();
if (!isAvailable) {
  console.log("Barometer not available on this device");
  return;
}

// Subscribe to barometer updates
const subscription = Barometer.addListener(({ pressure, relativeAltitude, timestamp }) => {
  console.log(`Atmospheric pressure: ${pressure.toFixed(2)} hPa`);
  
  // iOS provides relative altitude
  if (relativeAltitude !== undefined) {
    console.log(`Relative altitude: ${relativeAltitude.toFixed(2)} m`);
  }
  
  // Convert pressure to different units
  const pressureInBar = pressure / 1000;
  const pressureInPsi = pressure * 0.0145038;
  const pressureInInHg = pressure * 0.02953;
  
  console.log(`Pressure: ${pressureInBar.toFixed(4)} bar, ${pressureInPsi.toFixed(2)} psi, ${pressureInInHg.toFixed(2)} inHg`);
});

// Set update interval for weather monitoring
Barometer.setUpdateInterval(30000); // 30 seconds

// Clean up
subscription.remove();

Weather Monitoring:

import { Barometer } from "expo-sensors";

interface WeatherReading {
  pressure: number;
  trend: 'rising' | 'falling' | 'stable';
  weatherPrediction: 'improving' | 'worsening' | 'stable';
}

class WeatherMonitor {
  private pressureHistory: number[] = [];
  private maxHistory = 20; // Keep 20 readings for trend analysis
  
  startMonitoring(callback: (reading: WeatherReading) => void) {
    const subscription = Barometer.addListener(({ pressure }) => {
      this.pressureHistory.push(pressure);
      
      // Keep only recent readings
      if (this.pressureHistory.length > this.maxHistory) {
        this.pressureHistory.shift();
      }
      
      const trend = this.calculateTrend();
      const weatherPrediction = this.predictWeather(pressure, trend);
      
      callback({ pressure, trend, weatherPrediction });
    });
    
    // Update every 5 minutes for weather monitoring
    Barometer.setUpdateInterval(300000);
    
    return subscription;
  }
  
  private calculateTrend(): 'rising' | 'falling' | 'stable' {
    if (this.pressureHistory.length < 3) return 'stable';
    
    const recent = this.pressureHistory.slice(-5);
    const older = this.pressureHistory.slice(-10, -5);
    
    if (recent.length === 0 || older.length === 0) return 'stable';
    
    const recentAvg = recent.reduce((a, b) => a + b) / recent.length;
    const olderAvg = older.reduce((a, b) => a + b) / older.length;
    
    const change = recentAvg - olderAvg;
    
    if (change > 1) return 'rising';
    if (change < -1) return 'falling';
    return 'stable';
  }
  
  private predictWeather(pressure: number, trend: 'rising' | 'falling' | 'stable'): 'improving' | 'worsening' | 'stable' {
    // Basic weather prediction based on pressure and trend
    // Standard sea level pressure is around 1013.25 hPa
    
    if (pressure > 1020 && trend === 'rising') return 'improving';
    if (pressure < 1000 && trend === 'falling') return 'worsening';
    if (trend === 'falling' && pressure < 1010) return 'worsening';
    if (trend === 'rising' && pressure > 1010) return 'improving';
    
    return 'stable';
  }
}

// Usage
const weatherMonitor = new WeatherMonitor();
const subscription = weatherMonitor.startMonitoring(({ pressure, trend, weatherPrediction }) => {
  console.log(`Pressure: ${pressure.toFixed(2)} hPa, Trend: ${trend}, Weather: ${weatherPrediction}`);
});

Altitude Calculator:

import { Barometer } from "expo-sensors";

class AltitudeCalculator {
  private seaLevelPressure = 1013.25; // Standard sea level pressure in hPa
  
  // Set reference pressure for more accurate altitude calculation
  setSeaLevelPressure(pressure: number) {
    this.seaLevelPressure = pressure;
    console.log(`Sea level pressure set to: ${pressure} hPa`);
  }
  
  startAltitudeMonitoring() {
    const subscription = Barometer.addListener(({ pressure, relativeAltitude }) => {
      // Use iOS relative altitude if available
      if (relativeAltitude !== undefined) {
        console.log(`Altitude (iOS): ${relativeAltitude.toFixed(2)} m`);
      }
      
      // Calculate altitude using barometric formula
      const calculatedAltitude = this.calculateAltitude(pressure);
      console.log(`Altitude (calculated): ${calculatedAltitude.toFixed(2)} m`);
      
      // Convert to feet
      const altitudeFeet = calculatedAltitude * 3.28084;
      console.log(`Altitude: ${altitudeFeet.toFixed(0)} ft`);
    });
    
    return subscription;
  }
  
  private calculateAltitude(pressure: number): number {
    // Barometric formula for altitude calculation
    // Altitude = 44330 * (1 - (P/P0)^(1/5.255))
    const altitude = 44330 * (1 - Math.pow(pressure / this.seaLevelPressure, 1 / 5.255));
    return altitude;
  }
}

Light Sensor

Provides access to ambient light sensor for measuring illuminance levels.

/**
 * Light sensor instance providing access to ambient light data
 * @platform android
 */
declare const LightSensor: LightSensorInstance;

interface LightSensorInstance extends DeviceSensor<LightSensorMeasurement> {
  /**
   * Subscribe for updates to the light sensor
   * @param listener - Callback invoked when light sensor update is available
   * @returns Subscription that can be removed when done
   */
  addListener(listener: Listener<LightSensorMeasurement>): Subscription;
  
  /**
   * Returns whether the light sensor is available and enabled on the device. Requires at least Android 2.3 (API Level 9)
   * @returns Promise resolving to boolean denoting availability
   */
  isAvailableAsync(): Promise<boolean>;
}

interface LightSensorMeasurement {
  /** Ambient light level registered by the device measured in lux (lx) */
  illuminance: number;
  /** Timestamp of the measurement in seconds */
  timestamp: number;
}

Usage Examples:

import { LightSensor } from "expo-sensors";

// Check availability (Android only)
const isAvailable = await LightSensor.isAvailableAsync();
if (!isAvailable) {
  console.log("Light sensor not available on this device");
  return;
}

// Subscribe to light sensor updates
const subscription = LightSensor.addListener(({ illuminance, timestamp }) => {
  console.log(`Ambient light: ${illuminance.toFixed(2)} lux`);
  
  // Categorize light levels
  const lightLevel = categorizeLightLevel(illuminance);
  console.log(`Light condition: ${lightLevel}`);
});

function categorizeLightLevel(lux: number): string {
  if (lux < 1) return 'very dark';
  if (lux < 10) return 'dark';
  if (lux < 100) return 'dim';
  if (lux < 1000) return 'indoor lighting';
  if (lux < 10000) return 'bright indoor';
  if (lux < 50000) return 'daylight';
  return 'direct sunlight';
}

// Set responsive update interval
LightSensor.setUpdateInterval(1000); // 1 second

// Clean up
subscription.remove();

Automatic Brightness Control:

import { LightSensor } from "expo-sensors";

interface BrightnessSettings {
  screenBrightness: number; // 0-1 scale
  recommendedLevel: 'very low' | 'low' | 'medium' | 'high' | 'very high';
}

class AutoBrightness {
  private minLux = 0.1;
  private maxLux = 50000;
  
  startAutoBrightness(callback: (settings: BrightnessSettings) => void) {
    const subscription = LightSensor.addListener(({ illuminance }) => {
      const brightness = this.calculateBrightness(illuminance);
      const recommendedLevel = this.getRecommendedLevel(illuminance);
      
      callback({ screenBrightness: brightness, recommendedLevel });
    });
    
    LightSensor.setUpdateInterval(2000); // Update every 2 seconds
    return subscription;
  }
  
  private calculateBrightness(lux: number): number {
    // Logarithmic scale for more natural brightness adjustment
    const logLux = Math.log10(Math.max(lux, this.minLux));
    const logMin = Math.log10(this.minLux);
    const logMax = Math.log10(this.maxLux);
    
    let brightness = (logLux - logMin) / (logMax - logMin);
    
    // Clamp between 0.1 and 1.0
    brightness = Math.max(0.1, Math.min(1.0, brightness));
    
    return brightness;
  }
  
  private getRecommendedLevel(lux: number): 'very low' | 'low' | 'medium' | 'high' | 'very high' {
    if (lux < 1) return 'very low';
    if (lux < 100) return 'low';
    if (lux < 1000) return 'medium';
    if (lux < 10000) return 'high';
    return 'very high';
  }
}

// Usage
const autoBrightness = new AutoBrightness();
const subscription = autoBrightness.startAutoBrightness(({ screenBrightness, recommendedLevel }) => {
  console.log(`Recommended screen brightness: ${(screenBrightness * 100).toFixed(0)}% (${recommendedLevel})`);
  
  // Apply brightness to your app's display settings
  // adjustScreenBrightness(screenBrightness);
});

Smart Home Light Control:

import { LightSensor } from "expo-sensors";

class SmartLightController {
  private lightThresholds = {
    autoLightOn: 100,   // Turn lights on below 100 lux
    autoLightOff: 500,  // Turn lights off above 500 lux
  };
  
  private lightsOn = false;
  
  startSmartControl(onLightChange: (shouldTurnOn: boolean, reason: string) => void) {
    const subscription = LightSensor.addListener(({ illuminance }) => {
      const wasLightsOn = this.lightsOn;
      
      if (!this.lightsOn && illuminance < this.lightThresholds.autoLightOn) {
        this.lightsOn = true;
        onLightChange(true, `Low light detected: ${illuminance.toFixed(1)} lux`);
      } else if (this.lightsOn && illuminance > this.lightThresholds.autoLightOff) {
        this.lightsOn = false;
        onLightChange(false, `Sufficient light detected: ${illuminance.toFixed(1)} lux`);
      }
    });
    
    LightSensor.setUpdateInterval(5000); // Check every 5 seconds
    return subscription;
  }
  
  setThresholds(onThreshold: number, offThreshold: number) {
    this.lightThresholds.autoLightOn = onThreshold;
    this.lightThresholds.autoLightOff = offThreshold;
  }
}

Platform Considerations

Android

  • Barometer available on many modern devices (varies by manufacturer)
  • Light sensor widely available since Android 2.3
  • Light sensor provides lux measurements

iOS

  • Barometer available on iPhone 6+ and newer devices
  • Provides both pressure and relative altitude measurements
  • Light sensor not directly accessible (use camera or screen brightness APIs instead)

Web

  • Environmental sensors not available on web platforms
  • Consider using device cameras or other APIs for light detection approximations