LAPTOP-SNT8I5JK\Boounion
2025-02-17 0d885fe2e84ac5a6390ddc4d43ab701112eedc64
1.各设备Alive状态获取,监听状态变化并回调应用层;
已添加2个文件
已修改7个文件
467 ■■■■■ 文件已修改
SourceCode/Bond/Servo/CEquipment.cpp 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEquipment.h 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.cpp 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.h 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Model.cpp 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Servo.vcxproj.filters 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ToolUnits.cpp 304 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ToolUnits.h 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEquipment.cpp
@@ -1,16 +1,25 @@
#include "stdafx.h"
#include "CEquipment.h"
#include "ToolUnits.h"
namespace SERVO {
    CEquipment::CEquipment()
    {
        m_alive = {FALSE, 0, FALSE};
        m_listener.onAlive = {nullptr};
        InitializeCriticalSection(&m_criticalSection);
    }
    CEquipment::~CEquipment()
    {
        DeleteCriticalSection(&m_criticalSection);
    }
    void CEquipment::setListener(EquipmentListener listener)
    {
        m_listener.onAlive = listener.onAlive;
    }
    void CEquipment::init()
@@ -60,6 +69,7 @@
        m_blockReadBit.start = start;
        m_blockReadBit.end = end;
        m_blockReadBit.size = (m_blockReadBit.end - m_blockReadBit.start + 1) / 8;
        ASSERT(m_blockReadBit.size < BLOCK_BUFFER_MAX);
    }
    MemoryBlock& CEquipment::getReadBitBlock()
@@ -82,7 +92,19 @@
    void CEquipment::onTimer(UINT nTimerid)
    {
        // æ¯éš”一秒,检查一下ALIVE状态
        static int tick = 0;
        tick++;
        if (tick % (4 * 1) == 0) {
            m_alive.count++;
            if (m_alive.alive && m_alive.count > ALIVE_TIMEOUT) {
                m_alive.alive = FALSE;
                if (m_listener.onAlive != nullptr) {
                    m_listener.onAlive(this, m_alive.alive);
                }
            }
        }
    }
    void CEquipment::serialize(CArchive& ar)
@@ -90,4 +112,42 @@
    }
    void CEquipment::onReceiveLBData(const char* pszData, size_t size)
    {
        TRACE("%s onReceiveLBData: %d bytes\n", m_strName.c_str(), size);
        for (unsigned int i = 0; i < size; i++) {
            if (pszData[i] != 0)
                TRACE("%d[%x]\n", i, pszData[i]);
        }
        // è§£é‡Šæ•°æ®
        BOOL bAliveFlag = isBitOn(pszData, size, 0x340);
        if (m_alive.flag != bAliveFlag) {
            m_alive.flag = bAliveFlag;
            m_alive.count = 0;
            // ×´Ì¬
            if (!m_alive.alive) {
                m_alive.alive = TRUE;
                if (m_listener.onAlive != nullptr) {
                    m_listener.onAlive(this, m_alive.alive);
                }
            }
        }
    }
    BOOL CEquipment::isBitOn(const char* pszData, size_t size, int index)
    {
        int byteIndex, bitIndex;
        byteIndex = (index) / 8;
        bitIndex = (index) % 8;
        return CToolUnits::getBit(pszData[byteIndex], bitIndex);
    }
    BOOL CEquipment::isAlive()
    {
        return m_alive.alive;
    }
}
SourceCode/Bond/Servo/CEquipment.h
@@ -3,13 +3,30 @@
#include "CCLinkIEControl.h"
namespace SERVO {
#define BLOCK_BUFFER_MAX            1024
#define ALIVE_TIMEOUT                15
    typedef std::function<void(void* pEiuipment, BOOL bAlive)> ONALIVE;
    typedef struct _EquipmentListener
    {
        ONALIVE                onAlive;
    } EquipmentListener;
    // Memory Block ç»“构体定义
    typedef struct _MemoryBlock {
        unsigned int type;
        unsigned int start;
        unsigned int end;
        unsigned int size;
        char buffer[BLOCK_BUFFER_MAX];
    } MemoryBlock;
    // ALIVE
    typedef struct _ALIVE {
        BOOL flag;
        int count;
        BOOL alive;
    } ALIVE;
    class CEquipment
    {
@@ -20,6 +37,7 @@
    public:
        virtual const char* getClassName() = 0;
        virtual void setListener(EquipmentListener listener);
        void setName(const char* pszName);
        std::string& getName();
        void setDescription(const char* pszDescription);
@@ -34,18 +52,25 @@
        virtual void term();
        virtual void onTimer(UINT nTimerid);
        virtual void serialize(CArchive& ar);
        virtual void onReceiveLBData(const char* pszData, size_t size);
        BOOL isAlive();
    private:
        BOOL isBitOn(const char* pszData, size_t size, int index);
    protected:
        inline void Lock() { EnterCriticalSection(&m_criticalSection); }
        inline void Unlock() { LeaveCriticalSection(&m_criticalSection); }
    protected:
        EquipmentListener m_listener;
        std::string m_strName;
        std::string m_strDescription;
        CRITICAL_SECTION m_criticalSection;
        StationIdentifier m_station;
        MemoryBlock m_blockReadBit;
        MemoryBlock m_blockWriteBit;
        ALIVE m_alive;
    };
}
SourceCode/Bond/Servo/CMaster.cpp
@@ -12,7 +12,7 @@
    CMaster::CMaster()
    {
        m_listener = {nullptr};
    }
    CMaster::~CMaster()
@@ -21,6 +21,11 @@
            delete item;
        }
        m_listEquipment.clear();
    }
    void CMaster::setListener(MasterListener listener)
    {
        m_listener.onEqAlive = listener.onEqAlive;
    }
    int CMaster::init()
@@ -93,7 +98,16 @@
    int CMaster::addEquipment(CEquipment* pEquipment)
    {
        EquipmentListener listener;
        listener.onAlive = [&](void* pEquipment, BOOL bAlive) -> void {
            CEquipment* p = (CEquipment*)pEquipment;
            if (m_listener.onEqAlive != nullptr) {
                m_listener.onEqAlive(this, p, bAlive);
            }
        };
        pEquipment->setListener(listener);
        m_listEquipment.push_back(pEquipment);
        return 0;
    }
@@ -104,7 +118,7 @@
        }
        // ä»¥ä¸‹ä¸ºæµ‹è¯•代码
        // æŒ‰ä¸€å®šé¢‘率扫描LB数据
        static int i = 0;
        i++;
        if (i % (4 * 1) == 0) {
@@ -113,14 +127,11 @@
                const StationIdentifier& station = item->getStation();
                MemoryBlock& block = item->getReadBitBlock();
                char szBuffer[1024];
                int nRet = m_cclink.ReadData2(station, (short)block.type,
                    block.start, block.size, szBuffer);
                for (unsigned int i = 0; i < block.size; i++) {
                    if(szBuffer[i] != 0)
                        TRACE("%d[%x]\n", i, szBuffer[i]);
                    block.start, block.size, block.buffer);
                if (0 == nRet) {
                    item->onReceiveLBData(block.buffer, block.size);
                }
                TRACE("nRet=%d\n", nRet);
            }
        }
    }
SourceCode/Bond/Servo/CMaster.h
@@ -7,6 +7,12 @@
namespace SERVO {
    typedef std::function<void(void* pMaster, CEquipment* pEiuipment, BOOL bAlive)> ONEQALIVE;
    typedef struct _MasterListener
    {
        ONEQALIVE                onEqAlive;
    } MasterListener;
    class CMaster
    {
    public:
@@ -15,6 +21,7 @@
    public:
        void setListener(MasterListener listener);
        int init();
        int term();
        void onTimer(UINT nTimerid);
@@ -25,6 +32,7 @@
    private:
        MasterListener m_listener;
        CCCLinkIEControl m_cclink;
        std::list<CEquipment*> m_listEquipment;
    };
SourceCode/Bond/Servo/Model.cpp
@@ -89,6 +89,13 @@
    m_hsmsPassive.init(this, "APP", 7000);
    SERVO::MasterListener masterListener;
    masterListener.onEqAlive = [&](void* pMaster, SERVO::CEquipment* pEquipment, BOOL bAlive) -> void {
        LOGI("<CModel>Equipment onAlive:%d.\n", pEquipment->getName().c_str(),
            bAlive ? _T("ON") : _T("OFF"));
    };
    m_master.setListener(masterListener);
    return 0;
}
SourceCode/Bond/Servo/Servo.vcxproj
@@ -221,6 +221,7 @@
    <ClInclude Include="stdafx.h" />
    <ClInclude Include="targetver.h" />
    <ClInclude Include="TerminalDisplayDlg.h" />
    <ClInclude Include="ToolUnits.h" />
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="AlarmManager.cpp" />
@@ -251,6 +252,7 @@
      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
    </ClCompile>
    <ClCompile Include="TerminalDisplayDlg.cpp" />
    <ClCompile Include="ToolUnits.cpp" />
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="Servo.rc" />
SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -34,6 +34,7 @@
    <ClCompile Include="CBonder.cpp" />
    <ClCompile Include="CMaster.cpp" />
    <ClCompile Include="CEFEM.cpp" />
    <ClCompile Include="ToolUnits.cpp" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="AlarmManager.h" />
@@ -66,6 +67,7 @@
    <ClInclude Include="CBonder.h" />
    <ClInclude Include="CMaster.h" />
    <ClInclude Include="CEFEM.h" />
    <ClInclude Include="ToolUnits.h" />
  </ItemGroup>
  <ItemGroup>
    <ResourceCompile Include="Servo.rc" />
SourceCode/Bond/Servo/ToolUnits.cpp
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,304 @@
#include "stdafx.h"
#include "ToolUnits.h"
#include <chrono>
#include <memory>
CToolUnits::CToolUnits()
{
}
CToolUnits::~CToolUnits()
{
}
std::string CToolUnits::timeToString(ULONGLONG time)
{
    ULONGLONG time1, time2;
    time1 = time / 1000000000;
    time2 = time % 1000000000;
    char buffer1[256], buffer[128];
    struct tm timeinfo;
    time_t t = time_t(time1);
    localtime_s(&timeinfo, &t);
    strftime(buffer, 128, "%Y-%m-%d %H:%M:%S", &timeinfo);
    sprintf_s(buffer1, 256, "%s.%lld", buffer, time2);
    return std::string(buffer1);
}
std::string CToolUnits::timeToString2(ULONGLONG time)
{
    ULONGLONG time1;
    time1 = time / 1000;
    char buffer[256];
    struct tm timeinfo;
    time_t t = time_t(time1);
    localtime_s(&timeinfo, &t);
    strftime(buffer, 128, "%Y-%m-%d %H:%M:%S", &timeinfo);
    return std::string(buffer);
}
std::string CToolUnits::timeToString3(ULONGLONG time)
{
    ULONGLONG time1;
    int ms;
    time1 = time / 1000;
    ms = time % 1000;
    char buffer1[256], buffer[128];
    struct tm timeinfo;
    time_t t = time_t(time1);
    localtime_s(&timeinfo, &t);
    strftime(buffer, 128, "%Y-%m-%d %H:%M:%S", &timeinfo);
    sprintf_s(buffer1, 256, "%s.%03d", buffer, ms);
    return std::string(buffer1);
}
ULONGLONG CToolUnits::stringToTime(const char* pszTime)
{
    struct tm tm;
    memset(&tm, 0, sizeof(tm));
    sscanf_s(pszTime, "%d-%d-%d %d:%d:%d",
        &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
        &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
    tm.tm_year -= 1900;
    tm.tm_mon--;
    return mktime(&tm) * 1000;
}
ULONGLONG CToolUnits::getTimestamp()
{
    auto now = std::chrono::system_clock::now();
    auto duration_in_milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
    uint64_t timestamp = duration_in_milliseconds.count();
    return timestamp;
}
void CToolUnits::createDir(const char* pszDir)
{
    if (isDirectory(std::string(pszDir))) {
        return;
    }
    CString strDir = pszDir;
    int lastIndex = 0;
    int index = strDir.Find(_T("\\"), lastIndex);
    while (index > 0) {
        CString strTempDir = strDir.Left(index);
        CreateDirectory(strTempDir, NULL);
        lastIndex = index + 1;
        index = strDir.Find(_T("\\"), lastIndex);
    }
    CreateDirectory(strDir, NULL);
}
CString& CToolUnits::floatToString1(float value, CString& strOut)
{
    strOut.Format(_T("%.1f"), value);
    return strOut;
}
CString& CToolUnits::floatToString3(float value, CString& strOut)
{
    strOut.Format(_T("%.3f"), value);
    return strOut;
}
BOOL CToolUnits::copyTextToClipboard(CWnd* pWnd, const CString& strText)
{
    if (OpenClipboard(pWnd->GetSafeHwnd())) {
        EmptyClipboard();
        HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (strText.GetLength() + 1) * sizeof(TCHAR));
        if (hglbCopy == NULL) {
            CloseClipboard();
            return FALSE;
        }
        LPTSTR lptstrCopy = (LPTSTR)GlobalLock(hglbCopy);
        strcpy_s(lptstrCopy, strText.GetLength()+1, strText);
        GlobalUnlock(hglbCopy);
        SetClipboardData(CF_TEXT, hglbCopy);
        CloseClipboard();
        GlobalFree(hglbCopy);
        return TRUE;
    }
    return FALSE;
}
std::string CToolUnits::getCurrentExePath() {
    char path[MAX_PATH];
    GetModuleFileName(NULL, path, MAX_PATH);
    std::string exePath(path);
    return exePath.substr(0, exePath.find_last_of("\\/"));
}
bool CToolUnits::isFile(const std::string& path) {
    DWORD attributes = GetFileAttributes(path.c_str());
    return (attributes != INVALID_FILE_ATTRIBUTES && !(attributes & FILE_ATTRIBUTE_DIRECTORY));
}
bool CToolUnits::isDirectory(const std::string& path) {
    DWORD attributes = GetFileAttributes(path.c_str());
    return (attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY));
}
int CToolUnits::toInt32(const char* pBuffer)
{
    return (pBuffer[0] & 0xff) | ((pBuffer[1] & 0xff) << 8) | ((pBuffer[2] & 0xff) << 16) | ((pBuffer[3] & 0xff) << 24);
}
int CToolUnits::toInt16(const char* pBuffer)
{
    return (pBuffer[0] & 0xff) | (pBuffer[1] & 0xff) << 8;
}
BOOL CToolUnits::getBit(const char c, int index)
{
    switch (index)
    {
    case 0:
        return c & 0x01;
        break;
    case 1:
        return c & 0x02;
        break;
    case 2:
        return c & 0x04;
        break;
    case 3:
        return c & 0x08;
        break;
    case 4:
        return c & 0x10;
        break;
    case 5:
        return c & 0x20;
        break;
    case 6:
        return c & 0x40;
        break;
    case 7:
        return c & 0x80;
        break;
    default:
        break;
    }
    return FALSE;
}
void CToolUnits::setBit(char* p, int index)
{
    int byteIndex = 0;
    byte b = 0;
    if (index >= 8) byteIndex = 1;
    switch (index)
    {
    case 0:
    case 8:
        b = 0x1;
        break;
    case 1:
    case 9:
        b = 0x2;
        break;
    case 2:
    case 0xA:
        b = 0x4;
        break;
    case 3:
    case 0xB:
        b = 0x8;
        break;
    case 4:
    case 0xC:
        b = 0x10;
        break;
    case 5:
    case 0xD:
        b = 0x20;
        break;
    case 6:
    case 0xE:
        b = 0x40;
        break;
    case 7:
    case 0xF:
        b = 0x80;
        break;
    default:
        break;
    }
    p[byteIndex] = b;
}
void CToolUnits::setDlgItemDouble(CWnd* pWnd, int nCtrlId, double value)
{
    CString strText;
    strText.Format(_T("%.03f"), value);
    pWnd->SetDlgItemText(nCtrlId, strText);
}
std::vector<CString> CToolUnits::GetFileNamesInDirectory(const CString& strFolderPath, const CString& strExtension)
{
    std::vector<CString> fileNames;
    // ç¡®ä¿ç›®å½•路径最后有反斜杠
    CString strSearchPath = strFolderPath;
    if (strSearchPath[strSearchPath.GetLength() - 1] != '\\') {
        strSearchPath += '\\';
    }
    CString finalExtension = strExtension;
    if (finalExtension.Find('.') == -1) {
        finalExtension = '.' + finalExtension;
    }
    strSearchPath += "*" + finalExtension;
    std::unique_ptr<CFileFind> finder = std::make_unique<CFileFind>();
    BOOL bWorking = finder->FindFile(strSearchPath);
    // éåŽ†æ–‡ä»¶å¤¹
    while (bWorking) {
        bWorking = finder->FindNextFile();
        if (!finder->IsDirectory()) {
            CString fileName = finder->GetFileName();
            int dotPos = fileName.ReverseFind('.');
            if (dotPos != -1) {
                fileName = fileName.Left(dotPos);
            }
            fileNames.push_back(fileName);
        }
    }
    return fileNames;
}
std::string CToolUnits::getRecipePath()
{
    return getCurrentExePath() + "\\Recipe";
}
std::string CToolUnits::getCurrentTimeString()
{
    struct tm ltm;
    time_t now = time(0);
    localtime_s(&ltm, &now);  // ä½¿ç”¨å®‰å…¨çš„ localtime_s å‡½æ•°
    char buffer[256];
    sprintf_s(buffer, sizeof(buffer), "%04d-%02d-%02d %02d:%02d:%02d",
        ltm.tm_year + 1900, ltm.tm_mon + 1, ltm.tm_mday,
        ltm.tm_hour, ltm.tm_min, ltm.tm_sec);
    return std::string(buffer);
}
SourceCode/Bond/Servo/ToolUnits.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
#pragma once
#include <string>
class CToolUnits
{
public:
    CToolUnits();
    ~CToolUnits();
public:
    static std::string timeToString(ULONGLONG time);
    static std::string timeToString2(ULONGLONG time);
    static std::string timeToString3(ULONGLONG time);
    static ULONGLONG stringToTime(const char* pszTime);
    static CString& floatToString1(float value, CString& strOut);
    static CString& floatToString3(float value, CString& strOut);
    static ULONGLONG getTimestamp();
    static void createDir(const char* pszDir);
    static BOOL copyTextToClipboard(CWnd* pWnd, const CString& strText);
    static std::string getCurrentExePath();
    static bool isFile(const std::string& path);
    static bool isDirectory(const std::string& path);
    static int toInt32(const char* pBuffer);
    static int toInt16(const char* pBuffer);
    static BOOL getBit(const char c, int index);
    static void setBit(char* p, int index);
    static void setDlgItemDouble(CWnd* pWnd, int nCtrlId, double value);
    static std::vector<CString> GetFileNamesInDirectory(const CString& strFolderPath, const CString& strExtension);
    static std::string getRecipePath();
    static std::string getCurrentTimeString();
};