z21: implemented input simulation
Dieser Commit ist enthalten in:
Ursprung
71920a5a72
Commit
14c41bf540
@ -140,6 +140,12 @@ bool Z21Interface::removeInput(Input& input)
|
||||
return success;
|
||||
}
|
||||
|
||||
void Z21Interface::inputSimulateChange(uint32_t channel, uint32_t address)
|
||||
{
|
||||
if(m_kernel && inRange(address, outputAddressMinMax(channel)))
|
||||
m_kernel->simulateInputChange(channel, address);
|
||||
}
|
||||
|
||||
bool Z21Interface::addOutput(Output& output)
|
||||
{
|
||||
const bool success = OutputController::addOutput(output);
|
||||
|
||||
@ -86,6 +86,7 @@ class Z21Interface final
|
||||
std::pair<uint32_t, uint32_t> inputAddressMinMax(uint32_t channel) const final;
|
||||
[[nodiscard]] bool addInput(Input& input) final;
|
||||
[[nodiscard]] bool removeInput(Input& input) final;
|
||||
void inputSimulateChange(uint32_t channel, uint32_t address) final;
|
||||
|
||||
// OutputController:
|
||||
std::pair<uint32_t, uint32_t> outputAddressMinMax(uint32_t /*channel*/) const final { return {Z21::ClientKernel::outputAddressMin, Z21::ClientKernel::outputAddressMax}; }
|
||||
|
||||
@ -32,8 +32,9 @@
|
||||
|
||||
namespace Z21 {
|
||||
|
||||
ClientKernel::ClientKernel(const ClientConfig& config)
|
||||
: m_keepAliveTimer(m_ioContext)
|
||||
ClientKernel::ClientKernel(const ClientConfig& config, bool simulation)
|
||||
: m_simulation{simulation}
|
||||
, m_keepAliveTimer(m_ioContext)
|
||||
, m_config{config}
|
||||
{
|
||||
}
|
||||
@ -349,6 +350,45 @@ bool ClientKernel::setOutput(uint16_t address, bool value)
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClientKernel::simulateInputChange(uint32_t channel, uint32_t address)
|
||||
{
|
||||
if(!m_simulation)
|
||||
return;
|
||||
|
||||
m_ioContext.post(
|
||||
[this, channel, address]()
|
||||
{
|
||||
(void)address;
|
||||
switch(channel)
|
||||
{
|
||||
case InputChannel::rbus:
|
||||
{
|
||||
LanRMBusDataChanged message;
|
||||
message.groupIndex = (address - rbusAddressMin) / LanRMBusDataChanged::feedbackStatusCount;
|
||||
|
||||
for(uint8_t i = 0; i < LanRMBusDataChanged::feedbackStatusCount; i++)
|
||||
{
|
||||
const uint32_t n = static_cast<uint32_t>(message.groupIndex) * LanRMBusDataChanged::feedbackStatusCount + i;
|
||||
if(address == rbusAddressMin + n)
|
||||
message.setFeedbackStatus(i, m_rbusFeedbackStatus[n] != TriState::True);
|
||||
else
|
||||
message.setFeedbackStatus(i, m_rbusFeedbackStatus[n] == TriState::True);
|
||||
}
|
||||
|
||||
receive(message);
|
||||
|
||||
break;
|
||||
}
|
||||
case InputChannel::loconet:
|
||||
{
|
||||
const uint16_t feedbackAddress = address - loconetAddressMin;
|
||||
receive(LanLocoNetDetectorOccupancyDetector(feedbackAddress, m_loconetFeedbackStatus[feedbackAddress] != TriState::True));
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ClientKernel::onStart()
|
||||
{
|
||||
// reset all state values
|
||||
|
||||
@ -59,6 +59,7 @@ class ClientKernel final : public Kernel
|
||||
};
|
||||
|
||||
private:
|
||||
const bool m_simulation;
|
||||
boost::asio::steady_timer m_keepAliveTimer;
|
||||
|
||||
uint32_t m_serialNumber;
|
||||
@ -84,7 +85,7 @@ class ClientKernel final : public Kernel
|
||||
|
||||
ClientConfig m_config;
|
||||
|
||||
ClientKernel(const ClientConfig& config);
|
||||
ClientKernel(const ClientConfig& config, bool simulation);
|
||||
|
||||
void onStart() final;
|
||||
void onStop() final;
|
||||
@ -115,7 +116,7 @@ class ClientKernel final : public Kernel
|
||||
static std::unique_ptr<ClientKernel> create(const ClientConfig& config, Args... args)
|
||||
{
|
||||
static_assert(std::is_base_of_v<IOHandler, IOHandlerType>);
|
||||
std::unique_ptr<ClientKernel> kernel{new ClientKernel(config)};
|
||||
std::unique_ptr<ClientKernel> kernel{new ClientKernel(config, isSimulation<IOHandlerType>())};
|
||||
kernel->setIOHandler(std::make_unique<IOHandlerType>(*kernel, std::forward<Args>(args)...));
|
||||
return kernel;
|
||||
}
|
||||
@ -236,6 +237,8 @@ class ClientKernel final : public Kernel
|
||||
* @return \c true if send successful, \c false otherwise.
|
||||
*/
|
||||
bool setOutput(uint16_t address, bool value);
|
||||
|
||||
void simulateInputChange(uint32_t channel, uint32_t address);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -58,6 +58,12 @@ class IOHandler
|
||||
virtual void purgeClient(ClientId /*id*/) {}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
constexpr bool isSimulation()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -54,6 +54,12 @@ class SimulationIOHandler final : public IOHandler
|
||||
bool send(const Message& message) final;
|
||||
};
|
||||
|
||||
template<>
|
||||
constexpr bool isSimulation<SimulationIOHandler>()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -1274,6 +1274,15 @@ struct LanRMBusDataChanged : Message
|
||||
assert(index < feedbackStatusCount);
|
||||
return feedbackStatus[index >> 3] & (1 << (index & 0x7));
|
||||
}
|
||||
|
||||
inline void setFeedbackStatus(uint8_t index, bool value)
|
||||
{
|
||||
assert(index < feedbackStatusCount);
|
||||
if(value)
|
||||
feedbackStatus[index >> 3] |= (1 << (index & 0x7));
|
||||
else
|
||||
feedbackStatus[index >> 3] &= ~static_cast<uint8_t>(1 << (index & 0x7));
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(LanRMBusDataChanged) == 15);
|
||||
|
||||
|
||||
Laden…
x
In neuem Issue referenzieren
Einen Benutzer sperren