• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

homebridge/plugin-ui-utils: Create fully customisable configuration user interfa ...

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称:

homebridge/plugin-ui-utils

开源软件地址:

https://github.com/homebridge/plugin-ui-utils

开源编程语言:

TypeScript 100.0%

开源软件介绍:

npm npm Discord

Homebridge Plugin Custom UI Utils

The package assists plugin developers creating fully customisable configuration user interfaces for their plugins.

Implementation

A plugin's custom user interface has two main components:

  • User Interface - this is the HTML / CSS / JavaScript code the users interact with
  • Server - this is an optional server side script that provides endpoints the UI can call

Project Layout

A custom UI should be published under a directory named homebridge-ui:

  • homebridge-ui/public/index.html - required - this is the plugin UI entry point.
  • homebridge-ui/public/ - you can store any other assets (.css, .js, images etc.) in the public folder.
  • homebridge-ui/server.js - optional - this is the server side script containing API endpoints for your plugin UI.
  • config.schema.json - required - set customUi to true in the schema to enable custom UI.

Basic structure example:

homebridge-example-plugin/
├── homebridge-ui
│   ├── public
│   │   └── index.html
│   └── server.js
├── config.schema.json
├── package.json

You may customise the location of the homebridge-ui by setting the customUiPath property in the config.schema.json. For example: "customUiPath": "./dist/homebridge-ui".

User Interface API

A plugin's custom user interface is displayed inside an iframe in the settings modal, in place of the schema-generated form.

The user interface API is provided to the plugin's custom UI via the window.homebridge object. This is injected into the plugin's custom UI during render.

Note:

  • Developers are free to use front end frameworks such as Angular, Vue, or React to create the plugin's custom user interface.
  • Developers should make use Bootstrap 4 CSS classes, as these will automatically be styled and themed correctly. There is no need to include the boostrap css yourself, this will be injected by the Homebridge UI during render.
  • As the user interface is displayed in an isolated iframe, you can safely use any custom JavaScript and CSS.
  • The index.html file should not include <html>, <head>, or <body> tags, as these are added by the Homebridge UI during the render process.
  • You may include external assets in your HTML.

Example index.html:

<link rel="stylesheet" href="your-plugin.css">

<div class="card">
  <div class="form-group">
    <label for="exampleInputEmail1">Email address</label>
    <input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp">
    <small id="emailHelp" class="form-text text-muted">Help text...</small>
  </div>
</div>

<script>
(async () => {
  // get the current homebridge config
  const pluginConfig = await homebridge.getPluginConfig();

  // make requests to your server.js script
  const result = await homebridge.request('/hello', { name: 'world' });
})();
</script>

Config

homebridge.getPluginConfig

homebridge.getPluginConfig(): Promise<PluginConfig[]>;

Returns a promise that resolves an array of accessory or platform config blocks for the plugin.

An empty array will be returned if the plugin is not currently configured.

const pluginConfigBlocks = await homebridge.getPluginConfig();
// [{ platform: 'ExamplePlatform', name: 'example' }]

homebridge.updatePluginConfig

homebridge.updatePluginConfig(pluginConfig: PluginConfig[]): Promise<PluginConfig[]>;

Update the plugin config.

  • pluginConfig: A full array of platform and accessory config blocks.

This should be called whenever a change to the config is made.

This does not save the plugin config to disk.

Existing blocks not included will be removed.

const pluginConfig = [
  {
    name: 'my light 1',
    accessory: 'ExampleAccessory'
  },
  {
    name: 'my light 2',
    accessory: 'ExampleAccessory'
  }
]

await homebridge.updatePluginConfig(pluginConfig);

homebridge.savePluginConfig

homebridge.savePluginConfig(): Promise<void>

Saves the plugin config changes to the Homebridge config.json. This is the equivalent of clicking the Save button.

This should be used sparingly, for example, after a access token is generated.

You must call await homebridge.updatePluginConfig() first.

// update config first!
await homebridge.updatePluginConfig(pluginConfig);

// save config
await homebridge.savePluginConfig();

homebridge.getPluginConfigSchema

homebridge.getPluginConfigSchema(): Promise<PluginSchema>;

Returns the plugin's config.schema.json.

const schema = await homebridge.getPluginConfigSchema();

homebridge.getCachedAccessories

homebridge.getCachedAccessories(): Promise<CachedAccessory[]>;

Returns the any cached accessories for the plugin

const cachedAccessories = await homebridge.getCachedAccessories();

Requests

This allows the custom UI to make API requests to their server.js script.

homebridge.request

homebridge.request(path: string, body?: any): Promise<any>

Make a request to the plugin's server side script.

  • path: the path handler on the server that the request should be sent to
  • body: an optional payload

Returns a promise with the response from the server.

User Interface Example:

const response = await homebridge.request('/hello', { who: 'world' });
console.log(response); // the response from the server

The corresponding code in the server.js file would look like this:

// server side request handler
this.onRequest('/hello', async (payload) => {
  console.log(payload) // the payload sent from the UI
  return { hello: 'user' };
});

Toast Notifications

Toast notifications are the pop-up notifications displayed in the bottom right corner. A plugin's custom UI can generate custom notifications with custom content.

homebridge.toast.success

homebridge.toast.success(message: string, title?: string): void

Shows a green "success" notification.

  • message: the toast content
  • title: an optional title

homebridge.toast.error

homebridge.toast.error(message: string, title?: string): void

Shows a red "error" notification.

  • message: the toast content
  • title: an optional title

homebridge.toast.warning

homebridge.toast.warning(message: string, title?: string): void

Shows an amber "warning" notification.

  • message: the toast content
  • title: an optional title

homebridge.toast.info

homebridge.toast.info(message: string, title?: string): void

Shows a blue "info" notification.

  • message: the toast content
  • title: an optional title

Modal

homebridge.closeSettings

homebridge.closeSettings(): void

Close the settings modal.

This action does not save any config changes.

homebridge.closeSettings();

homebridge.showSpinner

homebridge.showSpinner(): void

Displays a spinner / loading overlay, preventing user input until cleared with homebridge.hideSpinner.

// show the spinner overlay
homebridge.showSpinner();

// wait for the request to process
await homebridge.request('/hello');

// hide the spinner overlay
homebridge.hideSpinner();

homebridge.hideSpinner

homebridge.hideSpinner(): void

Hide the spinner / loading overlay.

homebridge.hideSpinner();

Forms

The custom user interface allows you to create two types of forms:

  1. A form based on your plugin's config.schema.json file
    • User input is automatically mapped to the plugin config object
    • You can listen for change events from your custom user interface
    • The schema must contain all config options
  2. A standalone form
    • Not linked to your config.schema.json form in any way
    • You must listen for change events, process the event, and update the plugin config
    • The form does not need to include all config options

Developers are also able to create their own forms using HTML.

homebridge.showSchemaForm

homebridge.showSchemaForm(): void

Show the schema-generated form below the custom user interface. This feature only works for platform plugins that have set singular = true in their config.schema.json file.

homebridge.showSchemaForm();

When enabling the schema form, you should listen for the configChanged event to keep your config in sync. This event is triggered whenever the user makes a change in the schema-generated form (250ms debounce).

window.homebridge.addEventListener('configChanged', (event: MessageEvent) => {
  console.log('Updated config:', event.data);
});

homebridge.hideSchemaForm

homebridge.hideSchemaForm(): void

Hides the schema-generated form.

homebridge.hideSchemaForm();

homebridge.createForm

homebridge.createForm(schema: FormSchema, data: any, submitButton?: string, cancelButton?: string): IHomebridgeUiFormHelper;

Create a new standalone form. You may pass in an arbitrary schema using the same options as the config.schema.json.

Only one standalone form can be displayed at a time. The main config-schema based form cannot be shown while a standalone form is being displayed.

  • schema: The form schema object, may also contain layout metadata
  • data: The initial form data
  • submitButton: String. Optional label for a submit button, if not provided, no submit button will be displayed
  • cancelButton: String. Optional label for a cancel button, if not provided, no cancel button will be displayed

Example:

// create the form
const myForm = homebridge.createForm(
   {
      schema: {
        type: 'object',
        properties: {
          name: {
            title: 'Name',
            type: 'string',
            required: true,
          }
        }
      },
      layout: null,
      form: null,
   },
   {
      name: 'initial name value'
   }
);

// watch for change events
myForm.onChange((change) => {
  console.log(change);
});

// watch for submit button click events
myForm.onSubmit((form) => {
  console.log(form);
});

// watch for cancel button click events
myForm.onCancel((form) => {
  console.log(form);
});

// stop listening to change events and hide the form
myForm.end();

Events

The homebridge object is an EventTarget, this allows you to use the browsers built in addEventListener and removeEventListener functions to subscribe and unsubscribe from events.

Ready Event

Called when the Homebridge UI has completed rendering the plugin's custom UI.

homebridge.addEventListener('ready', () => {
  // do something with event
});

Custom Events

Custom events can be pushed from the plugin's server.js script.

UI Example:

homebridge.addEventListener('my-event', (event) => {
  console.log(event.data); // the event payload from the server
});

The corresponding code in the server.js file would look like this:

this.pushEvent('my-event', { some: 'data' });

Plugin / Server Information

homebridge.plugin

homebridge.plugin

Is an object that contains plugin metadata.

{
  name: string;
  description: string;
  installedVersion: string;
  latestVersion: string;
  verifiedPlugin: boolean;
  updateAvailable: boolean;
  publicPackage: boolean;
  links: {
    npm: string;
    homepage?: string;
  }
}

homebridge.serverEnv

homebridge.serverEnv

Is an object containing some server metadata

{
  env: {
    platform: string;       // darwin, win32, linux, freebsd etc.
    nodeVersion: string;    // Node.js version
  }
}

Server API

To provide server API endpoints that can be called from the custom UI, a plugin must place a server.js file in the homebridge-ui directory.

You will need to include the @homebridge/plugin-ui-utils library as a prod dependency:

npm install --save @homebridge/plugin-ui-utils

Note:

  • This server.js script will be spawned as a child process when the plugin's settings modal is opened, and is terminated when the settings modal is closed.
  • The server.js script must create a new instance of a class that extends HomebridgePluginUiServer from the @homebridge/plugin-ui-utils library.
  • This file will be spawned as a child process when the plugin's settings modal is opened, and is terminated when the settings modal is closed.
  • The server side script must extend the class provided by the @homebridge/plugin-ui-utils library.

Example server.js:

const { HomebridgePluginUiServer } = require('@homebridge/plugin-ui-utils');

// your class MUST extend the HomebridgePluginUiServer
class UiServer extends HomebridgePluginUiServer {
  constructor () { 
    // super must be called first
    super();

    // Example: create api endpoint request handlers (example only)
    this.onRequest('/hello', this.handleHelloRequest.bind(this));

    // this.ready() must be called to let the UI know you are ready to accept api calls
    this.ready();
  }

  /**
   * Example only.
   * Handle requests made from the UI to the `/hello` endpoint.
   */
  async handleHelloRequest(payload) {
    return { hello: 'world'; }
  }
}

// start the instance of the class
(() => {
  return new UiServer;
})();

Setup

this.ready


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap