• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

traintastic / traintastic / 23088148108

14 Mar 2026 12:40PM UTC coverage: 26.661% (-0.2%) from 26.84%
23088148108

push

github

reinder
[cbus] added input support for short/long events

0 of 133 new or added lines in 4 files covered. (0.0%)

587 existing lines in 20 files now uncovered.

8246 of 30929 relevant lines covered (26.66%)

185.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/server/src/hardware/protocol/cbus/simulator/cbussimulator.cpp
1
/**
2
 * This file is part of Traintastic,
3
 * see <https://github.com/traintastic/traintastic>.
4
 *
5
 * Copyright (C) 2026 Reinder Feenstra
6
 *
7
 * This program is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU General Public License
9
 * as published by the Free Software Foundation; either version 2
10
 * of the License, or (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20
 */
21

22
#include "cbussimulator.hpp"
23
#include <algorithm>
24
#include "../messages/cbusaccessorymessages.hpp"
25
#include "../messages/cbusaccessoryshortmessages.hpp"
26

27
namespace {
28

29
static constexpr uint8_t simCanId = 84;
30
static constexpr uint16_t simNodeNumber = 0x84B7;
31

32
}
33

34
namespace CBUS
35
{
36

37
Simulator::Simulator()
×
38
{
39
}
×
40

41
bool Simulator::addModule(std::unique_ptr<Module::CANModule> module)
×
42
{
43
  if(!module || std::find_if(m_modules.begin(), m_modules.end(),
×
44
    [nodeNumber=module->nodeNumber, canId=module->canId](const auto& m)
×
45
    {
46
      return (m->nodeNumber == nodeNumber) || (m->canId == canId);
×
47
    }) != m_modules.end())
×
48
  {
49
    return false;
×
50
  }
51
  m_modules.emplace_back(std::move(module));
×
52
  return true;
×
53
}
54

55
void Simulator::receive(const Message& message)
×
56
{
57
  for(const auto& module : m_modules)
×
58
  {
59
    module->receive(message);
×
60
  }
61
}
×
62

NEW
63
void Simulator::shortEvent(uint16_t eventNumber, SimulateInputAction action)
×
64
{
65
  bool value;
NEW
66
  switch(action)
×
67
  {
NEW
68
    case SimulateInputAction::SetTrue:
×
NEW
69
      value = true;
×
NEW
70
      break;
×
71

NEW
72
    case SimulateInputAction::SetFalse:
×
NEW
73
      value = false;
×
NEW
74
      break;
×
75

NEW
76
    case SimulateInputAction::Toggle:
×
NEW
77
      if(auto it = m_shortEvents.find(eventNumber); it != m_shortEvents.end())
×
78
      {
NEW
79
        value = !it->second;
×
80
      }
81
      else
82
      {
NEW
83
        value = true;
×
84
      }
NEW
85
      break;
×
86
  }
87

NEW
88
  if(value)
×
89
  {
NEW
90
    send(simCanId, AccessoryShortOn(simNodeNumber, eventNumber));
×
91
  }
92
  else
93
  {
NEW
94
    send(simCanId, AccessoryShortOff(simNodeNumber, eventNumber));
×
95
  }
NEW
96
}
×
97

NEW
98
void Simulator::longEvent(uint16_t nodeNumber, uint16_t eventNumber, SimulateInputAction action)
×
99
{
NEW
100
  uint8_t canId = simCanId;
×
NEW
101
  if(auto it = std::find_if(m_modules.begin(), m_modules.end(),
×
NEW
102
    [nodeNumber](const auto& module)
×
103
    {
NEW
104
      return module->nodeNumber == nodeNumber;
×
NEW
105
    }); it != m_modules.end())
×
106
  {
NEW
107
    canId = (**it).canId;
×
108
  }
109

110
  bool value;
NEW
111
  switch(action)
×
112
  {
NEW
113
    case SimulateInputAction::SetTrue:
×
NEW
114
      value = true;
×
NEW
115
      break;
×
116

NEW
117
    case SimulateInputAction::SetFalse:
×
NEW
118
      value = false;
×
NEW
119
      break;
×
120

NEW
121
    case SimulateInputAction::Toggle:
×
NEW
122
      if(auto it = m_longEvents.find({nodeNumber, eventNumber}); it != m_longEvents.end())
×
123
      {
NEW
124
        value = !it->second;
×
125
      }
126
      else
127
      {
NEW
128
        value = true;
×
129
      }
NEW
130
      break;
×
131
  }
132

NEW
133
  if(value)
×
134
  {
NEW
135
    send(canId, AccessoryOn(nodeNumber, eventNumber));
×
136
  }
137
  else
138
  {
NEW
139
    send(canId, AccessoryOff(nodeNumber, eventNumber));
×
140
  }
NEW
141
}
×
142

NEW
143
void Simulator::send(uint8_t canId, const Message& message)
×
144
{
NEW
145
  switch(message.opCode)
×
146
  {
147
    using enum OpCode;
148

NEW
149
    case ASON:
×
150
    {
NEW
151
      const auto& ason = static_cast<const AccessoryShortOn&>(message);
×
NEW
152
      m_shortEvents[ason.deviceNumber()] = true;
×
NEW
153
      break;
×
154
    }
NEW
155
    case ASOF:
×
156
    {
NEW
157
      const auto& asof = static_cast<const AccessoryShortOff&>(message);
×
NEW
158
      m_shortEvents[asof.deviceNumber()] = false;
×
NEW
159
      break;
×
160
    }
NEW
161
    case ACON:
×
162
    {
NEW
163
      const auto& acon = static_cast<const AccessoryOn&>(message);
×
NEW
164
      m_longEvents[{acon.nodeNumber(), acon.eventNumber()}] = true;
×
NEW
165
      break;
×
166
    }
NEW
167
    case ACOF:
×
168
    {
NEW
169
      const auto& acof = static_cast<const AccessoryOff&>(message);
×
NEW
170
      m_longEvents[{acof.nodeNumber(), acof.eventNumber()}] = false;
×
NEW
171
      break;
×
172
    }
NEW
173
    default:
×
NEW
174
      break;
×
175
  }
NEW
176
  onSend(canId, message);
×
NEW
177
}
×
178

179
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc