您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Script that helps to get DPs for your tuya devices
// ==UserScript== // @name Data Point (DP) list extractor for Tuya IoT platform // @namespace https://etcho.github.io/ // @version 2.1 // @description Script that helps to get DPs for your tuya devices // @author Everton Leite // @match *.iot.tuya.com/cloud/device/detail/* // @match *.platform.tuya.com/cloud/device/detail/* // @icon https://www.google.com/s2/favicons?sz=64&domain=tuya.com // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; let dp_list = document.createElement('ul'); let codes = {}; function waitForElm(selector) { return new Promise(resolve => { if (document.querySelector(selector)) return resolve(document.querySelector(selector)); const observer = new MutationObserver(mutations => { if (document.querySelector(selector)) { resolve(document.querySelector(selector)); observer.disconnect(); } }); observer.observe(document.body, {childList: true, subtree: true}); }); } function createListElement() { waitForElm('#rc-tabs-0-panel-deviceLogs').then((elm) => { dp_list.id = 'extracted_dp_list'; dp_list.style.position = 'absolute'; dp_list.style.width = '200px'; dp_list.style.top = '46px'; dp_list.style.right = '15px'; dp_list.style.background = '#FF4800'; dp_list.style.boxShadow = '2px 2px 4px rgba(0, 0, 0, 0.1)'; dp_list.style.color = '#FFF'; dp_list.style.border = '2px solid #cc3a00'; dp_list.style.fontSize = '12px'; dp_list.style.zIndex = 1; document.getElementById('rc-tabs-0-panel-deviceLogs').appendChild(dp_list); waitForElm('[aria-controls="code_list"]').then((elm) => { checkNewDPs(); }); }); } function simulateHovers() { if (document.querySelector('.ant-spin-blur') === null) { setTimeout(function() { let select = document.querySelector('[aria-controls="code_list"]').parentNode.parentNode; let clickEvent = document.createEvent('MouseEvents'); clickEvent.initEvent('mousedown', true, true); select.dispatchEvent(clickEvent); function emulateMouseOver(elm) { let clickEvent = document.createEvent('MouseEvents'); clickEvent.initEvent('mousemove', true, true); elm.dispatchEvent(clickEvent); } let options = document.querySelectorAll('.rc-virtual-list .ant-select-item-option'); for (let i = 0; i < options.length; i++) { setTimeout(emulateMouseOver, i * 10, options[i]); } select.dispatchEvent(clickEvent); }, 500); } } function idOfSelectedDevice() { return [...document.querySelector('[class*=detail_active]').innerHTML.matchAll(/\(([^)]+)\)[^)]*$/gm)][0][1]; } function renderList() { dp_list.replaceChildren(); let header = document.createElement('li'); header.id = 'dp_list_header'; header.style.background = 'rgb(207, 58, 0)'; header.style.textAlign = 'center'; header.style.fontWeight = 'bold'; header.innerHTML = 'DP List <a href="#" onclick="event.preventDefault(); document.querySelector(\'#extracted_dp_list\').remove();" style="float: right; color: #FFF; margin: -3px 3px 0px 0px;">x</a>'; dp_list.appendChild(header); for (const dp in codes[idOfSelectedDevice()]) { let item = document.createElement('li'); item.innerHTML = '<b>' + dp + '</b> → ' + codes[idOfSelectedDevice()][dp]; item.style.padding = '1px 4px'; if (Object.keys(codes[idOfSelectedDevice()]).pop() != dp) { item.style.borderBottom = '1px solid rgb(229, 65, 0)'; } dp_list.appendChild(item); } } function createListener() { waitForElm('#code_list').then((elm) => { var observer = new MutationObserver(mutations => { let code_items = document.getElementById('code_list').getElementsByTagName('div'); if (codes[idOfSelectedDevice()] === undefined) { codes[idOfSelectedDevice()] = {}; } for (const code_item of code_items) { codes[idOfSelectedDevice()][code_item.textContent] = code_item.getAttribute('aria-label'); } }); observer.observe(document.querySelector('#code_list'), {childList: true}); }); } function checkNewDPs() { if (codes[idOfSelectedDevice()] === undefined) { simulateHovers(); } else { renderList(); } setTimeout(checkNewDPs, 1000); } createListElement(); createListener(); })();