-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SNS - Accelerometer REPL Commands (#98)
Co-authored-by: H-Allen <harveyjallen1@gmail.com> Co-authored-by: Tom Lonergan <tomlonergan91@gmail.com> Co-authored-by: David Beechey <david@dtbeechey.dev>
- Loading branch information
1 parent
4f0f768
commit 2e2ba1b
Showing
9 changed files
with
251 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
#include "accelerometer_commands.hpp" | ||
|
||
#include <cstdint> | ||
|
||
#include "sensors/i2c_mux.hpp" | ||
|
||
namespace hyped::debug { | ||
core::Result AccelerometerCommands::addCommands(core::ILogger &logger, | ||
const std::shared_ptr<Repl> &repl, | ||
toml::v3::node_view<toml::v3::node> config) | ||
{ | ||
// get bus | ||
const auto optional_bus = config["bus"].value<std::uint8_t>(); | ||
if (!optional_bus) { | ||
logger.log(core::LogLevel::kFatal, "No I2C bus specified"); | ||
return core::Result::kFailure; | ||
}; | ||
const auto bus = *optional_bus; | ||
|
||
// get I2C instance | ||
auto optional_i2c = repl->getI2c(bus); | ||
if (!optional_i2c) { | ||
logger.log(core::LogLevel::kFatal, "Error creating I2C bus"); | ||
return core::Result::kFailure; | ||
}; | ||
const auto i2c = std::move(*optional_i2c); | ||
|
||
const auto optional_mux_channel = config["mux_channel"].value<std::uint8_t>(); | ||
if (!optional_mux_channel) { | ||
logger.log(core::LogLevel::kFatal, "No mux channel specified"); | ||
return core::Result::kFailure; | ||
} | ||
const auto mux_channel = *optional_mux_channel; | ||
|
||
auto optional_i2c_mux | ||
= sensors::I2cMux::create(logger, i2c, sensors::kDefaultMuxAddress, mux_channel); | ||
if (!optional_i2c_mux) { | ||
logger.log(core::LogLevel::kFatal, "Failed to create I2C mux"); | ||
return core::Result::kFailure; | ||
} | ||
const auto i2c_mux = std::move(*optional_i2c_mux); | ||
|
||
// get address | ||
const auto optional_address = config["address"].value<std::uint8_t>(); | ||
if (!optional_address) { | ||
logger.log(core::LogLevel::kFatal, "Invalid address"); | ||
return core::Result::kFailure; | ||
} | ||
const auto address = *optional_address; | ||
|
||
// create sensor | ||
const auto optional_accelerometer_sensor = sensors::Accelerometer::create( | ||
logger, i2c_mux, static_cast<sensors::accelerometerAddress>(address)); | ||
if (!optional_accelerometer_sensor) { | ||
logger.log(core::LogLevel::kFatal, "Failed to create accelerometer sensor"); | ||
return core::Result::kFailure; | ||
} | ||
const auto &accelerometer_sensor = *optional_accelerometer_sensor; | ||
const auto *const read_command_name = "accelerometer read"; | ||
const auto *const read_command_description = "Read from the accelerometer"; | ||
const auto *const read_command_usage = "accelerometer read"; | ||
const auto read_command_handler | ||
= [&logger, accelerometer_sensor](const std::vector<std::string> &) { | ||
const auto value_ready = accelerometer_sensor->isValueReady(); | ||
if (!value_ready) { | ||
logger.log(core::LogLevel::kFatal, "Value is not ready"); | ||
return; | ||
} | ||
const auto acceleration = accelerometer_sensor->read(); | ||
if (!acceleration) { | ||
logger.log(core::LogLevel::kFatal, "Failed to read acceleration"); | ||
return; | ||
} | ||
logger.log(core::LogLevel::kDebug, "Acceleration: %s m/s", acceleration); | ||
}; | ||
auto read_command = std::make_unique<Command>( | ||
read_command_name, read_command_description, read_command_usage, read_command_handler); | ||
repl->addCommand(std::move(read_command)); | ||
return core::Result::kSuccess; | ||
} | ||
|
||
} // namespace hyped::debug |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#pragma once | ||
|
||
#include <memory> | ||
|
||
#include <core/logger.hpp> | ||
#include <core/types.hpp> | ||
#include <debug/repl.hpp> | ||
#include <sensors/accelerometer.hpp> | ||
|
||
namespace hyped::debug { | ||
|
||
class AccelerometerCommands { | ||
public: | ||
static core::Result addCommands(core::ILogger &logger, | ||
const std::shared_ptr<Repl> &repl, | ||
toml::v3::node_view<toml::v3::node> config); | ||
}; | ||
|
||
} // namespace hyped::debug |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
#include "accelerometer.hpp" | ||
#include "accelerometer_node.hpp" | ||
|
||
#include <utility> | ||
|
||
#include "core/logger.hpp" | ||
#include "core/mqtt.hpp" | ||
#include "core/wall_clock.hpp" | ||
#include "io/hardware_i2c.hpp" | ||
|
||
namespace hyped::sensors { | ||
|
||
core::Result AccelerometerNode::startNode(toml::v3::node_view<const toml::v3::node> config, | ||
const std::string &mqtt_ip, | ||
const std::uint32_t mqtt_port) | ||
{ | ||
auto time = core::WallClock(); | ||
auto logger = core::Logger("Accelerometer", core::LogLevel::kDebug, time); | ||
auto optional_mqtt = core::Mqtt::create(logger, "Accelerometer", mqtt_ip, mqtt_port); | ||
if (!optional_mqtt) { | ||
logger.log(core::LogLevel::kFatal, "Failed to create MQTT client"); | ||
return core::Result::kFailure; | ||
} | ||
auto mqtt = *optional_mqtt; | ||
auto optional_i2c = io::HardwareI2c::create(logger, 2); | ||
if (!optional_i2c) { | ||
logger.log(core::LogLevel::kFatal, "Failed to create I2C bus"); | ||
return core::Result::kFailure; | ||
} | ||
auto i2c = *optional_i2c; | ||
auto optional_accelerometer = Accelerometer::create(logger, i2c, accelerometerAddress::k1D); | ||
if (!optional_accelerometer) { | ||
logger.log(core::LogLevel::kFatal, "Failed to create accelerometer"); | ||
return core::Result::kFailure; | ||
} | ||
auto accelerometer = *optional_accelerometer; | ||
auto node = AccelerometerNode(logger, time, mqtt, accelerometer); | ||
node.run(); | ||
return core::Result::kSuccess; | ||
} | ||
|
||
AccelerometerNode::AccelerometerNode(core::Logger &logger, | ||
core::ITimeSource &time, | ||
std::shared_ptr<core::Mqtt> mqtt, | ||
std::shared_ptr<Accelerometer> accelerometer) | ||
: logger_(logger), | ||
time_(time), | ||
mqtt_(std::move(mqtt)), | ||
accelerometer_(std::move(accelerometer)) | ||
{ | ||
} | ||
|
||
void AccelerometerNode::run() | ||
{ | ||
while (true) { | ||
auto result = accelerometer_->isValueReady(); | ||
if (!result) { continue; } | ||
if (*result == core::Result::kFailure) { continue; } | ||
auto optional_acceration = accelerometer_->read(); | ||
if (!optional_acceration) { | ||
logger_.log(core::LogLevel::kWarn, "Failed to read accelerometer data"); | ||
continue; | ||
} | ||
const auto acceleration = *optional_acceration; | ||
const auto topic = core::MqttTopic::kAccelerometer; | ||
auto message_payload = std::make_shared<rapidjson::Document>(); | ||
message_payload->SetObject(); | ||
rapidjson::Value acceleration_x(acceleration.x); | ||
rapidjson::Value acceleration_y(acceleration.y); | ||
rapidjson::Value acceleration_z(acceleration.z); | ||
message_payload->AddMember("x", acceleration_x, message_payload->GetAllocator()); | ||
message_payload->AddMember("y", acceleration_y, message_payload->GetAllocator()); | ||
message_payload->AddMember("z", acceleration_z, message_payload->GetAllocator()); | ||
const core::MqttMessage::Header header{ | ||
.timestamp = static_cast<std::uint64_t>(time_.now().time_since_epoch().count()), | ||
.priority = core::MqttMessagePriority::kNormal}; | ||
const core::MqttMessage message{topic, header, message_payload}; | ||
mqtt_->publish(message, core::MqttMessageQos::kExactlyOnce); | ||
} | ||
} | ||
|
||
} // namespace hyped::sensors |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#pragma once | ||
|
||
#include "accelerometer.hpp" | ||
|
||
#include "core/mqtt.hpp" | ||
#include "core/types.hpp" | ||
#include <toml++/toml.hpp> | ||
|
||
namespace hyped::sensors { | ||
|
||
class AccelerometerNode { | ||
public: | ||
static core::Result startNode(toml::v3::node_view<const toml::v3::node> config, | ||
const std::string &mqtt_ip, | ||
const std::uint32_t mqtt_port); | ||
AccelerometerNode(core::Logger &logger, | ||
core::ITimeSource &time, | ||
std::shared_ptr<core::Mqtt> mqtt, | ||
std::shared_ptr<Accelerometer> accelerometer); | ||
void run(); | ||
|
||
private: | ||
core::Logger logger_; | ||
core::ITimeSource &time_; | ||
std::shared_ptr<core::Mqtt> mqtt_; | ||
std::shared_ptr<Accelerometer> accelerometer_; | ||
}; | ||
|
||
} // namespace hyped::sensors |