Implemented frontend for motion trigger settings

Still read-only
This commit is contained in:
Mark van Renswoude 2018-01-17 23:28:39 +01:00
parent 0b42c49210
commit 9c22414fea
7 changed files with 259 additions and 82 deletions

View File

@ -162,6 +162,39 @@ app.post('/api/triggers/time', function(req, res)
});
var motionTriggers = {
enabled: true,
enabledDuringTimeTrigger: false,
transitionTime: 1000,
delay: 30000,
triggers: [
{
pin: 14,
brightness: 64,
direction: 2,
enabled: true
},
{
pin: 15,
brightness: 64,
direction: 3,
enabled: true
}
]
};
app.get('/api/triggers/motion', function(req, res)
{
res.send(motionTriggers);
});
app.post('/api/triggers/motion', function(req, res)
{
res.sendStatus(200);
});
app.listen(3000, function()
{
console.log('Development server listening on port 3000')

View File

@ -44,7 +44,15 @@ function startApp()
triggers: {
time: {
enabled: false,
transitionTime: 0,
transitionTime: null,
triggers: []
},
motion: {
enabled: false,
enabledDuringTimeTrigger: false,
transitionTime: null,
delay: null,
triggers: []
}
},
@ -125,10 +133,13 @@ function startApp()
{
self.loadTimeTriggers().then(function()
{
self.loadSteps().then(function()
self.loadMotionTriggers().then(function()
{
self.stopLoadingIndicator();
self.loading = false;
self.loadSteps().then(function()
{
self.stopLoadingIndicator();
self.loading = false;
});
});
});
});
@ -230,6 +241,20 @@ function startApp()
});
},
loadMotionTriggers: function()
{
var self = this;
return axios.get('/api/triggers/motion')
.then(function(response)
{
if (typeof response.data == 'object')
self.triggers.motion = response.data;
})
.catch(function(error)
{
console.log(error);
});
},
loadSteps: function()
{
@ -558,6 +583,8 @@ function startApp()
self.saving = true;
// TODO motion triggers (or separate the forms?)
var timeSettings = {
enabled: self.triggers.time.enabled,
transitionTime: self.triggers.time.transitionTime,
@ -624,6 +651,23 @@ function startApp()
self.triggers.time.triggers.splice(index, 1);
},
addMotionTrigger: function()
{
var self = this;
self.triggers.motion.triggers.push({
brightness: 0,
enabled: true,
pin: 2,
direction: 0
});
},
deleteMotionTrigger: function(index)
{
var self = this;
self.triggers.motion.triggers.splice(index, 1);
},
getDisplayTime: function(time, isRelative)
{
var result = '';

2
web/dist/bundle.css vendored

File diff suppressed because one or more lines are too long

2
web/dist/bundle.js vendored

File diff suppressed because one or more lines are too long

View File

@ -84,94 +84,154 @@
<fieldset>
<h3>{{ $t('triggers.timeTitle') }}</h3>
<div class="warning" v-if="!wifiStatus.station.enabled || wifiStatus.station.status != 3">
{{ $t('triggers.timeInternet') }}
</div>
<input type="checkbox" id="timeEnabled" v-model.boolean="triggers.time.enabled"><label for="timeEnabled" class="label-inline">{{ $t('triggers.timeEnabled') }}</label>
<div v-if="triggers.time.triggers.length" class="timeTriggers">
<div v-for="(trigger, index) in triggers.time.triggers" class="panel">
<div class="panel-header">
<input type="checkbox" :id="'time' + index + '_enabled'" v-model.boolean="trigger.enabled"><label class="label-inline" :for="'time' + index + '_enabled'">{{ $t('triggers.timeEnabled') }}</label>
<span class="actions">
[ <a href="#" @click.prevent="deleteItemTrigger(index)">{{ $t('triggers.timeDelete') }}</a> ]
</span>
<div class="clear"></div>
</div>
<div v-if="triggers.time.enabled">
<div class="warning" v-if="!wifiStatus.station.enabled || wifiStatus.station.status != 3">
{{ $t('triggers.timeInternet') }}
</div>
<div class="panel-body">
<select v-model.number="trigger.triggerType" class="inline">
<option value="0">{{ $t('triggers.timeFixedTime') }}</option>
<option value="1">{{ $t('triggers.timeSunrise') }}</option>
<option value="2">{{ $t('triggers.timeSunset') }}</option>
</select>
<label for="timeTransitionTime">{{ $t('triggers.timeTransitionTime') }}</label>
<input type="number" id="timeTransitionTime" v-model.number="triggers.time.transitionTime">
<select v-model.number="trigger.fixedTime" class="inline" v-if="trigger.triggerType == 0">
<option v-for="time in fixedTimes" :value="time">{{ getDisplayTime(time, false) }}</option>
</select>
<select v-model.number="trigger.relativeTime" class="inline" v-else>
<option v-for="time in relativeTimes" :value="time">{{ getDisplayTime(time, true) }}</option>
</select>
<div>
<span class="checkbox weekday">
<input type="checkbox" v-model.boolean="trigger.monday" :id="index + '_monday'">
<label :for="index + '_monday'" class="label-inline">{{ $t('triggers.timeMonday') }}</label>
</span>
<span class="checkbox weekday">
<input type="checkbox" v-model.boolean="trigger.tuesday" :id="index + '_tuesday'">
<label :for="index + '_tuesday'" class="label-inline">{{ $t('triggers.timeTuesday') }}</label>
</span>
<span class="checkbox weekday">
<input type="checkbox" v-model.boolean="trigger.wednesday" :id="index + '_wednesday'">
<label :for="index + '_wednesday'" class="label-inline">{{ $t('triggers.timeWednesday') }}</label>
</span>
<span class="checkbox weekday">
<input type="checkbox" v-model.boolean="trigger.thursday" :id="index + '_thursday'">
<label :for="index + '_thursday'" class="label-inline">{{ $t('triggers.timeThursday') }}</label>
</span>
<span class="checkbox weekday">
<input type="checkbox" v-model.boolean="trigger.friday" :id="index + '_friday'">
<label :for="index + '_friday'" class="label-inline">{{ $t('triggers.timeFriday') }}</label>
</span>
<span class="checkbox weekday">
<input type="checkbox" v-model.boolean="trigger.saturday" :id="index + '_saturday'">
<label :for="index + '_saturday'" class="label-inline">{{ $t('triggers.timeSaturday') }}</label>
</span>
<span class="checkbox weekday">
<input type="checkbox" v-model.boolean="trigger.sunday" :id="index + '_sunday'">
<label :for="index + '_sunday'" class="label-inline">{{ $t('triggers.timeSunday') }}</label>
<label>Regels</label>
<div v-if="triggers.time.triggers.length">
<div v-for="(trigger, index) in triggers.time.triggers" class="panel">
<div class="panel-header">
<input type="checkbox" :id="'time' + index + '_enabled'" v-model.boolean="trigger.enabled"><label class="label-inline" :for="'time' + index + '_enabled'">{{ $t('triggers.timeTriggerEnabled') }}</label>
<span class="actions">
[ <a href="#" @click.prevent="deleteTimeTrigger(index)">{{ $t('triggers.timeDelete') }}</a> ]
</span>
<div class="clear"></div>
</div>
<div class="step">
<span class="value">{{ Math.floor(trigger.brightness / 255 * 100) }}%</span>
<div class="slidercontainer">
<input type="range" min="0" max="255" class="slider" v-model.number="trigger.brightness">
<div class="panel-body">
<select v-model.number="trigger.triggerType" class="inline">
<option value="0">{{ $t('triggers.timeFixedTime') }}</option>
<option value="1">{{ $t('triggers.timeSunrise') }}</option>
<option value="2">{{ $t('triggers.timeSunset') }}</option>
</select>
<select v-model.number="trigger.fixedTime" class="inline" v-if="trigger.triggerType == 0">
<option v-for="time in fixedTimes" :value="time">{{ getDisplayTime(time, false) }}</option>
</select>
<select v-model.number="trigger.relativeTime" class="inline" v-else>
<option v-for="time in relativeTimes" :value="time">{{ getDisplayTime(time, true) }}</option>
</select>
<div>
<span class="checkbox weekday">
<input type="checkbox" v-model.boolean="trigger.monday" :id="index + '_monday'">
<label :for="index + '_monday'" class="label-inline">{{ $t('triggers.timeMonday') }}</label>
</span>
<span class="checkbox weekday">
<input type="checkbox" v-model.boolean="trigger.tuesday" :id="index + '_tuesday'">
<label :for="index + '_tuesday'" class="label-inline">{{ $t('triggers.timeTuesday') }}</label>
</span>
<span class="checkbox weekday">
<input type="checkbox" v-model.boolean="trigger.wednesday" :id="index + '_wednesday'">
<label :for="index + '_wednesday'" class="label-inline">{{ $t('triggers.timeWednesday') }}</label>
</span>
<span class="checkbox weekday">
<input type="checkbox" v-model.boolean="trigger.thursday" :id="index + '_thursday'">
<label :for="index + '_thursday'" class="label-inline">{{ $t('triggers.timeThursday') }}</label>
</span>
<span class="checkbox weekday">
<input type="checkbox" v-model.boolean="trigger.friday" :id="index + '_friday'">
<label :for="index + '_friday'" class="label-inline">{{ $t('triggers.timeFriday') }}</label>
</span>
<span class="checkbox weekday">
<input type="checkbox" v-model.boolean="trigger.saturday" :id="index + '_saturday'">
<label :for="index + '_saturday'" class="label-inline">{{ $t('triggers.timeSaturday') }}</label>
</span>
<span class="checkbox weekday">
<input type="checkbox" v-model.boolean="trigger.sunday" :id="index + '_sunday'">
<label :for="index + '_sunday'" class="label-inline">{{ $t('triggers.timeSunday') }}</label>
</span>
</div>
<div class="step">
<span class="value">{{ Math.floor(trigger.brightness / 255 * 100) }}%</span>
<div class="slidercontainer">
<input type="range" min="0" max="255" class="slider" v-model.number="trigger.brightness">
</div>
</div>
</div>
</div>
</div>
</div>
<div v-else class="nodata">
{{ $t('triggers.timeNoData') }}
</div>
<div v-else class="nodata">
{{ $t('triggers.timeNoData') }}
</div>
<div class="buttons">
<button class="button-primary button-outline" :disabled="saving" @click.prevent="addTimeTrigger">{{ $t('triggers.timeAdd') }}</button>
<input class="button-primary" type="submit" :disabled="saving" :value="saving ? $t('applyButtonSaving') : $t('applyButton')">
<div class="buttons">
<button class="button-primary button-outline" :disabled="saving" @click.prevent="addTimeTrigger">{{ $t('triggers.timeAdd') }}</button>
</div>
</div>
</fieldset>
<fieldset>
<h3>{{ $t('triggers.motionTitle') }}</h3>
<input type="checkbox" id="motionEnabled" v-model.boolean="triggers.motion.enabled"><label for="motionEnabled" class="label-inline">{{ $t('triggers.motionEnabled') }}</label>
<div v-if="triggers.motion.enabled">
<input type="checkbox" id="motionEnabledDuringTimeTrigger" v-model.boolean="triggers.motion.enabledDuringTimeTrigger"><label for="motionEnabledDuringTimeTrigger" class="label-inline">{{ $t('triggers.motionEnabledDuringTimeTrigger') }}</label>
<label for="motionTransitionTime">{{ $t('triggers.motionTransitionTime') }}</label>
<input type="number" id="motionTransitionTime" v-model.number="triggers.motion.transitionTime">
<label>Regels</label>
<div v-if="triggers.motion.triggers.length">
<div v-for="(trigger, index) in triggers.motion.triggers" class="panel">
<div class="panel-header">
<input type="checkbox" :id="'motion' + index + '_enabled'" v-model.boolean="trigger.enabled"><label class="label-inline" :for="'motion' + index + '_enabled'">{{ $t('triggers.motionTriggerEnabled') }}</label>
<span class="actions">
[ <a href="#" @click.prevent="deleteMotionTrigger(index)">{{ $t('triggers.motionDelete') }}</a> ]
</span>
<div class="clear"></div>
</div>
<div class="panel-body">
<label :for="'motion' + index + '_pin'">{{ $t('triggers.motionPin') }}</label>
<input type="number" :id="'motion' + index + '_pin'" v-model.number="trigger.pin">
<label :for="'motion' + index + '_direction'">{{ $t('triggers.motionDirection') }}</label>
<select :id="'motion' + index + '_direction'" v-model.number="trigger.direction">
<option value="1">{{ $t('triggers.motionDirectionNonDirectional') }}</option>
<option value="2">{{ $t('triggers.motionDirectionTopDown') }}</option>
<option value="3">{{ $t('triggers.motionDirectionBottomUp') }}</option>
</select>
<div class="step">
<span class="value">{{ Math.floor(trigger.brightness / 255 * 100) }}%</span>
<div class="slidercontainer">
<input type="range" min="0" max="255" class="slider" v-model.number="trigger.brightness">
</div>
</div>
</div>
</div>
</div>
<div v-else class="nodata">
{{ $t('triggers.motionNoData') }}
</div>
<div class="buttons">
<button class="button-primary button-outline" :disabled="saving" @click.prevent="addMotionTrigger">{{ $t('triggers.motionAdd') }}</button>
</div>
</div>
</fieldset>
<div class="buttons">
<input class="button-primary" type="submit" :disabled="saving" :value="saving ? $t('applyButtonSaving') : $t('applyButton')">
</div>
</form>
</div>
@ -294,7 +354,7 @@
<h3>{{ $t('system.mapsTitle') }}</h3>
<label for="mapsAPIKey">{{ $t('system.mapsAPIKey') }}</label>
<input type="number" id="mapsAPIKey" v-model.number="system.mapsAPIKey">
<input type="text" id="mapsAPIKey" v-model.number="system.mapsAPIKey">
<span class="hint">{{ $t('system.mapsAPIKeyhint') }}</span>
<div class="buttons">

View File

@ -40,10 +40,14 @@ var messages = {
timeTitle: 'Time',
timeInternet: 'Please note that time triggers require an internet connection.',
timeNoData: 'No time triggers defined yet',
timeEnabled: 'Enable time triggers',
timeTransitionTime: 'Transition time in milliseconds',
timeAdd: 'Add',
timeDelete: 'Delete',
timeEnabled: 'Enabled',
timeTriggerEnabled: 'Enabled',
timeFixedTime: 'Fixed time',
timeSunrise: 'Sunrise',
timeSunset: 'Sunset',
@ -57,7 +61,22 @@ var messages = {
timeSaturday: 'Saturday',
timeSunday: 'Sunday',
motionTitle: 'Motion'
motionTitle: 'Motion',
motionNoData: 'No motion triggers defined yet',
motionEnabled: 'Enable motion triggers',
motionEnabledDuringTimeTrigger: 'Activate even if a time trigger is already active',
motionTransitionTime: 'Transition time in milliseconds',
motionTriggerEnabled: 'Enabled',
motionAdd: 'Add',
motionDelete: 'Delete',
motionPin: 'GPIO pin (active high)',
motionDirection: 'Sweep animation',
motionDirectionNonDirectional: 'None (all steps at the same time)',
motionDirectionTopDown: 'Top down',
motionDirectionBottomUp: 'Bottom up'
},
connection: {
@ -97,7 +116,7 @@ var messages = {
pinLEDAP: 'Access Point status LED pin (+3.3v)',
pinLEDSTA: 'Station Mode status LED pin (+3.3v)',
pinAPButton: 'Enable Access Point button pin (pull low)',
pinAPButton: 'Enable Access Point button pin (active low)',
pinPWMDriverSDA: 'PCA9685 PWM driver SDA pin (data)',
pinPWMDriverSCL: 'PCA9685 PWM driver SCL pin (clock)',
pwmAddress: 'PCA9685 PWM driver I²C address',
@ -149,10 +168,14 @@ var messages = {
timeTitle: 'Tijd',
timeInternet: 'Let op dat voor tijd triggers een internetverbinding vereist is.',
timeNoData: 'Nog geen tijd triggers geconfigureerd',
timeEnabled: 'Tijd triggers inschakelen',
timeTransitionTime: 'Transitie tijd in milliseconden',
timeAdd: 'Toevoegen',
timeDelete: 'Verwijderen',
timeEnabled: 'Actief',
timeTriggerEnabled: 'Actief',
timeFixedTime: 'Vaste tijd',
timeSunrise: 'Zonsopkomst',
timeSunset: 'Zonsondergang',
@ -166,7 +189,22 @@ var messages = {
timeSaturday: 'Zaterdag',
timeSunday: 'Zondag',
motionTitle: 'Beweging'
motionTitle: 'Beweging',
motionNoData: 'Nog geen beweging triggers geconfigureerd',
motionEnabled: 'Beweging triggers inschakelen',
motionEnabledDuringTimeTrigger: 'Ook inschakelen als er al een tijd trigger actief is',
motionTransitionTime: 'Transitie tijd in milliseconden',
motionTriggerEnabled: 'Actief',
motionAdd: 'Toevoegen',
motionDelete: 'Verwijderen',
motionPin: 'GPIO pin (actief hoog)',
motionDirection: 'Animatie',
motionDirectionNonDirectional: 'Geen (alle treden gelijktijdig)',
motionDirectionTopDown: 'Boven naar beneden',
motionDirectionBottomUp: 'Beneden naar boven'
},
connection: {

View File

@ -12,6 +12,7 @@ $containerBackgroundColor: #202020;
$containerShadow: 0 0 50px #fcf6cf;
$panelBorderColor: #404040;
$panelBodyBackgroundColor: #242422;
$panelHeaderBackgroundColor: #302f28;
$panelHeaderColor: #808080;
$panelHeaderLinkColor: white;
@ -331,6 +332,7 @@ input[disabled]
& .panel-body
{
background-color: $panelBodyBackgroundColor;
padding: 2rem;
}
}