Leosac  0.8.0
Open Source Access Control
PFDigitalPin.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014-2016 Leosac
3 
4  This file is part of Leosac.
5 
6  Leosac is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Affero General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Leosac is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Affero General Public License for more details.
15 
16  You should have received a copy of the GNU Affero General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "PFDigitalPin.hpp"
21 #include "pifacedigital.h"
22 #include "tools/log.hpp"
23 
24 PFDigitalPin::PFDigitalPin(zmqpp::context &ctx, const std::string &name, int gpio_no,
25  Direction direction, bool value, uint8_t hardware_address)
26  : gpio_no_(gpio_no)
27  , sock_(ctx, zmqpp::socket_type::rep)
28  , bus_push_(new zmqpp::socket(ctx, zmqpp::socket_type::push))
29  , name_(name)
30  , direction_(direction)
31  , default_value_(value)
32  , hardware_address_(hardware_address)
33  , want_update_(false)
34 {
35  DEBUG("trying to bind to " << ("inproc://" + name));
36  sock_.bind("inproc://" + name);
37  bus_push_->connect("inproc://zmq-bus-pull");
38 
39  if (direction == Direction::Out)
40  value ? turn_on() : turn_off();
41 }
42 
44 {
47  delete bus_push_;
48 }
49 
51  : sock_(std::move(o.sock_))
52  , direction_(o.direction_)
53  , default_value_(o.default_value_)
54 {
55  this->gpio_no_ = o.gpio_no_;
56  this->name_ = o.name_;
57  this->bus_push_ = o.bus_push_;
58  this->want_update_ = o.want_update_;
59  this->hardware_address_ = o.hardware_address_;
60 
61  o.bus_push_ = nullptr;
62 }
63 
65 {
66  zmqpp::message_t msg;
67  std::string frame1;
68  sock_.receive(msg);
69 
70  msg >> frame1;
71  bool ok = false;
72  if (frame1 == "ON")
73  ok = turn_on(&msg);
74  else if (frame1 == "OFF")
75  ok = turn_off();
76  else if (frame1 == "TOGGLE")
77  ok = toggle();
78  else if (frame1 == "STATE")
79  return send_state();
80  else // invalid cmd
81  ERROR("Invalid command received (" << frame1
82  << "). Potential missconfiguration !");
83  sock_.send(ok ? "OK" : "KO");
84 }
85 
86 bool PFDigitalPin::turn_on(zmqpp::message *msg /* = nullptr */)
87 {
89  return false;
90 
91  if (msg && msg->parts() > 1)
92  {
93  // optional parameter is present
94  int64_t duration;
95  *msg >> duration;
97  std::chrono::system_clock::now() + std::chrono::milliseconds(duration);
98  want_update_ = true;
99  }
100  pifacedigital_write_bit(1, gpio_no_, OUTPUT, hardware_address_);
101 
102  publish_state();
103  return true;
104 }
105 
107 {
108  if (direction_ != Direction::Out)
109  return false;
110  pifacedigital_write_bit(0, gpio_no_, OUTPUT, hardware_address_);
111 
112  publish_state();
113  return true;
114 }
115 
117 {
118  if (direction_ != Direction::Out)
119  return false;
120 
121  uint8_t v = pifacedigital_read_bit(gpio_no_, OUTPUT, hardware_address_);
122 
123  if (v)
124  pifacedigital_write_bit(0, gpio_no_, OUTPUT, hardware_address_);
125  else
126  pifacedigital_write_bit(1, gpio_no_, OUTPUT, hardware_address_);
127 
128  publish_state();
129  return true;
130 }
131 
133 {
134  // pin's direction matter here (not read from same register).
135  return pifacedigital_read_bit(
136  gpio_no_, direction_ == Direction::Out ? OUTPUT : INPUT, hardware_address_);
137 }
138 
140 {
141  DEBUG("UPDATING");
142  turn_off();
143  want_update_ = false;
144 }
145 
146 std::chrono::system_clock::time_point PFDigitalPin::next_update() const
147 {
148  if (want_update_)
149  return next_update_time_;
150  return std::chrono::system_clock::time_point::max();
151 }
152 
154 {
155  if (bus_push_)
156  bus_push_->send(zmqpp::message() << ("S_" + name_)
157  << (read_value() ? "ON" : "OFF"));
158 }
159 
161 {
162  sock_.send((read_value() ? "ON" : "OFF"));
163 }
PFDigitalPin::PFDigitalPin
PFDigitalPin(zmqpp::context &ctx, const std::string &name, int gpio_no, Direction direction, bool value, uint8_t hardware_address)
Create a new GPIO pin.
Definition: PFDigitalPin.cpp:24
PFDigitalPin::next_update
std::chrono::system_clock::time_point next_update() const
This method shall returns the time point at which we want to be updated.
Definition: PFDigitalPin.cpp:146
PFDigitalPin
This is a implementation class.
Definition: PFDigitalPin.hpp:33
PFDigitalPin::direction_
const Direction direction_
This is the direction of the GPIO pin.
Definition: PFDigitalPin.hpp:126
zmqpp
Definition: CoreUtils.hpp:27
PFDigitalPin::~PFDigitalPin
~PFDigitalPin()
Definition: PFDigitalPin.cpp:43
ERROR
@ ERROR
Definition: log.hpp:32
DEBUG
@ DEBUG
Definition: log.hpp:35
Leosac::Hardware::GPIO::Direction::Out
@ Out
PFDigitalPin::update
void update()
Let the GPIO pin perform internal task.
Definition: PFDigitalPin.cpp:139
PFDigitalPin::publish_state
void publish_state()
Definition: PFDigitalPin.cpp:153
PFDigitalPin::name_
std::string name_
Definition: PFDigitalPin.hpp:115
PFDigitalPin::hardware_address_
uint8_t hardware_address_
Definition: PFDigitalPin.hpp:139
PFDigitalPin::turn_on
bool turn_on(zmqpp::message *msg=nullptr)
Write to PFDigital to turn the gpio on.
Definition: PFDigitalPin.cpp:86
PFDigitalPin::toggle
bool toggle()
Definition: PFDigitalPin.cpp:116
PFDigitalPin::handle_message
void handle_message()
The PFGpioModule will register this method so its called when a message is ready on the pin socket.
Definition: PFDigitalPin.cpp:64
PFDigitalPin.hpp
PFDigitalPin::gpio_no_
uint8_t gpio_no_
Definition: PFDigitalPin.hpp:103
PFDigitalPin::bus_push_
zmqpp::socket * bus_push_
PUSH socket to write to the bus.
Definition: PFDigitalPin.hpp:113
PFDigitalPin::send_state
void send_state()
Send the current GPIO state on the socket.
Definition: PFDigitalPin.cpp:160
PFDigitalPin::read_value
bool read_value()
Ask the PiFace device for this pin's value and return it.
Definition: PFDigitalPin.cpp:132
Leosac::Hardware::GPIO::Direction
Direction
Definition: GPIO.hpp:44
PFDigitalPin::want_update_
bool want_update_
Does this object wants to be update()d ?
Definition: PFDigitalPin.hpp:144
PFDigitalPin::turn_off
bool turn_off()
Write to PFDigital turn the gpio off.
Definition: PFDigitalPin.cpp:106
log.hpp
PFDigitalPin::default_value_
bool default_value_
The default value of the pin, it is only relevant is the pin is output.
Definition: PFDigitalPin.hpp:132
PFDigitalPin::next_update_time_
std::chrono::system_clock::time_point next_update_time_
Time point of next wished update.
Definition: PFDigitalPin.hpp:137
PFDigitalPin::sock_
zmqpp::socket sock_
listen to command from other component.
Definition: PFDigitalPin.hpp:108