Skip to content

Latest commit

 

History

126 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

English / 日本語

Aroma Shooter SDK (Java)

Version 3.1.0

Maven Central License

A desktop Java SDK for connecting to and controlling Aroma Shooter devices over USB.

Important — the internal booster is required for scent to be emitted. Enable it on every shoot: pass internalBooster: true (simple API) or internalBoosterIntensity > 0 (intensity API). With the internal booster off, no scent comes out.

This SDK ships as two Maven artifacts:

  • com.aromajoin.sdk:jvm — the USB controller, USBASController
  • com.aromajoin.sdk:core — shared protocol, commands and models, pulled in automatically

English

Table of Contents

  1. Supported devices
  2. Prerequisites
  3. Installation
  4. Upgrading from 2.x
  5. Usage
  6. Troubleshooting
  7. License

Supported devices

  • USB-compatible Aroma Shooter
    • Simple shooting API: compatible with AS1, AS2
    • Intensity shooting API: compatible with AS2, AS3 (newer models)

Prerequisites

  • JRE 1.8 or later
  • The device must be recognised as a serial/COM device. Install the FTDI driver for your OS if required.

Installation

Gradle:

dependencies {
    implementation 'com.aromajoin.sdk:jvm:3.1.0'
}

Maven:

<dependency>
  <groupId>com.aromajoin.sdk</groupId>
  <artifactId>jvm</artifactId>
  <version>3.1.0</version>
</dependency>

If you cannot use a dependency manager, the jars are attached to the latest release, and are also on Maven Central. Add jvm, core and jSerialComm to your build path.


Upgrading from 2.x

3.x renames a number of identifiers. Behaviour is unchanged, but calling code has to be updated.

2.x 3.x
diffuse* shoot*
Port AromaChamber
port.getPortNumber() chamber.getNumber()
ports parameter chambers
stopAllPorts() stopAllChambers()

Two things are new in 3.1.0 rather than renamed:

  • stopAllChambersWithIntensity() is new in 3.1.0 — before, the SDK could not send a valid intensity-stop frame at all. It and stopAllChambers() differ only in the protocol frame they send (21-byte vs 15-byte); either one stops the device, whichever API started the shoot.
  • connect(aromaShooter, callback) and disconnect(aromaShooter, callback) are implemented. They used to throw UnsupportedOperationException, so disconnectAll() was the only way to release a port.

Usage

For a complete program, see the Sample project.

0. Setup / discovery

Scanning walks every serial port on the machine, so it is not instant. It can be run synchronously or with a callback.

USBASController usb = new USBASController();

// Synchronous.
usb.scanAndConnect();
List<AromaShooter> devices = usb.getConnectedDevices();

// With a callback.
usb.scanAndConnect(new DiscoverCallback() {
    @Override
    public void onDiscovered(List<AromaShooter> aromaShooters) {
        for (AromaShooter aromaShooter : aromaShooters) {
            System.out.println(aromaShooter.getSerial());
        }
    }

    @Override
    public void onFailed(String msg) {
        // No device answered.
    }
});

1. Simple shooting API (AS1, AS2)

Chambers are numbered 1 to 6. Duration is in milliseconds, capped at 10000.

Shoot from all connected devices:

usb.shootAllSimple(3000, true, 2, 5);

Shoot from a specific device, by object or by serial:

usb.shootSimple(aromaShooter, 3000, true, 2, 5);
usb.shootSimple("ASN3A01192", 3000, true, 2, 5);

Stop:

usb.stopAllChambers();              // every connected device
usb.stopAllChambers(aromaShooter);  // one device

2. Intensity shooting API (AS2, AS3)

AromaChamber carries a chamber number and a concentration:

public class AromaChamber {
    public int getNumber();        // 1..6
    public int getConcentration(); // 0..100
}

A booster or chamber given 0 is switched off, not left as it was.

Shoot from all connected devices:

usb.shootAllWithIntensity(3000, 100, 0,
    new AromaChamber(2, 50), new AromaChamber(5, 100));

Shoot from a specific device, by object or by serial:

usb.shootWithIntensity(aromaShooter, 3000, 100, 0, new AromaChamber(2, 50));
usb.shootWithIntensity("ASN3A01192", 3000, 100, 0, new AromaChamber(2, 50));

Stop:

usb.stopAllChambersWithIntensity();
usb.stopAllChambersWithIntensity(aromaShooter);

stopAllChambers() and stopAllChambersWithIntensity() differ only in the protocol frame length (15-byte vs 21-byte). Either one stops the device, whichever API started the shoot.


3. Disconnecting / reconnecting

A serial port can only be held by one process at a time. Disconnecting stops the device and releases its port, so another application can take it over.

// Every connected device.
usb.disconnectAll();

// One device.
usb.disconnect(aromaShooter, new DisconnectCallback() {
    @Override
    public void onDisconnect(AromaShooter aromaShooter) {
        // Port released.
    }

    @Override
    public void onFailed(AromaShooter aromaShooter, String msg) {
        // Not connected, or not a USB device.
    }
});

connect re-opens a device found by an earlier scan, without probing every port again:

usb.connect(aromaShooter, new ConnectCallback() {
    @Override
    public void onConnected(AromaShooter aromaShooter) {
        // Ready to shoot again.
    }

    @Override
    public void onFailed(AromaShooter aromaShooter, String msg) {
        // The port could not be opened - another application may still hold it.
    }
});

Troubleshooting

No devices found. Check the FTDI driver is installed and that the port is not already open in another application — a serial port is exclusive. If a previous run of your own program did not call disconnectAll(), its port may still be held.

Nothing comes out, but no error. The internal booster is off. Pass internalBooster: true, or an internalBoosterIntensity above 0.

The scent does not stop. Update to 3.1.0. Earlier versions sent a malformed intensity-stop frame, so a shoot started with shootWithIntensity* could keep running. From 3.1.0 either stopAllChambers() or stopAllChambersWithIntensity() halts the device.

A booster keeps running after you asked for 0. Fixed in 3.1.0. Earlier versions left a channel untouched when its intensity was 0, and the device carried on with its previous instruction.


License

Please check the LICENSE file for the details.

If you get any issues or require any new features, please create a new issue.

About

Enable developers to connect and control Aroma Shooter.

Topics

Resources

Code of conduct

Contributing

Stars

5 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors