Edge SDK -- Quickstart Guide
This guide walks you through creating a new edge adapter project from scratch using the Zequent Edge SDK. By the end, you will have a running Quarkus application that receives commands from the platform and can push telemetry data.
Prerequisites
- Java 25
- Maven 3.9.9 or higher
- Docker or Podman (for running platform services)
- GitHub account with access to the Zequent packages repository
Step 1: Create a New Quarkus Project
mvn io.quarkus:quarkus-maven-plugin:3.17.4:create \
-DprojectGroupId=com.example.edge \
-DprojectArtifactId=my-edge-adapter \
-Dextensions="grpc,smallrye-health,arc"
cd my-edge-adapter
Step 2: Add the Edge SDK Dependency
Open pom.xml and add the Edge SDK and the GitHub Packages repository:
<dependencies>
<!-- Zequent Edge SDK -->
<dependency>
<groupId>com.zequent.framework.edge.sdk</groupId>
<artifactId>java-edge-sdk</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>github</id>
<url>https://maven.pkg.github.com/Zequent/zequent-framework</url>
</repository>
</repositories>
Make sure your ~/.m2/settings.xml has the GitHub credentials:
<settings>
<servers>
<server>
<id>github</id>
<username>YOUR_GITHUB_USERNAME</username>
<password>YOUR_GITHUB_TOKEN</password>
</server>
</servers>
</settings>
Step 3: Configure the Adapter
Create or edit src/main/resources/application.properties:
# Application
quarkus.application.name=my-edge-adapter
quarkus.http.host=0.0.0.0
quarkus.http.port=9001
# Edge Identity
zequent.edge.endpoint=localhost:9001
zequent.edge.sn=YOUR_DEVICE_SERIAL_NUMBER
zequent.edge.asset-type=ASSET_TYPE_DOCK
zequent.edge.asset-vendor=DJI
# Platform Services
quarkus.grpc.clients.live-data-service.host=localhost
quarkus.grpc.clients.live-data-service.port=8003
quarkus.grpc.clients.live-data-service.keep-alive-without-calls=true
quarkus.grpc.clients.connector-service.host=localhost
quarkus.grpc.clients.connector-service.port=8010
quarkus.grpc.clients.connector-service.keep-alive-without-calls=true
# gRPC server shares HTTP port
quarkus.grpc.server.use-separate-server=false
Step 4: Implement the EdgeAdapterService
Create your adapter class. You only need to override the commands that your hardware supports:
package com.example.edge;
import com.zequent.framework.edge.sdk.interfaces.EdgeAdapterService;
import com.zequent.framework.edge.sdk.models.*;
import jakarta.enterprise.context.ApplicationScoped;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CompletableFuture;
@Slf4j
@ApplicationScoped
public class MyDeviceAdapter implements EdgeAdapterService {
@Override
public CompletableFuture<CommandResult> takeOff(TakeOffRequest request) {
log.info("Takeoff requested for SN: {}", request.getSn());
// Replace with your actual device API call
boolean success = true;
if (success) {
return CompletableFuture.completedFuture(
CommandResult.success("Takeoff initiated", request.getTid(), request.getSn())
);
} else {
return CompletableFuture.completedFuture(
CommandResult.error("Takeoff failed", request.getSn())
);
}
}
@Override
public CompletableFuture<CommandResult> returnToHome(ReturnToHomeRequest request) {
log.info("Return to home for SN: {}", request.getSn());
return CompletableFuture.completedFuture(
CommandResult.success("Returning to home", request.getTid(), request.getSn())
);
}
@Override
public CompletableFuture<CommandResult> openCover(String sn) {
log.info("Opening cover for SN: {}", sn);
return CompletableFuture.completedFuture(
CommandResult.success("Cover opening", sn)
);
}
// All other commands default to NOT_IMPLEMENTED and that is fine.
// Override more as your hardware supports them.
}
Step 5: Push Telemetry Data (Optional)
If your device produces telemetry, inject the LiveDataService and push data:
package com.example.edge;
import com.zequent.framework.edge.sdk.interfaces.LiveDataService;
import com.zequent.framework.edge.sdk.models.TelemetryRequestData;
import com.zequent.framework.common.proto.LiveDataType;
import com.zequent.framework.utils.edge.sdk.dto.AssetTelemetryData;
import jakarta.enterprise.context.ApplicationScoped;
import lombok.extern.slf4j.Slf4j;
import java.time.LocalDateTime;
import java.util.UUID;
@Slf4j
@ApplicationScoped
public class TelemetryProducer {
private final LiveDataService liveDataService;
public TelemetryProducer(LiveDataService liveDataService) {
this.liveDataService = liveDataService;
}
public void sendAssetTelemetry(String sn) {
AssetTelemetryData assetData = new AssetTelemetryData();
assetData.setLatitude(47.3769f);
assetData.setLongitude(8.5417f);
assetData.setAbsoluteAltitude(450.0f);
assetData.setEnvironmentTemp(22.5f);
assetData.setHumidity(65.0f);
TelemetryRequestData data = TelemetryRequestData.builder()
.sn(sn)
.tid(UUID.randomUUID().toString())
.timestamp(LocalDateTime.now())
.type(LiveDataType.ASSET_TELEMETRY)
.assetTelemetry(assetData)
.build();
liveDataService.produceTelemetryData(data)
.subscribe().with(
ignored -> log.debug("Telemetry sent for {}", sn),
err -> log.error("Telemetry error", err)
);
}
}
Step 6: Start Platform Services
Before running your adapter, start the required platform services. Use the provided Docker Compose file from the framework root or create a minimal one:
# docker-compose.yml
version: "3.8"
services:
zequent_db:
image: docker.io/library/postgres:latest
environment:
POSTGRES_DB: zequent_db
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- "5433:5432"
redis:
image: docker.io/library/redis:latest
command: ["redis-server", "--appendonly", "yes"]
ports:
- "6379:6379"
connector-service:
depends_on:
- zequent_db
- redis
image: ghcr.io/zequent/connector-service:latest
ports:
- "8080:8080"
environment:
- QUARKUS_REDIS_HOSTS=redis://redis:6379
- QUARKUS_DATASOURCE_JDBC_URL=jdbc:postgresql://zequent_db:5432/zequent_db
- QUARKUS_DATASOURCE_USERNAME=postgres
- QUARKUS_DATASOURCE_PASSWORD=postgres
live-data-service:
depends_on:
- redis
image: ghcr.io/zequent/live-data-service:latest
ports:
- "8003:8003"
environment:
- QUARKUS_REDIS_HOSTS=redis://redis:6379
Start the services:
docker-compose up -d
Step 7: Run Your Adapter
./mvnw quarkus:dev
You should see output similar to:
Listening on: http://0.0.0.0:9001
gRPC Server started on 0.0.0.0:9001
Your adapter is now running and ready to receive commands from the platform via gRPC.
Step 8: Test with the Simulator
You can use the framework's built-in simulator (simulator/) to send test commands to your adapter. Alternatively, test with grpcurl:
# Install grpcurl if needed
# brew install grpcurl (macOS)
# go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest (Go)
# List available services
grpcurl -plaintext localhost:9001 list
# Call takeOff
grpcurl -plaintext -d '{
"base": {
"sn": "YOUR_DEVICE_SN",
"tid": "test-123",
"timestamp": {"seconds": 1700000000}
},
"request": {
"latitude": 47.3769,
"longitude": 8.5417,
"altitude": 100.0
}
}' localhost:9001 com.zequent.framework.sdks.edge.proto.EdgeAdapterService/TakeOff
Project Structure
After completing this guide, your project should look like this:
my-edge-adapter/
pom.xml
src/
main/
java/
com/example/edge/
MyDeviceAdapter.java # Your EdgeAdapterService implementation
TelemetryProducer.java # Optional: telemetry push logic
resources/
application.properties # Configuration
docker-compose.yml # Platform services (dev)
Next Steps
- Edge Adapter Reference -- Full command reference and advanced patterns
- Configuration Guide -- All configuration properties
- Live Data -- In-depth telemetry streaming guide
- Connector -- Asset and mission management
- Models Reference -- Complete model documentation
For a real-world implementation example, see the edge-adapters/edge-dji module in the framework repository.