32 changed files with 1391 additions and 405 deletions
@ -1,73 +0,0 @@ |
|||
package org.nl.acs.agv; |
|||
|
|||
import cn.hutool.core.collection.CollUtil; |
|||
import cn.hutool.http.HttpRequest; |
|||
import cn.hutool.http.HttpResponse; |
|||
import com.alibaba.fastjson.JSONObject; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.nl.acs.AcsConfig; |
|||
import org.nl.acs.instruction.domain.Instruction; |
|||
import org.nl.acs.instruction.service.InstructionService; |
|||
import org.nl.config.SpringContextHolder; |
|||
import org.nl.system.service.param.ISysParamService; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 定时查询AGV状态 |
|||
*/ |
|||
@Slf4j |
|||
@Component("queryAGVStatus") |
|||
public class QueryAGVStatus { |
|||
|
|||
public void run() { |
|||
InstructionService instructionService = SpringContextHolder.getBean(InstructionService.class); |
|||
ISysParamService paramService = SpringContextHolder.getBean(ISysParamService.class); |
|||
List<Instruction> allInstFromCache = instructionService.findAllInstFromCache(); |
|||
if (CollUtil.isEmpty(allInstFromCache) || allInstFromCache.size() < 1) { |
|||
return; |
|||
} |
|||
for (Instruction instruction : allInstFromCache) { |
|||
if ("4".equals(instruction.getInstruction_type())) { |
|||
String agvurl = paramService.findByCode(AcsConfig.AGV_URL).getValue(); |
|||
JSONObject param = new JSONObject(); |
|||
agvurl = agvurl + ":/" + instruction.getInstruction_code(); |
|||
log.info("根据运单号查询运单状态的请求:{}", agvurl); |
|||
HttpResponse result = HttpRequest.get(agvurl) |
|||
.timeout(20000)//超时,毫秒
|
|||
.execute(); |
|||
log.info("根据运单号查询运单状态的请求反馈:{}", result); |
|||
String body = result.body(); |
|||
JSONObject json = JSONObject.parseObject(body); |
|||
if (result.getStatus() == 200 && json.getString("id").equals(instruction.getInstruction_code())) { |
|||
// 已创建=CREATED,
|
|||
// 待分配=TOBEDISPATCHED,
|
|||
// 正在执行=RUNNING,
|
|||
// 完成=FINISHED,
|
|||
// 失败=FAILED(主动失败),
|
|||
// 终止=STOPPED(被人为终止),
|
|||
// 无法执行=Error(参数错误),
|
|||
// 等待=WAITING
|
|||
//执行中
|
|||
String state = json.getString("state"); |
|||
if ("RUNNING".equals(state) || "CREATED".equals(state) || "TOBEDISPATCHED".equals(state) || "WAITING".equals(state)) { |
|||
instruction.setInstruction_status("1"); |
|||
instructionService.update(instruction); |
|||
} else if ("FINISHED".equals(state)) { |
|||
instruction.setInstruction_status("2"); |
|||
try { |
|||
instructionService.finish(instruction); |
|||
} catch (Exception e) { |
|||
log.error("执行完成,但无法更新状态,可能由于参数错误导致的异常"); |
|||
e.printStackTrace(); |
|||
} |
|||
} else if ("STOPPED".equals(state) || "FAILED".equals(state) || "Error".equals(state)) { |
|||
instruction.setInstruction_status("1"); |
|||
instructionService.update(instruction); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,424 @@ |
|||
package org.nl.acs; /** |
|||
* Created by admin on 2019/8/21. |
|||
*/ |
|||
|
|||
import onbon.bx06.Bx6GEnv; |
|||
import onbon.bx06.Bx6GScreen; |
|||
import onbon.bx06.Bx6GScreenClient; |
|||
import onbon.bx06.area.*; |
|||
import onbon.bx06.area.page.ImageFileBxPage; |
|||
import onbon.bx06.area.page.TextBxPage; |
|||
import onbon.bx06.area.page.TextFileBxPage; |
|||
import onbon.bx06.cmd.dyn.DynamicBxAreaRule; |
|||
import onbon.bx06.file.ProgramBxFile; |
|||
import onbon.bx06.message.common.ErrorType; |
|||
import onbon.bx06.message.led.ReturnControllerStatus; |
|||
import onbon.bx06.message.tcp.ReturnNetwork; |
|||
import onbon.bx06.series.Bx6Card; |
|||
import onbon.bx06.series.Bx6E; |
|||
import onbon.bx06.utils.DisplayStyleFactory.DisplayStyle; |
|||
import onbon.bx06.utils.DisplayStyleFactory; |
|||
import onbon.bx06.utils.TextBinary; |
|||
|
|||
import java.awt.*; |
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* @program: bx06_demo |
|||
* @description: |
|||
* @author: Mr.Feng |
|||
* @create: 2019-08-21 14:52 |
|||
**/ |
|||
public class bx06_demo { |
|||
private static String ip = "192.168.81.56"; |
|||
private static int port = 5005; |
|||
public static void main(String[] args)throws Exception |
|||
{ |
|||
// 初始化API,此操作只在程序启动时候执行一次即可,多次执行会出现内存错误
|
|||
Bx6GEnv.initial(30000); |
|||
SendDynamicProgram(); |
|||
} |
|||
|
|||
// 将一个节目发送到控制器
|
|||
public static void SendProgram()throws Exception |
|||
{ |
|||
// 关于显示特技
|
|||
// 0:随机显示
|
|||
// 1:静止显示
|
|||
// 2:快速打出
|
|||
// 3:向左移动
|
|||
// 4:向左连移
|
|||
// 5:向上移动
|
|||
// 6:向上连移
|
|||
// 7:闪烁
|
|||
// 8:飘雪
|
|||
// 9:冒泡
|
|||
// 10:中间移出
|
|||
// 11:左右移入
|
|||
// 12:左右交叉移入
|
|||
// 13:上下交叉移入
|
|||
// 14:花卷闭合
|
|||
// 15:花卷打开
|
|||
// 16:向左拉伸
|
|||
// 17:向右拉伸
|
|||
// 18:向上拉伸
|
|||
// 19:向下拉伸
|
|||
// 20:向左镭射
|
|||
// 21:向右镭射
|
|||
// 22:向上镭射
|
|||
// 23:向下镭射
|
|||
// 24:左右交叉拉幕
|
|||
// 25:上下交叉拉幕
|
|||
// 26:分散左拉
|
|||
// 27:水平百叶
|
|||
// 28:垂直百叶
|
|||
// 29:向左拉幕
|
|||
// 30:向右拉幕
|
|||
// 31:向上拉幕
|
|||
// 32:向下拉幕
|
|||
// 33:左右闭合
|
|||
// 34:左右对开
|
|||
// 35:上下闭合
|
|||
// 36:上下对开
|
|||
// 37;向右移动
|
|||
// 38:向右连移
|
|||
// 39:向下移动
|
|||
// 40:向下连移
|
|||
// 41:45度左旋
|
|||
// 42:180度左旋
|
|||
// 43:90度右旋
|
|||
// 44:45度右旋
|
|||
// 45:180度右旋
|
|||
// 46:90度右旋
|
|||
// 47:菱形打开
|
|||
// 48:菱形闭合
|
|||
DisplayStyle[] styles = DisplayStyleFactory.getStyles().toArray(new DisplayStyle[0]); |
|||
|
|||
// 创建screen对象,用于与控制卡的交互
|
|||
// 第二个参数是控制卡型号,只有型号对才能正常通讯,否则会出现逾时未回应,如果使用的型号API中未定义,用new Bx6M()替代
|
|||
Bx6GScreenClient screen = new Bx6GScreenClient( "MyScreen",new Bx6E() ); |
|||
|
|||
// 连接控制器
|
|||
screen.connect( ip,port); |
|||
|
|||
// 创建节目 一个节目相当于一屏显示内容
|
|||
ProgramBxFile pf = new ProgramBxFile( "P000",screen.getProfile() ); |
|||
|
|||
// 创建一个分区
|
|||
// 分别输入X,Y,width,heigth
|
|||
// 注意区域坐标和宽度高度不要越界
|
|||
TextCaptionBxArea area = new TextCaptionBxArea( 0,0,160,64,screen.getProfile() ); |
|||
|
|||
// 创建一个数据页
|
|||
// 第一行数据
|
|||
TextBxPage page = new TextBxPage("仰邦科技欢迎你!"); |
|||
// 第二行数据
|
|||
page.newLine( "这是第二行数据" ); |
|||
// 设置字体
|
|||
page.setFont( new Font("宋体", Font.PLAIN,12) ); |
|||
// 设置显示特技为快速打出
|
|||
page.setDisplayStyle( styles[2] ); |
|||
|
|||
// 数据页可以是图片
|
|||
ImageFileBxPage iPage = new ImageFileBxPage( "D:a/004.bmp" ); |
|||
|
|||
// 数据页可以是txt文件
|
|||
TextFileBxPage tPage = new TextFileBxPage( "D:a/001.txt" ); |
|||
|
|||
// 将前面的page添加到area中,page不可以是表格,如果需要Led显示表格,请先将表格绘制成图片
|
|||
area.addPage( page ); |
|||
area.addPage( iPage ); |
|||
area.addPage( tPage ); |
|||
|
|||
// 将area添加到节目中,节目中可以添加多个area
|
|||
pf.addArea( area ); |
|||
|
|||
// 更新节目
|
|||
screen.writeProgram( pf ); |
|||
|
|||
// 断开连接
|
|||
screen.disconnect(); |
|||
|
|||
} |
|||
|
|||
// 将多个节目发送到控制器并显示
|
|||
public static void SendPrograms()throws Exception |
|||
{ |
|||
DisplayStyle[] styles = DisplayStyleFactory.getStyles().toArray(new DisplayStyle[0]); |
|||
|
|||
Bx6GScreenClient screen = new Bx6GScreenClient( "MyScreen",new Bx6E() ); |
|||
|
|||
screen.connect( ip,port ); |
|||
|
|||
ProgramBxFile pf = new ProgramBxFile( "P000",screen.getProfile() ); |
|||
|
|||
// 创建一个时间区
|
|||
DateTimeBxArea dtArea = new DateTimeBxArea( 0,0,160,64,screen.getProfile() ); |
|||
|
|||
// 设定时间区多行显示
|
|||
dtArea.setMultiline( true ); |
|||
|
|||
// 设定日期显示格式 NULL表示不显示日期
|
|||
dtArea.setDateStyle( DateStyle.YYYY_MM_DD_1 ); |
|||
// 设定时间显示格式 NULL表示不显示时间
|
|||
dtArea.setTimeStyle( TimeStyle.HH12_MM_SS_1 ); |
|||
// 设定星期显示格式 NULL表示不显示星期
|
|||
dtArea.setWeekStyle( WeekStyle.CHINESE ); |
|||
// 设定时间区字体
|
|||
dtArea.setFont( new Font("宋体",Font.PLAIN,12) ); |
|||
|
|||
pf.addArea( dtArea ); |
|||
|
|||
// 创建第二个节目
|
|||
ProgramBxFile pf_2 = new ProgramBxFile( "P001",screen.getProfile() ); |
|||
TextCaptionBxArea area = new TextCaptionBxArea( 0,0,160,64,screen.getProfile() ); |
|||
TextBxPage page = new TextBxPage( "Led控制系统首选仰邦" ); |
|||
page.setDisplayStyle( styles[4] ); |
|||
area.addPage( page ); |
|||
pf_2.addArea( area ); |
|||
|
|||
// 创建一个list
|
|||
ArrayList<ProgramBxFile> plist = new ArrayList<ProgramBxFile>( ); |
|||
plist.add( pf ); |
|||
plist.add( pf_2 ); |
|||
|
|||
screen.writePrograms( plist ); |
|||
|
|||
// 如果需要,可以从控制器回读控制器上已有的节目列表
|
|||
List<String> pfs = screen.readProgramList(); |
|||
for(String program:pfs) |
|||
{ |
|||
System.out.println( program ); |
|||
} |
|||
|
|||
screen.disconnect(); |
|||
} |
|||
|
|||
// 更新动态区
|
|||
// 六代卡中,只有BX-6E系列、BX-6EX系列和BX-6Q系列支持动态区
|
|||
// 动态区是完全独立于节目,其显示内容可以按区域单独更新
|
|||
// 动态区可以与节目一起播放,也可以单独播放
|
|||
// 动态区显示内容存储于ARM,掉电不保存,没有刷新次数限制
|
|||
|
|||
// 动态区单独播放
|
|||
public static void SendDynamic()throws Exception |
|||
{ |
|||
DisplayStyle[] styles = DisplayStyleFactory.getStyles().toArray(new DisplayStyle[0]); |
|||
|
|||
Bx6GScreenClient screen = new Bx6GScreenClient( "MyScreen",new Bx6E() ); |
|||
|
|||
screen.connect( ip,port ); |
|||
|
|||
// 创建动态区
|
|||
// BX-6E BX-6EX系列支持4个动态区,BX-6Q系列支持32个动态区
|
|||
DynamicBxAreaRule rule = new DynamicBxAreaRule(); |
|||
// 设定动态区ID ,此处ID为0 ,多个动态区ID不能相同
|
|||
rule.setId(0); |
|||
// 设定异步节目停止播放,仅播放动态区
|
|||
// 0:与异步节目一起播放
|
|||
// 1:异步节目 停止播放,仅播放动态区
|
|||
// 2:当播放完节目编号坐高的异步节目后播放该动态区
|
|||
rule.setImmediatePlay( (byte)1 ); |
|||
// 设定动态区循环播放
|
|||
// 0:循环显示
|
|||
// 1:显示完成后静止显示最后一页数据
|
|||
// 2:循环显示,超过设定时间后数据仍未更新时不再显示
|
|||
// 3:循环显示,超过设定时间后数据仍未更新时显示Logo信息
|
|||
// 4:循环显示,显示完成最后一页后就不再显示
|
|||
rule.setRunMode( (byte)0 ); |
|||
|
|||
DynamicBxArea area = new DynamicBxArea( 0,0,160,32,screen.getProfile() ); |
|||
|
|||
TextBxPage page = new TextBxPage( "第一个动态区" ); |
|||
|
|||
page.setFont( new Font( "宋体",Font.PLAIN,12 ) ); |
|||
|
|||
page.setDisplayStyle( styles[2] ); |
|||
|
|||
area.addPage( page ); |
|||
|
|||
screen.writeDynamic( rule,area ); |
|||
|
|||
// 创建第二个动态区
|
|||
DynamicBxAreaRule rule_2 = new DynamicBxAreaRule(); |
|||
rule_2.setId( 1 ); |
|||
rule_2.setImmediatePlay( (byte)1 ); |
|||
rule_2.setRunMode( (byte)0 ); |
|||
DynamicBxArea area_2 = new DynamicBxArea( 0,32,160,32,screen.getProfile() ); |
|||
TextBxPage page_2 = new TextBxPage( "第二个动态区" ); |
|||
page_2.setFont( new Font("宋体",Font.PLAIN,12) ); |
|||
page_2.setDisplayStyle( styles[2] ); |
|||
area_2.addPage( page_2 ); |
|||
screen.writeDynamic( rule_2,area_2 ); |
|||
|
|||
screen.disconnect(); |
|||
} |
|||
|
|||
// 动态区和节目一起播放
|
|||
public static void SendDynamicProgram()throws Exception |
|||
{ |
|||
DisplayStyle[] styles = DisplayStyleFactory.getStyles().toArray(new DisplayStyle[0]); |
|||
|
|||
Bx6GScreenClient screen = new Bx6GScreenClient( "MyScreen",new Bx6E() ); |
|||
|
|||
screen.connect( ip,port ); |
|||
|
|||
ProgramBxFile pf = new ProgramBxFile( 0,screen.getProfile() ); |
|||
|
|||
TextCaptionBxArea area = new TextCaptionBxArea( 0,0,160,32,screen.getProfile() ); |
|||
|
|||
TextBxPage page = new TextBxPage( "这是节目" ); |
|||
|
|||
area.addPage( page ); |
|||
|
|||
pf.addArea( area ); |
|||
|
|||
screen.writeProgram( pf ); |
|||
|
|||
DynamicBxAreaRule rule = new DynamicBxAreaRule(); |
|||
rule.setId(0); |
|||
rule.setRunMode( (byte)0 ); |
|||
// 新增动态区关联异步节目
|
|||
// 一旦关联了某个异步节目,则该节目和动态区一起播放
|
|||
// 设置动态区和节目关联
|
|||
// 设定是否关联全部节目
|
|||
// true: 所有异步节目播放是都允许播放该动态区
|
|||
// false:由规则来决定
|
|||
rule.setRelativeAllPrograms( false ); |
|||
rule.addRelativeProgram( 0 ); |
|||
|
|||
DynamicBxArea dArea = new DynamicBxArea( 0,32,160,32,screen.getProfile() ); |
|||
|
|||
TextBxPage dPage = new TextBxPage( "这是动态区" ); |
|||
dPage.setDisplayStyle( styles[2] ); |
|||
dPage.setFont( new Font( "宋体",Font.PLAIN,12 ) ); |
|||
|
|||
dArea.addPage( dPage ); |
|||
|
|||
screen.writeDynamic( rule,dArea ); |
|||
|
|||
List<String> pfs = screen.readProgramList(); |
|||
for(String program : pfs) |
|||
{ |
|||
System.out.println( program ); |
|||
} |
|||
|
|||
screen.disconnect(); |
|||
} |
|||
|
|||
// 关于语音播报区域
|
|||
// 语音播放目前只有六代部分卡支持
|
|||
public static void SendSound()throws Exception |
|||
{ |
|||
Bx6GScreenClient screen = new Bx6GScreenClient( "MyScreen",new Bx6E() ); |
|||
|
|||
screen.connect( ip,port ); |
|||
|
|||
DisplayStyle[] styles = DisplayStyleFactory.getStyles().toArray(new DisplayStyle[0]); |
|||
|
|||
ProgramBxFile pf = new ProgramBxFile( "P000",screen.getProfile() ); |
|||
|
|||
// 语音部分
|
|||
TextCaptionBxArea area_sound = new TextCaptionBxArea( 0,0,160,16,screen.getProfile()); |
|||
area_sound.setVoiceContent( "黑A12345请到淀粉副产品库DF-01月台" );// 该字符串会被语音播报
|
|||
area_sound.setVoiceFlag( true ); |
|||
area_sound.setVoiceReplayTimes( 2 );// 设置重复播报3次,如果不设置,默认一直播报
|
|||
// 语音的其他设置都在area_sound中设置
|
|||
|
|||
// 显示部分_1
|
|||
TextCaptionBxArea area_display_1 = new TextCaptionBxArea( 0,0,160,48,screen.getProfile() ); |
|||
TextBxPage page_display_1 = new TextBxPage( "黑A12345" ); |
|||
page_display_1.setFont( new Font( "宋体",Font.PLAIN,30 ) ); |
|||
page_display_1.setVerticalAlignment( TextBinary.Alignment.CENTER );// 设置水平居中
|
|||
page_display_1.setHorizontalAlignment( TextBinary.Alignment.CENTER );// 设置垂直居中
|
|||
page_display_1.setDisplayStyle( styles[2] ); |
|||
area_display_1.addPage( page_display_1 ); |
|||
|
|||
// 显示部分_2
|
|||
TextCaptionBxArea area_display_2 = new TextCaptionBxArea( 0,48,160,48,screen.getProfile() ); |
|||
TextBxPage page_diaplay_2 = new TextBxPage( "请到淀粉副产品库" ); |
|||
page_diaplay_2.newLine( "DF-01月台" ); |
|||
page_diaplay_2.setFont( new Font( "宋体",Font.PLAIN,16 ) ); |
|||
page_diaplay_2.setVerticalAlignment( TextBinary.Alignment.CENTER ); |
|||
page_diaplay_2.setHorizontalAlignment( TextBinary.Alignment.CENTER ); |
|||
page_diaplay_2.setDisplayStyle( styles[2] ); |
|||
area_display_2.addPage( page_diaplay_2 ); |
|||
|
|||
pf.addArea( area_sound ); |
|||
pf.addArea( area_display_1 ); |
|||
pf.addArea( area_display_2 ); |
|||
|
|||
screen.writeProgram( pf ); |
|||
|
|||
screen.disconnect(); |
|||
} |
|||
|
|||
// 其他一些常用命令
|
|||
public static void SendCmd()throws Exception |
|||
{ |
|||
Bx6GScreenClient screen = new Bx6GScreenClient( "MyScreen",new Bx6E() ); |
|||
screen.connect( ip,port ); |
|||
// 关机命令
|
|||
screen.turnOff(); |
|||
// 开机命令
|
|||
screen.turnOn(); |
|||
// ping命令
|
|||
screen.ping(); |
|||
// 查询控制器状态
|
|||
screen.checkControllerStatus(); |
|||
// 查询控制器内存
|
|||
screen.checkMemVolumes(); |
|||
// 校时命令
|
|||
screen.syncTime(); |
|||
// 锁定屏幕当前画面
|
|||
screen.lock(); |
|||
// 解除锁定屏幕当前画面
|
|||
screen.unlock(); |
|||
// 通过以下接口回读控制器状态
|
|||
Bx6GScreen.Result<ReturnControllerStatus> result = screen.checkControllerStatus(); |
|||
if(result.isOK()) |
|||
{ |
|||
ReturnControllerStatus status = result.reply; |
|||
status.getBrightness(); // 取得亮度值
|
|||
status.getTemperature1(); // 取得温度传感器温度值
|
|||
// status 还有很多接口,根据实际应用进行调用
|
|||
} |
|||
else |
|||
{ |
|||
ErrorType error = result.getError(); |
|||
System.out.println( error ); |
|||
} |
|||
|
|||
|
|||
// WindSpeed 字节数 2 风速(除以10为当前值) 0xffff时无效
|
|||
// WindDirction 字节数 2 风向(当前值) 0xffff时无效
|
|||
// PM2.5 字节数 2 PM2.5值(当前值) 0xffff时无效
|
|||
// PM10 字节数 2 PM10值(当前值) 0xffff时无效
|
|||
Bx6GScreenClient.Result<ReturnNetwork> result1 = screen.searchNetwork(); |
|||
byte[] temp = result1.reply.getReserved1(); // 返回的前8个字节为上面注释里的定义
|
|||
if(temp[1]*256+temp[0]!=0xffff) |
|||
{ |
|||
System.out.println("风速:"+(temp[1]*256+temp[0])/10); |
|||
} |
|||
else |
|||
{ |
|||
System.out.println("无数据"); |
|||
} |
|||
if (temp[3]*256+temp[2]!=0xffff) |
|||
{ |
|||
System.out.println("风向:"+(temp[3]*256+temp[2])); //0:0°北风 1:45°东北风 2:90°东风 3:135°东南风 4:180°南风 5:225°西南风 6:270°西风 7:315°西北风
|
|||
} |
|||
else |
|||
{ |
|||
System.out.println("无数据"); |
|||
} |
|||
|
|||
|
|||
System.out.println("保留字节:"+temp); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
} |
@ -0,0 +1,44 @@ |
|||
package org.nl.acs.ext.socket; |
|||
|
|||
import io.netty.bootstrap.AbstractBootstrap; |
|||
import io.netty.channel.Channel; |
|||
|
|||
import java.net.SocketAddress; |
|||
|
|||
/* |
|||
* @author ZZQ |
|||
* @Date 2024/1/22 10:01 |
|||
*/ |
|||
public abstract class AbstraceServer { |
|||
|
|||
|
|||
public AbstraceServer(SocketAddress address) { |
|||
this.address = address; |
|||
if (channel!=null){ |
|||
doDestroy(); |
|||
} |
|||
doOpen(); |
|||
doConnect(); |
|||
} |
|||
|
|||
public AbstractBootstrap server; |
|||
public SocketAddress address; |
|||
public Channel channel; |
|||
|
|||
public abstract void doOpen(); |
|||
|
|||
public void doDestroy(){ |
|||
if (channel!=null){ |
|||
channel.close(); |
|||
} |
|||
}; |
|||
|
|||
public abstract void doConnect() ; |
|||
|
|||
public void doDisConnect(){ |
|||
if (channel!=null){ |
|||
channel.close(); |
|||
doConnect(); |
|||
} |
|||
}; |
|||
} |
@ -0,0 +1,82 @@ |
|||
package org.nl.acs.ext.socket; |
|||
|
|||
import io.netty.bootstrap.ServerBootstrap; |
|||
import io.netty.channel.*; |
|||
import io.netty.channel.nio.NioEventLoopGroup; |
|||
import io.netty.channel.socket.SocketChannel; |
|||
import io.netty.channel.socket.nio.NioServerSocketChannel; |
|||
import io.netty.handler.codec.string.StringDecoder; |
|||
import io.netty.handler.codec.string.StringEncoder; |
|||
import io.netty.handler.timeout.IdleStateHandler; |
|||
import io.netty.util.concurrent.Future; |
|||
|
|||
import java.net.SocketAddress; |
|||
import java.util.concurrent.TimeUnit; |
|||
|
|||
import static java.util.concurrent.TimeUnit.MILLISECONDS; |
|||
|
|||
/* |
|||
* @author ZZQ |
|||
* @Date 2024/7/5 14:53 |
|||
*/ |
|||
public class HeartServer extends AbstraceServer { |
|||
|
|||
private static EventLoopGroup boss = new NioEventLoopGroup(); |
|||
private static EventLoopGroup worker = new NioEventLoopGroup(); |
|||
|
|||
public HeartServer(SocketAddress address) { |
|||
super(address); |
|||
} |
|||
|
|||
// 非阻塞IO线程组
|
|||
@Override |
|||
public void doOpen() { |
|||
ServerBootstrap bootstrap = new ServerBootstrap(); |
|||
AbstraceServer body = this; |
|||
bootstrap |
|||
.group(boss, worker) |
|||
.channel(NioServerSocketChannel.class) |
|||
// .childOption(ChannelOption.SO_KEEPALIVE, Boolean.TRUE)
|
|||
.childHandler(new ChannelInitializer<SocketChannel>() { |
|||
@Override |
|||
protected void initChannel(SocketChannel ch) throws Exception { |
|||
ch.pipeline() |
|||
.addLast("client-idle-handler", new IdleStateHandler(10, 0, 0, TimeUnit.SECONDS)) |
|||
.addLast( new StringEncoder()) |
|||
.addLast( new StringDecoder()) |
|||
.addLast(new HeartServerHandler(body)); |
|||
} |
|||
}); |
|||
server = bootstrap; |
|||
Runtime.getRuntime().addShutdownHook(new Thread(() -> this.doDestroy())); |
|||
|
|||
} |
|||
|
|||
@Override |
|||
public void doDestroy(){ |
|||
System.out.println("--------服务停机--------"); |
|||
if (channel != null) { |
|||
channel.close(); |
|||
} |
|||
Future<?> bossGroupShutdownFuture = boss.shutdownGracefully(); |
|||
Future<?> workerGroupShutdownFuture = worker.shutdownGracefully(); |
|||
bossGroupShutdownFuture.syncUninterruptibly(); |
|||
workerGroupShutdownFuture.syncUninterruptibly(); |
|||
} |
|||
|
|||
@Override |
|||
public void doConnect() { |
|||
ChannelFuture future = server.bind(address); |
|||
boolean ret = future.awaitUninterruptibly(3000, MILLISECONDS); |
|||
if (ret && future.isSuccess()) { |
|||
Channel newChannel = future.channel(); |
|||
if (channel != null) { |
|||
channel.close(); |
|||
channel = newChannel; |
|||
} |
|||
} else if (future.cause() != null) { |
|||
Throwable cause = future.cause(); |
|||
cause.printStackTrace(); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,56 @@ |
|||
package org.nl.acs.ext.socket; |
|||
|
|||
import io.netty.channel.ChannelHandlerContext; |
|||
import io.netty.channel.SimpleChannelInboundHandler; |
|||
import io.netty.handler.timeout.IdleState; |
|||
import io.netty.handler.timeout.IdleStateEvent; |
|||
|
|||
/* |
|||
* @author ZZQ |
|||
* @Date 2024/1/22 10:24 |
|||
*/ |
|||
public class HeartServerHandler extends SimpleChannelInboundHandler { |
|||
private AbstraceServer server; |
|||
|
|||
public HeartServerHandler(AbstraceServer server) { |
|||
this.server = server; |
|||
} |
|||
|
|||
@Override |
|||
public void channelInactive(ChannelHandlerContext ctx) throws Exception { |
|||
Online.isOnline = false; |
|||
System.out.println("服务端断开连接-----"); |
|||
ctx.close(); |
|||
super.channelInactive(ctx); |
|||
} |
|||
|
|||
@Override |
|||
public void channelActive(ChannelHandlerContext ctx) throws Exception { |
|||
Online.isOnline = true; |
|||
System.out.println("服务端收到连接-----连接"); |
|||
super.channelActive(ctx); |
|||
} |
|||
|
|||
|
|||
@Override |
|||
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { |
|||
if (!Online.isOnline) { |
|||
Online.isOnline = true; |
|||
} |
|||
System.out.println("接收到消息" + msg.toString()); |
|||
} |
|||
|
|||
@Override |
|||
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { |
|||
if (evt instanceof IdleStateEvent) { |
|||
IdleStateEvent stateEvent = (IdleStateEvent) evt; |
|||
System.out.println(stateEvent.state()); |
|||
if (stateEvent.state() == IdleState.READER_IDLE) { |
|||
Online.isOnline = false; |
|||
System.out.println("--------手动关闭连接--------"); |
|||
ctx.close(); |
|||
} |
|||
} |
|||
super.userEventTriggered(ctx, evt); |
|||
} |
|||
} |
@ -0,0 +1,10 @@ |
|||
package org.nl.acs.ext.socket; |
|||
|
|||
/** |
|||
* @Description TODO |
|||
* @Author Gengby |
|||
* @Date 2024/7/9 |
|||
*/ |
|||
public class Online { |
|||
public static boolean isOnline = false; |
|||
} |
@ -0,0 +1,61 @@ |
|||
package org.nl.system.service.quartz.task; |
|||
|
|||
import cn.hutool.core.date.DateUtil; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.apache.lucene.document.Document; |
|||
import org.apache.lucene.index.*; |
|||
import org.apache.lucene.search.*; |
|||
import org.apache.lucene.store.FSDirectory; |
|||
import org.apache.lucene.util.BytesRef; |
|||
import org.nl.config.lucene.config.LuceneAppender; |
|||
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; |
|||
import org.springframework.core.io.ClassPathResource; |
|||
import org.springframework.core.io.Resource; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.nio.file.Paths; |
|||
import java.time.Instant; |
|||
import java.time.temporal.ChronoUnit; |
|||
import java.util.Date; |
|||
import java.util.Properties; |
|||
|
|||
|
|||
/** |
|||
* @author onepiece |
|||
*/ |
|||
@Slf4j |
|||
@Component |
|||
public class AutoCleanLuceneLog { |
|||
|
|||
private static final long MAX_FILE_AGE_DAYS = 10; |
|||
|
|||
public void run() { |
|||
try { |
|||
Resource resource = new ClassPathResource("config/application.yml"); |
|||
YamlPropertiesFactoryBean yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean(); |
|||
yamlPropertiesFactoryBean.setResources(resource); |
|||
Properties properties = yamlPropertiesFactoryBean.getObject(); |
|||
String logDirectory = properties.getProperty("lucene.index.path"); |
|||
|
|||
Instant now = Instant.now(); |
|||
Instant cutoffTime = now.minus(MAX_FILE_AGE_DAYS, ChronoUnit.DAYS); |
|||
String cutoffTimeStr = DateUtil.format(Date.from(cutoffTime), "yyyy-MM-dd HH:mm:ss.SSS"); |
|||
|
|||
FSDirectory dir = FSDirectory.open(Paths.get(logDirectory)); |
|||
IndexWriter writer = LuceneAppender.indexWriter; |
|||
|
|||
try (IndexReader reader = DirectoryReader.open(dir)) { |
|||
IndexSearcher searcher = new IndexSearcher(reader); |
|||
Query query = new TermRangeQuery("logTime", new BytesRef(""), new BytesRef(cutoffTimeStr), true, true); |
|||
TopDocs topDocs = searcher.search(query, Integer.MAX_VALUE); |
|||
for (ScoreDoc scoreDoc : topDocs.scoreDocs) { |
|||
Document doc = searcher.doc(scoreDoc.doc); |
|||
writer.deleteDocuments(new Term("logTime", doc.get("logTime"))); |
|||
} |
|||
} |
|||
writer.commit(); |
|||
} catch (Exception e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
} |
@ -1,159 +0,0 @@ |
|||
package org.nl.system.service.quartz.task; |
|||
|
|||
import cn.hutool.core.collection.CollectionUtil; |
|||
import cn.hutool.core.date.DateUtil; |
|||
import cn.hutool.core.util.IdUtil; |
|||
import cn.hutool.core.util.StrUtil; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.nl.acs.device.device.domain.Device; |
|||
import org.nl.acs.device.device.service.DeviceAppService; |
|||
import org.nl.acs.device.driver.storage.standard_storage.StandardStorageDeviceDriver; |
|||
import org.nl.acs.instruction.domain.Instruction; |
|||
import org.nl.acs.instruction.enums.InstructionStatusEnum; |
|||
import org.nl.acs.instruction.service.InstructionService; |
|||
import org.nl.acs.route.service.RouteLineService; |
|||
import org.nl.acs.route.service.dto.RouteLineDto; |
|||
import org.nl.acs.task.enums.TaskStatusEnum; |
|||
import org.nl.acs.task.service.TaskService; |
|||
import org.nl.acs.task.service.dto.TaskDto; |
|||
import org.nl.common.utils.SecurityUtils; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.util.Arrays; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 自动创建堆垛机出库指令 |
|||
*/ |
|||
@Slf4j |
|||
@Component |
|||
public class AutoCreateDDJInst { |
|||
|
|||
@Autowired |
|||
private TaskService taskService; |
|||
@Autowired |
|||
private InstructionService instructionService; |
|||
@Autowired |
|||
private RouteLineService routeLineService; |
|||
@Autowired |
|||
private DeviceAppService deviceAppService; |
|||
|
|||
|
|||
public void run() throws Exception { |
|||
List<TaskDto> list = taskService.queryAllByStatus("0"); |
|||
for (int i = 0; i < list.size(); i++) { |
|||
TaskDto acsTask = list.get(i); |
|||
String start_device_code = acsTask.getStart_device_code(); |
|||
Device startDevice = deviceAppService.findDeviceByCode(start_device_code); |
|||
if (startDevice != null && startDevice.getDeviceDriver() instanceof StandardStorageDeviceDriver) { |
|||
String taskid = acsTask.getTask_id(); |
|||
String taskcode = acsTask.getTask_code(); |
|||
String task_type = acsTask.getTask_type(); |
|||
String vehiclecode = acsTask.getVehicle_code(); |
|||
String storage_task_type = acsTask.getStorage_task_type(); |
|||
String priority = acsTask.getPriority(); |
|||
String is_send = acsTask.getIs_send(); |
|||
|
|||
String start_point_code = acsTask.getStart_point_code(); |
|||
|
|||
String put_device_code = acsTask.getPut_device_code(); |
|||
String put_point_code = acsTask.getPut_point_code(); |
|||
|
|||
String next_device_code = acsTask.getNext_device_code(); |
|||
String next_point_code = acsTask.getNext_point_code(); |
|||
|
|||
String start_point_code2 = acsTask.getStart_point_code2(); |
|||
String start_device_code2 = acsTask.getStart_device_code2(); |
|||
|
|||
String next_point_code2 = acsTask.getNext_point_code2(); |
|||
String next_device_code2 = acsTask.getNext_device_code2(); |
|||
|
|||
String route_plan_code = acsTask.getRoute_plan_code(); |
|||
String vehicleType = acsTask.getVehicle_type(); |
|||
String agv_system_type = acsTask.getAgv_system_type(); |
|||
|
|||
String start_height = acsTask.getStart_height(); |
|||
String next_height = acsTask.getNext_height(); |
|||
|
|||
|
|||
if (StrUtil.equals(is_send, "0")) { |
|||
continue; |
|||
} |
|||
|
|||
List<RouteLineDto> shortPathsList = routeLineService.getShortPathLines(acsTask.getStart_device_code(), acsTask.getNext_device_code(), route_plan_code); |
|||
if (CollectionUtil.isEmpty(shortPathsList)) { |
|||
shortPathsList = routeLineService.getShortPathLinesByCode(acsTask.getStart_device_code(), route_plan_code); |
|||
} |
|||
if (CollectionUtil.isEmpty(shortPathsList)) { |
|||
acsTask.setRemark("路由不通"); |
|||
taskService.updateByCodeFromCache(acsTask); |
|||
continue; |
|||
} |
|||
RouteLineDto routeLineDto = shortPathsList.get(0); |
|||
String path = routeLineDto.getPath(); |
|||
String[] str = path.split("->"); |
|||
List<String> pathlist = Arrays.asList(str); |
|||
int index = 0; |
|||
for (int m = 0; m < pathlist.size(); m++) { |
|||
if (pathlist.get(m).equals(start_device_code)) { |
|||
index = m + 1; |
|||
break; |
|||
} |
|||
} |
|||
next_device_code = pathlist.get(index); |
|||
|
|||
if (StrUtil.equals(deviceAppService.findDeviceTypeByCode(next_device_code), "storage")) { |
|||
next_point_code = next_device_code + "-" + acsTask.getTo_y() + "-" + acsTask.getTo_z(); |
|||
} else { |
|||
next_point_code = next_device_code; |
|||
} |
|||
|
|||
Instruction instdto = new Instruction(); |
|||
instdto.setInstruction_type(task_type); |
|||
instdto.setInstruction_id(IdUtil.simpleUUID()); |
|||
instdto.setRoute_plan_code(route_plan_code); |
|||
instdto.setRemark(acsTask.getRemark()); |
|||
instdto.setMaterial(acsTask.getMaterial()); |
|||
instdto.setQuantity(acsTask.getQuantity()); |
|||
instdto.setTask_id(taskid); |
|||
instdto.setTask_code(taskcode); |
|||
instdto.setVehicle_code(vehiclecode); |
|||
String now = DateUtil.now(); |
|||
instdto.setCreate_time(now); |
|||
instdto.setCreate_by(SecurityUtils.getCurrentNickName()); |
|||
|
|||
instdto.setStart_device_code(start_device_code); |
|||
instdto.setStart_point_code(start_point_code); |
|||
instdto.setPut_device_code(put_device_code); |
|||
instdto.setPut_point_code(put_point_code); |
|||
instdto.setNext_device_code(next_device_code); |
|||
instdto.setNext_point_code(next_point_code); |
|||
|
|||
instdto.setStart_point_code2(start_point_code2); |
|||
instdto.setStart_device_code2(start_device_code2); |
|||
instdto.setNext_point_code2(next_point_code2); |
|||
instdto.setNext_device_code2(next_device_code2); |
|||
|
|||
instdto.setPriority(priority); |
|||
instdto.setInstruction_status(InstructionStatusEnum.READY.getIndex()); |
|||
instdto.setExecute_device_code(start_point_code); |
|||
instdto.setVehicle_type(vehicleType); |
|||
instdto.setAgv_system_type(agv_system_type); |
|||
instdto.setStart_height(start_height); |
|||
instdto.setNext_height(next_height); |
|||
|
|||
try { |
|||
instructionService.create(instdto); |
|||
} catch (Exception e) { |
|||
acsTask.setRemark("指令创建失败"); |
|||
taskService.updateByCodeFromCache(acsTask); |
|||
continue; |
|||
} |
|||
//创建指令后修改任务状态
|
|||
acsTask.setTask_status(TaskStatusEnum.BUSY.getIndex()); |
|||
taskService.update(acsTask); |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,87 @@ |
|||
package org.nl.system.service.quartz.task; |
|||
|
|||
import cn.hutool.core.util.ObjectUtil; |
|||
import cn.hutool.core.util.StrUtil; |
|||
import com.alibaba.fastjson.JSONArray; |
|||
import com.alibaba.fastjson.JSONObject; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.nl.acs.agv.server.XianGongAgvService; |
|||
import org.nl.acs.ext.UnifiedResponse; |
|||
import org.nl.acs.instruction.domain.Instruction; |
|||
import org.nl.acs.instruction.service.InstructionService; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
|
|||
/** |
|||
* 定时查询AGV状态 |
|||
*/ |
|||
@Slf4j |
|||
@Component("queryAGVStatus") |
|||
public class QueryAGVStatus { |
|||
|
|||
@Autowired |
|||
private XianGongAgvService agvService; |
|||
@Autowired |
|||
private InstructionService instructionService; |
|||
|
|||
public void run() { |
|||
try { |
|||
UnifiedResponse<JSONObject> resp = agvService.queryXZAgvInstStatus(JSONObject.class); |
|||
if (resp.isSuccess()) { |
|||
JSONObject data = resp.getData(); |
|||
JSONArray list = data.getJSONArray("list"); |
|||
if (list == null) return; |
|||
for (int i = 0; i < list.size(); i++) { |
|||
JSONObject one = list.getJSONObject(i); |
|||
String inst_code = one.getString("id"); |
|||
Instruction inst = instructionService.findByCodeFromCache(inst_code); |
|||
|
|||
if (ObjectUtil.isEmpty(inst)) continue; |
|||
|
|||
//子任务状态 待以后处理
|
|||
JSONArray blocks = JSONArray.parseArray(one.getString("blocks")); |
|||
for (int j = 0; j < blocks.size(); j++) { |
|||
JSONObject blocksjo = (JSONObject) blocks.get(j); |
|||
String blockId = blocksjo.getString("blockId"); |
|||
String device_code = blocksjo.getString("location"); |
|||
String state = blocksjo.getString("state"); |
|||
} |
|||
|
|||
String state = one.getString("state"); |
|||
if (!StrUtil.isEmpty(one.getString("vehicle"))) { |
|||
String carno = one.getString("vehicle"); |
|||
inst.setCarno(carno); |
|||
} |
|||
// 已创建=CREATED,
|
|||
// 待分配=TOBEDISPATCHED,
|
|||
// 正在执行=RUNNING,
|
|||
// 完成=FINISHED,
|
|||
// 失败=FAILED(主动失败),
|
|||
// 终止=STOPPED(被人为终止),
|
|||
// 无法执行=Error(参数错误),
|
|||
// 等待=WAITING
|
|||
//执行中
|
|||
if ("RUNNING".equals(state) || "CREATED".equals(state) || "TOBEDISPATCHED".equals(state) || "WAITING".equals(state)) { |
|||
if (inst != null) { |
|||
inst.setInstruction_status("1"); |
|||
instructionService.update(inst); |
|||
} |
|||
} else if ("FINISHED".equals(state)) { |
|||
if (inst != null) { |
|||
inst.setInstruction_status("2"); |
|||
instructionService.finish(inst); |
|||
} |
|||
} else if ("STOPPED".equals(state) || "FAILED".equals(state) || "Error".equals(state)) { |
|||
if (inst != null) { |
|||
inst.setInstruction_status("1"); |
|||
instructionService.update(inst); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} catch (Exception e) { |
|||
|
|||
} |
|||
} |
|||
} |
Loading…
Reference in new issue