Download the PHP package graystackit/laravel-testo-api without Composer
On this page you can find all versions of the php package graystackit/laravel-testo-api. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download graystackit/laravel-testo-api
More information about graystackit/laravel-testo-api
Files in graystackit/laravel-testo-api
Package laravel-testo-api
Short Description Laravel package for the Testo Saveris Data API, built on Saloon 4
License MIT
Homepage https://github.com/GraystackIT/laravel-testo-api
Informations about the package laravel-testo-api
graystackit/laravel-testo-cloud
A Laravel package for the Testo Smart Connect API, built on Saloon 4.
Retrieve historical measurements, alarm events, HACCP task records, device properties, device health status, measuring object configurations, and location hierarchies from Testo Smart Connect — all with a clean, Laravel-native interface.
Requirements
- PHP 8.3+
- Laravel 11, 12, or 13
Installation
Laravel auto-discovers the service provider. Then publish the config file:
Configuration
Add the following to your .env file:
Generate your API key from the Smart Connect home page. Keys are valid for up to one year.
Async Workflow
All data-export endpoints use the same two-step async pattern:
- Submit a POST request → receive a
request_uuid - Poll a GET request with that UUID until status is
Completed - Download each URL in
dataUrlsusingdownloadDataFile()
An unrecognized status string from Testo (e.g. a future state not listed above) maps to
AsyncRequestStatus::Unknown rather than being silently treated as still-processing — check
$response->rawStatus for the exact string Testo returned in that case.
Usage
Resolve TestoCloudClient from the container or inject via constructor.
Measurements POST /v2/measurements • GET /v2/measurements/{uuid}
$frommust be strictly before$to— an\InvalidArgumentExceptionis thrown otherwise.
Parse NDJSON measurement data
physical_extensiondisambiguates rows that share the samephysical_property_name(e.g. an external-probe temperature reading vs. the logger's own internal sensor) — readtemperature_extension/humidity_extensionwhen a logger reports more than one of each.The optional
$deviceUuidfilter assumes measurement rows carry adevice_uuidfield. Testo's migration guide instead documentsserial_noas the sensor identifier on measurement values — this is unconfirmed against a live payload either way. Rows with nodevice_uuidkey are never filtered out, so an incorrect assumption here degrades safely (passes everything through) rather than silently dropping data.
Alarms POST /v3/alarms • GET /v3/alarms/{uuid}
Retrieve historical alarm events for the configured account.
Tasks POST /v3/tasks • GET /v3/tasks/{uuid}
Retrieve quality-management / HACCP activity records executed by staff.
⚠️ Unverified (2026-09-28): this path does not appear anywhere in Testo's current Smart Connect API reference — checked the endpoint-examples overview, the OData filtering page, and the changelog, all of which enumerate the same fixed set of six endpoint pairs (device properties, device status, measurements, alarms, locations, measuring objects) with no tasks entry. A separate "Task Execution API" concept is referenced elsewhere but its actual endpoint path could not be confirmed. Verify against a live API key (or with Testo) before relying on this — it may 404, live under a different path, or belong to a different API family entirely.
Device Properties POST /v3/devices/properties • GET /v3/devices/properties/{uuid}
Retrieve device metadata including serial numbers, model codes, firmware versions, calibration status, and equipment relationships.
No date range required — returns current configuration.
Device Status POST /v3/devices/status • GET /v3/devices/status/{uuid}
Retrieve battery level, signal strength, last communication timestamp, firmware version, and serial numbers for all devices.
No date range required — returns current status snapshot.
⚠️ Needs verification (2026-09-28): Testo's changelog records
/v4/devices/statusbeing added on top of this v3 path, renaminglast_communication/next_communicationto..._time, removingfw_code/fw_version(now under/v3/devices/properties, used by Device Properties above), and addingproduction_date/battery_temperature/status_time. The changelog never states v3 is deprecated, but the docs' own endpoint-overview page still only lists v3 — the two sources disagree, so the version wasn't changed pending confirmation of which is actually current. This package doesn't parse any device-status-specific fields into a typed DTO today (only the generic async wrapper below), so the version gap is lower-risk than it looks, but should move to v4 once confirmed live.
Measuring Objects POST /v1/measuring-objects • GET /v1/measuring-objects/{uuid}
Retrieve measuring-object configurations including customer_uuid,
customer_site, product_family_id, measurement settings, and channel assignments.
No date range required — returns current configuration.
Locations POST /v1/locations • GET /v1/locations/{uuid}
Retrieve the location hierarchy (sites, zones, rooms) associated with the account.
No date range required — returns current location structure.
Data Objects
Submission response — AsyncSubmitResponse
Returned by every submit*() method.
| Property | Type | Description |
|---|---|---|
requestUuid |
string |
UUID to use when polling status |
status |
AsyncRequestStatus |
Enum — Submitted on initial response |
rawStatus |
string |
The status string exactly as Testo returned it |
Status response — AsyncStatusResponse
Returned by every check*Status() method.
| Property | Type | Description |
|---|---|---|
status |
AsyncRequestStatus |
Current state (see enum below) |
dataUrls |
string[] |
Download URLs (populated when completed) |
metadataUrl |
?string |
Metadata file URL (populated when completed) |
error |
?string |
Error message (populated when failed) |
rawStatus |
string |
The status string exactly as Testo returned it |
Helper methods: isCompleted(), isProcessing(), isFailed()
AsyncRequestStatus enum
The enum normalises all API status strings, including "In Progress" → Processing. An
unrecognized string never falls back to Processing — it maps to Unknown instead, so a
future new terminal status can't get stuck looking like it's still in progress. Read
$response->rawStatus to see the original string in that case.
Measurement-specific objects
Used by submitMeasurementRequest()/checkRequestStatus() (measurements only — kept as their
own classes since measurements has its own endpoint/status vocabulary separate from the shared
Alarms/Tasks/Equipment/Sensors/Measuring-Objects modules, but shaped the same way):
| Class | Properties |
|---|---|
MeasurementSubmitResponse |
requestUuid, status (AsyncRequestStatus), rawStatus |
MeasurementStatusResponse |
status, dataUrls[], metadataUrl, error, rawStatus, helpers |
Error Handling
All client methods throw GraystackIT\TestoCloud\Exceptions\TestoApiException on failure.
submit*Request() methods that accept a date range additionally throw \InvalidArgumentException when $from >= $to.
If TESTO_API_KEY is not configured, a \RuntimeException is thrown on container resolution.
API Endpoint Reference
| Module | Submit | Check Status |
|---|---|---|
| Measurements | POST /v2/measurements |
GET /v2/measurements/{uuid} |
| Alarms | POST /v3/alarms |
GET /v3/alarms/{uuid} |
| Tasks | POST /v3/tasks |
GET /v3/tasks/{uuid} |
| Device Properties | POST /v3/devices/properties |
GET /v3/devices/properties/{uuid} |
| Device Status | POST /v3/devices/status |
GET /v3/devices/status/{uuid} |
| Measuring Objects | POST /v1/measuring-objects |
GET /v1/measuring-objects/{uuid} |
| Locations | POST /v1/locations |
GET /v1/locations/{uuid} |
Base URL: https://data-api.{region}.smartconnect.testo.com
Database Storage
Migration
Run the migration to create the testo_measurements table:
To customise the migration before running it, publish it first:
testo_measurements schema
| Column | Type | Description |
|---|---|---|
id |
bigint | Auto-increment primary key |
logger_uuid |
string|null | Logger device UUID (populated when available) |
measured_at |
timestamp | Timestamp of the measurement |
temperature |
decimal(8,4)|null | Temperature reading |
humidity |
decimal(8,4)|null | Humidity reading |
created_at |
timestamp | Record insertion time |
updated_at |
timestamp | Record update time |
Model
Disabling automatic storage
Set TESTO_STORE_MEASUREMENTS=false in your .env (or store_measurements => false in config/testo.php) to fetch and parse data without writing to the database.
Artisan Command
Fetches historical measurements from the Testo API, parses the NDJSON response, and — when storage is enabled — persists every row to testo_measurements.
Options
| Option | Default | Description |
|---|---|---|
--from= |
default_from_days ago |
Start date (Y-m-d) |
--to= |
today | End date (Y-m-d) |
--format= |
JSON |
Export format (JSON or CSV) |
--logger-uuid= |
(all loggers) | Filter results to a single device UUID |
Examples
Console output
Testing
Tests use Saloon's MockClient — no real API calls are made.
License
MIT
All versions of laravel-testo-api with dependencies
illuminate/console Version ^11.0|^12.0|^13.0
illuminate/database Version ^11.0|^12.0|^13.0
illuminate/http Version ^11.0|^12.0|^13.0
illuminate/support Version ^11.0|^12.0|^13.0
saloonphp/saloon Version ^4.0