dcc++: added sensor/input support

(not yet tested with real hardware)
Dieser Commit ist enthalten in:
Reinder Feenstra 2022-02-01 23:01:49 +01:00
Ursprung 521998fd3a
Commit 8bbf2dd000
4 geänderte Dateien mit 67 neuen und 0 gelöschten Zeilen

Datei anzeigen

@ -39,10 +39,12 @@ DCCPlusPlusInterface::DCCPlusPlusInterface(World& world, std::string_view _id)
, baudrate{this, "baudrate", 115200, PropertyFlags::ReadWrite | PropertyFlags::Store}
, dccplusplus{this, "dccplusplus", nullptr, PropertyFlags::ReadOnly | PropertyFlags::Store | PropertyFlags::SubObject}
, decoders{this, "decoders", nullptr, PropertyFlags::ReadOnly | PropertyFlags::NoStore | PropertyFlags::SubObject}
, inputs{this, "inputs", nullptr, PropertyFlags::ReadOnly | PropertyFlags::NoStore | PropertyFlags::SubObject}
, outputs{this, "outputs", nullptr, PropertyFlags::ReadOnly | PropertyFlags::NoStore | PropertyFlags::SubObject}
{
dccplusplus.setValueInternal(std::make_shared<DCCPlusPlus::Settings>(*this, dccplusplus.name()));
decoders.setValueInternal(std::make_shared<DecoderList>(*this, decoders.name()));
inputs.setValueInternal(std::make_shared<InputList>(*this, inputs.name()));
outputs.setValueInternal(std::make_shared<OutputList>(*this, outputs.name()));
Attributes::addDisplayName(device, DisplayName::Serial::device);
@ -61,6 +63,9 @@ DCCPlusPlusInterface::DCCPlusPlusInterface(World& world, std::string_view _id)
Attributes::addDisplayName(decoders, DisplayName::Hardware::decoders);
m_interfaceItems.insertBefore(decoders, notes);
Attributes::addDisplayName(inputs, DisplayName::Hardware::inputs);
m_interfaceItems.insertBefore(inputs, notes);
Attributes::addDisplayName(outputs, DisplayName::Hardware::outputs);
m_interfaceItems.insertBefore(outputs, notes);
}
@ -87,6 +92,22 @@ void DCCPlusPlusInterface::decoderChanged(const Decoder& decoder, DecoderChangeF
m_kernel->decoderChanged(decoder, changes, functionNumber);
}
bool DCCPlusPlusInterface::addInput(Input& input)
{
const bool success = InputController::addInput(input);
if(success)
inputs->addObject(input.shared_ptr<Input>());
return success;
}
bool DCCPlusPlusInterface::removeInput(Input& input)
{
const bool success = InputController::removeInput(input);
if(success)
inputs->removeObject(input.shared_ptr<Input>());
return success;
}
bool DCCPlusPlusInterface::addOutput(Output& output)
{
const bool success = OutputController::addOutput(output);
@ -152,6 +173,8 @@ bool DCCPlusPlusInterface::setOnline(bool& value)
m_world.powerOff();
});
m_kernel->setDecoderController(this);
m_kernel->setInputController(this);
m_kernel->setOutputController(this);
m_kernel->start();
m_dccplusplusPropertyChanged = dccplusplus->propertyChanged.connect(

Datei anzeigen

@ -28,6 +28,8 @@
#include "../protocol/dccplusplus/settings.hpp"
#include "../decoder/decodercontroller.hpp"
#include "../decoder/decoderlist.hpp"
#include "../input/inputcontroller.hpp"
#include "../input/list/inputlist.hpp"
#include "../output/outputcontroller.hpp"
#include "../output/list/outputlist.hpp"
#include "../../core/objectproperty.hpp"
@ -39,6 +41,7 @@
class DCCPlusPlusInterface final
: public Interface
, public DecoderController
, public InputController
, public OutputController
{
CLASS_ID("interface.dccplusplus")
@ -67,6 +70,7 @@ class DCCPlusPlusInterface final
Property<uint32_t> baudrate;
ObjectProperty<DCCPlusPlus::Settings> dccplusplus;
ObjectProperty<DecoderList> decoders;
ObjectProperty<InputList> inputs;
ObjectProperty<OutputList> outputs;
DCCPlusPlusInterface(World& world, std::string_view _id);
@ -76,6 +80,11 @@ class DCCPlusPlusInterface final
[[nodiscard]] bool removeDecoder(Decoder& decoder) final;
void decoderChanged(const Decoder& decoder, DecoderChangeFlags changes, uint32_t functionNumber) final;
// InputController:
std::pair<uint32_t, uint32_t> inputAddressMinMax() const final { return {DCCPlusPlus::Kernel::idMin, DCCPlusPlus::Kernel::idMax}; }
[[nodiscard]] bool addInput(Input& input) final;
[[nodiscard]] bool removeInput(Input& input) final;
// OutputController:
std::pair<uint32_t, uint32_t> outputAddressMinMax() const final { return {DCCPlusPlus::Kernel::outputAddressMin, DCCPlusPlus::Kernel::outputAddressMax}; }
[[nodiscard]] bool addOutput(Output& output) final;

Datei anzeigen

@ -24,11 +24,13 @@
#include "messages.hpp"
#include "../../decoder/decoder.hpp"
#include "../../decoder/decoderchangeflags.hpp"
#include "../../input/inputcontroller.hpp"
#include "../../../utils/setthreadname.hpp"
#include "../../../utils/rtrim.hpp"
#include "../../../core/eventloop.hpp"
#include "../../../log/log.hpp"
#include "../../../utils/inrange.hpp"
#include "../../../utils/fromchars.hpp"
namespace DCCPlusPlus {
@ -149,6 +151,22 @@ void Kernel::receive(std::string_view message)
}
}
break;
case 'q': // Sensor/Input: ACTIVE to INACTIVE
case 'Q': // Sensor/Input: INACTIVE to ACTIVE
if(m_inputController && message[2] == ' ')
{
uint32_t id;
if(auto r = fromChars(message.substr(3), id); r.ec == std::errc() && *r.ptr == '>' && id <= idMax)
{
EventLoop::call(
[this, id, value=toTriState(message[1] == 'Q')]()
{
m_inputController->updateInputValue(id, value);
});
}
}
break;
}
}
}

Datei anzeigen

@ -34,6 +34,7 @@
class Decoder;
enum class DecoderChangeFlags;
class DecoderController;
class InputController;
class OutputController;
namespace DCCPlusPlus {
@ -43,6 +44,8 @@ struct Message;
class Kernel
{
public:
static constexpr uint32_t idMin = 0;
static constexpr uint32_t idMax = 32767;
static constexpr uint16_t outputAddressMin = 1;
static constexpr uint16_t outputAddressMax = 2044;
@ -60,6 +63,8 @@ class Kernel
DecoderController* m_decoderController;
InputController* m_inputController;
OutputController* m_outputController;
std::array<TriState, outputAddressMax - outputAddressMin + 1> m_outputValues;
@ -184,6 +189,18 @@ class Kernel
m_decoderController = decoderController;
}
/**
* @brief Set the input controller
*
* @param[in] inputController The input controller
* @note This function may not be called when the kernel is running.
*/
inline void setInputController(InputController* inputController)
{
assert(!m_started);
m_inputController = inputController;
}
/**
* @brief Set the output controller
*