scrypted-kasa 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/dependabot.yml +14 -0
- package/.github/workflows/ci.yml +35 -0
- package/.github/workflows/publish.yml +52 -0
- package/.nvmrc +1 -0
- package/.prettierignore +6 -0
- package/.prettierrc.json +11 -0
- package/LICENSE +21 -0
- package/README.md +184 -0
- package/eslint.config.mjs +33 -0
- package/package.json +75 -0
- package/src/camera/api.ts +329 -0
- package/src/camera/intercom.ts +163 -0
- package/src/camera/linkie.ts +185 -0
- package/src/camera/rtsp.ts +204 -0
- package/src/camera/stream.ts +428 -0
- package/src/iot/bulb.ts +178 -0
- package/src/iot/device.ts +103 -0
- package/src/iot/dimmer.ts +19 -0
- package/src/iot/plug.ts +5 -0
- package/src/iot/protocol.ts +143 -0
- package/src/iot/switch.ts +5 -0
- package/src/main.ts +1055 -0
- package/src/shared/cipher.ts +49 -0
- package/src/shared/discovery.ts +232 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [main]
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
# Cancel in-progress runs for the same PR/branch when a new commit is pushed.
|
|
10
|
+
concurrency:
|
|
11
|
+
group: ci-${{ github.workflow }}-${{ github.ref }}
|
|
12
|
+
cancel-in-progress: true
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
check:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
19
|
+
|
|
20
|
+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
|
21
|
+
with:
|
|
22
|
+
node-version-file: '.nvmrc'
|
|
23
|
+
cache: 'npm'
|
|
24
|
+
|
|
25
|
+
- name: Install dependencies
|
|
26
|
+
run: npm ci
|
|
27
|
+
|
|
28
|
+
- name: Prettier check
|
|
29
|
+
run: npm run fmt:check
|
|
30
|
+
|
|
31
|
+
- name: ESLint
|
|
32
|
+
run: npm run lint
|
|
33
|
+
|
|
34
|
+
- name: Build (scrypted-webpack)
|
|
35
|
+
run: npm run build
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
# Trigger on semver tags like v1.0.7. Push the tag with `git tag v1.0.7 && git push --tags`
|
|
6
|
+
# after bumping the version in package.json.
|
|
7
|
+
tags: ['v*']
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
publish:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
# id-token is required for npm publish provenance — provenance signs the package
|
|
15
|
+
# via the GitHub OIDC token so consumers can verify it was built by this workflow.
|
|
16
|
+
id-token: write
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
19
|
+
|
|
20
|
+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
|
21
|
+
with:
|
|
22
|
+
node-version-file: '.nvmrc'
|
|
23
|
+
cache: 'npm'
|
|
24
|
+
# Configures npm with the registry URL so NODE_AUTH_TOKEN is honored at publish.
|
|
25
|
+
registry-url: 'https://registry.npmjs.org'
|
|
26
|
+
|
|
27
|
+
- name: Verify package.json version matches git tag
|
|
28
|
+
run: |
|
|
29
|
+
PKG_VERSION=$(node -p "require('./package.json').version")
|
|
30
|
+
TAG_VERSION="${GITHUB_REF#refs/tags/v}"
|
|
31
|
+
if [ "$PKG_VERSION" != "$TAG_VERSION" ]; then
|
|
32
|
+
echo "::error::package.json version ($PKG_VERSION) does not match git tag ($TAG_VERSION)"
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
echo "Publishing scrypted-kasa@$PKG_VERSION"
|
|
36
|
+
|
|
37
|
+
- name: Install dependencies
|
|
38
|
+
run: npm ci
|
|
39
|
+
|
|
40
|
+
- name: Prettier check
|
|
41
|
+
run: npm run fmt:check
|
|
42
|
+
|
|
43
|
+
- name: ESLint
|
|
44
|
+
run: npm run lint
|
|
45
|
+
|
|
46
|
+
- name: Build (scrypted-webpack)
|
|
47
|
+
run: npm run build
|
|
48
|
+
|
|
49
|
+
- name: Publish to npm
|
|
50
|
+
run: npm publish --access public --provenance
|
|
51
|
+
env:
|
|
52
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/.nvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
v24
|
package/.prettierignore
ADDED
package/.prettierrc.json
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sergey Vilgelm
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# scrypted-kasa
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/scrypted-kasa)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
|
|
6
|
+
Adds support for the TP-Link Kasa device family to Scrypted: cameras, plugs/outlets,
|
|
7
|
+
switches/dimmers, and bulbs. Discovery is unified — one UDP/9999 sweep finds everything
|
|
8
|
+
and the plugin routes each device to the right Scrypted interfaces.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
In Scrypted:
|
|
13
|
+
|
|
14
|
+
1. Open the **Plugins** page.
|
|
15
|
+
2. Choose **Install** and enter `scrypted-kasa`.
|
|
16
|
+
3. The plugin appears as **Kasa Plugin** in the device list — see [Setup](#setup) below.
|
|
17
|
+
|
|
18
|
+
## Cameras
|
|
19
|
+
|
|
20
|
+
- Reads the camera's proprietary multipart stream (HTTPS port 19443, `/https/stream/mixed`)
|
|
21
|
+
and re-streams H.264 video + G.711 µ-law audio over local RTSP for Scrypted, HomeKit, the
|
|
22
|
+
NVR, etc.
|
|
23
|
+
- Streams talk audio back to the camera's speaker via the camera's separate uplink endpoint
|
|
24
|
+
(HTTPS port 18443, `/https/speaker/audio/g711block`) — usable from HomeKit and any other
|
|
25
|
+
Scrypted client that supports two-way audio.
|
|
26
|
+
- Exposes the camera's spotlight (when present, e.g. KC420WS) as an `OnOff` child light
|
|
27
|
+
device in the same room as the camera. Driven by the LINKIE2 control protocol on port
|
|
28
|
+
10443.
|
|
29
|
+
- Exposes the camera's siren (when present) as an `OnOff` child switch device, also in
|
|
30
|
+
the camera's room. Triggering it turns the siren on; the camera auto-stops after the
|
|
31
|
+
duration configured in the Kasa app (default 30 s).
|
|
32
|
+
- Exposes the camera's **status LED** as the camera's own `OnOff` interface, so HomeKit's
|
|
33
|
+
per-camera "Link Status Indicator" toggle drives the LED.
|
|
34
|
+
|
|
35
|
+
## Plugs / Switches / Dimmers / Bulbs (legacy IOT protocol)
|
|
36
|
+
|
|
37
|
+
Each device class is its own implementation, descended from a shared `KasaIotDevice`
|
|
38
|
+
base that holds the relay protocol:
|
|
39
|
+
|
|
40
|
+
- **`KasaPlug`** — plain plugs/outlets (HS100/HS103/HS105/HS107/HS110/KP100/...). `OnOff`,
|
|
41
|
+
`ScryptedDeviceType.Outlet`.
|
|
42
|
+
- **`KasaSwitch`** — plain wall switches (HS200/HS210/KS200/...). `OnOff`,
|
|
43
|
+
`ScryptedDeviceType.Switch`.
|
|
44
|
+
- **`KasaDimmer`** — dimmer plugs and switches (HS220 plug, KS230 3-way switch). `OnOff` +
|
|
45
|
+
`Brightness`, `ScryptedDeviceType.Light` (dimmable devices are exposed as lights since
|
|
46
|
+
they're almost always wired to a light fixture, matching the Kasa app's UX).
|
|
47
|
+
- **`KasaBulb`** — smart bulbs (LB1xx, KL1xx). `OnOff` + `Brightness`, plus
|
|
48
|
+
`ColorSettingHsv` for color bulbs and `ColorSettingTemperature` for variable-temperature
|
|
49
|
+
bulbs.
|
|
50
|
+
|
|
51
|
+
Multi-outlet plug strips (HS300, KP303) aren't modeled yet — discovery skips them.
|
|
52
|
+
|
|
53
|
+
Stream protocol described in [go2rtc's `pkg/kasa`](https://github.com/AlexxIT/go2rtc/tree/master/pkg/kasa);
|
|
54
|
+
camera control protocols (LINKIE2, talk endpoint, status LED) modeled after the official
|
|
55
|
+
Kasa iOS app's network traffic. The plug/bulb/switch protocol is the well-documented
|
|
56
|
+
legacy "smarthome" TCP/9999 wire format.
|
|
57
|
+
|
|
58
|
+
Tested camera models: KD110, KC200, KC401, KC420WS, EC71.
|
|
59
|
+
|
|
60
|
+
## Setup
|
|
61
|
+
|
|
62
|
+
### Auto-discovery (recommended)
|
|
63
|
+
|
|
64
|
+
1. Install the plugin.
|
|
65
|
+
2. Open the plugin's page and click **Discover Devices**. Discovery runs only when you
|
|
66
|
+
click the button — there are no background scans.
|
|
67
|
+
3. Every LAN-visible Kasa device appears in the list — cameras, plugs, switches, dimmers,
|
|
68
|
+
and bulbs are all discovered together.
|
|
69
|
+
4. For each device you want to adopt, fill in the adoption form and click adopt:
|
|
70
|
+
- **Name** — pre-filled with the device's alias or model; edit to taste.
|
|
71
|
+
- **Room** — optional, picked from a dropdown of rooms already in use by other
|
|
72
|
+
Scrypted devices, or type a new one.
|
|
73
|
+
- **Username** / **Password** *(cameras only)* — your Kasa account email and password.
|
|
74
|
+
After the first camera is configured these are pre-populated from any other Kasa
|
|
75
|
+
camera in Scrypted.
|
|
76
|
+
|
|
77
|
+
Adopted devices get their IP, port, name, model, MAC, serial number, and firmware version
|
|
78
|
+
populated automatically. The manufacturer is reported as `TP-Link Kasa`.
|
|
79
|
+
|
|
80
|
+
Discovery sends a single UDP/9999 burst on each connected /24:
|
|
81
|
+
|
|
82
|
+
- A **broadcast** of the IOT.SMARTHOME `get_sysinfo` query.
|
|
83
|
+
- A **paced unicast** of the same query at every IP on the subnet (~3 ms between sends).
|
|
84
|
+
Newer firmwares (e.g. KC420WS cameras) drop broadcast probes but still answer when the
|
|
85
|
+
packet is addressed directly. Pacing keeps the kernel/network from coalescing or
|
|
86
|
+
dropping the burst.
|
|
87
|
+
|
|
88
|
+
If a device is on a different VLAN/broadcast domain or a non-/24 subnet, use the manual
|
|
89
|
+
setup below.
|
|
90
|
+
|
|
91
|
+
### Manual setup
|
|
92
|
+
|
|
93
|
+
1. Install the plugin.
|
|
94
|
+
2. Use **Add Device** to create a new device. The Add form takes:
|
|
95
|
+
- **Type** — Camera, Plug, Switch, Dimmer, or Bulb.
|
|
96
|
+
- **Name** — required.
|
|
97
|
+
- **Room** — optional, with the same dropdown of existing rooms as the discovery flow.
|
|
98
|
+
3. After creation, open the device's settings and fill in:
|
|
99
|
+
- **IP Address** of the device on your LAN
|
|
100
|
+
- **Port** (default 19443 for cameras, 9999 for everything else)
|
|
101
|
+
- For cameras: **Username** + **Password** (your Kasa account email + password)
|
|
102
|
+
|
|
103
|
+
## How it works
|
|
104
|
+
|
|
105
|
+
### Receive (camera → Scrypted)
|
|
106
|
+
|
|
107
|
+
- The plugin opens a single HTTPS connection to the camera on port 19443 and parses the
|
|
108
|
+
`multipart/x-mixed-replace` body, splitting it into video parts (`video/x-h264`,
|
|
109
|
+
annex-b) and audio parts (`audio/g711u`).
|
|
110
|
+
- It scans the first H.264 frames for SPS (NAL 7) and PPS (NAL 8) and inlines them into
|
|
111
|
+
the locally served SDP as `sprop-parameter-sets` + `profile-level-id`. This lets short
|
|
112
|
+
-timeout consumers (HomeKit, browser players) pick up the codec immediately.
|
|
113
|
+
- It then runs ffmpeg in codec-copy mode, re-packetizing the raw H.264 and G.711 µ-law
|
|
114
|
+
streams as RTP into a local RTSP server that Scrypted reads from.
|
|
115
|
+
|
|
116
|
+
### Talk (Scrypted → camera speaker)
|
|
117
|
+
|
|
118
|
+
- When a client engages two-way audio, the plugin opens a long-lived chunked POST to
|
|
119
|
+
`https://<ip>:18443/https/speaker/audio/g711block` and ffmpeg-transcodes the client's
|
|
120
|
+
audio to 8 kHz mono G.711 µ-law.
|
|
121
|
+
- Each 20 ms (160 byte) audio block is wrapped in a `multipart/x-mixed-replace` part with
|
|
122
|
+
`Content-Type: audio/g711u` and streamed to the camera. Empty `audio/heartbeat` parts
|
|
123
|
+
are sent every 3 s during silence to keep the connection alive — same pattern the Kasa
|
|
124
|
+
app uses.
|
|
125
|
+
|
|
126
|
+
### Spotlight / control plane
|
|
127
|
+
|
|
128
|
+
- The Kasa app talks to the camera's "LINKIE2" RPC on port 10443 for non-streaming
|
|
129
|
+
features. Wire format: HTTPS POST `/data/LINKIE2.json`, body `application/x-www-form-
|
|
130
|
+
urlencoded` with a single `content=<base64(xor_ab(json))>` field. The XOR-AB autokey
|
|
131
|
+
cipher is the same one used by Kasa's UDP/9999 discovery protocol.
|
|
132
|
+
- On adoption (and whenever credentials change) the plugin probes three LINKIE2 endpoints
|
|
133
|
+
serially:
|
|
134
|
+
- `smartlife.cam.ipcamera.dayNight.get_force_lamp_state` — if it returns `on`/`off`, a
|
|
135
|
+
child `OnOff` light device named "<camera> Spotlight" is registered in the camera's
|
|
136
|
+
room.
|
|
137
|
+
- `smartlife.cam.ipcamera.siren.get_state` — same pattern; produces a "<camera> Siren"
|
|
138
|
+
switch child device.
|
|
139
|
+
- `smartlife.cam.ipcamera.led.get_status` — drives the camera's own `OnOff` so HomeKit
|
|
140
|
+
can bind its `CameraOperatingModeIndicator` (a.k.a. "Status Light") characteristic to
|
|
141
|
+
it. Enable **Link Status Indicator** in the HomeKit plugin's per-camera settings to
|
|
142
|
+
activate the binding.
|
|
143
|
+
- Toggling any of the three calls the matching `set_*` method with `{"value": "on"|"off"}`.
|
|
144
|
+
|
|
145
|
+
## Notes / limitations
|
|
146
|
+
|
|
147
|
+
- **Authentication** uses the cloud account password. All three endpoints take Basic auth
|
|
148
|
+
with the plain Kasa email as the username; the password format differs by endpoint —
|
|
149
|
+
receive uses base64(plaintext), talk and LINKIE2 use md5_hex(plaintext). The plugin
|
|
150
|
+
uses each in the right place.
|
|
151
|
+
- LINKIE2 requests must include a `User-Agent: Kasa/...` header and the `Authorization`
|
|
152
|
+
header on the very first request — the camera silently drops requests that don't look
|
|
153
|
+
enough like the official app.
|
|
154
|
+
- The camera presents a self-signed TLS certificate; certificate verification is disabled.
|
|
155
|
+
- Auto-discovery sweeps the local /24 only. Larger subnets (e.g. /23) are skipped to
|
|
156
|
+
avoid flooding.
|
|
157
|
+
|
|
158
|
+
## Development
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
git clone https://github.com/sv-tools/scrypted-kasa-plugin.git
|
|
162
|
+
cd scrypted-kasa-plugin
|
|
163
|
+
npm install
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Common scripts:
|
|
167
|
+
|
|
168
|
+
| Command | Purpose |
|
|
169
|
+
|---|---|
|
|
170
|
+
| `npm run build` | Webpack bundle into `out/main.nodejs.js` (+ `plugin.zip`) |
|
|
171
|
+
| `npm run fmt` | Format `src/**/*.ts` with prettier |
|
|
172
|
+
| `npm run fmt:check` | Verify formatting — what CI runs |
|
|
173
|
+
| `npm run lint` | ESLint |
|
|
174
|
+
| `npm run lint:fix` | ESLint with auto-fix |
|
|
175
|
+
| `npm run scrypted-deploy <host>` | Build and deploy to a Scrypted server |
|
|
176
|
+
|
|
177
|
+
CI on every PR runs `fmt:check`, `lint`, and `build`. Releases publish to npm
|
|
178
|
+
automatically when a `v*` tag is pushed (e.g. `git tag v1.2.3 && git push --tags`).
|
|
179
|
+
The publish workflow signs the package with [npm provenance](https://docs.npmjs.com/generating-provenance-statements)
|
|
180
|
+
via GitHub OIDC.
|
|
181
|
+
|
|
182
|
+
## License
|
|
183
|
+
|
|
184
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import js from '@eslint/js';
|
|
2
|
+
import tseslint from 'typescript-eslint';
|
|
3
|
+
|
|
4
|
+
// We deliberately don't use `eslint-config-prettier`: typescript-eslint's `recommended`
|
|
5
|
+
// preset focuses on code-quality rules, not style. Prettier already owns formatting via
|
|
6
|
+
// `npm run fmt` / `fmt:check`, and there's nothing in the rule set below that fights it.
|
|
7
|
+
// Skipping the dep also sidesteps the known eslint-config-prettier supply-chain compromise.
|
|
8
|
+
export default tseslint.config(
|
|
9
|
+
{
|
|
10
|
+
ignores: ['node_modules/', 'out/', 'build/', 'dist/'],
|
|
11
|
+
},
|
|
12
|
+
js.configs.recommended,
|
|
13
|
+
...tseslint.configs.recommended,
|
|
14
|
+
{
|
|
15
|
+
rules: {
|
|
16
|
+
// Allow `any` — used intentionally for kasa sysinfo (untyped JSON shape varies
|
|
17
|
+
// per device family) and for narrow casts where TypeScript can't see through
|
|
18
|
+
// the runtime tag (e.g. `kasaClass`).
|
|
19
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
20
|
+
|
|
21
|
+
// Treat `_`-prefixed args/vars as intentionally unused (matches the convention
|
|
22
|
+
// we already use for ignored handler params like `_options`, `_id`, `_nativeId`).
|
|
23
|
+
'@typescript-eslint/no-unused-vars': [
|
|
24
|
+
'warn',
|
|
25
|
+
{ argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrorsIgnorePattern: '^_' },
|
|
26
|
+
],
|
|
27
|
+
|
|
28
|
+
// Empty catch blocks are a deliberate teardown idiom in this codebase: e.g.
|
|
29
|
+
// `try { socket.close(); } catch {}` — best-effort, ignore failure. Don't nag.
|
|
30
|
+
'no-empty': ['warn', { allowEmptyCatch: true }],
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
);
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "scrypted-kasa",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "TP-Link Kasa plugin for Scrypted — cameras (video, two-way audio, spotlight, siren, status LED), plugs/outlets, wall switches, dimmers, and smart bulbs (on/off, brightness, color, color temperature).",
|
|
5
|
+
"author": "Sergey Vilgelm <sergey@vilgelm.com>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/sv-tools/scrypted-kasa-plugin.git"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/sv-tools/scrypted-kasa-plugin/issues"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/sv-tools/scrypted-kasa-plugin#readme",
|
|
15
|
+
"scripts": {
|
|
16
|
+
"scrypted-setup-project": "scrypted-setup-project",
|
|
17
|
+
"prescrypted-setup-project": "scrypted-package-json",
|
|
18
|
+
"build": "scrypted-webpack",
|
|
19
|
+
"prepublishOnly": "NODE_ENV=production scrypted-webpack",
|
|
20
|
+
"prescrypted-vscode-launch": "scrypted-webpack",
|
|
21
|
+
"scrypted-vscode-launch": "scrypted-deploy-debug",
|
|
22
|
+
"scrypted-deploy-debug": "scrypted-deploy-debug",
|
|
23
|
+
"scrypted-debug": "scrypted-debug",
|
|
24
|
+
"scrypted-deploy": "scrypted-deploy",
|
|
25
|
+
"scrypted-readme": "scrypted-readme",
|
|
26
|
+
"scrypted-package-json": "scrypted-package-json",
|
|
27
|
+
"fmt": "prettier --write \"src/**/*.ts\"",
|
|
28
|
+
"fmt:check": "prettier --check \"src/**/*.ts\"",
|
|
29
|
+
"lint": "eslint src",
|
|
30
|
+
"lint:fix": "eslint src --fix"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"scrypted",
|
|
34
|
+
"scrypted-plugin",
|
|
35
|
+
"plugin",
|
|
36
|
+
"kasa",
|
|
37
|
+
"tp-link",
|
|
38
|
+
"tplink",
|
|
39
|
+
"smarthome",
|
|
40
|
+
"smart-home",
|
|
41
|
+
"homekit",
|
|
42
|
+
"camera",
|
|
43
|
+
"intercom",
|
|
44
|
+
"two-way-audio",
|
|
45
|
+
"switch",
|
|
46
|
+
"outlet",
|
|
47
|
+
"plug",
|
|
48
|
+
"dimmer",
|
|
49
|
+
"bulb",
|
|
50
|
+
"light",
|
|
51
|
+
"lightbulb"
|
|
52
|
+
],
|
|
53
|
+
"scrypted": {
|
|
54
|
+
"name": "Kasa Plugin",
|
|
55
|
+
"type": "DeviceProvider",
|
|
56
|
+
"interfaces": [
|
|
57
|
+
"ScryptedSystemDevice",
|
|
58
|
+
"ScryptedDeviceCreator",
|
|
59
|
+
"DeviceProvider",
|
|
60
|
+
"DeviceCreator",
|
|
61
|
+
"DeviceDiscovery"
|
|
62
|
+
],
|
|
63
|
+
"pluginDependencies": [
|
|
64
|
+
"@scrypted/prebuffer-mixin"
|
|
65
|
+
]
|
|
66
|
+
},
|
|
67
|
+
"devDependencies": {
|
|
68
|
+
"@eslint/js": "^10.0.1",
|
|
69
|
+
"@scrypted/sdk": "^0.5.59",
|
|
70
|
+
"@types/node": "^24.12.2",
|
|
71
|
+
"eslint": "^10.2.1",
|
|
72
|
+
"prettier": "^3.8.3",
|
|
73
|
+
"typescript-eslint": "^8.59.1"
|
|
74
|
+
}
|
|
75
|
+
}
|