Flutter/Dart SDK for AnyButton

Install the SDK (Flutter / Dart)

Use a local path dependency from a downloaded package.

Download & path dependency

# Download the SDK archive (.zip)
curl -L -o anybutton_me_sdk_1.1.0_src.zip https://anybutton.me/docs/flutter/downloads/anybutton_me_sdk_1.0.0_src.zip
mkdir -p vendor/anybutton_me_sdk
unzip -q anybutton_me_sdk_1.1.0_src.zip -d vendor/anybutton_me_sdk
# pubspec.yaml
dependencies:
  anybutton_me_sdk:
    path: vendor/anybutton_me_sdk

macOS: Disable the App Sandbox during development. Ensure the device appears under /dev/cu.usbmodem*.

Get packages

flutter pub get

Example App (Flutter)

A ready-to-run sample app to validate USB connectivity and events.

Add locally

# Download the example archive (.zip)
curl -L -o anybutton_example_1.0.0_src.zip https://anybutton.me/docs/flutter/downloads/anybutton_example_1.0.0_src.zip

# Unzip into a vendor folder
mkdir -p vendor/anybutton_example
unzip -q anybutton_example_1.0.0_src.zip -d vendor/anybutton_example

Point to the local SDK

# example/pubspec.yaml
dependencies:
  anybutton_me_sdk:
    path: ../anybutton_me_sdk

Get packages

cd vendor/anybutton_example
flutter pub get

Run

cd vendor/anybutton_example
flutter run

macOS: Disable App Sandbox. Confirm the device shows up as /dev/cu.usbmodem*.

Quick Start (Flutter)

import 'dart:async';
import 'package:anybutton_me_sdk/anybutton_me_sdk.dart';

Future<void> main() async {
  final client = AnyButtonClient.autodetect();
  client.onLog = (m) => print('[log] $m');

  // Required options; defaults shown
  final opts = AnyButtonOptions(
    ledEnabled: true,
    ledPattern: 1,
    buzzerEnabled: true,
    buzzerPattern: 1,
    autoOffSeconds: 0,
    invert: false,
    identifier: '',
  );

  await client.start(opts);
  client.events.listen((e) {
    print('autoOff: ${e.autoOff.seconds > 0 ? 'on' : 'off'} • ${e.autoOff.seconds}s');
    print('event: fw=${e.firmware} id=${e.id} btn=${e.buttonState}');
  });
}

Event Model

Listen to a single stream of DeviceEventState objects. Each event is a full snapshot.

Subscribe to events

final sub = client.events.listen((evt) {
  // evt.buttonState: ButtonStateEnum.on/off
  // evt.led, evt.buzzer, evt.autoOff, evt.wifi
  // evt.firmware, evt.id
});

Connection state

client.connectionStateListenable.addListener(() {
  print('conn: ${client.connectionState.name}');
});

Granular change streams

In addition to the full snapshot stream, the SDK exposes focused streams that fire only when specific fields change.

// Granular, C#-style events
client.connectionStateChanged.listen((s) => print('conn: ${s.name}'));
client.buttonStateChanged.listen((b) => print('button: ${b.name}'));
client.wifiStateChanged.listen((w) => print('wifi: ${w.name}'));
client.ledChanged.listen((e) => print('led: on=${e.led.isOn} pattern=${e.led.pattern}'));
client.buzzerChanged.listen((e) => print('buzzer: on=${e.buzzer.isOn} pattern=${e.buzzer.pattern}'));
client.autoOffChanged.listen((e) => print('autoOff: ${e.autoOff.seconds}s'));
client.informationChanged.listen((e) => print('id=${e.id} fw=${e.firmware}'));

Listeners (C#‑style granular events)

Subscribe to fine‑grained streams that fire only when their corresponding values change. These mirror the C# SDK events.

ListenerPayloadFires when…
connectionStateChanged ConnectionStateEnum Client connects/disconnects (also reflected via connectionStateListenable).
buttonStateChanged ButtonStateEnum Logical button toggles on/off.
wifiStateChanged WifiConnectionStateEnum Wi‑Fi state transitions (unsupported/disconnected/reconnecting/connected/error).
ledChanged DeviceEventState Any LED field changes (enabled, on/off, invert, pattern).
buzzerChanged DeviceEventState Any buzzer field changes (enabled, on/off, pattern).
autoOffChanged DeviceEventState autoOff.seconds changes; value 0 means off.
informationChanged DeviceEventState Identifier (id) or firmware version changes.

Sample

final subs = <StreamSubscription>[
  client.connectionStateChanged.listen((s) => print('conn: ${s.name}')),
  client.buttonStateChanged.listen((b) => print('button: ${b.name}')),
  client.wifiStateChanged.listen((w) => print('wifi: ${w.name}')),
  client.ledChanged.listen((e) => print('led on=${e.led.isOn} pattern=${e.led.pattern}')),
  client.buzzerChanged.listen((e) => print('buzzer on=${e.buzzer.isOn} pattern=${e.buzzer.pattern}')),
  client.autoOffChanged.listen((e) => print('autoOff ${e.autoOff.seconds}s')),
  client.informationChanged.listen((e) => print('id=${e.id} fw=${e.firmware}')),
];

For a complete snapshot on every update, use client.events.

Runtime Controls

// Logical button
await client.turnOn();
await client.turnOff();

// LED / buzzer
await client.setLedEnabled(true);
await client.setLedOn(pattern: 1);
await client.setLedOff();

await client.setBuzzerEnabled(true);
await client.setBuzzerOn(pattern: 1);
await client.setBuzzerOff();

// Other options (persist only if different)
await client.setInvert(false);
await client.setAutoOff(5); // 0 = off
await client.setIdentifier('My Button');

Calls that change configuration persist automatically only when the device config actually differs.

Apply multiple options

final res = await client.setOptions(AnyButtonOptions(
  ledEnabled: true,
  ledPattern: 1,
  buzzerEnabled: true,
  buzzerPattern: 1,
  autoOffSeconds: 5,
  invert: false,
  identifier: 'Desk',
));
print('apply options: ok=${res.ok} changed=${res.applied.join('|')}');
// changed includes 'autoOffSeconds' when it differs from the current device value

DeviceEventState

Top-level

PropertyTypeDescription
firmwareStringFirmware version.
idStringIdentifier.
buttonStateButtonStateEnumon or off.
ledLedStateEnabled, on/off, invert, pattern.
buzzerBuzzerStateEnabled, on/off, pattern.
autoOffAutoOffStateTimeout seconds via autoOff.seconds. 0 = off, > 0 = on.
wifiWifiStateSSID + connection state.

Enums

NameValuesDescription
ConnectionStateEnumdisconnected, connectedClient connection.
ButtonStateEnumon, offLogical state.
WifiConnectionStateEnumunsupported, disconnected, reconnecting, connected, errorWi-Fi state.