server: Z21 add LanXExtAccessoryInfo message
- Support querying and obtaining DCCExt accessory status
Dieser Commit ist enthalten in:
Ursprung
09c86cb1cc
Commit
d11c40a30f
@ -89,6 +89,21 @@ void ClientKernel::receive(const Message& message)
|
||||
}
|
||||
break;
|
||||
|
||||
case LAN_X_EXT_ACCESSORY_INFO:
|
||||
if(message.dataLen() == sizeof(LanXExtAccessoryInfo))
|
||||
{
|
||||
const auto& reply = static_cast<const LanXExtAccessoryInfo&>(message);
|
||||
if(reply.isDataValid())
|
||||
{
|
||||
EventLoop::call(
|
||||
[this, address=reply.address(), value=reply.aspect()]()
|
||||
{
|
||||
m_outputController->updateOutputValue(OutputChannel::DCCext, address, value);
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LAN_X_BC:
|
||||
if(message == LanXBCTrackPowerOff() || message == LanXBCTrackShortCircuit())
|
||||
{
|
||||
|
||||
@ -151,6 +151,29 @@ bool SimulationIOHandler::send(const Message& message)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LAN_X_SET_EXT_ACCESSORY:
|
||||
{
|
||||
if(message.dataLen() == sizeof(LanXSetExtAccessory))
|
||||
{
|
||||
const auto& setAccessory = static_cast<const LanXSetExtAccessory&>(message);
|
||||
if((m_broadcastFlags & BroadcastFlags::PowerLocoTurnoutChanges) == BroadcastFlags::PowerLocoTurnoutChanges)
|
||||
{
|
||||
// Client has subscribed to turnout changes
|
||||
reply(LanXExtAccessoryInfo(setAccessory.address(), setAccessory.aspect(), false));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LAN_X_EXT_ACCESSORY_INFO:
|
||||
{
|
||||
if(message.dataLen() == sizeof(LanXGetExtAccessoryInfo))
|
||||
{
|
||||
const auto& getAccessory = static_cast<const LanXGetExtAccessoryInfo&>(message);
|
||||
//We do not keep a record of accessory states so send "Unknown Position"
|
||||
reply(LanXExtAccessoryInfo(getAccessory.address(), 0, true));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -120,6 +120,24 @@ std::string toString(const Message& message, bool raw)
|
||||
s.append(" queue=").append(setTurnout.queue() ? "yes" : "no");
|
||||
break;
|
||||
}
|
||||
case LAN_X_EXT_ACCESSORY_INFO:
|
||||
{
|
||||
if(message.dataLen() == sizeof(LanXExtAccessoryInfo))
|
||||
{
|
||||
const auto& reply = static_cast<const LanXExtAccessoryInfo&>(message);
|
||||
s = "LAN_X_EXT_ACCESSORY_INFO";
|
||||
s.append(" address=").append(std::to_string(reply.address()));
|
||||
s.append(" aspect=").append(std::to_string(reply.aspect()));
|
||||
s.append(" unknown=").append(std::to_string(!reply.isDataValid()));
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto& getAccessoryInfo = static_cast<const LanXGetExtAccessoryInfo&>(message);
|
||||
s = "LAN_X_GET_EXT_ACCESSORY_INFO";
|
||||
s.append(" address=").append(std::to_string(getAccessoryInfo.address()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LAN_X_SET_EXT_ACCESSORY:
|
||||
{
|
||||
const auto& setExtAccessory = static_cast<const LanXSetExtAccessory&>(message);
|
||||
|
||||
@ -145,6 +145,8 @@ enum LocoMode : uint8_t
|
||||
|
||||
static constexpr uint8_t LAN_X_TURNOUT_INFO = 0x43;
|
||||
static constexpr uint8_t LAN_X_SET_TURNOUT = 0x53;
|
||||
|
||||
static constexpr uint8_t LAN_X_EXT_ACCESSORY_INFO = 0x44;
|
||||
static constexpr uint8_t LAN_X_SET_EXT_ACCESSORY = 0x54;
|
||||
|
||||
static constexpr uint8_t LAN_X_BC = 0x61;
|
||||
@ -549,9 +551,109 @@ struct LanXSetExtAccessory : LanX
|
||||
{
|
||||
return rawAddress() + 3;
|
||||
}
|
||||
|
||||
inline uint8_t aspect() const
|
||||
{
|
||||
return db2;
|
||||
}
|
||||
} ATTRIBUTE_PACKED;
|
||||
static_assert(sizeof(LanXSetExtAccessory) == 10);
|
||||
|
||||
// LAN_X_GET_EXT_ACCESSORY_INFO
|
||||
struct LanXGetExtAccessoryInfo : LanX
|
||||
{
|
||||
uint8_t addressMSB;
|
||||
uint8_t addressLSB;
|
||||
uint8_t db2 = 0x00; // Reserved for future extension, must be 0x00
|
||||
uint8_t checksum;
|
||||
|
||||
LanXGetExtAccessoryInfo(uint16_t address)
|
||||
: LanX(sizeof(LanXGetExtAccessoryInfo), LAN_X_EXT_ACCESSORY_INFO)
|
||||
, addressMSB(high8(address + 3))
|
||||
, addressLSB(low8(address + 3))
|
||||
{
|
||||
}
|
||||
|
||||
inline uint16_t rawAddress() const
|
||||
{
|
||||
return to16(addressLSB, addressMSB);
|
||||
}
|
||||
|
||||
inline uint16_t address() const
|
||||
{
|
||||
return rawAddress() + 3;
|
||||
}
|
||||
} ATTRIBUTE_PACKED;
|
||||
static_assert(sizeof(LanXGetExtAccessoryInfo) == 9);
|
||||
|
||||
// LAN_X_EXT_ACCESSORY_INFO
|
||||
struct LanXExtAccessoryInfo : LanX
|
||||
{
|
||||
uint8_t addressMSB;
|
||||
uint8_t addressLSB;
|
||||
uint8_t db2;
|
||||
uint8_t db3 = 0x00;
|
||||
uint8_t checksum;
|
||||
|
||||
LanXExtAccessoryInfo(uint16_t address)
|
||||
: LanX(sizeof(LanXExtAccessoryInfo), LAN_X_EXT_ACCESSORY_INFO)
|
||||
, addressMSB(high8(address + 3))
|
||||
, addressLSB(low8(address + 3))
|
||||
{
|
||||
}
|
||||
|
||||
LanXExtAccessoryInfo(uint16_t address, uint8_t aspect, bool isUnknown)
|
||||
: LanXExtAccessoryInfo(address)
|
||||
{
|
||||
db2 = aspect;
|
||||
db3 = isUnknown ? 0xFF : 0x00; // 0xFF represent Unknown Data
|
||||
updateChecksum();
|
||||
}
|
||||
|
||||
LanXExtAccessoryInfo(uint16_t address, bool dir, uint8_t powerOnTime)
|
||||
: LanXExtAccessoryInfo(address)
|
||||
{
|
||||
assert(powerOnTime <= 127);
|
||||
db2 = powerOnTime & 0x7F;
|
||||
if(dir)
|
||||
{
|
||||
db2 |= 0x80;
|
||||
}
|
||||
updateChecksum();
|
||||
}
|
||||
|
||||
inline uint16_t rawAddress() const
|
||||
{
|
||||
return to16(addressLSB, addressMSB);
|
||||
}
|
||||
|
||||
inline uint16_t address() const
|
||||
{
|
||||
return rawAddress() + 3;
|
||||
}
|
||||
|
||||
inline bool isDataValid() const
|
||||
{
|
||||
return db3 == 0x00;
|
||||
}
|
||||
|
||||
inline uint8_t aspect() const
|
||||
{
|
||||
return db2;
|
||||
}
|
||||
|
||||
inline bool direction() const
|
||||
{
|
||||
return db2 & 0x80;
|
||||
}
|
||||
|
||||
inline bool powerOnTime() const
|
||||
{
|
||||
return db2 & 0x7F;
|
||||
}
|
||||
} ATTRIBUTE_PACKED;
|
||||
static_assert(sizeof(LanXExtAccessoryInfo) == 10);
|
||||
|
||||
// LAN_X_SET_STOP
|
||||
struct LanXSetStop : LanX
|
||||
{
|
||||
|
||||
Laden…
x
In neuem Issue referenzieren
Einen Benutzer sperren