nocmt / ewelink-api-next

CoolKit v2 API Official Library
MIT License
22 stars 5 forks source link

How to get the updated power / current of a S31TPB(US) #19

Closed ksaye closed 7 months ago

ksaye commented 10 months ago

I love the node package ‘ewelink-api-next@1.0.1’ and use it all the time to get the status of all my devices with the command ‘await client.device.getAllThings({})’.

I recently added a device ‘S31TPB(US)’ with the hope of reading the current, power and voltage.

Using the getAllThings({}), I see the device below, but the power, current and voltage do not change UNTIL I launch the EWELINK app on my phone.

How do I get the current power, current and voltage on devices?

  {
      "status": 200,
      "responseTime": 1030,
      "error": 0,
      "msg": "",
      "data": {
          "thingList": [
              {
                  "itemType": 1,
                  "itemData": {
                      "name": "Switch1",
                      "deviceid": "1001f7e71b",
                      "apikey": "e8845c9a-8c01-4107-9c67-d45438592dae",
                      "extra": {
                          "uiid": 32,
                          "description": "",
                          "itCredential": "rd*************Hsk",
                          "brandId": "5c4c1aee3a7d24c7100be054",
                          "apmac": "d0:27:03:66:8e:09",
                          "mac": "d0:27:03:66:8e:08",
                          "ui": "功率检测插座过载告警",
                          "modelInfo": "5c700f8dcc248c47441fd23a",
                          "model": "PSC-B67-GL",
                          "manufacturer": "深圳松诺技术有限公司",
                          "chipid": "00856F90",
                          "staMac": "BC:FF:4D:85:6F:90"
                      },
                      "brandName": "SONOFF",
                      "brandLogo": https://us-ota.coolkit.cc/logo/q62PevoglDNmwUJ9oPE7kRrpt1nL1CoA.png,
                      "showBrand": true,
                      "productModel": "S31TPB(US)",
                      "tags": {
                          "m_2dae_ksay": "on"
                      },
                      "devConfig": {
                          "timerCount": "16/28"
                      },
                      "settings": {
                          "opsNotify": 0,
                          "opsHistory": 1,
                          "alarmNotify": 1,
                          "wxAlarmNotify": 0,
                          "wxOpsNotify": 0,
                          "wxDoorbellNotify": 0,
                          "appDoorbellNotify": 1
                      },
                      "devGroups": [],
                      "family": {
                          "familyid": "5eaade31b0ad2b0008ada452",
                          "index": -8,
                          "members": []
                      },
                      "shareTo": [],
                      "devicekey": "fd726a33-9433-4c98-a0a5-667b9c2d8b83",
                      "online": true,
                      "params": {
                          …
                          "power": "167.36",
                          "voltage": "122.20",
                          "current": "2.26",
                          …
                      },
                      "isSupportGroup": false,
                      "isSupportedOnMP": true,
                      "isSupportChannelSplit": false,
                      "deviceFeature": {}
                  },
                  "index": -8
              }
          ],
          "total": 13
      }
  }
ksaye commented 10 months ago

Any update on this?

nocmt commented 10 months ago
image

Protocol document: https://coolkit-technologies.github.io/eWeLink-API/#/en/UIIDProtocol?id=uiid5-power-detection-single-channel-plug

The real-time acquisition of power, current, and voltage is achieved by issuing uiActive commands to activate the device every 60 seconds, so you need to establish a websocket connection to monitor the device status in real time and query it through the above protocol.

Document information on establishing a websocket connection: https://coolkit-technologies.github.io/eWeLink-API/#/en/APICenterV2?id=real-time-control-device

Only one latest historical record reported by the device can be obtained through the interface.

ksaye commented 10 months ago

@nocmt thanks for the response. Your explanation help me understand what I am seeing and what I need to do.

ksaye commented 10 months ago

@nocmt , is there a working sample code showing both onMessage and logging in with the appId and appSecret?

Using the code below, I am unclear how to subscribe to 'onMessage' or to fetch the power state. I have also noted that below the "wsClient.Connect.updateState('1001f7e71b', { switch: 'on',});" does not seem to turn the switch on.

  // eWeLink WebSocket API

  import eWeLink from "ewelink-api-next";

  const wsClient = new eWeLink.Ws({
    appId: 'pf2**********************j1w', // App ID, which needs to be configured in the eWeLink open platform
    appSecret: 'c7h*****************x3a', // App Secret, which needs to be configured in the eWeLink open platform
    region: "us"
  });

  let ws = await wsClient.Connect.create({
    appId: wsClient?.appId || "",
    at: wsClient.at,
    region: "us",
    userApiKey: wsClient.userApiKey
  });

  wsClient.Connect.updateState('1001f7e71b', {
    switch: 'on',
  });

  wsClient.Connect.updateState('1001f7e71b', {
    "uiActive": 60,
  });

  while (ws.readyState != 1) {
    await new Promise(r => setTimeout(r, 1000));
  }

  while (ws.readyState ==1) {
    await new Promise(r => setTimeout(r, 60000));
    console.log(ws.readyState);
    // get the power of the device here
    //  ?????
  }
ksaye commented 9 months ago

Any response?

nocmt commented 8 months ago

Any response?

https://github.com/nocmt/eWeLinkOAuthLoginDemo/blob/main/wssDemo.js

Here is an example of starting listening

Remember to add uiActive

ksaye commented 7 months ago

Thanks @nocmt.

For others, here is the updated sample code:

  import { wsClient, client } from './config.js';
  import * as fs from "fs";

  let region = "us";
  let at = "";

  const getUserApiKey = async ()=> {
      if (fs.existsSync("token.json")) {
          const tokenObj = JSON.parse(fs.readFileSync("token.json"));
          at = client.at = tokenObj.data.accessToken;
          region = client.region = tokenObj.region;
          client.setUrl(region);
          const response = await client.home.getFamily({});
          return response.error === 0 ? response.data.familyList[0]?.apikey : null;
      }else{
          console.error("token.json not found");
          process.exit(1);
      }
  }

  function isJson(str) {
      try {
      JSON.parse(str);
      } catch (e) {
      return false;
      }
      return true;
      }

  // GET@/v2/family
  wsClient.userApiKey = await getUserApiKey();

  if (wsClient.userApiKey && region) {
      await wsClient.Connect.create({
          appId: wsClient?.appId || "",
          at: at,
          region: region,
          userApiKey: wsClient.userApiKey
      }, ()=>{
          console.log("connected");
          wsClient.Connect.updateState('10******1b', {
              "uiActive": 60,
          })
      }, ()=>{
          console.log("disconnected");
      }, (_err)=>{
          console.log("Error generated:", _err);
      }, (_ws, _msg)=>{
          const currentDate = new Date();
          if (isJson(_msg.data)) {
              let message = JSON.parse(_msg.data);
              if (message.hasOwnProperty('params')){
                  message.params.date = currentDate;
                  console.log(message.params);
              }
          } else {
              console.log(`${currentDate}: `, _msg.data);
          }
      });
  }

After adding a token.json file and running node wssDemo.js I get the following output:

  $ node wssDemo.js 
  connected
  {
    power: '0.00',
    voltage: '122.76',
    current: '0.00',
    date: 2024-03-26T23:23:00.515Z
  }
slavendam commented 4 months ago

@ksaye I just want to say thank you for this code, it was really helpful! This works with Sonoff S60 also