TMRAppBle/html/echarts_circle.html

724 lines
30 KiB
HTML
Raw Normal View History

2023-10-19 15:00:17 +08:00
<!-- <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../script/echarts.js"></script>
<script src="../script/api.js"></script>
</head>
<style>
.echarts_wrap {
width: 100%;
height: 96vh;
/* background-color: black; */
display: flex;
justify-content: center;
align-items: center;
}
.echarts_item {
width: 35%;
height: 96vh;
}
.echarts_item1 {
width: 30%;
height: 96vh;
}
.header_btn {
background-color: #407ae6;
color: #ffffff;
font-size: 20px;
height: 50px;
font-weight: 900;
width: 100%;
}
</style>
<body>
<div class="echarts_wrap">
<div class="echarts_item" id="echarts_main_one"></div>
<div class="echarts_item" id="echarts_main_two"></div>
<div class="echarts_item1" >
<div class="header_led_text" id="beforeWeight"></div>
<div class="header_led_text" id="nowWeight">称实时重量:</div>
<button type="button" class="header_btn" onclick="weightFix()">校准装料前重量</button>
<text style="color: red;font-size: 14px;">请在装料前校准,装料过程中禁止校准</text>
</div>
</div>
<script type="text/javascript">
// 初始化echarts Dom
var weightChartDom = document.getElementById('echarts_main_two');
var weightMyChart = echarts.init(weightChartDom);
var feedChartDom = document.getElementById('echarts_main_one');
var feedMyChart = echarts.init(feedChartDom);
// 语言播报路径 讯飞语言引擎appid
var android_appid = '3cbf130a';
var audioPath = 'fs://speechRecogniser/read.mp3';
// 字符卡通信配置
var zifukaHost = '';
var zifukaPort = null;
// 称重通信配置
var weightHost = '';
var weightPort = null;
// 称重通信连接id
var sid;
// 装料状态还是卸料状态
var load = true;
// 是否是该车次第一个料
var isFirst = getUrlParam("isFirst")
//之前总重量,车次计划总量:计划量,实时总重量,已装量,剩余量,允许误差
var beforeWeight = getUrlParam('beforeWeight');
$api.html($api.byId("beforeWeight"),"装料前重量:"+(beforeWeight?beforeWeight:''));
var _weightSum = getUrlParam('total');
var _planSum = getUrlParam('plan');
var nowWeight = 0;
var _feedNum = 0;
var allow = getUrlParam("allow")
// 定义语言引擎,字符卡
var tts;
var zfk;
// 定义称重稳定滤波数组
var weightArray = [];
//echarts公共参数
var ROOT_PATH = 'https://echarts.apache.org/examples';
var _panelImageURL = ROOT_PATH + '/data/asset/img/custom-gauge-panel.png';
var _outerRadius = 220;
var _innerRadius = 170;
var zfkList = [];
var feedName;
var _pointerInnerRadius = 20;
var _insidePanelRadius = 160;
var fontsize = 70;
var lastZfkMsg = ''
apiready = function () {
lastZfkMsg = ''
api.setGlobalData({ key: 'wendin', value: false });
// 判断是装料还是卸料
if (getUrlParam('type') == 1) {
load = true;
} else {
load = false;
}
// console.log(allow);
weightArray = []
resizeWindow()
var feedJson = { plan: _planSum, feed: _feedNum, id: getUrlParam('id'), beforeWeight: nowWeight, type: getUrlParam('type') }
api.setGlobalData({ key: 'feedJson', value: feedJson });
// 渲染装料echarts
renderUnload()
// 渲染总重量echarts
renderLoad()
// 称重通信服务初始化
startWeightService()
clearInterval(interv)
var interv = setInterval(function () {
// console.log("监听消息"+ api.getGlobalData({ key: 'feedName' }) + Number(_planSum - _feedNum).toFixed(0));
// 判断字符卡服务和饲料名称都存在且上次字符卡消息不等于当前要发的消息
if(zfk!=undefined && feedName!='' && lastZfkMsg != api.getGlobalData({ key: 'feedName' }) + Number(_planSum - _feedNum).toFixed(0)){
lastZfkMsg = api.getGlobalData({ key: 'feedName' }) + Number(_planSum - _feedNum).toFixed(0);
var param={
start:"78 ",
ver:'34 ',
addr:'01 00 ',
cmd:'29 ',
ident:'BC FD 00 00 ',
frame:'00 00 00 00 ',
end:'A5',
msg: lastZfkMsg,
diskId:'01 00 ',
encode:'01 ',
show:'02 ',
color:'01 '
}
if(zfkList && zfkList.length >0 ){
var sourceCow = api.getPrefs({sync: true,key: 'sourceCow'});
var LedType = api.getPrefs({sync: true,key: 'LedType'});
zfkList.forEach(e => {
// 奶二版本
if(sourceCow == 2){
param.addr = e+" ";
zfk.send(param, function (ret, err) {
// console.log(JSON.stringify(ret));
api.setGlobalData({ key: 'sendMsg', value: ret.sendMsg });
console.log(ret.sendMsg);
if (!ret.status) {
console.warn("字符卡发送失败");
}
})
}
})
}
}
}, 1000);
}
function startWeightService() {
// console.log('http://192.168.0.107:8088/app/tmr/appService?deviceId=' + api.deviceId + '&sbId='+api.getGlobalData({ key: 'sbId' }));
// 查询称重服务配置并启动
api.ajax({
// url: 'http://192.168.0.107:8088/app/tmr/appService?sbId='+api.getGlobalData({ key: 'sbId' }),
url: 'https://tmr.nxcyx.com/api/app/tmr/appService?sbId='+api.getGlobalData({ key: 'sbId' }),
method: 'get',
}, function (ret, err) {
ret.data.forEach(e => {
if (e.serviceName == 'weight') {
weightHost = e.param.host;
weightPort = e.param.port;
api.setGlobalData({ key: 'weightTcp', value: weightHost + ':' + weightPort });
// console.log('*****************************'+e.serviceName+" "+e.param.host+':'+e.param.port+'*****************************');
} else if (e.serviceName == 'zfk') {
zfkList = e.param.addrList;
zifukaHost = e.param.host;
zifukaPort = Number(e.param.port);
api.setGlobalData({ key: 'zfkTcp', value: zifukaHost + ':' + zifukaPort });
api.setGlobalData({ key: 'addrList', value: e.param.addrList});
initReadStrAndLedSend()
setTimeout(() => {
initWeightService()
}, 1000);
}
})
})
// 定时语言播报误差值并发送给LED屏
// setInterval(function () {
// var err = _planSum - _feedNum;
// var feedName = api.getGlobalData({
// key: 'feedName'
// });
// var str = feedName + "差" + err + "kg";
// // readStr(str)
// zfk.send({ msg: feedName + "差" + err + "kg" }, function (ret, err) {
// if (!ret.status) {
// console.warn("字符卡发送失败");
// }
// })
// }, 6000)
}
// 之前重量矫正,抓取实时重量并赋值
function weightFix(){
api.confirm({
title: '提醒',
msg: '确认重新校准装料前称总重量么?',
buttons: ['确认', '取消']
}, function (ret, err) {
if (1 == ret.buttonIndex) {
beforeWeight = nowWeight;
// console.log("校准完重量为"+beforeWeight);
api.setGlobalData({ key: 'beforeWeight', value: beforeWeight });
$api.html($api.byId("beforeWeight"),"装料前重量:"+beforeWeight);
}
});
}
function initWeightService() {
var s = api.require('socketManager');
var sssid = api.getGlobalData({ key: 'sid' });
// console.log(sssid);
if (sssid) {
s.closeSocket({ sid: sssid }, function (ret, err) {
// console.log(JSON.stringify(ret));
});
}
s.createSocket({ host: weightHost, port: weightPort }, function (ret, err) {
if (ret.state == 101) {
// console.log("192.168.0.107连接中");
} else if (ret.state == 102) {
// console.log("192.168.0.107连接成功");
sid = ret.sid;
// console.log(sid);
api.setGlobalData({ key: 'sid', value: ret.sid });
} else if (ret.state == 103) {
// 如果是手动清零需要刷新页面
// 实时获取回传重量信息
nowWeight = Number(ret.data)
// 第一次装料当前重量即等于之前重量,不一定为0
if (undefined == beforeWeight && isFirst) {
readStr("开始装料" + api.getGlobalData({ key: 'feedName' }) + _planSum + "kg")
// console.log("*********************装料前车总重量"+nowWeight+"*********************");
beforeWeight = nowWeight
// 设置装料前车次基础重量
api.setGlobalData({ key: 'beforeWeight', value: beforeWeight });
}
$api.html($api.byId("beforeWeight"),"装料前重量:"+beforeWeight);
// 设置卸料完后车次基础重量
api.setGlobalData({ key: 'totalWeight', value: nowWeight });
// 计算装料卸料已装重量
if (load) {
_feedNum = nowWeight - beforeWeight;
} else {
_feedNum = beforeWeight - nowWeight;
}
// 计算计划和实际误差值
var err = _planSum - _feedNum;
// 获取饲料名称
var feedName = api.getGlobalData({
key: 'feedName'
});
ifWeightWendin(err)
// 实时更新饲料计划量,装载量,饲料id,之前重量,装料类型
var feedJson = { plan: _planSum, feed: _feedNum, id: getUrlParam('id'), beforeWeight: nowWeight, type: getUrlParam('type') }
api.setGlobalData({ key: 'feedJson', value: feedJson });
if(zfkList && zfkList.length >0 ){
var sourceCow = api.getPrefs({sync: true,key: 'sourceCow'});
if(sourceCow != 2){
zfkList.forEach(e => {
var param1={
SF:"AA A5 ",
LEN:'1A 00 ',
DES:'01 01 ',
SRC:'12 34 ',
TID:'B0 A1 ',
CMD1:'38 02 ',
X:'00 00 ',
Y:'00 00 ',
WIDTH:'40 00 ',
HEIGHT:'20 00 ',
FORMAT:'00 00 01 00 ',
CNT:'04 00 ',
CRC:'00 00 ',
EF:'5A 55 ',
msg:''
}
var newmsg = api.getGlobalData({ key: 'feedName' });
if(newmsg.length == 1){
newmsg = newmsg+":还"
}else if(newmsg.length == 2){
newmsg = newmsg+""
}
param1.DES = e+" ";
param1.msg = newmsg.substr(0,4) +"差"+ Number(_planSum - _feedNum).toFixed(0)
zfk.send1(param1, function (ret, err) {
console.log(ret.sendMsg);
if (!ret.status) {
console.warn("字符卡发送失败");
}
})
// // 奶二版本
// if(sourceCow == 2){
// }else{
// }
})
}
}
// 实时渲染echarts图
feedMyChart.setOption({
dataset: {
// source: [[1, err]]
source: [[1, _feedNum]]
}
})
weightMyChart.setOption({
dataset: {
source: [[1, nowWeight]]
}
})
} else {
console.warn("*********************称重连接失败*********************")
api.alert({ msg: '称服务连接失败,请检查配置' });
}
})
}
function ifWeightWendin(err) {
// 重量稳定判断
var countSize = 30;
if (Math.abs(err) <= allow) {
weightArray.push(nowWeight);
} else {
weightArray = []
}
weightArray.push(nowWeight);
if (weightArray.length > countSize && Math.abs(err) <= allow) {
weightArray.splice(0, 1)
var arr = weightArray;
var count = 0
for (var i = 0; i < arr.length - 1; i++) {
if (arr[i] != 0) {
count += arr[i + 1] - arr[i]
}
}
// console.log(Math.abs(err) / _planSum);
// 判断最近30条数据平均值是否小于允许误差,并且误差在5%以下
// console.log(err+"/"+Math.abs(err) / _planSum + "/"+ allow);
if (nowWeight && (count / countSize) <= allow && (Math.abs(err) / _planSum < 0.05)) {
// console.log("*********************重量已经稳定,且在误差允许范围内*********************");
api.setGlobalData({ key: 'wendin', value: true });
weightArray = [];
} else {
weightArray = [];
// console.log("重量未稳定,请等待");
api.setGlobalData({ key: 'wendin', value: false });
}
}
}
function initReadStrAndLedSend() {
// 初始化讯飞语言引擎和字符卡通信
tts = api.require('iflyRecognition');
zfk = api.require("moduleDemo");
var param = {
host:zifukaHost,
port:zifukaPort,
};
// console.log(JSON.stringify(param));
zfk.createTcp(param, function (ret, err) {
if (!ret.status) {
console.log("字符卡连接异常");
api.alert({ msg: '字符卡连接异常,请检查配置' });
}
})
tts.createUtility({
android_appid: android_appid
}, function (ret, err) {
if (!ret.status) {
console.warn("语音引擎创建失败");
}
});
}
//语言播报指定内容
function readStr(str) {
tts.read({
readStr: str,
speed: 0,
volume: 100,
voice: "xiaoyan",
rate: 16000,
audioPath: audioPath
}, function (ret, err) {
if (ret.status) {
ret.speakProgress
} else {
console.warn("语言播报异常");
}
});
}
function resizeWindow() {
// 获取当前屏幕宽度,高度
var winWidth = api.winWidth;
var winHeight = api.winHeight;
if (winWidth < 800) {
_outerRadius = 82
_innerRadius = 70
_insidePanelRadius = 65
fontsize = 25
} else if (winWidth < 1200) {
_outerRadius = 105
_innerRadius = 80
_insidePanelRadius = 75
fontsize = 30
}
}
function getUrlParam(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
var r = window.location.search.substr(1).match(reg); //匹配目标参数
if (r != null) return unescape(r[2]); return null; //返回参数值
}
function convertToPolarPoint(renderItemParams, radius, radian) {
return [
Math.cos(radian) * radius + renderItemParams.coordSys.cx,
-Math.sin(radian) * radius + renderItemParams.coordSys.cy
];
}
function makePionterPoints(renderItemParams, polarEndRadian) {
return [
convertToPolarPoint(renderItemParams, _outerRadius, polarEndRadian),
convertToPolarPoint(
renderItemParams,
_outerRadius,
polarEndRadian + Math.PI * 0.03
),
convertToPolarPoint(renderItemParams, _pointerInnerRadius, polarEndRadian)
];
}
//计划量/已装量echarts参数
function renderItemFeed(params, api) {
var valOnRadian = api.value(1);
var coords = api.coord([api.value(0), valOnRadian]);
var polarEndRadian = coords[3];
var imageStyle = {
image: _panelImageURL,
x: params.coordSys.cx - _outerRadius,
y: params.coordSys.cy - _outerRadius,
width: _outerRadius * 2,
height: _outerRadius * 2
};
return {
type: 'group',
children: [
{
type: 'image',
style: imageStyle,
clipPath: {
type: 'sector',
shape: {
cx: params.coordSys.cx,
cy: params.coordSys.cy,
r: _outerRadius,
r0: _innerRadius,
startAngle: 0,
endAngle: -polarEndRadian,
transition: 'endAngle',
enterFrom: { endAngle: 0 }
}
}
},
{
type: 'image',
style: imageStyle,
clipPath: {
type: 'polygon',
shape: {
points: makePionterPoints(params, polarEndRadian)
},
extra: {
polarEndRadian: polarEndRadian,
transition: 'polarEndRadian',
enterFrom: { polarEndRadian: 0 }
},
during: function (apiDuring) {
apiDuring.setShape(
'points',
makePionterPoints(params, apiDuring.getExtra('polarEndRadian'))
);
}
}
},
{
type: 'circle',
shape: {
cx: params.coordSys.cx,
cy: params.coordSys.cy,
r: _insidePanelRadius
},
style: {
fill: '#fff',
shadowBlur: 25,
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowColor: 'rgba(76,107,167,0.4)'
}
},
{
type: 'text',
extra: {
valOnRadian: valOnRadian,
transition: 'valOnRadian',
enterFrom: { valOnRadian: 0 }
},
style: {
text: makeTextFeed(valOnRadian),
fontSize: fontsize,
fontWeight: 900,
x: params.coordSys.cx,
y: params.coordSys.cy,
fill: 'rgb(255, 0, 0)',
align: 'center',
verticalAlign: 'middle',
enterFrom: { opacity: 0 }
},
during: function (apiDuring) {
apiDuring.setStyle(
'text',
makeTextFeed(apiDuring.getExtra('valOnRadian'))
);
}
}
]
};
}
function makeTextFeed(valOnRadian) {
if (load) {
// return '剩余应装\n' + valOnRadian.toFixed(1) + 'kg';
return api.getGlobalData({ key: 'feedName' }) + '差\n' + (_planSum - _feedNum).toFixed(0) + 'kg';
} else {
// return '剩余应卸\n' + valOnRadian.toFixed(1) + 'kg';
return api.getGlobalData({ key: 'feedName' }) + '差\n' + (_planSum - _feedNum).toFixed(0) + 'kg';
}
}
function renderLoad(title) {
var weightOption = {
animation: false,
dataset: {
source: [[1, nowWeight]]
},
title: {
// text:'总重量/剩余量'
// text:title
},
tooltip: {},
angleAxis: {
type: 'value',
startAngle: 0,
show: false,
min: 0,
max: _weightSum
},
radiusAxis: {
type: 'value',
show: false
},
polar: {},
series: [
{
type: 'custom',
coordinateSystem: 'polar',
renderItem: renderItemWeight
}
]
};
weightOption && weightMyChart.setOption(weightOption);
}
function renderUnload() {
var feedOption = {
animation: false,
dataset: {
// source: [[1, _planSum]]
source: [[1, _feedNum]]
},
tooltip: {},
angleAxis: {
type: 'value',
startAngle: 0,
show: false,
min: 0,
max: _planSum
},
radiusAxis: {
type: 'value',
show: false
},
polar: {},
series: [
{
type: 'custom',
coordinateSystem: 'polar',
renderItem: renderItemFeed
}
]
};
feedOption && feedMyChart.setOption(feedOption);
}
//总重量/剩余量echarts参数
function renderItemWeight(params, api) {
var valOnRadian = api.value(1);
var coords = api.coord([api.value(0), valOnRadian]);
var polarEndRadian = coords[3];
var imageStyle = {
image: _panelImageURL,
x: params.coordSys.cx - _outerRadius,
y: params.coordSys.cy - _outerRadius,
width: _outerRadius * 2,
height: _outerRadius * 2
};
return {
type: 'group',
children: [
{
type: 'image',
style: imageStyle,
clipPath: {
type: 'sector',
shape: {
cx: params.coordSys.cx,
cy: params.coordSys.cy,
r: _outerRadius,
r0: _innerRadius,
startAngle: 0,
endAngle: -polarEndRadian,
transition: 'endAngle',
enterFrom: { endAngle: 0 }
}
}
},
{
type: 'image',
style: imageStyle,
clipPath: {
type: 'polygon',
shape: {
points: makePionterPoints(params, polarEndRadian)
},
extra: {
polarEndRadian: polarEndRadian,
transition: 'polarEndRadian',
enterFrom: { polarEndRadian: 0 }
},
during: function (apiDuring) {
apiDuring.setShape(
'points',
makePionterPoints(params, apiDuring.getExtra('polarEndRadian'))
);
}
}
},
{
type: 'circle',
shape: {
cx: params.coordSys.cx,
cy: params.coordSys.cy,
r: _insidePanelRadius
},
style: {
fill: '#fff',
shadowBlur: 25,
shadowOffsetX: 0,
shadowOffsetY: 0,
shadowColor: 'rgba(76,107,167,0.4)'
}
},
{
type: 'text',
extra: {
valOnRadian: valOnRadian,
transition: 'valOnRadian',
enterFrom: { valOnRadian: 0 }
},
style: {
text: makeTextWeight(valOnRadian),
fontSize: fontsize,
fontWeight: 900,
x: params.coordSys.cx,
y: params.coordSys.cy,
fill: 'rgb(0, 0, 0)',
align: 'center',
verticalAlign: 'middle',
enterFrom: { opacity: 0 }
},
during: function (apiDuring) {
apiDuring.setStyle(
'text',
makeTextWeight(apiDuring.getExtra('valOnRadian'))
);
}
}
]
};
}
function makeTextWeight(valOnRadian) {
return '总装料重\n' + valOnRadian.toFixed(0) + 'kg';
}
</script>
</body>
</html> -->