Configure device timezones for Ultraloq locks to enable time-bound access codes
Ultraloq devices require timezone configuration before you can create time-bound access codes. This guide explains why this is necessary and how to configure timezones for your Ultraloq devices.
from seam import Seamseam = Seam()device = seam.devices.get(device_id="your-device-id")# Check for timezone warninghas_timezone_warning = any( w.warning_code == "ultraloq_time_zone_unknown" for w in device.warnings)if has_timezone_warning: print("⚠️ Timezone not configured") print("Configure timezone before creating time-bound access codes")# Check timezone valuetimezone = device.properties.get("ultraloq_metadata", {}).get("time_zone")print(f"Current timezone: {timezone}") # Will be None if not configured
require "seam"seam = Seam.new()device = seam.devices.get(device_id: "your-device-id")# Check for timezone warninghas_timezone_warning = device.warnings.any? do |w| w.warning_code == "ultraloq_time_zone_unknown"endif has_timezone_warning puts "⚠️ Timezone not configured" puts "Configure timezone before creating time-bound access codes"end# Check timezone valuetimezone = device.properties.dig("ultraloq_metadata", "time_zone")puts "Current timezone: #{timezone}" # Will be nil if not configured
You can configure timezones for multiple devices in a single API call:
import { Seam } from 'seam'const seam = new Seam()// Get all Ultraloq devicesconst devices = await seam.devices.list({ device_type: 'ultraloq_lock',})// Configure timezone for all devicesawait seam.devices.reportProviderMetadata({ devices: devices.map((device) => ({ device_id: device.device_id, ultraloq_metadata: { time_zone: 'America/Los_Angeles', // Or get from user }, })),})console.log(`✓ Configured timezone for ${devices.length} devices`)
from seam import Seamseam = Seam()# Get all Ultraloq devicesdevices = seam.devices.list(device_type="ultraloq_lock")# Configure timezone for all devicesseam.devices.report_provider_metadata( devices=[ { "device_id": device.device_id, "ultraloq_metadata": { "time_zone": "America/Los_Angeles" # Or get from user } } for device in devices ])print(f"✓ Configured timezone for {len(devices)} devices")
require "seam"seam = Seam.new()# Get all Ultraloq devicesdevices = seam.devices.list(device_type: "ultraloq_lock")# Configure timezone for all devicesseam.devices.report_provider_metadata( devices: devices.map do |device| { device_id: device.device_id, ultraloq_metadata: { time_zone: "America/Los_Angeles" # Or get from user } } end)puts "✓ Configured timezone for #{devices.length} devices"
<?phprequire 'vendor/autoload.php';use Seam\SeamClient;$seam = new SeamClient();// Get all Ultraloq devices$devices = $seam->devices->list(device_type: "ultraloq_lock");// Configure timezone for all devices$deviceMetadata = array_map(function($device) { return [ "device_id" => $device->device_id, "ultraloq_metadata" => [ "time_zone" => "America/Los_Angeles" // Or get from user ] ];}, $devices);$seam->devices->report_provider_metadata(devices: $deviceMetadata);echo "✓ Configured timezone for " . count($devices) . " devices";
using Seam.Client;using System.Linq;var seam = new SeamClient();// Get all Ultraloq devicesvar devices = seam.Devices.List(deviceType: "ultraloq_lock");// Configure timezone for all devicesseam.Devices.ReportProviderMetadata( devices: devices.Select(device => new DeviceMetadata { DeviceId = device.DeviceId, UltraloqMetadata = new UltraloqMetadata { TimeZone = "America/Los_Angeles" // Or get from user } }).ToArray());Console.WriteLine($"✓ Configured timezone for {devices.Count()} devices");
import com.seam.api.Seam;import com.seam.api.types.Device;import java.util.stream.Collectors;Seam seam = Seam.builder().build();// Get all Ultraloq devicesList<Device> devices = seam.devices().list( DevicesListRequest.builder() .deviceType("ultraloq_lock") .build());// Configure timezone for all devicesseam.devices().reportProviderMetadata( DevicesReportProviderMetadataRequest.builder() .devices(devices.stream() .map(device -> DeviceMetadata.builder() .deviceId(device.getDeviceId()) .ultraloqMetadata(UltraloqMetadata.builder() .timeZone("America/Los_Angeles") // Or get from user .build()) .build()) .collect(Collectors.toList())) .build());System.out.println("✓ Configured timezone for " + devices.size() + " devices");
Do not use timezone abbreviations like "EST", "PST", or "GMT-5".
These are ambiguous and will cause validation errors. Always use the full IANA
timezone string.
Most programming languages also provide timezone lookup utilities:
// Using Intl API (built-in)const userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZoneconsole.log(`User's timezone: ${userTimezone}`)// Example: "America/Los_Angeles"// Or using moment-timezone libraryconst moment = require('moment-timezone')const allTimezones = moment.tz.names()console.log(`Available timezones: ${allTimezones.length}`)
import pytz# List all available timezonesall_timezones = pytz.all_timezonesprint(f"Available timezones: {len(all_timezones)}")# Search for timezones containing "New"ny_timezones = [tz for tz in all_timezones if "New" in tz]print(ny_timezones)# ['America/New_York', 'America/North_Dakota/New_Salem', ...]
require 'tzinfo'# List all available timezonesall_timezones = TZInfo::Timezone.all_identifiersputs "Available timezones: #{all_timezones.length}"# Search for timezones containing "New"ny_timezones = all_timezones.select { |tz| tz.include?("New") }puts ny_timezones# ["America/New_York", "America/North_Dakota/New_Salem", ...]
You can change a device’s timezone at any time by calling /devices/report_provider_metadata again with the new timezone.
import { Seam } from 'seam'const seam = new Seam()// User moved device from New York to Los Angelesawait seam.devices.reportProviderMetadata({ devices: [ { device_id: 'your-device-id', ultraloq_metadata: { time_zone: 'America/Los_Angeles', // Changed from America/New_York }, }, ],})console.log('✓ Timezone updated to Pacific Time')
from seam import Seamseam = Seam()# User moved device from New York to Los Angelesseam.devices.report_provider_metadata( devices=[ { "device_id": "your-device-id", "ultraloq_metadata": { "time_zone": "America/Los_Angeles" # Changed from America/New_York } } ])print("✓ Timezone updated to Pacific Time")
require "seam"seam = Seam.new()# User moved device from New York to Los Angelesseam.devices.report_provider_metadata( devices: [ { device_id: "your-device-id", ultraloq_metadata: { time_zone: "America/Los_Angeles" # Changed from America/New_York } } ])puts "✓ Timezone updated to Pacific Time"
<?phprequire 'vendor/autoload.php';use Seam\SeamClient;$seam = new SeamClient();// User moved device from New York to Los Angeles$seam->devices->report_provider_metadata( devices: [ [ "device_id" => "your-device-id", "ultraloq_metadata" => [ "time_zone" => "America/Los_Angeles" // Changed from America/New_York ] ] ]);echo "✓ Timezone updated to Pacific Time";
using Seam.Client;var seam = new SeamClient();// User moved device from New York to Los Angelesseam.Devices.ReportProviderMetadata( devices: new[] { new DeviceMetadata { DeviceId = "your-device-id", UltraloqMetadata = new UltraloqMetadata { TimeZone = "America/Los_Angeles" // Changed from America/New_York } } });Console.WriteLine("✓ Timezone updated to Pacific Time");
import com.seam.api.Seam;Seam seam = Seam.builder().build();// User moved device from New York to Los Angelesseam.devices().reportProviderMetadata( DevicesReportProviderMetadataRequest.builder() .devices(List.of( DeviceMetadata.builder() .deviceId("your-device-id") .ultraloqMetadata(UltraloqMetadata.builder() .timeZone("America/Los_Angeles") // Changed from America/New_York .build()) .build() )) .build());System.out.println("✓ Timezone updated to Pacific Time");
Impact on Existing Access Codes:
Existing time-bound access codes maintain their UTC timestamps
They continue working correctly because Seam stores them in UTC internally
Future access codes will use the new timezone for scheduling
Configure the timezone as soon as you connect an Ultraloq device, before users try to create time-bound access codes:
# Good practice: Configure timezone right after connectiondevices = seam.devices.list(connected_account_id=account_id)seam.devices.report_provider_metadata( devices=[ { "device_id": device.device_id, "ultraloq_metadata": {"time_zone": user_timezone} } for device in devices ])
2. Check Warnings Before Creating Time-Bound Codes
Always check for the ultraloq_time_zone_unknown warning before creating time-bound access codes:
def can_create_time_bound_codes(device): return not any( w.warning_code == "ultraloq_time_zone_unknown" for w in device.warnings )if can_create_time_bound_codes(device): # Safe to create time-bound codes seam.access_codes.create( device_id=device.device_id, starts_at="...", ends_at="..." )else: # Prompt user to configure timezone print("Configure device timezone before creating time-bound codes")
After configuration, you can reference the configured timezone from device.location.timezone:
device = seam.devices.get(device_id="...")if device.location and device.location.timezone: print(f"Device is in {device.location.timezone}") # Use this timezone for display or calculations