loconet: added support for F9-F20 (works with DR5000)
Dieser Commit ist enthalten in:
Ursprung
3edd6525d0
Commit
4bb36509a5
@ -22,7 +22,7 @@
|
||||
|
||||
#include "loconet.hpp"
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <chrono>
|
||||
#include "../../core/eventloop.hpp"
|
||||
#include "../../core/traintastic.hpp"
|
||||
#include "../commandstation/commandstation.hpp"
|
||||
@ -106,6 +106,16 @@ std::string to_string(const LocoNet::Message& message, bool raw = false)
|
||||
s.append(" f8=").append(locoSnd.f8() ? "on" : "off");
|
||||
break;
|
||||
}
|
||||
case LocoNet::OPC_LOCO_F9F12:
|
||||
{
|
||||
const LocoNet::LocoF9F12& locoF9F12 = static_cast<const LocoNet::LocoF9F12&>(message);
|
||||
s.append(" slot=").append(std::to_string(locoF9F12.slot));
|
||||
s.append(" f9=").append(locoF9F12.f9() ? "on" : "off");
|
||||
s.append(" f10=").append(locoF9F12.f10() ? "on" : "off");
|
||||
s.append(" f11=").append(locoF9F12.f11() ? "on" : "off");
|
||||
s.append(" f12=").append(locoF9F12.f12() ? "on" : "off");
|
||||
break;
|
||||
}
|
||||
case LocoNet::OPC_INPUT_REP:
|
||||
{
|
||||
const LocoNet::InputRep& inputRep = static_cast<const LocoNet::InputRep&>(message);
|
||||
@ -170,11 +180,6 @@ std::string to_string(const LocoNet::Message& message, bool raw = false)
|
||||
return s;
|
||||
}
|
||||
|
||||
constexpr bool isLongAddress(uint16_t address)
|
||||
{
|
||||
return address > 127;
|
||||
}
|
||||
|
||||
void updateDecoderSpeed(const std::shared_ptr<Hardware::Decoder>& decoder, uint8_t speed)
|
||||
{
|
||||
decoder->emergencyStop.setValueInternal(speed == LocoNet::SPEED_ESTOP);
|
||||
@ -246,9 +251,9 @@ bool LocoNet::send(const Message& message)
|
||||
return m_send(message);
|
||||
}
|
||||
|
||||
void LocoNet::send(uint16_t address, SlotMessage& message)
|
||||
void LocoNet::send(uint16_t address, Message& message, uint8_t& slot)
|
||||
{
|
||||
if((message.slot = m_slots.getSlot(address)) != SLOT_UNKNOWN)
|
||||
if((slot = m_slots.getSlot(address)) != SLOT_UNKNOWN)
|
||||
{
|
||||
updateChecksum(message);
|
||||
send(message);
|
||||
@ -317,7 +322,7 @@ void LocoNet::receive(const Message& message)
|
||||
updateDecoderSpeed(decoder, locoSpd.speed);
|
||||
});
|
||||
break;
|
||||
|
||||
|
||||
case OPC_LOCO_DIRF:
|
||||
EventLoop::call(
|
||||
[this, locoDirF=*static_cast<const LocoDirF*>(&message)]()
|
||||
@ -348,6 +353,20 @@ void LocoNet::receive(const Message& message)
|
||||
});
|
||||
break;
|
||||
|
||||
case OPC_LOCO_F9F12:
|
||||
EventLoop::call(
|
||||
[this, locoF9F12=*static_cast<const LocoF9F12*>(&message)]()
|
||||
{
|
||||
if(auto decoder = getDecoder(locoF9F12.slot))
|
||||
{
|
||||
decoder->setFunctionValue(9, locoF9F12.f9());
|
||||
decoder->setFunctionValue(10, locoF9F12.f10());
|
||||
decoder->setFunctionValue(11, locoF9F12.f11());
|
||||
decoder->setFunctionValue(12, locoF9F12.f12());
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
||||
case OPC_INPUT_REP:
|
||||
EventLoop::call(
|
||||
[this, inputRep=*static_cast<const InputRep*>(&message)]()
|
||||
@ -370,7 +389,7 @@ void LocoNet::receive(const Message& message)
|
||||
else
|
||||
m_queryLocoSlots = SLOT_UNKNOWN; // done
|
||||
}
|
||||
|
||||
|
||||
if(slotReadData.isBusy() || slotReadData.isActive())
|
||||
{
|
||||
m_slots.set(slotReadData.address(), slotReadData.slot);
|
||||
@ -410,7 +429,8 @@ void LocoNet::decoderChanged(const Hardware::Decoder& decoder, Hardware::Decoder
|
||||
LocoSpd message{static_cast<uint8_t>(decoder.emergencyStop ? 1 : (decoder.speedStep > 0 ? 1 + decoder.speedStep : 0))};
|
||||
send(decoder.address, message);
|
||||
}
|
||||
else if(has(changes, DecoderChangeFlags::FunctionValue | DecoderChangeFlags::Direction))
|
||||
|
||||
if(has(changes, DecoderChangeFlags::FunctionValue | DecoderChangeFlags::Direction))
|
||||
{
|
||||
if(functionNumber <= 4 || has(changes, DecoderChangeFlags::Direction))
|
||||
{
|
||||
@ -432,6 +452,28 @@ void LocoNet::decoderChanged(const Hardware::Decoder& decoder, Hardware::Decoder
|
||||
decoder.getFunctionValue(8)};
|
||||
send(decoder.address, message);
|
||||
}
|
||||
else if(functionNumber <= 12)
|
||||
{
|
||||
LocoF9F12 message{
|
||||
decoder.getFunctionValue(9),
|
||||
decoder.getFunctionValue(10),
|
||||
decoder.getFunctionValue(11),
|
||||
decoder.getFunctionValue(12)};
|
||||
send(decoder.address, message);
|
||||
}
|
||||
else if(functionNumber <= 20)
|
||||
{
|
||||
LocoF13F20 message{
|
||||
decoder.getFunctionValue(13),
|
||||
decoder.getFunctionValue(14),
|
||||
decoder.getFunctionValue(15),
|
||||
decoder.getFunctionValue(16),
|
||||
decoder.getFunctionValue(17),
|
||||
decoder.getFunctionValue(18),
|
||||
decoder.getFunctionValue(19),
|
||||
decoder.getFunctionValue(20)};
|
||||
send(decoder.address, message);
|
||||
}
|
||||
else
|
||||
logWarning("Function F" + std::to_string(functionNumber) + " not supported");
|
||||
}
|
||||
|
||||
@ -26,11 +26,6 @@
|
||||
* LocoNet is a registered trademark of DigiTrax, Inc.
|
||||
*/
|
||||
|
||||
/**
|
||||
* OPC_MULTI_SENSE and OPC_MULTI_SENSE_LONG message format
|
||||
* based on reverse engineering, see loconet.md
|
||||
*/
|
||||
|
||||
#ifndef TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_LOCONET_HPP
|
||||
#define TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_LOCONET_HPP
|
||||
|
||||
@ -55,6 +50,12 @@ class LocoNet : public SubObject
|
||||
{
|
||||
//friend class LocoNetInput;
|
||||
|
||||
protected:
|
||||
static constexpr bool isLongAddress(uint16_t address)
|
||||
{
|
||||
return address > 127;
|
||||
}
|
||||
|
||||
public:
|
||||
struct Message;
|
||||
|
||||
@ -84,10 +85,24 @@ class LocoNet : public SubObject
|
||||
static constexpr uint8_t SL_F2 = 0x02;
|
||||
static constexpr uint8_t SL_F1 = 0x01;
|
||||
|
||||
static constexpr uint8_t SL_F8 = 0x08;
|
||||
static constexpr uint8_t SL_F7 = 0x04;
|
||||
static constexpr uint8_t SL_F6 = 0x02;
|
||||
static constexpr uint8_t SL_F5 = 0x01;
|
||||
static constexpr uint8_t SL_F6 = 0x02;
|
||||
static constexpr uint8_t SL_F7 = 0x04;
|
||||
static constexpr uint8_t SL_F8 = 0x08;
|
||||
|
||||
static constexpr uint8_t SL_F9 = 0x01;
|
||||
static constexpr uint8_t SL_F10 = 0x02;
|
||||
static constexpr uint8_t SL_F11 = 0x04;
|
||||
static constexpr uint8_t SL_F12 = 0x08;
|
||||
|
||||
static constexpr uint8_t SL_F13 = 0x01;
|
||||
static constexpr uint8_t SL_F14 = 0x02;
|
||||
static constexpr uint8_t SL_F15 = 0x04;
|
||||
static constexpr uint8_t SL_F16 = 0x08;
|
||||
static constexpr uint8_t SL_F17 = 0x10;
|
||||
static constexpr uint8_t SL_F18 = 0x20;
|
||||
static constexpr uint8_t SL_F19 = 0x40;
|
||||
static constexpr uint8_t SL_F20 = 0x80;
|
||||
|
||||
static constexpr uint8_t MULTI_SENSE_TYPE_MASK = 0xE0;
|
||||
static constexpr uint8_t MULTI_SENSE_TYPE_TRANSPONDER_GONE = 0x00;
|
||||
@ -106,6 +121,7 @@ class LocoNet : public SubObject
|
||||
OPC_LOCO_SPD = 0xA0,
|
||||
OPC_LOCO_DIRF = 0xA1,
|
||||
OPC_LOCO_SND = 0xA2,
|
||||
OPC_LOCO_F9F12 = 0xA3, // based on reverse engineering, see loconet.md
|
||||
OPC_SW_REQ = 0xB0,
|
||||
OPC_SW_REP = 0xB1,
|
||||
OPC_INPUT_REP = 0xB2,
|
||||
@ -121,10 +137,11 @@ class LocoNet : public SubObject
|
||||
OPC_LOCO_ADR = 0xBF,
|
||||
|
||||
// 6 byte message opcodes:
|
||||
OPC_MULTI_SENSE = 0xD0,
|
||||
OPC_MULTI_SENSE = 0xD0, // based on reverse engineering, see loconet.md
|
||||
OPC_D4 = 0xD4,// based on reverse engineering, probably used for multiple sub commands, see loconet.md
|
||||
|
||||
// variable byte message opcodes:
|
||||
OPC_MULTI_SENSE_LONG = 0XE0,
|
||||
OPC_MULTI_SENSE_LONG = 0XE0, // based on reverse engineering, see loconet.md
|
||||
OPC_PEER_XFER = 0xE5,
|
||||
OPC_SL_RD_DATA = 0xE7,
|
||||
OPC_IMM_PACKET = 0xED,
|
||||
@ -161,8 +178,7 @@ class LocoNet : public SubObject
|
||||
return reinterpret_cast<const uint8_t*>(this)[1];
|
||||
|
||||
default:
|
||||
//assert(false);
|
||||
return 0;
|
||||
return 0; // invalid opcode
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -367,7 +383,7 @@ class LocoNet : public SubObject
|
||||
uint8_t checksum;
|
||||
|
||||
LocoSnd(bool f5, bool f6, bool f7, bool f8) :
|
||||
SlotMessage{OPC_LOCO_DIRF, SLOT_UNKNOWN},
|
||||
SlotMessage{OPC_LOCO_SND, SLOT_UNKNOWN},
|
||||
snd{0}
|
||||
{
|
||||
if(f5)
|
||||
@ -436,6 +452,80 @@ class LocoNet : public SubObject
|
||||
};
|
||||
static_assert(sizeof(LocoSnd) == 4);
|
||||
|
||||
struct LocoF9F12 : SlotMessage
|
||||
{
|
||||
uint8_t function;
|
||||
uint8_t checksum;
|
||||
|
||||
LocoF9F12(bool f9, bool f10, bool f11, bool f12) :
|
||||
SlotMessage{OPC_LOCO_F9F12, SLOT_UNKNOWN},
|
||||
function{0}
|
||||
{
|
||||
if(f9)
|
||||
function |= SL_F9;
|
||||
if(f10)
|
||||
function |= SL_F10;
|
||||
if(f11)
|
||||
function |= SL_F11;
|
||||
if(f12)
|
||||
function |= SL_F12;
|
||||
|
||||
checksum = calcChecksum(*this);
|
||||
}
|
||||
|
||||
inline bool f9() const
|
||||
{
|
||||
return function & SL_F9;
|
||||
}
|
||||
|
||||
inline void setF9(bool value)
|
||||
{
|
||||
if(value)
|
||||
function |= SL_F9;
|
||||
else
|
||||
function &= ~SL_F9;
|
||||
}
|
||||
|
||||
inline bool f10() const
|
||||
{
|
||||
return function & SL_F10;
|
||||
}
|
||||
|
||||
inline void setF10(bool value)
|
||||
{
|
||||
if(value)
|
||||
function |= SL_F10;
|
||||
else
|
||||
function &= ~SL_F10;
|
||||
}
|
||||
|
||||
inline bool f11() const
|
||||
{
|
||||
return function & SL_F7;
|
||||
}
|
||||
|
||||
inline void setF11(bool value)
|
||||
{
|
||||
if(value)
|
||||
function |= SL_F11;
|
||||
else
|
||||
function &= ~SL_F11;
|
||||
}
|
||||
|
||||
inline bool f12() const
|
||||
{
|
||||
return function & SL_F8;
|
||||
}
|
||||
|
||||
inline void setF12(bool value)
|
||||
{
|
||||
if(value)
|
||||
function |= SL_F12;
|
||||
else
|
||||
function &= ~SL_F12;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(LocoF9F12) == 4);
|
||||
|
||||
/*
|
||||
|
||||
@ -493,7 +583,7 @@ class LocoNet : public SubObject
|
||||
uint8_t data2;
|
||||
uint8_t checksum;
|
||||
|
||||
RequestSlotData(uint8_t _slot) :
|
||||
RequestSlotData(uint8_t _slot) :
|
||||
Message(OPC_RQ_SL_DATA),
|
||||
slot{_slot},
|
||||
data2{0}
|
||||
@ -528,6 +618,43 @@ class LocoNet : public SubObject
|
||||
};
|
||||
static_assert(sizeof(MultiSense) == 6);
|
||||
|
||||
struct LocoF13F20 : Message
|
||||
{
|
||||
uint8_t data1;
|
||||
uint8_t slot;
|
||||
uint8_t data3;
|
||||
uint8_t function;
|
||||
uint8_t checksum;
|
||||
|
||||
LocoF13F20(bool f13, bool f14, bool f15, bool f16, bool f17, bool f18, bool f19, bool f20) :
|
||||
Message(OPC_D4),
|
||||
data1{0x20},
|
||||
slot{SLOT_UNKNOWN},
|
||||
data3{0x08},
|
||||
function{0}
|
||||
{
|
||||
if(f13)
|
||||
function |= SL_F13;
|
||||
if(f14)
|
||||
function |= SL_F14;
|
||||
if(f15)
|
||||
function |= SL_F15;
|
||||
if(f16)
|
||||
function |= SL_F16;
|
||||
if(f17)
|
||||
function |= SL_F17;
|
||||
if(f18)
|
||||
function |= SL_F18;
|
||||
if(f19)
|
||||
function |= SL_F19;
|
||||
if(f20)
|
||||
function |= SL_F20;
|
||||
|
||||
checksum = calcChecksum(*this);
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(LocoF13F20) == 6);
|
||||
|
||||
struct MultiSenseTransponder : MultiSense
|
||||
{
|
||||
bool isPresent() const
|
||||
@ -792,7 +919,153 @@ class LocoNet : public SubObject
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(SlotReadData) == 14);
|
||||
/*
|
||||
struct ImmediatePacket : Message
|
||||
{
|
||||
uint8_t len;
|
||||
uint8_t header;
|
||||
uint8_t reps;
|
||||
uint8_t dhi;
|
||||
uint8_t im[5];
|
||||
uint8_t checksum;
|
||||
|
||||
ImmediatePacket() :
|
||||
Message(OPC_IMM_PACKET),
|
||||
len{11},
|
||||
header{0x7F},
|
||||
reps{0},
|
||||
dhi{0},
|
||||
im{0, 0, 0, 0, 0}
|
||||
{
|
||||
}
|
||||
|
||||
void setIMCount(uint8_t value)
|
||||
{
|
||||
assert(value <= 5);
|
||||
reps = (reps & 0x8F) | ((value & 0x07) << 4);
|
||||
}
|
||||
|
||||
void updateDHI()
|
||||
{
|
||||
dhi = 0x20 |
|
||||
(im[0] & 0x40) >> 7 |
|
||||
(im[1] & 0x40) >> 6 |
|
||||
(im[2] & 0x40) >> 5 |
|
||||
(im[3] & 0x40) >> 4 |
|
||||
(im[4] & 0x40) >> 3;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(ImmediatePacket) == 11);
|
||||
|
||||
struct ImmediatePacketLoco : ImmediatePacket
|
||||
{
|
||||
ImmediatePacketLoco(uint16_t address, uint8_t repeatCount) :
|
||||
ImmediatePacket()
|
||||
{
|
||||
assert(repeatCount <= 7);
|
||||
reps = repeatCount & 0x07;
|
||||
|
||||
if(isLongAddress(address))
|
||||
{
|
||||
im[0] = 0xC0 | ((address >> 8) & 0x3F);
|
||||
im[1] = address & 0xFF;
|
||||
}
|
||||
else
|
||||
im[0] = address & 0x7F;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(ImmediatePacketLoco) == sizeof(ImmediatePacket));
|
||||
|
||||
struct ImmediatePacketF9F12 : ImmediatePacketLoco
|
||||
{
|
||||
ImmediatePacketF9F12(uint16_t address, bool f9, bool f10, bool f11, bool f12, uint8_t repeatCount = 2) :
|
||||
ImmediatePacketLoco(address, repeatCount)
|
||||
{
|
||||
const uint8_t offset = (im[0] & 0x80) ? 2 : 1;
|
||||
|
||||
im[offset] = 0xB0; // Function group two instruction: F9-F12
|
||||
if(f9)
|
||||
im[offset] |= 0x01;
|
||||
if(f10)
|
||||
im[offset] |= 0x02;
|
||||
if(f11)
|
||||
im[offset] |= 0x04;
|
||||
if(f12)
|
||||
im[offset] |= 0x08;
|
||||
|
||||
setIMCount(offset + 1);
|
||||
updateDHI();
|
||||
checksum = calcChecksum(*this);
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(ImmediatePacketF9F12) == sizeof(ImmediatePacketLoco));
|
||||
|
||||
struct ImmediatePacketF13F20 : ImmediatePacketLoco
|
||||
{
|
||||
ImmediatePacketF13F20(uint16_t address, bool f13, bool f14, bool f15, bool f16, bool f17, bool f18, bool f19, bool f20, uint8_t repeatCount = 2) :
|
||||
ImmediatePacketLoco(address, repeatCount)
|
||||
{
|
||||
uint8_t offset = (im[0] & 0x80) ? 2 : 1;
|
||||
|
||||
im[offset++] = 0xDE; // Feature Expansion Instruction: F13-F20 function control
|
||||
|
||||
if(f13)
|
||||
im[offset] |= 0x01;
|
||||
if(f14)
|
||||
im[offset] |= 0x02;
|
||||
if(f15)
|
||||
im[offset] |= 0x04;
|
||||
if(f16)
|
||||
im[offset] |= 0x08;
|
||||
if(f17)
|
||||
im[offset] |= 0x10;
|
||||
if(f18)
|
||||
im[offset] |= 0x20;
|
||||
if(f19)
|
||||
im[offset] |= 0x40;
|
||||
if(f20)
|
||||
im[offset] |= 0x80;
|
||||
|
||||
setIMCount(offset + 1);
|
||||
updateDHI();
|
||||
checksum = calcChecksum(*this);
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(ImmediatePacketF13F20) == sizeof(ImmediatePacketLoco));
|
||||
|
||||
struct ImmediatePacketF21F28 : ImmediatePacketLoco
|
||||
{
|
||||
ImmediatePacketF21F28(uint16_t address, bool f21, bool f22, bool f23, bool f24, bool f25, bool f26, bool f27, bool f28, uint8_t repeatCount = 2) :
|
||||
ImmediatePacketLoco(address, repeatCount)
|
||||
{
|
||||
uint8_t offset = (im[0] & 0x80) ? 2 : 1;
|
||||
|
||||
im[offset++] = 0xDF; // Feature Expansion Instruction: F20-F28 function control
|
||||
|
||||
if(f21)
|
||||
im[offset] |= 0x01;
|
||||
if(f22)
|
||||
im[offset] |= 0x02;
|
||||
if(f23)
|
||||
im[offset] |= 0x04;
|
||||
if(f24)
|
||||
im[offset] |= 0x08;
|
||||
if(f25)
|
||||
im[offset] |= 0x10;
|
||||
if(f26)
|
||||
im[offset] |= 0x20;
|
||||
if(f27)
|
||||
im[offset] |= 0x40;
|
||||
if(f28)
|
||||
im[offset] |= 0x80;
|
||||
|
||||
setIMCount(offset + 1);
|
||||
updateDHI();
|
||||
checksum = calcChecksum(*this);
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(ImmediatePacketF21F28) == sizeof(ImmediatePacketLoco));
|
||||
*/
|
||||
protected:
|
||||
class Slots
|
||||
{
|
||||
@ -835,6 +1108,13 @@ class LocoNet : public SubObject
|
||||
|
||||
std::shared_ptr<Hardware::Decoder> getDecoder(uint8_t slot, bool request = true);
|
||||
|
||||
void send(uint16_t address, Message& message, uint8_t& slot);
|
||||
template<typename T>
|
||||
inline void send(uint16_t address, T& message)
|
||||
{
|
||||
send(address, message, message.slot);
|
||||
}
|
||||
|
||||
public://protected:
|
||||
bool isInputAddressAvailable(uint16_t address);
|
||||
bool addInput(const std::shared_ptr<LocoNetInput>& input);
|
||||
@ -849,7 +1129,6 @@ class LocoNet : public SubObject
|
||||
LocoNet(Object& _parent, const std::string& parentPropertyName, std::function<bool(const Message&)> send);
|
||||
|
||||
bool send(const Message& message);
|
||||
void send(uint16_t address, SlotMessage& message);
|
||||
void receive(const Message& message);
|
||||
|
||||
void decoderChanged(const Hardware::Decoder& decoder, Hardware::DecoderChangeFlags changes, uint32_t functionNumber);
|
||||
@ -860,6 +1139,3 @@ class LocoNet : public SubObject
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,5 +1,45 @@
|
||||
# LocoNet
|
||||
|
||||
|
||||
## DR5000 - loconet 0 using Multimaus
|
||||
|
||||
2020-07-16 22:20:38.953136 [debug] cs_1.loconet: rx: A3 [A3 1F 01 42] -> F9
|
||||
2020-07-16 22:20:46.782380 [debug] cs_1.loconet: rx: A3 [A3 1F 00 43]
|
||||
2020-07-16 22:21:13.039958 [debug] cs_1.loconet: rx: A3 [A3 1F 02 41] -> F10
|
||||
2020-07-16 22:21:15.329510 [debug] cs_1.loconet: rx: A3 [A3 1F 00 43]
|
||||
2020-07-16 22:21:20.004596 [debug] cs_1.loconet: rx: A3 [A3 1F 04 47] -> F11
|
||||
2020-07-16 22:21:20.644998 [debug] cs_1.loconet: rx: A3 [A3 1F 00 43]
|
||||
2020-07-16 22:21:21.413525 [debug] cs_1.loconet: rx: A3 [A3 1F 08 4B] -> F12
|
||||
2020-07-16 22:21:21.893828 [debug] cs_1.loconet: rx: A3 [A3 1F 00 43]
|
||||
|
||||
|
||||
F13 ON:
|
||||
2020-07-16 22:49:50.937588 [debug] cs_1.loconet: rx: D4 [D4 20 1F 08 01 1D]
|
||||
2020-07-16 22:49:50.937756 [debug] cs_1.loconet: rx: D4 [D4 20 1F 05 00 11] // why??
|
||||
F13 OFF:
|
||||
2020-07-16 22:49:53.723441 [debug] cs_1.loconet: rx: D4 [D4 20 1F 08 00 1C]
|
||||
2020-07-16 22:49:53.723604 [debug] cs_1.loconet: rx: D4 [D4 20 1F 05 00 11]
|
||||
|
||||
F14 ON:
|
||||
2020-07-16 22:50:54.355985 [debug] cs_1.loconet: rx: D4 [D4 20 1F 08 02 1E]
|
||||
2020-07-16 22:50:54.356150 [debug] cs_1.loconet: rx: D4 [D4 20 1F 05 00 11]
|
||||
F14 OFF:
|
||||
2020-07-16 22:50:56.821657 [debug] cs_1.loconet: rx: D4 [D4 20 1F 08 00 1C]
|
||||
2020-07-16 22:50:56.821816 [debug] cs_1.loconet: rx: D4 [D4 20 1F 05 00 11]
|
||||
|
||||
F15 ON:
|
||||
2020-07-16 22:51:18.564022 [debug] cs_1.loconet: rx: D4 [D4 20 1F 08 04 18]
|
||||
2020-07-16 22:51:18.564195 [debug] cs_1.loconet: rx: D4 [D4 20 1F 05 00 11]
|
||||
F16 OFF:
|
||||
2020-07-16 22:51:20.933660 [debug] cs_1.loconet: rx: D4 [D4 20 1F 08 00 1C]
|
||||
2020-07-16 22:51:20.949613 [debug] cs_1.loconet: rx: D4 [D4 20 1F 05 00 11]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## DR5088RC - RailCom
|
||||
|
||||
OPC_MULTI_SENSE standard (dir=off):
|
||||
|
||||
Laden…
x
In neuem Issue referenzieren
Einen Benutzer sperren