122 lines
2.8 KiB
Vue
122 lines
2.8 KiB
Vue
<script setup lang="ts">
|
|
import { reactive } from "vue";
|
|
import { $mqtt } from "vue-paho-mqtt";
|
|
|
|
const props = defineProps({
|
|
room: String,
|
|
id: Number,
|
|
name: String,
|
|
dimmable: Boolean,
|
|
});
|
|
|
|
const topicPrefix = `${props.room}/lucke`
|
|
|
|
const status = reactive({
|
|
brightness: 0,
|
|
})
|
|
|
|
$mqtt.subscribe(`${topicPrefix}/brightness/${props.id}`, (message) => {
|
|
status.brightness = parseInt(message);
|
|
});
|
|
|
|
function doBrightness(brightness: Number) {
|
|
$mqtt.publish(`${topicPrefix}/set/${props.id}`, brightness.toFixed(0), 'Fnr');
|
|
}
|
|
|
|
</script>
|
|
|
|
<template>
|
|
<div v-if="props.dimmable">
|
|
<label>{{props.name}}</label>
|
|
<input type="range" min="0" max="100" step="10" :value="status.brightness" @input="doBrightness(parseInt(($event.target as HTMLInputElement).value))" >
|
|
</div>
|
|
<span v-else>
|
|
<label>{{props.name}}</label>
|
|
<button @click="doBrightness(status.brightness != 0 ? 0 : 100)" :class="{currentlyActive: status.brightness != 0 }">
|
|
</button>
|
|
</span>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.disabled {
|
|
opacity: 0.5;
|
|
pointer-events: none;
|
|
}
|
|
button {
|
|
border: 1px solid #000000;
|
|
height: 36px;
|
|
width: 36px;
|
|
border-radius: 3px;
|
|
background: #ffffff;
|
|
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
|
|
}
|
|
|
|
span {
|
|
display: inline-flex
|
|
}
|
|
|
|
div {
|
|
display: flex;
|
|
}
|
|
|
|
label {
|
|
padding: .5rem
|
|
}
|
|
|
|
input[type=range] {
|
|
flex: 1;
|
|
-webkit-appearance: none; /* Hides the slider so that custom slider can be made */
|
|
--width: 100%; /* Specific width is required for Firefox. */
|
|
background: transparent; /* Otherwise white in Chrome */
|
|
}
|
|
|
|
input[type=range]::-webkit-slider-thumb {
|
|
-webkit-appearance: none;
|
|
}
|
|
|
|
input[type=range]:focus {
|
|
outline: none;
|
|
}
|
|
|
|
input[type=range]::-moz-range-track {
|
|
width: 100%;
|
|
height: 8.4px;
|
|
cursor: pointer;
|
|
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
|
|
background: lightgray;
|
|
border-radius: 1.3px;
|
|
border: 0.2px solid #010101;
|
|
}
|
|
|
|
input[type=range]::-webkit-slider-runnable-track {
|
|
width: 100%;
|
|
height: 8.4px;
|
|
cursor: pointer;
|
|
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
|
|
background: lightgray;
|
|
border-radius: 1.3px;
|
|
border: 0.2px solid #010101;
|
|
}
|
|
|
|
|
|
input[type=range]::-moz-range-thumb {
|
|
border: 1px solid #000000;
|
|
height: 36px;
|
|
width: 32px;
|
|
border-radius: 3px;
|
|
background: #ffffff;
|
|
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
|
|
}
|
|
|
|
input[type=range]::-webkit-slider-thumb {
|
|
-webkit-appearance: none;
|
|
-webkit-appearance: none;
|
|
border: 1px solid #000000;
|
|
height: 36px;
|
|
width: 32px;
|
|
border-radius: 3px;
|
|
background: #ffffff;
|
|
box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
|
|
margin-top: -14px; /* You need to specify a margin in Chrome, but in Firefox and IE it is automatic */
|
|
}
|
|
</style>
|