中化项目-边缘主机维护-前端项目
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

523 lines
15 KiB

import { Component, OnInit, ViewContainerRef } from '@angular/core';
import { ActivatedRoute, Route, Router } from '@angular/router';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { NzFormTooltipIcon } from 'ng-zorro-antd/form';
import { NzModalService } from 'ng-zorro-antd/modal';
import { AddcameraComponent } from './addcamera/addcamera.component';
import { NzMessageService } from 'ng-zorro-antd/message';
import { HttpClient, HttpErrorResponse, HttpResponse } from '@angular/common/http';
import { EditcameraComponent } from './editcamera/editcamera.component';
import { catchError, tap } from 'rxjs/operators';
import { ConfigFormDataService } from 'src/app/service/configFormData.service';
import { SendFileComponent } from './send-file/send-file.component';
import { ImageLabel2Component } from '../image-label2/image-label2.component';
interface Camera {
name: string;
user: string;
password: string;
uri: string;
type: number;
order: number;
dimensionedPoints: string
}
@Component({
selector: 'app-host-config',
templateUrl: './host-config.component.html',
styleUrls: ['./host-config.component.scss']
})
export class HostConfigComponent implements OnInit {
constructor(private router: Router, private route: ActivatedRoute, private fb: FormBuilder, private modal: NzModalService, private message: NzMessageService, private viewContainerRef: ViewContainerRef, private http: HttpClient, public configFormData: ConfigFormDataService,) { }
hostId//主机id
orId//加油站id
ngOnInit(): void {
this.hostId = this.route.snapshot.queryParams.hostId
this.orId = this.route.snapshot.queryParams.orId
this.getCamera()
this.http.get(`/api/EdgeDevices/${this.hostId}`).subscribe(
{
next: ((data: any) => {
console.log(data)
// let isExist = data.configFiles.find((item, index, arr) => {
// if (item.name == 'source.yaml') {
// console.log("存在", index)
// return item
// }
// })
if (data.configFiles) {
this.isSourceYaml = true
} else {
this.isSourceYaml = false
}
}),
error: (err) => {
// this.message.create('error', '请先下发source.yaml配置');
}
}
)
}
listOfData: Camera[] = [];
goback() {
history.go(-1)
}
//摄像头
isLoading = false
getCamera() {
let params = {
ContainsChildren: true,
EdgeDeviceId: this.hostId
}
this.isLoading = true
this.http.get('/api/Cameras',{ params: params }).subscribe((data: any) => {
data.items.forEach(element => {
element.dimensionedPointsObj = JSON.parse(element.dimensionedPoints)
});
this.listOfData = data.items
this.isLoading = false
console.log('摄像头列表', data.items)
})
}
addCamera() {
const modal = this.modal.create({
nzTitle: '新增加油站摄像头',
nzContent: AddcameraComponent,
nzViewContainerRef: this.viewContainerRef,
nzWidth: 388,
nzComponentParams: {},
nzOnOk: async () => {
if (instance.validateForm.valid) {
await new Promise(resolve => {
console.log('表单信息', instance.validateForm)
let body = {
name: instance.validateForm.value.name,
user: instance.validateForm.value.user,
password: instance.validateForm.value.password,
uri: instance.validateForm.value.uri,
type: instance.validateForm.value.type,
organizationId: this.orId,
edgeDeviceId: this.hostId,
order: instance.validateForm.value.order,
}
this.http.post('/api/Cameras', body).subscribe(data => {
resolve(data)
this.message.create('success', '创建成功!');
this.getCamera()
this.isSourceYaml = false
return true
})
})
} else {
this.message.create('warning', '请填写完整!');
return false
}
}
});
const instance = modal.getContentComponent();
}
editCamera(data) {
console.log(data)
const modal = this.modal.create({
nzTitle: '编辑加油站摄像头',
nzContent: EditcameraComponent,
nzViewContainerRef: this.viewContainerRef,
nzWidth: 388,
nzComponentParams: {
data: data
},
nzOnOk: async () => {
if (instance.validateForm.valid) {
await new Promise(resolve => {
console.log('表单信息', instance.validateForm)
let body = {
name: instance.validateForm.value.name,
user: instance.validateForm.value.user,
password: instance.validateForm.value.password,
uri: instance.validateForm.value.uri,
type: instance.validateForm.value.type,
organizationId: this.orId,
edgeDeviceId: this.hostId,
order: instance.validateForm.value.order,
}
this.http.put(`/api/Cameras/${data.id}`, body).subscribe(data => {
resolve(data)
this.message.create('success', '编辑成功!');
this.getCamera()
this.isSourceYaml = false
return true
})
})
} else {
this.message.create('warning', '请填写完整!');
return false
}
}
});
const instance = modal.getContentComponent();
}
deleteCamera(item) {
console.log(item)
this.modal.confirm({
nzTitle: `确定要删除${item.name}这个摄像头吗?`,
nzOkText: '确定',
nzOkType: 'default',
nzOnOk: () => {
this.http.delete(`/api/Cameras/${item.id}`).subscribe(data => {
this.message.create('success', '删除成功!');
this.getCamera()
this.isSourceYaml = false
})
},
nzCancelText: '取消'
});
}
isSourceYaml: boolean
label(item) {
this.http.get(`/api/EdgeDevices/${this.hostId}`).subscribe(
{
next: ((data: any) => {
if (data.configFiles) {
this.isSourceYaml = true
const element = document.documentElement
if(element.requestFullscreen) { //进入全屏
element.requestFullscreen();
}
const modal = this.modal.create({
nzContent: ImageLabel2Component,
nzViewContainerRef: this.viewContainerRef,
nzWidth: 1920,
nzClosable: false,
nzFooter: null,
nzWrapClassName: 'canvasContentBox',
nzBodyStyle: {
'border-radius': '0px',
'padding': '0px',
'margin': '0px',
},
nzComponentParams: {
data: item.id
},
nzOnOk: async () => {
}
});
const instance = modal.getContentComponent();
//this.router.navigate(['/system/host/camera/imageLabel'], { queryParams: { id: item.id } })
} else {
this.isSourceYaml = false
this.message.create('error', '请先下发source.yaml配置');
}
}),
error: (err) => {
// this.message.create('error', '请先下发source.yaml配置');
}
}
)
}
connect() {
let isAllLabel = this.listOfData.find((item: any) => {
if (item.type != 1 && !item.dimensionedPoints) {
console.log('存在摄像头未标注的情况')
return item
}
})
if (isAllLabel) {
this.message.create('error', '存在摄像头未标注的情况');
return
}
let ids = []
this.listOfData.forEach((item: any) => {
ids.push(item.id)
})
this.http.get('/api/Cameras/Statuses', {
params: { ids: ids }
}).subscribe({
next: (data) => {
console.log('连接状态', data)
this.disposalData()
this.router.navigate(['/system/host/camera/configForm'], { queryParams: { 'hostId': this.hostId, 'orId': this.orId } })
},
error: (err) => {
console.log('连接失败', err)
}
})
}
sourceYaml() {
let config4 = `video_rate: 5
inference_buffer_second: 10
sources:`
this.listOfData.forEach((item: any, index) => {
config4 += `
- name: '${item.name}'
user: '${item.user}'
password: '${item.password}'
uri: '${item.uri}'
type: ${item.type}
`
})
const modal = this.modal.create({
nzTitle: '下发source.yaml配置',
nzContent: SendFileComponent,
nzViewContainerRef: this.viewContainerRef,
nzWidth: 1000,
nzBodyStyle: {
'border-radius': '0px',
'padding': '7px',
},
nzComponentParams: {
data: config4
},
nzOnOk: async () => {
await new Promise(resolve => {
console.log('表单信息', instance.validateForm)
let body = {
configFiles: [
{ name: 'source.yaml', content: instance.datacopy }
]
}
this.http.put(`/api/EdgeDevices/${this.hostId}`, body).subscribe({
next: (data) => {
this.message.create('success', `文件保存成功`);
resolve('成功了')
this.isSourceYaml = true
let params = {
edgeDeviceId: this.hostId,
fileName: 'source.yaml'
}
this.http.put('/api/EdgeDevices/Commands/PushFile', '', { params: params }).subscribe({
next: (data) => {
this.message.create('success', `发送文件名成功`);
},
error: err => {
// this.message.create('error', `发送文件名失败`);
// reject('失败了')
}
})
},
error: (err) => {
// this.message.create('error', `文件保存失败`);
}
})
})
}
});
const instance = modal.getContentComponent();
}
//整理配置文件数据
disposalData() {
console.log(this.listOfData)
let config1 = `[property]
enable=1
#Width height used for configuration to which below configs are configured
config-width=1980
config-height=1080
#osd-mode 0: Dont display any lines, rois and text
# 1: Display only lines, rois and static text i.e. labels
# 2: Display all info from 1 plus information about counts
osd-mode=2
#Set OSD font size that has to be displayed
display-font-size=12
`
let config2 = ''
let config3 = `test_action: true
logging_interval : 600
`
let xieyouqu = []
this.listOfData.forEach((item: any, index) => {
if (item.type == 2) { xieyouqu.push(item) }
if (item.type == 0) {
let str = ''
item.dimensionedPointsObj.polygon.forEach(element => {
str += element.x + ','
str += element.y + ','
});
str = str.substring(0, str.lastIndexOf(','))
console.log('进出口多边形', str)
config1 += `
## Per stream configuration
[roi-filtering-stream-${item.order}]
#shoushiyuan-out202
#enable or disable following feature
enable=1
#ROI to filter select objects, and remove from meta data
roi-RF=${str}
#remove objects in the ROI
inverse-roi=0
class-id=-1
`
}
if ((item.type == 2 || item.type == 3) && item.dimensionedPointsObj) {
let arrowArr = item.dimensionedPointsObj.arrow
let str = arrowArr[0].startX + ',' + arrowArr[0].startY + ',' + arrowArr[0].endX + ',' + arrowArr[0].endY + ',' + arrowArr[1].startX + ',' + arrowArr[1].startY + ',' + arrowArr[1].endX + ',' + arrowArr[1].endY
console.log('十字箭头', str)
config1 += `
[line-crossing-stream-${item.order}]
enable=1
#Label;direction;lc
line-crossing-Entry=${str}
# line-crossing-Exit=789;672;1084;900;851;773;1203;732
class-id=0
#extended when 0- only counts crossing on the configured Line
# 1- assumes extended Line crossing counts all the crossing
extended=0
#LC modes supported:
#loose : counts all crossing without strong adherence to direction
#balanced: Strict direction adherence expected compared to mode=loose
#strict : Strict direction adherence expected compared to mode=balanced
mode=strict
`
}
})
if (xieyouqu.length != 1) {
this.message.create('warning', '有且只能有一个卸油区!');
return
} else {
let xieyouguan = ''
let jingdian = ''
xieyouqu[0].dimensionedPointsObj.rectangle.forEach(element => {
if (element.oilUnloadingArea) {
xieyouguan = element.x + ',' + element.y + ',' + element.width + ',' + element.height
} else {
jingdian = element.x + ',' + element.y + ',' + element.width + ',' + element.height
}
});
console.log('泄油管区域', xieyouguan)
console.log('静电接地', jingdian)
config2 = `# The all in one config file.
# RTSP sources
# type
# 0 ViolateArea.ENTRANCE,
# 1 ViolateArea.GAS_AREA,
# 2 ViolateArea.FUEL_AREA,
# 3 ViolateArea.MART,
# don't change the key name.
debug: true #when the debug is on, osd.
sources:
config: 'config/source.yaml'
tracker:
config: 'config/dstest_tracker_config.txt'
analytics:
config: 'config/config_nvdsanalytics.txt'
peoplenet:
enable: true
apply_on: -1
interval: 1
batch_size: 16
topk: 5
roi-top-offset: 0
roi-bottom-offset: 0
detected-min-w: 20
detected-min-h: 200
trafficcam:
enable: true
apply_on: 0
interval: 1
batch_size: 16
topk: 5
roi-top-offset: 0
roi-bottom-offset: 0
detected-min-w: 100
detected-min-h: 100
actionnet:
enable: false
apply_on: 1
# roi:
# - 'fuel_island-4':
# - [200, 0, 450, 500]
# - 'fuel_island-5':
# - [930, 93, 940, 987]
# - 'fuel_island-6':
# - [1174, 151, 746, 929]
# - 'fuel_island-7':
# - [1450, 300, 460, 650]
interval: 1
batch_size: 32
idnet:
enable: true
apply_on: -1
interval: 1
batch_size: 32
oilnet:
enable: true
apply_on: 2
interval: 1
batch_size: 16
roi-top-offset: 0
roi-bottom-offset: 0
detected-min-w: 20
detected-min-h: 20
fire_smoke_net:
enable: true
apply_on: -1
interval: 1
batch_size: 16
smoking_calling_net:
enable: true
apply_on: -1
interval: 1
batch_size: 32
connet:
enable: true
apply_on: 2
roi:
- 'oil_tube-3':
- [${xieyouguan}]
- 'grounder-3':
- [${jingdian}]
interval: 1
batch_size: 2
#new field for rule threshold
rule_threshold:
object_occurence_interval_second: 15
object_disappear_interval_second: 60
on_car_parking_interval_second: 1800
on_fire_smoke_interval_second: 5
threshold_relying_sitting: 0.4 #rolling mean confidence
threshold_smoking_calling: 0.5 #rolling mean confidence
threshold_connecting: 0.667 #rolling mean confidence
threshold_identity: 0.1 #only to filter out people net error
`
}
sessionStorage.setItem('config1', config1)
sessionStorage.setItem('config2', config2)
sessionStorage.setItem('config3', config3)
}
}