From 5aeff6b0d31c69b3539e36efb232332c335d6860 Mon Sep 17 00:00:00 2001 From: wyh Date: Thu, 23 Nov 2023 15:53:25 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=AF=E8=A7=86=E5=AF=B9=E8=AE=B2=EF=BC=8C?= =?UTF-8?q?=E4=BA=A4=E4=BA=92=E4=BA=8B=E4=BB=B6=E6=97=A0=E6=B3=95=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- iot/hikvision-iot.go | 53 ++++++++++++++++++-- iot/model/voicetalk-model.go | 6 +++ iot/oauth_test.go | 30 +++++++++-- iot/qrcode-iot.go | 2 +- iot/voiceTalk-iot.go | 96 ++++++++++++++++++++++++++++++++++++ 5 files changed, 179 insertions(+), 8 deletions(-) create mode 100644 iot/model/voicetalk-model.go create mode 100644 iot/voiceTalk-iot.go diff --git a/iot/hikvision-iot.go b/iot/hikvision-iot.go index 2101a7d..a03d1ed 100644 --- a/iot/hikvision-iot.go +++ b/iot/hikvision-iot.go @@ -104,7 +104,7 @@ func hikvisionOauth() (*string, error) { scope: scope, } - resp, err := hikvisionRequestUrlencoded("POST", `/oauth/token`, params, false) + resp, err := hikvisionIOTRequestUrlencoded("POST", `/oauth/token`, params, false) if err != nil { return nil, err } @@ -126,10 +126,10 @@ func hikvisionOauth() (*string, error) { return &token, nil } -// 使用form请求 application/x-www-form-urlencoded,公共方法 +// iot 使用form请求 application/x-www-form-urlencoded,公共方法 // // 传入的结构体内的字段名称必须与文档一致 -func hikvisionRequestUrlencoded(method string, url string, body interface{}, auth bool) ([]byte, error) { +func hikvisionIOTRequestUrlencoded(method string, url string, body interface{}, auth bool) ([]byte, error) { reader, err := hikvisioninspectStruct(body) if err != nil { @@ -176,6 +176,53 @@ func hikvisionRequestUrlencoded(method string, url string, body interface{}, aut return respBody, nil } +func hikvisionRequestUrlencoded(method string, url string, body interface{}, auth bool) ([]byte, error) { + + reader, err := hikvisioninspectStruct(body) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(method, url, strings.NewReader(reader.Encode())) + if err != nil { + return nil, err + } + + req.Header.Add("Accept", "*/*") + req.Header.Add("Content-Type", "application/x-www-form-urlencoded") + if auth { + token, err := hikvisionOauth() + if err != nil { + return nil, err + } + req.Header.Add("authorization", fmt.Sprintf(" bearer %s", *token)) + } + tr := &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + } + + client := &http.Client{Transport: tr, Timeout: 10 * time.Second} + resp, err := client.Do(req) + if err != nil { + return nil, err + } + + if resp.StatusCode != 200 { + errmsg := fmt.Sprintf("http status code: %d", resp.StatusCode) + return nil, errors.New(errmsg) + } + + defer resp.Body.Close() + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + return respBody, nil +} + // 解析结构体数据,写入到url.values中 func hikvisioninspectStruct(u interface{}) (url.Values, error) { values := url.Values{} diff --git a/iot/model/voicetalk-model.go b/iot/model/voicetalk-model.go new file mode 100644 index 0000000..9858c24 --- /dev/null +++ b/iot/model/voicetalk-model.go @@ -0,0 +1,6 @@ +package model + +type VoiceTalkGet struct { + Hikvision + Data string `json:"data"` +} diff --git a/iot/oauth_test.go b/iot/oauth_test.go index 6a6874f..b67eb78 100644 --- a/iot/oauth_test.go +++ b/iot/oauth_test.go @@ -7,21 +7,43 @@ import ( ) func TestOauth(t *testing.T) { - - // r0, err := QrCodeVisitors("1231", "231123150000", "231123180000", 9) + // r0, err := VoiceTalkSet() // if err != nil { // log.Fatal(err) // return // } // fmt.Println(r0) - r1, err := EventLocalQuery(1, 30, "AF8534579", "", "", 5, 6, "2023-11-23T08:00:00+08:00", "2023-11-23T20:00:00+08:00") + r1, err := VoiceTalkInform("2023-11-23T08:00:00+08:00", 1, 101, 2, "request", 3, "outdoor", "AF8534579", 1, 3) if err != nil { log.Fatal(err) return } fmt.Println(r1) + // r2, err := VoiceTalkGet() + // if err != nil { + // log.Fatal(err) + // return + // } + // fmt.Println(r2) +} + +/* +// r0, err := QrCodeVisitors("1231", "231123150000", "231123180000", 9) + // if err != nil { + // log.Fatal(err) + // return + // } + // fmt.Println(r0) + + // r1, err := EventLocalQuery(1, 30, "AF8534579", "", "", 5, 6, "2023-11-23T08:00:00+08:00", "2023-11-23T20:00:00+08:00") + // if err != nil { + // log.Fatal(err) + // return + // } + // fmt.Println(r1) + // groupid := "4b9e7ab1068d45269b1acb6c8b50d855" // r1, err := PermissionGroupAddDevice(groupid, true, []string{"AF8534579"}, true) // if err != nil { @@ -98,4 +120,4 @@ func TestOauth(t *testing.T) { // return // } // fmt.Println(r8) -} +*/ diff --git a/iot/qrcode-iot.go b/iot/qrcode-iot.go index 0cce777..091e1a2 100644 --- a/iot/qrcode-iot.go +++ b/iot/qrcode-iot.go @@ -24,7 +24,7 @@ func QrCodeVisitors(cardNo, effectTime, expireTime string, openTimes int) (*mode openTimes: openTimes, } - resp, err := hikvisionRequestUrlencoded("POST", qr_code_visitor, req, true) + resp, err := hikvisionIOTRequestUrlencoded("POST", qr_code_visitor, req, true) if err != nil { return nil, err } diff --git a/iot/voiceTalk-iot.go b/iot/voiceTalk-iot.go new file mode 100644 index 0000000..90c36ea --- /dev/null +++ b/iot/voiceTalk-iot.go @@ -0,0 +1,96 @@ +package iot + +import ( + "encoding/json" + "os" + + "myschools.me/suguo/hikvision/iot/model" +) + +const ( + voicetalk_base = "/api/v1/open/accessControl/configs/voiceTalk" + voicetalk_notifyUrl = voicetalk_base + "/notifyUrl" +) + +var ( + notifyUrl = "" +) + +func init() { + notifyUrl = os.Getenv("IOT_NOTIFY_URL") + if notifyUrl == "" { + notifyUrl = "https://hikvision.com" + } +} + +// 设置可视对讲通知地址 +func VoiceTalkSet() (*model.Hikvision, error) { + req := &struct { + NotifyUrl string `json:"notifyUrl"` + }{ + NotifyUrl: notifyUrl, + } + + resp, err := hikvisionRequest("POST", voicetalk_notifyUrl, req) + if err != nil { + return nil, err + } + var result = &model.Hikvision{} + if err := json.Unmarshal(resp, &result); err != nil { + return nil, err + } + return result, nil +} + +// 可视对讲交互事件通知 使用前请设置环境变量 IOT_NOTIFY_URL +// +// 当设备触发可视对讲交互事件时,平台通知第三方。 未测试通过 +func VoiceTalkInform(dataTime string, periodNumber, roomNumber, devIndex int, cmdtype string, unitNumber int, unittype, deviceSerial string, floornumber, buildingNumber int) (*model.Hikvision, error) { + req := struct { + dateTime string //2023-11-23T08:00:00+08:00 + periodNumber int //期号 + roomNumber int //房间号 + devIndex int //设备序号 + cmdType string //操作类型 + unitNumber int //单元号 + unitType string //类型: outdoor门口机,wall围墙机 + deviceSerial string + floorNumber int //层号 + buildingNumber int //楼号 + }{ + dateTime: dataTime, + periodNumber: periodNumber, + roomNumber: roomNumber, + devIndex: devIndex, + cmdType: cmdtype, + unitNumber: unitNumber, + unitType: unittype, + deviceSerial: deviceSerial, + floorNumber: floornumber, + buildingNumber: buildingNumber, + } + + resp, err := hikvisionRequestUrlencoded("POST", notifyUrl, req, true) + if err != nil { + return nil, err + } + var result = &model.Hikvision{} + if err := json.Unmarshal(resp, &result); err != nil { + return nil, err + } + return result, nil +} + +// 获取可视对讲通知地址 +func VoiceTalkGet() (*model.VoiceTalkGet, error) { + + resp, err := hikvisionRequest("GET", voicetalk_notifyUrl, nil) + if err != nil { + return nil, err + } + var result = &model.VoiceTalkGet{} + if err := json.Unmarshal(resp, &result); err != nil { + return nil, err + } + return result, nil +}