Implemented frontend for motion trigger settings
Still read-only
This commit is contained in:
parent
0b42c49210
commit
9c22414fea
33
devserver.js
33
devserver.js
@ -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')
|
||||
|
52
web/app.js
52
web/app.js
@ -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
2
web/dist/bundle.css
vendored
File diff suppressed because one or more lines are too long
2
web/dist/bundle.js
vendored
2
web/dist/bundle.js
vendored
File diff suppressed because one or more lines are too long
202
web/index.html
202
web/index.html
@ -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">
|
||||
|
48
web/lang.js
48
web/lang.js
@ -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: {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user