peoplecounter, IR, spacestatus, proxy config, amplifier

master
openhabian configurator 2019-07-18 20:07:57 +02:00
parent a02aee8dc4
commit c2bf6d60e4
14 changed files with 238 additions and 48 deletions

View File

@ -1,4 +1,13 @@
An openHAB implementaiton for the level2 hackerspace
Dump this into /etc/openhab2
Installing proxy for paperUI
sudo bash
apt-get update
apt-get install nginx
@ -8,13 +17,29 @@ cat >/etc/nginx/sites-available/openhab <<"EOF"
server {
listen 80;
server_name lights.level2.lu;
# https://community.openhab.org/t/occasional-offline-in-basicui-when-proxying-via-nginx-connection-timed-out/63347
location / {
proxy_pass http://localhost:8080/basicui/;
proxy_pass http://localhost:8080/;
proxy_buffering off;
proxy_request_buffering off;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
client_body_buffer_size 0;
client_max_body_size 0;
proxy_max_temp_file_size 0;
proxy_read_timeout 18000;
proxy_send_timeout 18000;
gzip off;
}
location ~ ^/(paperui|habmin) {
# return 301 /basicui/app;
deny all;
}
}
EOF

View File

@ -12,14 +12,16 @@ Group area42 "Area42" (main_floor)
//-------------------------------------------------------------------------------
Number entrance_people_counter "People Counter [%s]" <parents_1_1> (entrance)
Number entrance_people_counter_max "People Counter Max [%s]" <parents_1_1> (entrance)
Switch entrance_door_status "Door Status" { channel="mqtt:topic:entrance_door_status:status" }
Switch entrance_ceiling_lamps "Ceiling Lamps" <lightbulb> (entrance) { channel="mqtt:topic:entrance_ceiling_lamps:power" }
Switch entrance_marbleadder_lamps "Marbleadder Lamps" <lightbulb> (entrance) { channel="mqtt:topic:mosquitto:entrance_marbleadder_lamps:power" }
Switch chill_zone_lamps "Lamps" <lightbulb> (chill_zone) { channel="mqtt:topic:chill_zone_lamps:power" }
Switch engineering_table_lamps "Table Lamps" <lightbulb> (engineering) { channel="mqtt:topic:engineering_table_lamps:power" }
Switch engineering_ceiling_lamps "Ceiling Lamps" <lightbulb> (engineering) { channel="mqtt:topic:engineering_ceiling_lamps:power" }
Switch engineering_status_lamp "Status Lamp" <lightbulb> (engineering) { channel="mqtt:topic:engineering_status_lamp:power" }
Switch engineering_ceiling_phone_flash "Ceiling Phone Flash" <lightbulb> (engineering) { channel="mqtt:topic:engineering_phone_flash:pulse" }
Switch area42_status_lamp "Status Lamp" <lightbulb> (area42) { channel="mqtt:topic:area42_status_lamp:power" }
Switch area42_status_lamp "Status Lamp" <lightbulb> (area42) { channel="mqtt:topic:mosquitto:area42_status_lamp:power" }
Switch lab_soldering_table "Soldering table" <lightbulb> (lab) { channel="mqtt:topic:mosquitto:lab_soldering_table:power" }
@ -41,6 +43,26 @@ String chill_zone_chromecast_status
Switch chill_zone_beamer
"Beamer"
(chill_zone)
String chill_zone_beamer_input "beamer input" (chill_zone)
// please help: beamer current state can be optained like this:
//wget -qO - 'http://10.2.113.7/tgi/return.tgi?query=info' |awk -F'[<>]' '/<info>/{print substr($3,33,2)}'
// the awk extracts the info. It is in format '<return>NG</return>' or '<return><info>data</info></return>
//NG = off
// from data, the interesting part is chars 33 and 34
// vv
//2a3139c616503735303000000048e60102ac0c010076
//00=no signal
//01=VGA1
//02=DVI (slideshow)
//03=composite
//04=s-video
//05=component
//09=VGA2
//11=LAN
//12=USB A (presentation to go)
//13=USB B (WTF?)
//15=hdmi2 (chromecast)
// ----------------------------------------------------------------------------
@ -63,6 +85,6 @@ Switch chill_zone_screen_button_down
Rollershutter chill_projection_screen "Projection Screen"
String IRCode_01 "IR Code" { channel="mqtt:topic:mosquitto:irremote:ir_code" }
String IRCode "IR Code" { channel="mqtt:topic:mosquitto:irremote:ir_code" }
String proxyIR

1
items/statuslights.items Normal file
View File

@ -0,0 +1 @@
Switch all_status_lights "All Status Lights" <lightbulb> (engineering)

View File

@ -4,4 +4,5 @@ Strategies {
Items {
entrance_people_counter: strategy = everyChange
entrance_people_counter_max: strategy = everyChange
}

View File

@ -7,6 +7,7 @@ then
//all_engineering_lights.postUpdate("ON")
chill_zone_lamps.sendCommand("ON")
entrance_ceiling_lamps.sendCommand("ON")
entrance_marbleadder_lamps.sendCommand("ON")
end
@ -18,6 +19,7 @@ then
engineering_ceiling_lamps.sendCommand("OFF")
chill_zone_lamps.sendCommand("OFF")
entrance_ceiling_lamps.sendCommand("OFF")
entrance_marbleadder_lamps.sendCommand("OFF")
end

View File

@ -2,5 +2,5 @@ rule "proxy IR mqtt"
when
Item proxyIR received command
then
IRCode_01.sendCommand(transform("MAP", "ir.map", receivedCommand.toString))
IRCode.sendCommand(transform("MAP", "ir.map", receivedCommand.toString))
end

View File

@ -1,35 +1,69 @@
var Timer ChromeCastOffTimer = null
val peoplecountermax = 0 // if openhab is restarted, the max value is lost... do we need persistence, how does that work?
val SpaceStatus = ''
rule "Startup"
when
System started
then
if (entrance_door_status.state.toString == 'OFF') {
SpaceStatus = 'open'
} else {
SpaceStatus = 'closed'
}
end
rule "Door Status"
when
Item entrance_door_status changed
then
val state = entrance_door_status.state.toString
val peoplecountermax
// the sensor state is inverted:
// OFF means opened
// ON means opened
if (state == 'OFF') {
logInfo('door', 'opened')
SpaceStatus = 'open'
entrance_ceiling_lamps.sendCommand("ON")
entrance_marbleadder_lamps.sendCommand("ON")
chill_zone_lamps.sendCommand("ON")
engineering_table_lamps.sendCommand("ON")
engineering_ceiling_lamps.sendCommand("ON")
engineering_status_lamp.sendCommand("ON")
area42_status_lamp.sendCommand("ON")
executeCommandLine("/etc/openhab2/syn2cat/spaceapi-set-status.sh open")
// needs current time in OpenTime
// sendTweet("It's "+OpenTime+" and we are open \o/ \ncome in and create something awesome =) \nhttps://Level2.lu/openingTimes")
} else {
logInfo('door', 'closed')
SpaceStatus = 'closed'
// turn the beamer off
sendHttpGetRequest("http://10.2.113.7/tgi/return.tgi?command=2a3102fd0660")
chill_zone_screen_button_up.sendCommand("ON")
entrance_ceiling_lamps.sendCommand("OFF")
entrance_marbleadder_lamps.sendCommand("OFF")
chill_zone_lamps.sendCommand("OFF")
engineering_table_lamps.sendCommand("OFF")
engineering_ceiling_lamps.sendCommand("OFF")
engineering_status_lamp.sendCommand("OFF")
area42_status_lamp.sendCommand("OFF")
lab_soldering_table.sendCommand("OFF")
IRCode.sendCommand(transform("MAP", "ir.map", "amp_off"))
executeCommandLine("/etc/openhab2/syn2cat/spaceapi-set-status.sh closed")
// needs current time in OpenTime
// and number of people in peopleMax="\nThere were up to $peopleMax hackers today.\n"
peoplecountermax=entrance_people_counter_max.state
if(peoplecountermax>8) {
peopleMax="\nThere were up to "+peoplecountermax+" hackers today.\n"
} else {
peopleMax=".".repeat(peoplecountermax)
}
logInfo("door", "twitter message: "+ OpenTime+peopleMax)
// sendTweet("We just closed our doors at "+OpenTime+peopleMax+" See you very soon... \nhttps://Level2.lu/openingTimes")
entrance_people_counter_max.postUpdate(0)
}
@ -47,10 +81,26 @@ then
val count = java.lang.Integer.parseInt(
transform("XPATH", "/table/tr[4]/td[2]/text()", response).trim()
)
if ( SpaceStatus == 'closed' ) {
count=0
}
if ( count != Integer.parseInt(entrance_people_counter.previousState().state.toString)) {
entrance_people_counter.postUpdate(count)
// fresh run needs a max init, later we use persistence to init
if (entrance_people_counter_max.state == NULL) {entrance_people_counter_max.postUpdate(count) }
// count is bigger, so we got a new maximum
if(entrance_people_counter_max.state < count) {
entrance_people_counter_max.postUpdate(count)
logInfo("door", "People counter maximum set to "+ count)
}
executeCommandLine("/etc/openhab2/syn2cat/spaceapi-update-peoplecount.sh "+count)
}
end
// moved this to some external scripts, way easier with debugging and quoting
// /usr/bin/curl --max-time 1 --silent --data key="$spaceapikey" --data-urlencode 'sensors={"sensors":{"people_now_present":[{"value":'"$presency"'}]}}' https://spaceapi.syn2cat.lu/sensor/set
// executeCommandLine("/usr/bin/curl -v --max-time 1 --data key=$(cat /etc/openhab2/spaceapikey.txt) --data-urlencode 'sensors={\"sensors\":{\"people_now_present\":[{\"value\":'+count+'}]}}' https://spaceapi.syn2cat.lu/sensor/set >/tmp/c.log 2>&1")
// needs import java.net.URLEncoder
// sendHttpGetRequest("https://spaceapi.syn2cat.lu/sensor/set?"+URLEncoder::encode('key='+spaceapikey+'&sensors={sensors":{"people_now_present":[{"value":'+count+'}]}}')
// ----------------------------------------------------------------------------
@ -58,7 +108,8 @@ rule "Tweet People Count"
when
Item entrance_people_counter changed
then
// sendTweet('There are currently ' + entrance_people_counter.state.toString + ' hackers present. Just pass by!')
// val people = entrance_people_counter.state.toString
// sendTweet('There are currently ' + people + ' hackers present. Just pass by!')
end
// ----------------------------------------------------------------------------
@ -87,15 +138,39 @@ then
if (state == 'ON') {
// turn the beamer on
beamerResponse = sendHttpGetRequest("http://10.2.113.7/tgi/return.tgi?command=2a3101fe0660")
beamerResponse = sendHttpGetRequest("http://10.2.113.7/tgi/return.tgi?command=2a3101fe0660")
chill_zone_screen_button_down.sendCommand("ON")
} else {
// turn the beamer off
beamerResponse = sendHttpGetRequest("http://10.2.113.7/tgi/return.tgi?command=2a3102fd0660")
beamerResponse = sendHttpGetRequest("http://10.2.113.7/tgi/return.tgi?command=2a3102fd0660")
}
val beamerStatus = transform("XPATH", "/return/text()", beamerResponse).replace("\n", '')
logInfo("beamer", "Beamer state: {}", beamerStatus)
end
rule "Beamer input"
when
Item chill_zone_beamer_input received command
then
val state = chill_zone_beamer_input.state.toString
var beamerResponse
if (state == 'hdmi1') {
beamerResponse = sendHttpGetRequest("http://10.2.113.7/tgi/return.tgi?command=2a3109f6071475")
} else if (state == 'hdmi2') {
beamerResponse = sendHttpGetRequest("http://10.2.113.7/tgi/return.tgi?command=2a3109f6071576")
} else if (state == 'dvi') {
beamerResponse = sendHttpGetRequest("http://10.2.113.7/tgi/return.tgi?command=2a3109f6070566")
} else if (state == 'vga1') {
beamerResponse = sendHttpGetRequest("http://10.2.113.7/tgi/return.tgi?command=2a3109f6070162")
} else if (state == 'vga2') {
beamerResponse = sendHttpGetRequest("http://10.2.113.7/tgi/return.tgi?command=2a3109f6070263")
}
else { }
val beamerStatus = transform("XPATH", "/return/text()", beamerResponse).replace("\n", '')
logInfo("beamer", "Beamer state: {}", beamerStatus)
end
// ----------------------------------------------------------------------------

15
rules/statuslights.rules Normal file
View File

@ -0,0 +1,15 @@
rule "Status Lights ON"
when
Item all_status_lights received update ON
then
engineering_status_lamp.sendCommand("ON")
area42_status_lamp.sendCommand("ON")
end
rule "Status Lights OFF"
when
Item all_status_lights received update OFF
then
engineering_status_lamp.sendCommand("OFF")
area42_status_lamp.sendCommand("OFF")
end

View File

@ -26,7 +26,7 @@
# Include legacy 1.x bindings. If set to true, it also allows the installation of 1.x bindings for which there is
# already a 2.x version available (requires remote repo access, see above). (default is false)
#
legacy = true
legacy = false
# A comma-separated list of bindings to install (e.g. "binding = sonos,knx,zwave")
binding = chromecast,mqtt,http1,exec,systeminfo
@ -38,7 +38,7 @@ ui = basic,habmin,habpanel,paper
persistence = mapdb
# A comma-separated list of actions to install (e.g. "action = mail,pushover")
action = mail,twitter,mqtt
action = mail,twitter
# A comma-separated list of transformation services to install (e.g. "transformation = map,jsonpath")
transformation = jsonpath,map,regex,scale,xpath

View File

@ -5,49 +5,51 @@ sitemap default label="Level2" {
Switch item=all_lights label="All Lights" icon="light"
}
Frame label="Multimedia" {
Switch item=chill_zone_beamer label="Beamer" icon="projector"
Switch item=chill_zone_beamer label="Beamer" icon="projector" mappings=[ON="on",OFF="off"]
Selection item=chill_zone_beamer_input label="input" mappings=['hdmi1'='HDMI','hdmi2'='Chromecast','dvi'='Slideshow','vga1'='VGA']
// mir brauchen en screen rule mat 3 status dei een kann setzen
// Switch item=chill_zone_screen_button_up label="Projection Screen (todo)" icon="screen" mappings=[up="up",stop="stop",down="down"]
Switch item=chill_projection_screen icon="screen" mappings=[UP="up",STOP="stop",DOWN="down"]
}
Frame label="Amplifier" {
Switch item=proxyIR label="power" mappings=['amp_on'='on','amp_off'='off']
Switch item=proxyIR label="volume" mappings=['amp_volup'='up','amp_voldown'='down']
Selection item=proxyIR label="input" mappings=['amp_jack1'='jack1','amp_jack2'='jack2','amp_hdmi'='hdmi','amp_optical'='optical','amp_cd'='cd','amp_tuner'='tuner']
}
Frame label="Bluray" {
Switch item=proxyIR label="power" mappings=['br_power'='power']
Switch item=proxyIR label="play" mappings=['br_play'='play','br_pause'='pause'] icon="mediacontrol"
Switch item=proxyIR label="control" mappings=['br_menu'='menu','br_ok'='ok']
Switch item=proxyIR label="navigate" mappings=['br_left'='left','br_up'='up','br_down'='down','br_right'='right'] icon="movecontrol"
Switch item=proxyIR label="language" mappings=['br_language'='audio','br_subtitle'='subtitles']
}
Frame label="Amplifier" {
Switch item=proxyIR label="power" mappings=['amp_on'='on','amp_off'='off']
Switch item=proxyIR label="volume" mappings=['amp_volup'='up','amp_voldown'='down']
Selection item=proxyIR label="input" mappings=['amp_jack1'='jack1','amp_jack2'='jack2','amp_hdmi'='hdmi','amp_optical'='optical','amp_cd'='cd','amp_tuner'='tuner']
}
Frame label="Bluray" {
Switch item=proxyIR label="power" mappings=['br_power'='power']
Switch item=proxyIR label="play" mappings=['br_play'='play','br_pause'='pause'] icon="mediacontrol"
Switch item=proxyIR label="control" mappings=['br_menu'='menu','br_ok'='ok']
Switch item=proxyIR label="navigate" mappings=['br_left'='left','br_up'='up','br_down'='down','br_right'='right'] icon="movecontrol"
Switch item=proxyIR label="language" mappings=['br_language'='audio','br_subtitle'='subtitles']
}
Frame label="Other" {
// een knaeppchen deen nemmen aus geht
Switch item=lab_soldering_table label="Soldering Table" icon="poweroutlet" mappings=[OFF="off"]
Switch item=engineering_ceiling_phone_flash label="Phone flashlight" icon="siren" mappings=[OFF="off"]
// wei switchen ech dei 2 status lights?. Dat hei ass fir status un ze maachen falls se net un wiren
Switch item=area42_status_lamp label="Status lights (todo)" mappings=[ON="ON"]
Switch item=all_status_lights label="Status lights" mappings=[ON="on"]
}
Frame label="Main Floor" icon="firstfloor" {
Group item=engineering
// Group item=lab
Group item=chill_zone
Group item=entrance
// Frame label="Main Floor" icon="firstfloor" {
// Group item=engineering
// // Group item=lab
// Group item=chill_zone
// Group item=entrance
//
// // Selection item=chill_zone_beamer_input
// // label="Beamer Input"
// // mappings=[
// // 0="DVI", // Hackerspace video
// // 1="HDMI 1",
// // 2="HDMI 2", // Chromecast
// // 3="VGA 1",
// // 4="VGA 2"
// // ]
// }
// Selection item=chill_zone_beamer_input
// label="Beamer Input"
// mappings=[
// 0="DVI", // Hackerspace video
// 1="HDMI 1",
// 2="HDMI 2", // Chromecast
// 3="VGA 1",
// 4="VGA 2"
// ]
}
Frame label="Ground Floor" icon="groundfloor" {
Group item=ground_floor
// Image url="https://raw.githubusercontent.com/wiki/openhab/openhab/images/features.png"
}
// Frame label="Ground Floor" icon="groundfloor" {
// Group item=ground_floor
// // Image url="https://raw.githubusercontent.com/wiki/openhab/openhab/images/features.png"
// }
}

1
syn2cat/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
spaceapikey.txt

24
syn2cat/spaceapi-set-status.sh Executable file
View File

@ -0,0 +1,24 @@
#!/bin/bash
set -x
exec >>/tmp/c.log
exec 2>&1
if [ "$1" = "" ] || ( [ "$1" != "open" ] && [ "$1" != "closed" ] )
then
echo "usage: $0 {open|closed}"
exit 1
fi
spaceapikey="$(cat "$(dirname $0)"/spaceapikey.txt)"
nai=$(date +%s)
case "$1" in
"open" )
openstate="true"
;;
"closed" )
openstate="false"
;;
* ) echo "error"
exit
;;
esac
/usr/bin/curl --max-time 1 --silent --data key="$spaceapikey" --data-urlencode sensors='{"state":{"open":'"$openstate"',"lastchange":'"$nai"'}}' https://spaceapi.syn2cat.lu/sensor/set

View File

@ -0,0 +1,13 @@
#!/bin/bash
set -x
exec >>/tmp/c.log
exec 2>&1
if [ "$1" = "" ]
then
echo "usage: $0 number"
exit 1
fi
spaceapikey="$(cat "$(dirname $0)"/spaceapikey.txt)"
presency="$1"
/usr/bin/curl --max-time 1 --silent --data key="$spaceapikey" --data-urlencode sensors='{"sensors":{"people_now_present":[{"value":'"$presency"'}]}}' https://spaceapi.syn2cat.lu/sensor/set

View File

@ -14,13 +14,20 @@ Bridge mqtt:broker:mosquitto "Mosquitto" [
stateTopic="stat/entrance/door_status/POWER"
]
}
Thing topic entrance_ceiling_lamps "Entrance Ceiling Lamps" @ "Entrance" {
Channels:
Type switch : power "Power" [
commandTopic="cmnd/entrance/ceiling_lamp/Power"
]
}
Thing topic entrance_marbleadder_lamps "Entrance Marbleadder Lamps" @ "Entrance" {
Channels:
Type switch : power "Power" [
commandTopic="cmnd/entrance/marbleadder_lamp/Power"
]
}
// ----------------------------------------------------------------------------
@ -45,6 +52,7 @@ Bridge mqtt:broker:mosquitto "Mosquitto" [
commandTopic="cmnd/chill_zone/sonoffs/Power"
]
}
Thing exec:command:beamerpower [command="/sbin/apcaccess -u", interval=5, timeout=2, autorun=false]
// ----------------------------------------------------------------------------
@ -90,7 +98,7 @@ Bridge mqtt:broker:mosquitto "Mosquitto" [
Thing topic lab_soldering_table "Soldering table" @ "Lab" {
Channels:
Type switch : power "Power" [
commandTopic="cmnd/lab/soldering_table/Power", stateTopic="stat/lab/soldering_table/Power"
commandTopic="cmnd/lab/soldering_table/Power", stateTopic="stat/lab/soldering_table/POWER"
]
}
@ -100,7 +108,8 @@ Bridge mqtt:broker:mosquitto "Mosquitto" [
Thing topic irremote "IR remote" @ "Chill Zone" {
Type string : ir_code "ircode"
[ commandTopic="cmnd/chill_zone/irremote/IRSEND"
[
commandTopic="cmnd/chill_zone/irremote/IRSEND"
]
}
@ -110,4 +119,4 @@ Bridge mqtt:broker:mosquitto "Mosquitto" [
Thing chromecast:chromecast:b000d809ccb35a409a3dd3d14e0fbf08 [ipAddress="10.2.113.120", port=8009]
//Thing exec:command:meaow [command="espeak -s 250 'meow meow meow meow meow meow meow meow' && espeak -s 250 -p 99 'meow meow meow meow meow meow' && espeak -s 250 -p 10 'meow meow meow meow meow meow' && espeak -s 30 -p 1 'meow meow meow meow'", autorun=false]
//Thing exec:command:meaow [command="espeak -s 250 'meow meow meow meow meow meow meow meow'", autorun=false]
//Thing exec:command:meaow [command="espeak -s 250 'meow meow meow meow meow meow meow meow'", autorun=false]