MyTask.java 13.1 KB
package com.example.dahua;

import com.example.dahua.Gate.Gate;
import com.example.dahua.alarmListen.AlarmListenModule;
import com.example.dahua.bean.CardBean;
import com.example.dahua.bean.DeviceInfoBean;
import com.example.dahua.bean.TeacherBean;
import com.example.dahua.bean.UserInfoBean;
import com.example.dahua.dao.UserDao;
import com.example.dahua.lib.NetSDKLib;
import com.example.dahua.lib.ToolKits;
import com.example.dahua.lib.Utils;
import com.example.dahua.module.AutoRegisterModule;
import com.example.dahua.module.GateModule;
import com.example.dahua.module.LoginModule;
import com.example.dahua.service.AttendanceService;
import com.example.dahua.utils.FileUtils;
import com.example.dahua.xiananDao.SendRecordDao;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;

@Component
public class MyTask implements ApplicationRunner {

    // 主动注册监听回调
    private ServiceCB servicCallback = new ServiceCB();

    // 设备断线通知回调
    private DisConnect disConnect = new DisConnect();

    // 网络连接恢复
    private HaveReConnect haveReConnect = new HaveReConnect();

    //设备登录账号
    public static String strUser = "admin";

    //设备登密码
    public static String password = "q12345678";

    //在线设备信息集合
    private List<DeviceInfoBean> deviceInfoBeans = new ArrayList<>();

    //存放登录句柄
    public static Map<String, NetSDKLib.LLong> lLongMap = new HashMap<>();

    @Autowired
    SendRecordDao sendRecordDao;

    @Autowired
    UserDao userDao;

    public boolean isHasNewDevice = false;//判断是否有新设备上线

    @Override
    public void run(ApplicationArguments args) throws Exception {
//        121.40.109.21

        LoginModule.init(disConnect, haveReConnect);   // 打开工程,初始化

        autoRegister();//自注册

//        System.out.println(" sendRecordDao:"+sendRecordDao.getSenSuccess());
    }


    /**
     * 设备自注册
     */
    private void autoRegister() {

        /**
         * 开启监听服务
         */

        AutoRegisterModule.startServer(new Utils().getHostAddress(), 9500, servicCallback);

    }

    // 设备断线回调: 通过 CLIENT_Init 设置该回调函数,当设备出现断线时,SDK会调用该函数
    private class DisConnect implements NetSDKLib.fDisConnect {
        public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {
            System.out.printf("Device[%s] Port[%d] DisConnect!\n", pchDVRIP, nDVRPort);
            String deviceId = getDeviceId(pchDVRIP, nDVRPort);
            if (!StringUtils.isEmpty(deviceId)) {
                attendanceService.updateConnectStateWithDevid(0, deviceId);
                GateModule.stopRealLoadPic(lLongMap.get(deviceId));
                lLongMap.remove(deviceId);
//                devMap.remove(deviceId);
                removeDevice(deviceId);
                isHasNewDevice = true;
            }
//            AutoRegisterModule.logout()
            // 断线提示
        }
    }

    // 网络连接恢复,设备重连成功回调
    // 通过 CLIENT_SetAutoReconnect 设置该回调函数,当已断线的设备重连成功时,SDK会调用该函数
    private class HaveReConnect implements NetSDKLib.fHaveReConnect {
        public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {
            System.out.printf("ReConnect Device[%s] Port[%d]\n", pchDVRIP, nDVRPort);
            // 重连提示
            String deviceId = getDeviceId(pchDVRIP, nDVRPort);
            if (!StringUtils.isEmpty(deviceId)) {
                attendanceService.updateConnectStateWithDevid(1, deviceId);
//                devMap.put(deviceId,"");
                DeviceInfoBean deviceInfoBean = new DeviceInfoBean();
                deviceInfoBean.setDevcieId(deviceId);
                deviceInfoBean.setDeviceIp(pchDVRIP);
                deviceInfoBean.setDevicePort(nDVRPort);
                deviceInfoBean.setLoginHandle(m_hLoginHandle);
                deviceInfoBean.setPassword(password);
                deviceInfoBean.setUsername(strUser);
                deviceInfoBeans.add(deviceInfoBean);
                lLongMap.put(deviceId, m_hLoginHandle);
                isHasNewDevice = true;
            }
        }
    }

    /**
     * 根据ip和port获取设备id
     *
     * @param pchDVRIP
     * @param nDVRPort
     * @return
     */
    private String getDeviceId(String pchDVRIP, int nDVRPort) {
        for (DeviceInfoBean deviceInfoBean :
                deviceInfoBeans) {
            if (pchDVRIP.equals(deviceInfoBean.getDeviceIp()) && nDVRPort == deviceInfoBean.getDevicePort()) {
                return deviceInfoBean.getDevcieId();
            }
        }
        return "";
    }

    /**
     * 移除设备
     *
     * @param deviceId
     */
    private void removeDevice(String deviceId) {

        DeviceInfoBean deviceInfoBean = null;


        for (DeviceInfoBean dev :
                deviceInfoBeans) {
            if (dev.getDevcieId().equals(deviceId)) deviceInfoBean = dev;
        }

        if (null != deviceInfoBean) deviceInfoBeans.remove(deviceInfoBean);
    }


    @Autowired
    private AttendanceService attendanceService;//设备控制服务

    /**
     * 侦听服务器回调函数
     */
    public class ServiceCB implements NetSDKLib.fServiceCallBack {
        @Override
        public int invoke(NetSDKLib.LLong lHandle, final String pIp, final int wPort,
                          int lCommand, Pointer pParam1, int dwParamLen,
                          Pointer dwUserData) {

            // 将 pParam 转化为序列号
            byte[] buffer1 = new byte[dwParamLen];
            pParam1.read(0, buffer1, 0, dwParamLen);
            //设备id
            String deviceId = "";
            try {
                deviceId = new String(buffer1, "GBK").trim();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            System.out.printf("Register Device Info [Device address %s][port %s][DeviceID %s] \n", pIp, wPort, deviceId);
            switch (lCommand) {
                case NetSDKLib.EM_LISTEN_TYPE.NET_DVR_DISCONNECT: {  // 验证期间设备断线回调
                    System.out.println("EM_LISTEN_TYPE:验证期间设备断线回调");

                    break;
                }
                case NetSDKLib.EM_LISTEN_TYPE.NET_DVR_SERIAL_RETURN: { // 设备注册携带序列号
                    System.out.println("EM_LISTEN_TYPE:设备注册携带序列号");
                    /**
                     * 主动注册调用的登录接口,获取登录句柄
                     */
                    NetSDKLib.LLong loginHandleLong = AutoRegisterModule.login(pIp, wPort, strUser, password, deviceId);
//                    FileUtils.getInstance().writeLogs("设备注册:"+deviceId+" 登录句柄:"+loginHandleLong,FileUtils.devices);
                    if (loginHandleLong.longValue() != 0) {
                        lLongMap.put(deviceId, loginHandleLong);
                        isHasNewDevice = true;
                        String inTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
                        int index = attendanceService.insert(deviceId, "22", pIp, wPort + "", inTime, "-1", "1");
                        DeviceInfoBean deviceInfoBean = new DeviceInfoBean();
                        deviceInfoBean.setDevcieId(deviceId);
                        deviceInfoBean.setDeviceIp(pIp);
                        deviceInfoBean.setDevicePort(wPort);
                        deviceInfoBean.setLoginHandle(loginHandleLong);
                        deviceInfoBeans.add(deviceInfoBean);

                    } else {
//                        System.err.println(String.format("Login Failed[Device IP %s] [Port %s][DeviceID %s] %s", pIp,
//                                wPort, deviceId));
                    }
                    break;
                }
                default:
                    break;
            }

            return 0;
        }
    }

    public synchronized void reloadPic() {
        isHasNewDevice = false;
     if (null!=deviceInfoBeans&&deviceInfoBeans.size()>0){
         for (DeviceInfoBean dev :
                 deviceInfoBeans) {
//             FileUtils.getInstance().writeLogs(dev.getDevcieId() + "------" + lLongMap.get(dev.getDevcieId()), FileUtils.device_login);
             if (lLongMap.get(dev.getDevcieId()).intValue() > 0){
                 NetSDKLib.LLong lLong = GateModule.realLoadPic(0, analyzerCallback, lLongMap.get(dev.getDevcieId()));
                if (lLong.intValue()!=-1){
                    deviceInfoBeans.remove(dev);
                }
             }

         }
     }
    }


    //智能订阅
    private AnalyzerDataCB analyzerCallback = new AnalyzerDataCB();

    private class AnalyzerDataCB implements NetSDKLib.fAnalyzerDataCallBack {
        private BufferedImage gateBufferedImage = null;

        public int invoke(NetSDKLib.LLong lAnalyzerHandle, int dwAlarmType,
                          Pointer pAlarmInfo, Pointer pBuffer, int dwBufSize,
                          Pointer dwUser, int nSequence, Pointer reserved) {
            if (lAnalyzerHandle.longValue() == 0 || pAlarmInfo == null) {
                return -1;
            }

            byte[] bufferBytes = new byte[dwBufSize];

            pBuffer.read(0, bufferBytes, 0, dwBufSize);


            File path = new File(".\\FaceRecoder");
            if (!path.exists()) {
                path.mkdir();
            }

            ///< 门禁事件
            if (dwAlarmType == NetSDKLib.EVENT_IVS_ACCESS_CTL) {
                NetSDKLib.DEV_EVENT_ACCESS_CTL_INFO msg = new NetSDKLib.DEV_EVENT_ACCESS_CTL_INFO();
                ToolKits.GetPointerData(pAlarmInfo, msg);
                System.out.println("sda:" + new String(msg.szCardNo) + " 抓拍照片存储地址:");
                try {
                    String card = new String(msg.szCardNo).trim();
                    if (!StringUtils.isEmpty(card)) {
                        // 保存图片,获取图片缓存
                        String snapPicPath = path + "\\" + System.currentTimeMillis() + ".png";  // 保存图片地址
                        byte[] buffer = pBuffer.getByteArray(0, dwBufSize);
                        ByteArrayInputStream byteArrInputGlobal = new ByteArrayInputStream(buffer);
                        gateBufferedImage = ImageIO.read(byteArrInputGlobal);
                        if (gateBufferedImage != null) {
                            ImageIO.write(gateBufferedImage, "png", new File(snapPicPath));
                        }
                        card=cardNo(card);
                        CardBean cardBean = userDao.getCards(card);//根据卡号获取身份信息
                        String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
                        snapPicPath = snapPicPath.replaceFirst("\\.", "http://121.40.109.21:8991");
                        snapPicPath = snapPicPath.replace("FaceRecoder","image");
                        if (cardBean.getType() == 0) {//老师
                            TeacherBean teacherBean = userDao.getTeacherWithId(cardBean.getUser_id());
                            sendRecordDao.addFaceRecoder("", teacherBean.getUser_id(), teacherBean.getName(), snapPicPath, 1, time, card);
                        } else if (cardBean.getType() == 2) {//学生
                            UserInfoBean userInfoBean = userDao.getStudentWithid(cardBean.getUser_id());
                            sendRecordDao.addFaceRecoder("", userInfoBean.getUser_id(), userInfoBean.getName(), snapPicPath, 1, time, card);
                        }
                    }

                } catch (IOException e2) {
                    e2.printStackTrace();
                }

                // 图片以及门禁信息界面显示
//                EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
//                if (eventQueue != null) {
//                    eventQueue.postEvent( new GateFrame.AccessEvent(target,
//                            gateBufferedImage,
//                            msg));
//                }
            }

            return 0;
        }
    }

    /**
     * 卡号两两取反
     *
     * @param cardDex
     * @return
     */
    public String cardNo(String cardDex) {

        String cardR = "";
        int length = cardDex.length();
        if (length != 8) {
            System.out.println("卡号格式不正确:" + cardDex);
            return cardDex;
        }
        while (length > 0) {
            length -= 2;
            cardR += cardDex.substring(length, length + 2);
        }

        return cardR;

    }

}