finalized scripts for prototype deployment, added some features on frontend
This commit is contained in:
parent
6aacdcadbc
commit
61a8aa8ebc
21 changed files with 762 additions and 153 deletions
|
@ -1,30 +1,31 @@
|
|||
Hostname: {{ ansible_facts['hostname'] }} running {{ansible_facts['distribution'] }} on address {{ addr }}
|
||||
Connected projectors: {{ barco_G62[0].ip }}
|
||||
|
||||
[global]
|
||||
room = {{ room }}
|
||||
mqttIp = {{ mqtt_ip }}
|
||||
mqttPort = {{ mqtt_port }}
|
||||
room = "{{ room }}"
|
||||
mqttIp = "{{ mqtt_ip }}"
|
||||
mqttPort = "{{ mqtt_port }}"
|
||||
|
||||
{% if barco_G62 %}
|
||||
{% if barco_G62 is defined %}
|
||||
{%+ for projector in barco_G62 +%}
|
||||
[{{projector.model}}.{{projector.position}}]
|
||||
ip = {{projector.ip}}
|
||||
ip = "{{projector.ip}}"
|
||||
port = {{projector.port}}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{%+ if tse_box +%}
|
||||
serial_device = {{ tse_box.serial_device }}
|
||||
{%+ if tse_box is defined +%}
|
||||
serial_device = "{{ tse_box.serial_device }}"
|
||||
{% endif %}
|
||||
|
||||
{%+ if projector_motors +%} {# change to appropriate thingy for running them #}
|
||||
{% end if %}
|
||||
{%+ if projector_motors is defined +%} {# change to appropriate thingy for running them #}
|
||||
{%+ for motor in projector_motors +%}
|
||||
[projector_motors.{{motor.position}}]
|
||||
i2c_address = {{motor.i2c_address}}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{%+ if extron_audio +%}
|
||||
{%+ if extron_audio is defined +%}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{%+ if extron_video +%}
|
||||
{%+ if extron_video is defined +%}
|
||||
|
||||
{% endif %}
|
|
@ -10,14 +10,12 @@ P01:
|
|||
- position: main
|
||||
model: barco_G62
|
||||
port: 3023
|
||||
ip: 192.168.192.13
|
||||
- position : side
|
||||
model: barco_G62
|
||||
port: 3023
|
||||
ip: 192.168.192.14
|
||||
|
||||
barco_old:
|
||||
main_ip: 1.1.1.1
|
||||
|
||||
P22:
|
||||
ip: localhost #for testirovanje
|
||||
# ip: 192.168.192.13
|
||||
# - position : side
|
||||
# model: barco_G62
|
||||
# port: 3023
|
||||
# ip: 192.168.192.14
|
||||
tse_box:
|
||||
serial_device: /dev/ttyUSB0
|
||||
|
34
ansible_deploy/malinca.yml
Normal file
34
ansible_deploy/malinca.yml
Normal file
|
@ -0,0 +1,34 @@
|
|||
P01:
|
||||
hosts:
|
||||
10.32.50.170:
|
||||
#192.168.192.42
|
||||
vars:
|
||||
static_ip: 192.168.192.42
|
||||
static_mask: 24
|
||||
static_routers: 192.168.192.1
|
||||
static_nameservers: 192.168.192.1
|
||||
room: P01
|
||||
mqtt_ip: localhost
|
||||
mqtt_port: 1883
|
||||
|
||||
barco_G62:
|
||||
- position: main
|
||||
model: barco_G62
|
||||
port: 3023
|
||||
# ip: localhost #for testirovanje
|
||||
ip: 192.168.192.12
|
||||
- position : side
|
||||
model: barco_G62
|
||||
port: 3023
|
||||
ip: 192.168.192.13
|
||||
tse_box:
|
||||
serial_device: /dev/ttyUSB0
|
||||
|
||||
projector_motors:
|
||||
- position: main
|
||||
i2c_address: 0x42
|
||||
offset: 0 #for when using single 8 channel relay board
|
||||
- position: side
|
||||
i2c_address: 0x43
|
||||
offset: 4
|
||||
|
|
@ -1,49 +1,64 @@
|
|||
- name: test playbook
|
||||
- name: Test playbook
|
||||
hosts: P01
|
||||
|
||||
#vars_files:
|
||||
# vars_files:
|
||||
# - secret
|
||||
vars:
|
||||
addr: "192.168.122.245"
|
||||
os_environment:
|
||||
- key: VITE_MQTT_HOST
|
||||
value: polztest.local
|
||||
vars:
|
||||
# addr: "192.168.122.245"
|
||||
|
||||
handlers:
|
||||
- name: restart NM
|
||||
ansible.builtin.service:
|
||||
name: NetworkManager
|
||||
state: restarted
|
||||
|
||||
tasks:
|
||||
- name: ping hosts
|
||||
- name: Ping hosts
|
||||
ansible.builtin.ping:
|
||||
|
||||
- name: install pkgs
|
||||
|
||||
|
||||
- name: set eth0 static IP
|
||||
become: true
|
||||
community.general.nmcli:
|
||||
conn_name: "Multimedia network"
|
||||
ifname: eth0
|
||||
type: ethernet
|
||||
ip4: "{{ static_ip }}/{{ static_mask }}"
|
||||
gw4: "{{ static_routers }}"
|
||||
state: present
|
||||
#notify: restart NM
|
||||
|
||||
|
||||
- name: Install pkgs
|
||||
become: true
|
||||
#become_user: root
|
||||
apt:
|
||||
name:
|
||||
- python3-pip
|
||||
- mosquitto
|
||||
- python3-poetry
|
||||
#- npm
|
||||
- nginx
|
||||
state: latest
|
||||
|
||||
#- name: set env
|
||||
|
||||
- name: ensures services dir exists
|
||||
file:
|
||||
path: "/home/kat/pyServices"
|
||||
state: directory
|
||||
|
||||
- name: ensures services dir exists
|
||||
file:
|
||||
path: "/home/kat/pyServices/fri-mm-maline"
|
||||
state: directory
|
||||
|
||||
- name: Copy poetry
|
||||
become: true
|
||||
- name: pip install
|
||||
pip:
|
||||
break_system_packages: true
|
||||
name:
|
||||
- poetry
|
||||
|
||||
|
||||
- name: check for script directory
|
||||
file:
|
||||
path: "/home/pi/pyServices"
|
||||
state: directory
|
||||
|
||||
|
||||
- name: Copy poetry conf
|
||||
#become: true
|
||||
ansible.builtin.copy:
|
||||
#seuser: root
|
||||
src: "../{{ item }}"
|
||||
dest: "/home/kat/pyServices/fri-mm-maline/{{ item }}"
|
||||
owner: kat
|
||||
group: kat
|
||||
dest: "/home/pi/pyServices/{{ item }}"
|
||||
owner: pi
|
||||
group: pi
|
||||
mode: '0644'
|
||||
backup: yes
|
||||
loop:
|
||||
|
@ -51,13 +66,19 @@
|
|||
- pyproject.toml
|
||||
- README.md
|
||||
|
||||
|
||||
- name: template config.toml
|
||||
ansible.builtin.template:
|
||||
src: ./conf.j2
|
||||
dest: /home/pi/pyServices/malinaConfig.toml
|
||||
|
||||
- name: copy python scripts
|
||||
become: true
|
||||
#become: true
|
||||
ansible.builtin.copy:
|
||||
src: "../{{ item }}"
|
||||
dest: "/home/kat/pyServices/fri-mm-maline"
|
||||
owner: kat
|
||||
group: kat
|
||||
dest: "/home/pi/pyServices"
|
||||
owner: pi
|
||||
group: pi
|
||||
mode: '0644'
|
||||
backup: yes
|
||||
loop:
|
||||
|
@ -67,30 +88,91 @@
|
|||
- projector_motors/projector_motors.py
|
||||
- tse_serial/tse_serial_controler.py
|
||||
- tse_serial/tse_serial_interpreter.py
|
||||
- config.toml #TODO GENERATE CONFIG
|
||||
# - config.toml # bruh
|
||||
|
||||
|
||||
|
||||
- name: poetry installation from thing
|
||||
- name: poetry installation
|
||||
ansible.builtin.shell:
|
||||
cmd: "poetry install"
|
||||
chdir: "/home/kat/pyServices/fri-mm-maline"
|
||||
chdir: "/home/pi/pyServices"
|
||||
|
||||
- name: Copy barco config
|
||||
- name: mosquitto service and reload
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
#seuser: root
|
||||
src: "../{{ item }}"
|
||||
dest: /lib/systemd/system
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
#backup: yes
|
||||
loop:
|
||||
- barco@.service
|
||||
- extron_audio.service
|
||||
- mqtt_init.service
|
||||
- projector_motors.service
|
||||
- tse_box.service
|
||||
ansible.builtin.systemd_service:
|
||||
name: mosquitto.service
|
||||
state: started
|
||||
daemon_reload: true
|
||||
|
||||
|
||||
- name: generate systemd services
|
||||
become: true
|
||||
block:
|
||||
- name: barco services
|
||||
when: barco_G62 is defined
|
||||
block:
|
||||
- name: template service
|
||||
vars:
|
||||
script_file: "/home/pi/pyServices/barco_G62_control.py %i"
|
||||
ansible.builtin.template:
|
||||
src: ./service.j2
|
||||
dest: /lib/systemd/system/barco@.service
|
||||
- name: enable service
|
||||
ansible.builtin.systemd_service:
|
||||
name: "{{item}}"
|
||||
enabled: true
|
||||
state: started
|
||||
loop:
|
||||
- barco@main.service
|
||||
- barco@side.service
|
||||
|
||||
- name: template projector motors service
|
||||
when: projector_motors is defined
|
||||
block:
|
||||
- name: template service
|
||||
vars:
|
||||
script_file: "/home/pi/pyServices/projector_motors.py"
|
||||
ansible.builtin.template:
|
||||
src: ./service.j2
|
||||
dest: /lib/systemd/system/projector_motors.service
|
||||
- name: enable service
|
||||
ansible.builtin.systemd_service:
|
||||
name: projector_motors.service
|
||||
enabled: true
|
||||
state: started
|
||||
|
||||
- name: template tse serial box service
|
||||
when: tse_box is defined
|
||||
block:
|
||||
- name: template service
|
||||
vars:
|
||||
script_file: "/home/pi/pyServices/tse_serial_controler.py"
|
||||
ansible.builtin.template:
|
||||
src: ./service.j2
|
||||
dest: /lib/systemd/system/tse_box.service
|
||||
- name: enable service
|
||||
ansible.builtin.systemd_service:
|
||||
name: tse_box.service
|
||||
enabled: true
|
||||
state: started
|
||||
|
||||
|
||||
|
||||
# - name: Copy barco config
|
||||
# become: true
|
||||
# ansible.builtin.copy:
|
||||
# #seuser: root
|
||||
# src: "./{{ item }}"
|
||||
# dest: /lib/systemd/system
|
||||
# owner: root
|
||||
# group: root
|
||||
# mode: '0644'
|
||||
# #backup: yes
|
||||
# loop:
|
||||
# - barco@.service
|
||||
# #- extron_audio.service
|
||||
# # - mqtt_init.service
|
||||
# - projector_motors.service
|
||||
# # - tse_box.service
|
||||
|
||||
|
||||
|
||||
|
@ -118,35 +200,29 @@
|
|||
become: true
|
||||
|
||||
ansible.builtin.copy:
|
||||
src: /home/kat/Documents/polzp/fri_multimedia_rework/frontend/vju_display/dist
|
||||
src: /home/kat/Documents/polzp/fri_multimedia_rework/frontend/vju_display/dist/
|
||||
#src: /home/kat/fri_multimedia_rework/frontend/vju_display/dist
|
||||
#remote_src: true
|
||||
dest: /srv/www
|
||||
#dest: /srv/www
|
||||
dest: /var/www/html/
|
||||
#dest: /home/kat/testoa
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0755'
|
||||
backup: yes
|
||||
|
||||
- name: enable modules
|
||||
become: true
|
||||
ansible.builtin.systemd_service:
|
||||
#name: "{{[ 'barco@main.service', 'barco@side.service' ]}}"
|
||||
name: "{{ item }}"
|
||||
state: stopped
|
||||
enabled: false
|
||||
loop:
|
||||
- barco@main.service
|
||||
- barco@side.service
|
||||
- extron_audio.service
|
||||
- mqtt_init.service
|
||||
- projector_motors.service
|
||||
- tse_box.service
|
||||
# - name: enable modules
|
||||
# become: true
|
||||
# ansible.builtin.systemd_service:
|
||||
# #name: "{{[ 'barco@main.service', 'barco@side.service' ]}}"
|
||||
# name: "{{ item }}"
|
||||
# state: stopped
|
||||
# enabled: false
|
||||
# loop:
|
||||
# - barco@main.service
|
||||
# - barco@side.service
|
||||
# # - extron_audio.service
|
||||
# # - mqtt_init.service
|
||||
# - projector_motors.service
|
||||
# # - tse_box.service
|
||||
|
||||
|
||||
- name: mosquitto service and reload
|
||||
become: true
|
||||
ansible.builtin.systemd_service:
|
||||
name: mosquitto.service
|
||||
state: started
|
||||
daemon_reload: true
|
|
@ -3,12 +3,13 @@ Description={{ script_file }}
|
|||
After=multi-user.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/poetry run /usr/bin/python3 {{ script_file }}
|
||||
ExecStart=/usr/local/bin/poetry run python3 {{ script_file }}
|
||||
Type=simple
|
||||
Restart=always
|
||||
User=kat
|
||||
Group=kat
|
||||
User=pi
|
||||
Group=pi
|
||||
RestartSec=10
|
||||
WorkingDirectory=/home/pi/pyServices
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
tasks:
|
||||
- name: test things
|
||||
when: barco_g62 is defined
|
||||
when: barco_G62 is defined
|
||||
block:
|
||||
#- name: ping hosts
|
||||
# ansible.builtin.ping:
|
||||
|
@ -19,13 +19,13 @@
|
|||
- name: template config.toml
|
||||
ansible.builtin.template:
|
||||
src: ./conf.j2
|
||||
dest: /home/kat/testo/conf.txt
|
||||
dest: /home/pi/conf.toml
|
||||
- name: template barco systemd service
|
||||
vars:
|
||||
script_file: "/home/kat/pyServices/fri-mm-maline/barco_G62_control.py %i"
|
||||
ansible.builtin.template:
|
||||
src: ./service.j2
|
||||
dest: /home/kat/testo/barc.serv
|
||||
dest: /home/kat/testo/barco.service
|
||||
- name: enable barcos
|
||||
ansible.builtin.ping:
|
||||
#itd itd itd
|
||||
|
@ -34,4 +34,5 @@
|
|||
block:
|
||||
- name: pingerino
|
||||
ansible.builtin.ping:
|
||||
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import Tab from './components/tabs/Tab.vue';
|
|||
import LightingPage from './components/pages/LightingPage.vue';
|
||||
import ServisPage from './components/pages/ServisPage.vue';
|
||||
|
||||
|
||||
let urlParams = new URLSearchParams(window.location.search);
|
||||
|
||||
const currentRoom = ref(urlParams.get('room') || 'none') // if no param specified
|
||||
|
@ -16,32 +17,16 @@ const currentRoom = ref(urlParams.get('room') || 'none') // if no param specifie
|
|||
|
||||
|
||||
const pageNum = ref(0)
|
||||
const srvcUnlocked = ref(false)
|
||||
const srvcUnlocked = ref(true)
|
||||
const showPinPopup = ref(false)
|
||||
|
||||
function openPinDiag() {
|
||||
|
||||
}
|
||||
|
||||
function closePinDiag() {
|
||||
|
||||
}
|
||||
|
||||
function unlockServicePage() {
|
||||
showPinPopup.value = true
|
||||
while (true) {
|
||||
if ('' == '') {
|
||||
srvcUnlocked.value = true
|
||||
closePinDiag()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function lockServicePage() {
|
||||
srvcUnlocked.value = false
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -59,18 +44,17 @@ function lockServicePage() {
|
|||
<Tab @click="pageNum=1; lockServicePage()" :selected="pageNum==1">Video</Tab>
|
||||
<Tab @click="pageNum=2; lockServicePage()" :selected="pageNum==2">Audio</Tab>
|
||||
<Tab @click="pageNum=3; lockServicePage()" :selected="pageNum==3">Lučke</Tab>
|
||||
<Tab @click="pageNum=4; unlockServicePage()" :selected="pageNum==4">Servis</Tab>
|
||||
<Tab @click="pageNum=4; lockServicePage()" :selected="pageNum==4">Servis</Tab>
|
||||
</VerticalTabs>
|
||||
<large style="display: flex;">turbo odličen super mega kontrol panel</large>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<MainPage v-if="pageNum == 0" :room="currentRoom" />
|
||||
<VideoPage v-else-if="pageNum == 1" :room="currentRoom" />
|
||||
|
||||
<LightingPage v-else-if="pageNum == 3" :room="currentRoom" />
|
||||
|
||||
<ServisPage v-else-if="pageNum == 4 && srvcUnlocked" :room="currentRoom" />
|
||||
<ServisPage v-else-if="pageNum == 4" :room="currentRoom" />
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -100,4 +84,8 @@ h1 {
|
|||
padding: .4rem;
|
||||
}
|
||||
|
||||
* {
|
||||
cursor: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
87
frontend/vju_display/src/components/AudioControlModule.vue
Normal file
87
frontend/vju_display/src/components/AudioControlModule.vue
Normal file
|
@ -0,0 +1,87 @@
|
|||
<script setup lang="ts">
|
||||
//import HelloWorld from './components/HelloWorld.vue'
|
||||
//import TheWelcome from './components/TheWelcome.vue'
|
||||
import { ref, onMounted, reactive, watch } from 'vue'
|
||||
import { $mqtt } from 'vue-paho-mqtt'
|
||||
|
||||
const props = defineProps({
|
||||
room: String,
|
||||
})
|
||||
|
||||
const topicstrs = [ //TODO everything else
|
||||
props.room + '/power/audio/status',
|
||||
]
|
||||
|
||||
const subscriptions =
|
||||
topicstrs.map(topic => {
|
||||
// console.log('subbing to', topic)
|
||||
$mqtt.subscribe(topic, (msg) => {
|
||||
// console.log('received:', topic, msg)
|
||||
handleIncomingMQTT(topic, msg)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
const audioStatus = ref(false)
|
||||
|
||||
function handleIncomingMQTT(topic: string, msg: string) {
|
||||
console.log('Received on', topic, 'with message', msg)
|
||||
audioStatus.value = msg == '1'
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// console.log('test')
|
||||
//$mqtt.publish('peepee', 'poopoo', 'Qr') // dela
|
||||
|
||||
})
|
||||
|
||||
function publishMQTTMsg(topic: string, msg: string) {
|
||||
//msg = msg.toString()
|
||||
console.log('Sending to [', topic, '] with message [', msg, ']')
|
||||
$mqtt.publish(topic, msg, 'Qr') //todo refactor to 1 or 0 maybe
|
||||
console.log('sent')
|
||||
}
|
||||
|
||||
async function setAudio() {
|
||||
let topicPref = props.room + "/power/audio/set"
|
||||
let command = '0'
|
||||
if (!audioStatus.value) {
|
||||
command = '1'
|
||||
}
|
||||
publishMQTTMsg(topicPref, command)
|
||||
//audioStatus.value = command == '1'
|
||||
}
|
||||
|
||||
|
||||
|
||||
//TODO organize better, binds, etc.
|
||||
|
||||
|
||||
const roomState = ref(0)
|
||||
// OFF -> 0; ON -> 1; IN BETWEEN -> 2
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<!-- TODO lepš -->
|
||||
<div>
|
||||
<h3>Ozvočenje</h3>
|
||||
<button style="" @click="setAudio()">
|
||||
{{ audioStatus ? 'UGASNI' : 'PRIŽGI' }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.disabled {
|
||||
opacity: .8;
|
||||
pointer-events: none;
|
||||
}
|
||||
button {
|
||||
padding: 1rem;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
|
@ -66,7 +66,7 @@ function publishMQTTMsg(topic: string, msg: string) {
|
|||
|
||||
async function setLecture(pos?: String) {
|
||||
if (!pos) { return }
|
||||
let topicPref = props.room + "/projektorji/" + props.position + "/"
|
||||
let topicPref = props.room + "/projectors/" + props.position + "/"
|
||||
let command = '0'
|
||||
if (roomState.value == 0) {
|
||||
command = '1'
|
||||
|
@ -75,8 +75,8 @@ async function setLecture(pos?: String) {
|
|||
} else { return }
|
||||
publishMQTTMsg((topicPref + 'set/power'), command)
|
||||
publishMQTTMsg((topicPref + 'platno/goto'), command == '1' ? 'DOWN' : 'UP')
|
||||
publishMQTTMsg((topicPref + 'lift/move/' + (command == '1' ? 'down' : 'up') ), command)
|
||||
await sleep(500)
|
||||
publishMQTTMsg((topicPref + 'lift/move/' + (command == '1' ? 'down' : 'up') ), '1')
|
||||
await sleep(1000)
|
||||
publishMQTTMsg((topicPref + 'platno/goto'), 'STOP')
|
||||
publishMQTTMsg((topicPref + 'lift/move/' + (command == '1' ? 'down' : 'up') ), '0')
|
||||
}
|
||||
|
@ -91,6 +91,8 @@ const roomStatus = reactive({
|
|||
platno_state: 'UNKNOWN',
|
||||
})
|
||||
|
||||
|
||||
|
||||
const roomState = ref(0)
|
||||
// OFF -> 0; ON -> 1; IN BETWEEN -> 2
|
||||
|
||||
|
@ -115,7 +117,7 @@ watch (roomStatus, (_, _newState) => {
|
|||
<!-- TODO lepš -->
|
||||
<div>
|
||||
<h3 v-if="roomState == 1">AKTIVNO</h3>
|
||||
<h3 v-else-if="roomState == 0">V PRIPRAVLJENOSTI</h3>
|
||||
<h3 v-else-if="roomState == 0">PRIPRAVLJENOST</h3>
|
||||
<h3 v-else-if="roomState == 2">POČAKAJTE</h3>
|
||||
<h3 v-else="roomState == 1">NAPAKA</h3>
|
||||
<button style="" @click="setLecture(props.position)" :disabled="roomState == 2">
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
<script setup lang="ts">
|
||||
//import HelloWorld from './components/HelloWorld.vue'
|
||||
//import TheWelcome from './components/TheWelcome.vue'
|
||||
import { ref, onMounted, reactive, watch } from 'vue'
|
||||
import { $mqtt } from 'vue-paho-mqtt'
|
||||
|
||||
const props = defineProps({
|
||||
room: String,
|
||||
})
|
||||
|
||||
const topicstrs = [ //TODO everything else
|
||||
props.room + '/power/master/status',
|
||||
]
|
||||
|
||||
const subscriptions =
|
||||
topicstrs.map(topic => {
|
||||
// console.log('subbing to', topic)
|
||||
$mqtt.subscribe(topic, (msg) => {
|
||||
// console.log('received:', topic, msg)
|
||||
handleIncomingMQTT(topic, msg)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
const MasterStatus = ref(false)
|
||||
|
||||
function handleIncomingMQTT(topic: string, msg: string) {
|
||||
console.log('Received on', topic, 'with message', msg)
|
||||
audioStatus.value = msg == '1'
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// console.log('test')
|
||||
//$mqtt.publish('peepee', 'poopoo', 'Qr') // dela
|
||||
|
||||
})
|
||||
|
||||
function publishMQTTMsg(topic: string, msg: string) {
|
||||
//msg = msg.toString()
|
||||
console.log('Sending to [', topic, '] with message [', msg, ']')
|
||||
$mqtt.publish(topic, msg, 'Qr') //todo refactor to 1 or 0 maybe
|
||||
console.log('sent')
|
||||
}
|
||||
|
||||
async function setMaster() {
|
||||
let topicPref = props.room + "/power/audio/set"
|
||||
let command = '0'
|
||||
if (!MasterStatus.value) {
|
||||
command = '1'
|
||||
}
|
||||
publishMQTTMsg(topicPref, command)
|
||||
//audioStatus.value = command == '1'
|
||||
}
|
||||
|
||||
|
||||
|
||||
//TODO organize better, binds, etc.
|
||||
|
||||
|
||||
const roomState = ref(0)
|
||||
// OFF -> 0; ON -> 1; IN BETWEEN -> 2
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<!-- TODO lepš -->
|
||||
<div>
|
||||
<h3>Sistem</h3>
|
||||
<button style="" @click="setMaster()">
|
||||
{{ MasterStatus ? 'UGASNI' : 'PRIŽGI' }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.disabled {
|
||||
opacity: .8;
|
||||
pointer-events: none;
|
||||
}
|
||||
button {
|
||||
padding: 1rem;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
78
frontend/vju_display/src/components/PinPopup.vue
Normal file
78
frontend/vju_display/src/components/PinPopup.vue
Normal file
|
@ -0,0 +1,78 @@
|
|||
<script setup lang="ts">
|
||||
|
||||
import { ref, onMounted } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
onClose: [Function, null],
|
||||
onSuccess: [Function, null]
|
||||
})
|
||||
|
||||
const pin = ref("1337")
|
||||
const testPin = ref("0000")
|
||||
// export default {
|
||||
// props: ['onClose', 'onSuccess'],
|
||||
// data() {
|
||||
// return {
|
||||
// pin: '',
|
||||
// };
|
||||
// },
|
||||
// methods: {
|
||||
function checkPin() {
|
||||
// Your hard-coded pin
|
||||
if (testPin.value === pin.value) {
|
||||
if (props.onSuccess)
|
||||
props.onSuccess(); // Let parent component know pin is correct
|
||||
if (props.onClose)
|
||||
props.onClose();
|
||||
} else {
|
||||
alert('Incorrect pin');
|
||||
}
|
||||
}
|
||||
function close() {
|
||||
if (props.onClose)
|
||||
props.onClose();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="pin-popup">
|
||||
<div class="overlay" @click="close"></div>
|
||||
<div class="popup">
|
||||
<h2>Enter Pin Code</h2>
|
||||
<input v-model="pin" type="password" placeholder="Pin Code" />
|
||||
<button @click="checkPin">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<style scoped>
|
||||
.pin-popup {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.popup {
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -87,15 +87,17 @@ const platnoStatus = ref(platnoState.UNKNOWN)
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div style="display:flex; gap: 1rem">
|
||||
<!-- <h3>{{ props.room }}</h3> -->
|
||||
<!-- <form> -->
|
||||
<!-- TODO lepš -->
|
||||
<div>
|
||||
<h4>platna {{ props.position }}</h4>
|
||||
<button
|
||||
@click="publishMQTTMsg(publishPrefix + 'goto', 'UP')"><UpIcon/></button>
|
||||
<button
|
||||
@click="publishMQTTMsg(publishPrefix + 'goto', 'DOWN')"><DownIcon/></button>
|
||||
</div>
|
||||
<div v-if="props.ctrlType == 'service'">
|
||||
<h5>Manual control</h5>
|
||||
<button
|
||||
|
@ -113,5 +115,9 @@ const platnoStatus = ref(platnoState.UNKNOWN)
|
|||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
button {
|
||||
padding: 1rem;
|
||||
margin: 0.1rem;
|
||||
width: 45%;
|
||||
}
|
||||
</style>
|
||||
|
|
87
frontend/vju_display/src/components/ProjectorPowerModule.vue
Normal file
87
frontend/vju_display/src/components/ProjectorPowerModule.vue
Normal file
|
@ -0,0 +1,87 @@
|
|||
<script setup lang="ts">
|
||||
//import HelloWorld from './components/HelloWorld.vue'
|
||||
//import TheWelcome from './components/TheWelcome.vue'
|
||||
import { ref, onMounted, reactive, watch } from 'vue'
|
||||
import { $mqtt } from 'vue-paho-mqtt'
|
||||
|
||||
const props = defineProps({
|
||||
room: String,
|
||||
})
|
||||
|
||||
const topicstrs = [ //TODO everything else
|
||||
props.room + '/power/projectors/status',
|
||||
]
|
||||
|
||||
const subscriptions =
|
||||
topicstrs.map(topic => {
|
||||
// console.log('subbing to', topic)
|
||||
$mqtt.subscribe(topic, (msg) => {
|
||||
// console.log('received:', topic, msg)
|
||||
handleIncomingMQTT(topic, msg)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
const projectorsStatus = ref(false)
|
||||
|
||||
function handleIncomingMQTT(topic: string, msg: string) {
|
||||
console.log('Received on', topic, 'with message', msg)
|
||||
projectorsStatus.value = msg == '1'
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// console.log('test')
|
||||
//$mqtt.publish('peepee', 'poopoo', 'Qr') // dela
|
||||
|
||||
})
|
||||
|
||||
function publishMQTTMsg(topic: string, msg: string) {
|
||||
//msg = msg.toString()
|
||||
console.log('Sending to [', topic, '] with message [', msg, ']')
|
||||
$mqtt.publish(topic, msg, 'Qr') //todo refactor to 1 or 0 maybe
|
||||
console.log('sent')
|
||||
}
|
||||
|
||||
async function setProjectors() {
|
||||
let topicPref = props.room + "/power/projectors/set"
|
||||
let command = '0'
|
||||
if (!projectorsStatus.value) {
|
||||
command = '1'
|
||||
}
|
||||
publishMQTTMsg(topicPref, command)
|
||||
//audioStatus.value = command == '1'
|
||||
}
|
||||
|
||||
|
||||
|
||||
//TODO organize better, binds, etc.
|
||||
|
||||
|
||||
const roomState = ref(0)
|
||||
// OFF -> 0; ON -> 1; IN BETWEEN -> 2
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<!-- TODO lepš -->
|
||||
<div>
|
||||
<h3>Projektorji</h3>
|
||||
<button style="" @click="setProjectors()">
|
||||
{{ projectorsStatus ? 'UGASNI' : 'PRIŽGI' }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.disabled {
|
||||
opacity: .8;
|
||||
pointer-events: none;
|
||||
}
|
||||
button {
|
||||
padding: 1rem;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
|
@ -7,7 +7,7 @@ import { $mqtt } from 'vue-paho-mqtt'
|
|||
const props = defineProps({
|
||||
room: String,
|
||||
position: String,
|
||||
ctrlType: [String, null]
|
||||
ctrltype: [String, null]
|
||||
})
|
||||
|
||||
const topicstrs = [ //TODO everything else
|
||||
|
|
83
frontend/vju_display/src/components/ResetButton.vue
Normal file
83
frontend/vju_display/src/components/ResetButton.vue
Normal file
|
@ -0,0 +1,83 @@
|
|||
<script setup lang="ts">
|
||||
//import HelloWorld from './components/HelloWorld.vue'
|
||||
//import TheWelcome from './components/TheWelcome.vue'
|
||||
import { ref, onMounted, reactive, watch } from 'vue'
|
||||
import { $mqtt } from 'vue-paho-mqtt'
|
||||
|
||||
const props = defineProps({
|
||||
room: String,
|
||||
})
|
||||
|
||||
const topicstrs = [ //TODO everything else
|
||||
props.room + '',
|
||||
]
|
||||
|
||||
const subscriptions =
|
||||
topicstrs.map(topic => {
|
||||
// console.log('subbing to', topic)
|
||||
$mqtt.subscribe(topic, (msg) => {
|
||||
// console.log('received:', topic, msg)
|
||||
handleIncomingMQTT(topic, msg)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
const audioStatus = ref(false)
|
||||
|
||||
function handleIncomingMQTT(topic: string, msg: string) {
|
||||
console.log('Received on', topic, 'with message', msg)
|
||||
audioStatus.value = msg == '1'
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// console.log('test')
|
||||
//$mqtt.publish('peepee', 'poopoo', 'Qr') // dela
|
||||
|
||||
})
|
||||
|
||||
function publishMQTTMsg(topic: string, msg: string) {
|
||||
//msg = msg.toString()
|
||||
console.log('Sending to [', topic, '] with message [', msg, ']')
|
||||
$mqtt.publish(topic, msg, 'Qr') //todo refactor to 1 or 0 maybe
|
||||
console.log('sent')
|
||||
}
|
||||
|
||||
async function resetAll() {
|
||||
let topicPref = props.room + "/power/"
|
||||
publishMQTTMsg(topicPref + 'audio/set', '0')
|
||||
publishMQTTMsg(topicPref + 'projectors/set', '1')
|
||||
publishMQTTMsg(topicPref + 'master/set', '1')
|
||||
publishMQTTMsg(props.room + "/projectors/main/lift/move/up", '1')
|
||||
publishMQTTMsg(props.room + "/projectors/side/lift/move/up", '1')
|
||||
//TODO NOT HARDCODE THISEFEWGJREWGREW
|
||||
publishMQTTMsg(props.room + "/projectors/main/platno/goto", 'UP')
|
||||
publishMQTTMsg(props.room + "/projectors/side/platno/goto", 'UP')
|
||||
//audioStatus.value = command == '1'
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<!-- TODO lepš -->
|
||||
<div>
|
||||
<h3>Reset sistema</h3>
|
||||
<button style="" @click="resetAll()">
|
||||
RESET
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.disabled {
|
||||
opacity: .8;
|
||||
pointer-events: none;
|
||||
}
|
||||
button {
|
||||
padding: 1rem;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
|
@ -75,7 +75,7 @@ function publishMQTTMsg(topic: string, msg: string) {
|
|||
$mqtt.publish(topic, msg, 'Qr') //todo refactor to 1 or 0 maybe
|
||||
console.log('sent')
|
||||
}
|
||||
const publishPrefix = ref(props.room + '/firanki/')
|
||||
const publishPrefix = ref(props.room + '/')
|
||||
|
||||
|
||||
</script>
|
||||
|
@ -89,15 +89,26 @@ const publishPrefix = ref(props.room + '/firanki/')
|
|||
<h4>Firanki</h4>
|
||||
|
||||
<button
|
||||
@mousedown="publishMQTTMsg(publishPrefix + 'move', 'MOVE_UP')"
|
||||
@mouseup="publishMQTTMsg(publishPrefix + 'move', 'STOP')" >
|
||||
@mousedown="publishMQTTMsg(publishPrefix + 'firanki/move', 'MOVE_UP')"
|
||||
@mouseup="publishMQTTMsg(publishPrefix + 'firanki/move', 'STOP')" >
|
||||
<UpIcon /></button>
|
||||
<button
|
||||
@mousedown="publishMQTTMsg(publishPrefix + 'move', 'MOVE_DOWN')"
|
||||
@mouseup="publishMQTTMsg(publishPrefix + 'move', 'STOP')" >
|
||||
@mousedown="publishMQTTMsg(publishPrefix + 'firanki/move', 'MOVE_DOWN')"
|
||||
@mouseup="publishMQTTMsg(publishPrefix + 'firanki/move', 'STOP')" >
|
||||
<DownIcon /></button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex; gap: 1rem;">
|
||||
<div>
|
||||
<h4>Lučka presets</h4>
|
||||
<button @click="publishMQTTMsg(publishPrefix + 'lightpresets/set', 'A')"A>Plchldr A</button>
|
||||
<button @click="publishMQTTMsg(publishPrefix + 'lightpresets/set', 'B')"A>Plchldr B</button>
|
||||
<button @click="publishMQTTMsg(publishPrefix + 'lightpresets/set', 'C')"A>Plchldr C</button>
|
||||
<button @click="publishMQTTMsg(publishPrefix + 'lightpresets/set', 'D')"A>Plchldr D</button>
|
||||
<button @click="publishMQTTMsg(publishPrefix + 'lightpresets/set', 'E')"A>Plchldr E</button>
|
||||
<button @click="publishMQTTMsg(publishPrefix + 'lightpresets/set', 'F')"A>Plchldr F</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
|
|
@ -5,21 +5,22 @@ import Projektor from '../Projektor.vue';
|
|||
import Platno from '../Platno.vue';
|
||||
import Lift from '../Lift.vue';
|
||||
import LectureModule from '../LectureModule.vue';
|
||||
import AudioControlModule from '../AudioControlModule.vue';
|
||||
|
||||
const props = defineProps({
|
||||
room: String
|
||||
})
|
||||
|
||||
const _glavni_position = ref('glavni')
|
||||
const _stranski_position = ref('stranski')
|
||||
const _glavni_position = ref('main')
|
||||
const _stranski_position = ref('side')
|
||||
|
||||
let _glavni = ref('glavni')
|
||||
let _stranski = ref('stranski')
|
||||
let _glavni = ref('main')
|
||||
let _stranski = ref('side')
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div style="display:flex; gap: 1rem">
|
||||
<div style="display:flex; gap: 1rem; margin:inherit">
|
||||
<div style="width: 50%;">
|
||||
<h4>Glavni:</h4>
|
||||
<LectureModule :room="props.room" :position="_glavni" />
|
||||
|
@ -29,4 +30,13 @@ let _stranski = ref('stranski')
|
|||
<LectureModule :room="props.room" :position="_stranski" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div>
|
||||
<AudioControlModule :room="props.room" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="css">
|
||||
* {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
38
frontend/vju_display/src/components/pages/PinPage.vue
Normal file
38
frontend/vju_display/src/components/pages/PinPage.vue
Normal file
|
@ -0,0 +1,38 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
//import HelloWorld from './components/HelloWorld.vue'
|
||||
//import TheWelcome from './components/TheWelcome.vue'
|
||||
import {ref, onMounted, reactive } from 'vue'
|
||||
import { $mqtt } from 'vue-paho-mqtt'
|
||||
// import Projektor from '../Projektor.vue'
|
||||
// import Platno from '../Platno.vue'
|
||||
import Lift from '../Lift.vue';
|
||||
import Projektor from '../Projektor.vue';
|
||||
|
||||
const props = defineProps({
|
||||
room: String,
|
||||
})
|
||||
const _glavni_position = ref('glavni')
|
||||
const _stranski_position = ref('stranski')
|
||||
const _ctrl_type = ref('service')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div style="display: flex; gap: 1rem">
|
||||
<div>
|
||||
<Projektor :room="props.room" :position="_glavni_position" :ctrlType="_ctrl_type" />
|
||||
<Lift :room="props.room" :position="_glavni_position" />
|
||||
<Platno :room="props.room" :position="_glavni_position" :ctrlType="_ctrl_type"/>
|
||||
|
||||
</div>
|
||||
<div>
|
||||
<Projektor :room="props.room" :position="_stranski_position" :ctrlType="_ctrl_type"/>
|
||||
<Lift :room="props.room" :position="_stranski_position" />
|
||||
<Platno :room="props.room" :position="_stranski_position" :ctrlType="_ctrl_type" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -4,15 +4,21 @@
|
|||
import {ref, onMounted, reactive } from 'vue'
|
||||
import { $mqtt } from 'vue-paho-mqtt'
|
||||
// import Projektor from '../Projektor.vue'
|
||||
// import Platno from '../Platno.vue'
|
||||
import Platno from '../Platno.vue'
|
||||
import Lift from '../Lift.vue';
|
||||
import Projektor from '../Projektor.vue';
|
||||
import ProjectorPowerModule from "@/components/ProjectorPowerModule.vue";
|
||||
import AudioControlModule from "@/components/AudioControlModule.vue";
|
||||
import MasterPowerControlModule from "@/components/MasterPowerControlModule.vue";
|
||||
import ResetButton from "@/components/ResetButton.vue";
|
||||
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
room: String,
|
||||
})
|
||||
const _glavni_position = ref('glavni')
|
||||
const _stranski_position = ref('stranski')
|
||||
const _glavni_position = ref('main')
|
||||
const _stranski_position = ref('side')
|
||||
const _ctrl_type = ref('service')
|
||||
</script>
|
||||
|
||||
|
@ -29,6 +35,16 @@ const _ctrl_type = ref('service')
|
|||
<Lift :room="props.room" :position="_stranski_position" />
|
||||
<Platno :room="props.room" :position="_stranski_position" :ctrlType="_ctrl_type" />
|
||||
</div>
|
||||
<div>
|
||||
<h5>POWER CONTROL</h5>
|
||||
<div>
|
||||
<ProjectorPowerModule :room="props.room" />
|
||||
<AudioControlModule :room="props.room" />
|
||||
<MasterPowerControlModule :room="props.room" />
|
||||
</div>
|
||||
<div></div>
|
||||
<ResetButton :room="props.room"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@ import Platno from '../Platno.vue'
|
|||
const props = defineProps({
|
||||
room: String,
|
||||
})
|
||||
const _glavni_position = ref('glavni')
|
||||
const _stranski_position = ref('stranski')
|
||||
const _glavni_position = ref('main')
|
||||
const _stranski_position = ref('side')
|
||||
const _test = ref('test')
|
||||
|
||||
</script>
|
||||
|
@ -20,12 +20,12 @@ const _test = ref('test')
|
|||
<div>
|
||||
<h4>Glavni</h4>
|
||||
<Projektor :room="props.room" :position="_glavni_position" :ctrl-type="_test" />
|
||||
<Platno :room="props.room" :position="_glavni_position" />
|
||||
<Platno :room="props.room" :position="_glavni_position" :ctrl-type="_test" />
|
||||
</div>
|
||||
<div>
|
||||
<h4>Stranski</h4>
|
||||
<Projektor :room="props.room" :position="_stranski_position" />
|
||||
<Platno :room="props.room" :position="_stranski_position" />
|
||||
<Projektor :room="props.room" :position="_stranski_position" :ctrltype="_test"/>
|
||||
<Platno :room="props.room" :position="_stranski_position" :ctrl-type="_test"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
5
malinaConfig.toml
Normal file
5
malinaConfig.toml
Normal file
|
@ -0,0 +1,5 @@
|
|||
[global]
|
||||
room = "P01"
|
||||
mqttIp = "localhost"
|
||||
mqttPort = "1883"
|
||||
|
Loading…
Reference in a new issue