package host import ( "database/sql/driver" "encoding" "encoding/json" "fmt" "strings" "git.lnton.com/lnton/pkg/orm" "github.com/lib/pq" "gorm.io/gorm" ) // Channel 通道 type Channel struct { ID string `gorm:"primaryKey;column:id" json:"id"` // ID CreatedAt orm.Time `gorm:"type:timestamptz;notNull;default:CURRENT_TIMESTAMP;index;comment:创建时间" json:"created_at"` UpdatedAt orm.Time `gorm:"type:timestamptz;notNull;default:CURRENT_TIMESTAMP;comment:更新时间" json:"updated_at"` Enabled bool `gorm:"column:enabled;notNull;default:true;comment:是否启用" json:"enabled"` // 是否启用 Name string `gorm:"column:name;notNull;default:'';comment:通道名称" json:"name"` // 通道名称 DeviceID string `gorm:"column:device_id;notNull;default:'';index;comment:设备ID" json:"device_id"` // 设备 id Protocol string `gorm:"column:protocol;notNull;default:'';comment:通道协议" json:"protocol"` // 通道协议 PTZType int `gorm:"column:ptz_type;notNull;default:0;comment:云台类型" json:"ptz_type"` // 云台类型 Remark string `gorm:"column:remark;notNull;default:'';comment:备注" json:"remark"` // 备注描述 Transport string `gorm:"column:transport;notNull;default:'TCP';comment:传输协议" json:"transport"` // TCP/UDP IP string `gorm:"column:ip;notNull;default:'';comment:IP" json:"ip"` // ip 地址 Port int `gorm:"column:port;notNull;default:0;comment:端口号" json:"port"` // 端口号 Username string `gorm:"column:username;notNull;default:'';comment:用户名" json:"-"` // 用户名 Password string `gorm:"column:password;notNull;default:'';comment:密码" json:"-"` // 密码 BID string `gorm:"column:bid;notNull;default:'';comment:协议专属 id" json:"bid"` PTZ bool `gorm:"column:ptz;notNull;default:FALSE;comment:是否支持 ptz" json:"ptz"` // 是否支持 ptz Talk bool `gorm:"column:talk;notNull;default:FALSE;comment:是否支持对讲" json:"talk"` // 是否支持语音对讲 PID string `gorm:"column:pid;notNull;index;default:'';comment:父通道 ID" json:"pid"` Groups pq.StringArray `gorm:"column:groups;type:text[];default:'{}';comment:虚拟组织" json:"-"` Ext ChannelExt `gorm:"column:ext;type:jsonb;notNull;default:'{}';comment:扩展字段" json:"ext"` ChildCount int `gorm:"column:child_count;notNull;default:0" json:"child_count"` // 子通道数量(不包含子孙通道) Status bool `gorm:"column:status;notNull;default:false;comment:通道状态" json:"status"` LastPushedAt orm.Time `gorm:"column:last_pushed_at;notNull;index;default:'1970-01-01 00:00:00';comment:最后推送时间" json:"last_pushed_at"` // CustomGBID string `gorm:"column:custom_gb_id;notNull;default:'';comment:自定义国标ID" json:"custom_gb_id"` DefaultGBID string `gorm:"column:default_gb_id;notNull;default:'';comment:默认国标ID" json:"default_gb_id"` // 默认国标ID CustomName string `gorm:"column:custom_name;notNull;default:'';comment:自定义名称 " json:"custom_name"` URL string `gorm:"-" json:"url"` // Playing bool `gorm:"-" json:"playing"` // 是否播放中 PlayingStatus string `gorm:"-" json:"playing_status"` IsDir bool `gorm:"-" json:"is_dir"` // 是否目录 RecordPlanEnabled bool `gorm:"-" json:"record_plan_enabled"` // 是否启用了录像计划 CascadeShareEnabled bool `gorm:"-" json:"cascade_share_enabled"` // 是否启用了级联共享 CustomID string `gorm:"-" json:"custom_id"` IsRecording bool `gorm:"-" json:"is_recording"` // 是否配置录像计划 PlanID int `gorm:"-" json:"plan_id"` // 绑定的录像计划 DeviceName string `gorm:"-" json:"device_name"` // 设备名称;单独给前端用的 // 长沙地铁项目 ServerID string `gorm:"column:server_id;notNull;default:'';comment:平台ID" json:"server_id" ` ServerName string `json:"column:server_name;notNull;default:'';comment:平台名称" json:"server_name"` // Latitude float32 // Longitude float32 } func (a ChannelExt) Value() (driver.Value, error) { return json.Marshal(a) } func (c *Channel) GetTransport() string { switch strings.ToUpper(c.Transport) { case "UDP": return "UDP" case "TCPA": return "TCPA" default: return "TCP" } } func (d *Channel) BeforeCreate(tx *gorm.DB) error { d.CreatedAt = orm.Now() d.UpdatedAt = orm.Now() return nil } func (d *Channel) BeforeUpdate(tx *gorm.DB) error { d.UpdatedAt = orm.Now() return nil } // type sortByChannel []*device.SyncReply_Channel // func (a sortByChannel) Len() int { return len(a) } // func (a sortByChannel) Swap(i, j int) { a[i], a[j] = a[j], a[i] } // func (a sortByChannel) Less(i, j int) bool { return a[i].GetBid() < a[j].GetBid() } // ChannelExt 通道的扩展内容,主要集中在国标上 type ChannelExt struct { Parental int `json:"parental"` // 是否有子设备(1:有;0:没有) ParentID string `json:"parent_id"` // 父设备/区域/系统ID } // SetIsDir 设置是否为目录 func (i *Channel) SetIsDir() { i.IsDir = i.ChildCount > 0 || i.Ext.Parental == 1 } // Scan implements orm.Scaner. func (i *ChannelExt) Scan(input interface{}) error { return orm.JsonUnmarshal(input, i) } // UnmarshalBinary implements encoding.BinaryUnmarshaler. func (c *Channel) UnmarshalBinary(data []byte) error { return orm.JsonUnmarshal(data, c) } // MarshalBinary implements encoding.BinaryMarshaler. func (c *Channel) MarshalBinary() (data []byte, err error) { return json.Marshal(c) } var ( _ encoding.BinaryMarshaler = (*Channel)(nil) _ encoding.BinaryUnmarshaler = (*Channel)(nil) ) // GetID 根据不同的设备类型返回 id // func (c *Channel) GetID() string { // switch c.Protocol { // case DeviceTypeSD, DeviceTypeGB, DeviceTypeOnvif, DeviceTypePull: // return c.BID // } // return c.ID // } // GetBID 获取设备BID // BID是通道的实际ID // GB28181: 由设备提供20位纯数字 // ONVIF: 由设备提供可能带有下划线 // PULL: 由平台提供,例如: 01,02(目前只支持单通道) func (c *Channel) GetBID() string { // switch c.Protocol { // case DeviceTypeSD, DeviceTypeGB, DeviceTypeOnvif, DeviceTypePull,DeviceTypePush: // return c.BID // } // return c.ID return c.BID } // GetStreamName 获取流 id func (c *Channel) GetStreamName() string { return fmt.Sprintf("%s_%s", c.DeviceID, c.GetBID()) } // TableName 指定表名 // func (Channel) TableName() string { // return "channels" // } // // // IsGB28181 ... // func (c Channel) IsGB28181() bool { // return c.Protocol == DeviceTypeGB // } // // // IsSaida ... // func (c Channel) IsSaida() bool { // return c.Protocol == DeviceTypeSD // } // // // IsSupportLocalRecord 该协议是否支持本地录像 // func (c *Channel) IsSupportLocalRecord() bool { // return c.Protocol == DeviceTypeSD // }