Hi,
I created an Countdown widget for my Amazon Echo dot and want to share it with you.
It is not finished but i think it’s ready to share.
This is my configuration:
Thing/Channel:
- I used the “nextTimer” channel of my echo Thing
Items:
- EchoKuche_Countdown (DateTime) → Dummy item to store the remaining time
– added the following stateDescription: %1$tH:%1$tM:%1$tS - EchoKuche_NachsterTimerSekunden (Number) → Dummy item to store the remaining seconds
- EchoKuche_NachsterTimerMaxSekunden(Number) → Dummy item to store the duration of the timer in seconds
- EchoKuche_NachsterTimer (DateTime) → linked to the nextTimer channel
Rules:
I have created 3 rules to count down
-
Start rule
This rule will be triggered if the item EchoKuche_NachsterTimer change from UNDEF
Will execute an ECMAScript which will do the following
– get the target time of EchoKuche_NachsterTimer item
– get the diff between now and the target time
– create a new DateTime which starts at 00:00:00 on the Same day + the diff calculated before
– store the new DateTime into EchoKuche_Countdown item
– store the diff in seconds into EchoKuche_NachsterTimerSekunden
– store the diff in seconds into EchoKuche_NachsterTimerMaxSekunden
And will enable the “Count down” rule -
End rule
This rule will be triggered if the item EchoKuche_NachsterTimer change to UNDEF
Will execute an ECMAScript which will do the following
– create a new DateTime which starts at 00:00:00
– store the new DateTime into EchoKuche_Countdown item
– store 0 seconds into EchoKuche_NachsterTimerSekunden
And will disable the “Count down” rule -
Count down rule
This rule will be triggered by a cron every second
Will execute an ECMAScript which will do the following
– get the target time of EchoKuche_NachsterTimer item
– get the diff between now and the target time (the diff is decreasing each time for 1 second)
– create a new DateTime which starts at 00:00:00 on the Same day + the diff calculated before
– store the new DateTime into EchoKuche_Countdown item
– store the diff in seconds into EchoKuche_NachsterTimerSekunden
Widget:
I have created a Widget which sould look like my echo dot from above with a timer in the middle
The buttons are not working at the moment, but i think will add some functions to it later on.
You have to configure 3 props:
- EchoKuche_Countdown in “item”
- EchoKuche_NachsterTimerSekunden in “seconds”
- EchoKuche_NachsterTimerMaxSekunden in “maxSeconds”
Resources
Here is the code for the rules and the widget:
Start rule
triggers:
- id: "1"
configuration:
itemName: EchoKuche_NachsterTimer
previousState: UNDEF
type: core.ItemStateChangeTrigger
conditions: []
actions:
- inputs: {}
id: "2"
configuration:
type: application/javascript
script: >-
var zdt = Java.type('java.time.ZonedDateTime');
var duration = Java.type('java.time.Duration');
var localTime = Java.type('java.time.LocalTime');
var chronunit = Java.type('java.time.temporal.ChronoUnit');
var alarm = itemRegistry.getItem("EchoKuche_NachsterTimer").state;
var countdown = itemRegistry.getItem("EchoKuche_Countdown");
var coutndownMaxSekunden = itemRegistry.getItem("EchoKuche_NachsterTimerMaxSekunden");
var coutndownSekunden = itemRegistry.getItem("EchoKuche_NachsterTimerSekunden");
var jetzt = zdt.now().toLocalTime();
var alarmTime = alarm.getZonedDateTime().toLocalTime();
var diff = duration.between(jetzt, alarmTime);
var startime = localTime.of(0, 0, 0).plus(diff).truncatedTo(chronunit.SECONDS);
events.postUpdate(countdown, startime.toString());
events.postUpdate(coutndownMaxSekunden, diff.getSeconds());
events.postUpdate(coutndownSekunden, diff.getSeconds());
type: script.ScriptAction
- inputs: {}
id: "3"
configuration:
enable: true
ruleUIDs:
- 81f01c329e
type: core.RuleEnablementAction
End Rule
triggers:
- id: "1"
configuration:
itemName: EchoKuche_NachsterTimer
state: UNDEF
type: core.ItemStateChangeTrigger
conditions: []
actions:
- inputs: {}
id: "2"
configuration:
enable: false
ruleUIDs:
- 81f01c329e
type: core.RuleEnablementAction
- inputs: {}
id: "3"
configuration:
type: application/javascript
script: >-
var localTime = Java.type('java.time.LocalTime');
var countdown = itemRegistry.getItem("EchoKuche_Countdown");
var coutndownSekunden = itemRegistry.getItem("EchoKuche_NachsterTimerSekunden");
var startime = localTime.of(0, 0, 0);
events.postUpdate(countdown, startime.toString());
events.postUpdate(coutndownSekunden, 0);
type: script.ScriptAction
Count down
triggers:
- id: "1"
configuration:
cronExpression: "* * * * * ? *"
type: timer.GenericCronTrigger
conditions: []
actions:
- inputs: {}
id: "2"
configuration:
type: application/javascript
script: >-
var zdt = Java.type('java.time.ZonedDateTime');
var duration = Java.type('java.time.Duration');
var localTime = Java.type('java.time.LocalTime');
var chronunit = Java.type('java.time.temporal.ChronoUnit');
var alarm = itemRegistry.getItem("EchoKuche_NachsterTimer").state;
var countdown = itemRegistry.getItem("EchoKuche_Countdown");
var coutndownSekunden = itemRegistry.getItem("EchoKuche_NachsterTimerSekunden");
var jetzt = zdt.now().toLocalTime();
var alarmTime = alarm.getZonedDateTime().toLocalTime();
var diff = duration.between(jetzt, alarmTime);
var startime = localTime.of(0, 0, 0).plus(diff).truncatedTo(chronunit.SECONDS);
events.postUpdate(countdown, startime.toString());
events.postUpdate(coutndownSekunden, diff.getSeconds());
type: script.ScriptAction
Widget
uid: echoTimer
tags: []
props:
parameters:
- context: item
description: The time to show in the middle
label: Item
name: item
required: true
type: TEXT
- context: item
description: maxvalue for the gauge
label: maxSeconds
name: maxSeconds
required: true
type: TEXT
- context: item
description: current value for the gauge
label: seconds
name: seconds
required: true
type: TEXT
parameterGroups: []
timestamp: Feb 5, 2021, 10:39:30 AM
component: f7-card
slots:
default:
- component: oh-chart
slots:
series:
- component: oh-data-series
config:
radius: 100%
type: gauge
min: =0
max: =(items[props.maxSeconds].state)
data:
- value: =(items[props.seconds].state)
progress:
show: true
startAngle: 90
endAngle: -270
axisLine:
lineStyle:
width: 10
color:
- - 1
- lightgrey
detail:
show: false
axisTick:
show: true
length: 10
lineStyle:
width: 3
color: darkgrey
splitLine:
show: false
axisLabel:
show: false
pointer:
show: false
title:
show: false
anchor:
show: false
- component: f7-block
config:
style:
position: absolute
width: 55px
height: 55px
left: 55px
right: 0
top: 62px
margin-left: auto
margin-right: auto
margin-top: auto
transform: translate(-50%, -50%)
border-radius: 50%
border-style: solid
border-color: darkgrey
border-width: 1px
- component: f7-icon
config:
size: 35
style:
position: absolute
left: 37px
right: 0
top: 62px
margin-left: auto
margin-right: auto
margin-top: auto
transform: translate(-50%, -50%)
color: grey
f7: plus
- component: f7-block
config:
style:
position: absolute
width: 55px
height: 55px
left: 55px
right: 0
top: 238px
margin-left: auto
margin-right: auto
margin-top: auto
transform: translate(-50%, -50%)
border-radius: 50%
border-style: solid
border-color: darkgrey
border-width: 1px
- component: f7-icon
config:
size: 35
style:
position: absolute
left: 37px
right: 0
top: 238px
margin-left: auto
margin-right: auto
margin-top: auto
transform: translate(-50%, -50%)
color: grey
f7: minus
- component: f7-block
config:
style:
position: absolute
width: 55px
height: 55px
left: -120px
right: 0
top: 150px
margin-left: auto
margin-right: auto
margin-top: auto
transform: translate(-50%, -50%)
border-radius: 50%
border-style: solid
border-color: darkgrey
border-width: 1px
- component: f7-icon
config:
size: 32
style:
position: absolute
left: -144px
right: 0
top: 150px
margin-left: auto
margin-right: auto
margin-top: auto
transform: translate(-50%, -50%)scaleX(-1)
color: grey
f7: mic_slash_fill
- component: f7-block
config:
style:
position: absolute
width: 55px
height: 55px
left: 230px
right: 0
top: 150px
margin-left: auto
margin-right: auto
margin-top: auto
transform: translate(-50%, -50%)
border-radius: 50%
border-style: solid
border-color: darkgrey
border-width: 1px
- component: f7-icon
config:
size: 20
style:
position: absolute
left: 195px
right: 0
top: 151px
margin-left: auto
margin-right: auto
margin-top: auto
transform: translate(-50%, -50%)
color: grey
f7: circle_fill
- component: Label
config:
text: =(items[props.item].displayState)
style:
position: absolute
top: 50%
left: 50%
transform: translate(-50%, -50%)
font-size: 30px