第一步,netty服务搭建,本人整合了微服务,单机netty可以百度查到

<dependencies><!-- SpringCloud Alibaba Nacos --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- SpringCloud Alibaba Nacos Config --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>com.hope</groupId><artifactId>hope-common-redis</artifactId></dependency><dependency><groupId>com.hope</groupId><artifactId>hope-common-rocketmq</artifactId><version>${hope.version}</version></dependency></dependencies>
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;import javax.annotation.Resource;/*** socket服务* @author zhangYuHui* date 2022-09-30*/
@Slf4j
@Component
public class SocketServer {@Resourceprivate SocketInitializer socketInitializer;@Getterprivate ServerBootstrap serverBootstrap;/*** netty服务监听端口*/@Value("${netty.port:8088}")private int port;/*** 主线程组数量*/@Value("${netty.bossThread:2}")private int bossThread;/*** 启动netty服务器*/public void start() {this.init();try {this.serverBootstrap.bind(this.port).sync();} catch (InterruptedException e) {e.printStackTrace();log.error("Netty error  on port: {} (TCP) with boss thread {}", this.port, this.bossThread);}log.info("Netty started on port: {} (TCP) with boss thread {}", this.port, this.bossThread);}/*** 初始化netty配置*/private void init() {// 创建两个线程组,bossGroup为接收请求的线程组,一般1-2个就行NioEventLoopGroup bossGroup = new NioEventLoopGroup(this.bossThread);// 实际工作的线程组NioEventLoopGroup workerGroup = new NioEventLoopGroup();this.serverBootstrap = new ServerBootstrap();// 两个线程组加入进来this.serverBootstrap.group(bossGroup, workerGroup)// 配置为nio类型.channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 1024)// 保持连接.option(ChannelOption.SO_KEEPALIVE, true).childOption(ChannelOption.SO_KEEPALIVE, true)// 加入自己的初始化器.childHandler(this.socketInitializer);}}
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;import javax.annotation.Resource;/*** 监听Spring容器启动完成,完成后启动Netty服务器* @author zhangYuHui* date 2022-09-30*/
@Component
public class NettyStartListener implements  ApplicationRunner {@Resourceprivate SocketServer socketServer;@Overridepublic void run(ApplicationArguments args) throws Exception {this.socketServer.start();}}
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import org.springframework.stereotype.Component;/*** Socket 初始化器,每一个Channel进来都会调用这里的 InitChannel 方法** @author zhangYuHui* date 2022-09-30*/
@Component
public class SocketInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel socketChannel){ChannelPipeline pipeline = socketChannel.pipeline();pipeline.addLast(new DelimiterBasedFrameDecoder(1024,false,true, Unpooled.copiedBuffer(new byte[]{0x23,0x23})));pipeline.addLast(new XFSocketHandler());}}
import com.hope.netty.entity.QnResult;
import com.hope.netty.entity.SmartIotProtocol;
import com.hope.netty.service.FireSwitchboardService;
import com.hope.common.core.utils.SpringUtils;
import com.hope.common.netty.ByteUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;/*** 消防处理器,一般都是4040开头* @author zhangYuHui* date 2022-10-28*/
@Slf4j
public class XFSocketHandler extends ChannelInboundHandlerAdapter {public static final Map<String, ChannelHandlerContext> ctxMap = new ConcurrentHashMap<>(16);public static FireSwitchboardService fireSwitchboardService;static {fireSwitchboardService = SpringUtils.getBean(FireSwitchboardService.class);}/*** 读取到客户端发来的消息* @param ctx ChannelHandlerContext* @param msg msg* @throws Exception e*/@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {// 由于我们配置的是 字节数组 编解码器,所以这里取到的用户发来的数据是 byte数组ByteBuf buf = (ByteBuf) msg;byte[] data = new byte[buf.readableBytes()];buf.readBytes(data);String strDate = ByteUtil.bytes2HexStr(data);log.info("消防报文数据: " + strDate);if (strDate.startsWith("4040") && strDate.endsWith("2323")){try {// 消防报文,目前只对接青鸟SmartIotProtocol smartIotProtocol = SmartIotProtocol.geEntity(data);fireSwitchboardService.beiDaQingNiao(smartIotProtocol,ctx.channel().id().asShortText());} finally {byte[] result = QnResult.success(data);ctx.writeAndFlush(Unpooled.copiedBuffer(result));}}}@Overridepublic void handlerAdded(ChannelHandlerContext ctx) throws Exception {String s = ctx.channel().id().asShortText();log.info("消防新的客户端链接: " + s);ctxMap.put( s,ctx);}@Overridepublic void handlerRemoved(ChannelHandlerContext ctx) throws Exception {String s = ctx.channel().id().asShortText();log.info("消防有的客户端与服务器断开连接: " + s);ctxMap.remove(s);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {cause.printStackTrace();ctx.channel().close();log.info("消防出现异常,断开连接: " +ctx.channel().id().asShortText());ctxMap.remove(ctx.channel().id().asShortText());}}

大概格式

4个实体

import com.hope.common.core.utils.DateUtils;
import com.hope.common.netty.ByteUtil;
import com.hope.common.netty.XfDict;
import lombok.Data;import java.util.Arrays;/*** 青鸟建筑消防设施部件运行状态* 青鸟用传装置 类型标志 02* @author zhangYuHui* date 2022-10-12*/
@Data
public class QnComponentEntity {/**设备id*/private String id;/**ctxId*/private String ctxId;/**系统类型  10=消防联动控制器 */private String  systemType;/**系统地址 3=3号机 */private int systemAddress;/**部件类型*/private String partsType;/**部件地址*/private String partsAddress;/**状态  0测试状态 1 正常运行状态 */private int status;/**状态  0无火警 1 火警 */private int isFire;/**状态  0无故障 1 故障 */private int isFault;/**31字节的中文注释 字符集GB18030(GBK)C类型字符串数组(\0值尾部) 1-16分区消报消钮 */private String notes;/**状态发生时间*/private String date;/**系统当前时间*/private String sysDateTime;public static QnComponentEntity init(byte[] data){if (data.length != 48){return  null;}int i  = data[0] & 0xff;if (i != 2){return null;}QnComponentEntity entity = new QnComponentEntity();entity.setSystemType(XfDict.systemType(data[2] & 0xff));entity.setSystemAddress(data[3] & 0xff);entity.setPartsType(XfDict.partsType(data[4] & 0xff));entity.setPartsAddress(XfDict.partsAddress(Arrays.copyOfRange(data,5,9)));entity.setStatus(data[9] & 0x1);entity.setIsFire(data[9] >>> 1 & 0x1);entity.setIsFault(data[9] >>> 2 & 0x1);entity.setNotes(ByteUtil.bytes2HexStr(Arrays.copyOfRange(data,11,42)));entity.setDate(XfDict.getDate(Arrays.copyOfRange(data,42,48)));entity.setSysDateTime(DateUtils.getDateTime());return entity;}}
import com.hope.common.core.utils.DateUtils;
import com.hope.common.netty.XfDict;
import lombok.Data;import java.util.Arrays;/*** 上传用户信息传输装置操作信息记录* 青鸟用传装置 类型标志 24* @author zhangYuHui* date 2022-10-12*/
@Data
public class QnOperationEntity {/**设备id*/private String id;/**ctxId*/private String ctxId;/**状态  0 无操作 1 复位 */private int isReset;/**状态   0 无操作 1 消音 */private int isSilence;/**状态   0 无操作 1 报警 */private int isWarning;/**状态   0 无操作 1 自检  */private int isTesting;/**状态 操作员编号 */private int code;/**状态发生时间*/private String date;/**系统时间**/private String sysDateTime;public static QnOperationEntity init(byte[] data){if (data.length != 10){return  null;}int i  = data[0] & 0xff;if (i != 24){return null;}QnOperationEntity entity = new QnOperationEntity();entity.setIsReset(data[2] & 0x1);entity.setIsSilence(data[2] >>> 1 & 0x1);entity.setIsWarning(data[2] >>> 2 & 0x1);entity.setIsTesting(data[2] >>> 4 & 0x1);entity.setCode(data[3] & 0xff);entity.setDate(XfDict.getDate(Arrays.copyOfRange(data,4,10)));entity.setSysDateTime(DateUtils.getDateTime());return entity;}}
import com.hope.common.netty.ByteUtil;
import lombok.Data;import java.util.Arrays;/*** 自定义协议** @author zhangYuHui* date 2022-09-30*/
@Data
public class SmartIotProtocol {/*** 数据包启动符号 @@*/public String start;/*** 业务流水号*/private String flowid;/*** 主版本*/private byte versionMajor;/*** 次版本*/private byte versionMinor;/*** 秒*/private byte second;/*** 分钟*/private byte minute;/*** 小时*/private byte hour;/*** 日*/private byte day;/*** 月*/private byte month;/*** 年*/private byte year;/*** 数据包的源地址*/private byte[] src;/*** 数据包的目的地址*/private byte[] dest;/*** 应用数据单元长度 长度不应大于1024;低字节传输在前*/private int dataLen;/*** 命令字节 为控制单元的命令字节*/private byte cmd;/*** 应用数据单元  对于确认/否认等命令包,此单元可为空*/private byte[] data;/*** 校验和 控制单元中各字节数据(第3~第27字节)及应用数据单元的算术校验和,舍去8位以上的进位位后所形成的1字节二进制数*/private byte checksum;/*** 协议结束符号 ##*/public String  end ;/*** 打印调试信息*/public void printDebugInfo(){System.out.println("---------完整数据包开始------------");System.out.println("|开始标志: " + start);System.out.println("|业务流水: " + flowid);System.out.println("|协议版本: " + printHexByte(versionMajor) + printHexByte(versionMinor));System.out.println("|时间标签: " + "20" + year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second);System.out.println("|源地址 : " + ByteUtil.bytesToIp(src));System.out.println("|目的地址: " + ByteUtil.bytesToIp(dest));System.out.println("|数据长度: " + dataLen);System.out.println("|命令字节: " + printHexByte(cmd));System.out.println("|应用数据: " + printHexBytes(data));System.out.println("|校验字节: " + printHexByte(checksum));System.out.println("|结束标志: " + end);System.out.println("---------------------------------");}private String printHexByte(byte b){return String.format("%02X", b);}private String printHexBytes(byte[] bytes){String str = "";for(int i=0; i<bytes.length; i++){str += String.format("%02X", bytes[i]);}return str;}private String printHexShort(int s){byte[] bytes = hexShort(s);return printHexBytes(bytes);}private byte[] hexShort(int s){byte[] bytes = new byte[2];bytes[0] = (byte)((s << 24) >> 24);bytes[1] = (byte)((s << 16) >> 24);return bytes;}private byte[] hexInt(int n){byte[] bytes = new byte[4];bytes[3] = (byte) ((n      ) >> 24);bytes[2] = (byte) ((n <<  8) >> 24);bytes[1] = (byte) ((n << 16) >> 24);bytes[0] = (byte) ((n << 24) >> 24);return bytes;}/*** 初始化数据* @param data 字节* @return SmartIotProtocol*/public static SmartIotProtocol geEntity( byte[] data ){SmartIotProtocol entity = new SmartIotProtocol();entity.setStart(ByteUtil.bytes2HexStr(data, 0, 2));entity.setFlowid(ByteUtil.bytes2HexStr(data, 2, 2));entity.setVersionMajor(data[4]);entity.setVersionMinor(data[5]);entity.setSecond(data[6]);entity.setMinute(data[7]);entity.setHour(data[8]);entity.setDay(data[9]);entity.setMonth(data[10]);entity.setYear(data[11]);entity.setSrc(Arrays.copyOfRange(data,12,17));entity.setDest(Arrays.copyOfRange(data,18,23));entity.setDataLen(ByteUtil.byteArrayToInt(Arrays.copyOfRange(data,24,26)));entity.setCmd(data[26]);entity.setData(Arrays.copyOfRange(data,27,data.length-3));entity.setChecksum(data[data.length-3]);entity.setEnd(ByteUtil.bytes2HexStr(data, data.length-2, 2));return  entity;}}
import com.hope.common.netty.ByteUtil;import java.util.Calendar;/*** 青鸟消防返回报文** @author zhangYuHui* date 2022-10-18*/
public class QnResult {/**秒*/private static  byte SECOND;/**分*/private static  byte MINUTE;/**时*/private static  byte HOUR;/**日*/private static  byte DAY;/**月*/private static  byte MONTH;/**年*/private static  byte YEAR;/*** 成功回应,应答确认* @param data 原数据 3* @return byte[]*/public static byte[] success(byte[] data){return  getBytes(data,(byte)0x03);}/*** 成功回应,否认确认* @param data 原数据* @return byte[]*/public static byte[] error(byte[] data){return  getBytes(data,(byte)0x06);}/*** 返回对应的应答* @param data 原数据* @param b  3 对控制命令和发送信息的确认回答*           6 对控制命令和发送信息的否认回答* @return byte*/public static byte[] getBytes(byte[] data,byte b){byte cac = getCac(data);return new byte[]{(byte)0x40, (byte)0x40,data[2],  data[3], (byte)0x01, (byte)0x01,SECOND, MINUTE, HOUR,DAY,MONTH,YEAR,data[18], data[19], data[20],data[21],data[22],data[23],data[12], data[13], data[14],data[15],data[16],data[17],(byte)0x00, (byte)0x00, b,cac,(byte)0x23, (byte)0x23};}/*** 控制单元中各字节数据(第3~27字节)及应用数据单元的算术校验和,舍去8位* (1字节) 以上的进位位后所形成的 1 字节二进制数* @param data 数据* @return byte*/public  static byte getCac(byte[] data){Calendar c = Calendar.getInstance();SECOND = (byte) (c.get(Calendar.SECOND) & 0xff);MINUTE = (byte)(c.get(Calendar.MINUTE) & 0xff);HOUR = (byte)(c.get(Calendar.HOUR_OF_DAY) & 0xff);DAY = (byte)(c.get(Calendar.DATE) & 0xff);MONTH = (byte)((c.get(Calendar.MONTH) + 1) & 0xff);YEAR = (byte)(Integer.parseInt(String.valueOf(c.get(Calendar.YEAR)).substring(2)) & 0xff);byte[] success = new byte[] { data[2],  data[3], (byte)0x01, (byte)0x01,SECOND, MINUTE, HOUR,DAY,MONTH,YEAR,data[18], data[19], data[20],data[21],data[22],data[23],data[12], data[13], data[14],data[15],data[16],data[17],(byte)0x00, (byte)0x00,(byte)0x03};return ByteUtil.calCRC(success);}}

service 层


import com.hope.netty.entity.QnComponentEntity;
import com.hope.netty.entity.QnOperationEntity;/*** rocketmq 消息* @author zhangyuhui* @date 2022-07-20 16:03:07*/
public interface RocketmqService {/*** 发送上传用户信息传输装置操作信息记录* @param init 原数据*/void send(QnOperationEntity init);/*** 部件的运行状态* @param init 原数据*/void send(QnComponentEntity init);
}
import com.hope.netty.entity.SmartIotProtocol;/*** 消防总机service* @author hcbf* @version 1.0* @date 2022-07-20 16:03:07*/
public interface FireSwitchboardService {/*** 北大青鸟消防主键* @param smartIotProtocol 消防设备报文解析* @param ctxId 客户端id*/void beiDaQingNiao(SmartIotProtocol smartIotProtocol,String ctxId);}
import com.hope.netty.entity.QnComponentEntity;
import com.hope.netty.entity.QnOperationEntity;
import com.hope.netty.service.RocketmqService;
import com.hope.rocketmq.constant.MqConstants;
import com.hope.rocketmq.domain.NqOperationExchange;
import com.hope.rocketmq.domain.QnComponentExchange;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;/*** rocketmq消息* @author zhangYuHui* date 2022-10-24*/@Service
@Slf4j
public class RocketmqServiceImpl  implements RocketmqService {public final RocketMQTemplate rocketMQTemplate;public RocketmqServiceImpl(RocketMQTemplate rocketMQTemplate) {this.rocketMQTemplate = rocketMQTemplate;}@Overridepublic void send(QnOperationEntity init) {if (init ==null){return;}int status = 0;if (1 == init.getIsReset()){status = 1;}else if (1 == init.getIsSilence()){status = 2;}  else  if (1 == init.getIsWarning()){status = 3 ;} else  if (1 == init.getIsTesting()){status = 4;}NqOperationExchange exchange = new NqOperationExchange();exchange.setId(init.getId()).setCtxId(init.getCtxId()).setCode(init.getCode()).setDate(init.getDate()).setSysDateTime(init.getSysDateTime()).setStatus(status);Message<NqOperationExchange> springMessage = MessageBuilder.withPayload(exchange).build();rocketMQTemplate.send(MqConstants.NQ_OPERATION_EXCHANGE,springMessage);log.info("发送上传用户信息传输装置操作信息记录");}@Overridepublic void send(QnComponentEntity init) {if (init == null){return;}int status =  init.getStatus();if (1 == init.getIsFire()){status = 3;} else  if (1 == init.getIsFault()){status = 4;}QnComponentExchange exchange = new QnComponentExchange();exchange.setId(init.getId()).setCtxId(init.getCtxId()).setDate(init.getDate()).setSystemType(init.getSystemType()).setSystemAddress(init.getSystemAddress()).setPartsType(init.getPartsType()).setPartsAddress(init.getPartsAddress()).setSysDateTime(init.getSysDateTime()).setStatus(status);Message<QnComponentExchange> springMessage = MessageBuilder.withPayload(exchange).build();rocketMQTemplate.send(MqConstants.NQ_COMPONENT_EXCHANGE,springMessage);log.info("发送部件运行状态信息");}
}

import com.hope.netty.entity.QnComponentEntity;
import com.hope.netty.entity.QnOperationEntity;
import com.hope.netty.entity.SmartIotProtocol;
import com.hope.netty.service.FireSwitchboardService;
import com.hope.netty.service.RocketmqService;
import com.hope.common.core.constant.CacheConstants;
import com.hope.common.core.constant.Constants;
import com.hope.common.core.utils.SpringUtils;
import com.hope.common.netty.XfDict;
import com.hope.common.redis.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;/*** 消防总机* @author zhangYuHui* date 2022-10-03*/
@Service
@Slf4j
public class FireSwitchboardServiceImpl implements FireSwitchboardService {private static Map<String,String> maps = new ConcurrentHashMap<>(10);@Autowiredprivate RocketmqService rocketmqService;@Overridepublic void beiDaQingNiao(SmartIotProtocol smartIotProtocol, String ctxId) {byte[] data = smartIotProtocol.getData();if (data.length  == 0){return;}int i  = data[0] & 0xff;// 消防模块if (i == 2){QnComponentEntity init = QnComponentEntity.init(smartIotProtocol.getData());if (init ==null){return;}init.setId(maps.get(ctxId));init.setCtxId(ctxId);rocketmqService.send(init);}else  if (i == 24){// 装置操作QnOperationEntity init = QnOperationEntity.init(smartIotProtocol.getData());if (init ==null){return;}init.setId(maps.get(ctxId));init.setCtxId(ctxId);rocketmqService.send(init);}else  if (i==26){//心跳检测String id = XfDict.getId(smartIotProtocol.getData());SpringUtils.getBean(RedisService.class).setCacheObject(CacheConstants.EQ_NQ_KEY+id, ctxId, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);maps.put(ctxId,id);log.info("心跳检测: " + id);}}}

测试结果

netty对接青鸟消防主机相关推荐

  1. CAN光纤转换器CAN光端机在青鸟消防主机JB-TB-JBF系列中的应用

    三台青鸟消防主机配套CAN光端机进行光纤冗余环网组网测试: 项目背景: 1.三台青鸟消防主机组成光纤冗余环网: 2.单台设备或一段线路出现故障时,不影响网络内其它设备正常工作. 组网和测试方案: 1. ...

  2. 北大青鸟汉字注释机内码_消防维修北大青鸟消防主机汉字注释如何书写?

    北大青鸟消防主机有两种汉字注释.一种是用编程和调试软件编写文本注释,另一种是直接检查消防主机上的汉字内部代码并进入系统进行编辑.下面简要介绍使用编程和调试软件进行文本注释的方法. 1.序列号项目是自动 ...

  3. 北大青鸟消防控制器组网_北大青鸟消防主机概述

    北大青鸟环宇消防设备股份有限公司严格遵照国标<GB 28184-2011消防设备电源监控系统>研制开发了JBF-PWMS型(Power Monitor System)消防设备电源监控系统, ...

  4. 北大青鸟消防控制器组网_北大青鸟消防报警主机维修与调试

    一.北大青鸟消防报警主机的特点: 北大青鸟消防报警主机两总线无极性,采用地址编码技术. 整个系统只用两根总线,建筑物布线极其简单,布线路径及方式任意,且不分先后顺序,提高了布线可靠性,也便于穿线施工和 ...

  5. 浅谈一下海湾,利达,西子门,青鸟,三江,松江,山鹰等消防主机的2种布线方式

    今天浅谈一下海湾,利达,西子门,青鸟,三江,松江,山鹰等消防主机的几种布线方式. 因为海湾,利达,西子门,青鸟,三江,松江,山鹰等消防主机都有CANBUS接口,所以一般消防主机都是按照CANBUS的协 ...

  6. can转光纤 can光端机 总线式CAN光纤转换器用于消防主机长距离互联

    简介: 由于消防监控主机联网的跨度很大,很多情况下都超过CAN-bus 的电气特性所规定的极限距离.并且现场环境通常都比较恶劣,高压高辐射的干扰对CAN-bus 的正确传输都造成严重影响.所以目前消防 ...

  7. 西门子消防主机FC18配套CAN光端机进行光纤冗余环网组网测试

    项目背景: 1.三台西门子消防主机FC18组成光纤冗余环网: 2.单台设备或一段线路出现故障时,不影响网络内其它设备正常工作. 组网和测试方案025-68250795: 1.西门子消防主机FC18通过 ...

  8. can 光端机 适配国内主流消防主机的CAN光纤转换器

    can转光纤,can 光端机 can 光适配国内主流消防主机的CAN光纤转换器的介绍 1.适配国内主流消防主机 (1) 产品已配套海湾.利达.北大青鸟.西门子.飞繁.依爱等公司消防报警主机大量长期使用 ...

  9. can转光纤,can 光端机 can 光适配国内主流消防主机的CAN光纤转换器的介绍

    1.适配国内主流消防主机 (1) 产品已配套海湾.利达.北大青鸟.西门子.飞繁.依爱等公司消防报警主机大量长期使用. (2) 不管哪家的消防主机,不管消防主机CAN通道的通讯波特率是什么, (3) 不 ...

最新文章

  1. WordPress插件开发: 文章同步到OSC博客插件(OscPress) (四)
  2. selendroid之inspector
  3. 电阻(4)之上/下拉电阻
  4. hdu 3401(单调队列优化dp)
  5. Linux常用开发环境软件-Redis安装(docker环境下)
  6. 如何在开源社区贡献代码_如何在15分钟内从浏览器获得您的第一个开源贡献
  7. javascript中浅拷贝和深拷贝的理解
  8. java httppost wsdl_Java使用HttpUrlConnection调用webService(wsdl)
  9. luaL_setfunc设置upvalue的用法示例
  10. (21)Spring Boot过滤器、监听器【从零开始学Spring Boot】
  11. azure夜校培训第四场3月8日18:00---网络服务
  12. 隐瞒中国iPhone需求下滑实情:库克和苹果惹上事了
  13. php环境下cache失效,cache缓存失效高并发读数据库的问题
  14. Drools 规则引擎一文读懂
  15. 比特率(码率) = 采样率 (Sampling rate ) * 位深 (Bit depth)* 声道数目/Opus/AAC/mp3
  16. jzoj6152. 【GDOI2019Day2模拟2019.4.29】Endless (倍增维护并查集,平方串)
  17. playm3u8插件 android,Playm3u8插件下载|Playm3u8插件 免费版_最火软件站
  18. 向NS2中添加协议PING
  19. Python爬取猫眼电影榜单评分,以及评论
  20. 影像变革之年 CP+2019展会五大看点

热门文章

  1. linux服务器设置成代理服务器
  2. java适配器模式例子_java适配器模式实例解析
  3. java图像识别库_Java使用Tess4J 实现简单的图像识别(Maven版)
  4. docker 安装 portainer 并汉化 中文版
  5. 很全面的视频编码格式表
  6. 理解Sharding jdbc原理,看这一篇就够了
  7. 使用WebSocket推送服务器消息
  8. 用pdfjs 在 node服务端将pdf转为图片
  9. 声纹验证和声纹识别中的AS-norm、Z-norm、T-norm、ZT-norm、 S-norm操作
  10. vivado仿真时,输出为高阻态