mirror of
https://github.com/brmlab/brmdoor_libnfc.git
synced 2025-08-02 18:33:37 +02:00
Added topic chaning for switch open/close
This commit is contained in:
parent
388d8a80b0
commit
ef1d8b8080
2 changed files with 83 additions and 18 deletions
|
@ -42,10 +42,13 @@ channels = #test-bjornbot
|
||||||
tls = True
|
tls = True
|
||||||
reconnect_delay = 300
|
reconnect_delay = 300
|
||||||
|
|
||||||
[open-switch]
|
[open_switch]
|
||||||
# Controls showing status of "OPEN/CLOSE" switch that is connected to some GPIO pin
|
# Controls showing status of "OPEN/CLOSE" switch that is connected to some GPIO pin
|
||||||
# Changes topic of connected IRC channels if IRC is enabled
|
# Changes topic of connected IRC channels if IRC is enabled
|
||||||
|
# There is no point in enabling this if you disabled IRC
|
||||||
# enabled - True/False
|
# enabled - True/False
|
||||||
# status_file - file in sysfs that contains 1 or 0 defining the state of button
|
# status_file - file in sysfs that contains 1 or 0 defining the state of button
|
||||||
|
# open_value - which value in status_file respresents the switch being in "OPEN" position, 1 character
|
||||||
enabled = True
|
enabled = True
|
||||||
status_file = /sys/class/gpio/gpio11/value
|
status_file = /sys/class/gpio/gpio11/value
|
||||||
|
open_value = 1
|
||||||
|
|
|
@ -8,6 +8,7 @@ import threading
|
||||||
import irc.client
|
import irc.client
|
||||||
import ssl
|
import ssl
|
||||||
import Queue
|
import Queue
|
||||||
|
import re
|
||||||
|
|
||||||
from binascii import hexlify
|
from binascii import hexlify
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
@ -57,11 +58,15 @@ class BrmdoorConfig(object):
|
||||||
self.ircNick = self.config.get("irc", "nick")
|
self.ircNick = self.config.get("irc", "nick")
|
||||||
self.ircPassword = self.config.get("irc", "password") if self.config.has_option("irc", "password") else None
|
self.ircPassword = self.config.get("irc", "password") if self.config.has_option("irc", "password") else None
|
||||||
self.ircChannels = self.config.get("irc", "channels").split(" ")
|
self.ircChannels = self.config.get("irc", "channels").split(" ")
|
||||||
|
if len(self.ircChannels) < 1:
|
||||||
|
print >> sys.stderr, "You must specify at least one channel for IRC when IRC is enabled"
|
||||||
|
sys.exit(1)
|
||||||
self.ircUseTLS = self.config.getboolean("irc", "tls")
|
self.ircUseTLS = self.config.getboolean("irc", "tls")
|
||||||
self.ircReconnectDelay = self.config.getint("irc", "reconnect_delay")
|
self.ircReconnectDelay = self.config.getint("irc", "reconnect_delay")
|
||||||
self.useOpenSwitch = self.config.getboolean("open-switch", "enabled")
|
self.useOpenSwitch = self.config.getboolean("open_switch", "enabled")
|
||||||
if self.useOpenSwitch:
|
if self.useOpenSwitch:
|
||||||
self.switchStatusFile = self.config.get("open-switch", "status_file")
|
self.switchStatusFile = self.config.get("open_switch", "status_file")
|
||||||
|
self.switchOpenValue = self.config.get("open_switch", "open_value")
|
||||||
|
|
||||||
def convertLoglevel(self, levelString):
|
def convertLoglevel(self, levelString):
|
||||||
"""Converts string 'debug', 'info', etc. into corresponding
|
"""Converts string 'debug', 'info', etc. into corresponding
|
||||||
|
@ -197,6 +202,7 @@ class IrcThread(threading.Thread):
|
||||||
self.reactor = None
|
self.reactor = None
|
||||||
self.connected = False
|
self.connected = False
|
||||||
self.threadLock = threading.Lock()
|
self.threadLock = threading.Lock()
|
||||||
|
self.connection = None
|
||||||
|
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
|
|
||||||
|
@ -230,6 +236,14 @@ class IrcThread(threading.Thread):
|
||||||
logging.error("Could not connect to IRC server: %s", e)
|
logging.error("Could not connect to IRC server: %s", e)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def getTopic(self, channel):
|
||||||
|
with self.threadLock:
|
||||||
|
return self.connection.topic(channel)
|
||||||
|
|
||||||
|
def setTopic(self, channel, newTopic):
|
||||||
|
with self.threadLock:
|
||||||
|
return self.connection.topic(channel, newTopic)
|
||||||
|
|
||||||
def onConnect(self, connection, event):
|
def onConnect(self, connection, event):
|
||||||
for channel in self.channels:
|
for channel in self.channels:
|
||||||
connection.join(channel)
|
connection.join(channel)
|
||||||
|
@ -240,24 +254,32 @@ class IrcThread(threading.Thread):
|
||||||
time.sleep(self.reconnectDelay)
|
time.sleep(self.reconnectDelay)
|
||||||
self.setConnected(self.connect())
|
self.setConnected(self.connect())
|
||||||
|
|
||||||
|
def onJoin(self, connection, event):
|
||||||
|
logging.info("Joined channel, event: %s", event)
|
||||||
|
connection.privmsg(self.channels[0], "brmbot-libfc starting")
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
logging.debug("Starting IRC thread")
|
logging.debug("Starting IRC thread")
|
||||||
while True:
|
while True:
|
||||||
connected = self.connect()
|
try:
|
||||||
logging.info("IRC connected: %s", connected)
|
connected = self.connect()
|
||||||
self.setConnected(connected)
|
logging.info("IRC connected: %s", connected)
|
||||||
self.connection.add_global_handler("welcome", partial(IrcThread.onConnect, self))
|
self.setConnected(connected)
|
||||||
self.connection.add_global_handler("disconnect", partial(IrcThread.onDisconnect, self))
|
self.connection.add_global_handler("welcome", partial(IrcThread.onConnect, self))
|
||||||
|
self.connection.add_global_handler("disconnect", partial(IrcThread.onDisconnect, self))
|
||||||
|
self.connection.add_global_handler("join", partial(IrcThread.onJoin, self))
|
||||||
|
|
||||||
while self.getConnected():
|
while self.getConnected():
|
||||||
self.reactor.process_once(timeout=5)
|
self.reactor.process_once(timeout=5)
|
||||||
try:
|
try:
|
||||||
msg = self.msgQueue.get_nowait()
|
with self.threadLock:
|
||||||
self.connection.privmsg_many(self.channels, msg)
|
msg = self.msgQueue.get_nowait()
|
||||||
except Queue.Empty:
|
self.connection.privmsg_many(self.channels, msg)
|
||||||
pass
|
except Queue.Empty:
|
||||||
else:
|
pass
|
||||||
time.sleep(self.reconnectDelay)
|
except Exception:
|
||||||
|
logging.exception("Exception in IRC thread")
|
||||||
|
time.sleep(self.reconnectDelay)
|
||||||
|
|
||||||
class OpenSwitchThread(threading.Thread):
|
class OpenSwitchThread(threading.Thread):
|
||||||
"""
|
"""
|
||||||
|
@ -270,12 +292,46 @@ class OpenSwitchThread(threading.Thread):
|
||||||
:param config - BrmdoorConfig object
|
:param config - BrmdoorConfig object
|
||||||
:param ircThread: IrcThread through which we can set and receive current topics
|
:param ircThread: IrcThread through which we can set and receive current topics
|
||||||
"""
|
"""
|
||||||
self.statusFile = config.statusFile
|
self.statusFile = config.switchStatusFile
|
||||||
|
self.openValue = config.switchOpenValue
|
||||||
|
self.ircThread = ircThread
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
logging.info("Switch thread start")
|
||||||
|
if self.ircThread is None: #no point in running this thread if we can't report it anywhere
|
||||||
|
return
|
||||||
|
|
||||||
|
lastStatus = None #Some random value so that first time it will be registered as change
|
||||||
while True:
|
while True:
|
||||||
|
try:
|
||||||
|
switchFile = open(self.statusFile)
|
||||||
|
status = switchFile.read(1)
|
||||||
|
switchFile.close()
|
||||||
|
if status != lastStatus:
|
||||||
|
logging.info("Open switch status changed, new status: %s", status)
|
||||||
|
lastStatus = status
|
||||||
|
if status == self.openValue:
|
||||||
|
strStatus = "OPEN |"
|
||||||
|
else:
|
||||||
|
strStatus = "CLOSED |"
|
||||||
|
|
||||||
|
if self.ircThread.connected:
|
||||||
|
for channel in self.ircThread.channels:
|
||||||
|
topic = self.ircThread.getTopic(channel)
|
||||||
|
if not topic or not re.match(r"^\s*(OPEN|CLOSED) \|", topic):
|
||||||
|
newTopic = strStatus
|
||||||
|
else:
|
||||||
|
newTopic = re.sub(r"^\s*(OPEN|CLOSED) \|", strStatus, topic)
|
||||||
|
self.ircThread.setTopic(channel, newTopic)
|
||||||
|
except (IOError, OSError):
|
||||||
|
logging.exception("Could not read switch status")
|
||||||
|
pass #silently ignore non-existent file and other errors, otherwise it'd spam log
|
||||||
|
except Exception:
|
||||||
|
logging.exception("Exception in open switch thread")
|
||||||
|
logging.info("Before sleep")
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
logging.info("After sleep")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -295,10 +351,16 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
ircMsgQueue = Queue.Queue()
|
ircMsgQueue = Queue.Queue()
|
||||||
ircThread = None
|
ircThread = None
|
||||||
|
openSwitchThread = None
|
||||||
|
|
||||||
if config.useIRC:
|
if config.useIRC:
|
||||||
ircThread = IrcThread(config, ircMsgQueue)
|
ircThread = IrcThread(config, ircMsgQueue)
|
||||||
ircThread.setDaemon(True)
|
ircThread.setDaemon(True)
|
||||||
ircThread.start()
|
ircThread.start()
|
||||||
|
if config.useOpenSwitch:
|
||||||
|
openSwitchThread = OpenSwitchThread(config, ircThread)
|
||||||
|
openSwitchThread.setDaemon(True)
|
||||||
|
openSwitchThread.start()
|
||||||
|
|
||||||
nfcScanner = NFCScanner(config, ircMsgQueue, ircThread)
|
nfcScanner = NFCScanner(config, ircMsgQueue, ircThread)
|
||||||
nfcScanner.run()
|
nfcScanner.run()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue