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() app.listen(3000, function()
{ {
console.log('Development server listening on port 3000') console.log('Development server listening on port 3000')

View File

@ -44,7 +44,15 @@ function startApp()
triggers: { triggers: {
time: { time: {
enabled: false, enabled: false,
transitionTime: 0, transitionTime: null,
triggers: []
},
motion: {
enabled: false,
enabledDuringTimeTrigger: false,
transitionTime: null,
delay: null,
triggers: [] triggers: []
} }
}, },
@ -124,6 +132,8 @@ function startApp()
self.loadSystem().then(function() self.loadSystem().then(function()
{ {
self.loadTimeTriggers().then(function() self.loadTimeTriggers().then(function()
{
self.loadMotionTriggers().then(function()
{ {
self.loadSteps().then(function() self.loadSteps().then(function()
{ {
@ -134,6 +144,7 @@ function startApp()
}); });
}); });
}); });
});
}, },
methods: { methods: {
@ -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() loadSteps: function()
{ {
@ -558,6 +583,8 @@ function startApp()
self.saving = true; self.saving = true;
// TODO motion triggers (or separate the forms?)
var timeSettings = { var timeSettings = {
enabled: self.triggers.time.enabled, enabled: self.triggers.time.enabled,
transitionTime: self.triggers.time.transitionTime, transitionTime: self.triggers.time.transitionTime,
@ -624,6 +651,23 @@ function startApp()
self.triggers.time.triggers.splice(index, 1); 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) getDisplayTime: function(time, isRelative)
{ {
var result = ''; 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,16 +84,23 @@
<fieldset> <fieldset>
<h3>{{ $t('triggers.timeTitle') }}</h3> <h3>{{ $t('triggers.timeTitle') }}</h3>
<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.enabled">
<div class="warning" v-if="!wifiStatus.station.enabled || wifiStatus.station.status != 3"> <div class="warning" v-if="!wifiStatus.station.enabled || wifiStatus.station.status != 3">
{{ $t('triggers.timeInternet') }} {{ $t('triggers.timeInternet') }}
</div> </div>
<div v-if="triggers.time.triggers.length" class="timeTriggers"> <label for="timeTransitionTime">{{ $t('triggers.timeTransitionTime') }}</label>
<input type="number" id="timeTransitionTime" v-model.number="triggers.time.transitionTime">
<label>Regels</label>
<div v-if="triggers.time.triggers.length">
<div v-for="(trigger, index) in triggers.time.triggers" class="panel"> <div v-for="(trigger, index) in triggers.time.triggers" class="panel">
<div class="panel-header"> <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> <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"> <span class="actions">
[ <a href="#" @click.prevent="deleteItemTrigger(index)">{{ $t('triggers.timeDelete') }}</a> ] [ <a href="#" @click.prevent="deleteTimeTrigger(index)">{{ $t('triggers.timeDelete') }}</a> ]
</span> </span>
<div class="clear"></div> <div class="clear"></div>
</div> </div>
@ -165,13 +172,66 @@
<div class="buttons"> <div class="buttons">
<button class="button-primary button-outline" :disabled="saving" @click.prevent="addTimeTrigger">{{ $t('triggers.timeAdd') }}</button> <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>
</div> </div>
</fieldset> </fieldset>
<fieldset> <fieldset>
<h3>{{ $t('triggers.motionTitle') }}</h3> <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> </fieldset>
<div class="buttons">
<input class="button-primary" type="submit" :disabled="saving" :value="saving ? $t('applyButtonSaving') : $t('applyButton')">
</div>
</form> </form>
</div> </div>
@ -294,7 +354,7 @@
<h3>{{ $t('system.mapsTitle') }}</h3> <h3>{{ $t('system.mapsTitle') }}</h3>
<label for="mapsAPIKey">{{ $t('system.mapsAPIKey') }}</label> <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> <span class="hint">{{ $t('system.mapsAPIKeyhint') }}</span>
<div class="buttons"> <div class="buttons">

View File

@ -40,10 +40,14 @@ var messages = {
timeTitle: 'Time', timeTitle: 'Time',
timeInternet: 'Please note that time triggers require an internet connection.', timeInternet: 'Please note that time triggers require an internet connection.',
timeNoData: 'No time triggers defined yet', timeNoData: 'No time triggers defined yet',
timeEnabled: 'Enable time triggers',
timeTransitionTime: 'Transition time in milliseconds',
timeAdd: 'Add', timeAdd: 'Add',
timeDelete: 'Delete', timeDelete: 'Delete',
timeEnabled: 'Enabled', timeTriggerEnabled: 'Enabled',
timeFixedTime: 'Fixed time', timeFixedTime: 'Fixed time',
timeSunrise: 'Sunrise', timeSunrise: 'Sunrise',
timeSunset: 'Sunset', timeSunset: 'Sunset',
@ -57,7 +61,22 @@ var messages = {
timeSaturday: 'Saturday', timeSaturday: 'Saturday',
timeSunday: 'Sunday', 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: { connection: {
@ -97,7 +116,7 @@ var messages = {
pinLEDAP: 'Access Point status LED pin (+3.3v)', pinLEDAP: 'Access Point status LED pin (+3.3v)',
pinLEDSTA: 'Station Mode 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)', pinPWMDriverSDA: 'PCA9685 PWM driver SDA pin (data)',
pinPWMDriverSCL: 'PCA9685 PWM driver SCL pin (clock)', pinPWMDriverSCL: 'PCA9685 PWM driver SCL pin (clock)',
pwmAddress: 'PCA9685 PWM driver I²C address', pwmAddress: 'PCA9685 PWM driver I²C address',
@ -149,10 +168,14 @@ var messages = {
timeTitle: 'Tijd', timeTitle: 'Tijd',
timeInternet: 'Let op dat voor tijd triggers een internetverbinding vereist is.', timeInternet: 'Let op dat voor tijd triggers een internetverbinding vereist is.',
timeNoData: 'Nog geen tijd triggers geconfigureerd', timeNoData: 'Nog geen tijd triggers geconfigureerd',
timeEnabled: 'Tijd triggers inschakelen',
timeTransitionTime: 'Transitie tijd in milliseconden',
timeAdd: 'Toevoegen', timeAdd: 'Toevoegen',
timeDelete: 'Verwijderen', timeDelete: 'Verwijderen',
timeEnabled: 'Actief', timeTriggerEnabled: 'Actief',
timeFixedTime: 'Vaste tijd', timeFixedTime: 'Vaste tijd',
timeSunrise: 'Zonsopkomst', timeSunrise: 'Zonsopkomst',
timeSunset: 'Zonsondergang', timeSunset: 'Zonsondergang',
@ -166,7 +189,22 @@ var messages = {
timeSaturday: 'Zaterdag', timeSaturday: 'Zaterdag',
timeSunday: 'Zondag', 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: { connection: {

View File

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