NDEVR
API Documentation
DeviCounterSimulator.h
1/*--------------------------------------------------------------------------------------------
2Copyright (c) 2023, NDEVR LLC
3tyler.parke@ndevr.org
4 __ __ ____ _____ __ __ _______
5 | \ | | | __ \ | ___|\ \ / / | __ \
6 | \ | | | | \ \ | |___ \ \ / / | |__) |
7 | . \| | | |__/ / | |___ \ V / | _ /
8 | |\ |_|_____/__|_____|___\_/____| | \ \
9 |__| \__________________________________| \__\
10
11Subject to the terms of the Enterprise+ Agreement, NDEVR hereby grants
12Licensee a limited, non-exclusive, non-transferable, royalty-free license
13(without the right to sublicense) to use the API solely for the purpose of
14Licensee's internal development efforts to develop applications for which
15the API was provided.
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
21INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
22PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
23FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25DEALINGS IN THE SOFTWARE.
26
27Library: DeviCounter
28File: DLLInfo
29Included in API: True
30Author(s): Tyler Parke
31 *-----------------------------------------------------------------------------------------**/
32#pragma once
33#include "DeviCounterConnection.h"
34#include <NDEVR/Connection.h>
35#include <NDEVR/Random.h>
36#include <NDEVR/Thread.h>
37namespace NDEVR
38{
42 class DeviCounterSimulatorIO : public ConnectionBackend
43 {
44 public:
45 DeviCounterSimulatorIO()
46 : ConnectionBackend(nullptr)
47 , next_send_time(Time::SystemTime())
48 {
49 simulateDeploymentStart();
50 simulateRandomEvent();
51 }
52 uint04 peek(char* s, uint04 size = Constant<uint04>::Max) const final override
53 {
54 simulateRandomEvent();
55 if (Time::SystemTime() <= next_send_time)
56 return 0U;
57 uint04 final_size = getMin(size, m_next_send.size());
58 memcpy(s, m_next_send.c_str(), final_size);
59 return final_size;
60 }
61 uint04 rx(char* s, uint04 size = Constant<uint04>::Max) final override
62 {
63 if (Time::SystemTime() <= next_send_time)
64 return 0U;
65 next_send_time += TimeSpan(1.0);
66 simulateRandomEvent();
67 uint04 final_size = getMin(size, m_next_send.size());
68 memcpy(s, m_next_send.c_str(), final_size);
69 if (final_size >= m_next_send.size())
70 m_next_send.clear();
71 else
72 m_next_send.removeAllIndex(0, size);
73 return final_size;
74 }
75 void tx(const StringView&) final override
76 {
77 simulateRandomEvent();
78 };
79
80 bool open(const ConnectionInfo&) final override
81 {
82 if (m_is_open)
83 return true;
84 simulateRandomEvent();
85 m_is_open = MakeRandom(10.0) > 0.1;
86 return m_is_open;
87 }
88 void close() final override
89 {
90 m_is_open = false;
91 simulateRandomEvent();
92 m_next_send.clear();
93 }
94 bool isOpen() const final override
95 {
96 return m_is_open;
97 }
98 bool waitForReadyRead(const TimeSpan& span) final override
99 {
100 if (Time::SystemTime() >= next_send_time)
101 return true;
102 ThreadFunctions::RequestSleep(getMin(span, Time::SystemTime() - next_send_time));
103 if (Time::SystemTime() >= next_send_time)
104 return true;
105 return false;
106 }
107
108 void simulateDeploymentStart()
109 {
110 m_speed = MakeRandom(0.02, 0.05);
111 }
112 void simulateRandomEvent() const
113 {
114 m_battery_voltage -= MakeRandom(0.0, 0.01);
115 m_temperature += MakeRandom(-0.01, 0.01);
116 if(m_speed > 0.0)
117 m_speed += MakeRandom(-0.001, 0.001);
118 m_distance += m_speed * (Time::SystemTime() - m_last_speed_time).elapsedSeconds();
119 if (Time::SystemTime() - m_last_speed_time > TimeSpan(1.0))
120 {
121 m_last_speed_time = Time::SystemTime();
122 m_next_send += "$"
123 + String(m_distance) + ";"
124 + String(m_speed) + ";"
125 + String(m_battery_voltage) + ";999;0;0*12";
126 }
127
128 }
129
130 TranslatedString lastError() const final override
131 {
132 return TranslatedString();
133 }
134 uint04 bytesAvailable() const final override
135 {
136 if (Time::SystemTime() >= next_send_time)
137 return m_next_send.size();
138 return 0U;
139 }
140 uint08 elapsedTime() const
141 {
142 return (Time::SystemTime() - m_start_time).elapsedMilliseconds();
143 }
144 mutable Time m_start_time;
145 mutable Time m_last_speed_time;
146 mutable String m_error = String("0000");
147 mutable fltp08 m_battery_voltage = 0.0;
148 mutable fltp08 m_distance = 0.0;
149 mutable fltp08 m_temperature = 0.0;
150 mutable fltp08 m_speed = 0.0;
151 mutable String m_next_send;
152 mutable Time next_send_time = Constant<Time>::Invalid;
153 bool m_is_open = false;
154 };
155}
ConnectionBackend(LogPtr log)
Constructs a ConnectionBackend with the given log.
uint04 bytesAvailable() const final override
Returns the number of bytes available to read.
void tx(const StringView &) final override
Transmits a string command over the connection.
uint04 rx(char *s, uint04 size=Constant< uint04 >::Max) final override
Reads and consumes data from the receive buffer.
TranslatedString lastError() const final override
Returns the last error message from this backend.
bool waitForReadyRead(const TimeSpan &span) final override
Blocks until data is available to read or the timeout expires.
void close() final override
Closes the connection.
uint04 peek(char *s, uint04 size=Constant< uint04 >::Max) const final override
Reads data from the receive buffer without consuming it.
bool open(const ConnectionInfo &) final override
Opens the connection using the provided connection info.
bool isOpen() const final override
Checks whether the connection is currently open.
The core String View class for the NDEVR API.
Definition StringView.h:58
static void RequestSleep(const TimeSpan &interval)
Puts the current thread to sleep for a specified duration.
Stores a time span, or difference between two times, with an optional start time.
Definition TimeSpan.h:46
static Time SystemTime()
Retrieves the current system time which is a combination of std::chrono::steady_clock to ensure smoot...
Any text displayed to the user should be defined as a TranslatedString which allows the program to lo...
The primary namespace for the NDEVR SDK.
constexpr t_type getMin(const t_type &left, const t_type &right)
Finds the minimum of the given arguments based on the < operator Author: Tyler Parke Date: 2017-11-05...
t_type MakeRandom(t_type max)
Returns a pseudo-random number between 0 and the associated max value.
Definition Random.h:55
uint64_t uint08
-Defines an alias representing an 8 byte, unsigned integer
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
double fltp08
Defines an alias representing an 8 byte floating-point number.
A structure designed to store information about a specific Connection.
Definition Connection.h:90