dcc++: added sensor/input support
(not yet tested with real hardware)
Dieser Commit ist enthalten in:
Ursprung
521998fd3a
Commit
8bbf2dd000
@ -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(
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
*
|
||||
|
||||
Laden…
x
In neuem Issue referenzieren
Einen Benutzer sperren