Skip to content

Upgrade buttplug from v3 to v4#83

Open
heavyrubberslave wants to merge 9 commits into
mainfrom
upgrade-buttplug-v4
Open

Upgrade buttplug from v3 to v4#83
heavyrubberslave wants to merge 9 commits into
mainfrom
upgrade-buttplug-v4

Conversation

@heavyrubberslave

@heavyrubberslave heavyrubberslave commented Jun 4, 2026

Copy link
Copy Markdown
Member

Summary

  • Upgrades buttplug from ^3.2.1 to ^4.0.2
  • Replaces the removed messageAttributes API with the new features Map API (ButtplugClientDevice.features)
  • Replaces ActuatorType/SensorType enums with OutputType/InputType
  • Uses DeviceOutput.X.percent(value) for sending actuator commands via ButtplugClientDeviceFeature.runOutput()
  • Deletes SlvCtrlPlusButtplugWebsocketClientConnector — the workaround was already marked with a comment "until upgraded to buttplug@4.0.0"; the upstream connect() error handling is fixed in v4

Notes

The v4 ButtplugClientDeviceFeature public API does not expose FeatureDescriptor or device-specific step counts, so attribute labels default to undefined and actuator range attributes use a standard 0–100 step count (percent-based sending means the library handles the conversion to device-specific steps internally).

Test plan

  • npm run typecheck passes
  • npm test — all 72 tests pass

Closes #69

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Dependencies

    • Updated Buttplug library to v5.0.1
  • Improvements

    • Device I/O migrated to feature-based input/output model for more consistent control and sensing
    • Switched to the standard Buttplug websocket connector for improved compatibility
    • Device attribute handling now derives ranges from device-reported feature descriptors for clearer read/write behavior
    • Stop operation now awaits completion before responding, improving reliability
  • Tests

    • Updated device tests to validate feature-based input/output commands instead of legacy APIs

@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Bumps buttplug to ^5.0.1; migrates device I/O to feature-based InputType/OutputType (doRefresh/runInput, setAttribute/runOutput with DeviceOutputCommand); replaces custom websocket connector with ButtplugNodeWebsocketClientConnector; rewrites attribute factory; updates unit tests; makes StopScriptController.execute async.

Changes

Buttplug v5 API Migration

Layer / File(s) Summary
Buttplug dependency upgrade
package.json
Buttplug dependency updated from ^3.2.1 to ^5.0.1.
Websocket connector replacement
src/device/protocol/buttplugIo/buttplugIoWebsocketDeviceProvider.ts
Provider now constructs ButtplugNodeWebsocketClientConnector from the buttplug package and sets client name to include PID.
Core device I/O refactor
src/device/protocol/buttplugIo/buttplugIoDevice.ts
Device migrated to InputType/OutputType: imports changed; ButtplugIoDeviceAttributeKey templates updated; doRefresh iterates features and calls feature.runInput(..., InputCommandType.Read); setAttribute parses OutputType-index and routes outputs via feature.runOutput using created DeviceOutputCommand.
Attribute factory rewrite
src/device/protocol/buttplugIo/buttplugIoDeviceFactory.ts
parseDeviceAttributes iterates buttplugDevice.features and creates BoolDeviceAttribute for [0,1] ranges or IntRangeDeviceAttribute otherwise, keyed by `${OutputType
Unit tests updated for runOutput
tests/unit/device/protocol/buttplugIo/buttplugIoDevice.spec.ts
Tests now stub feature.runOutput, add makeDeviceStub, update imports to DeviceOutputCommand/OutputType, compute attribute keys from OutputType, and assert runOutput command shape/value instead of scalar calls.
StopScriptController async change
src/controller/automation/stopScriptController.ts
execute made async and now awaits scriptRuntime.stop(), returning Promise<void>.

Sequence Diagram

sequenceDiagram
  participant App as Application
  participant Dev as ButtplugIoDevice
  participant F as Feature
  App->>Dev: doRefresh()
  Dev->>F: runInput(InputCommandType.Read)
  F-->>Dev: input result
  Dev->>Dev: update attribute (InputType-index)
  App->>Dev: setAttribute(OutputType-index, value)
  Dev->>Dev: createOutputCommand(OutputType, value)
  Dev->>F: runOutput(DeviceOutputCommand)
  F-->>Dev: output complete
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

Suggested labels

minor

Poem

🐰 I hopped through types and swapped a wire,
Features read and outputs inspire,
Connector moved to upstream land,
Tests now check the command in hand,
Devices hum — all warmed by my little paw.

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title states 'Upgrade buttplug from v3 to v4' but the actual version bump in package.json is to ^5.0.1, not v4. Update the PR title to accurately reflect the actual dependency version change, e.g., 'Upgrade buttplug from v3 to v5' or 'Upgrade buttplug to v5.0.1'.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Linked Issues check ❓ Inconclusive The PR objectives state the upgrade is to buttplug@4.0.2, but package.json shows ^5.0.1 and commit message mentions 'buttplugio-js@v5', creating inconsistency with issue #69's intent. Clarify whether this PR upgrades to v4 or v5 to ensure alignment with issue #69 requirements and update all documentation accordingly.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Out of Scope Changes check ✅ Passed The changes are narrowly focused on buttplug dependency migration, including necessary updates to device protocol handling, factory methods, websocket provider, and related tests.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch upgrade-buttplug-v4

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/device/protocol/buttplugIo/buttplugIoDeviceFactory.ts`:
- Around line 65-99: The DeviceAttributeModifier values are flipped: in the
outputs loop (for (const [outputType, output] of feature.outputs) ...) replace
DeviceAttributeModifier.readOnly with DeviceAttributeModifier.writeOnly when
calling IntRangeDeviceAttribute.createInitialized for attrName, and in the
inputs loop (for (const [inputType, input] of feature.inputs) ...) replace
DeviceAttributeModifier.writeOnly with DeviceAttributeModifier.readOnly so
actuators created by IntRangeDeviceAttribute.createInitialized are writable and
sensors are readable; keep the rest of the attribute initialization (attrName,
feature.featureDescriptor, valueRange, step, default) unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 663ff87a-a8c1-4aef-a151-49973aa4c527

📥 Commits

Reviewing files that changed from the base of the PR and between 2297c29 and b40a321.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (2)
  • package.json
  • src/device/protocol/buttplugIo/buttplugIoDeviceFactory.ts

Comment thread src/device/protocol/buttplugIo/buttplugIoDeviceFactory.ts
heavyrubberslave and others added 8 commits June 7, 2026 15:07
- Replace ActuatorType/SensorType enums with OutputType/InputType
- Replace messageAttributes API with new features Map API
- Use DeviceOutput.X.percent() for sending actuator commands
- Delete SlvCtrlPlusButtplugWebsocketClientConnector workaround (fixed upstream in v4)

Closes #69

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
src/device/protocol/buttplugIo/buttplugIoDeviceFactory.ts (1)

97-100: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Pass the requested modifier through for boolean features.

This helper hardcodes DeviceAttributeModifier.writeOnly for every [0, 1] range, so boolean inputs created from Line 82 are modeled as write-only again. That breaks any binary sensor feature even though the caller already classified it as readOnly.

Proposed fix
         if (valueRangeMin === 0 && valueRangeMax === 1) {
             return BoolDeviceAttribute.createInitialized(
-                attrName, featureDescriptor, DeviceAttributeModifier.writeOnly, false
+                attrName, featureDescriptor || undefined, attributeModifier, false
             );
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/device/protocol/buttplugIo/buttplugIoDeviceFactory.ts` around lines 97 -
100, The boolean-attribute branch hardcodes DeviceAttributeModifier.writeOnly
when valueRangeMin === 0 && valueRangeMax === 1; change the call to
BoolDeviceAttribute.createInitialized to pass the incoming/requested modifier
(the variable used earlier to represent the attribute modifier) instead of
always using writeOnly so callers that classified the feature as readOnly are
preserved; update the invocation that currently supplies
DeviceAttributeModifier.writeOnly to use that modifier variable along with
attrName, featureDescriptor and the default value.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@src/device/protocol/buttplugIo/buttplugIoDeviceFactory.ts`:
- Around line 97-100: The boolean-attribute branch hardcodes
DeviceAttributeModifier.writeOnly when valueRangeMin === 0 && valueRangeMax ===
1; change the call to BoolDeviceAttribute.createInitialized to pass the
incoming/requested modifier (the variable used earlier to represent the
attribute modifier) instead of always using writeOnly so callers that classified
the feature as readOnly are preserved; update the invocation that currently
supplies DeviceAttributeModifier.writeOnly to use that modifier variable along
with attrName, featureDescriptor and the default value.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e3815912-9398-4d83-99bf-df36f1c8f4ff

📥 Commits

Reviewing files that changed from the base of the PR and between b40a321 and 3b74202.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (7)
  • package.json
  • src/controller/automation/stopScriptController.ts
  • src/device/protocol/buttplugIo/buttplugIoDevice.ts
  • src/device/protocol/buttplugIo/buttplugIoDeviceFactory.ts
  • src/device/protocol/buttplugIo/buttplugIoWebsocketDeviceProvider.ts
  • src/device/protocol/buttplugIo/slvCtrlPlusButtplugWebsocketClientConnector.ts
  • tests/unit/device/protocol/buttplugIo/buttplugIoDevice.spec.ts
💤 Files with no reviewable changes (1)
  • src/device/protocol/buttplugIo/slvCtrlPlusButtplugWebsocketClientConnector.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/device/protocol/buttplugIo/buttplugIoWebsocketDeviceProvider.ts
  • package.json
  • src/device/protocol/buttplugIo/buttplugIoDevice.ts
  • tests/unit/device/protocol/buttplugIo/buttplugIoDevice.spec.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Upgrade to buttplug@4.0.0

1 participant