1
0
mirror of https://github.com/binary-kitchen/doorlockd synced 2024-07-05 13:07:46 +02:00
doorlockd-mirror/doorlockd/door.cpp

136 lines
3.1 KiB
C++
Raw Normal View History

2015-05-11 00:18:22 +02:00
#include <iostream>
2015-05-11 00:18:22 +02:00
#include <wiringPi.h>
#include <unistd.h>
2015-05-11 00:18:22 +02:00
2015-05-25 15:47:44 +02:00
#include "config.h"
2015-05-11 00:18:22 +02:00
#include "logger.h"
#include "door.h"
using namespace std;
Door::Door() :
_l(Logger::get())
2015-05-11 00:18:22 +02:00
{
_l(LogLevel::info, "Initializing Raspberry Pi GPIOs");
wiringPiSetup();
2015-05-21 13:35:30 +02:00
pinMode(_HEARTBEATPIN, OUTPUT);
pinMode(_SCHNAPPERPIN, OUTPUT);
pinMode(_LOCKPIN, INPUT);
pullUpDnControl(_LOCKPIN, PUD_UP);
2015-05-11 00:18:22 +02:00
lock();
}
Door::~Door()
{
lock();
2015-05-11 00:18:22 +02:00
}
Door &Door::get()
{
static Door d;
return d;
}
Door::State Door::state() const
{
return _state;
}
2015-05-11 00:18:22 +02:00
void Door::lock()
{
std::lock_guard<std::mutex> l(_mutex);
2015-05-25 15:47:44 +02:00
_l(LogLevel::notice, "Executing Pre Lock Script");
system(PRE_LOCK_SCRIPT);
2015-05-21 13:35:30 +02:00
digitalWrite(_SCHNAPPERPIN, HIGH);
2015-05-11 00:18:22 +02:00
_l(LogLevel::info, "Door closed");
2015-05-21 13:35:30 +02:00
if (_state == State::Unlocked)
{
2015-05-21 13:35:30 +02:00
// Stop the Heartbeat Thread
_state = State::Locked;
_heartbeat.join();
}
2015-05-18 22:22:08 +02:00
2015-05-25 15:47:44 +02:00
_l(LogLevel::notice, "Executing Post Lock Script");
system(POST_LOCK_SCRIPT);
2015-05-11 00:18:22 +02:00
}
void Door::unlock()
{
2015-05-25 15:47:44 +02:00
_l(LogLevel::notice, "Executing Pre Unlock Script");
system(PRE_UNLOCK_SCRIPT);
2015-05-21 13:35:30 +02:00
// In any case, klacker the schnapper
_schnapper = true;
2015-05-21 13:35:30 +02:00
// If heartbeat is already running, return
if (_state == State::Unlocked)
{
return;
}
2015-05-21 13:35:30 +02:00
// If not, first set state to unlocked
_state = State::Unlocked;
// Start the Heartbeat Thread
_heartbeat = std::thread([this] () {
2015-05-21 13:35:30 +02:00
// One "beat" is one complete cycle of the heartbeat clock
auto beat = [this] () {
2015-05-21 13:35:30 +02:00
digitalWrite(_HEARTBEATPIN, HIGH);
usleep(10000);
2015-05-21 13:35:30 +02:00
digitalWrite(_HEARTBEATPIN, LOW);
usleep(10000);
};
2015-05-20 22:42:20 +02:00
2015-05-21 13:35:30 +02:00
// The default of the Schnapperpin: always high
digitalWrite(_SCHNAPPERPIN, HIGH);
// Heartbeat while the state is unlocked
while (_state == State::Unlocked) {
// In case of schnapper, send 0x55 resp. 0xaa to the schnapperpin
if (_schnapper == true)
{
2015-05-20 22:42:20 +02:00
for (int i = 0; i < 32 ; i++)
{
2015-05-21 13:35:30 +02:00
// Set '0'
digitalWrite(_SCHNAPPERPIN, LOW);
// cycle and send
2015-05-20 22:42:20 +02:00
beat();
2015-05-21 13:35:30 +02:00
// Set '1'
digitalWrite(_SCHNAPPERPIN, HIGH);
// cycle and send
2015-05-20 22:42:20 +02:00
beat();
}
2015-05-21 13:35:30 +02:00
// Reset schnapperpin
digitalWrite(_SCHNAPPERPIN, HIGH);
// and deactivate schnapper for the next round
_schnapper = false;
}
2015-05-21 13:35:30 +02:00
// Heartbeat
beat();
if (!digitalRead(_LOCKPIN)) {
std::thread([this] () {
_l(LogLevel::info, "Incoming door close request on button press");
lock();
}).detach();
// Busy wait till door is locked
while(_state == State::Unlocked);
}
}
});
2015-05-11 00:18:22 +02:00
_l(LogLevel::info, "Door opened");
2015-05-25 15:47:44 +02:00
_l(LogLevel::notice, "Executing Post Unlock Script");
system(POST_UNLOCK_SCRIPT);
2015-05-11 00:18:22 +02:00
}