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 Installing proxy for paperUI
sudo bash sudo bash
apt-get update apt-get update
apt-get install nginx apt-get install nginx
@ -8,13 +17,29 @@ cat >/etc/nginx/sites-available/openhab <<"EOF"
server { server {
listen 80; listen 80;
server_name lights.level2.lu; server_name lights.level2.lu;
# https://community.openhab.org/t/occasional-offline-in-basicui-when-proxying-via-nginx-connection-timed-out/63347
location / { 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 Host $http_host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; 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 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 "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_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_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 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_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_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_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 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" } 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 Switch chill_zone_beamer
"Beamer" "Beamer"
(chill_zone) (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" 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 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 { Items {
entrance_people_counter: strategy = everyChange entrance_people_counter: strategy = everyChange
entrance_people_counter_max: strategy = everyChange
} }

View File

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

View File

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

View File

@ -1,35 +1,69 @@
var Timer ChromeCastOffTimer = null 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" rule "Door Status"
when when
Item entrance_door_status changed Item entrance_door_status changed
then then
val state = entrance_door_status.state.toString val state = entrance_door_status.state.toString
val peoplecountermax
// the sensor state is inverted: // the sensor state is inverted:
// OFF means opened // OFF means opened
// ON means opened // ON means opened
if (state == 'OFF') { if (state == 'OFF') {
logInfo('door', 'opened') logInfo('door', 'opened')
SpaceStatus = 'open'
entrance_ceiling_lamps.sendCommand("ON") entrance_ceiling_lamps.sendCommand("ON")
entrance_marbleadder_lamps.sendCommand("ON")
chill_zone_lamps.sendCommand("ON") chill_zone_lamps.sendCommand("ON")
engineering_table_lamps.sendCommand("ON") engineering_table_lamps.sendCommand("ON")
engineering_ceiling_lamps.sendCommand("ON") engineering_ceiling_lamps.sendCommand("ON")
engineering_status_lamp.sendCommand("ON") engineering_status_lamp.sendCommand("ON")
area42_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 { } else {
logInfo('door', 'closed') logInfo('door', 'closed')
SpaceStatus = 'closed'
// turn the beamer off // turn the beamer off
sendHttpGetRequest("http://10.2.113.7/tgi/return.tgi?command=2a3102fd0660") sendHttpGetRequest("http://10.2.113.7/tgi/return.tgi?command=2a3102fd0660")
chill_zone_screen_button_up.sendCommand("ON") chill_zone_screen_button_up.sendCommand("ON")
entrance_ceiling_lamps.sendCommand("OFF") entrance_ceiling_lamps.sendCommand("OFF")
entrance_marbleadder_lamps.sendCommand("OFF")
chill_zone_lamps.sendCommand("OFF") chill_zone_lamps.sendCommand("OFF")
engineering_table_lamps.sendCommand("OFF") engineering_table_lamps.sendCommand("OFF")
engineering_ceiling_lamps.sendCommand("OFF") engineering_ceiling_lamps.sendCommand("OFF")
engineering_status_lamp.sendCommand("OFF") engineering_status_lamp.sendCommand("OFF")
area42_status_lamp.sendCommand("OFF") area42_status_lamp.sendCommand("OFF")
lab_soldering_table.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( val count = java.lang.Integer.parseInt(
transform("XPATH", "/table/tr[4]/td[2]/text()", response).trim() 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)) { if ( count != Integer.parseInt(entrance_people_counter.previousState().state.toString)) {
entrance_people_counter.postUpdate(count) 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 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 when
Item entrance_people_counter changed Item entrance_people_counter changed
then 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 end
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -88,6 +139,7 @@ then
if (state == 'ON') { if (state == 'ON') {
// turn the beamer 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 { } else {
// turn the beamer off // 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")
@ -96,6 +148,29 @@ then
logInfo("beamer", "Beamer state: {}", beamerStatus) logInfo("beamer", "Beamer state: {}", beamerStatus)
end 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 # 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) # 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") # A comma-separated list of bindings to install (e.g. "binding = sonos,knx,zwave")
binding = chromecast,mqtt,http1,exec,systeminfo binding = chromecast,mqtt,http1,exec,systeminfo
@ -38,7 +38,7 @@ ui = basic,habmin,habpanel,paper
persistence = mapdb persistence = mapdb
# A comma-separated list of actions to install (e.g. "action = mail,pushover") # 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") # A comma-separated list of transformation services to install (e.g. "transformation = map,jsonpath")
transformation = jsonpath,map,regex,scale,xpath transformation = jsonpath,map,regex,scale,xpath

View File

@ -5,10 +5,12 @@ sitemap default label="Level2" {
Switch item=all_lights label="All Lights" icon="light" Switch item=all_lights label="All Lights" icon="light"
} }
Frame label="Multimedia" { 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 // 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_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"] Switch item=chill_projection_screen icon="screen" mappings=[UP="up",STOP="stop",DOWN="down"]
}
Frame label="Amplifier" { Frame label="Amplifier" {
Switch item=proxyIR label="power" mappings=['amp_on'='on','amp_off'='off'] Switch item=proxyIR label="power" mappings=['amp_on'='on','amp_off'='off']
@ -22,32 +24,32 @@ sitemap default label="Level2" {
Switch item=proxyIR label="navigate" mappings=['br_left'='left','br_up'='up','br_down'='down','br_right'='right'] icon="movecontrol" 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'] Switch item=proxyIR label="language" mappings=['br_language'='audio','br_subtitle'='subtitles']
} }
}
Frame label="Other" { Frame label="Other" {
// een knaeppchen deen nemmen aus geht // een knaeppchen deen nemmen aus geht
Switch item=lab_soldering_table label="Soldering Table" icon="poweroutlet" mappings=[OFF="off"] 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"] 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 // 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" { // Frame label="Main Floor" icon="firstfloor" {
Group item=engineering // Group item=engineering
// Group item=lab // // Group item=lab
Group item=chill_zone // Group item=chill_zone
Group item=entrance // 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 // Frame label="Ground Floor" icon="groundfloor" {
// label="Beamer Input" // Group item=ground_floor
// mappings=[ // // Image url="https://raw.githubusercontent.com/wiki/openhab/openhab/images/features.png"
// 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"
}
} }

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

@ -22,6 +22,13 @@ Bridge mqtt:broker:mosquitto "Mosquitto" [
] ]
} }
Thing topic entrance_marbleadder_lamps "Entrance Marbleadder Lamps" @ "Entrance" {
Channels:
Type switch : power "Power" [
commandTopic="cmnd/entrance/marbleadder_lamp/Power"
]
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
Thing topic chill_zone_screen "Screen" @ "Chill Zone" { Thing topic chill_zone_screen "Screen" @ "Chill Zone" {
@ -45,6 +52,7 @@ Bridge mqtt:broker:mosquitto "Mosquitto" [
commandTopic="cmnd/chill_zone/sonoffs/Power" 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" { Thing topic lab_soldering_table "Soldering table" @ "Lab" {
Channels: Channels:
Type switch : power "Power" [ 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" { Thing topic irremote "IR remote" @ "Chill Zone" {
Type string : ir_code "ircode" Type string : ir_code "ircode"
[ commandTopic="cmnd/chill_zone/irremote/IRSEND" [
commandTopic="cmnd/chill_zone/irremote/IRSEND"
] ]
} }