我无法在涂鸦周日程表(PHP cURL)中添加或删除单个日程表

问题描述 投票:0回答:1

我正在开发一个网站,用户可以控制他们的恒温器,但我在时间表部分遇到困难。我可以显示它,但无法创建新的计划。我只能使用 Postman 来完成,但我希望可以通过网站上的 PHP 来完成。这是我的代码:

脚本.php

<?php
class ConnectTuya
{
    private $_baseUrl;
    private $_deviceId;
    private $_clientId;
    private $_secret_key;
    private $_getToken;
    private $_fDevices;
    private $_t;
    
    public function __construct()
    {
        // code...
        $this->_baseUrl = 'https://openapi.tuyaeu.com/'; # url of your data center Ex: https://openapi.tuyaus.com/
        $this->_clientId  = 'xxxxxxxxxxxx'; 
        $this->_secret_key = 'xxxxxxxxxxxxx';
        $this->_getToken = "v1.0/token?grant_type=1";
        $this->_t = round(microtime(true) * 1000);
        $this->_fDevices = 'v1.0/iot-03/devices/';
        $this->_aDevices = 'v1.0/devices/';
        $this->_bDevices = 'v2.0/cloud/timer/device/';
    }

    /**
     * Get access token
     * 
     * @author hao.nguyen <[email protected]>
     * @return Array response access_token of request
     */ 

    public function get_token()
    {
        $headers = array(
            'sign_method: HMAC-SHA256',
            'client_id: '.$this->_clientId,
            't: '.$this->_t,
            'Content-Type: application/json',
            'access_token:'
        );
        $url =  $this->_baseUrl . $this->_getToken;
        $sign = $this->build_sign('GET', $url, [], []);

        $headers[] = "sign: " . $sign;
        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'GET',
            CURLOPT_HTTPHEADER => $headers
        ));

        $response = curl_exec($curl);

        curl_close($curl);
        return json_decode($response, true);
    }

    /**
     * Get device specification
     *
     * @param String   $device_id  device id
     * @param String $access_token Access_token from get_token function
     * 
     * @author hao.nguyen <[email protected]>
     * @return Array response specification of request
     */ 

    public function get_specification($device_id,  $access_token)
    {
        $headers = array(
            'sign_method: HMAC-SHA256',
            'client_id: '.$this->_clientId,
            't: '.$this->_t,
            'Content-Type: application/json',
            'access_token: ' . $access_token
        );
        $method = 'GET';
        $payload = array(
            'device_id' => $device_id
        );
        $url =  $this->_baseUrl . $this->_fDevices . $device_id . '/specification';
        $sign = $this->build_sign($method, $url, [], [], $access_token);

        $headers[] = "sign: " . $sign;
        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => $method,
            CURLOPT_HTTPHEADER => $headers
        ));

        $response = curl_exec($curl);

        curl_close($curl);
        return json_decode($response, true);
    }

    /**
     * Send command by device
     *
     * @param String   $device_id  device id
     * @param Array   $commands  array of commands 
     * @param String $access_token Access_token from get_token function
     * 
     * @author hao.nguyen <[email protected]>
     * @return Array response specification of request
     */

    public function send_commands($device_id, $commands ,$access_token)
    {
        $headers = array(
            'sign_method: HMAC-SHA256',
            'client_id: '.$this->_clientId,
            't: '.$this->_t,
            'Content-Type: application/json',
            'access_token: ' . $access_token
        );
        $method = 'POST';
        if (empty($commands)) {
            // code...
            return false;
        }
        $payload = array(
            "commands" => $commands
        );
        $url =  $this->_baseUrl . $this->_fDevices . $device_id . '/commands';
        $sign = $this->build_sign($method, $url, $payload, [], $access_token);

        $headers[] = "sign: " . $sign;
        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => $method,
            CURLOPT_POSTFIELDS =>json_encode($payload),
            CURLOPT_HTTPHEADER => $headers
        ));

        $response = curl_exec($curl);

        curl_close($curl);
        return json_decode($response, true);
    }

    public function get_scheduled($device_id,  $access_token)
    {
        $headers = array(
            'sign_method: HMAC-SHA256',
            'client_id: '.$this->_clientId,
            't: '.$this->_t,
            'Content-Type: application/json',
            'access_token: ' . $access_token
        );
        $method = 'GET';
        $payload = array(
            'device_id' => $device_id
        );
        $url =  $this->_baseUrl . $this->_bDevices . $device_id ;
        $sign = $this->build_sign($method, $url, [], [], $access_token);

        $headers[] = "sign: " . $sign;
        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => $method,
            CURLOPT_HTTPHEADER => $headers
        ));

        $response = curl_exec($curl);

        curl_close($curl);
        return json_decode($response, true);
    }

    public function add_scheduled($device_id, $time, $loops, $data, $access_token) {
        $headers = array(
            'sign_method: HMAC-SHA256',
            'client_id: ' . $this->_clientId,
            't: ' . $this->_t,
            'Content-Type: application/json',
            'access_token: ' . $access_token
        );
    
        $method = 'POST';
        $url = $this->_baseUrl . '/v2.0/cloud/timer/device/' . $device_id;
    
        $payload = array(
            "alias_name" => "Scheduled",
            "time" => $time,
            "timezone_id" => "Europe/Paris",
            "loops" => $loops,
            "functions" => array($data)
        );
    
        // Convert payload to JSON for CURLOPT_POSTFIELDS
        $payload_json = json_encode($payload);
    
        // Construct the signature
        $sign = $this->build_sign($method, $url, $payload_json, $headers, $access_token);
    
        $headers[] = "sign: " . $sign;
    
        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => $method,
            CURLOPT_POSTFIELDS => $payload_json,
            CURLOPT_HTTPHEADER => $headers
        ));
    
        $response = curl_exec($curl);
    
        curl_close($curl);
    
        return json_decode($response, true);
    }

    public function get_device_information($device_id,  $access_token)
    {
        $headers = array(
            'sign_method: HMAC-SHA256',
            'client_id: '.$this->_clientId,
            't: '.$this->_t,
            'Content-Type: application/json',
            'access_token: ' . $access_token
        );
        $method = 'GET';
        $payload = array(
            'device_id' => $device_id
        );
        $url =  $this->_baseUrl . $this->_aDevices . $device_id . '/';
        $sign = $this->build_sign($method, $url, [], [], $access_token);

        $headers[] = "sign: " . $sign;
        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => $method,
            CURLOPT_HTTPHEADER => $headers
        ));

        $response = curl_exec($curl);

        curl_close($curl);
        return json_decode($response, true);
    }

    /**
     * Genarator sign for request
     *
     * @param String   $method  POST or GET
     * @param String $url url of request
     * @param Array $payload body of request
     * @param Array $headers headers of request, !!! if error put it empty array
     * @param String $token access_token
     * 
     * @author hao.nguyen <[email protected]>
     * @return hash sign
     */ 

    private function build_sign($method, $url ,$payload, $headers, $token = "")
    {
        $str_header = "";
        if ($headers) {
            // code...
            $str_header = implode("\n", $headers);
        }
        $str_payload = "";
        if ($payload) {
            // code...
            $str_payload = json_encode($payload);
        }

        $content_SHA256 = hash('sha256', $str_payload);
        
        $parse_url = parse_url($url);
        $part_url = empty($parse_url['path']) ? "" : $parse_url['path'];
        $query_url = empty($parse_url['query']) ? "" : "?" . $parse_url['query'];
        $str_to_sign = $method . "\n" . $content_SHA256 . "\n" . $str_header . "\n" . $part_url . $query_url;

        $sign = strtoupper(hash_hmac('SHA256', $this->_clientId . $token . $this->_t . $str_to_sign, $this->_secret_key));
        return $sign;
    }
}
?>

add_scheduled
功能不起作用。这是我的代码中的内容:

index.php

        $time = $_POST['new_time'];
    $temp = $_POST['new_temperature'];
    $jour = $_POST['jour'];

    if($jour == "Dimanche") {
        $loops = "1000000";
    }else if($jour == "Lundi") {
        $loops = "0100000";
    }else if($jour == "Mardi") {
        $loops = "0010000";
    }else if($jour == "Mercredi") {
        $loops = "0001000";
    }else if($jour == "Jeudi") {
        $loops = "0000100";
    }else if($jour == "Vendredi") {
        $loops = "0000010";
    }else if($jour == "Samedi") {
        $loops = "0000001";
    }

    echo $loops;

    $data = array(
        array(
            "code" => "switch_1",
            "value" => true
        ),
        array(
            "code" => "temp_set",
            "value" => $temp
        ),
        array(
            "code" => "customize_mode_switch",
            "value" => true
        )
    );
    

    $addschedule = $tuya_obj->add_scheduled($device_id,$time,$loops, $data, $access_token['result']['access_token']);
    print_r(json_encode($addschedule));

我得到的错误是涂鸦网站上的1004 1004 is sign invalid:

the error

网站:https://developer.tuya.com/en/docs/iot/error-code?id=K989ruxx88swc

网址(左侧添加部分):

我尝试使用我所知道的一切和脚本的 github: https://github.com/hao159/tuya-connect-php

在邮递员中: Postman Add-Schedule

php php-curl tuya
1个回答
0
投票

如果检查

send_commands()
方法,您可以看到它以数组形式传递
$payload
build_sign()
,而不是
json_encode()
d。如果你追踪
build_sign()
,你可以看到它
json_encode()
是它接收到的有效负载。

但是如果你将其与

add_scheduled()
进行比较 - 我理解这是行不通的方法 - 你正在传递
build_sign()
一个已经
json_encode()
d 的有效负载。
build_sign()
会再次
json_encode()
,我想这是一个问题。

尝试将有效负载作为原始数组传递:

// Construct the signature
$sign = $this->build_sign($method, $url, $payload, $headers, $access_token);
© www.soinside.com 2019 - 2024. All rights reserved.