plasticrake / tplink-smarthome-api

TP-Link Smarthome WiFi API
MIT License
1.02k stars 141 forks source link

set time/timezone via API? #91

Closed snowdd1 closed 4 years ago

snowdd1 commented 4 years ago

Hi platicrake, I am using my HS100 locally (no internet connect, no cloud) via API only, but I found that the API is failing if the time and location are not set, and the plug is queried using client.getPlug(host: name). Not sure about location though, 0/0 could be good. Is there a way to set time after a power outage, except manually via the KASA app?

Funny thing: using an older version and full discovery it still works, only my new program with the new version of the API fails. I don't know exactly which version the old one had, but could look it up if it is of interest to you.

Thanks!

{"err_code":-11,"err_msg":"time not sync"} in

[Zisternenpumpe] device.startPolling(): getInfo(): error: ResponseError: err_code response: {"emeter":
{"err_code":-1,"err_msg":"module not support"},"schedule":{"get_next_action":
{"err_code":-11,"err_msg":"time not sync"}},"system":{"get_sysinfo":{"err_code":0,"sw_ver":"1.1.0 Build 160503 Rel.145047","hw_ver":"1.0","type":"IOT.SMARTPLUGSWITCH","model":"HS100(EU)","mac":"50:C7:BF:B6:EE:5B","deviceId":"****","hwId":"****","fwId":"****","oemId":"****","alias":"Zisternenpumpe","dev_name":"Wi-Fi Smart Plug","icon_hash":"","relay_state":1,"on_time":27,"active_mode":"none","feature":"TIM","updating":0,"rssi":-67,"led_off":0,"latitude":52,"longitude":7}},"cnCloud":{"get_info":{"username":"","server":"devs.tplinkcloud.com","binded":0,"cld_connection":0,"illegalType":-1,"stopConnect":-1,"tcspStatus":-1,"fwDlPage":"","tcspInfo":"","fwNotifyType":0,"err_code":0}}} command: {"emeter":{"get_realtime":{}},"schedule":{"get_next_action":{}},"system":{"get_sysinfo":{}},"cnCloud":{"get_info":{}}}
    at processResponse (Q:\hs100-test\node_modules\tplink-smarthome-api\lib\device\index.js:86:11)
    at Plug.sendCommand (Q:\hs100-test\node_modules\tplink-smarthome-api\lib\device\index.js:370:21)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async Plug.getInfo (Q:\hs100-test\node_modules\tplink-smarthome-api\lib\plug\index.js:353:14)
    at async Timeout.fn [as _onTimeout] (Q:\hs100-test\node_modules\tplink-smarthome-api\lib\device\index.js:411:9) {
  name: 'ResponseError',
  response: {
    emeter: { err_code: -1, err_msg: 'module not support' },
    schedule: { get_next_action: [Object] },
    system: { get_sysinfo: [Object] },
    cnCloud: { get_info: [Object] }
  },
  command: {
    emeter: { get_realtime: {} },
    schedule: { get_next_action: {} },
    system: { get_sysinfo: {} },
    cnCloud: { get_info: {} }
  },
  errorModules: [ 'emeter', 'schedule' ]
}
snowdd1 commented 4 years ago

For the time being I monkey-patched lib/plug/index.js #352-382

    try {
      //data = await this.sendCommand('{"emeter":{"get_realtime":{}},"schedule":{"get_next_action":{}},"system":{"get_sysinfo":{}},"cnCloud":{"get_info":{}}}', this.childId, sendOptions);
      data = await this.sendCommand('{"system":{"get_sysinfo":{}},"cnCloud":{"get_info":{}}}', this.childId, sendOptions);
    } catch (err) {
      // Ignore emeter section errors as not all devices support it
      if (err instanceof ResponseError && err.errorModules.length === 1 && err.errorModules[0] === 'emeter') {
        data = err.response;
      } else {
        throw err;
      }
    }

    this.sysInfo = data.system.get_sysinfo;
    this.cloud.info = data.cnCloud.get_info;

    // if (Object.prototype.hasOwnProperty.call(data.emeter, 'get_realtime')) {
    //   this.emeter.realtime = data.emeter.get_realtime;
    // }

    // this.schedule.nextAction = data.schedule.get_next_action;
    return {
      sysInfo: this.sysInfo,
      cloud: {
        info: this.cloud.info
      // },
      // emeter: {
      //   realtime: this.emeter.realtime
      // },
      // schedule: {
      //   nextAction: this.schedule.nextAction
      }
    };

to remove support for EMETER and schedule which I don't use anyway. I saw that the EMETER error has been excluded by hardwiring already, maybe the "time not in sync" could be handled similarly, or a new option in getPlug() to fix it to a type, and a range of feature you want to use/support.

snowdd1 commented 4 years ago

Can be closed. I found out that setting the time is no active process, but the plug queries the internet for a time server. So I will allow the firewall to talk to one of the time servers the plug is querying.