├── .github └── workflows │ └── main.yml ├── .gitignore ├── README.md ├── app-side └── index.js ├── app.js ├── app.json ├── assets ├── amazfit-band7 │ ├── brightness_down.png │ ├── brightness_max.png │ ├── brightness_mid.png │ ├── brightness_min_1.png │ ├── brightness_min_2.png │ ├── brightness_up.png │ ├── forward.png │ ├── forward24.png │ ├── icon.png │ ├── loading │ │ ├── loading_0.png │ │ ├── loading_1.png │ │ ├── loading_10.png │ │ ├── loading_11.png │ │ ├── loading_12.png │ │ ├── loading_13.png │ │ ├── loading_14.png │ │ ├── loading_15.png │ │ ├── loading_16.png │ │ ├── loading_17.png │ │ ├── loading_18.png │ │ ├── loading_19.png │ │ ├── loading_2.png │ │ ├── loading_20.png │ │ ├── loading_21.png │ │ ├── loading_22.png │ │ ├── loading_23.png │ │ ├── loading_24.png │ │ ├── loading_25.png │ │ ├── loading_26.png │ │ ├── loading_27.png │ │ ├── loading_28.png │ │ ├── loading_29.png │ │ ├── loading_3.png │ │ ├── loading_30.png │ │ ├── loading_31.png │ │ ├── loading_32.png │ │ ├── loading_33.png │ │ ├── loading_34.png │ │ ├── loading_35.png │ │ ├── loading_36.png │ │ ├── loading_37.png │ │ ├── loading_38.png │ │ ├── loading_39.png │ │ ├── loading_4.png │ │ ├── loading_40.png │ │ ├── loading_41.png │ │ ├── loading_42.png │ │ ├── loading_43.png │ │ ├── loading_44.png │ │ ├── loading_45.png │ │ ├── loading_46.png │ │ ├── loading_47.png │ │ ├── loading_48.png │ │ ├── loading_49.png │ │ ├── loading_5.png │ │ ├── loading_50.png │ │ ├── loading_51.png │ │ ├── loading_52.png │ │ ├── loading_53.png │ │ ├── loading_54.png │ │ ├── loading_55.png │ │ ├── loading_56.png │ │ ├── loading_57.png │ │ ├── loading_58.png │ │ ├── loading_59.png │ │ ├── loading_6.png │ │ ├── loading_7.png │ │ ├── loading_8.png │ │ └── loading_9.png │ ├── pause.png │ ├── play.png │ ├── power.png │ ├── power_pressed.png │ ├── radio_select.png │ ├── skip_next.png │ ├── skip_next_pressed.png │ ├── skip_previous.png │ ├── skip_previous_pressed.png │ ├── switch_off.png │ ├── switch_on.png │ ├── volume_down.png │ ├── volume_max.png │ ├── volume_mid.png │ ├── volume_min_1.png │ ├── volume_min_2.png │ ├── volume_off.png │ └── volume_up.png ├── balance │ ├── brightness_down.png │ ├── brightness_max.png │ ├── brightness_mid.png │ ├── brightness_min_1.png │ ├── brightness_min_2.png │ ├── brightness_up.png │ ├── forward.png │ ├── forward24.png │ ├── icon.png │ ├── loading │ │ ├── loading_0.png │ │ ├── loading_1.png │ │ ├── loading_10.png │ │ ├── loading_11.png │ │ ├── loading_12.png │ │ ├── loading_13.png │ │ ├── loading_14.png │ │ ├── loading_15.png │ │ ├── loading_16.png │ │ ├── loading_17.png │ │ ├── loading_18.png │ │ ├── loading_19.png │ │ ├── loading_2.png │ │ ├── loading_20.png │ │ ├── loading_21.png │ │ ├── loading_22.png │ │ ├── loading_23.png │ │ ├── loading_24.png │ │ ├── loading_25.png │ │ ├── loading_26.png │ │ ├── loading_27.png │ │ ├── loading_28.png │ │ ├── loading_29.png │ │ ├── loading_3.png │ │ ├── loading_30.png │ │ ├── loading_31.png │ │ ├── loading_32.png │ │ ├── loading_33.png │ │ ├── loading_34.png │ │ ├── loading_35.png │ │ ├── loading_36.png │ │ ├── loading_37.png │ │ ├── loading_38.png │ │ ├── loading_39.png │ │ ├── loading_4.png │ │ ├── loading_40.png │ │ ├── loading_41.png │ │ ├── loading_42.png │ │ ├── loading_43.png │ │ ├── loading_44.png │ │ ├── loading_45.png │ │ ├── loading_46.png │ │ ├── loading_47.png │ │ ├── loading_48.png │ │ ├── loading_49.png │ │ ├── loading_5.png │ │ ├── loading_50.png │ │ ├── loading_51.png │ │ ├── loading_52.png │ │ ├── loading_53.png │ │ ├── loading_54.png │ │ ├── loading_55.png │ │ ├── loading_56.png │ │ ├── loading_57.png │ │ ├── loading_58.png │ │ ├── loading_59.png │ │ ├── loading_6.png │ │ ├── loading_7.png │ │ ├── loading_8.png │ │ └── loading_9.png │ ├── pause.png │ ├── play.png │ ├── power.png │ ├── power_pressed.png │ ├── radio_select.png │ ├── skip_next.png │ ├── skip_next_pressed.png │ ├── skip_previous.png │ ├── skip_previous_pressed.png │ ├── switch_off.png │ ├── switch_on.png │ ├── volume_down.png │ ├── volume_max.png │ ├── volume_mid.png │ ├── volume_min_1.png │ ├── volume_min_2.png │ ├── volume_off.png │ └── volume_up.png ├── gts3 │ ├── brightness_down.png │ ├── brightness_max.png │ ├── brightness_mid.png │ ├── brightness_min_1.png │ ├── brightness_min_2.png │ ├── brightness_up.png │ ├── forward.png │ ├── forward24.png │ ├── icon.png │ ├── loading │ │ ├── loading_0.png │ │ ├── loading_1.png │ │ ├── loading_10.png │ │ ├── loading_11.png │ │ ├── loading_12.png │ │ ├── loading_13.png │ │ ├── loading_14.png │ │ ├── loading_15.png │ │ ├── loading_16.png │ │ ├── loading_17.png │ │ ├── loading_18.png │ │ ├── loading_19.png │ │ ├── loading_2.png │ │ ├── loading_20.png │ │ ├── loading_21.png │ │ ├── loading_22.png │ │ ├── loading_23.png │ │ ├── loading_24.png │ │ ├── loading_25.png │ │ ├── loading_26.png │ │ ├── loading_27.png │ │ ├── loading_28.png │ │ ├── loading_29.png │ │ ├── loading_3.png │ │ ├── loading_30.png │ │ ├── loading_31.png │ │ ├── loading_32.png │ │ ├── loading_33.png │ │ ├── loading_34.png │ │ ├── loading_35.png │ │ ├── loading_36.png │ │ ├── loading_37.png │ │ ├── loading_38.png │ │ ├── loading_39.png │ │ ├── loading_4.png │ │ ├── loading_40.png │ │ ├── loading_41.png │ │ ├── loading_42.png │ │ ├── loading_43.png │ │ ├── loading_44.png │ │ ├── loading_45.png │ │ ├── loading_46.png │ │ ├── loading_47.png │ │ ├── loading_48.png │ │ ├── loading_49.png │ │ ├── loading_5.png │ │ ├── loading_50.png │ │ ├── loading_51.png │ │ ├── loading_52.png │ │ ├── loading_53.png │ │ ├── loading_54.png │ │ ├── loading_55.png │ │ ├── loading_56.png │ │ ├── loading_57.png │ │ ├── loading_58.png │ │ ├── loading_59.png │ │ ├── loading_6.png │ │ ├── loading_7.png │ │ ├── loading_8.png │ │ └── loading_9.png │ ├── pause.png │ ├── play.png │ ├── power.png │ ├── power_pressed.png │ ├── radio_select.png │ ├── skip_next.png │ ├── skip_next_pressed.png │ ├── skip_previous.png │ ├── skip_previous_pressed.png │ ├── switch_off.png │ ├── switch_on.png │ ├── volume_down.png │ ├── volume_max.png │ ├── volume_mid.png │ ├── volume_min_1.png │ ├── volume_min_2.png │ ├── volume_off.png │ └── volume_up.png ├── mi-band7 │ ├── brightness_down.png │ ├── brightness_max.png │ ├── brightness_mid.png │ ├── brightness_min_1.png │ ├── brightness_min_2.png │ ├── brightness_up.png │ ├── forward.png │ ├── forward24.png │ ├── icon.png │ ├── loading │ │ ├── loading_0.png │ │ ├── loading_1.png │ │ ├── loading_10.png │ │ ├── loading_11.png │ │ ├── loading_12.png │ │ ├── loading_13.png │ │ ├── loading_14.png │ │ ├── loading_15.png │ │ ├── loading_16.png │ │ ├── loading_17.png │ │ ├── loading_18.png │ │ ├── loading_19.png │ │ ├── loading_2.png │ │ ├── loading_20.png │ │ ├── loading_21.png │ │ ├── loading_22.png │ │ ├── loading_23.png │ │ ├── loading_24.png │ │ ├── loading_25.png │ │ ├── loading_26.png │ │ ├── loading_27.png │ │ ├── loading_28.png │ │ ├── loading_29.png │ │ ├── loading_3.png │ │ ├── loading_30.png │ │ ├── loading_31.png │ │ ├── loading_32.png │ │ ├── loading_33.png │ │ ├── loading_34.png │ │ ├── loading_35.png │ │ ├── loading_36.png │ │ ├── loading_37.png │ │ ├── loading_38.png │ │ ├── loading_39.png │ │ ├── loading_4.png │ │ ├── loading_40.png │ │ ├── loading_41.png │ │ ├── loading_42.png │ │ ├── loading_43.png │ │ ├── loading_44.png │ │ ├── loading_45.png │ │ ├── loading_46.png │ │ ├── loading_47.png │ │ ├── loading_48.png │ │ ├── loading_49.png │ │ ├── loading_5.png │ │ ├── loading_50.png │ │ ├── loading_51.png │ │ ├── loading_52.png │ │ ├── loading_53.png │ │ ├── loading_54.png │ │ ├── loading_55.png │ │ ├── loading_56.png │ │ ├── loading_57.png │ │ ├── loading_58.png │ │ ├── loading_59.png │ │ ├── loading_6.png │ │ ├── loading_7.png │ │ ├── loading_8.png │ │ └── loading_9.png │ ├── pause.png │ ├── play.png │ ├── power.png │ ├── power_pressed.png │ ├── radio_select.png │ ├── skip_next.png │ ├── skip_next_pressed.png │ ├── skip_previous.png │ ├── skip_previous_pressed.png │ ├── switch_off.png │ ├── switch_on.png │ ├── volume_down.png │ ├── volume_max.png │ ├── volume_mid.png │ ├── volume_min_1.png │ ├── volume_min_2.png │ ├── volume_off.png │ └── volume_up.png └── trex2 │ ├── brightness_down.png │ ├── brightness_max.png │ ├── brightness_mid.png │ ├── brightness_min_1.png │ ├── brightness_min_2.png │ ├── brightness_up.png │ ├── forward.png │ ├── forward24.png │ ├── icon.png │ ├── loading │ ├── loading_0.png │ ├── loading_1.png │ ├── loading_10.png │ ├── loading_11.png │ ├── loading_12.png │ ├── loading_13.png │ ├── loading_14.png │ ├── loading_15.png │ ├── loading_16.png │ ├── loading_17.png │ ├── loading_18.png │ ├── loading_19.png │ ├── loading_2.png │ ├── loading_20.png │ ├── loading_21.png │ ├── loading_22.png │ ├── loading_23.png │ ├── loading_24.png │ ├── loading_25.png │ ├── loading_26.png │ ├── loading_27.png │ ├── loading_28.png │ ├── loading_29.png │ ├── loading_3.png │ ├── loading_30.png │ ├── loading_31.png │ ├── loading_32.png │ ├── loading_33.png │ ├── loading_34.png │ ├── loading_35.png │ ├── loading_36.png │ ├── loading_37.png │ ├── loading_38.png │ ├── loading_39.png │ ├── loading_4.png │ ├── loading_40.png │ ├── loading_41.png │ ├── loading_42.png │ ├── loading_43.png │ ├── loading_44.png │ ├── loading_45.png │ ├── loading_46.png │ ├── loading_47.png │ ├── loading_48.png │ ├── loading_49.png │ ├── loading_5.png │ ├── loading_50.png │ ├── loading_51.png │ ├── loading_52.png │ ├── loading_53.png │ ├── loading_54.png │ ├── loading_55.png │ ├── loading_56.png │ ├── loading_57.png │ ├── loading_58.png │ ├── loading_59.png │ ├── loading_6.png │ ├── loading_7.png │ ├── loading_8.png │ └── loading_9.png │ ├── pause.png │ ├── play.png │ ├── power.png │ ├── power_pressed.png │ ├── radio_select.png │ ├── skip_next.png │ ├── skip_next_pressed.png │ ├── skip_previous.png │ ├── skip_previous_pressed.png │ ├── switch_off.png │ ├── switch_on.png │ ├── volume_down.png │ ├── volume_max.png │ ├── volume_mid.png │ ├── volume_min_1.png │ ├── volume_min_2.png │ ├── volume_off.png │ └── volume_up.png ├── controls ├── nativeSlider.js ├── progressBar.js └── slider.js ├── global.d.ts ├── images ├── 1.png ├── 2.png └── 3.png ├── jsconfig.json ├── package.json ├── page ├── home │ ├── index.page.js │ ├── index.page.json │ └── index.style.js ├── light │ ├── effectPicker.page.js │ └── index.page.js ├── media_player │ └── index.page.js ├── sensors_update │ └── index.page.js └── test_page │ └── index.page.js ├── setting └── index.js ├── shared ├── buffer.js ├── data.js ├── defer.js ├── device-polyfill.js ├── event.js ├── fs.js ├── global.js ├── js-module.js ├── logger.js ├── message.js ├── promise.js └── setTimeout.js └── utils └── index.js /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches: 5 | - "main" 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-22.04 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: actions/setup-node@v3 13 | with: 14 | node-version: '16.x' 15 | - run: npm i @zeppos/zeus-cli -g 16 | - run: zeus build 17 | - run: mv dist/*.zab dist/ha-zepp.zab 18 | - uses: "marvinpinto/action-automatic-releases@latest" 19 | with: 20 | repo_token: "${{ secrets.GITHUB_TOKEN }}" 21 | automatic_release_tag: "latest" 22 | prerelease: true 23 | title: "Development Build" 24 | files: | 25 | dist/ha-zepp.zab -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/** 3 | dist/* 4 | npm-debug.log 5 | yarn-debug.log* 6 | yarn-error.log* 7 | yarn.lock 8 | package-lock.json 9 | selenium-debug.log 10 | .idea 11 | .vscode 12 | *.suo 13 | *.ntvs* 14 | *.njsproj 15 | *.sln -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Home Assistant companion for Zepp OS devices 2 | Application that allows you to control Home Assistant 3 | 4 | ![image](images/1.png) ![image](images/2.png) ![image](images/3.png) 5 | 6 | ## Features 7 | - (Binary) Sensor status 8 | - Toggle switch 9 | - Toggle light, see its effect (if presented), change its brightness (if this possible) 10 | - Media player support with play/pause, prev/next, volume control 11 | - Input boolean 12 | - Start/stop scripts 13 | - Enable/disable automations 14 | - Update sensors info to Home Assistant REST API (Not stable! Turn off notications on the wearable for most stable experience) 15 | 16 | ### To Do: 17 | - Fix some bugs in the ha-zepp settings page 18 | - Editing colors for lights 19 | - Open for suggestions 20 | 21 | ### Devices supported 22 | - Mi Band 7 23 | - Amazfit Band 7 24 | - Amazfit T-Rex 2 25 | - All other Zepp OS devices, but there is no proper UI for them and you need to add the build configuration yourself 26 | 27 | ### Preparations 28 | #### Mi Band 7 only 29 | - ~~[Modified Zepp App](https://4pda.to/forum/index.php?showtopic=797981&st=15700#entry122653549) (registration required)~~ 30 | - ~~You need to connect Mi Band 7 to Modified Zepp App the same way you would with Zepp Life (google auth is not supported)~~ 31 | - You can use the official Zepp App, but have to create a custom QR code. Follow [this guide](https://habr.com/en/articles/699368/) for the URL of the QR code you have to adapt. 32 | #### General steps 33 | - Download the official Zepp App 34 | - You need to enable [Developer Mode](https://docs.zepp.com/docs/1.0/guides/tools/zepp-app/) in Zepp app 35 | - Build and install the ha-zepp application yourself using the [Zeus CLI](https://docs.zepp.com/docs/1.0/guides/tools/cli/) 36 | - Open the application settings and specify the addresses of Home Assistant, Long-lived access token and select the sensors you want to display on Zepp OS device 37 | #### Home Assistant 38 | - Long-lived access token (you can generate it on your-ha-instance.local/profile page) 39 | - "If you are not using the [`frontend`](https://www.home-assistant.io/integrations/frontend/) in your setup then you need to add the [`api` integration](https://www.home-assistant.io/integrations/api/) to your `configuration.yaml` file." 40 | 41 | ### About the sensor updates to the Home Assitant REST API 42 | Since it is not possible for the general public to access [Huami's WEB API](https://github.com/zepp-health/rest-api/wiki), I decided to make a background updater within this app to send the wearable sensor data to Home Assistant. 43 | It uses the [alarm](https://docs.zepp.com/docs/1.0/reference/device-app-api/hmApp/alarm/alarmNew/) mechanism, which can open a page even when the device is inactive. When this page is opened, the POST requests are performed towards the HA REST API. However, notifications on the device (e.g. app notifications or the calendar notification) are remained open for a while (if you don't swipe it away), which can block this alarm mechanism from showing the ha-zepp page. If the ha-zepp page is blocked by a notification, you will see that if you swipe it away, the ha-zepp page will appear. If you don't swipe it away, the ZeppOS system eventually will remove all stored pages and notifications to save RAM and be more power efficient. If this ha-zepp page is not openend, ha-zepp is unable to create a new alarm, meaning the background updater will break. Therefore, it's best to `DISABLE ALL SORT OF NOTIFICATIONS` if you want this feature to work properly. 44 | -------------------------------------------------------------------------------- /app-side/index.js: -------------------------------------------------------------------------------- 1 | import { MessageBuilder } from "../shared/message"; 2 | 3 | const messageBuilder = new MessageBuilder(); 4 | 5 | function getEntityList() { 6 | return settings.settingsStorage.getItem("entityList") 7 | ? JSON.parse(settings.settingsStorage.getItem("entityList")) 8 | : []; 9 | } 10 | 11 | async function fetchRequest(url, path, fetchParams = {}) { 12 | const token = settings.settingsStorage.getItem("HAToken"); 13 | const res = await fetch({ 14 | url: new URL(path, url).toString(), 15 | method: "GET", 16 | ...fetchParams, 17 | headers: { 18 | Authorization: `Bearer ${token}`, 19 | "Content-Type": "application/json", 20 | ...fetchParams.headers, 21 | }, 22 | }); 23 | if (res.status < 200 || res.status > 204) { 24 | throw new Error("HTTP response code: " + res.status); 25 | } 26 | return res; 27 | } 28 | 29 | async function request(path, fetchParams) { 30 | const localHAIP = settings.settingsStorage.getItem("localHAIP"); 31 | const externalHAIP = settings.settingsStorage.getItem("externalHAIP"); 32 | const hasLocalIP = typeof localHAIP === "string"; 33 | const hasExternalIP = typeof externalHAIP === "string"; 34 | if (!hasLocalIP && !hasExternalIP) { 35 | throw new Error("No addresses to requests"); 36 | } 37 | let error = ""; 38 | if (hasLocalIP) { 39 | try { 40 | const res = await fetchRequest(localHAIP, path, fetchParams); 41 | return res; 42 | } catch (e) { 43 | error = e; 44 | } 45 | } 46 | if (hasExternalIP) { 47 | try { 48 | const res = await fetchRequest(externalHAIP, path, fetchParams); 49 | return res; 50 | } catch (e) { 51 | error = e; 52 | } 53 | } 54 | throw new Error("Connection error:\n" + error); 55 | } 56 | 57 | async function getEnabledEntities() { 58 | const { body } = await request("/api/states"); 59 | const entities = typeof body === "string" ? JSON.parse(body) : body; 60 | const enabledEntities = getEntityList() 61 | .filter((item) => item.value) 62 | .map((item) => { 63 | const actualEntity = entities.find((it) => it.entity_id === item.key); 64 | if (!actualEntity) return null; 65 | let title = actualEntity.entity_id; 66 | let state = actualEntity.state; 67 | if (actualEntity.attributes) { 68 | if (typeof actualEntity.attributes.friendly_name === "string") { 69 | title = actualEntity.attributes.friendly_name; 70 | } 71 | if (typeof actualEntity.attributes.unit_of_measurement === "string") { 72 | state += actualEntity.attributes.unit_of_measurement; 73 | } 74 | } 75 | return { 76 | key: actualEntity.entity_id, 77 | title, 78 | state, 79 | type: actualEntity.entity_id.split(".")[0], 80 | }; 81 | }) 82 | .filter((item) => item); 83 | return enabledEntities; 84 | } 85 | 86 | async function getEntityState(entity_id) { 87 | const { body } = await request(`/api/states/${entity_id}`); 88 | const entity = typeof body === "string" ? JSON.parse(body) : body; 89 | if (!entity) return null; 90 | 91 | let title = entity.entity_id; 92 | let state = entity.state; 93 | if (entity.attributes) { 94 | if (typeof entity.attributes.friendly_name === "string") { 95 | title = entity.attributes.friendly_name; 96 | } 97 | if (typeof entity.attributes.unit_of_measurement === "string") { 98 | state += entity.attributes.unit_of_measurement; 99 | } 100 | } 101 | 102 | actualEntity = { 103 | key: entity.entity_id, 104 | title, 105 | state, 106 | type: entity.entity_id.split(".")[0], 107 | attributes: {}, 108 | }; 109 | 110 | if (actualEntity.type === "light") { 111 | if (typeof entity.attributes.brightness === "number") 112 | actualEntity.attributes.brightness = Math.round( 113 | (entity.attributes.brightness / 255) * 100 114 | ); 115 | 116 | if (Array.isArray(entity.attributes.rgb_color)) 117 | actualEntity.attributes.rgb_color = entity.attributes.rgb_color; 118 | 119 | if (typeof entity.attributes.effect === "string") 120 | actualEntity.attributes.effect = entity.attributes.effect; 121 | 122 | if (Array.isArray(entity.attributes.effect_list)) 123 | actualEntity.attributes.effect_list = entity.attributes.effect_list; 124 | 125 | actualEntity.attributes.supported_features = 126 | entity.attributes.supported_features; 127 | } 128 | 129 | if (actualEntity.type === "media_player") { 130 | if (typeof entity.attributes.volume_level === "number") 131 | actualEntity.attributes.volume_level = entity.attributes.volume_level; 132 | 133 | if (typeof entity.attributes.is_volume_muted === "boolean") 134 | actualEntity.attributes.is_volume_muted = 135 | entity.attributes.is_volume_muted; 136 | 137 | if (typeof entity.attributes.media_position === "number") 138 | actualEntity.attributes.media_position = entity.attributes.media_position; 139 | 140 | if (typeof entity.attributes.media_duration === "number") 141 | actualEntity.attributes.media_duration = entity.attributes.media_duration; 142 | 143 | if (typeof entity.attributes.media_title === "string") 144 | actualEntity.attributes.media_title = entity.attributes.media_title; 145 | 146 | if (typeof entity.attributes.media_artist === "string") 147 | actualEntity.attributes.media_artist = entity.attributes.media_artist; 148 | 149 | actualEntity.attributes.supported_features = 150 | entity.attributes.supported_features; 151 | } 152 | 153 | console.log(actualEntity); 154 | return actualEntity; 155 | } 156 | 157 | AppSideService({ 158 | onInit() { 159 | console.log("onInit"); 160 | messageBuilder.listen(() => {}); 161 | settings.settingsStorage.addListener( 162 | "change", 163 | async ({ key, newValue, oldValue }) => { 164 | if (key === "entityList") { 165 | const enabledEntities = await getEnabledEntities(); 166 | messageBuilder.call({ 167 | action: "listUpdate", 168 | value: enabledEntities, 169 | }); 170 | } 171 | if (key === "listFetchRandom") { 172 | const { body } = await request("/api/states"); 173 | const res = typeof body === "string" ? JSON.parse(body) : body; 174 | const entityList = res.map((item) => { 175 | let title = item.entity_id; 176 | if ( 177 | item.attributes && 178 | typeof item.attributes.friendly_name === "string" 179 | ) { 180 | title = item.attributes.friendly_name; 181 | } 182 | return { 183 | key: item.entity_id, 184 | title, 185 | }; 186 | }); 187 | const newStr = JSON.stringify(entityList); 188 | settings.settingsStorage.setItem("entityList", newStr); 189 | } 190 | } 191 | ); 192 | messageBuilder.on("request", async (ctx) => { 193 | const payload = messageBuilder.buf2Json(ctx.request.payload); 194 | if (payload.method === "TOGGLE_SWITCH") { 195 | let state = "off"; 196 | let service = "switch"; 197 | if (payload.value) { 198 | state = "on"; 199 | } 200 | if (payload.service) { 201 | service = payload.service; 202 | } 203 | await request(`/api/services/${service}/turn_${state}`, { 204 | method: "POST", 205 | body: JSON.stringify({ 206 | entity_id: payload.entity_id, 207 | }), 208 | }); 209 | ctx.response({ data: { result: [] } }); 210 | } 211 | if (payload.method == "PRESS_BUTTON") { 212 | let state = "off"; 213 | if (payload.current_state === "off") { 214 | state = "on"; 215 | } 216 | await request(`/api/services/${payload.service}/turn_${state}`, { 217 | method: "POST", 218 | body: JSON.stringify({ 219 | entity_id: payload.entity_id, 220 | }), 221 | }); 222 | ctx.response({ data: { result: [] } }); 223 | } 224 | if (payload.method === "LIGHT_SET") { 225 | await request(`/api/services/${payload.service}/turn_on`, { 226 | method: "POST", 227 | body: JSON.stringify({ 228 | entity_id: payload.entity_id, 229 | ...JSON.parse(payload.value), 230 | }), 231 | }); 232 | ctx.response({ data: { result: [] } }); 233 | } 234 | if (payload.method === "MEDIA_ACTION") { 235 | await request(`/api/services/media_player/${payload.service}`, { 236 | method: "POST", 237 | body: JSON.stringify({ 238 | entity_id: payload.entity_id, 239 | ...JSON.parse(payload.value), 240 | }), 241 | }); 242 | ctx.response({ data: { result: [] } }); 243 | } 244 | if (payload.method === "GET_ENTITY_LIST") { 245 | try { 246 | const enabledEntities = await getEnabledEntities(); 247 | ctx.response({ data: { result: enabledEntities } }); 248 | } catch (e) { 249 | ctx.response({ data: { error: e.message } }); 250 | } 251 | } 252 | if (payload.method === "GET_ENTITY") { 253 | try { 254 | const entityState = await getEntityState(payload.entity_id); 255 | ctx.response({ data: { result: entityState } }); 256 | } catch (e) { 257 | ctx.response({ data: { error: e.message } }); 258 | } 259 | } 260 | if (payload.method === "GET_UPDATE_SENSORS_STATE") { 261 | const state = 262 | (settings.settingsStorage.getItem("updateSensorsBool") === "true"); 263 | ctx.response({ data: { result: state } }); 264 | } 265 | if (payload.method === "UPDATE_SENSORS") { 266 | const attributes = payload.attributes; 267 | try { 268 | // send request and await in case of caught error 269 | await request( 270 | `/api/states/sensor.${payload.device_id}_${payload.sensor_name}`, 271 | { 272 | method: "POST", 273 | body: JSON.stringify({ 274 | state: payload.state, 275 | attributes, 276 | }), 277 | } 278 | ); 279 | ctx.response({ data: { result: [] } }); 280 | } catch (e) { 281 | ctx.response({ data: { error: e.message } }); 282 | } 283 | } 284 | }); 285 | }, 286 | 287 | async onRun() { 288 | console.log("onRun"); 289 | }, 290 | 291 | onDestroy() {}, 292 | }); 293 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | import "./shared/device-polyfill"; 2 | import { MessageBuilder } from "./shared/message"; 3 | 4 | const FS_REF_SENSORS_UPDATE_ALARM_ID = 'sensors_update_alarm_id' 5 | const FS_REF_SENSORS_UPDATE_STATE = 'sensors_update_state' 6 | const FS_REF_SENSORS_UPDATE_TIMESTAMP = 'sensors_update_timestamp' 7 | 8 | const appDevicePort = 20; 9 | const appSidePort = 0; 10 | const appId = 391257; 11 | const messageBuilder = new MessageBuilder({ 12 | appId, 13 | }); 14 | 15 | hmUI.setStatusBarVisible(false); 16 | 17 | App({ 18 | globalData: { 19 | messageBuilder: messageBuilder, 20 | appId: appId, 21 | FS_REF_SENSORS_UPDATE_ALARM_ID, 22 | FS_REF_SENSORS_UPDATE_STATE 23 | }, 24 | onCreate() { 25 | messageBuilder.connect(); 26 | }, 27 | 28 | onDestroy() { 29 | messageBuilder.disConnect(); 30 | }, 31 | }); 32 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "configVersion": "v2", 3 | "app": { 4 | "appId": 391257, 5 | "appName": "Home Assistant", 6 | "appType": "app", 7 | "version": { 8 | "code": 2, 9 | "name": "1.1.0" 10 | }, 11 | "icon": "icon.png", 12 | "vender": "zepp", 13 | "description": "Home Assistant companion" 14 | }, 15 | "permissions": [], 16 | "runtime": { 17 | "apiVersion": { 18 | "compatible": "1.0.0", 19 | "target": "1.0.1", 20 | "minVersion": "1.0.0" 21 | } 22 | }, 23 | "debug": true, 24 | "targets": { 25 | "mi-band7": { 26 | "module": { 27 | "page": { 28 | "pages": [ 29 | "page/home/index.page", 30 | "page/light/index.page", 31 | "page/light/effectPicker.page", 32 | "page/media_player/index.page", 33 | "page/sensors_update/index.page", 34 | "page/test_page/index.page" 35 | ], 36 | "window": { 37 | "navigationBarBackgroundColor": "#ffffff", 38 | "navigationBarTextStyle": "black", 39 | "navigationBarTitleText": "Home Assistant", 40 | "backgroundColor": "#eeeeee", 41 | "backgroundTextStyle": "light" 42 | } 43 | }, 44 | "app-side": { 45 | "path": "app-side/index" 46 | }, 47 | "setting": { 48 | "path": "setting/index" 49 | } 50 | }, 51 | "platforms": [ 52 | { 53 | "name": "amazfit-band7-nfc", 54 | "deviceSource": 252 55 | }, 56 | { 57 | "name": "amazfit-band7", 58 | "deviceSource": 253 59 | }, 60 | { 61 | "name": "amazfit-band7-w", 62 | "deviceSource": 254 63 | }, 64 | { 65 | "name": "l66", 66 | "deviceSource": 260 67 | }, 68 | { 69 | "name": "l66w", 70 | "deviceSource": 261 71 | }, 72 | { 73 | "name": "l66_1", 74 | "deviceSource": 262 75 | }, 76 | { 77 | "name": "l66w_2", 78 | "deviceSource": 263 79 | }, 80 | { 81 | "name": "l66_3", 82 | "deviceSource": 264 83 | }, 84 | { 85 | "name": "l66_4", 86 | "deviceSource": 265 87 | }, 88 | { 89 | "name": "l66_5", 90 | "deviceSource": 266 91 | } 92 | ], 93 | "designWidth": 194 94 | }, 95 | "amazfit-band7": { 96 | "module": { 97 | "page": { 98 | "pages": [ 99 | "page/home/index.page", 100 | "page/light/index.page", 101 | "page/light/effectPicker.page", 102 | "page/media_player/index.page", 103 | "page/sensors_update/index.page", 104 | "page/test_page/index.page" 105 | ] 106 | }, 107 | "app-side": { 108 | "path": "app-side/index" 109 | }, 110 | "setting": { 111 | "path": "setting/index" 112 | } 113 | }, 114 | "platforms": [ 115 | { 116 | "name": "amazfit-band7-nfc", 117 | "deviceSource": 252 118 | }, 119 | { 120 | "name": "amazfit-band7", 121 | "deviceSource": 253 122 | }, 123 | { 124 | "name": "amazfit-band7-w", 125 | "deviceSource": 254 126 | } 127 | ], 128 | "designWidth": 194 129 | }, 130 | "gts3": { 131 | "module": { 132 | "page": { 133 | "pages": [ 134 | "page/home/index.page", 135 | "page/light/index.page", 136 | "page/light/effectPicker.page", 137 | "page/media_player/index.page", 138 | "page/test_page/index.page" 139 | ], 140 | "window": { 141 | "navigationBarBackgroundColor": "#ffffff", 142 | "navigationBarTextStyle": "black", 143 | "navigationBarTitleText": "Home Assistant", 144 | "backgroundColor": "#eeeeee", 145 | "backgroundTextStyle": "light" 146 | } 147 | }, 148 | "app-side": { 149 | "path": "app-side/index" 150 | }, 151 | "setting": { 152 | "path": "setting/index" 153 | } 154 | }, 155 | "platforms": [ 156 | { 157 | "name": "gts-3", 158 | "deviceSource": 224 159 | }, 160 | { 161 | "name": "gts-3-w", 162 | "deviceSource": 225 163 | } 164 | ], 165 | "designWidth": 90 166 | }, 167 | "balance": { 168 | "module": { 169 | "page": { 170 | "pages": [ 171 | "page/home/index.page", 172 | "page/light/index.page", 173 | "page/light/effectPicker.page", 174 | "page/media_player/index.page", 175 | "page/test_page/index.page" 176 | ], 177 | "window": { 178 | "navigationBarBackgroundColor": "#ffffff", 179 | "navigationBarTextStyle": "black", 180 | "navigationBarTitleText": "Home Assistant", 181 | "backgroundColor": "#eeeeee", 182 | "backgroundTextStyle": "light" 183 | } 184 | }, 185 | "app-side": { 186 | "path": "app-side/index" 187 | }, 188 | "setting": { 189 | "path": "setting/index" 190 | } 191 | }, 192 | "platforms": [ 193 | { 194 | "name": "balance", 195 | "deviceSource": 8519936 196 | }, 197 | { 198 | "name": "balance-w", 199 | "deviceSource": 8519937 200 | }, 201 | { 202 | "name": "balance-x", 203 | "deviceSource": 8519939 204 | } 205 | ], 206 | "designWidth": 100 207 | }, 208 | "trex2": { 209 | "module": { 210 | "page": { 211 | "pages": [ 212 | "page/home/index.page", 213 | "page/light/index.page", 214 | "page/light/effectPicker.page", 215 | "page/media_player/index.page", 216 | "page/test_page/index.page" 217 | ], 218 | "window": { 219 | "navigationBarBackgroundColor": "#ffffff", 220 | "navigationBarTextStyle": "black", 221 | "navigationBarTitleText": "Home Assistant", 222 | "backgroundColor": "#eeeeee", 223 | "backgroundTextStyle": "light" 224 | } 225 | }, 226 | "app-side": { 227 | "path": "app-side/index" 228 | }, 229 | "setting": { 230 | "path": "setting/index" 231 | } 232 | }, 233 | "platforms": [ 234 | { 235 | "name": "trex2", 236 | "deviceSource": 418 237 | }, 238 | { 239 | "name": "trex2-w", 240 | "deviceSource": 419 241 | } 242 | ], 243 | "designWidth": 545 244 | } 245 | }, 246 | "i18n": { 247 | "en-US": { 248 | "appName": "Home Assistant" 249 | } 250 | }, 251 | "defaultLanguage": "en-US" 252 | } 253 | -------------------------------------------------------------------------------- /assets/amazfit-band7/brightness_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/brightness_down.png -------------------------------------------------------------------------------- /assets/amazfit-band7/brightness_max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/brightness_max.png -------------------------------------------------------------------------------- /assets/amazfit-band7/brightness_mid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/brightness_mid.png -------------------------------------------------------------------------------- /assets/amazfit-band7/brightness_min_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/brightness_min_1.png -------------------------------------------------------------------------------- /assets/amazfit-band7/brightness_min_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/brightness_min_2.png -------------------------------------------------------------------------------- /assets/amazfit-band7/brightness_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/brightness_up.png -------------------------------------------------------------------------------- /assets/amazfit-band7/forward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/forward.png -------------------------------------------------------------------------------- /assets/amazfit-band7/forward24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/forward24.png -------------------------------------------------------------------------------- /assets/amazfit-band7/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/icon.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_0.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_1.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_10.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_11.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_12.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_13.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_14.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_15.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_16.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_17.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_18.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_19.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_2.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_20.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_21.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_22.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_23.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_24.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_25.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_26.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_27.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_28.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_29.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_3.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_30.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_31.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_32.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_33.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_34.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_35.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_36.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_37.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_38.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_39.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_4.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_40.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_41.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_42.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_43.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_44.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_45.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_46.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_46.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_47.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_48.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_49.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_49.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_5.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_50.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_51.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_51.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_52.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_53.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_53.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_54.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_54.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_55.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_56.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_57.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_58.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_59.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_59.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_6.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_7.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_8.png -------------------------------------------------------------------------------- /assets/amazfit-band7/loading/loading_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/loading/loading_9.png -------------------------------------------------------------------------------- /assets/amazfit-band7/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/pause.png -------------------------------------------------------------------------------- /assets/amazfit-band7/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/play.png -------------------------------------------------------------------------------- /assets/amazfit-band7/power.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/power.png -------------------------------------------------------------------------------- /assets/amazfit-band7/power_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/power_pressed.png -------------------------------------------------------------------------------- /assets/amazfit-band7/radio_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/radio_select.png -------------------------------------------------------------------------------- /assets/amazfit-band7/skip_next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/skip_next.png -------------------------------------------------------------------------------- /assets/amazfit-band7/skip_next_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/skip_next_pressed.png -------------------------------------------------------------------------------- /assets/amazfit-band7/skip_previous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/skip_previous.png -------------------------------------------------------------------------------- /assets/amazfit-band7/skip_previous_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/skip_previous_pressed.png -------------------------------------------------------------------------------- /assets/amazfit-band7/switch_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/switch_off.png -------------------------------------------------------------------------------- /assets/amazfit-band7/switch_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/switch_on.png -------------------------------------------------------------------------------- /assets/amazfit-band7/volume_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/volume_down.png -------------------------------------------------------------------------------- /assets/amazfit-band7/volume_max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/volume_max.png -------------------------------------------------------------------------------- /assets/amazfit-band7/volume_mid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/volume_mid.png -------------------------------------------------------------------------------- /assets/amazfit-band7/volume_min_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/volume_min_1.png -------------------------------------------------------------------------------- /assets/amazfit-band7/volume_min_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/volume_min_2.png -------------------------------------------------------------------------------- /assets/amazfit-band7/volume_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/volume_off.png -------------------------------------------------------------------------------- /assets/amazfit-band7/volume_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/amazfit-band7/volume_up.png -------------------------------------------------------------------------------- /assets/balance/brightness_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/brightness_down.png -------------------------------------------------------------------------------- /assets/balance/brightness_max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/brightness_max.png -------------------------------------------------------------------------------- /assets/balance/brightness_mid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/brightness_mid.png -------------------------------------------------------------------------------- /assets/balance/brightness_min_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/brightness_min_1.png -------------------------------------------------------------------------------- /assets/balance/brightness_min_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/brightness_min_2.png -------------------------------------------------------------------------------- /assets/balance/brightness_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/brightness_up.png -------------------------------------------------------------------------------- /assets/balance/forward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/forward.png -------------------------------------------------------------------------------- /assets/balance/forward24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/forward24.png -------------------------------------------------------------------------------- /assets/balance/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/icon.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_0.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_1.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_10.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_11.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_12.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_13.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_14.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_15.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_16.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_17.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_18.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_19.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_2.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_20.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_21.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_22.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_23.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_24.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_25.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_26.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_27.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_28.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_29.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_3.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_30.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_31.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_32.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_33.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_34.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_35.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_36.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_37.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_38.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_39.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_4.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_40.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_41.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_42.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_43.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_44.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_45.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_46.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_46.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_47.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_48.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_49.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_49.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_5.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_50.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_51.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_51.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_52.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_53.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_53.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_54.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_54.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_55.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_56.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_57.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_58.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_59.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_59.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_6.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_7.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_8.png -------------------------------------------------------------------------------- /assets/balance/loading/loading_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/loading/loading_9.png -------------------------------------------------------------------------------- /assets/balance/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/pause.png -------------------------------------------------------------------------------- /assets/balance/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/play.png -------------------------------------------------------------------------------- /assets/balance/power.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/power.png -------------------------------------------------------------------------------- /assets/balance/power_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/power_pressed.png -------------------------------------------------------------------------------- /assets/balance/radio_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/radio_select.png -------------------------------------------------------------------------------- /assets/balance/skip_next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/skip_next.png -------------------------------------------------------------------------------- /assets/balance/skip_next_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/skip_next_pressed.png -------------------------------------------------------------------------------- /assets/balance/skip_previous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/skip_previous.png -------------------------------------------------------------------------------- /assets/balance/skip_previous_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/skip_previous_pressed.png -------------------------------------------------------------------------------- /assets/balance/switch_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/switch_off.png -------------------------------------------------------------------------------- /assets/balance/switch_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/switch_on.png -------------------------------------------------------------------------------- /assets/balance/volume_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/volume_down.png -------------------------------------------------------------------------------- /assets/balance/volume_max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/volume_max.png -------------------------------------------------------------------------------- /assets/balance/volume_mid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/volume_mid.png -------------------------------------------------------------------------------- /assets/balance/volume_min_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/volume_min_1.png -------------------------------------------------------------------------------- /assets/balance/volume_min_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/volume_min_2.png -------------------------------------------------------------------------------- /assets/balance/volume_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/volume_off.png -------------------------------------------------------------------------------- /assets/balance/volume_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/balance/volume_up.png -------------------------------------------------------------------------------- /assets/gts3/brightness_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/brightness_down.png -------------------------------------------------------------------------------- /assets/gts3/brightness_max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/brightness_max.png -------------------------------------------------------------------------------- /assets/gts3/brightness_mid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/brightness_mid.png -------------------------------------------------------------------------------- /assets/gts3/brightness_min_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/brightness_min_1.png -------------------------------------------------------------------------------- /assets/gts3/brightness_min_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/brightness_min_2.png -------------------------------------------------------------------------------- /assets/gts3/brightness_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/brightness_up.png -------------------------------------------------------------------------------- /assets/gts3/forward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/forward.png -------------------------------------------------------------------------------- /assets/gts3/forward24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/forward24.png -------------------------------------------------------------------------------- /assets/gts3/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/icon.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_0.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_1.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_10.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_11.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_12.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_13.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_14.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_15.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_16.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_17.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_18.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_19.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_2.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_20.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_21.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_22.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_23.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_24.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_25.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_26.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_27.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_28.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_29.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_3.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_30.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_31.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_32.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_33.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_34.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_35.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_36.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_37.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_38.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_39.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_4.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_40.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_41.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_42.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_43.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_44.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_45.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_46.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_46.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_47.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_48.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_49.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_49.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_5.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_50.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_51.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_51.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_52.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_53.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_53.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_54.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_54.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_55.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_56.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_57.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_58.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_59.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_59.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_6.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_7.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_8.png -------------------------------------------------------------------------------- /assets/gts3/loading/loading_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/loading/loading_9.png -------------------------------------------------------------------------------- /assets/gts3/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/pause.png -------------------------------------------------------------------------------- /assets/gts3/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/play.png -------------------------------------------------------------------------------- /assets/gts3/power.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/power.png -------------------------------------------------------------------------------- /assets/gts3/power_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/power_pressed.png -------------------------------------------------------------------------------- /assets/gts3/radio_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/radio_select.png -------------------------------------------------------------------------------- /assets/gts3/skip_next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/skip_next.png -------------------------------------------------------------------------------- /assets/gts3/skip_next_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/skip_next_pressed.png -------------------------------------------------------------------------------- /assets/gts3/skip_previous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/skip_previous.png -------------------------------------------------------------------------------- /assets/gts3/skip_previous_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/skip_previous_pressed.png -------------------------------------------------------------------------------- /assets/gts3/switch_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/switch_off.png -------------------------------------------------------------------------------- /assets/gts3/switch_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/switch_on.png -------------------------------------------------------------------------------- /assets/gts3/volume_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/volume_down.png -------------------------------------------------------------------------------- /assets/gts3/volume_max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/volume_max.png -------------------------------------------------------------------------------- /assets/gts3/volume_mid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/volume_mid.png -------------------------------------------------------------------------------- /assets/gts3/volume_min_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/volume_min_1.png -------------------------------------------------------------------------------- /assets/gts3/volume_min_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/volume_min_2.png -------------------------------------------------------------------------------- /assets/gts3/volume_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/volume_off.png -------------------------------------------------------------------------------- /assets/gts3/volume_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/gts3/volume_up.png -------------------------------------------------------------------------------- /assets/mi-band7/brightness_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/brightness_down.png -------------------------------------------------------------------------------- /assets/mi-band7/brightness_max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/brightness_max.png -------------------------------------------------------------------------------- /assets/mi-band7/brightness_mid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/brightness_mid.png -------------------------------------------------------------------------------- /assets/mi-band7/brightness_min_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/brightness_min_1.png -------------------------------------------------------------------------------- /assets/mi-band7/brightness_min_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/brightness_min_2.png -------------------------------------------------------------------------------- /assets/mi-band7/brightness_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/brightness_up.png -------------------------------------------------------------------------------- /assets/mi-band7/forward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/forward.png -------------------------------------------------------------------------------- /assets/mi-band7/forward24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/forward24.png -------------------------------------------------------------------------------- /assets/mi-band7/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/icon.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_0.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_1.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_10.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_11.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_12.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_13.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_14.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_15.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_16.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_17.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_18.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_19.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_2.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_20.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_21.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_22.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_23.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_24.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_25.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_26.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_27.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_28.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_29.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_3.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_30.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_31.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_32.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_33.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_34.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_35.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_36.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_37.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_38.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_39.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_4.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_40.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_41.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_42.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_43.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_44.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_45.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_46.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_46.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_47.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_48.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_49.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_49.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_5.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_50.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_51.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_51.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_52.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_53.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_53.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_54.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_54.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_55.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_56.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_57.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_58.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_59.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_59.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_6.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_7.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_8.png -------------------------------------------------------------------------------- /assets/mi-band7/loading/loading_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/loading/loading_9.png -------------------------------------------------------------------------------- /assets/mi-band7/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/pause.png -------------------------------------------------------------------------------- /assets/mi-band7/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/play.png -------------------------------------------------------------------------------- /assets/mi-band7/power.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/power.png -------------------------------------------------------------------------------- /assets/mi-band7/power_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/power_pressed.png -------------------------------------------------------------------------------- /assets/mi-band7/radio_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/radio_select.png -------------------------------------------------------------------------------- /assets/mi-band7/skip_next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/skip_next.png -------------------------------------------------------------------------------- /assets/mi-band7/skip_next_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/skip_next_pressed.png -------------------------------------------------------------------------------- /assets/mi-band7/skip_previous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/skip_previous.png -------------------------------------------------------------------------------- /assets/mi-band7/skip_previous_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/skip_previous_pressed.png -------------------------------------------------------------------------------- /assets/mi-band7/switch_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/switch_off.png -------------------------------------------------------------------------------- /assets/mi-band7/switch_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/switch_on.png -------------------------------------------------------------------------------- /assets/mi-band7/volume_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/volume_down.png -------------------------------------------------------------------------------- /assets/mi-band7/volume_max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/volume_max.png -------------------------------------------------------------------------------- /assets/mi-band7/volume_mid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/volume_mid.png -------------------------------------------------------------------------------- /assets/mi-band7/volume_min_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/volume_min_1.png -------------------------------------------------------------------------------- /assets/mi-band7/volume_min_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/volume_min_2.png -------------------------------------------------------------------------------- /assets/mi-band7/volume_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/volume_off.png -------------------------------------------------------------------------------- /assets/mi-band7/volume_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/mi-band7/volume_up.png -------------------------------------------------------------------------------- /assets/trex2/brightness_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/brightness_down.png -------------------------------------------------------------------------------- /assets/trex2/brightness_max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/brightness_max.png -------------------------------------------------------------------------------- /assets/trex2/brightness_mid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/brightness_mid.png -------------------------------------------------------------------------------- /assets/trex2/brightness_min_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/brightness_min_1.png -------------------------------------------------------------------------------- /assets/trex2/brightness_min_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/brightness_min_2.png -------------------------------------------------------------------------------- /assets/trex2/brightness_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/brightness_up.png -------------------------------------------------------------------------------- /assets/trex2/forward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/forward.png -------------------------------------------------------------------------------- /assets/trex2/forward24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/forward24.png -------------------------------------------------------------------------------- /assets/trex2/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/icon.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_0.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_1.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_10.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_11.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_12.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_13.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_14.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_15.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_16.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_17.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_18.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_19.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_2.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_20.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_21.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_22.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_23.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_24.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_25.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_26.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_27.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_28.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_29.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_3.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_30.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_31.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_32.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_33.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_34.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_35.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_36.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_37.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_38.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_39.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_4.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_40.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_41.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_42.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_43.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_44.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_45.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_46.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_46.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_47.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_48.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_49.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_49.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_5.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_50.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_51.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_51.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_52.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_53.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_53.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_54.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_54.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_55.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_56.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_57.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_58.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_59.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_59.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_6.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_7.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_8.png -------------------------------------------------------------------------------- /assets/trex2/loading/loading_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/loading/loading_9.png -------------------------------------------------------------------------------- /assets/trex2/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/pause.png -------------------------------------------------------------------------------- /assets/trex2/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/play.png -------------------------------------------------------------------------------- /assets/trex2/power.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/power.png -------------------------------------------------------------------------------- /assets/trex2/power_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/power_pressed.png -------------------------------------------------------------------------------- /assets/trex2/radio_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/radio_select.png -------------------------------------------------------------------------------- /assets/trex2/skip_next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/skip_next.png -------------------------------------------------------------------------------- /assets/trex2/skip_next_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/skip_next_pressed.png -------------------------------------------------------------------------------- /assets/trex2/skip_previous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/skip_previous.png -------------------------------------------------------------------------------- /assets/trex2/skip_previous_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/skip_previous_pressed.png -------------------------------------------------------------------------------- /assets/trex2/switch_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/switch_off.png -------------------------------------------------------------------------------- /assets/trex2/switch_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/switch_on.png -------------------------------------------------------------------------------- /assets/trex2/volume_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/volume_down.png -------------------------------------------------------------------------------- /assets/trex2/volume_max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/volume_max.png -------------------------------------------------------------------------------- /assets/trex2/volume_mid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/volume_mid.png -------------------------------------------------------------------------------- /assets/trex2/volume_min_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/volume_min_1.png -------------------------------------------------------------------------------- /assets/trex2/volume_min_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/volume_min_2.png -------------------------------------------------------------------------------- /assets/trex2/volume_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/volume_off.png -------------------------------------------------------------------------------- /assets/trex2/volume_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/assets/trex2/volume_up.png -------------------------------------------------------------------------------- /controls/nativeSlider.js: -------------------------------------------------------------------------------- 1 | import { DEVICE_HEIGHT, DEVICE_WIDTH, TOP_BOTTOM_OFFSET, BUTTON_COLOR_NORMAL, BUTTON_COLOR_PRESSED } from "../page/home/index.style"; 2 | 3 | /** 4 | * @param {object} args { 5 | * ctx: object, 6 | * onSliderMove: function(ctx,floatpos,isUserInput), 7 | * frontColor: number, 8 | * backColor: number, 9 | * stateImages: array[string] 10 | * button: object, //{ onButtonToggle: function(ctx, boolean), image: string } 11 | * Image MUST be 12 | * } 13 | * @returns {object} { 14 | * show(), 15 | * setPosition(floatpos), 16 | * getPosition(), 17 | * setButtonToggle(boolean), // only if button is set in params 18 | * getButtonToggle(boolean), // only if button is set in params 19 | * } 20 | */ 21 | export const nativeSlider = (args) => { 22 | let width = DEVICE_WIDTH - TOP_BOTTOM_OFFSET * 2 23 | let height = (DEVICE_HEIGHT - TOP_BOTTOM_OFFSET * (args.button ? 4 : 2)) 24 | let pos_x = TOP_BOTTOM_OFFSET 25 | let pos_y = TOP_BOTTOM_OFFSET 26 | 27 | let outlineWidth = (width) / 2 28 | const buttonSize = width / 3 * 2 29 | const stateImageSize = 72 30 | const actionImgSize = 36 31 | 32 | let backgroundRectangle = null 33 | let sliderBottom = null 34 | let sliderTop = null 35 | let outlineStroke = null 36 | let actionButton = null 37 | let actionButtonIcon = null 38 | let stateImage = null 39 | 40 | let shown = false; 41 | let sliderPressed = false 42 | let lastHeight = height / 2 43 | let buttonState = false 44 | let stateImageIndex = 0 45 | 46 | const getButtonToggle = () => { return buttonState }; 47 | 48 | const setButtonToggle = (value, fromUserInput) => { 49 | if (!shown) return 50 | 51 | buttonState = value 52 | actionButton.setProperty(hmUI.prop.MORE, { 53 | x: DEVICE_WIDTH / 2 - buttonSize / 2, 54 | y: pos_y + height + 20, 55 | w: buttonSize, 56 | h: buttonSize, 57 | normal_color: buttonState ? BUTTON_COLOR_PRESSED : BUTTON_COLOR_NORMAL, 58 | press_color: buttonState ? BUTTON_COLOR_PRESSED : BUTTON_COLOR_NORMAL, 59 | }) 60 | 61 | if (fromUserInput) 62 | args.button.onButtonToggle(args.ctx, buttonState) 63 | }; 64 | 65 | const setPosition = (floatvalue) => { 66 | if (!shown || sliderPressed) return 67 | 68 | let newHeight = Math.round((1 - floatvalue) * height) 69 | newHeight = Math.max(0, newHeight) 70 | newHeight = Math.min(height, newHeight) 71 | lastHeight = newHeight 72 | sliderTop.setProperty(hmUI.prop.MORE, 73 | { 74 | x: pos_x, 75 | y: pos_y, 76 | w: width, 77 | h: newHeight 78 | }) 79 | 80 | if (stateImage) { 81 | stateImageIndex = Math.floor(floatvalue * (args.stateImages.length - 1)) 82 | stateImage.setProperty(hmUI.prop.MORE, { 83 | src: args.stateImages[stateImageIndex] 84 | }) 85 | } 86 | }; 87 | 88 | const getPosition = () => { 89 | return (1 - (lastHeight / height)) 90 | }; 91 | 92 | const show = () => { 93 | if (shown) return 94 | backgroundRectangle = hmUI.createWidget(hmUI.widget.FILL_RECT, { 95 | h: DEVICE_HEIGHT, 96 | w: DEVICE_WIDTH, 97 | x: 0, 98 | y: 0, 99 | color: 0x000000 100 | }) 101 | 102 | sliderBottom = hmUI.createWidget(hmUI.widget.FILL_RECT, { 103 | x: pos_x, 104 | y: pos_y, 105 | w: width, 106 | h: height, 107 | radius: 0, 108 | color: args.frontColor 109 | }) 110 | 111 | sliderTop = hmUI.createWidget(hmUI.widget.FILL_RECT, { 112 | x: pos_x, 113 | y: pos_y, 114 | w: width, 115 | h: height / 2, 116 | radius: 0, 117 | color: args.backColor 118 | }) 119 | sliderTop.setEnable(false) 120 | 121 | outlineStroke = hmUI.createWidget(hmUI.widget.STROKE_RECT, { 122 | x: pos_x - outlineWidth, 123 | y: pos_y - outlineWidth, 124 | w: width + 2 * outlineWidth, 125 | h: height + 2 * outlineWidth, 126 | radius: (width), 127 | color: 0x000000, 128 | line_width: outlineWidth 129 | }) 130 | outlineStroke.setEnable(false) 131 | 132 | if (args.stateImages) { 133 | stateImage = hmUI.createWidget(hmUI.widget.IMG, 134 | { 135 | x: DEVICE_WIDTH / 2 - stateImageSize / 2, 136 | y: pos_y + height - 20 - stateImageSize, 137 | h: stateImageSize, 138 | w: stateImageSize, 139 | src: args.stateImages[stateImageIndex] 140 | }) 141 | stateImage.setEnable(false) 142 | } 143 | 144 | let last_y = 0 145 | 146 | sliderBottom.addEventListener(hmUI.event.MOVE, function (info) { 147 | if (!sliderPressed) return 148 | let newHeight = Math.round((info.y - last_y) + lastHeight) 149 | newHeight = Math.max(0, newHeight) 150 | newHeight = Math.min(height, newHeight) 151 | 152 | sliderTop.setProperty(hmUI.prop.MORE, 153 | { 154 | x: pos_x, 155 | y: pos_y, 156 | w: width, 157 | h: newHeight 158 | }) 159 | lastHeight = newHeight 160 | last_y = info.y 161 | 162 | if (stateImage) { 163 | let newStateImageIndex = Math.floor((1 - lastHeight / height) * (args.stateImages.length - 1)) 164 | 165 | if (newStateImageIndex != stateImageIndex) { 166 | stateImageIndex = newStateImageIndex 167 | stateImage.setProperty(hmUI.prop.MORE, { 168 | src: args.stateImages[stateImageIndex] 169 | }) 170 | } 171 | } 172 | 173 | }) 174 | 175 | sliderBottom.addEventListener(hmUI.event.CLICK_DOWN, function (info) { 176 | last_y = info.y 177 | sliderPressed = true 178 | }) 179 | 180 | sliderBottom.addEventListener(hmUI.event.CLICK_UP, function (info) { 181 | if (sliderPressed) args.onSliderMove(args.ctx, (1 - (lastHeight / height)), true); 182 | sliderPressed = false 183 | }) 184 | 185 | if (args.button) { 186 | actionButton = hmUI.createWidget(hmUI.widget.BUTTON, { 187 | x: DEVICE_WIDTH / 2 - buttonSize / 2, 188 | y: pos_y + height + 20, 189 | w: buttonSize, 190 | h: buttonSize, 191 | radius: buttonSize / 2, 192 | normal_color: BUTTON_COLOR_NORMAL, 193 | press_color: BUTTON_COLOR_NORMAL, 194 | click_func: (button_widget) => { setButtonToggle(!buttonState, true) } 195 | }) 196 | 197 | actionButtonIcon = hmUI.createWidget(hmUI.widget.IMG, { 198 | x: DEVICE_WIDTH / 2 - actionImgSize / 2, 199 | y: pos_y + height + 20 + buttonSize / 2 - actionImgSize / 2, 200 | w: actionImgSize, 201 | h: actionImgSize, 202 | src: args.button.image 203 | }) 204 | actionButtonIcon.setEnable(false) 205 | } 206 | 207 | hmApp.registerGestureEvent(function (event) { 208 | if (event == hmApp.gesture.RIGHT) { 209 | hmUI.deleteWidget(outlineStroke) 210 | hmUI.deleteWidget(sliderTop) 211 | hmUI.deleteWidget(sliderBottom) 212 | 213 | hmUI.deleteWidget(backgroundRectangle) 214 | 215 | if (args.stateImages) { 216 | hmUI.deleteWidget(stateImage) 217 | } 218 | 219 | if (args.button) { 220 | hmUI.deleteWidget(actionButton) 221 | hmUI.deleteWidget(actionButtonIcon) 222 | } 223 | hmUI.redraw(); 224 | hmApp.unregisterGestureEvent(); 225 | 226 | shown = false; 227 | 228 | return true 229 | } 230 | return false; 231 | }) 232 | shown = true; 233 | } 234 | 235 | return { setPosition, getPosition, setButtonToggle, getButtonToggle, show } 236 | }; -------------------------------------------------------------------------------- /controls/progressBar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {object} args { 3 | * h: number, //height of thickest part or height of image 4 | * w: number, 5 | * x: number, 6 | * y: number, 7 | * src: string, //image name 8 | * ctx: object, 9 | * onClick: function(ctx), //if this set, progressBar will act as button 10 | * frontColor: number, 11 | * backColor: number, 12 | * } 13 | * @returns {object} { 14 | * setPosition(floatpos), 15 | * components: array[Widget], 16 | * } 17 | */ 18 | export const createProgressBar = (args) => { 19 | const components = [] 20 | 21 | let progressBarBg = hmUI.createWidget(hmUI.widget.FILL_RECT, { 22 | x: args.x, 23 | y: args.y, 24 | w: args.w, 25 | h: args.h, 26 | color: 0x000000 27 | }); 28 | 29 | if (args.src) { 30 | const img = hmUI.createWidget(hmUI.widget.IMG, { 31 | x: args.x, 32 | y: args.y, 33 | w: args.h, 34 | h: args.h, 35 | src: args.src 36 | }) 37 | 38 | args.x += args.h + 5 39 | args.y += args.h / 4 40 | args.w -= args.h + 5 41 | args.h /= 2 42 | 43 | components.push(img) 44 | } 45 | 46 | const progressBarRow = hmUI.createWidget(hmUI.widget.FILL_RECT, { 47 | x: args.x, 48 | y: args.y, 49 | w: args.w, 50 | h: args.h, 51 | radius: args.h / 2, 52 | color: args.backColor 53 | }); 54 | 55 | const progressBarPoint = hmUI.createWidget(hmUI.widget.FILL_RECT, { 56 | x: args.x, 57 | y: args.y, 58 | w: args.h / 2, 59 | h: args.h, 60 | radius: args.h / 2, 61 | color: args.frontColor 62 | }); 63 | 64 | const setPosition = (floatvalue) => { 65 | progressBarPoint.setProperty( 66 | hmUI.prop.MORE, 67 | { w: floatvalue * args.w }); 68 | }; 69 | 70 | components.push(progressBarBg, progressBarRow, progressBarPoint) 71 | 72 | components.forEach((component) => component.setEnable(false)) 73 | 74 | if (args.onClick) { 75 | progressBarBg.setEnable(true) 76 | progressBarBg.addEventListener(hmUI.event.CLICK_UP, () => { args.onClick(args.ctx) }) 77 | } 78 | 79 | return { setPosition, components } 80 | }; -------------------------------------------------------------------------------- /controls/slider.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {object} args { 3 | * h: number, //height of thickest part or height of image 4 | * w: number, 5 | * x: number, 6 | * y: number, 7 | * hasPoint: boolean, 8 | * buttons: object, //{img_down: "minus_image.png", img_up: "plus_image.png", change_amt: 0.5} 9 | * ctx: object, 10 | * onSliderMove: function(ctx,floatpos,isUserInput), 11 | * onSliderClick: function(ctx), //if this set, slider will act as button 12 | * frontColor: number, 13 | * backColor: number, 14 | * } 15 | * @returns {object} { 16 | * setPosition(floatpos), 17 | * getPosition(), 18 | * components: array[Widget], 19 | * } 20 | */ 21 | export const createSlider = (args) => { 22 | let downButton = null; 23 | let upButton = null; 24 | 25 | if (args.buttons) { 26 | downButton = hmUI.createWidget(hmUI.widget.IMG, { 27 | x: args.x, 28 | y: args.y, 29 | w: args.h, 30 | h: args.h, 31 | src: args.buttons.img_down 32 | }) 33 | 34 | upButton = hmUI.createWidget(hmUI.widget.IMG, { 35 | x: args.x + args.w - args.h, 36 | y: args.y, 37 | w: args.h, 38 | h: args.h, 39 | src: args.buttons.img_up 40 | }) 41 | 42 | args.x += args.h + 5 43 | args.y += args.h / 4 44 | args.w -= args.h * 2 + 10 45 | args.h /= 2 46 | } 47 | 48 | let sliderRow = hmUI.createWidget(hmUI.widget.FILL_RECT, { 49 | x: args.x, 50 | y: args.y, 51 | w: args.w, 52 | h: args.h, 53 | radius: args.h / 2, 54 | color: args.backColor 55 | }); 56 | 57 | let sliderPoint = hmUI.createWidget(hmUI.widget.FILL_RECT, { 58 | x: args.x, 59 | y: args.hasPoint ? args.y - args.h / 2 : args.y, 60 | w: args.hasPoint ? args.h * 2 : args.h / 2, 61 | h: args.hasPoint ? args.h * 2 : args.h, 62 | radius: args.h / 2, 63 | color: args.frontColor 64 | }); 65 | 66 | let sliderValue = 0; 67 | 68 | const onSliderMove = (info) => { 69 | let value = 0; 70 | if (args.hasPoint) { 71 | value = info.x - args.h 72 | value = Math.max(value, args.x - args.h) 73 | value = Math.min(value, args.x + args.w - args.h) 74 | sliderValue = (value - args.x + args.h) / args.w 75 | } else { 76 | value = info.x - args.x 77 | value = Math.max(value, 0) 78 | value = Math.min(value, args.x + args.w) 79 | sliderValue = (value / args.w) 80 | } 81 | 82 | if (args.hasPoint) 83 | sliderPoint.setProperty( 84 | hmUI.prop.MORE, 85 | { x: value } 86 | ); 87 | else 88 | sliderPoint.setProperty( 89 | hmUI.prop.MORE, 90 | { w: value } 91 | ); 92 | if (args.onSliderMove) args.onSliderMove(args.ctx, sliderValue, true); 93 | }; 94 | 95 | const setPosition = (floatvalue, isUserInput = false) => { 96 | sliderValue = floatvalue; 97 | if (args.hasPoint) 98 | sliderPoint.setProperty( 99 | hmUI.prop.MORE, 100 | { x: floatvalue * args.w + args.x - (args.h) }) 101 | else 102 | sliderPoint.setProperty( 103 | hmUI.prop.MORE, 104 | { w: floatvalue * args.w }); 105 | if (args.onSliderMove) args.onSliderMove(args.ctx, floatvalue, isUserInput); 106 | }; 107 | 108 | const getPosition = () => { 109 | return sliderValue 110 | }; 111 | 112 | let components = [sliderRow, sliderPoint] 113 | 114 | if (args.onSliderClick) { 115 | if (args.buttons) { 116 | components.push(downButton, upButton) 117 | downButton.addEventListener(hmUI.event.CLICK_UP, () => { args.onSliderClick(args.ctx) }) 118 | upButton.addEventListener(hmUI.event.CLICK_UP, () => { args.onSliderClick(args.ctx) }) 119 | } 120 | sliderRow.addEventListener(hmUI.event.CLICK_UP, () => { args.onSliderClick(args.ctx) }) 121 | 122 | if (args.hasPoint) 123 | sliderPoint.addEventListener(hmUI.event.CLICK_UP, () => { args.onSliderClick(args.ctx) }); 124 | else 125 | sliderPoint.setEnable(false); 126 | } 127 | else { 128 | if (args.buttons) { 129 | components.push(downButton, upButton) 130 | downButton.addEventListener(hmUI.event.CLICK_UP, (info) => { setPosition(Math.max(0, sliderValue - args.buttons.change_amt), true) }) 131 | upButton.addEventListener(hmUI.event.CLICK_UP, (info) => { setPosition(Math.min(1, sliderValue + args.buttons.change_amt), true) }) 132 | } 133 | else { 134 | sliderRow.addEventListener(hmUI.event.CLICK_UP, onSliderMove) 135 | 136 | if (args.hasPoint) 137 | sliderPoint.addEventListener(hmUI.event.CLICK_UP, onSliderMove); 138 | else 139 | sliderPoint.setEnable(false); 140 | } 141 | } 142 | 143 | return { setPosition, getPosition, components } 144 | }; -------------------------------------------------------------------------------- /global.d.ts: -------------------------------------------------------------------------------- 1 | /// -------------------------------------------------------------------------------- /images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/images/1.png -------------------------------------------------------------------------------- /images/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/images/2.png -------------------------------------------------------------------------------- /images/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ga2mer/ha-zepp/dd7c4355797fdb663d78ab5b179a1584d9d52c1f/images/3.png -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "checkJs": true 6 | }, 7 | "exclude": [ 8 | "node_modules", 9 | "**/node_modules/*" 10 | ], 11 | "files": [ 12 | "node_modules/@zeppos/device-types/index.d.ts" 13 | ] 14 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "empty", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "@zeppos/device-types": "^1.0.0" 13 | }, 14 | "dependencies": { 15 | "@zeppos/zeus-cli": "^1.2.3" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /page/home/index.page.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /page/home/index.style.js: -------------------------------------------------------------------------------- 1 | export const TOP_BOTTOM_OFFSET = 46; 2 | 3 | export const { width: DEVICE_WIDTH, height: DEVICE_HEIGHT } = 4 | hmSetting.getDeviceInfo(); 5 | 6 | export const BUTTON_COLOR_PRESSED = 0x0986d4 7 | export const BUTTON_COLOR_NORMAL = 0x333333 -------------------------------------------------------------------------------- /page/light/effectPicker.page.js: -------------------------------------------------------------------------------- 1 | import { DEVICE_HEIGHT, DEVICE_WIDTH, TOP_BOTTOM_OFFSET } from "../home/index.style"; 2 | import { createSlider } from "../../controls/slider"; 3 | const { messageBuilder } = getApp()._options.globalData; 4 | const logger = DeviceRuntimeCore.HmLogger.getLogger("ha-zepp-light-effectPicker"); 5 | 6 | Page({ 7 | state: { 8 | y: TOP_BOTTOM_OFFSET, 9 | item: null, 10 | widgets: [], 11 | rendered: false, 12 | reloadTimer: null 13 | }, 14 | addWidget(widget) { 15 | this.state.widgets.push(widget); 16 | }, 17 | createWidget(...args) { 18 | const widget = hmUI.createWidget(...args); 19 | this.state.widgets.push(widget); 20 | return widget; 21 | }, 22 | clearWidgets() { 23 | this.state.widgets.forEach((widget, index) => { 24 | hmUI.deleteWidget(widget); 25 | }); 26 | this.state.widgets = []; 27 | this.state.rendered = false; 28 | this.state.y = TOP_BOTTOM_OFFSET; // start from this y to skip rounded border 29 | // hmUI.redraw(); 30 | }, 31 | drawElements() { 32 | this.state.rendered = false; 33 | this.clearWidgets() 34 | 35 | if (typeof this.state.item !== 'object') { 36 | this.drawError("Wrong entity data " + typeof this.state.item) 37 | return; 38 | } 39 | 40 | const titleHeight = 40; 41 | 42 | this.createWidget(hmUI.widget.TEXT, { 43 | x: 0, 44 | y: this.state.y, 45 | w: DEVICE_WIDTH, 46 | h: titleHeight, 47 | text: this.state.item.title, 48 | text_size: 19, 49 | color: 0xffffff, 50 | align_h: hmUI.align.CENTER_H, 51 | }); 52 | this.state.y += titleHeight 53 | 54 | if (this.state.item.attributes.effect) { 55 | this.createWidget(hmUI.widget.TEXT, { 56 | x: 10, 57 | y: this.state.y, 58 | w: DEVICE_WIDTH / 3, 59 | h: 32, 60 | text: "Effect:", 61 | text_size: 17, 62 | color: 0xffffff, 63 | align_h: hmUI.align.LEFT, 64 | }); 65 | 66 | const effectText = this.createWidget(hmUI.widget.TEXT, { 67 | x: 10 + DEVICE_WIDTH / 3, 68 | y: this.state.y, 69 | w: DEVICE_WIDTH / 3 * 2 - 20, 70 | h: 32, 71 | text: this.state.item.attributes.effect, 72 | text_size: 17, 73 | color: 0xffffff, 74 | align_h: hmUI.align.RIGHT, 75 | }); 76 | this.state.y += 32 77 | 78 | const dataList = this.state.item.attributes.effect_list.map((item) => { return { name: item } }) 79 | 80 | function scrollListItemClick(list, index, ctx) { 81 | effectText.setProperty(hmUI.prop.TEXT, dataList[index].name) 82 | 83 | list.setProperty(hmUI.prop.UPDATE_DATA, { 84 | data_type_config: [ 85 | { 86 | start: 0, 87 | end: index - 1, 88 | type_id: 0 89 | }, 90 | { 91 | start: index, 92 | end: index, 93 | type_id: 1 94 | }, 95 | { 96 | start: index + 1, 97 | end: dataList.length, 98 | type_id: 0 99 | }, 100 | ], 101 | data_type_config_count: 3, 102 | data_array: dataList, 103 | data_count: dataList.length, 104 | on_page: 1 105 | }) 106 | 107 | if (ctx.state.rendered) { 108 | messageBuilder.request( 109 | { 110 | method: "LIGHT_SET", 111 | entity_id: ctx.state.item.key, 112 | value: `{"effect": "${dataList[index].name}"}`, 113 | service: ctx.state.item.type 114 | }); 115 | } 116 | } 117 | 118 | 119 | 120 | const effectList = hmUI.createWidget(hmUI.widget.SCROLL_LIST, { 121 | x: 10, 122 | y: this.state.y + 20, 123 | h: DEVICE_HEIGHT - this.state.y - 20, 124 | w: DEVICE_WIDTH - 20, 125 | item_space: 10, 126 | item_config: [ 127 | { 128 | type_id: 0, 129 | item_bg_color: 0x101010, 130 | item_bg_radius: 10, 131 | text_view: [ 132 | { x: 10, y: 16, w: DEVICE_WIDTH - 40, h: 32, key: 'name', color: 0xffffff, text_size: 18 }, 133 | ], 134 | text_view_count: 1, 135 | item_height: 64 136 | }, 137 | { 138 | type_id: 1, 139 | item_bg_color: 0x262626, 140 | item_bg_radius: 10, 141 | text_view: [ 142 | { x: 10, y: 16, w: DEVICE_WIDTH - 40, h: 32, key: 'name', color: 0xffffff, text_size: 18 }, 143 | ], 144 | text_view_count: 1, 145 | item_height: 64 146 | }, 147 | ], 148 | item_config_count: 2, 149 | data_array: dataList, 150 | data_count: dataList.length, 151 | item_click_func: (list,index) => scrollListItemClick(list, index, this), 152 | data_type_config_count: 1 153 | }) 154 | 155 | scrollListItemClick(effectList, this.state.item.attributes.effect_list.indexOf(this.state.item.attributes.effect), this) 156 | } 157 | else { 158 | hmApp.goBack() 159 | } 160 | 161 | this.state.rendered = true; 162 | }, 163 | onInit(param) { 164 | logger.log('onInit') 165 | logger.log("param", param) 166 | this.state.item = JSON.parse(param) 167 | this.drawElements() 168 | }, 169 | build() { }, 170 | onDestroy() { 171 | hmUI.setStatusBarVisible(false); 172 | } 173 | }); -------------------------------------------------------------------------------- /page/light/index.page.js: -------------------------------------------------------------------------------- 1 | import { DEVICE_HEIGHT, DEVICE_WIDTH, TOP_BOTTOM_OFFSET } from "../home/index.style"; 2 | import { createProgressBar } from "../../controls/progressBar"; 3 | import { nativeSlider } from "../../controls/nativeSlider"; 4 | const { messageBuilder } = getApp()._options.globalData; 5 | const logger = DeviceRuntimeCore.HmLogger.getLogger("ha-zepp-light"); 6 | 7 | Page({ 8 | state: { 9 | y: TOP_BOTTOM_OFFSET, 10 | item: null, 11 | widgets: [], 12 | nativeSlider: null, 13 | brightnessBar: null, 14 | sliderText: null, 15 | rendered: false, 16 | reloadTimer: null 17 | }, 18 | addWidgets(widgets) { 19 | this.state.widgets.push(...widgets); 20 | }, 21 | createWidget(...args) { 22 | const widget = hmUI.createWidget(...args); 23 | this.state.widgets.push(widget); 24 | return widget; 25 | }, 26 | clearWidgets() { 27 | this.state.widgets.forEach((widget, index) => { 28 | hmUI.deleteWidget(widget); 29 | }); 30 | this.state.widgets = []; 31 | this.state.rendered = false; 32 | this.state.y = TOP_BOTTOM_OFFSET; // start from this y to skip rounded border 33 | hmUI.redraw(); 34 | }, 35 | drawTextMessage(message, button) { 36 | this.clearWidgets(); 37 | this.createWidget(hmUI.widget.TEXT, { 38 | x: 0, 39 | y: 0, 40 | w: DEVICE_WIDTH, 41 | h: DEVICE_HEIGHT, 42 | text: message, 43 | text_size: 18, 44 | color: 0xffffff, 45 | align_h: hmUI.align.CENTER_H, 46 | align_v: hmUI.align.CENTER_V, 47 | }); 48 | return; 49 | }, 50 | drawWait() { 51 | //return this.drawTextMessage(`Loading...\n${this.state.item.title}`); 52 | return this.createWidget(hmUI.widget.IMG_ANIM, { 53 | anim_path: 'loading', 54 | anim_prefix: 'loading', 55 | anim_ext: 'png', 56 | anim_fps: 30, 57 | anim_size: 60, 58 | repeat_count: 0, 59 | anim_status: hmUI.anim_status.START, 60 | x: DEVICE_WIDTH / 2 - 150/2, 61 | y: DEVICE_HEIGHT / 2 - 150/2, 62 | }); 63 | }, 64 | drawError(message) { 65 | let text = "An error occurred"; 66 | if (typeof message === 'string') { 67 | text += ':\n'; 68 | text += message; 69 | } 70 | return this.drawTextMessage(text); 71 | }, 72 | getEntityInfo() { 73 | messageBuilder 74 | .request({ method: "GET_ENTITY", entity_id: this.state.item.key }) 75 | .then(({ result, error }) => { 76 | if (error) { 77 | this.drawError(error); 78 | return; 79 | } 80 | this.state.item = result; 81 | this.drawElements(); 82 | }) 83 | .catch((res) => { 84 | this.drawError(); 85 | console.log(res); 86 | }); 87 | }, 88 | drawSlider() { 89 | const titleHeight = 32; 90 | /* brightness slider */ 91 | this.createWidget(hmUI.widget.TEXT, { 92 | x: 10, 93 | y: this.state.y, 94 | w: DEVICE_WIDTH / 3 * 2, 95 | h: titleHeight, 96 | text: "Brightness:", 97 | text_size: 17, 98 | color: 0xffffff, 99 | align_h: hmUI.align.LEFT, 100 | }); 101 | 102 | this.state.sliderText = this.createWidget(hmUI.widget.TEXT, { 103 | x: DEVICE_WIDTH / 3 * 2 + 10, 104 | y: this.state.y, 105 | w: DEVICE_WIDTH / 3 - 20, 106 | h: titleHeight, 107 | text: "50%", 108 | text_size: 17, 109 | color: 0xffffff, 110 | align_h: hmUI.align.RIGHT, 111 | }); 112 | this.state.y += titleHeight + 10 113 | 114 | this.state.nativeSlider = nativeSlider({ 115 | ctx: this, 116 | onSliderMove: (ctx, floatpos, isUserInput) => { 117 | logger.log("nativeslider input", floatpos) 118 | 119 | value_pct = Math.round(floatpos * 100) 120 | ctx.state.sliderText.setProperty(hmUI.prop.MORE, { text: value_pct.toString() + "%" }) 121 | ctx.state.brightnessBar.setPosition(floatpos); 122 | if (ctx.state.rendered && isUserInput) 123 | messageBuilder.request( 124 | { 125 | method: "LIGHT_SET", 126 | entity_id: ctx.state.item.key, 127 | value: `{"brightness_pct": ${value_pct}}`, 128 | service: ctx.state.item.type 129 | }); 130 | }, 131 | stateImages: ["brightness_min_1.png", "brightness_min_2.png", "brightness_mid.png", "brightness_mid.png", "brightness_max.png", "brightness_max.png"], 132 | backColor: 0x303030, 133 | frontColor: 0xf0f0f0 134 | }) 135 | 136 | this.state.brightnessBar = createProgressBar( 137 | { 138 | x: 10, 139 | y: this.state.y, 140 | h: 24, 141 | w: DEVICE_WIDTH - 20, 142 | backColor: 0x262626, 143 | frontColor: 0xffffff, 144 | src: "brightness_up.png", 145 | ctx: this, 146 | onClick: (ctx) => { 147 | if (!ctx.state.rendered) return 148 | 149 | ctx.state.nativeSlider.show() 150 | ctx.state.nativeSlider.setPosition(this.state.item.attributes.brightness / 100) 151 | } 152 | }) 153 | this.state.y += 24 + 20 154 | 155 | this.state.brightnessBar.setPosition(this.state.item.attributes.brightness / 100) 156 | 157 | this.addWidgets(this.state.brightnessBar.components) 158 | }, 159 | drawColorWheel() { 160 | const titleHeight = 32; 161 | const rectSize = 24 162 | this.createWidget(hmUI.widget.TEXT, { 163 | x: 10, 164 | y: this.state.y, 165 | w: DEVICE_WIDTH - rectSize * 2 - 10, 166 | h: titleHeight, 167 | text: "Color:", 168 | text_size: 17, 169 | color: 0xffffff, 170 | align_h: hmUI.align.LEFT, 171 | }); 172 | const color = this.state.item.attributes.rgb_color 173 | this.createWidget(hmUI.widget.FILL_RECT, { 174 | x: DEVICE_WIDTH - rectSize * 2 - 10, 175 | y: this.state.y + titleHeight / 2 - rectSize / 2, 176 | w: rectSize * 2, 177 | h: rectSize, 178 | radius: rectSize / 2, 179 | color: color[0] << 16 | color[1] << 8 | color[2] 180 | }) 181 | 182 | this.state.y += titleHeight + 10 183 | }, 184 | drawElements() { 185 | this.state.rendered = false; 186 | this.clearWidgets() 187 | 188 | if (typeof this.state.item !== 'object') { 189 | this.drawError("Wrong entity data " + typeof this.state.item) 190 | return; 191 | } 192 | 193 | const titleHeight = 40; 194 | const valueHeight = 48; 195 | 196 | this.createWidget(hmUI.widget.TEXT, { 197 | x: 0, 198 | y: this.state.y, 199 | w: DEVICE_WIDTH, 200 | h: titleHeight, 201 | text: this.state.item.title, 202 | text_size: 19, 203 | color: 0xffffff, 204 | align_h: hmUI.align.CENTER_H, 205 | }); 206 | this.state.y += titleHeight 207 | 208 | this.createWidget(hmUI.widget.SLIDE_SWITCH, { 209 | x: DEVICE_WIDTH / 2 - 76 / 2, 210 | y: this.state.y, 211 | w: DEVICE_WIDTH, 212 | h: valueHeight, 213 | select_bg: "switch_on.png", 214 | un_select_bg: "switch_off.png", 215 | slide_src: "radio_select.png", 216 | slide_select_x: 32, 217 | slide_un_select_x: 8, 218 | checked: this.state.item.state === "on" ? true : false, 219 | checked_change_func: (slideSwitch, checked) => { 220 | if (!this.state.rendered) return; 221 | messageBuilder.request({ method: "TOGGLE_SWITCH", entity_id: this.state.item.key, value: checked, service: this.state.item.type }); 222 | this.state.reloadTimer = timer.createTimer( 223 | 2000, 224 | 10000, 225 | function (page) { 226 | timer.stopTimer(page.state.reloadTimer) 227 | page.state.reloadTimer = null 228 | page.clearWidgets() 229 | page.drawWait() 230 | page.getEntityInfo() 231 | }, 232 | this 233 | ) 234 | }, 235 | }); 236 | this.state.y += valueHeight + 10 237 | 238 | 239 | if (typeof this.state.item.attributes.brightness === 'number') { 240 | this.drawSlider() 241 | } 242 | 243 | if (this.state.item.attributes.rgb_color) { 244 | this.drawColorWheel() 245 | } 246 | 247 | if (this.state.item.attributes.effect) { 248 | this.createWidget(hmUI.widget.TEXT, { 249 | x: 10, 250 | y: this.state.y, 251 | w: DEVICE_WIDTH / 3, 252 | h: 32, 253 | text: "Effect:", 254 | text_size: 17, 255 | color: 0xffffff, 256 | align_h: hmUI.align.LEFT, 257 | }); 258 | 259 | const effectText = this.createWidget(hmUI.widget.TEXT, { 260 | x: 10 + DEVICE_WIDTH / 3, 261 | y: this.state.y, 262 | w: DEVICE_WIDTH / 3 * 2 - 20, 263 | h: 32, 264 | text: this.state.item.attributes.effect, 265 | text_size: 17, 266 | color: 0xffffff, 267 | align_h: hmUI.align.RIGHT, 268 | }); 269 | 270 | effectText.addEventListener(hmUI.event.CLICK_DOWN, (info) => { 271 | hmApp.gotoPage({ file: `page/light/effectPicker.page`, param: JSON.stringify(this.state.item) }) 272 | }) 273 | } 274 | 275 | if (Object.keys(this.state.item.attributes).length === 0) { 276 | this.createWidget(hmUI.widget.TEXT, { 277 | x: 0, 278 | y: this.state.y, 279 | w: DEVICE_WIDTH, 280 | h: DEVICE_HEIGHT - this.state.y, 281 | text: "Nothing here because the light is off", 282 | text_size: 18, 283 | color: 0xffffff, 284 | align_h: hmUI.align.CENTER_H, 285 | align_v: hmUI.align.CENTER_V 286 | }); 287 | } 288 | 289 | this.state.rendered = true; 290 | }, 291 | onDataSave() { 292 | 293 | }, 294 | onInit(param) { 295 | logger.log('onInit') 296 | this.state.item = JSON.parse(param) 297 | this.drawWait() 298 | this.getEntityInfo() 299 | }, 300 | build() { 301 | hmUI.setLayerScrolling(false); 302 | }, 303 | onDestroy() { 304 | hmUI.setStatusBarVisible(false); 305 | } 306 | }); -------------------------------------------------------------------------------- /page/test_page/index.page.js: -------------------------------------------------------------------------------- 1 | import { DEVICE_HEIGHT, DEVICE_WIDTH, TOP_BOTTOM_OFFSET } from "../home/index.style"; 2 | import { createSlider } from "../../controls/slider"; 3 | import { nativeSlider } from "../../controls/nativeSlider"; 4 | const logger = DeviceRuntimeCore.HmLogger.getLogger("ha-zepp-testpage"); 5 | 6 | Page({ 7 | state: { 8 | y: TOP_BOTTOM_OFFSET, 9 | widgets: [], 10 | rendered: false 11 | }, 12 | createWidget(...args) { 13 | const widget = hmUI.createWidget(...args); 14 | this.state.widgets.push(widget); 15 | return widget; 16 | }, 17 | addWidget(widget) { 18 | this.state.widgets.push(widget); 19 | }, 20 | destroyTimers() { 21 | }, 22 | clearWidgets() { 23 | this.state.widgets.forEach((widget, index) => { 24 | hmUI.deleteWidget(widget); 25 | }); 26 | this.state.widgets = []; 27 | this.state.rendered = false; 28 | this.state.y = TOP_BOTTOM_OFFSET; // start from this y to skip rounded border 29 | // hmUI.redraw(); 30 | }, 31 | drawSlider() { 32 | const titleHeight = 32; 33 | /* brightness slider */ 34 | this.createWidget(hmUI.widget.TEXT, { 35 | x: 10, 36 | y: this.state.y, 37 | w: DEVICE_WIDTH / 3 * 2, 38 | h: titleHeight, 39 | text: "Value", 40 | text_size: 17, 41 | color: 0xffffff, 42 | align_h: hmUI.align.LEFT, 43 | }); 44 | 45 | const sliderText = this.createWidget(hmUI.widget.TEXT, { 46 | x: DEVICE_WIDTH / 3 * 2 + 10, 47 | y: this.state.y, 48 | w: DEVICE_WIDTH / 3 - 20, 49 | h: titleHeight, 50 | text: "50%", 51 | text_size: 17, 52 | color: 0xffffff, 53 | align_h: hmUI.align.RIGHT, 54 | }); 55 | this.state.y += titleHeight + 10 56 | 57 | const brightnessSlider = createSlider( 58 | { 59 | h: 12, 60 | w: 150, 61 | x: DEVICE_WIDTH / 2 - 150 / 2, 62 | y: this.state.y, 63 | backColor: 0x0884d0, 64 | frontColor: 0xffffff, 65 | hasPoint: true, 66 | ctx: this, 67 | onSliderMove: (ctx, floatvalue, isUserInput) => { 68 | floatvalue = Math.round(floatvalue * 100) 69 | sliderText.setProperty(hmUI.prop.MORE, { text: floatvalue.toString() + "%" }) 70 | if (ctx.state.rendered && isUserInput) 71 | console.log("userinput", floatvalue) 72 | } 73 | }) 74 | this.state.y += 12 * 2 + 20 75 | 76 | brightnessSlider.setPosition(0.5) 77 | 78 | this.addWidget(brightnessSlider.components) 79 | }, 80 | drawTextMessage(message, button) { 81 | this.clearWidgets(); 82 | this.createWidget(hmUI.widget.TEXT, { 83 | x: 0, 84 | y: 0, 85 | w: DEVICE_WIDTH, 86 | h: DEVICE_HEIGHT, 87 | text: message, 88 | text_size: 18, 89 | color: 0xffffff, 90 | align_h: hmUI.align.CENTER_H, 91 | align_v: hmUI.align.CENTER_V, 92 | }); 93 | return; 94 | }, 95 | drawError(message) { 96 | let text = "An error occurred"; 97 | if (typeof message === 'string') { 98 | text += ':\n'; 99 | text += message; 100 | } 101 | return this.drawTextMessage(text); 102 | }, 103 | drawElements() { 104 | this.state.rendered = false; 105 | this.clearWidgets() 106 | 107 | this.drawSlider() 108 | 109 | const volumeSlider = createSlider( 110 | { 111 | h: 12, 112 | w: 150, 113 | x: DEVICE_WIDTH / 2 - 150 / 2, 114 | y: this.state.y, 115 | backColor: 0x262626, 116 | frontColor: 0xffffff, 117 | hasPoint: false, 118 | ctx: this, 119 | onSliderMove: (ctx, floatvalue, isUserInput) => { 120 | if (ctx.state.rendered && isUserInput) 121 | console.log("userinput", floatvalue) 122 | } 123 | }) 124 | this.state.y += 12 * 2 + 20 125 | this.addWidget(volumeSlider.components) 126 | 127 | const buttonSlider = createSlider( 128 | { 129 | h: 24, 130 | w: 150, 131 | x: DEVICE_WIDTH / 2 - 150 / 2, 132 | y: this.state.y, 133 | backColor: 0x262626, 134 | frontColor: 0xffffff, 135 | hasPoint: false, 136 | buttons: { img_down: "brightness_down.png", img_up: "brightness_up.png", change_amt: 0.1 }, 137 | ctx: this, 138 | onSliderMove: (ctx, floatvalue, isUserInput) => { 139 | if (ctx.state.rendered && isUserInput) 140 | console.log("userinput", floatvalue) 141 | } 142 | }) 143 | this.state.y += 12 * 2 + 20 144 | this.addWidget(buttonSlider.components) 145 | 146 | const nativeslider = nativeSlider({ 147 | ctx: this, 148 | onSliderMove: (ctx, floatpos, isUserInput) => { 149 | console.log("nativeslider input", floatpos) 150 | }, 151 | stateImages: ["volume_min_1.png", "volume_min_2.png", "volume_mid.png", "volume_mid.png", "volume_max.png", "volume_max.png"], 152 | button: { 153 | onButtonToggle: (ctx, newValue) => { console.log("nativeSlider button", newValue) }, 154 | image: "volume_off.png" 155 | }, 156 | backColor: 0x303030, 157 | frontColor: 0xf0f0f0 158 | }) 159 | 160 | this.createWidget(hmUI.widget.BUTTON, { 161 | x: 0, 162 | y: this.state.y, 163 | w: DEVICE_WIDTH, 164 | h: TOP_BOTTOM_OFFSET, 165 | text: "Native slider", 166 | click_func: () => { 167 | nativeslider.show() 168 | nativeslider.setPosition(0.23) 169 | } 170 | }); 171 | 172 | this.state.rendered = true; 173 | }, 174 | onInit() { 175 | logger.log('onInit') 176 | 177 | hmUI.setLayerScrolling(false); 178 | this.drawElements() 179 | }, 180 | build() { }, 181 | onDestroy() { } 182 | }); -------------------------------------------------------------------------------- /setting/index.js: -------------------------------------------------------------------------------- 1 | import { gettext } from 'i18n' 2 | 3 | AppSettingsPage({ 4 | state: { 5 | entityList: [], 6 | props: {}, 7 | }, 8 | setState(props) { 9 | this.state.props = props; 10 | if (props.settingsStorage.getItem("entityList")) { 11 | this.state.entityList = JSON.parse( 12 | props.settingsStorage.getItem("entityList") 13 | ); 14 | } else { 15 | this.state.entityList = []; 16 | console.log("Initialized"); 17 | } 18 | }, 19 | setItem() { 20 | const newStr = JSON.stringify(this.state.entityList); 21 | this.state.props.settingsStorage.setItem("entityList", newStr); 22 | }, 23 | toggleEntity(key, val) { 24 | const newEntityList = this.state.entityList.map((_item) => { 25 | const item = _item; 26 | if (item.key === key) { 27 | item.value = val; 28 | } 29 | return item; 30 | }); 31 | this.state.entityList = newEntityList; 32 | this.setItem(); 33 | }, 34 | moveEntityToTop(index) { 35 | entity = this.state.entityList[index]; 36 | this.state.entityList = this.state.entityList.filter((_, ind) => { 37 | return ind !== index 38 | }) 39 | this.state.entityList.unshift(entity); 40 | this.setItem() 41 | }, 42 | build(props) { 43 | this.setState(props); 44 | const textInputStyle = { 45 | marginTop: "4px", 46 | color: "#000000", 47 | fontSize: "15px", 48 | borderStyle: "solid", 49 | borderColor: "#000000", 50 | borderRadius: "2px", 51 | height: "28px", 52 | width: "50%", 53 | overflow: "hidden", 54 | borderWidth: "2px", 55 | }; 56 | let entityList = []; 57 | let filter = props.settingsStorage.getItem("filter") 58 | this.state.entityList.forEach((item, i) => { 59 | if ( 60 | !item.key.startsWith('light.') && 61 | !item.key.startsWith('switch.') && 62 | !item.key.startsWith('input_boolean.') && 63 | !item.key.startsWith('binary_sensor.') && 64 | !item.key.startsWith('sensor.') && 65 | !item.key.startsWith('media_player.') && 66 | !item.key.startsWith('script.') && 67 | !item.key.startsWith('automation.') 68 | ) { 69 | return; 70 | } 71 | if(!item.key.includes(filter)) { 72 | return; 73 | } 74 | entityList.push( 75 | View({ 76 | style: { 77 | position: 'relative', 78 | display: 'flex', 79 | borderBottom: "1px solid #eaeaea", 80 | padding: "6px 0", 81 | marginBottom: '6px' 82 | }}, 83 | [ 84 | View({ style: { width: "70%" }}, 85 | Toggle({ 86 | label: `${item.title} (${item.key})`, 87 | value: item.value, 88 | onChange: this.toggleEntity.bind(this, item.key), 89 | }) 90 | ), 91 | View({ style: { flex: 1 }}, 92 | Button({ 93 | label: gettext('^'), 94 | style: { 95 | position: 'absolute', 96 | bottom: '10px', 97 | right: '0px', 98 | minWidth: '32px', 99 | height: '10px', 100 | borderRadius: '60px', 101 | background: '#18BCF2', 102 | color: 'white' 103 | }, 104 | onClick: () => { 105 | this.moveEntityToTop(i) 106 | } 107 | }), 108 | ) 109 | ]) 110 | ); 111 | }); 112 | return Section({}, [ 113 | TextInput({ 114 | label: 'Local HA instance address:', 115 | settingsKey: "localHAIP", 116 | subStyle: textInputStyle, 117 | }), 118 | TextInput({ 119 | label: "External HA instance address:", 120 | settingsKey: "externalHAIP", 121 | subStyle: textInputStyle, 122 | }), 123 | TextInput({ 124 | label: "Long access token:", 125 | settingsKey: "HAToken", 126 | subStyle: textInputStyle, 127 | }), 128 | TextInput({ 129 | label: "Filter entities id:", 130 | subStyle: textInputStyle, 131 | settingsKey: "filter", 132 | }), 133 | Section( 134 | { style: {width: '50%'} }, 135 | Toggle({ 136 | label: "Update sensor data to HA, interval 1 hour (BETA)" + 137 | "(works best if you turn all notifications OFF, this includes the calendar sync)", 138 | value: (props.settingsStorage.getItem("updateSensorsBool") === "true"), 139 | onChange: (value) => { 140 | props.settingsStorage.setItem("updateSensorsBool", value); 141 | }, 142 | }) 143 | ), 144 | Section( 145 | {}, 146 | Button({ 147 | label: "Refresh entities", 148 | async onClick() { 149 | props.settingsStorage.removeItem("entityList"); 150 | props.settingsStorage.setItem("listFetchRandom", Math.random()); 151 | return; 152 | }, 153 | }) 154 | ), 155 | Text({}, "Only the media player, light, switch, input_boolean, script, automation and (binary) " + 156 | "sensor entities are supported for now:"), 157 | entityList.length > 0 && 158 | View( 159 | { 160 | style: { 161 | marginTop: "12px", 162 | padding: "10px", 163 | border: "1px solid #eaeaea", 164 | borderRadius: "6px", 165 | backgroundColor: "white", 166 | }, 167 | }, 168 | entityList 169 | ), 170 | ]); 171 | }, 172 | }); 173 | -------------------------------------------------------------------------------- /shared/buffer.js: -------------------------------------------------------------------------------- 1 | import { getGlobal } from './global' 2 | 3 | let globalNS = getGlobal() 4 | 5 | if (!globalNS.Buffer) { 6 | if (typeof Buffer !== 'undefined') { 7 | globalNS.Buffer = Buffer 8 | } else { 9 | globalNS.Buffer = DeviceRuntimeCore.Buffer 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /shared/data.js: -------------------------------------------------------------------------------- 1 | export function json2Buf(json) { 2 | return str2buf(json2str(json)) 3 | } 4 | 5 | export function len(binOrBuf) { 6 | return binOrBuf.byteLength 7 | } 8 | 9 | export function buf2Json(buf) { 10 | return str2json(buf2str(buf)) 11 | } 12 | 13 | export function str2json(str) { 14 | return JSON.parse(str) 15 | } 16 | 17 | export function json2str(json) { 18 | return JSON.stringify(json) 19 | } 20 | 21 | export function str2buf(str) { 22 | return Buffer.from(str, 'utf-8') 23 | } 24 | 25 | export function buf2str(buf) { 26 | return buf.toString('utf-8') 27 | } 28 | 29 | export function bin2buf(bin) { 30 | return Buffer.from(bin) 31 | } 32 | 33 | export function buf2bin(buf) { 34 | return buf.buffer 35 | } 36 | 37 | export function buf2hex(buf) { 38 | return buf.toString('hex') 39 | } 40 | 41 | export function bin2hex(bin) { 42 | return buf2hex(bin2buf(bin)) 43 | } 44 | 45 | export function bin2json(bin) { 46 | return buf2Json(bin2buf(bin)) 47 | } 48 | 49 | export function bin2str(bin) { 50 | return buf2str(bin2buf(bin)) 51 | } 52 | 53 | export function str2bin(str) { 54 | return buf2bin(str2buf(str)) 55 | } 56 | 57 | export function allocOfBin(size = 0) { 58 | return Buffer.alloc(size).buffer 59 | } 60 | 61 | export function allocOfBuf(size = 0) { 62 | return Buffer.alloc(size) 63 | } 64 | -------------------------------------------------------------------------------- /shared/defer.js: -------------------------------------------------------------------------------- 1 | export function Deferred() { 2 | const defer = {} 3 | 4 | defer.promise = new Promise(function (resolve, reject) { 5 | defer.resolve = resolve 6 | defer.reject = reject 7 | }) 8 | 9 | return defer 10 | } 11 | 12 | export function delay(ms) { 13 | const defer = Deferred() 14 | 15 | setTimeout(defer.resolve, ms) 16 | 17 | return defer.promise 18 | } 19 | 20 | export function timeout(ms, cb) { 21 | const defer = Deferred() 22 | ms = ms || 1000 23 | 24 | const wait = setTimeout(() => { 25 | clearTimeout(wait) 26 | 27 | if (cb) { 28 | cb && cb(defer.resolve, defer.reject) 29 | } else { 30 | defer.reject('Timed out in ' + ms + 'ms.') 31 | } 32 | }, ms) 33 | 34 | return defer.promise 35 | } 36 | -------------------------------------------------------------------------------- /shared/device-polyfill.js: -------------------------------------------------------------------------------- 1 | import './logger' 2 | import './buffer' 3 | import './setTimeout' 4 | import './promise' 5 | -------------------------------------------------------------------------------- /shared/event.js: -------------------------------------------------------------------------------- 1 | export class EventBus { 2 | constructor() { 3 | this.map = new Map() 4 | } 5 | 6 | on(type, cb) { 7 | if (this.map.has(type)) { 8 | this.map.get(type).push(cb) 9 | } else { 10 | this.map.set(type, [cb]) 11 | } 12 | } 13 | 14 | off(type, cb) { 15 | if (type) { 16 | if (cb) { 17 | const cbs = this.map.get(type) 18 | 19 | if (!cbs) return 20 | const index = cbs.findIndex((i) => i === cb) 21 | 22 | if (index >= 0) { 23 | cbs.splice(index, 1) 24 | } 25 | } else { 26 | this.map.delete(type) 27 | } 28 | } else { 29 | this.map.clear() 30 | } 31 | } 32 | 33 | emit(type, ...args) { 34 | for (let cb of this.map.get(type) ? this.map.get(type) : []) { 35 | cb && cb(...args) 36 | } 37 | } 38 | 39 | count(type) { 40 | return this.map.get(type) ? this.map.get(type).length : 0 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /shared/fs.js: -------------------------------------------------------------------------------- 1 | const logger = DeviceRuntimeCore.HmLogger.getLogger('fs.js') 2 | 3 | function ab2str(buf) { 4 | return String.fromCharCode.apply(null, new Uint16Array(buf)) 5 | } 6 | 7 | function str2ab(str) { 8 | var buf = new ArrayBuffer(str.length * 2) // 2 bytes for each char 9 | var bufView = new Uint16Array(buf) 10 | for (var i = 0, strLen = str.length; i < strLen; i++) { 11 | bufView[i] = str.charCodeAt(i) 12 | } 13 | return buf 14 | } 15 | 16 | /** 17 | * Get metadata of a file. 18 | * @param {} filename 19 | * @returns 20 | */ 21 | export function statSync(filename) { 22 | logger.log('statSync', filename) 23 | const [fs_stat, err] = hmFS.stat(filename) 24 | logger.log('res', fs_stat, err) 25 | if (err == 0) { 26 | logger.log('fs--->size:', fs_stat.size) 27 | return fs_stat 28 | } else { 29 | logger.log('fs--->err:', err) 30 | return null 31 | } 32 | } 33 | 34 | /** 35 | * Write data to a file in a single operation. If a file with that name already exists, it is overwritten; otherwise, a new file is created. 36 | * @param {*} filename 37 | * @param {*} data 38 | * @param {*} options 39 | */ 40 | export function writeFileSync(filename, data, options) { 41 | logger.log('writeFileSync begin -->', filename) 42 | 43 | const stringBuffer = str2ab(data) 44 | const source_buf = new Uint8Array(stringBuffer) 45 | 46 | const file = hmFS.open(filename, hmFS.O_CREAT | hmFS.O_RDWR | hmFS.O_TRUNC) 47 | logger.log('writeFileSync file open success -->', file) 48 | hmFS.seek(file, 0, hmFS.SEEK_SET) 49 | hmFS.write(file, source_buf.buffer, 0, source_buf.length) 50 | hmFS.close(file) 51 | logger.log('writeFileSync success -->', filename) 52 | } 53 | 54 | /** 55 | * Read an entire file into a buffer in a single operation. 56 | * @param {*} filename 57 | * @param {*} options 58 | * @returns 59 | */ 60 | export function readFileSync(filename, options) { 61 | logger.log('readFileSync fiename:', filename) 62 | 63 | const fs_stat = statSync(filename) 64 | if (!fs_stat) return undefined 65 | 66 | const destination_buf = new Uint8Array(fs_stat.size) 67 | const file = hmFS.open(filename, hmFS.O_RDONLY) 68 | 69 | hmFS.seek(file, 0, hmFS.SEEK_SET) 70 | hmFS.read(file, destination_buf.buffer, 0, fs_stat.size) 71 | hmFS.close(file) 72 | 73 | const content = ab2str(destination_buf.buffer) 74 | logger.log('readFileSync', content) 75 | return content 76 | } 77 | 78 | /** 79 | * Delete a file. 80 | * @param {*} filename 81 | */ 82 | export function unlinkSync(filename) { 83 | logger.log('unlinkSync begin -->', filename) 84 | const result = hmFS.remove(filename) 85 | logger.log('unlinkSync result -->', result) 86 | return result 87 | } 88 | 89 | /** 90 | * Rename a file. 91 | * @param {*} filename 92 | */ 93 | export function renameSync(oldFilename, newFilename) { 94 | logger.log('renameSync begin -->', filename) 95 | hmFS.rename(oldFilename, newFilename) 96 | logger.log('renameSync success -->', filename) 97 | } 98 | 99 | /** 100 | * Synchronously creates a directory. 101 | * @param {*} path 102 | * @param {*} options 103 | */ 104 | export function mkdirSync(path, options) { 105 | logger.log('mkdirSync begin -->', path) 106 | hmFS.mkdir(path) 107 | logger.log('mkdirSync success -->', path) 108 | } 109 | 110 | /** 111 | * Reads the contents of the directory. 112 | * @param {*} path 113 | * @param {*} options 114 | */ 115 | export function readdirSync(path, options) { 116 | logger.log('readdirSync begin -->', path) 117 | hmFS.readdirSync(path) 118 | logger.log('readdirSync success -->', path) 119 | } 120 | 121 | /** 122 | * Just to test the fs module 123 | */ 124 | export function test(fileName, dataString) { 125 | logger.log('saveData begin') 126 | 127 | writeFileSync(fileName, dataString) 128 | 129 | logger.log('fs_writeFileSync -> ', dataString) 130 | 131 | const content = readFileSync(fileName) 132 | 133 | logger.log('fs_readFileSync -> ', content) 134 | } 135 | -------------------------------------------------------------------------------- /shared/global.js: -------------------------------------------------------------------------------- 1 | export function getGlobal() { 2 | if (typeof self !== 'undefined') { 3 | return self 4 | } 5 | if (typeof window !== 'undefined') { 6 | return window 7 | } 8 | if (typeof global !== 'undefined') { 9 | return global 10 | } 11 | if (typeof globalThis !== 'undefined') { 12 | return globalThis 13 | } 14 | 15 | throw new Error('unable to locate global object') 16 | } 17 | -------------------------------------------------------------------------------- /shared/js-module.js: -------------------------------------------------------------------------------- 1 | export function isHmUIDefined() { 2 | return typeof hmUI !== 'undefined' 3 | } 4 | 5 | export function isHmBleDefined() { 6 | return typeof hmBle !== 'undefined' 7 | } 8 | 9 | export function isHmTimerDefined() { 10 | return typeof timer !== 'undefined' 11 | } 12 | 13 | export function isHmFsDefined() { 14 | return typeof hmFS !== 'undefined' 15 | } 16 | 17 | export function isHmAppDefined() { 18 | return typeof hmApp !== 'undefined' 19 | } 20 | 21 | export function isHmSensorDefined() { 22 | return typeof hmSensor !== 'undefined' 23 | } 24 | 25 | export function isHmSettingDefined() { 26 | return typeof hmSetting !== 'undefined' 27 | } 28 | -------------------------------------------------------------------------------- /shared/logger.js: -------------------------------------------------------------------------------- 1 | import { getGlobal } from './global' 2 | 3 | let globalNS = getGlobal() 4 | 5 | if (!globalNS.Logger && typeof DeviceRuntimeCore !== 'undefined') { 6 | globalNS.Logger = DeviceRuntimeCore.HmLogger 7 | } 8 | -------------------------------------------------------------------------------- /shared/promise.js: -------------------------------------------------------------------------------- 1 | ;(function (global, factory) { 2 | typeof exports === 'object' && typeof module !== 'undefined' 3 | ? factory() 4 | : typeof define === 'function' && define.amd 5 | ? define(factory) 6 | : factory() 7 | })(globalThis, function () { 8 | 'use strict' 9 | 10 | /** 11 | * @this {Promise} 12 | */ 13 | function finallyConstructor(callback) { 14 | var constructor = this.constructor 15 | return this.then( 16 | function (value) { 17 | // @ts-ignore 18 | return constructor.resolve(callback()).then(function () { 19 | return value 20 | }) 21 | }, 22 | function (reason) { 23 | // @ts-ignore 24 | return constructor.resolve(callback()).then(function () { 25 | // @ts-ignore 26 | return constructor.reject(reason) 27 | }) 28 | }, 29 | ) 30 | } 31 | 32 | function allSettled(arr) { 33 | var P = this 34 | return new P(function (resolve, reject) { 35 | if (!(arr && typeof arr.length !== 'undefined')) { 36 | return reject( 37 | new TypeError( 38 | typeof arr + 39 | ' ' + 40 | arr + 41 | ' is not iterable(cannot read property Symbol(Symbol.iterator))', 42 | ), 43 | ) 44 | } 45 | var args = Array.prototype.slice.call(arr) 46 | if (args.length === 0) return resolve([]) 47 | var remaining = args.length 48 | 49 | function res(i, val) { 50 | if (val && (typeof val === 'object' || typeof val === 'function')) { 51 | var then = val.then 52 | if (typeof then === 'function') { 53 | then.call( 54 | val, 55 | function (val) { 56 | res(i, val) 57 | }, 58 | function (e) { 59 | args[i] = { status: 'rejected', reason: e } 60 | if (--remaining === 0) { 61 | resolve(args) 62 | } 63 | }, 64 | ) 65 | return 66 | } 67 | } 68 | args[i] = { status: 'fulfilled', value: val } 69 | if (--remaining === 0) { 70 | resolve(args) 71 | } 72 | } 73 | 74 | for (var i = 0; i < args.length; i++) { 75 | res(i, args[i]) 76 | } 77 | }) 78 | } 79 | 80 | // Store setTimeout reference so promise-polyfill will be unaffected by 81 | // other code modifying setTimeout (like sinon.useFakeTimers()) 82 | var setTimeoutFunc = setTimeout 83 | 84 | function isArray(x) { 85 | return Boolean(x && typeof x.length !== 'undefined') 86 | } 87 | 88 | function noop() {} 89 | 90 | // Polyfill for Function.prototype.bind 91 | function bind(fn, thisArg) { 92 | return function () { 93 | fn.apply(thisArg, arguments) 94 | } 95 | } 96 | 97 | /** 98 | * @constructor 99 | * @param {Function} fn 100 | */ 101 | function Promise(fn) { 102 | if (!(this instanceof Promise)) 103 | throw new TypeError('Promises must be constructed via new') 104 | if (typeof fn !== 'function') throw new TypeError('not a function') 105 | /** @type {!number} */ 106 | this._state = 0 107 | /** @type {!boolean} */ 108 | this._handled = false 109 | /** @type {Promise|undefined} */ 110 | this._value = undefined 111 | /** @type {!Array} */ 112 | this._deferreds = [] 113 | 114 | doResolve(fn, this) 115 | } 116 | 117 | function handle(self, deferred) { 118 | while (self._state === 3) { 119 | self = self._value 120 | } 121 | if (self._state === 0) { 122 | self._deferreds.push(deferred) 123 | return 124 | } 125 | self._handled = true 126 | Promise._immediateFn(function () { 127 | var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected 128 | if (cb === null) { 129 | ;(self._state === 1 ? resolve : reject)(deferred.promise, self._value) 130 | return 131 | } 132 | var ret 133 | try { 134 | ret = cb(self._value) 135 | } catch (e) { 136 | reject(deferred.promise, e) 137 | return 138 | } 139 | resolve(deferred.promise, ret) 140 | }) 141 | } 142 | 143 | function resolve(self, newValue) { 144 | try { 145 | // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure 146 | if (newValue === self) 147 | throw new TypeError('A promise cannot be resolved with itself.') 148 | if ( 149 | newValue && 150 | (typeof newValue === 'object' || typeof newValue === 'function') 151 | ) { 152 | var then = newValue.then 153 | if (newValue instanceof Promise) { 154 | self._state = 3 155 | self._value = newValue 156 | finale(self) 157 | return 158 | } else if (typeof then === 'function') { 159 | doResolve(bind(then, newValue), self) 160 | return 161 | } 162 | } 163 | self._state = 1 164 | self._value = newValue 165 | finale(self) 166 | } catch (e) { 167 | reject(self, e) 168 | } 169 | } 170 | 171 | function reject(self, newValue) { 172 | self._state = 2 173 | self._value = newValue 174 | finale(self) 175 | } 176 | 177 | function finale(self) { 178 | if (self._state === 2 && self._deferreds.length === 0) { 179 | Promise._immediateFn(function () { 180 | if (!self._handled) { 181 | Promise._unhandledRejectionFn(self._value) 182 | } 183 | }) 184 | } 185 | 186 | for (var i = 0, len = self._deferreds.length; i < len; i++) { 187 | handle(self, self._deferreds[i]) 188 | } 189 | self._deferreds = null 190 | } 191 | 192 | /** 193 | * @constructor 194 | */ 195 | function Handler(onFulfilled, onRejected, promise) { 196 | this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null 197 | this.onRejected = typeof onRejected === 'function' ? onRejected : null 198 | this.promise = promise 199 | } 200 | 201 | /** 202 | * Take a potentially misbehaving resolver function and make sure 203 | * onFulfilled and onRejected are only called once. 204 | * 205 | * Makes no guarantees about asynchrony. 206 | */ 207 | function doResolve(fn, self) { 208 | var done = false 209 | try { 210 | fn( 211 | function (value) { 212 | if (done) return 213 | done = true 214 | resolve(self, value) 215 | }, 216 | function (reason) { 217 | if (done) return 218 | done = true 219 | reject(self, reason) 220 | }, 221 | ) 222 | } catch (ex) { 223 | if (done) return 224 | done = true 225 | reject(self, ex) 226 | } 227 | } 228 | 229 | Promise.prototype['catch'] = function (onRejected) { 230 | return this.then(null, onRejected) 231 | } 232 | 233 | Promise.prototype.then = function (onFulfilled, onRejected) { 234 | // @ts-ignore 235 | var prom = new this.constructor(noop) 236 | 237 | handle(this, new Handler(onFulfilled, onRejected, prom)) 238 | return prom 239 | } 240 | 241 | Promise.prototype['finally'] = finallyConstructor 242 | 243 | Promise.all = function (arr) { 244 | return new Promise(function (resolve, reject) { 245 | if (!isArray(arr)) { 246 | return reject(new TypeError('Promise.all accepts an array')) 247 | } 248 | 249 | var args = Array.prototype.slice.call(arr) 250 | if (args.length === 0) return resolve([]) 251 | var remaining = args.length 252 | 253 | function res(i, val) { 254 | try { 255 | if (val && (typeof val === 'object' || typeof val === 'function')) { 256 | var then = val.then 257 | if (typeof then === 'function') { 258 | then.call( 259 | val, 260 | function (val) { 261 | res(i, val) 262 | }, 263 | reject, 264 | ) 265 | return 266 | } 267 | } 268 | args[i] = val 269 | if (--remaining === 0) { 270 | resolve(args) 271 | } 272 | } catch (ex) { 273 | reject(ex) 274 | } 275 | } 276 | 277 | for (var i = 0; i < args.length; i++) { 278 | res(i, args[i]) 279 | } 280 | }) 281 | } 282 | 283 | Promise.allSettled = allSettled 284 | 285 | Promise.resolve = function (value) { 286 | if (value && typeof value === 'object' && value.constructor === Promise) { 287 | return value 288 | } 289 | 290 | return new Promise(function (resolve) { 291 | resolve(value) 292 | }) 293 | } 294 | 295 | Promise.reject = function (value) { 296 | return new Promise(function (resolve, reject) { 297 | reject(value) 298 | }) 299 | } 300 | 301 | Promise.race = function (arr) { 302 | return new Promise(function (resolve, reject) { 303 | if (!isArray(arr)) { 304 | return reject(new TypeError('Promise.race accepts an array')) 305 | } 306 | 307 | for (var i = 0, len = arr.length; i < len; i++) { 308 | Promise.resolve(arr[i]).then(resolve, reject) 309 | } 310 | }) 311 | } 312 | 313 | // Use polyfill for setImmediate for performance gains 314 | Promise._immediateFn = 315 | // @ts-ignore 316 | (typeof setImmediate === 'function' && 317 | function (fn) { 318 | // @ts-ignore 319 | setImmediate(fn) 320 | }) || 321 | function (fn) { 322 | setTimeoutFunc(fn, 0) 323 | } 324 | 325 | Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) { 326 | if (typeof console !== 'undefined' && console) { 327 | console.log('[jsfwk.error ] Possible Unhandled Promise Rejection:', err) // eslint-disable-line no-console 328 | } 329 | } 330 | 331 | /** @suppress {undefinedVars} */ 332 | var globalNS = (function () { 333 | // the only reliable means to get the global object is 334 | // `Function('return this')()` 335 | // However, this causes CSP violations in Chrome apps. 336 | if (typeof self !== 'undefined') { 337 | return self 338 | } 339 | if (typeof window !== 'undefined') { 340 | return window 341 | } 342 | if (typeof global !== 'undefined') { 343 | return global 344 | } 345 | if (typeof globalThis !== 'undefined') { 346 | return globalThis 347 | } 348 | 349 | throw new Error('unable to locate global object') 350 | })() 351 | 352 | globalNS['Promise'] = Promise 353 | // Expose the polyfill if Promise is undefined or set to a 354 | // non-function value. The latter can be due to a named HTMLElement 355 | // being exposed by browsers for legacy reasons. 356 | // https://github.com/taylorhakes/promise-polyfill/issues/114 357 | }) 358 | -------------------------------------------------------------------------------- /shared/setTimeout.js: -------------------------------------------------------------------------------- 1 | import { isHmTimerDefined } from './js-module' 2 | import { getGlobal } from './global' 3 | 4 | let globalNS = getGlobal() 5 | 6 | if (typeof setTimeout === 'undefined' && isHmTimerDefined()) { 7 | globalNS.clearTimeout = function clearTimeout(timerRef) { 8 | timerRef && timer.stopTimer(timerRef) 9 | } 10 | 11 | globalNS.setTimeout = function setTimeout(func, ns) { 12 | const timer1 = timer.createTimer( 13 | ns || 1, 14 | Number.MAX_SAFE_INTEGER, 15 | function () { 16 | globalNS.clearTimeout(timer1) 17 | func && func() 18 | }, 19 | {}, 20 | ) 21 | 22 | return timer1 23 | } 24 | 25 | globalNS.clearImmediate = function clearImmediate(timerRef) { 26 | timerRef && timer.stopTimer(timerRef) 27 | } 28 | 29 | globalNS.setImmediate = function setImmediate(func) { 30 | const timer1 = timer.createTimer( 31 | 1, 32 | Number.MAX_SAFE_INTEGER, 33 | function () { 34 | globalNS.clearImmediate(timer1) 35 | func && func() 36 | }, 37 | {}, 38 | ) 39 | 40 | return timer1 41 | } 42 | 43 | globalNS.clearInterval = function clearInterval(timerRef) { 44 | timerRef && timer.stopTimer(timerRef) 45 | } 46 | 47 | globalNS.setInterval = function setInterval(func, ms) { 48 | const timer1 = timer.createTimer( 49 | 1, 50 | ms, 51 | function () { 52 | func && func() 53 | }, 54 | {}, 55 | ) 56 | 57 | return timer1 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /utils/index.js: -------------------------------------------------------------------------------- 1 | export function assets(type) { 2 | return (path) => type + '/' + path 3 | } 4 | 5 | const TYPE = { 6 | 'sensor': 1, 7 | 'binary_sensor': 1, 8 | 'switch': 3, 9 | 'input_boolean': 3, 10 | 'light': 3, 11 | }; 12 | 13 | export function getScrollListDataConfig(dataList) { 14 | let previousType = ''; 15 | let currentIndex = -1; 16 | const dataTypeConfig = [] 17 | dataList.forEach((item, index) => { 18 | let currentType = item.type; 19 | if (currentType !== previousType) { 20 | currentIndex += 1; 21 | previousType = currentType; 22 | dataTypeConfig.push({ 23 | start: index, 24 | type: TYPE[currentType], 25 | }); 26 | } 27 | dataTypeConfig[currentIndex].end = index + 1; 28 | }); 29 | const dataTypeConfigCount = dataTypeConfig.length; 30 | return { dataTypeConfig, dataTypeConfigCount }; 31 | } --------------------------------------------------------------------------------