├── .eslintrc ├── .gitattributes ├── .github ├── dependabot.yml ├── labeler.yml └── workflows │ ├── beta-release.yml │ ├── build.yml │ ├── changerelease.yml │ ├── dependabot.yml │ ├── labeler.yml │ ├── release-drafter.yml │ ├── release.yml │ └── stale.yml ├── .gitignore ├── .npmignore ├── BLE.md ├── CHANGELOG.md ├── LICENSE ├── OpenAPI.md ├── README.md ├── branding ├── Node_x_SwitchBot.svg ├── icon.png └── switchbot.png ├── docs ├── .nojekyll ├── assets │ ├── hierarchy.js │ ├── highlight.css │ ├── icons.js │ ├── icons.svg │ ├── main.js │ ├── navigation.js │ ├── search.js │ └── style.css ├── classes │ ├── Advertising.html │ ├── SwitchBotBLE.html │ ├── SwitchBotOpenAPI.html │ ├── SwitchbotDevice.html │ ├── WoBlindTilt.html │ ├── WoBulb.html │ ├── WoCeilingLight.html │ ├── WoContact.html │ ├── WoCurtain.html │ ├── WoHand.html │ ├── WoHub2.html │ ├── WoHumi.html │ ├── WoHumi2.html │ ├── WoIOSensorTH.html │ ├── WoKeypad.html │ ├── WoLeak.html │ ├── WoPlugMiniJP.html │ ├── WoPlugMiniUS.html │ ├── WoPresence.html │ ├── WoRelaySwitch1.html │ ├── WoRelaySwitch1PM.html │ ├── WoRemote.html │ ├── WoSensorTH.html │ ├── WoSensorTHPlus.html │ ├── WoSensorTHPro.html │ ├── WoSensorTHProCO2.html │ ├── WoSmartLock.html │ ├── WoSmartLockPro.html │ └── WoStrip.html ├── enums │ ├── LogLevel.html │ ├── SwitchBotBLEModel.html │ ├── SwitchBotBLEModelFriendlyName.html │ ├── SwitchBotBLEModelName.html │ └── SwitchBotModel.html ├── hierarchy.html ├── index.html ├── interfaces │ ├── AdvertisementData.html │ ├── Chars.html │ ├── ErrorObject.html │ ├── NobleTypes.html │ ├── Params.html │ ├── Rule.html │ ├── ServiceData.html │ ├── SwitchBotBLEDevice.html │ ├── WebhookDetail.html │ ├── ad.html │ ├── body.html │ ├── bodyChange.html │ ├── deleteWebhookResponse.html │ ├── device.html │ ├── deviceList.html │ ├── deviceStatus.html │ ├── deviceStatusRequest.html │ ├── deviceWebhook.html │ ├── deviceWebhookContext.html │ ├── devices.html │ ├── infraredRemoteList.html │ ├── irdevice.html │ ├── pushResponse.html │ ├── queryWebhookResponse.html │ ├── setupWebhookResponse.html │ ├── switchbot.html │ ├── updateWebhookResponse.html │ └── webhookRequest.html ├── media │ ├── BLE.md │ └── OpenAPI.md ├── modules.html └── types │ ├── MacAddress.html │ ├── batteryCirculatorFan.html │ ├── batteryCirculatorFanServiceData.html │ ├── batteryCirculatorFanStatus.html │ ├── batteryCirculatorFanWebhookContext.html │ ├── blindTilt.html │ ├── blindTiltServiceData.html │ ├── blindTiltStatus.html │ ├── blindTiltWebhookContext.html │ ├── bot.html │ ├── botServiceData.html │ ├── botStatus.html │ ├── botWebhookContext.html │ ├── ceilingLight.html │ ├── ceilingLightPro.html │ ├── ceilingLightProServiceData.html │ ├── ceilingLightProStatus.html │ ├── ceilingLightProWebhookContext.html │ ├── ceilingLightServiceData.html │ ├── ceilingLightStatus.html │ ├── ceilingLightWebhookContext.html │ ├── circulatorFanStatus.html │ ├── circulatorFanWebhookContext.html │ ├── colorBulb.html │ ├── colorBulbServiceData.html │ ├── colorBulbStatus.html │ ├── colorBulbWebhookContext.html │ ├── contactSensor.html │ ├── contactSensorServiceData.html │ ├── contactSensorStatus.html │ ├── contactSensorWebhookContext.html │ ├── curtain.html │ ├── curtain3.html │ ├── curtain3ServiceData.html │ ├── curtain3WebhookContext.html │ ├── curtainServiceData.html │ ├── curtainStatus.html │ ├── curtainWebhookContext.html │ ├── floorCleaningRobotS10.html │ ├── floorCleaningRobotS10Status.html │ ├── floorCleaningRobotS10WebhookContext.html │ ├── hub2.html │ ├── hub2ServiceData.html │ ├── hub2Status.html │ ├── hub2WebhookContext.html │ ├── humidifier.html │ ├── humidifier2ServiceData.html │ ├── humidifier2Status.html │ ├── humidifier2WebhookContext.html │ ├── humidifierServiceData.html │ ├── humidifierStatus.html │ ├── humidifierWebhookContext.html │ ├── indoorCam.html │ ├── indoorCameraWebhookContext.html │ ├── keypad.html │ ├── keypadDetectorServiceData.html │ ├── keypadTouch.html │ ├── keypadTouchWebhookContext.html │ ├── keypadWebhookContext.html │ ├── lock.html │ ├── lockPro.html │ ├── lockProServiceData.html │ ├── lockProStatus.html │ ├── lockProWebhookContext.html │ ├── lockServiceData.html │ ├── lockStatus.html │ ├── lockWebhookContext.html │ ├── meter.html │ ├── meterPlus.html │ ├── meterPlusServiceData.html │ ├── meterPlusStatus.html │ ├── meterPlusWebhookContext.html │ ├── meterPro.html │ ├── meterProCO2ServiceData.html │ ├── meterProCO2Status.html │ ├── meterProCO2WebhookContext.html │ ├── meterProServiceData.html │ ├── meterProStatus.html │ ├── meterProWebhookContext.html │ ├── meterServiceData.html │ ├── meterStatus.html │ ├── meterWebhookContext.html │ ├── motionSensor.html │ ├── motionSensorServiceData.html │ ├── motionSensorStatus.html │ ├── motionSensorWebhookContext.html │ ├── onadvertisement.html │ ├── ondiscover.html │ ├── outdoorMeter.html │ ├── outdoorMeterServiceData.html │ ├── outdoorMeterStatus.html │ ├── outdoorMeterWebhookContext.html │ ├── panTiltCamWebhookContext.html │ ├── pantiltCam.html │ ├── pantiltCam2k.html │ ├── plug.html │ ├── plugMini.html │ ├── plugMiniJPServiceData.html │ ├── plugMiniJPWebhookContext.html │ ├── plugMiniStatus.html │ ├── plugMiniUSServiceData.html │ ├── plugMiniUSWebhookContext.html │ ├── plugStatus.html │ ├── plugWebhookContext.html │ ├── relaySwitch1Context.html │ ├── relaySwitch1PMContext.html │ ├── relaySwitch1PMServiceData.html │ ├── relaySwitch1PMStatus.html │ ├── relaySwitch1ServiceData.html │ ├── relaySwitch1Status.html │ ├── remote.html │ ├── remoteServiceData.html │ ├── robotVacuumCleanerS1.html │ ├── robotVacuumCleanerS1Plus.html │ ├── robotVacuumCleanerS1PlusStatus.html │ ├── robotVacuumCleanerS1PlusWebhookContext.html │ ├── robotVacuumCleanerS1Status.html │ ├── robotVacuumCleanerS1WebhookContext.html │ ├── robotVacuumCleanerServiceData.html │ ├── stripLight.html │ ├── stripLightServiceData.html │ ├── stripLightStatus.html │ ├── stripLightWebhookContext.html │ ├── waterLeakDetector.html │ ├── waterLeakDetectorServiceData.html │ ├── waterLeakDetectorStatus.html │ └── waterLeakDetectorWebhookContext.html ├── eslint.config.js ├── jest.config.js ├── package-lock.json ├── package.json ├── src ├── device.ts ├── index.test.ts ├── index.ts ├── parameter-checker.ts ├── settings.test.ts ├── settings.ts ├── switchbot-ble.ts ├── switchbot-openapi.ts └── types │ ├── bledevicestatus.ts │ ├── devicelist.ts │ ├── devicepush.ts │ ├── deviceresponse.ts │ ├── devicestatus.ts │ ├── devicewebhookstatus.ts │ └── irdevicelist.ts ├── tsconfig.json └── typedoc.json /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "extends": [ 4 | "eslint:recommended", 5 | "plugin:@typescript-eslint/eslint-recommended", 6 | "plugin:@typescript-eslint/recommended", // uses the recommended rules from the @typescript-eslint/eslint-plugin 7 | "plugin:jest/recommended" // enables eslint-plugin-jest 8 | ], 9 | "parserOptions": { 10 | "ecmaVersion": 2021, 11 | "sourceType": "module" 12 | }, 13 | "ignorePatterns": [ 14 | "dist", 15 | "server" 16 | ], 17 | "rules": { 18 | "quotes": [ 19 | "warn", 20 | "single" 21 | ], 22 | "indent": [ 23 | "warn", 24 | 2, 25 | { 26 | "SwitchCase": 1 27 | } 28 | ], 29 | "linebreak-style": [ 30 | "warn", 31 | "unix" 32 | ], 33 | "semi": [ 34 | "warn", 35 | "always" 36 | ], 37 | "comma-dangle": [ 38 | "warn", 39 | "always-multiline" 40 | ], 41 | "dot-notation": "off", 42 | "eqeqeq": "warn", 43 | "curly": [ 44 | "warn", 45 | "all" 46 | ], 47 | "brace-style": [ 48 | "warn" 49 | ], 50 | "prefer-arrow-callback": [ 51 | "warn" 52 | ], 53 | "max-len": [ 54 | "warn", 55 | 150 56 | ], // use the provided log method instead 57 | "no-non-null-assertion": [ 58 | "off" 59 | ], 60 | "comma-spacing": [ 61 | "error" 62 | ], 63 | "no-multi-spaces": [ 64 | "warn", 65 | { 66 | "ignoreEOLComments": true 67 | } 68 | ], 69 | "no-trailing-spaces": [ 70 | "warn" 71 | ], 72 | "lines-between-class-members": [ 73 | "warn", 74 | "always", 75 | { 76 | "exceptAfterSingleLine": true 77 | } 78 | ], 79 | "@typescript-eslint/explicit-function-return-type": "off", 80 | "@typescript-eslint/no-non-null-assertion": "off", 81 | "@typescript-eslint/explicit-module-boundary-types": "off", 82 | "@typescript-eslint/no-explicit-any": "error" 83 | } 84 | } -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: 'npm' # See documentation for possible values 9 | directory: '/' # Location of package manifests 10 | target-branch: 'beta-*.*.*' 11 | schedule: 12 | interval: 'daily' 13 | - package-ecosystem: 'github-actions' # See documentation for possible values 14 | directory: '/' # Location of package manifests 15 | target-branch: 'beta-*.*.*' 16 | schedule: 17 | interval: 'daily' 18 | -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | # Add 'branding' label to any changes within 'docs' folder or any subfolders 2 | branding: 3 | - changed-files: 4 | - any-glob-to-any-file: branding/** 5 | 6 | # Add 'docs' label to any change to .md files within the entire repository 7 | docs: 8 | - changed-files: 9 | - any-glob-to-any-file: '**/*.md' 10 | 11 | # Add 'enhancement' label to any change to src files within the source dir EXCEPT for the docs sub-folder 12 | enhancement: 13 | - changed-files: 14 | - any-glob-to-any-file: 'src/**/*' 15 | - any-glob-to-any-file: 'config.schema.json' 16 | 17 | # Add 'dependencies' label to any change to src files within the source dir EXCEPT for the docs sub-folder 18 | dependencies: 19 | - changed-files: 20 | - any-glob-to-any-file: 'package.json' 21 | - any-glob-to-any-file: 'package-lock.json' 22 | 23 | # Add 'beta' label to any PR that is opened against the `beta` branch 24 | beta: 25 | - base-branch: 'beta*' 26 | 27 | # Add 'alpha' label to any PR that is opened against the `alpha` branch 28 | alpha: 29 | - base-branch: 'alpha*' 30 | 31 | # Add 'latest' label to any PR that is opened against the `latest` branch 32 | latest: 33 | - base-branch: 'latest' 34 | 35 | # Add 'workflow' to any changes within 'workflow' folder or any subfolders 36 | workflow: 37 | - changed-files: 38 | - any-glob-to-any-file: .github/** -------------------------------------------------------------------------------- /.github/workflows/beta-release.yml: -------------------------------------------------------------------------------- 1 | name: Beta Release 2 | 3 | on: 4 | push: 5 | branches: [beta-*.*.*, beta] 6 | workflow_dispatch: 7 | 8 | jobs: 9 | build_and_test: 10 | uses: OpenWonderLabs/.github/.github/workflows/nodejs-build-and-test.yml@latest 11 | with: 12 | enable_coverage: true 13 | secrets: 14 | token: ${{ secrets.GITHUB_TOKEN }} 15 | 16 | lint: 17 | needs: build_and_test 18 | uses: OpenWonderLabs/.github/.github/workflows/eslint.yml@latest 19 | 20 | publish: 21 | needs: lint 22 | if: ${{ github.repository == 'OpenWonderLabs/node-switchbot' }} 23 | permissions: 24 | id-token: write 25 | uses: OpenWonderLabs/.github/.github/workflows/npm-publish-esm.yml@latest 26 | with: 27 | tag: 'beta' 28 | dynamically_adjust_version: true 29 | npm_version_command: 'pre' 30 | pre_id: 'beta' 31 | secrets: 32 | npm_auth_token: ${{ secrets.npm_token }} 33 | 34 | pre-release: 35 | needs: publish 36 | if: ${{ github.repository == 'OpenWonderLabs/node-switchbot' }} 37 | uses: OpenWonderLabs/.github/.github/workflows/pre-release.yml@latest 38 | with: 39 | npm_version: ${{ needs.publish.outputs.NPM_VERSION }} 40 | body: | 41 | **Beta Release** 42 | **Version**: v${{ needs.publish.outputs.NPM_VERSION }} 43 | [How To Test Beta Releases](https://github.com/OpenWonderLabs/homebridge-switchbot/wiki/Beta-Version) 44 | 45 | github-releases-to-discord: 46 | name: Discord Webhooks 47 | needs: [build_and_test,publish] 48 | if: ${{ github.repository == 'OpenWonderLabs/node-switchbot' }} 49 | uses: OpenWonderLabs/.github/.github/workflows/discord-webhooks.yml@latest 50 | with: 51 | title: "Node-SwitchBot Beta Release" 52 | description: | 53 | Version `v${{ needs.publish.outputs.NPM_VERSION }}` 54 | url: "https://github.com/homebridge/camera-utils/releases/tag/v${{ needs.publish.outputs.NPM_VERSION }}" 55 | secrets: 56 | DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_URL_BETA || secrets.DISCORD_WEBHOOK_URL_LATEST }} -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Node Build 2 | 3 | on: 4 | push: 5 | branches: [latest] 6 | pull_request: 7 | workflow_dispatch: 8 | 9 | jobs: 10 | build_and_test: 11 | uses: OpenWonderLabs/.github/.github/workflows/nodejs-build-and-test.yml@latest 12 | with: 13 | enable_coverage: true 14 | secrets: 15 | token: ${{ secrets.GITHUB_TOKEN }} 16 | lint: 17 | needs: build_and_test 18 | uses: OpenWonderLabs/.github/.github/workflows/eslint.yml@latest 19 | -------------------------------------------------------------------------------- /.github/workflows/changerelease.yml: -------------------------------------------------------------------------------- 1 | name: Changelog to Release 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | changerelease: 9 | uses: OpenWonderLabs/.github/.github/workflows/changerelease.yml@latest 10 | secrets: 11 | token: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/dependabot.yml: -------------------------------------------------------------------------------- 1 | name: AutoDependabot 2 | 3 | on: 4 | pull_request: 5 | branches: [beta, latest] 6 | pull_request_target: 7 | branches: [beta, latest] 8 | 9 | jobs: 10 | dependabot: 11 | uses: OpenWonderLabs/.github/.github/workflows/dependabot.yml@latest 12 | secrets: 13 | token: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/labeler.yml: -------------------------------------------------------------------------------- 1 | # This workflow will triage pull requests and apply a label based on the 2 | # paths that are modified in the pull request. 3 | # 4 | # To use this workflow, you will need to set up a .github/labeler.yml 5 | # file with configuration. For more information, see: 6 | # https://github.com/actions/labeler/blob/main/README.md 7 | 8 | name: Labeler 9 | 10 | on: pull_request_target 11 | 12 | jobs: 13 | labeler: 14 | uses: OpenWonderLabs/.github/.github/workflows/labeler.yml@latest 15 | secrets: 16 | token: ${{ secrets.GITHUB_TOKEN }} 17 | -------------------------------------------------------------------------------- /.github/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name: Release Drafter 2 | 3 | on: 4 | push: 5 | branches: [latest] 6 | pull_request: # required for autolabeler 7 | types: [opened, reopened, synchronize] 8 | workflow_dispatch: 9 | 10 | jobs: 11 | release-drafter: 12 | uses: OpenWonderLabs/.github/.github/workflows/release-drafter.yml@latest 13 | secrets: 14 | token: ${{ secrets.GITHUB_TOKEN }} 15 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | build_and_test: 9 | uses: OpenWonderLabs/.github/.github/workflows/nodejs-build-and-test.yml@latest 10 | with: 11 | enable_coverage: true 12 | secrets: 13 | token: ${{ secrets.GITHUB_TOKEN }} 14 | 15 | publish: 16 | needs: build_and_test 17 | if: ${{ github.repository == 'OpenWonderLabs/node-switchbot' }} 18 | permissions: 19 | id-token: write 20 | uses: OpenWonderLabs/.github/.github/workflows/npm-publish-esm.yml@latest 21 | secrets: 22 | npm_auth_token: ${{ secrets.npm_token }} 23 | 24 | github-releases-to-discord: 25 | name: Discord Webhooks 26 | needs: [build_and_test,publish] 27 | if: ${{ github.repository == 'OpenWonderLabs/node-switchbot' }} 28 | uses: OpenWonderLabs/.github/.github/workflows/discord-webhooks.yml@latest 29 | with: 30 | title: "Node-SwitchBot Release" 31 | description: | 32 | Version `v${{ needs.publish.outputs.NPM_VERSION }}` 33 | url: "https://github.com/homebridge/camera-utils/releases/tag/v${{ needs.publish.outputs.NPM_VERSION }}" 34 | secrets: 35 | DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_URL_LATEST }} 36 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: Stale workflow 2 | 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | - cron: '45 11 * * *' 7 | 8 | jobs: 9 | stale: 10 | uses: OpenWonderLabs/.github/.github/workflows/stale.yml@latest 11 | secrets: 12 | token: ${{ secrets.GITHUB_TOKEN }} 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore compiled code 2 | 3 | dist 4 | 5 | # ------------- Defaults ------------- 6 | 7 | # Logs 8 | 9 | logs 10 | _.log 11 | npm-debug.log_ 12 | yarn-debug.log* 13 | yarn-error.log* 14 | lerna-debug.log\* 15 | 16 | # Diagnostic reports (https://nodejs.org/api/report.html) 17 | 18 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 19 | 20 | # Runtime data 21 | 22 | pids 23 | _.pid 24 | _.seed 25 | \*.pid.lock 26 | 27 | # Directory for instrumented libs generated by jscoverage/JSCover 28 | 29 | lib-cov 30 | 31 | # Coverage directory used by tools like istanbul 32 | 33 | coverage 34 | \*.lcov 35 | 36 | # nyc test coverage 37 | 38 | .nyc_output 39 | 40 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 41 | 42 | .grunt 43 | 44 | # Bower dependency directory (https://bower.io/) 45 | 46 | bower_components 47 | 48 | # node-waf configuration 49 | 50 | .lock-wscript 51 | 52 | # Compiled binary addons (https://nodejs.org/api/addons.html) 53 | 54 | build/Release 55 | 56 | # Dependency directories 57 | 58 | node_modules/ 59 | jspm_packages/ 60 | 61 | # Snowpack dependency directory (https://snowpack.dev/) 62 | 63 | web_modules/ 64 | 65 | # TypeScript cache 66 | 67 | \*.tsbuildinfo 68 | 69 | # Optional npm cache directory 70 | 71 | .npm 72 | 73 | # Optional eslint cache 74 | 75 | .eslintcache 76 | 77 | # Microbundle cache 78 | 79 | .rpt2_cache/ 80 | .rts2_cache_cjs/ 81 | .rts2_cache_es/ 82 | .rts2_cache_umd/ 83 | 84 | # Optional REPL history 85 | 86 | .node_repl_history 87 | 88 | # Output of 'npm pack' 89 | 90 | \*.tgz 91 | 92 | # Yarn Integrity file 93 | 94 | .yarn-integrity 95 | 96 | # dotenv environment variables file 97 | 98 | .env 99 | .env.test 100 | 101 | # parcel-bundler cache (https://parceljs.org/) 102 | 103 | .cache 104 | .parcel-cache 105 | 106 | # Next.js build output 107 | 108 | .next 109 | 110 | # Nuxt.js build / generate output 111 | 112 | .nuxt 113 | dist 114 | 115 | # Gatsby files 116 | 117 | .cache/ 118 | 119 | # Comment in the public line in if your project uses Gatsby and not Next.js 120 | 121 | # https://nextjs.org/blog/next-9-1#public-directory-support 122 | 123 | # public 124 | 125 | # vuepress build output 126 | 127 | .vuepress/dist 128 | 129 | # Serverless directories 130 | 131 | .serverless/ 132 | 133 | # FuseBox cache 134 | 135 | .fusebox/ 136 | 137 | # DynamoDB Local files 138 | 139 | .dynamodb/ 140 | 141 | # TernJS port file 142 | 143 | .tern-port 144 | 145 | # Stores VSCode versions used for testing VSCode extensions 146 | 147 | .vscode-test 148 | 149 | # yarn v2 150 | 151 | .yarn/cache 152 | .yarn/unplugged 153 | .yarn/build-state.yml 154 | .pnp.\* 155 | 156 | # others 157 | .DS_Store 158 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Ignore source code 2 | 3 | src 4 | 5 | # ------------- Defaults ------------- 6 | 7 | # eslint 8 | 9 | .eslintrc 10 | 11 | # typescript 12 | 13 | tsconfig.json 14 | 15 | # vscode 16 | 17 | .vscode 18 | 19 | # nodemon 20 | 21 | nodemon.json 22 | 23 | # Logs 24 | 25 | logs 26 | _.log 27 | npm-debug.log_ 28 | yarn-debug.log* 29 | yarn-error.log* 30 | lerna-debug.log\* 31 | 32 | # Diagnostic reports (https://nodejs.org/api/report.html) 33 | 34 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 35 | 36 | # Runtime data 37 | 38 | pids 39 | _.pid 40 | _.seed 41 | \*.pid.lock 42 | 43 | # Directory for instrumented libs generated by jscoverage/JSCover 44 | 45 | lib-cov 46 | 47 | # Coverage directory used by tools like istanbul 48 | 49 | coverage 50 | \*.lcov 51 | 52 | # nyc test coverage 53 | 54 | .nyc_output 55 | 56 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 57 | 58 | .grunt 59 | 60 | # Bower dependency directory (https://bower.io/) 61 | 62 | bower_components 63 | 64 | # node-waf configuration 65 | 66 | .lock-wscript 67 | 68 | # Compiled binary addons (https://nodejs.org/api/addons.html) 69 | 70 | build/Release 71 | 72 | # Dependency directories 73 | 74 | node_modules/ 75 | jspm_packages/ 76 | 77 | # Snowpack dependency directory (https://snowpack.dev/) 78 | 79 | web_modules/ 80 | 81 | # TypeScript cache 82 | 83 | \*.tsbuildinfo 84 | 85 | # Optional npm cache directory 86 | 87 | .npm 88 | 89 | # Optional eslint cache 90 | 91 | .eslintcache 92 | 93 | # Microbundle cache 94 | 95 | .rpt2_cache/ 96 | .rts2_cache_cjs/ 97 | .rts2_cache_es/ 98 | .rts2_cache_umd/ 99 | 100 | # Optional REPL history 101 | 102 | .node_repl_history 103 | 104 | # Output of 'npm pack' 105 | 106 | \*.tgz 107 | 108 | # Yarn Integrity file 109 | 110 | .yarn-integrity 111 | 112 | # dotenv environment variables file 113 | 114 | .env 115 | .env.test 116 | 117 | # parcel-bundler cache (https://parceljs.org/) 118 | 119 | .cache 120 | .parcel-cache 121 | 122 | # Next.js build output 123 | 124 | .next 125 | 126 | # Nuxt.js build / generate output 127 | 128 | .nuxt 129 | dist 130 | 131 | # Gatsby files 132 | 133 | .cache/ 134 | 135 | # Comment in the public line in if your project uses Gatsby and not Next.js 136 | 137 | # https://nextjs.org/blog/next-9-1#public-directory-support 138 | 139 | # public 140 | 141 | # vuepress build output 142 | 143 | .vuepress/dist 144 | 145 | # Serverless directories 146 | 147 | .serverless/ 148 | 149 | # FuseBox cache 150 | 151 | .fusebox/ 152 | 153 | # DynamoDB Local files 154 | 155 | .dynamodb/ 156 | 157 | # TernJS port file 158 | 159 | .tern-port 160 | 161 | # Stores VSCode versions used for testing VSCode extensions 162 | 163 | .vscode-test 164 | 165 | # yarn v2 166 | 167 | .yarn/cache 168 | .yarn/unplugged 169 | .yarn/build-state.yml 170 | .pnp.\* 171 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License (ISC) 2 | Copyright (c) 2020 SwitchBot 3 | 4 | Permission to use, copy, modify, and/or distribute this software for any 5 | purpose with or without fee is hereby granted, provided that the above 6 | copyright notice and this permission notice appear in all copies. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 | PERFORMANCE OF THIS SOFTWARE. 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | ![node-switchbot](https://raw.githubusercontent.com/OpenWonderLabs/node-switchbot/latest/branding/Node_x_SwitchBot.svg?sanitize=true) 4 | 5 | # Node-SwitchBot 6 | 7 | [![npm version](https://badgen.net/npm/v/node-switchbot)](https://www.npmjs.com/package/node-switchbot) 8 | [![npm downloads](https://badgen.net/npm/dt/node-switchbot)](https://www.npmjs.com/package/node-switchbot) 9 | 10 |
11 | 12 | The `node-switchbot` is a Node.js module that allows you to interact with various SwitchBot devices. You can control your [SwitchBot (Bot)'s](https://www.switch-bot.com/bot) arm, operate your [SwitchBot Curtain](https://www.switch-bot.com/products/switchbot-curtain), and manage your [SwitchBot Lock](https://www.switch-bot.com/products/switchbot-lock). Additionally, you can monitor temperature and humidity using the [SwitchBot Thermometer & Hygrometer (Meter)](https://www.switch-bot.com/meter), and check the status of the [SwitchBot Motion Sensor](https://www.switch-bot.com/products/motion-sensor) and [SwitchBot Contact Sensor](https://www.switch-bot.com/products/contact-sensor). 13 | 14 | This module now supports both Bluetooth Low Energy (BLE) and the SwitchBot OpenAPI, providing more flexibility and options for interacting with your devices. 15 | 16 | Please note that most of this module was developed by referencing the official [BLE API](https://github.com/OpenWonderLabs/SwitchBotAPI-BLE) and [OpenAPI](https://github.com/OpenWonderLabs/SwitchBotAPI) documentation. However, some functionalities were developed through trial and error, so there might be inaccuracies in the information obtained from this module. 17 | 18 | --- 19 | 20 | ## [Installation](https://npmjs.org/node-switchbot) 21 | 22 | To install the `node-switchbot` module within your project, use the following command: 23 | 24 | ```sh 25 | $ npm install --save node-switchbot 26 | ``` 27 | 28 | ## [BLE (Bluetooth Low Energy)](BLE.md) 29 | 30 | To see a breakdown of how to use the BLE functionality of this project, visit the [BLE (Bluetooth Low Energy)](BLE.md) documentation. 31 | 32 | ## [OpenAPI](OpenAPI.md) 33 | 34 | To see a breakdown of how to use the OpenAPI functionality of this project, visit the [OpenAPI](OpenAPI.md) documentation. 35 | 36 | ## References 37 | 38 | - [SwitchBot (Official website)](https://www.switch-bot.com/) 39 | - [Facebook @SwitchBotRobot](https://www.facebook.com/SwitchBotRobot/) 40 | - [Twitter @SwitchBot](https://twitter.com/switchbot) 41 | -------------------------------------------------------------------------------- /branding/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenWonderLabs/node-switchbot/bd44206094127456f2b9ec451fafaeb9a77bd787/branding/icon.png -------------------------------------------------------------------------------- /branding/switchbot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenWonderLabs/node-switchbot/bd44206094127456f2b9ec451fafaeb9a77bd787/branding/switchbot.png -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /docs/assets/hierarchy.js: -------------------------------------------------------------------------------- 1 | window.hierarchyData = "eJyVlkFP2zAYQP+Lzx8jn53YTo5jB7aBiFYQB8QhTQy1SBzkOJsQ6n+fomg0LhB7p0rty3u2Gyd+Jbbv3UCKOypQAEV+D8Sqh1bVTvdmIMUrocinD1N1ihRk80e7erft3Tf1W9eKAHnSpiEFUglktC0pSN1Ww6CG0yP0y851LYH5Z1IQNzQn07Un8xdA6p1uG6sMKe4Y45BSCRlK4JgBlwkITkGmCeRJBrmUgIlAQGQCkCYMkPIckKUSMKUCMM0pYMYzQM4koJgQwSWgZAxQ5hIw5ynQyUJRyPs9EMaWU73tv7baNNe6dWvTXGCBKe6BpFT6hbHdBuRjuw17M/S9Z0q32jxe6MddYPBLMtzhmPmd3riqDiVmKMIuE98+WldpE7DPUNguOPXs55Vp1tUTEfbK1B/1+bilAe+4pWFvnmRH3k6HvJ2O8Er5zhsccKcjRjxtSU/9/WqjzNDb6/N1/4GLiCATXuSnenmuAv/kzETIacI8+YWqntbVExEj5rknLtvx8VIb/aNc1x+4iAhL5YeRm01c5GYTEUmpv/6lVYMy6++CAxUTyP2N+ku11cv8NsH1yJKMCGU8+zRUXsanysuIGGfyKNb1LrBoMxMhF0e3bdy2+49NJ7j8MFC24xAXmciIkGQfz6S0fWTH9jGZ/JP52P7sKvA09NmIWM5TP9ZV1l30deDJ8oaFE/T4yft2bXjdFmRECMXRwjmrnwOFCYlQC1w+WBr/gEkz/s+sjVP2oarVcNqsHy3fSP94SSUT03lv+nxX3LjKLe7pte6MRtT3+/1fvJagpQ==" -------------------------------------------------------------------------------- /docs/assets/highlight.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --light-hl-0: #795E26; 3 | --dark-hl-0: #DCDCAA; 4 | --light-hl-1: #000000; 5 | --dark-hl-1: #D4D4D4; 6 | --light-hl-2: #A31515; 7 | --dark-hl-2: #CE9178; 8 | --light-hl-3: #0000FF; 9 | --dark-hl-3: #569CD6; 10 | --light-hl-4: #0070C1; 11 | --dark-hl-4: #4FC1FF; 12 | --light-hl-5: #008000; 13 | --dark-hl-5: #6A9955; 14 | --light-hl-6: #001080; 15 | --dark-hl-6: #9CDCFE; 16 | --light-code-background: #FFFFFF; 17 | --dark-code-background: #1E1E1E; 18 | } 19 | 20 | @media (prefers-color-scheme: light) { :root { 21 | --hl-0: var(--light-hl-0); 22 | --hl-1: var(--light-hl-1); 23 | --hl-2: var(--light-hl-2); 24 | --hl-3: var(--light-hl-3); 25 | --hl-4: var(--light-hl-4); 26 | --hl-5: var(--light-hl-5); 27 | --hl-6: var(--light-hl-6); 28 | --code-background: var(--light-code-background); 29 | } } 30 | 31 | @media (prefers-color-scheme: dark) { :root { 32 | --hl-0: var(--dark-hl-0); 33 | --hl-1: var(--dark-hl-1); 34 | --hl-2: var(--dark-hl-2); 35 | --hl-3: var(--dark-hl-3); 36 | --hl-4: var(--dark-hl-4); 37 | --hl-5: var(--dark-hl-5); 38 | --hl-6: var(--dark-hl-6); 39 | --code-background: var(--dark-code-background); 40 | } } 41 | 42 | :root[data-theme='light'] { 43 | --hl-0: var(--light-hl-0); 44 | --hl-1: var(--light-hl-1); 45 | --hl-2: var(--light-hl-2); 46 | --hl-3: var(--light-hl-3); 47 | --hl-4: var(--light-hl-4); 48 | --hl-5: var(--light-hl-5); 49 | --hl-6: var(--light-hl-6); 50 | --code-background: var(--light-code-background); 51 | } 52 | 53 | :root[data-theme='dark'] { 54 | --hl-0: var(--dark-hl-0); 55 | --hl-1: var(--dark-hl-1); 56 | --hl-2: var(--dark-hl-2); 57 | --hl-3: var(--dark-hl-3); 58 | --hl-4: var(--dark-hl-4); 59 | --hl-5: var(--dark-hl-5); 60 | --hl-6: var(--dark-hl-6); 61 | --code-background: var(--dark-code-background); 62 | } 63 | 64 | .hl-0 { color: var(--hl-0); } 65 | .hl-1 { color: var(--hl-1); } 66 | .hl-2 { color: var(--hl-2); } 67 | .hl-3 { color: var(--hl-3); } 68 | .hl-4 { color: var(--hl-4); } 69 | .hl-5 { color: var(--hl-5); } 70 | .hl-6 { color: var(--hl-6); } 71 | pre, code { background: var(--code-background); } 72 | -------------------------------------------------------------------------------- /docs/assets/navigation.js: -------------------------------------------------------------------------------- 1 | window.navigationData = "eJylm01z2zYQhv+Lzpk6Vib98M2Wk0lSKdZYdnPo9ACRsIQaBBQQtKvp5L93aEoWSCx2F+xV++6z2BfgF0j9+e/Ey3/85GIyt5u5fJJ68mayE347uZhI01T12fH3n7a+aoOPypSTi19/vHnNXD0rX2yvrL+af1jYMkZEggzWR6ekKfX+q6gkyQ3FGTVYbCYTN4Do/rJ8ks6rWpnNCVFoUdeyPguCfcL5NNVdDAmjNGVt/bV8UoVMgV4FrBHd7KS5XH5GRnVQYLRv9korU94p7WNQECQYjV6D6Y1e45kzqbQym7nabMEBhHGCZI0XBQzpQkR+47xQBszvQnj+J2FKKLn9nchs1lMws1lPqcxKwZmVojMTRStFVP18s5Kmtu7uEwQ4RXHK73K/E6BjXQTPnkvxCOW2v+OZS91sFsqoL0so/xTlUe5XGOV+RVCcrKWBTginGE64lVrsuwP+HKKEcT5puaBYywVFq6wH++oieDa2vnir66ha6qbGKG2cSXIWBTnL5sxuwEOvryBolXB+bgvwIHgNMhmp1oI4QfJO7UBEG8BywzOAMl66B1HI+mx4+E/f/wxc2GUljb8WXoCMSIUh17bcg5Q2QCXOtsJsZDK9C2OQ2Va4Gsx/iWCppdTSy29yvbX28VbWO2tqeCigEkf3b1Z6rPg2BUqeq9ojgDZMQ2BnDjE6feWFbzBGJ+CCbuX3RqJd9XQ09jAjCPCgYKPa+532Z5J4EGLgD85Zd7P+WxYwL4hjGGUenHCy7M7+yWURy1CoQ5boMYgBvtq1lnf7XWKJncIYZCmcqGBAF8KSd029RY/aUICBvjfS7TmnAUiIgW8bDYPaAJa4kq71P3l+DuIYppa+2XEag4Qo+PjMBdOOUbTF4Plv+GgXdhrJMGizKwXvjA4qMfRBei29UBpE9hQY6vlYNX027EvQi6jwXrr9TLmi0cJb91EED2K+PQLPIM2A+fa3X87fTwkuuCzTJdKrlFdtcPFBCkFXIVaN1Fk/XQs9/cc14x2CAxreHUAImPmAhs+Fbe6H2TTCUFhG0m1Mis4uUBbmmc1yy6Z8slyHLOXNUEARC3D/p4MVyb0fnNN7nIlR0dMMSUNmIK3MrQHODCjKJOMzhopzKjFNGukQbU++N3xjMl2hLwCAJItKDH38ub6w2rr+du6BeQywCdiCADR8LuxoP8ymEU7CMpr+suHcbejEzCCYRUIdhXV5/ISzkSSLSjmclJJVhjv2ByK0W5/MfpdIf8fNxyYllnCphGmgismmB5w/3sTKCYNMEqvxvL4ftLVupqUwymxubXu3c/52SAZFo8iwF4h0VBXcJ0YKVXXbeyvVYbfRGyk4D1ligzCLBhp6inAYuF2xgmZWqlQPSkan91OEz8ANg1Q57IR9A0EGkTIzIeRXYNkxyg3KjFwvuFbkOaFM2R6/ohoCXwNsgnQCH2NaSdV4HLzB7XiPwNvbVO619LLw6I1NUsircGebYgszX0IZFNzGpJBXgQPP4+rey8GOo6N3gnAe8AStofeAyWxkQmMFlwkeur0gk4SbDYo4ZKLpzI7T7fJ7pRvN63IhisuydLKOxnWKUIxK+vii+fIjK7P/Qj/Ijt/kIwRkqiANnwtO2iDMpuHTl5Dx6PEBfvydmz+7we5aYFUOG3EyEGQQOW4CQm4FhhkjnMBtyPOAZ8CI7qnWc/tGms7omNFuZq/WK2vgTZ0wlsPBrINlWXTYyEiRwyRsTSqpGtaI8IOdIXgQpmmlqgv7FF9qThGS0fj21ngBXbDCWA4Hme+ELIsOznesyGHi851WUjV2wnilPfCQc4rwGdPoXjeMMTh3nRbvNqUj+brZRCzdbDh57XekUG77Ozf/yxJZd6CITyYcS+i4fHhF96Nc1v2K4UJPxCfzXBjqOPy0A/zu6dHljcsFXwInoIAkh7pcMLivojwysgqSwswK4JxBmhwuc9wjR02PmTvi/pffR0781XcqF+1zICCJ7d73H6JomuplO1y61XkEBTRjuNCjaUo3lp+YJVQ9thZ+1uBljanN73F8f/m9/e++kFWNialKdfuJPfj9zCnCZyCjBEUZZHBWh3E+D5/BlI7iPwsvXfsnouOO8xAcCbKJiMWYNr8OaHhClk3H7SfkcLW//gNYd0n3" -------------------------------------------------------------------------------- /docs/types/MacAddress.html: -------------------------------------------------------------------------------- 1 | MacAddress | node-switchbot

Type Alias MacAddress

MacAddress: string
2 | -------------------------------------------------------------------------------- /docs/types/batteryCirculatorFan.html: -------------------------------------------------------------------------------- 1 | batteryCirculatorFan | node-switchbot

Type Alias batteryCirculatorFan

batteryCirculatorFan: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/bot.html: -------------------------------------------------------------------------------- 1 | bot | node-switchbot

Type Alias bot

bot: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/ceilingLight.html: -------------------------------------------------------------------------------- 1 | ceilingLight | node-switchbot

Type Alias ceilingLight

ceilingLight: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/ceilingLightPro.html: -------------------------------------------------------------------------------- 1 | ceilingLightPro | node-switchbot

Type Alias ceilingLightPro

ceilingLightPro: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/ceilingLightStatus.html: -------------------------------------------------------------------------------- 1 | ceilingLightStatus | node-switchbot

Type Alias ceilingLightStatus

ceilingLightStatus: deviceStatus & {
    brightness: number;
    colorTemperature: number;
    power: boolean;
}
2 | -------------------------------------------------------------------------------- /docs/types/colorBulb.html: -------------------------------------------------------------------------------- 1 | colorBulb | node-switchbot

Type Alias colorBulb

colorBulb: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/contactSensor.html: -------------------------------------------------------------------------------- 1 | contactSensor | node-switchbot

Type Alias contactSensor

contactSensor: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/floorCleaningRobotS10.html: -------------------------------------------------------------------------------- 1 | floorCleaningRobotS10 | node-switchbot

Type Alias floorCleaningRobotS10

floorCleaningRobotS10: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/hub2.html: -------------------------------------------------------------------------------- 1 | hub2 | node-switchbot

Type Alias hub2

hub2: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/hub2Status.html: -------------------------------------------------------------------------------- 1 | hub2Status | node-switchbot

Type Alias hub2Status

hub2Status: deviceStatus & {
    humidity: number;
    lightLevel: number;
    temperature: number;
}
2 | -------------------------------------------------------------------------------- /docs/types/humidifier.html: -------------------------------------------------------------------------------- 1 | humidifier | node-switchbot

Type Alias humidifier

humidifier: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/indoorCam.html: -------------------------------------------------------------------------------- 1 | indoorCam | node-switchbot

Type Alias indoorCam

indoorCam: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/indoorCameraWebhookContext.html: -------------------------------------------------------------------------------- 1 | indoorCameraWebhookContext | node-switchbot

Type Alias indoorCameraWebhookContext

indoorCameraWebhookContext: deviceWebhookContext & {
    detectionState: "DETECTED";
}
2 | -------------------------------------------------------------------------------- /docs/types/keypad.html: -------------------------------------------------------------------------------- 1 | keypad | node-switchbot

Type Alias keypad

keypad: device & { keyList: keyList; lockDeviceId: string; remoteType: string }
2 | -------------------------------------------------------------------------------- /docs/types/keypadTouch.html: -------------------------------------------------------------------------------- 1 | keypadTouch | node-switchbot

Type Alias keypadTouch

keypadTouch: device & {
    keyList: keyList;
    lockDeviceId: string;
    remoteType: string;
}
2 | -------------------------------------------------------------------------------- /docs/types/meter.html: -------------------------------------------------------------------------------- 1 | meter | node-switchbot

Type Alias meter

meter: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/meterPlus.html: -------------------------------------------------------------------------------- 1 | meterPlus | node-switchbot

Type Alias meterPlus

meterPlus: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/meterPlusStatus.html: -------------------------------------------------------------------------------- 1 | meterPlusStatus | node-switchbot

Type Alias meterPlusStatus

meterPlusStatus: deviceStatus & {
    battery: number;
    humidity: number;
    temperature: number;
}
2 | -------------------------------------------------------------------------------- /docs/types/meterPro.html: -------------------------------------------------------------------------------- 1 | meterPro | node-switchbot

Type Alias meterPro

meterPro: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/meterStatus.html: -------------------------------------------------------------------------------- 1 | meterStatus | node-switchbot

Type Alias meterStatus

meterStatus: deviceStatus & {
    battery: number;
    humidity: number;
    temperature: number;
}
2 | -------------------------------------------------------------------------------- /docs/types/motionSensor.html: -------------------------------------------------------------------------------- 1 | motionSensor | node-switchbot

Type Alias motionSensor

motionSensor: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/outdoorMeter.html: -------------------------------------------------------------------------------- 1 | outdoorMeter | node-switchbot

Type Alias outdoorMeter

outdoorMeter: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/outdoorMeterStatus.html: -------------------------------------------------------------------------------- 1 | outdoorMeterStatus | node-switchbot

Type Alias outdoorMeterStatus

outdoorMeterStatus: deviceStatus & {
    battery: number;
    humidity: number;
    temperature: number;
}
2 | -------------------------------------------------------------------------------- /docs/types/panTiltCamWebhookContext.html: -------------------------------------------------------------------------------- 1 | panTiltCamWebhookContext | node-switchbot

Type Alias panTiltCamWebhookContext

panTiltCamWebhookContext: deviceWebhookContext & { detectionState: "DETECTED" }
2 | -------------------------------------------------------------------------------- /docs/types/pantiltCam.html: -------------------------------------------------------------------------------- 1 | pantiltCam | node-switchbot

Type Alias pantiltCam

pantiltCam: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/pantiltCam2k.html: -------------------------------------------------------------------------------- 1 | pantiltCam2k | node-switchbot

Type Alias pantiltCam2k

pantiltCam2k: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/plug.html: -------------------------------------------------------------------------------- 1 | plug | node-switchbot

Type Alias plug

plug: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/plugMini.html: -------------------------------------------------------------------------------- 1 | plugMini | node-switchbot

Type Alias plugMini

plugMini: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/plugMiniJPWebhookContext.html: -------------------------------------------------------------------------------- 1 | plugMiniJPWebhookContext | node-switchbot

Type Alias plugMiniJPWebhookContext

plugMiniJPWebhookContext: deviceWebhookContext & { powerState: "ON" | "OFF" }
2 | -------------------------------------------------------------------------------- /docs/types/plugMiniUSWebhookContext.html: -------------------------------------------------------------------------------- 1 | plugMiniUSWebhookContext | node-switchbot

Type Alias plugMiniUSWebhookContext

plugMiniUSWebhookContext: deviceWebhookContext & { powerState: "ON" | "OFF" }
2 | -------------------------------------------------------------------------------- /docs/types/plugStatus.html: -------------------------------------------------------------------------------- 1 | plugStatus | node-switchbot

Type Alias plugStatus

plugStatus: deviceStatus & { power: string; version: string }
2 | -------------------------------------------------------------------------------- /docs/types/plugWebhookContext.html: -------------------------------------------------------------------------------- 1 | plugWebhookContext | node-switchbot

Type Alias plugWebhookContext

plugWebhookContext: deviceWebhookContext & { powerState: "ON" | "OFF" }
2 | -------------------------------------------------------------------------------- /docs/types/relaySwitch1Status.html: -------------------------------------------------------------------------------- 1 | relaySwitch1Status | node-switchbot

Type Alias relaySwitch1Status

relaySwitch1Status: deviceStatus & { switchStatus: 0 | 1; version: string }
2 | -------------------------------------------------------------------------------- /docs/types/remote.html: -------------------------------------------------------------------------------- 1 | remote | node-switchbot

Type Alias remote

remote: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/robotVacuumCleanerS1.html: -------------------------------------------------------------------------------- 1 | robotVacuumCleanerS1 | node-switchbot

Type Alias robotVacuumCleanerS1

robotVacuumCleanerS1: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/robotVacuumCleanerS1Plus.html: -------------------------------------------------------------------------------- 1 | robotVacuumCleanerS1Plus | node-switchbot

Type Alias robotVacuumCleanerS1Plus

robotVacuumCleanerS1Plus: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/stripLight.html: -------------------------------------------------------------------------------- 1 | stripLight | node-switchbot

Type Alias stripLight

stripLight: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/stripLightStatus.html: -------------------------------------------------------------------------------- 1 | stripLightStatus | node-switchbot

Type Alias stripLightStatus

stripLightStatus: deviceStatus & {
    brightness: number;
    color: string;
    power: string;
}
2 | -------------------------------------------------------------------------------- /docs/types/waterLeakDetector.html: -------------------------------------------------------------------------------- 1 | waterLeakDetector | node-switchbot

Type Alias waterLeakDetector

waterLeakDetector: device & {}
2 | -------------------------------------------------------------------------------- /docs/types/waterLeakDetectorStatus.html: -------------------------------------------------------------------------------- 1 | waterLeakDetectorStatus | node-switchbot

Type Alias waterLeakDetectorStatus

waterLeakDetectorStatus: deviceStatus & { battery: number; status: 0 | 1 }
2 | -------------------------------------------------------------------------------- /docs/types/waterLeakDetectorWebhookContext.html: -------------------------------------------------------------------------------- 1 | waterLeakDetectorWebhookContext | node-switchbot

Type Alias waterLeakDetectorWebhookContext

waterLeakDetectorWebhookContext: deviceWebhookContext & {
    battery: number;
    detectionState: 0 | 1;
}
2 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import antfu from '@antfu/eslint-config' 2 | 3 | export default antfu( 4 | { 5 | ignores: ['dist', 'docs'], 6 | jsx: false, 7 | typescript: true, 8 | formatters: { 9 | markdown: true, 10 | }, 11 | rules: { 12 | 'curly': ['error', 'multi-line'], 13 | 'import/extensions': ['error', 'ignorePackages'], 14 | 'import/order': 0, 15 | 'jsdoc/check-alignment': 'error', 16 | 'jsdoc/check-line-alignment': 'error', 17 | 'perfectionist/sort-exports': 'error', 18 | 'perfectionist/sort-imports': [ 19 | 'error', 20 | { 21 | groups: [ 22 | 'builtin-type', 23 | 'external-type', 24 | 'internal-type', 25 | ['parent-type', 'sibling-type', 'index-type'], 26 | 'builtin', 27 | 'external', 28 | 'internal', 29 | ['parent', 'sibling', 'index'], 30 | 'object', 31 | 'unknown', 32 | ], 33 | order: 'asc', 34 | type: 'natural', 35 | }, 36 | ], 37 | 'perfectionist/sort-named-exports': 'error', 38 | 'perfectionist/sort-named-imports': 'error', 39 | 'sort-imports': 0, 40 | 'style/brace-style': ['error', '1tbs', { allowSingleLine: true }], 41 | 'style/quote-props': ['error', 'consistent-as-needed'], 42 | 'test/no-only-tests': 'error', 43 | 'unicorn/no-useless-spread': 'error', 44 | 'unused-imports/no-unused-vars': ['error', { caughtErrors: 'none' }], 45 | 'no-new': 0, // Disable the no-new rule 46 | 'new-cap': 0, // Disable the new-cap rule 47 | 'no-undef': 0, // Disable the no-undef rule 48 | }, 49 | }, 50 | ) 51 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | export const preset = 'ts-jest'; 2 | export const testEnvironment = 'node'; 3 | export const testMatch = ['**/?(*.)+(spec|test).[jt]s?(x)']; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-switchbot", 3 | "type": "module", 4 | "version": "3.5.0", 5 | "description": "The node-switchbot is a Node.js module which allows you to control your Switchbot Devices through Bluetooth (BLE).", 6 | "author": "OpenWonderLabs (https://github.com/OpenWonderLabs)", 7 | "license": "MIT", 8 | "homepage": "https://github.com/OpenWonderLabs/node-switchbot", 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/OpenWonderLabs/node-switchbot.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/OpenWonderLabs/node-switchbot/issues" 15 | }, 16 | "keywords": [ 17 | "switchbot", 18 | "bot", 19 | "meter", 20 | "temperature", 21 | "humidity", 22 | "curtain", 23 | "blind", 24 | "BLE", 25 | "Bluetooth Low Energy", 26 | "Bluetooth smart", 27 | "Bluetooth", 28 | "OpenAPI", 29 | "OpenWonderLabs", 30 | "Switchbot API" 31 | ], 32 | "main": "dist/index.js", 33 | "types": "dist/index.d.ts", 34 | "engines": { 35 | "node": "^20 || ^22" 36 | }, 37 | "scripts": { 38 | "check": "npm install && npm outdated", 39 | "lint": "eslint src/**/*.ts", 40 | "lint:fix": "eslint src/**/*.ts --fix", 41 | "watch": "npm run build && npm link && nodemon", 42 | "build": "npm run clean && tsc", 43 | "prepublishOnly": "npm run lint && npm run build && npm run docs && npm run lint-docs", 44 | "postpublish": "npm run clean && npm ci", 45 | "clean": "shx rm -rf ./dist", 46 | "test": "vitest run", 47 | "test:watch": "vitest watch", 48 | "test-coverage": "npm run test -- --coverage", 49 | "docs": "typedoc", 50 | "lint-docs": "typedoc --emit none --treatWarningsAsErrors" 51 | }, 52 | "readmeFilename": "README.md", 53 | "dependencies": { 54 | "@stoprocent/noble": "^1.19.1", 55 | "async-mutex": "^0.5.0", 56 | "undici": "7.4.0" 57 | }, 58 | "optionalDependencies": { 59 | "@stoprocent/bluetooth-hci-socket": "^1.5.2" 60 | }, 61 | "devDependencies": { 62 | "@antfu/eslint-config": "^4.4.0", 63 | "@types/aes-js": "^3.1.4", 64 | "@types/debug": "^4.1.12", 65 | "@types/fs-extra": "^11.0.4", 66 | "@types/mdast": "^4.0.4", 67 | "@types/node": "^22.13.9", 68 | "@types/semver": "^7.5.8", 69 | "@types/source-map-support": "^0.5.10", 70 | "@vitest/coverage-v8": "^3.0.7", 71 | "eslint": "^9.21.0", 72 | "eslint-plugin-format": "^1.0.1", 73 | "nodemon": "^3.1.9", 74 | "shx": "^0.3.4", 75 | "ts-node": "^10.9.2", 76 | "typedoc": "^0.27.9", 77 | "typescript": "^5.8.2", 78 | "vitest": "^3.0.7" 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest' 2 | 3 | import * as index from './index.js' 4 | 5 | describe('index module exports', () => { 6 | it('should export switchbot-ble', () => { 7 | expect(index.SwitchBotBLE).toBeDefined() 8 | }) 9 | 10 | it('should export switchbot-openapi', () => { 11 | expect(index.SwitchBotOpenAPI).toBeDefined() 12 | }) 13 | 14 | it('should export SwitchbotDevice', () => { 15 | expect(index.SwitchbotDevice).toBeDefined() 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /* Copyright(C) 2024, donavanbecker (https://github.com/donavanbecker). All rights reserved. 2 | * 3 | * index.ts: Switchbot BLE API registration. 4 | */ 5 | export * from './device.js' 6 | export * from './switchbot-ble.js' 7 | export * from './switchbot-openapi.js' 8 | export * from './types/bledevicestatus.js' 9 | export * from './types/devicelist.js' 10 | export * from './types/devicepush.js' 11 | export * from './types/deviceresponse.js' 12 | export * from './types/devicestatus.js' 13 | export * from './types/devicewebhookstatus.js' 14 | export * from './types/irdevicelist.js' 15 | -------------------------------------------------------------------------------- /src/settings.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest' 2 | 3 | import { 4 | CHAR_UUID_DEVICE, 5 | CHAR_UUID_NOTIFY, 6 | CHAR_UUID_WRITE, 7 | COMMAND_TIMEOUT_MSEC, 8 | READ_TIMEOUT_MSEC, 9 | SERV_UUID_PRIMARY, 10 | urls, 11 | WoSmartLockCommands, 12 | WoSmartLockProCommands, 13 | WRITE_TIMEOUT_MSEC, 14 | } from './settings.js' 15 | 16 | describe('switchBot API Settings', () => { 17 | it('should have correct Devices URL', () => { 18 | expect(urls.devicesURL).toBe('https://api.switch-bot.com/v1.1/devices') 19 | }) 20 | 21 | it('should have correct setupWebhook URL', () => { 22 | expect(urls.setupWebhook).toBe('https://api.switch-bot.com/v1.1/webhook/setupWebhook') 23 | }) 24 | 25 | it('should have correct queryWebhook URL', () => { 26 | expect(urls.queryWebhook).toBe('https://api.switch-bot.com/v1.1/webhook/queryWebhook') 27 | }) 28 | 29 | it('should have correct updateWebhook URL', () => { 30 | expect(urls.updateWebhook).toBe('https://api.switch-bot.com/v1.1/webhook/updateWebhook') 31 | }) 32 | 33 | it('should have correct deleteWebhook URL', () => { 34 | expect(urls.deleteWebhook).toBe('https://api.switch-bot.com/v1.1/webhook/deleteWebhook') 35 | }) 36 | 37 | it('should have correct BLE API constants', () => { 38 | expect(SERV_UUID_PRIMARY).toBe('cba20d00224d11e69fb80002a5d5c51b') 39 | expect(CHAR_UUID_WRITE).toBe('cba20002224d11e69fb80002a5d5c51b') 40 | expect(CHAR_UUID_NOTIFY).toBe('cba20003224d11e69fb80002a5d5c51b') 41 | expect(CHAR_UUID_DEVICE).toBe('2a00') 42 | }) 43 | 44 | it('should have correct timeout constants', () => { 45 | expect(READ_TIMEOUT_MSEC).toBe(3000) 46 | expect(WRITE_TIMEOUT_MSEC).toBe(3000) 47 | expect(COMMAND_TIMEOUT_MSEC).toBe(3000) 48 | }) 49 | 50 | it('should have correct WoSmartLockProCommands', () => { 51 | expect(WoSmartLockProCommands.GET_CKIV).toBe('570f2103') 52 | expect(WoSmartLockProCommands.LOCK_INFO).toBe('570f4f8102') 53 | expect(WoSmartLockProCommands.UNLOCK).toBe('570f4e0101000080') 54 | expect(WoSmartLockProCommands.UNLOCK_NO_UNLATCH).toBe('570f4e01010000a0') 55 | expect(WoSmartLockProCommands.LOCK).toBe('570f4e0101000000') 56 | expect(WoSmartLockProCommands.ENABLE_NOTIFICATIONS).toBe('570e01001e00008101') 57 | expect(WoSmartLockProCommands.DISABLE_NOTIFICATIONS).toBe('570e00') 58 | }) 59 | 60 | it('should have correct WoSmartLockCommands', () => { 61 | expect(WoSmartLockCommands.GET_CKIV).toBe('570f2103') 62 | expect(WoSmartLockCommands.LOCK_INFO).toBe('570f4f8101') 63 | expect(WoSmartLockCommands.UNLOCK).toBe('570f4e01011080') 64 | expect(WoSmartLockCommands.UNLOCK_NO_UNLATCH).toBe('570f4e010110a0') 65 | expect(WoSmartLockCommands.LOCK).toBe('570f4e01011000') 66 | expect(WoSmartLockCommands.ENABLE_NOTIFICATIONS).toBe('570e01001e00008101') 67 | expect(WoSmartLockCommands.DISABLE_NOTIFICATIONS).toBe('570e00') 68 | }) 69 | }) 70 | -------------------------------------------------------------------------------- /src/settings.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Switchbot BLE API registration settings. 3 | * 4 | * © 2024, donavanbecker (https://github.com/donavanbecker). All rights reserved. 5 | */ 6 | let baseURL = 'https://api.switch-bot.com' 7 | 8 | let devicesURL = `${baseURL}/v1.1/devices` 9 | let setupWebhook = `${baseURL}/v1.1/webhook/setupWebhook` 10 | let queryWebhook = `${baseURL}/v1.1/webhook/queryWebhook` 11 | let updateWebhook = `${baseURL}/v1.1/webhook/updateWebhook` 12 | let deleteWebhook = `${baseURL}/v1.1/webhook/deleteWebhook` 13 | 14 | /** 15 | * Updates the base URL for the SwitchBot API endpoints. 16 | * @param {string} newBaseURL - The new base URL to use. 17 | */ 18 | export function updateBaseURL(newBaseURL: string): void { 19 | baseURL = newBaseURL 20 | devicesURL = `${baseURL}/v1.1/devices` 21 | setupWebhook = `${baseURL}/v1.1/webhook/setupWebhook` 22 | queryWebhook = `${baseURL}/v1.1/webhook/queryWebhook` 23 | updateWebhook = `${baseURL}/v1.1/webhook/updateWebhook` 24 | deleteWebhook = `${baseURL}/v1.1/webhook/deleteWebhook` 25 | } 26 | 27 | export const urls = { 28 | get baseURL() { return baseURL }, 29 | get devicesURL() { return devicesURL }, 30 | get setupWebhook() { return setupWebhook }, 31 | get queryWebhook() { return queryWebhook }, 32 | get updateWebhook() { return updateWebhook }, 33 | get deleteWebhook() { return deleteWebhook }, 34 | } 35 | 36 | /** 37 | * constants used to access SwitchBot BLE API 38 | */ 39 | export const SERV_UUID_PRIMARY = 'cba20d00224d11e69fb80002a5d5c51b' 40 | export const CHAR_UUID_WRITE = 'cba20002224d11e69fb80002a5d5c51b' 41 | export const CHAR_UUID_NOTIFY = 'cba20003224d11e69fb80002a5d5c51b' 42 | export const CHAR_UUID_DEVICE = '2a00' 43 | 44 | export const READ_TIMEOUT_MSEC = 3000 45 | export const WRITE_TIMEOUT_MSEC = 3000 46 | export const COMMAND_TIMEOUT_MSEC = 3000 47 | 48 | export const DEFAULT_DISCOVERY_DURATION = 5000 49 | export const PRIMARY_SERVICE_UUID_LIST = [] 50 | 51 | export enum WoSmartLockProCommands { 52 | GET_CKIV = '570f2103', 53 | LOCK_INFO = '570f4f8102', 54 | UNLOCK = '570f4e0101000080', 55 | UNLOCK_NO_UNLATCH = '570f4e01010000a0', 56 | LOCK = '570f4e0101000000', 57 | ENABLE_NOTIFICATIONS = '570e01001e00008101', 58 | DISABLE_NOTIFICATIONS = '570e00', 59 | } 60 | 61 | export enum WoSmartLockCommands { 62 | GET_CKIV = '570f2103', 63 | LOCK_INFO = '570f4f8101', 64 | UNLOCK = '570f4e01011080', 65 | UNLOCK_NO_UNLATCH = '570f4e010110a0', 66 | LOCK = '570f4e01011000', 67 | ENABLE_NOTIFICATIONS = '570e01001e00008101', 68 | DISABLE_NOTIFICATIONS = '570e00', 69 | } 70 | -------------------------------------------------------------------------------- /src/types/devicelist.ts: -------------------------------------------------------------------------------- 1 | /* Copyright(C) 2017-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved. 2 | * 3 | * devicelist.ts: @switchbot/homebridge-switchbot platform class. 4 | */ 5 | export interface deviceList { 6 | device: device[] 7 | } 8 | 9 | export interface device { 10 | deviceId: string 11 | deviceName: string 12 | deviceType: string 13 | enableCloudService: boolean 14 | hubDeviceId: string 15 | version?: number 16 | } 17 | 18 | export type bot = device & {} 19 | 20 | export type curtain = device & { 21 | curtainDevicesIds: string[] 22 | calibrate: boolean 23 | group: boolean 24 | master: boolean 25 | openDirection: string 26 | } 27 | 28 | export type curtain3 = device & { 29 | curtainDevicesIds: string[] 30 | calibrate: boolean 31 | group: boolean 32 | master: boolean 33 | openDirection?: string 34 | } 35 | 36 | export type hub2 = device & {} 37 | 38 | export type meter = device & {} 39 | 40 | export type meterPlus = device & {} 41 | 42 | export type meterPro = device & {} 43 | 44 | export type outdoorMeter = device & {} 45 | 46 | export type lock = device & { 47 | group: boolean 48 | master: boolean 49 | groupName: string 50 | lockDevicesIds: string[] 51 | } 52 | 53 | export type lockPro = device & { 54 | group: boolean 55 | master: boolean 56 | groupName: string 57 | lockDevicesIds: string[] 58 | } 59 | 60 | export type keypad = device & { 61 | remoteType: string 62 | lockDeviceId: string 63 | keyList: keyList 64 | } 65 | 66 | export type keypadTouch = device & { 67 | remoteType: string 68 | lockDeviceId: string 69 | keyList: keyList 70 | } 71 | 72 | interface keyList { 73 | id: number 74 | name: string 75 | type: string 76 | password: string 77 | iv: string 78 | status: string 79 | createTime: number 80 | } 81 | 82 | export type remote = device & {} 83 | 84 | export type motionSensor = device & {} 85 | 86 | export type contactSensor = device & {} 87 | 88 | export type waterLeakDetector = device & {} 89 | 90 | export type ceilingLight = device & {} 91 | 92 | export type ceilingLightPro = device & {} 93 | 94 | export type plug = device & {} 95 | 96 | export type plugMini = device & {} 97 | 98 | export type stripLight = device & {} 99 | 100 | export type colorBulb = device & {} 101 | 102 | export type robotVacuumCleanerS1 = device & {} 103 | 104 | export type robotVacuumCleanerS1Plus = device & {} 105 | 106 | export type floorCleaningRobotS10 = device & {} 107 | 108 | export type humidifier = device & {} 109 | 110 | export type indoorCam = device & {} 111 | 112 | export type pantiltCam = device & {} 113 | 114 | export type pantiltCam2k = device & {} 115 | 116 | export type blindTilt = device & { 117 | blindTiltDevicesIds: string[] 118 | calibrate: boolean 119 | group: boolean 120 | master: boolean 121 | direction: string 122 | slidePosition: number 123 | } 124 | 125 | export type batteryCirculatorFan = device & {} 126 | -------------------------------------------------------------------------------- /src/types/devicepush.ts: -------------------------------------------------------------------------------- 1 | /* Copyright(C) 2017-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved. 2 | * 3 | * pushbody.ts: @switchbot/homebridge-switchbot platform class. 4 | */ 5 | export interface bodyChange { 6 | command: string 7 | parameter: string 8 | commandType: string 9 | } 10 | 11 | export interface pushResponse { 12 | statusCode: number 13 | body: { 14 | commandId: string 15 | } 16 | message: string 17 | } 18 | -------------------------------------------------------------------------------- /src/types/deviceresponse.ts: -------------------------------------------------------------------------------- 1 | /* Copyright(C) 2017-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved. 2 | * 3 | * deviceresponse.ts: @switchbot/homebridge-switchbot platform class. 4 | */ 5 | import type { deviceList } from './devicelist.js' 6 | import type { infraredRemoteList } from './irdevicelist.js' 7 | 8 | // json response from SwitchBot API 9 | export interface devices { 10 | statusCode: number 11 | message: string 12 | body: body 13 | } 14 | 15 | export interface body { 16 | deviceList: deviceList 17 | infraredRemoteList: infraredRemoteList 18 | } 19 | -------------------------------------------------------------------------------- /src/types/irdevicelist.ts: -------------------------------------------------------------------------------- 1 | /* Copyright(C) 2017-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved. 2 | * 3 | * irdevicelist.ts: ds7@switchbot/homebridge-switchbot platform class. 4 | */ 5 | export interface infraredRemoteList { 6 | device: irdevice[] 7 | } 8 | 9 | export interface irdevice { 10 | deviceId?: string 11 | deviceName: string 12 | remoteType: string 13 | hubDeviceId: string 14 | } 15 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "lib": [ 5 | "DOM", 6 | "ES2022" 7 | ], 8 | "rootDir": "src", 9 | "module": "ES2022", 10 | "moduleResolution": "bundler", 11 | "strict": true, 12 | "noImplicitAny": false, 13 | "declaration": true, 14 | "declarationMap": true, 15 | "outDir": "dist", 16 | "sourceMap": true, 17 | "allowSyntheticDefaultImports": true, 18 | "esModuleInterop": true, 19 | "forceConsistentCasingInFileNames": true 20 | }, 21 | "include": [ 22 | "src" 23 | ], 24 | "exclude": [ 25 | "**/*.spec.ts" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "out": "docs", 3 | "exclude": ["src/**/*.spec.ts"], 4 | "entryPoints": [ 5 | "src/index.ts" 6 | ], 7 | "excludePrivate": true, 8 | "excludeProtected": true, 9 | "excludeExternals": true, 10 | "hideGenerator": true, 11 | "includeVersion": false, 12 | "validation": { 13 | "invalidLink": true, 14 | "notExported": false 15 | }, 16 | "inlineTags": ["@link", "@see"] 17 | } 18 | --------------------------------------------------------------------------------