Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/feat/2.0.0' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
Koenkk committed Dec 1, 2024
2 parents 2c6e437 + cd9135e commit 12a29c3
Show file tree
Hide file tree
Showing 34 changed files with 611 additions and 525 deletions.
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"image": "mcr.microsoft.com/devcontainers/javascript-node:18",

"postCreateCommand": "npm install",
"postCreateCommand": "pnpm i --frozen-lockfile",

"portsAttributes": {
"8080": {
Expand Down
4 changes: 3 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
docs/devices/*.md
pnpm-lock.yaml
pnpm-lock.yaml
public/images/**/*
docs/images/**/*
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ Docgen is written in Typescript, so you need a recent version of Node.js and NPM

```bash
# Install dependencies
npm ci
pnpm i --frozen-lockfile

# Run docgen
npm run docgen
pnpm run docgen
```

### Docgen Tests
Expand All @@ -47,21 +47,21 @@ Docgen includes some scripts to help testing the page.

## VuePress

Use Node.js 18 for building VuePress (other versions are not officially supported).
Use Node.js 20 for building VuePress (other versions are not officially supported).

```bash
# Switch to node 18 (for nvm or nvm-compatible tool users)
# Switch to node 20 (for nvm or nvm-compatible tool users)
nvm use

# Install dependencies
npm ci
pnpm i --frozen-lockfile
```

### Building

```bash
# Run vuepress build
npm run build
pnpm run build
```

The build-artifact gets written to `dist` directory.
Expand All @@ -70,11 +70,11 @@ The build-artifact gets written to `dist` directory.

```bash
# Run vuepress in dev mode with hot-reloading
npm run dev
pnpm run dev
```

The `dev`-Mode **excludes** the huge amount device-pages which slows down the build process drastically.
If you are interested in the device-pages you could include them by using the `npm run dev:devices` npm-run script.
If you are interested in the device-pages you could include them by using the `pnpm run dev:devices` npm-run script.

#### Include specific device

Expand All @@ -84,10 +84,10 @@ Useful when working on improving notes of just one device.

```bash
# Run vuepress in dev mode with specific device included
npx cross-env INCLUDE_DEVICE=<DEVICE_FILE_NAME> npm run dev
npx cross-env INCLUDE_DEVICE=<DEVICE_FILE_NAME> pnpm run dev

# Example for TS011F_plug_1
npx cross-env INCLUDE_DEVICE=TS011F_plug_1 npm run dev
npx cross-env INCLUDE_DEVICE=TS011F_plug_1 pnpm run dev
```

#### Change development port
Expand All @@ -96,10 +96,10 @@ You can change development server port when the default one (8080) is taken on y

```bash
# Run vuepress in dev mode on specified port
npx cross-env DEV_PORT=<PORT_NUMBER> npm run dev
npx cross-env DEV_PORT=<PORT_NUMBER> pnpm run dev

# Example for port no 15080
npx cross-env DEV_PORT=15080 npm run dev
npx cross-env DEV_PORT=15080 pnpm run dev
```

## Docker
Expand All @@ -109,6 +109,6 @@ You can also just use a docker-image include Node.js.
```bash
$ docker run --rm -v $PWD:/app -u $UID -ti node:18-slim bash
node@87e1438ef553:/$ cd /app
node@87e1438ef553:/app$ npm ci
node@87e1438ef553:/app$ npm run dev
node@87e1438ef553:/app$ pnpm i --frozen-lockfile
node@87e1438ef553:/app$ pnpm run dev
```
4 changes: 2 additions & 2 deletions docgen/missing_device_images.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export async function downloadMissing() {
}
}

console.log(`Done! Filter and update all the files under '${missingImagesPath}', execute 'npm run move-missing-device-images'`);
console.log(`Done! Filter and update all the files under '${missingImagesPath}', execute 'pnpm run move-missing-device-images'`);
}

export async function prepareMissing() {
Expand Down Expand Up @@ -119,7 +119,7 @@ export async function prepareMissing() {
if (fs.existsSync(imagePath)) fs.rmSync(imagePath);
}
}
console.log(`Done! Filter and update all the files under '${missingImagesPath}', execute 'npm run move-missing-device-images'`);
console.log(`Done! Filter and update all the files under '${missingImagesPath}', execute 'pnpm run move-missing-device-images'`);
}

async function moveMissing() {
Expand Down
74 changes: 74 additions & 0 deletions docs/advanced/more/external_converters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
sidebar: auto
---

# External converters

Zigbee2MQTT uses [zigbee-herdsman-converters](https://github.com/Koenkk/zigbee-herdsman-converters) to parse messages to and from devices.

External converters provide a way to test support for new devices, they work identically to internal converters.

External converters are stored in `data/external_converters` folder and have to export a JavaScript Object or Array of Object matching the type [`DefinitionWithExtend`](https://github.com/Koenkk/zigbee-herdsman-converters/blob/master/src/lib/types.ts). Refer to [existing converters](https://github.com/Koenkk/zigbee-herdsman-converters/tree/master/src/devices) to get familiar with the framework.

:::tip TIP
Once your converter is ready, open a [pull request](https://github.com/Koenkk/zigbee-herdsman-converters/pulls) so it can be integrated into Zigbee2MQTT for all to use. Once the new Zigbee2MQTT version is released, you can just delete the external converter.
:::

Example:

File: `data/external_converters/my-first-converter.js`

```js
const {temperature, humidity, battery} = require('zigbee-herdsman-converters/lib/modernExtend');

const definition = {
zigbeeModel: ['lumi.sens'],
model: 'WSDCGQ01LM',
vendor: 'Xiaomi',
description: 'MiJia temperature & humidity sensor',
extend: [temperature(), humidity(), battery()],
};

module.exports = definition;
```

### More examples

- [Sensor using modern extends](https://github.com/Koenkk/zigbee2mqtt.io/blob/master/docs/externalConvertersExample/sensor_me.js) (same as above)
- [Sensor using non modern extends](https://github.com/Koenkk/zigbee2mqtt.io/blob/master/docs/externalConvertersExample/sensor.js)
- [Bulb (light)](https://github.com/Koenkk/zigbee2mqtt.io/blob/master/docs/externalConvertersExample/light.js)
- [Plug (switch)](https://github.com/Koenkk/zigbee2mqtt.io/blob/master/docs/externalConvertersExample/switch.js)
- [Advanced example](https://github.com/Koenkk/zigbee2mqtt.io/blob/master/docs/externalConvertersExample/freepad_ext.js)
- Definitions of already supported devices can be found [here](https://github.com/Koenkk/zigbee-herdsman-converters/tree/master/src/devices). It may help to look at devices from the same vendor or type.

### Using modern extends

The entire API can be found [here](https://github.com/Koenkk/zigbee-herdsman-converters/blob/master/src/lib/modernExtend.ts).

### Using non modern extends

The most common API endpoints are accessible from the following imports:

```js
const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const ota = require('zigbee-herdsman-converters/lib/ota');
const utils = require('zigbee-herdsman-converters/lib/utils');
const globalStore = require('zigbee-herdsman-converters/lib/store');
const e = exposes.presets;
const ea = exposes.access;
```

## Converters list

When Zigbee2MQTT starts it publishes `zigbee2mqtt/bridge/converters` with payload `[{"name": "my-first-converter.js": "code": <HERE COMES YOUR CONVERTER CODE>}]` containing all the converters loaded from the file system. The same message is also published when a converter changes at runtime (from one of the below actions), with the appropriately updated payload.

## Save converter

To save a converter at runtime, send a message to `zigbee2mqtt/bridge/request/converter/save` with payload `{"name": "my-first-converter.js", "code": <HERE COMES YOUR CONVERTER CODE>}`. The code will be saved in `data/external_converters/` in the file with the given name.

## Remove converter

To remove a converter at runtime, send a message to `zigbee2mqtt/bridge/request/converter/remove` with payload `{"name": "my-first-converter.js"}`. The file will be deleted from `data/external_converters/`.
66 changes: 66 additions & 0 deletions docs/advanced/more/external_extensions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
sidebar: auto
---

# External extensions

External extensions provide a way to extend Zigbee2MQTT behavior, they work identically to internal extensions.

To get familiar with the Extension framework, refer to the [source code of internal extensions](https://github.com/Koenkk/zigbee2mqtt/tree/master/lib/extension).

External extensions are stored in `data/external_extensions` folder and have to export a JavaScript Class that conforms to the `Extension` base class (see above link).

Example:

File: `data/external_extensions/my-first-extension.js`

```js
class MyExampleExtension {
constructor(zigbee, mqtt, state, publishEntityState, eventBus, settings, logger) {
this.zigbee = zigbee;
this.mqtt = mqtt;
this.state = state;
this.publishEntityState = publishEntityState;
this.eventBus = eventBus;
this.settings = settings;
this.logger = logger;

logger.info('Loaded MyExampleExtension');
}

/**
* Called when the extension starts (on Zigbee2MQTT startup, or when the extension is saved at runtime)
*/
start() {
this.mqtt.publish('example/extension', 'hello from MyExampleExtension');

// All possible events can be seen here: https://github.com/Koenkk/zigbee2mqtt/blob/master/lib/eventBus.ts

// Subscribe to MQTT messages
this.eventBus.onMQTTMessage(this, (data) => {
console.log(`Received MQTT message on topic '${data.topic}' with message '${data.message}'`);
});
}

/**
* Called when the extension stops (on Zigbee2MQTT shutdown, or when the extension is saved/removed at runtime)
*/
stop() {
this.eventBus.removeListeners(this);
}
}

module.exports = MyExampleExtension;
```

## Extensions list

When Zigbee2MQTT starts it publishes `zigbee2mqtt/bridge/extensions` with payload `[{"name": "my-first-extension.js": "code": <HERE COMES YOUR EXTENSION SOURCE CODE>}]` containing all the extensions loaded from the file system. The same message is also published when an extension changes at runtime (from one of the below actions), with the appropriately updated payload.

## Save extension

To save an extension at runtime, send a message to `zigbee2mqtt/bridge/request/extension/save` with payload `{"name": "my-first-extension.js", "code": <HERE COMES YOUR EXTENSION SOURCE CODE>}`. The code will be saved in `data/external_extensions/` in the file with the given name.

## Remove extension

To remove an extension at runtime, send a message to `zigbee2mqtt/bridge/request/extension/remove` with payload `{"name": "my-first-extension.js"}`. The file will be deleted from `data/external_extensions/`.
2 changes: 1 addition & 1 deletion docs/advanced/more/switch-to-dev-branch.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ git fetch origin dev
# If you get an `error: pathspec 'dev' did not match any file(s) known to git` execute: `git fetch origin --unshallow`
git checkout dev # Change 'dev' to 'master' to switch back to the release version
git pull
npm ci
pnpm i --frozen-lockfile

# Restore configuration
cp -R data-backup/* data
Expand Down
66 changes: 0 additions & 66 deletions docs/advanced/more/user_extensions.md

This file was deleted.

Loading

0 comments on commit 12a29c3

Please sign in to comment.