From 326327d35f90b967de68d9feee291ee0e1ecbfaa Mon Sep 17 00:00:00 2001 From: Myron Franze <58065110+Norym@users.noreply.github.com> Date: Wed, 17 Jun 2020 11:08:18 +0200 Subject: [PATCH] 1.0.0 * used namespace direct * deleted version stuff --- CMakeLists.txt | 23 +++++++ gtest/CMakeLists.txt | 15 +++++ gtest/signal_test.cpp | 138 ++++++++++++++++++++++++++++++++++++++++ gtest/siguni_test.cpp | 55 ++++++++++++++++ gtest/test.cpp | 10 +++ gtest/unit_test.cpp | 60 +++++++++++++++++ interface/icontrolbus.h | 19 ++++++ interface/ihw.h | 29 +++++++++ interface/isignal.h | 45 +++++++++++++ interface/iunit.h | 27 ++++++++ managerbase.cpp | 40 ++++++++++++ managerbase.h | 32 ++++++++++ protocol.cpp | 71 +++++++++++++++++++++ protocol.h | 34 ++++++++++ signal.cpp | 35 ++++++++++ signal.h | 66 +++++++++++++++++++ unit.cpp | 37 +++++++++++ unit.h | 44 +++++++++++++ 18 files changed, 780 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 gtest/CMakeLists.txt create mode 100644 gtest/signal_test.cpp create mode 100644 gtest/siguni_test.cpp create mode 100644 gtest/test.cpp create mode 100644 gtest/unit_test.cpp create mode 100644 interface/icontrolbus.h create mode 100644 interface/ihw.h create mode 100644 interface/isignal.h create mode 100644 interface/iunit.h create mode 100644 managerbase.cpp create mode 100644 managerbase.h create mode 100644 protocol.cpp create mode 100644 protocol.h create mode 100644 signal.cpp create mode 100644 signal.h create mode 100644 unit.cpp create mode 100644 unit.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b58e612 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required (VERSION 3.16) + +SET(CMAKE_CXX_STANDARD 20) +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wpedantic -Werror=pedantic -Wextra") + +SET(PRJ_NAME "siguni") +project(${PRJ_NAME}) + +find_package(GTest QUIET) + +if(${GTest_FOUND}) +add_subdirectory(gtest) +endif() + + +add_library(${PRJ_NAME} + + unit + signal + protocol + managerbase + +) diff --git a/gtest/CMakeLists.txt b/gtest/CMakeLists.txt new file mode 100644 index 0000000..abc81e7 --- /dev/null +++ b/gtest/CMakeLists.txt @@ -0,0 +1,15 @@ +SET(LIB_NAME "sigunit-test") +project (${LIB_NAME}) + +add_executable( ${LIB_NAME} + test.cpp + signal_test.cpp + unit_test.cpp + siguni_test.cpp +) + +target_link_libraries( ${LIB_NAME} + gtest + pthread + siguni +) diff --git a/gtest/signal_test.cpp b/gtest/signal_test.cpp new file mode 100644 index 0000000..e4c153b --- /dev/null +++ b/gtest/signal_test.cpp @@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: GPLv3-or-later */ +/* Copyright (c) 2020 Project WomoLIN */ +/* Author Myron Franze */ + +#include "../signal.h" + +#include + + +namespace siguni::gtest +{ + +class CSerialTest : public ::testing::Test { }; + + +class CSignalSetResetTest : public interface::ISignalSetReset +{ +public: + CSignalSetResetTest() = default ; + ~CSignalSetResetTest() = default; + void UpdateUnitSignalSetReset( std::string & attKey, std::string & attValue ) override final + { + key = attKey; + value = attValue; + }; + std::string key; + std::string value { "UNKNOWN" }; + +}; + + +TEST_F( CSerialTest, ISignalSetReset ) { + + std::string key { "KEY" }; + std::string val { "GET" }; + + auto test = CSignalSetResetTest(); + + test.UpdateUnitSignalSetReset( key, val ); + + ASSERT_STREQ( test.key.c_str() , "KEY" ); + ASSERT_STREQ( test.value.c_str(), "GET" ); + +} + +class CSignalGetVoltageTest : public interface::ISignalGetVoltage +{ +public: + CSignalGetVoltageTest() = default ; + ~CSignalGetVoltageTest() = default; + void UpdateUnitSignalGetVoltage( std::string & attKey, std::string & attGetVoltage ) override final + { + key = attKey; + voltage = attGetVoltage; + }; + std::string key; + std::string voltage; +}; + + +TEST_F( CSerialTest, ISignalGetVoltage ) { + + std::string key {"KEY"}; + std::string voltage {"VOLTAGE"}; + + auto test = CSignalGetVoltageTest(); + + test.UpdateUnitSignalGetVoltage( key, voltage ); + + ASSERT_STREQ( test.key.c_str() , "KEY" ); + ASSERT_STREQ( test.voltage.c_str() , "VOLTAGE"); + +} + + +class CSignalGetVersionTest : public interface::ISignalGetVersion +{ +public: + CSignalGetVersionTest() = default ; + ~CSignalGetVersionTest() = default; + void UpdateUnitSignalGetVersion( std::string & attKey, std::string & attVersion ) override final + { + key = attKey; + fw = attVersion; + }; + std::string key; + std::string fw; +}; + + +TEST_F( CSerialTest, ISignalGetVersion ) { + + std::string key {"KEY"}; + std::string fw {"FW"}; + + auto test = CSignalGetVersionTest(); + + test.UpdateUnitSignalGetVersion( key, fw ); + + ASSERT_STREQ( test.key.c_str() , "KEY" ); + ASSERT_STREQ( test.fw.c_str() , "FW"); + +} + + + + +class CSignalAddUnitIntTest : public CSignalAddUnit +{ +public: + CSignalAddUnitIntTest() { unitsPointer = &units ; } ; + ~CSignalAddUnitIntTest() = default; + const std::vector* unitsPointer; // pointer to access unit array +}; + +TEST_F( CSerialTest, CSignalAddUnitInt ) { + + int val1 {1}; + int val2 {2}; + + auto test = CSignalAddUnitIntTest(); + + ASSERT_TRUE( (*test.unitsPointer).empty() ) << "no values added, array must be empty"; + test.AddUnit( &val1 ); + ASSERT_EQ( 1, (*test.unitsPointer).size() ) << "added one value, array must be have one value"; + + test.AddUnit( &val2 ); // add second value to array + + val1 = 10; // change initialize value from value 1 + val2 = 20; // change initialize value from value 2 + + ASSERT_EQ( 10, *(*test.unitsPointer).at(0) ) << "value 1 must be 10, changed variable var1 changed"; + ASSERT_EQ( 20, *(*test.unitsPointer).at(1) ) << "value 1 must be 20, changed variable var2 changed"; + +} + +} + diff --git a/gtest/siguni_test.cpp b/gtest/siguni_test.cpp new file mode 100644 index 0000000..0df6534 --- /dev/null +++ b/gtest/siguni_test.cpp @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPLv3-or-later */ +/* Copyright (c) 2020 Project WomoLIN */ +/* Author Myron Franze */ + +#include "../unit.h" +#include "../signal.h" + +#include + +namespace siguni::gtest +{ + + +class CSiguniTest : public ::testing::Test { }; + + + +class CUnitSignalSetReset : public interface::ISignalSetReset +{ + void UpdateUnitSignalSetReset( std::string & /*attKey*/, std::string & /*attValue*/ ) override {}; +}; + + +class CRelayOutput : public interface::IUnitOutput +{ +public: + CRelayOutput() = default ; + ~CRelayOutput() = default; + + void Set( std::string & attSetOutput ) override final { set = attSetOutput; }; + + std::string set; +}; + + +TEST_F( CSiguniTest, CUnitOutput ) { + + auto signal_setReset_1 = CSignalSetReset(); + + auto unit_setReset_1 = CUnitSignalSetReset(); + + signal_setReset_1.AddUnit( &unit_setReset_1 ); + + std::string key {}; + std::string val {}; + + signal_setReset_1.UpdateUnit( key, val ); + + // TODO + //std::cout << key << std::endl; + //std::cout << val << std::endl; + +} + +} diff --git a/gtest/test.cpp b/gtest/test.cpp new file mode 100644 index 0000000..b117dc1 --- /dev/null +++ b/gtest/test.cpp @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPLv3-or-later */ +/* Copyright (c) 2020 Project WomoLIN */ +/* Author Myron Franze */ + +#include + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/gtest/unit_test.cpp b/gtest/unit_test.cpp new file mode 100644 index 0000000..f68449f --- /dev/null +++ b/gtest/unit_test.cpp @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: GPLv3-or-later */ +/* Copyright (c) 2020 Project WomoLIN */ +/* Author Myron Franze */ + +#include "../unit.h" + +#include + +namespace siguni::gtest +{ + +class CUnitTest : public ::testing::Test { }; + + +class CUnitOutputTest : public interface::IUnitOutput +{ +public: + CUnitOutputTest() = default ; + ~CUnitOutputTest() = default; + + void Set( std::string & attSetOutput ) override final { setCommand = attSetOutput; }; + + std::string setCommand; +}; + +TEST_F( CUnitTest, IUnitOutput ) { + + auto test = CUnitOutputTest(); + + std::string setCommand { "SET" }; + + test.Set( setCommand ); + ASSERT_STREQ( test.setCommand.c_str() , "SET" ); + + setCommand = "RESET"; + + test.Set( setCommand ); + ASSERT_STREQ( test.setCommand.c_str() , "RESET" ); +} + +class CUnitInputTest : public interface::IUnitInput +{ +public: + CUnitInputTest() = default ; + ~CUnitInputTest() = default; + + void Get( std::string & attStatus ) override final { attStatus = "SET"; }; +}; + +TEST_F( CUnitTest, IUnitInput ) { + + auto test = CUnitInputTest(); + + std::string status_string {"UNKNOWN"}; + + test.Get( status_string ); + ASSERT_STREQ( status_string.c_str() , "SET" ); +} + +} diff --git a/interface/icontrolbus.h b/interface/icontrolbus.h new file mode 100644 index 0000000..acfb0c5 --- /dev/null +++ b/interface/icontrolbus.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPLv3-or-later */ +/* Copyright (c) 2019 Project WomoLIN */ +/* Author Myron Franze */ + +#pragma once + +#include + +namespace siguni::interface +{ + class IControlbus + { + public: + virtual ~IControlbus() = default; + + virtual int WriteData( const std::string & attMessage ) = 0; + virtual int ReadData( std::string & attMessage ) = 0; + }; +} diff --git a/interface/ihw.h b/interface/ihw.h new file mode 100644 index 0000000..c62be32 --- /dev/null +++ b/interface/ihw.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPLv3-or-later */ +/* Copyright (c) 2020 Project WomoLIN */ +/* Author Myron Franze */ + +#pragma once + +#include "iunit.h" + +namespace siguni::interface +{ + + class IInputHwBoardVersion : public siguni::interface::IUnitInput + { + public: + virtual ~IInputHwBoardVersion() = default; + + void Get( std::string & attGetInput ) override = 0; + }; + + class IInputDriverVersion : public siguni::interface::IUnitInput + { + public: + virtual ~IInputDriverVersion() = default; + + void Get( std::string & attGetInput ) override = 0; + }; + +} + diff --git a/interface/isignal.h b/interface/isignal.h new file mode 100644 index 0000000..2aa6414 --- /dev/null +++ b/interface/isignal.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPLv3-or-later */ +/* Copyright (c) 2019 Project WomoLIN */ +/* Author Myron Franze */ + +#pragma once + +#include +#include +#include + + +namespace siguni::interface +{ + + class ISignal + { + public: + virtual ~ISignal() = default; + virtual void UpdateUnit( std::string & attKey, std::string & attValue ) = 0; + }; + + class ISignalSetReset + { + public: + virtual ~ISignalSetReset() = default; + virtual void UpdateUnitSignalSetReset( std::string & attKey, std::string & attValue ) = 0; + }; + + class ISignalGetVoltage + { + public: + virtual ~ISignalGetVoltage() = default; + virtual void UpdateUnitSignalGetVoltage( std::string & attKey, std::string & attGetVoltage ) = 0; + }; + + class ISignalGetVersion + { + public: + virtual ~ISignalGetVersion() = default; + virtual void UpdateUnitSignalGetVersion( std::string & attKey, std::string & attVersion ) = 0; + }; + + +} + diff --git a/interface/iunit.h b/interface/iunit.h new file mode 100644 index 0000000..e2b5153 --- /dev/null +++ b/interface/iunit.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPLv3-or-later */ +/* Copyright (c) 2019 Project WomoLIN */ +/* Author Myron Franze */ + +#pragma once + +#include "isignal.h" + +namespace siguni::interface +{ + + class IUnitOutput + { + public: + virtual ~IUnitOutput() = default; + + virtual void Set( std::string & attSetOutput ) = 0; + }; + + class IUnitInput + { + public: + virtual ~IUnitInput() = default; + + virtual void Get( std::string & attGetOuput ) = 0; + }; +} diff --git a/managerbase.cpp b/managerbase.cpp new file mode 100644 index 0000000..6b11352 --- /dev/null +++ b/managerbase.cpp @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPLv3-or-later */ +/* Copyright (c) 2019 Project WomoLIN */ +/* Author Myron Franze */ + +#include "managerbase.h" + +#include + +namespace siguni +{ + + CManagerBase::CManagerBase( interface::IControlbus & attControlbus ) + : controlbus( attControlbus ) + , protocol( controlbus ) + { + } + + void CManagerBase::DoWork() + { + + std::string key; + std::string value; + std::string valueCopy; + + while( 1 ) + { + if( true == protocol.GetKeyValue( key, value ) ) { + if ( true == signalVector.count(key) ) { + + valueCopy = value; + signalVector.at(key)->UpdateUnit( key, value ); + + if( 0 == valueCopy.compare( "GET" ) ) { + protocol.SendKeyValue( key, value ); + } + } + } + } + } +} diff --git a/managerbase.h b/managerbase.h new file mode 100644 index 0000000..9d03db7 --- /dev/null +++ b/managerbase.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPLv3-or-later */ +/* Copyright (c) 2020 Project WomoLIN */ +/* Author Myron Franze */ + +#pragma once + +#include "interface/isignal.h" +#include "protocol.h" + +#include + +namespace siguni +{ + + class CManagerBase + { + public: + CManagerBase( interface::IControlbus & attControlbus ); + ~CManagerBase() = default; + + void DoWork(); + + protected: + std::string message; + std::map signalVector; + + private: + interface::IControlbus & controlbus; + CProtocol protocol; + + }; +} diff --git a/protocol.cpp b/protocol.cpp new file mode 100644 index 0000000..b3ce3dc --- /dev/null +++ b/protocol.cpp @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPLv3-or-later */ +/* Copyright (c) 2019 Project WomoLIN */ +/* Author Myron Franze */ + +#include "protocol.h" + +#include + +namespace siguni +{ + + CProtocol::CProtocol( interface::IControlbus & attControlbus ) + : controlbus( attControlbus ) + { + } + + bool CProtocol::GetKeyValue( std::string & attKey, std::string & attValue) + { + // if no key or value found, then send empty strings + attKey.clear(); + attValue.clear(); + + std::string buffer; + buffer.clear(); + + if( 0 >= controlbus.ReadData( buffer ) ) { // no data read + return false; + } + + messageBuffer += buffer; + buffer.clear(); // clearing for get key and value from protocol string + + auto pos = messageBuffer.find( STARTBYTE ); + if ( std::string::npos == pos ){ + messageBuffer.clear(); + return false; + } + // remove all bytes left from startbyte + messageBuffer = messageBuffer.substr( pos + 1 ); + + pos = messageBuffer.find( ENDBYTE ); + if ( std::string::npos == pos ){ + return false; + } + + // copy a full message and remove this message from buffer + auto protocolString = messageBuffer.substr( 0, pos ); + messageBuffer = messageBuffer.substr( pos ); + + // separator present ? + pos = protocolString.find( SEPARATOR ); + if ( std::string::npos == pos ) { + return false; + } + + // extract key and value + attKey = protocolString.substr( 0, pos ); + attValue = protocolString.substr( pos + 1 ); + + return true; + } + + void CProtocol::SendKeyValue( std::string & attKey, std::string & attValue ) + { + std::string message; + message = STARTBYTE + attKey + SEPARATOR + attValue + ENDBYTE + LINEBREAK; + controlbus.WriteData( message ); + } + + +} diff --git a/protocol.h b/protocol.h new file mode 100644 index 0000000..e3002f6 --- /dev/null +++ b/protocol.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPLv3-or-later */ +/* Copyright (c) 2019 Project WomoLIN */ +/* Author Myron Franze */ + +#pragma once + +#include "interface/icontrolbus.h" + +namespace siguni +{ + + class CProtocol final + { + public: + CProtocol( interface::IControlbus & attControlbus ); + ~CProtocol() = default; + + bool GetKeyValue( std::string & attKey, std::string & attValue); + void SendKeyValue( std::string & attKey, std::string & attValue); + + private: + interface::IControlbus & controlbus; + std::string messageBuffer; + + + private: + + static constexpr char STARTBYTE { '^' }; + static constexpr char SEPARATOR { ';' }; + static constexpr char ENDBYTE { '$' }; + static constexpr char LINEBREAK { '\n' }; + }; +} + diff --git a/signal.cpp b/signal.cpp new file mode 100644 index 0000000..64afec6 --- /dev/null +++ b/signal.cpp @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPLv3-or-later */ +/* Copyright (c) 2019 Project WomoLIN */ +/* Author Myron Franze */ + +#include "signal.h" + +namespace siguni +{ + + void CSignalSetReset::UpdateUnit( std::string & attKey, std::string & attValue ) + { + + for( const auto & unit : units ){ + unit->UpdateUnitSignalSetReset( attKey, attValue ); + } + + } + + void CSignalGetVersion::UpdateUnit( std::string & attKey, std::string & attValue ) + { + for( const auto & unit : units ){ + unit->UpdateUnitSignalGetVersion( attKey, attValue ); + } + } + + void CSignalGetVoltage::UpdateUnit( std::string & attKey, std::string & attValue ) + { + for( const auto & unit : units ){ + unit->UpdateUnitSignalGetVoltage( attKey, attValue ); + } + } + + + +} diff --git a/signal.h b/signal.h new file mode 100644 index 0000000..688c897 --- /dev/null +++ b/signal.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPLv3-or-later */ +/* Copyright (c) 2019 Project WomoLIN */ +/* Author Myron Franze */ + +#pragma once + +#include "interface/isignal.h" +#include + +namespace siguni +{ + + template + class CSignalAddUnit + { + public: + CSignalAddUnit() = default; + ~CSignalAddUnit() = default; + + void AddUnit(T* unit); + + protected: + std::vector units; + }; + + + template + void CSignalAddUnit::AddUnit( T* unit ) + { + units.push_back(unit); + } + + + class CSignalSetReset final + : public CSignalAddUnit + , public interface::ISignal + { + public: + CSignalSetReset() = default; + ~CSignalSetReset() = default; + void UpdateUnit( std::string & attKey, std::string & attValue ) override final; + }; + + class CSignalGetVoltage final + : public CSignalAddUnit + , public interface::ISignal + { + public: + CSignalGetVoltage() = default; + ~CSignalGetVoltage() = default; + void UpdateUnit( std::string & attKey, std::string & attValue ) override final; + }; + + + class CSignalGetVersion final + : public CSignalAddUnit + , public interface::ISignal + { + public: + CSignalGetVersion() = default; + ~CSignalGetVersion() = default; + void UpdateUnit( std::string & attKey, std::string & attValue ) override final; + }; + + +} diff --git a/unit.cpp b/unit.cpp new file mode 100644 index 0000000..6f8f03a --- /dev/null +++ b/unit.cpp @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPLv3-or-later */ +/* Copyright (c) 2019 Project WomoLIN */ +/* Author Myron Franze */ + +#include "unit.h" + +namespace siguni +{ + + CUnitOutput::CUnitOutput( interface::IUnitOutput & attUnitOutput ) : unitOutput( attUnitOutput ) {} + + void CUnitOutput::UpdateUnitSignalSetReset( std::string & /*attKey*/, std::string & attValue ) + { + unitOutput.Set( attValue ); + } + + CUnitInput::CUnitInput( interface::IUnitInput & attUnitInput ) : unitInput( attUnitInput ) {} + + void CUnitInput::UpdateUnitSignalSetReset( std::string & /*attKey*/, std::string & attValue ) + { + unitInput.Get( attValue ); + } + + void CUnitInput::UpdateUnitSignalGetVersion( std::string & /*attKey*/, std::string & attValue ) + { + unitInput.Get( attValue ); + } + + void CUnitInput::UpdateUnitSignalGetVoltage( std::string & /*attKey*/, std::string & attValue ) + { + unitInput.Get( attValue ); + } + + + + +} diff --git a/unit.h b/unit.h new file mode 100644 index 0000000..2dcfa17 --- /dev/null +++ b/unit.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPLv3-or-later */ +/* Copyright (c) 2019 Project WomoLIN */ +/* Author Myron Franze */ + +#pragma once + +#include "interface/isignal.h" +#include "interface/iunit.h" + +namespace siguni +{ + + class CUnitOutput + : public interface::ISignalSetReset + { + public: + CUnitOutput( interface::IUnitOutput & attUnitOutput) ; + ~CUnitOutput() = default; + + void UpdateUnitSignalSetReset( std::string & attKey, std::string & attValue ) override final; + + private: + interface::IUnitOutput & unitOutput; + }; + + class CUnitInput + : public interface::ISignalSetReset + , public interface::ISignalGetVersion + , public interface::ISignalGetVoltage + { + public: + CUnitInput( interface::IUnitInput & attUnitInput) ; + ~CUnitInput() = default; + + void UpdateUnitSignalSetReset( std::string & attKey, std::string & attValue ) override final; + void UpdateUnitSignalGetVersion( std::string & attKey, std::string & attValue ) override final; + void UpdateUnitSignalGetVoltage( std::string & attKey, std::string & attValue ) override final; + + private: + interface::IUnitInput & unitInput; + }; + + +}