This commit is contained in:
suguo.yao 2023-11-21 09:35:10 +08:00
parent c93370eacd
commit d5978b95f2
11 changed files with 164 additions and 150 deletions

View File

@ -1,42 +0,0 @@
package cloud
import (
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
)
// 基础云眸http请求
func BaseCloudHttpRequest(accesstoken *string, method string, url string, body interface{}) ([]byte, error) {
b, err := json.Marshal(body)
if err != nil {
return nil, err
}
reqbody := strings.NewReader(string(b))
req, err := http.NewRequest(method, url, reqbody)
if err != nil {
return nil, err
}
req.Header.Add("authorization", fmt.Sprintf(" bearer %s", *accesstoken))
if strings.ToLower(method) == "post" {
req.Header.Add("Content-Type", "application/json")
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return respBody, nil
}

View File

@ -1,78 +0,0 @@
package cloud
import (
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"net/url"
"strings"
"time"
)
const (
BASEURL = "https://api2.hik-cloud.com/oauth"
)
type OauthRequest struct {
ClientID string `json:"client_id"`
ClientSecret string `json:"client_secret"`
GrantType string `json:"grant_type"`
Scope string `json:"scope"`
}
type OauthResponse struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
Scope string `json:"scope"`
}
// 客户端认证获取access_token
func HikvisionOauth(body *OauthRequest) (*OauthResponse, error) {
params := url.Values{}
params.Add("client_id", body.ClientID)
params.Add("client_secret", body.ClientSecret)
params.Add("grant_type", body.GrantType)
params.Add("scope", body.Scope)
req, err := http.NewRequest("POST", fmt.Sprintf(`%s/token`, BASEURL), strings.NewReader(string(params.Encode())))
if err != nil {
return nil, err
}
req.Header.Add("Accept", "*/*")
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
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
}
var result *OauthResponse
if err := json.Unmarshal(respBody, &result); err != nil {
return nil, err
}
return result, nil
}

View File

@ -1 +0,0 @@
海康云眸平台

View File

@ -57,7 +57,7 @@ type DeviceData struct {
//
// 注册设备时首先会将设备添加到平台,然后异步同步设备通道。如果设备添加成功而同步设备通道失败,则可以先获取设备列表信息,再手动调用通道同步接口同步设备下的通道。\
func DeivceRegister(access_token *string, req *DeviceRegister) (*DeviceRegisterRes, error) {
resp, err := BaseCloudHttpRequest(access_token, "POST", ACCESS_REGISTER, req)
resp, err := hikvisionRequest(access_token, "POST", ACCESS_REGISTER, req)
if err != nil {
return nil, err
}
@ -74,7 +74,7 @@ func DeivceRegister(access_token *string, req *DeviceRegister) (*DeviceRegisterR
// 从某一分组内删除设备
func DeivceDelete(access_token *string, deviceSerial string) (*model.BaseOperationRes, error) {
resp, err := BaseCloudHttpRequest(access_token, "POST", fmt.Sprintf("%s?deviceSerial=%s", ACCESS_DELETE, deviceSerial), nil)
resp, err := hikvisionRequest(access_token, "POST", fmt.Sprintf("%s?deviceSerial=%s", ACCESS_DELETE, deviceSerial), nil)
if err != nil {
return nil, err
}
@ -96,7 +96,7 @@ type DeivceUpdateReq struct {
// 该接口用于修改设备名称
func DeivceUpdate(access_token *string, req *DeivceUpdateReq) (*model.BaseOperationRes, error) {
resp, err := BaseCloudHttpRequest(access_token, "POST", ACCESS_UPDATE, req)
resp, err := hikvisionRequest(access_token, "POST", ACCESS_UPDATE, req)
if err != nil {
return nil, err
}
@ -113,7 +113,7 @@ func DeivceUpdate(access_token *string, req *DeivceUpdateReq) (*model.BaseOperat
// 该接口用于根据设备序列号获取单个设备详细信息
func DeivceDetail(access_token *string, deviceSerial string) (*DeviceData, error) {
resp, err := BaseCloudHttpRequest(access_token, "GET", fmt.Sprintf("%s?deviceSerial=%s", ACCESS_DETAIL, deviceSerial), nil)
resp, err := hikvisionRequest(access_token, "GET", fmt.Sprintf("%s?deviceSerial=%s", ACCESS_DETAIL, deviceSerial), nil)
if err != nil {
return nil, err
}
@ -150,7 +150,7 @@ type DeivceListData struct {
// 该接口用于查询某组下设备列表信息
func DeivceList(access_token *string, req *DeivceListReq) (*DeivceListData, error) {
url := fmt.Sprintf("%s?groupNo=%s&pageNo=%d&pageSize=%d", ACCESS_LIST, req.GroupNo, req.pageNo, req.pageSize)
resp, err := BaseCloudHttpRequest(access_token, "GET", url, nil)
resp, err := hikvisionRequest(access_token, "GET", url, nil)
if err != nil {
return nil, err
}
@ -178,7 +178,7 @@ type DeivceNumData struct {
// 该接口用于获取用户接入的设备总数
func DeivceNum(access_token *string) (*int, error) {
resp, err := BaseCloudHttpRequest(access_token, "GET", ACCESS_ACCOUNT, nil)
resp, err := hikvisionRequest(access_token, "GET", ACCESS_ACCOUNT, nil)
if err != nil {
return nil, err
}
@ -215,7 +215,7 @@ type DeivceStatusData struct {
// 该接口用于查询设备的状态信息,目前仅支持萤石设备 /*测试未通过*/
func DeivceStatus(access_token *string, deviceserial string) (*DeivceStatusData, error) {
resp, err := BaseCloudHttpRequest(access_token, "GET", fmt.Sprintf("%s?deviceSerial=%s", ACCESS_STATUS, deviceserial), nil)
resp, err := hikvisionRequest(access_token, "GET", fmt.Sprintf("%s?deviceSerial=%s", ACCESS_STATUS, deviceserial), nil)
if err != nil {
return nil, err
}
@ -238,7 +238,7 @@ func DeivceReboot(access_token *string, deviceserial string) (*model.BaseOperati
DeviceSerial: deviceserial,
}
resp, err := BaseCloudHttpRequest(access_token, "POST", ACCESS_REBOOT, params)
resp, err := hikvisionRequest(access_token, "POST", ACCESS_REBOOT, params)
if err != nil {
return nil, err
}
@ -266,7 +266,7 @@ func DeivceReboot(access_token *string, deviceserial string) (*model.BaseOperati
// 下线确认
func DeivceOffline(access_token *string, deviceserial string) (*model.BaseOperationRes, error) {
resp, err := BaseCloudHttpRequest(access_token, "GET", fmt.Sprintf("https://api2.hik-cloud.com/v1/carrier/wing/endpoint/confirm/right/offlineconfirm?deviceSerial=%s", deviceserial), nil)
resp, err := hikvisionRequest(access_token, "GET", fmt.Sprintf("https://api2.hik-cloud.com/v1/carrier/wing/endpoint/confirm/right/offlineconfirm?deviceSerial=%s", deviceserial), nil)
if err != nil {
return nil, err
}
@ -284,7 +284,7 @@ func DeivceOffline(access_token *string, deviceserial string) (*model.BaseOperat
// 上线线确认
func DeivceOnline(access_token *string, deviceserial string) (*model.BaseOperationRes, error) {
resp, err := BaseCloudHttpRequest(access_token, "GET", fmt.Sprintf("https://api2.hik-cloud.com/v1/carrier/wing/endpoint/confirm/right/onlineconfirm?deviceSerial=%s", deviceserial), nil)
resp, err := hikvisionRequest(access_token, "GET", fmt.Sprintf("https://api2.hik-cloud.com/v1/carrier/wing/endpoint/confirm/right/onlineconfirm?deviceSerial=%s", deviceserial), nil)
if err != nil {
return nil, err
}
@ -311,7 +311,7 @@ type DeviceGetTimeModeData struct {
// 该接口用于获取设备当前校时配置
func DeviceGetTimeMode(access_token *string, deviceserial string) (*DeviceGetTimeModeData, error) {
resp, err := BaseCloudHttpRequest(access_token, "GET", fmt.Sprintf("%s?deviceSerial=%s", TIME_BASE, deviceserial), nil)
resp, err := hikvisionRequest(access_token, "GET", fmt.Sprintf("%s?deviceSerial=%s", TIME_BASE, deviceserial), nil)
if err != nil {
return nil, err
}
@ -333,7 +333,7 @@ type DeviceSetTimeModeReq struct {
// 该接口用于配置设备校时模式
func DeviceSetTimeMode(access_token *string, req *DeviceSetTimeModeReq) (*model.BaseOperationRes, error) {
resp, err := BaseCloudHttpRequest(access_token, "POST", TIME_BASE, req)
resp, err := hikvisionRequest(access_token, "POST", TIME_BASE, req)
if err != nil {
return nil, err
}
@ -350,7 +350,7 @@ func DeviceSetTimeMode(access_token *string, req *DeviceSetTimeModeReq) (*model.
// 该接口用于获取设备当前NTP服务器配置
func DeviceGetNTPCfg(access_token *string, deviceserial string) (*DeviceSetNTPCfgServer, error) {
resp, err := BaseCloudHttpRequest(access_token, "GET", fmt.Sprintf("%s?deviceSerial=%s", TIME_NTPCFG, deviceserial), nil)
resp, err := hikvisionRequest(access_token, "GET", fmt.Sprintf("%s?deviceSerial=%s", TIME_NTPCFG, deviceserial), nil)
if err != nil {
return nil, err
}
@ -381,7 +381,7 @@ type DeviceSetNTPCfgServer struct {
// 该接口用于配置设备NTP服务器参数
func DeviceSetNTPCfg(access_token *string, req *DeviceSetNTPCfgReq) (*model.BaseOperationRes, error) {
resp, err := BaseCloudHttpRequest(access_token, "POST", TIME_NTPCFG, req)
resp, err := hikvisionRequest(access_token, "POST", TIME_NTPCFG, req)
if err != nil {
return nil, err
}
@ -404,7 +404,7 @@ type DeviceGetNTPServerRes struct {
// 该接口用于获取设备指定NTP服务器配置
func DeviceGetNTPServerCfg(access_token *string, deviceserial string, ntpserverid int) (*DeviceSetNTPCfgServer, error) {
resp, err := BaseCloudHttpRequest(access_token, "GET", fmt.Sprintf("%s?deviceSerial=%s&ntpServerId=%d", TIM_NTPSERVER_CFG, deviceserial, ntpserverid), nil)
resp, err := hikvisionRequest(access_token, "GET", fmt.Sprintf("%s?deviceSerial=%s&ntpServerId=%d", TIM_NTPSERVER_CFG, deviceserial, ntpserverid), nil)
if err != nil {
return nil, err
}
@ -427,7 +427,7 @@ type DeviceSetNTPServerCfgReq struct {
// 该接口用于配置设备指定NTP服务器参数
func DeviceSetNTPServerCfg(access_token *string, req DeviceSetNTPServerCfgReq) (*model.BaseOperationRes, error) {
resp, err := BaseCloudHttpRequest(access_token, "POST", TIM_NTPSERVER_CFG, req)
resp, err := hikvisionRequest(access_token, "POST", TIM_NTPSERVER_CFG, req)
if err != nil {
return nil, err
}

View File

@ -31,7 +31,7 @@ type GroupAddReq struct {
// 该接口用于通过编号来新增组。最多支持3000个组最多支持5层嵌套。
func GroupAdd(access_token *string, req *GroupAddReq) (*model.BaseOperationRes, error) {
resp, err := BaseCloudHttpRequest(access_token, "POST", GROUP_ADD, req)
resp, err := hikvisionRequest(access_token, "POST", GROUP_ADD, req)
if err != nil {
return nil, err
}
@ -54,7 +54,7 @@ type GroupUpdateReq struct {
// 该接口用于通过组编号来删除组。组下面挂有下级节点或者设备的不可以删除,需清空后进行删除。
func GroupUpdate(access_token *string, req *GroupUpdateReq) (*model.BaseOperationRes, error) {
resp, err := BaseCloudHttpRequest(access_token, "POST", GROUP_UPDATE, req)
resp, err := hikvisionRequest(access_token, "POST", GROUP_UPDATE, req)
if err != nil {
return nil, err
}
@ -71,7 +71,7 @@ func GroupUpdate(access_token *string, req *GroupUpdateReq) (*model.BaseOperatio
// 该接口用于通过组编号来删除组。组下面挂有下级节点或者设备的不可以删除,需清空后进行删除。
func GroupRemove(access_token *string, groupNo string) (*model.BaseOperationRes, error) {
resp, err := BaseCloudHttpRequest(access_token, "POST", fmt.Sprintf("%s?groupNo=%s", GROUP_REMOVE, groupNo), nil)
resp, err := hikvisionRequest(access_token, "POST", fmt.Sprintf("%s?groupNo=%s", GROUP_REMOVE, groupNo), nil)
if err != nil {
return nil, err
}
@ -101,7 +101,7 @@ type Group struct {
// 该接口用于通过组编号获取组的详细信息
func CloudGetGroup(access_token *string, groupNo string) (*Group, error) {
resp, err := BaseCloudHttpRequest(access_token, "GET", fmt.Sprintf("%s?groupNo=%s", GROUP_DETAIL, groupNo), nil)
resp, err := hikvisionRequest(access_token, "GET", fmt.Sprintf("%s?groupNo=%s", GROUP_DETAIL, groupNo), nil)
if err != nil {
return nil, err
}
@ -124,7 +124,7 @@ type Groups struct {
// 该接口用于获取所有组。
func GroupGetAll(access_token *string) ([]Group, error) {
resp, err := BaseCloudHttpRequest(access_token, "GET", GROUP_LISTALL, nil)
resp, err := hikvisionRequest(access_token, "GET", GROUP_LISTALL, nil)
if err != nil {
return nil, err
}
@ -141,7 +141,7 @@ func GroupGetAll(access_token *string) ([]Group, error) {
// 该接口用于通过组编号查找某组的下级节点。如果父节点为空,则查询根节点。
func GroupChildList(access_token *string, groupNo string) ([]Group, error) {
resp, err := BaseCloudHttpRequest(access_token, "GET", fmt.Sprintf("%s?parentNo=%s", GROUP_CHILD_LIST, groupNo), nil)
resp, err := hikvisionRequest(access_token, "GET", fmt.Sprintf("%s?parentNo=%s", GROUP_CHILD_LIST, groupNo), nil)
if err != nil {
return nil, err
}

129
iot/hikvision-iot.go Normal file
View File

@ -0,0 +1,129 @@
package cloud
import (
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"net/url"
"os"
"strings"
"time"
)
var (
baseURL = "https://api2.hik-cloud.com/oauth"
clientID = ""
clientSecret = ""
scope = ""
)
func init() {
baseURL = os.Getenv("HIK_IOT_URL")
if baseURL == "" {
baseURL = "https://api2.hik-cloud.com/oauth"
}
}
// 基础云眸http请求
func hikvisionRequest(method string, url string, body interface{}) ([]byte, error) {
b, err := json.Marshal(body)
if err != nil {
return nil, err
}
reqbody := strings.NewReader(string(b))
req, err := http.NewRequest(method, url, reqbody)
if err != nil {
return nil, err
}
token, err := hikvisionOauth()
if err != nil {
return nil, err
}
req.Header.Add("authorization", fmt.Sprintf(" bearer %s", token))
if strings.ToLower(method) == "post" {
req.Header.Add("Content-Type", "application/json")
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return respBody, nil
}
var token string
var expired time.Time
type OauthResponse struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
Scope string `json:"scope"`
}
// 客户端认证获取access_token
func hikvisionOauth() (*string, error) {
if expired.Before(time.Now()) {
return &token, nil
}
params := url.Values{}
params.Add("client_id", clientID)
params.Add("client_secret", clientSecret)
params.Add("grant_type", "client_credentials")
params.Add("scope", scope)
req, err := http.NewRequest("POST", fmt.Sprintf(`%s/token`, baseURL), strings.NewReader(string(params.Encode())))
if err != nil {
return nil, err
}
req.Header.Add("Accept", "*/*")
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
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
}
var result *OauthResponse
if err := json.Unmarshal(respBody, &result); err != nil {
return nil, err
}
token = result.AccessToken
expired = time.Now().Add(time.Duration(result.ExpiresIn) * time.Second)
return &token, nil
}

View File

@ -1,9 +1,8 @@
@url=https://api2.hik-cloud.com/oauth
@token=authorization: bearer a08a8044-3770-41f5-b5a5-048004a723ac
@token_type=bearer
@url=https://api2.hik-cloud.com/api/v1
@token=bearer a08a8044-3770-41f5-b5a5-048004a723ac
### 客户端认证
POST {{url}}/token HTTP/1.1
POST https://api2.hik-cloud.com/oauth/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
client_id=164edfd71b744dd88c945dbd5ae30a9a&client_secret=2f580d932d7d46029a2091ece681035c&grant_type=client_credentials&scope=yy
@ -34,4 +33,4 @@ POST {{url}}/mq/consumer/messages HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Authorization: {{token}}
autoCommit=true&consumerId=7db9420cdb2844f5ba8bba07d1417d54
autoCommit=true&consumerId=7db9420cdb2844f5ba8bba07d1417d54

6
iot/model/group-model.go Normal file
View File

@ -0,0 +1,6 @@
package model
type Groups struct {
Hikvision
Data []Group `json:"data"`
}

View File

@ -1,7 +1,7 @@
package model
// 基础操作回参
type BaseOperationRes struct {
type Hikvision struct {
Code int `json:"code"`
Message string `json:"message"`
}

1
iot/readme.md Normal file
View File

@ -0,0 +1 @@
海康云眸平台IOT