// // Created by Matthew on 2025/3/5. // #include "PtzController.h" #include "SensorsProtocol.h" #include "GPIOControl.h" #include "PhoneDevice.h" #include PtzController::PtzController(CPhoneDevice* pPhoneDevice) : m_pPhoneDevice(pPhoneDevice) { m_exit = false; } void PtzController::Startup() { m_thread = std::thread(PtzThreadProc, this); } void PtzController::PtzThreadProc(PtzController* pThis) { pThis->PtzProc(); } void PtzController::AddCommand(uint8_t channel, int cmdidx, uint8_t bImageSize, uint8_t preset, const char *serfile, uint32_t baud, int addr) { SERIAL_CMD cmd = { 0 }; cmd.channel = channel; cmd.channel = preset; cmd.cmdidx = cmdidx; cmd.bImageSize = bImageSize; strcpy(cmd.serfile, serfile); cmd.baud = baud; cmd.addr = addr; m_locker.lock(); m_cmds.push_back(cmd); m_locker.unlock(); m_sem.release(); } void PtzController::AddPhotoCommand(IDevice::PHOTO_INFO& photoInfo, const std::string& path, const std::vector& osds) { IDevice::SerialsPhotoParam param = { "", 0, 0 }; m_pPhoneDevice->GetPhotoSerialsParamCb(param); SERIAL_CMD cmdPreset = { 0 }; time_t ts = time(NULL); // if (photoInfo.preset != 0 && photoInfo.preset != 0xFF) { cmdPreset.ts = photoInfo.selfTestingTime; cmdPreset.delayTime = photoInfo.closeDelayTime; cmdPreset.channel = photoInfo.channel; cmdPreset.channel = photoInfo.preset; cmdPreset.cmdidx = OPEN_TOTAL; strcpy(cmdPreset.serfile, param.serfile); cmdPreset.baud = param.baud; cmdPreset.addr = param.addr; } SERIAL_CMD cmd = { 0 }; cmd.ts = ts; cmd.delayTime = photoInfo.closeDelayTime; cmd.channel = photoInfo.channel; cmd.preset = photoInfo.preset; cmd.cmdidx = Take_Photo; cmd.bImageSize = photoInfo.resolution; strcpy(cmd.serfile, param.serfile); cmd.baud = param.baud; cmd.addr = param.addr; PtzPhotoParams* ppp = new PtzPhotoParams(photoInfo, path, osds); cmd.photoParams.reset(ppp); // cmd.delayTime; // uint8_t bImageSize; // char serfile[128]; // uint32_t baud; // int addr; m_locker.lock(); if (cmdPreset.cmdidx != 0) { m_cmds.push_back(cmdPreset); } m_cmds.push_back(cmd); m_locker.unlock(); m_sem.release(); m_sem.release(); } void PtzController::ExitAndWait() { m_exit = true; m_sem.release(); if (m_thread.joinable()) { m_thread.join(); } } void PtzController::PtzProc() { PTZ_STATE state = PTZS_POWER_OFF; SERIAL_CMD cmd; bool hasCmd = false; std::shared_ptr powerCtrl; time_t selfTestingStartTime = 0; time_t selfTestingWaitTime = 0; while(true) { m_sem.acquire(); if (m_exit) { break; } hasCmd = false; m_locker.lock(); for (auto it = m_cmds.begin(); it != m_cmds.end(); ++it) { if (state == PTZS_SELF_TESTING) { // find first non-taking-photo cmd if (it->cmdidx != Take_Photo) { cmd = *it; m_cmds.erase(it); hasCmd = true; break; } } else { cmd = *it; m_cmds.erase(it); hasCmd = true; break; } } m_locker.unlock(); if (!hasCmd) { if (state == PTZS_SELF_TESTING) { time_t timeout = time(NULL) - selfTestingStartTime; if (timeout >= selfTestingWaitTime) { state = PTZS_IDLE; m_sem.release(); continue; } std::this_thread::sleep_for(std::chrono::milliseconds(1000)); m_sem.release(); continue; } powerCtrl.reset(); continue; } switch (cmd.cmdidx) { case Take_Photo: { if (state == PTZS_POWER_OFF) { if (!powerCtrl) { powerCtrl = std::make_shared(cmd.photoParams->mPhotoInfo.closeDelayTime); selfTestingStartTime = time(NULL); selfTestingWaitTime = cmd.photoParams->mPhotoInfo.selfTestingTime; state = PTZS_SELF_TESTING; m_locker.lock(); m_cmds.insert(m_cmds.begin(), cmd); m_locker.unlock(); m_sem.release(); continue; } } state = PTZS_TAKING_PHOTO; if (cmd.preset != 0 && cmd.preset != 0xFF) { CameraPhotoCmd(0, cmd.channel, MOVE_PRESETNO, 0, cmd.preset, cmd.serfile, cmd.baud, cmd.addr); std::this_thread::sleep_for(std::chrono::milliseconds(10 * 1000)); } m_pPhoneDevice->TakePhotoWithNetCamera(cmd.photoParams->mPhotoInfo, cmd.photoParams->mPath, cmd.photoParams->mOsds, powerCtrl); state = PTZS_IDLE; } break; case OPEN_TOTAL: if (state == PTZS_POWER_OFF) { if (!powerCtrl) { powerCtrl = std::make_shared(cmd.delayTime); selfTestingStartTime = time(NULL); selfTestingWaitTime = cmd.ts; state = PTZS_SELF_TESTING; } } break; case CLOSE_TOTAL: if (state == PTZS_POWER_OFF) { // Do Nothing } else { powerCtrl.reset(); state = PTZS_POWER_OFF; } break; default: { CameraPhotoCmd(cmd.ts, cmd.channel, cmd.cmdidx, 0, cmd.preset, cmd.serfile, cmd.baud, cmd.addr); } break; } } }