inital spaceapi (with backup from cache)

This commit is contained in:
Martin/Geno 2018-08-22 01:57:27 +02:00
parent 02e2fda2de
commit b01d732f72
No known key found for this signature in database
GPG key ID: 9D7D3C6BFF600C6A
13 changed files with 259 additions and 149 deletions

13
License
View file

@ -1,13 +0,0 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

View file

@ -1,18 +0,0 @@
# Eingangsschalter
der Hebel bei der Eingangstür, der im IRC schreibt, wenn jemand den Hebel zieht.
das python-skript legt man idealerweise in /usr/bin/
das systemd-ding legt man am besten in /etc/systemd/system/
mit den systemctl-befehlen muss man die "unit" dann noch starten.
further reading / sources :
https://linuxacademy.com/blog/geek/creating-an-irc-bot-with-python3/
http://pi4j.com/pins/model-b-rev1.html
http://razzpisampler.oreilly.com/ch07.html
http://wiringpi.com/the-gpio-utility/

21
install.sh Normal file
View file

@ -0,0 +1,21 @@
#!/usr/bin/bash
INSTALL_PATH=$PWD
# install dependencies
# apt-get install sopel nginx certbot
# install json (to save)
cp $INSTALL_PATH/spaceapi.json /var/www/html/spaceapi.json
chown pi:pi /var/www/html/spaceapi.json
# install mini-website
cp $INSTALL_PATH/www/index.html /var/www/html/index.html
# install ircbot
ln -s $INSTALL_PATH/sopel-bot /home/pi/.sopel
#install services
cp $INSTALL_PATH/systemd/{ircbot,schalter}.service /etc/systemd/system
systemctl daemon-reload
systemctl enable ircbot schalter
systemctl start ircbot schalter

View file

@ -1,11 +0,0 @@
[Unit]
Description=irc-daemon für türschalter
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/ircbot.py
[Install]
WantedBy=multi-user.target

View file

@ -1,85 +0,0 @@
#!/usr/bin/python
import socket
import RPi.GPIO as GPIO
import time
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server = "irc.freenode.net" # Server
channel = "#yanniktest" # Channel
botnick = "yanniksBot" # Your bots nick
adminname = "yannik_" #Your IRC nickname.
exitcode = "bye " + botnick
ircsock.connect((server, 6667)) # Here we connect to the server using the port 6667
ircsock.send(bytes("USER "+ botnick +" "+ botnick +" "+ botnick + " " + botnick + "\n", "UTF-8")) #We are basically filling out a form with this line and saying to set all the fields to the bot nickname.
ircsock.send(bytes("NICK "+ botnick +"\n", "UTF-8")) # assign the nick to the bot
def joinchan(chan): # join channel(s).
ircsock.send(bytes("JOIN "+ chan +"\n", "UTF-8"))
ircmsg = "hey, ircmsg!"
while ircmsg.find("End of /NAMES list.") == -1:
ircmsg = ircsock.recv(2048).decode("UTF-8")
ircmsg = ircmsg.strip('\n\r')
print(ircmsg)
def ping(): # respond to server Pings.
ircsock.send(bytes("PONG :pingis\n", "UTF-8"))
def sendmsg(msg, target=channel): # sends messages to the target.
ircsock.send(bytes("PRIVMSG "+ target +" :"+ msg +"\n", "UTF-8"))
def main():
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
joinchan(channel)
prev=None
while 1:
#print("ein weiterer durchlauf der main-schleiffe")
current=GPIO.input(18)
# liste[i%2] = GPIO.input(18)
if ( current != prev) :
if( prev != None):
sendmsg("schalter wurde betätigt! {}".format(current))
if (current == 0):
sendmsg("es ist nun offen!")
if (current == 1):
sendmsg("es ist nun zu, gute nacht!")
prev=current
ircmsg=" "
time.sleep(10)
#ircmsg = ircsock.recv(2048).decode("UTF-8")
#ircmsg = ircmsg.strip('\n\r')
print(ircmsg)
if ircmsg.find("PRIVMSG") != -1:
name = ircmsg.split('!',1)[0][1:]
message = ircmsg.split('PRIVMSG',1)[1].split(':',1)[1]
if len(name) < 17:
if message.find('Hi ' + botnick) != -1:
sendmsg("Hello " + name + "!")
if message[:5].find('.tell') != -1:
target = message.split(' ', 1)[1]
if target.find(' ') != -1:
message = target.split(' ', 1)[1]
target = target.split(' ')[0]
else:
target = name
message = "Could not parse. The message should be in the format of .tell [target] [message] to work properly."
sendmsg(message, target)
if name.lower() == adminname.lower() and message.rstrip() == exitcode:
sendmsg("oh...okay. :'(")
ircsock.send(bytes("QUIT \n", "UTF-8"))
return
else:
if ircmsg.find("PING :") != -1:
ping()
main()

View file

@ -1,22 +0,0 @@
import json
import time
import RPi.GPIO as GPIO
pin_number = 18;
data = {1:"asdf"}
wert_des_schalters = False
while True:
#/* Sphinx Vorschlag */
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
while True:
time.sleep(1)
if wert_des_schalters != GPIO.input(18) : # das ist gut
time.sleep(1) # // Contact bounce protection
print("wert wurde geaendert")
wert_des_schalters = GPIO.input(pin_number)
data = {1:wert_des_schalters}
with open('data.txt', 'w') as outfile:
json.dump(data, outfile)

73
schalter.py Executable file
View file

@ -0,0 +1,73 @@
#!/usr/bin/env python3
#########################################################################
# Spaceapi Implementation for a 63A switch
# (using 5 V 150 mA Raspberry Pi GPIO pin)
#
#
#########################################################################
# to make sure that everything does not happen at onec
import time
import datetime
# json and raspi imports
import json
# for using GPIO pins of the raspi
import RPi.GPIO as GPIO
# for logging
import logging
import systemd.journal
########################################################
#start init
log = logging.getLogger("SpaceAPI Schalter") #create a logger
log_fmt = logging.Formatter("%(levelname)s %(message)s") #define logging format
log_ch = JournalHandler() # create logging Handler
log_ch.setFormatter(log_fmt)
log.addHandler(log_ch)
log.setLevel(logging.INFO)
log.info("CCCHB space api switch v. 0.3 ")
#################################################################################
#function definitons:
#################################################################################
# will read the GPIO header of the pi and write the current state in the www spaceapi json file
def switched(pos):
wert_des_schalters = not bool(GPIO.input(pin_number))
icons= data.get("state").get('icon')
if (pos!= wert_des_schalters):
log.info("state changed to: ", wert_des_schalters)
chn_time = datetime.datetime.now().isoformat()
data.update({'state':{'open':wert_des_schalters,'lastchange':chn_time, "icon":icons}})
with open('/var/www/html/spaceapi.json', 'w') as outfile:
json.dump(data, outfile,sort_keys=True)
return wert_des_schalters
#################################################################################
#init GPIO pin on raspi
pin_number = 18; #set GPIO Pin number
GPIO.setmode(GPIO.BCM)
GPIO.setup(pin_number, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.add_event_detect(pin_number, GPIO.BOTH, callback=switched, bouncetime=200)
log.info("init complete... starting json foo")
#read json file
with open('spaceapi.json','r') as infile:
data = json.load(infile)
json.JSONDecoder(data) #decode json to python (may not be neccecary.)
#run switched once to get current switch status and change if needed.
#switched(wert_des_schalters)
currentValue = bool(0)
try:
while True:
time.sleep(1)
currentValue = switched(currentValue)
#include IRCBOT status here?
#do other stuff otherwise just don't do anything?!
except KeyboardInterrupt:
GPIO.cleanup()

2
sopel-bot/defaults.cfg Normal file
View file

@ -0,0 +1,2 @@
[core]
verify_ssl = false

View file

@ -0,0 +1,55 @@
#!/usr/bin/env python3
import json
import sopel.module
SPACEAPI = "/var/www/html/spaceapi.json"
CHANNEL = "#ccchb"
PLACE = "P5"
cache = {
"open": False
}
def get_spaceapi():
with open(SPACEAPI, 'r') as infile:
data = json.load(infile)
return data
def status_msg(status):
status_text = "closed"
if status:
status_text = "open"
return PLACE + ' is ' + status_text
def change_status(bot, status):
status_text = "closed"
if status:
status_text = "open"
bot.say(PLACE +' changed to '+ status_text, CHANNEL)
topic = status_msg(status)
channel = bot.channels[CHANNEL]
if channel.topic != None:
topic = channel.topic.replace(status_msg(not status), topic)
bot.write(('TOPIC', CHANNEL + ' :' + topic))
def check_status(bot, human=False):
data = get_spaceapi()
status = data["state"]["open"]
if status != cache["open"]:
cache["open"] = status
if CHANNEL in bot.channels:
change_status(bot, status)
if human:
bot.reply(status_msg(status))
@sopel.module.interval(5)
def interval_check_status(bot):
check_status(bot)
@sopel.module.commands('status')
def cmd_check_status(bot, trigger):
check_status(bot, True)

20
spaceapi.json Normal file
View file

@ -0,0 +1,20 @@
{
"api": "0.13",
"location": {
"address": "Postamt 5, An der Weide 50a, 28195 Bremen, Germany",
"ext_floor": 1,
"lat": 53.0815,
"lon": 8.8154
},
"logo": "https://ccchb.de/logo/CCCHB-logo_256x256_bw.png",
"space": "CCCHB",
"state": {
"icon": {
"closed": "https://ccchb.de/w/images/9/9e/SpaceClosed.svg",
"open": "https://ccchb.de/w/images/9/95/SpaceOpen.svg"
},
"lastchange": 1534869423.371439,
"open": false
},
"url": "https://ccchb.de/"
}

0
systemd/ircbot.service Normal file
View file

0
systemd/schalter.service Normal file
View file

88
www/index.html Normal file
View file

@ -0,0 +1,88 @@
<html>
<head>
<style>
body {
background-color: black;
color: white;
}
nav {
border-bottom: 2px solid green;
display: flex;
align-items:center;
flex-direction: row;
}
body.closed nav{
border-color: red;
}
#name {
font-size: 3em;
padding: auto;
}
#logo {
height: 4em;
margin-right: 10px;
}
#refresh {
margin-left: auto;
border: 5px solid green;
border-radius: 5px;
background: black;
color: white;
font-size: 2em;
}
body.closed #refresh {
border-color: red;
}
div#content {
display: flex;
justify-content: center;
}
#state {
margin: auto;
width: 40%;
}
</style>
<title>CCCHB is open</title></head>
<body class="offline">
<nav>
<img id="logo" src="">
<span id="name"></span>
<button id="refresh" type="button" onclick="load()">Update</button>
</nav>
<div id="content">
<img id="state" src="">
</div>
<script>
function load() {
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "spaceapi.json", false);
xhttp.send();
var result = JSON.parse(xhttp.responseText);
document.title = result.space + " is " + (result.state.open ? 'open' : 'close');
document.getElementById("name").innerText = result.space;
document.getElementById("logo").src = result.logo;
var stateurl = result.state.open ? result.state.icon.open : result.state.icon.closed;
document.getElementById("state").src = stateurl;
var link = document.querySelector("link[rel*='icon']") || document.createElement('link');
link.type = 'image/x-icon';
link.rel = 'shortcut icon';
link.href = stateurl;
document.getElementsByTagName('head')[0].appendChild(link);
var body = document.querySelector("body");
if (!result.state.open) {
body.classList.add("closed");
} else{
body.classList.remove("closed");
}
}
load();
window.setInterval(load, 60 * 1000);
</script>
</body>
</html>