Sensor/Switch (sensor.{h,cpp}, switch.{h.cpp})#
class Sensor#
#pragma once
#include <filesystem>
class Sensor
{
public:
Sensor(const std::filesystem::path& celsius_temperature_file);
void turn_on() { _on = true; }
void turn_off() { _on = false; }
long get_temperature();
std::string path() const { return _celsius_temperature_file.string(); }
private:
std::filesystem::path _celsius_temperature_file;
bool _on;
};
#include "sensor.h"
#include <print>
#include <string>
#include <cassert>
#include <fcntl.h>
#include <unistd.h>
Sensor::Sensor(const std::filesystem::path& celsius_temperature_file)
: _celsius_temperature_file(celsius_temperature_file)
{}
long Sensor::get_temperature()
{
if (! _on) {
std::println("switching sensor on again -> BOOM!");
return 666'666'666'666;
}
int fd = open(_celsius_temperature_file.c_str(), O_RDONLY);
if (fd == -1) {
perror(std::format("open(\"{}\", O_RDONLY)", _celsius_temperature_file.string()).c_str());
assert(false);
}
char tmp[16] = {};
ssize_t nread = read(fd, tmp, sizeof(tmp)-1);
if (nread == -1) {
perror("read");
assert(false);
}
close(fd);
try {
return std::stoi(tmp);
}
catch (const std::exception& e) {
std::println(stderr, "content of file {} ({}) is not an integer", _celsius_temperature_file.string(), tmp);
assert(false);
}
}
class Switch#
#pragma once
#include <filesystem>
class Switch
{
public:
Switch(const std::filesystem::path& control_file);
void set_state(bool);
bool get_state() const;
std::string path() const { return _control_file.string(); }
private:
std::filesystem::path _control_file;
};
#include "switch.h"
#include <cassert>
#include <fcntl.h>
#include <unistd.h>
static bool read_state(const std::filesystem::path& control_file)
{
int fd = open(control_file.c_str(), O_RDONLY);
if (fd == -1) {
perror(std::format("open(\"{}\", O_RDONLY)", control_file.string()).c_str());
assert(false);
}
char c;
ssize_t nread = read(fd, &c, 1);
if (nread == -1) {
perror("read");
assert(false);
}
close(fd);
return (c == '1');
}
static void write_state(const std::filesystem::path& control_file, bool state)
{
int fd = open(control_file.c_str(), O_WRONLY|O_TRUNC);
if (fd == -1) {
perror(std::format("open(\"{}\", O_WRONLY|O_TRUNC)", control_file.string()).c_str());
assert(false);
}
static const char on = '1';
static const char off = '0';
ssize_t nwritten = write(fd, state?&on:&off, 1);
if (nwritten == -1) {
perror("write");
assert(false);
}
}
Switch::Switch(const std::filesystem::path& control_file)
: _control_file(control_file)
{
write_state(_control_file, false); // Initialize to OFF
}
void Switch::set_state(bool state)
{
if (state != get_state())
write_state(_control_file, state);
}
bool Switch::get_state() const
{
return read_state(_control_file);
}