Merge pull request #15 from Someone0nEarth/lean_ui
Icons for Menu Types
@ -21,7 +21,7 @@
|
||||
Use "Monkey C: Edit Application" from the Visual Studio Code command palette
|
||||
to update the application attributes.
|
||||
-->
|
||||
<iq:application id="98c36259-498a-4458-9cef-74a273ad2bc3" type="watch-app" name="@Strings.AppName" entry="HomeAssistantApp" launcherIcon="@Drawables.LauncherIcon" minApiLevel="3.1.0">
|
||||
<iq:application id="40131e87-31ff-454b-a8e2-92276ee399d6" type="watch-app" name="@Strings.AppName" entry="HomeAssistantApp" launcherIcon="@Drawables.LauncherIcon" minApiLevel="3.1.0">
|
||||
<!--
|
||||
Use the following from the Visual Studio Code comand palette to edit
|
||||
the build targets:
|
||||
|
@ -17,4 +17,6 @@
|
||||
|
||||
<drawables>
|
||||
<bitmap id="ErrorIcon" filename="error.svg"/>
|
||||
<bitmap id="GroupTypeIcon" filename="group_type.svg"/>
|
||||
<bitmap id="TapTypeIcon" filename="tap_type.svg"/>
|
||||
</drawables>
|
1
resources-icons-18/group_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="18" viewBox="0 -960 960 960" width="18" xmlns="http://www.w3.org/2000/svg"><path d="M479.858-160Q460-160 446-174.142q-14-14.141-14-34Q432-228 446.142-242q14.141-14 34-14Q500-256 514-241.858q14 14.141 14 34Q528-188 513.858-174q-14.141 14-34 14Zm0-272Q460-432 446-446.142q-14-14.141-14-34Q432-500 446.142-514q14.141-14 34-14Q500-528 514-513.858q14 14.141 14 34Q528-460 513.858-446q-14.141 14-34 14Zm0-272Q460-704 446-718.142q-14-14.141-14-34Q432-772 446.142-786q14.141-14 34-14Q500-800 514-785.858q14 14.141 14 34Q528-732 513.858-718q-14.141 14-34 14Z" fill="darkgrey" stroke="darkgrey"/></svg>
|
After Width: | Height: | Size: 605 B |
1
resources-icons-18/tap_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="18" viewBox="0 -960 960 960" width="18" xmlns="http://www.w3.org/2000/svg"><path d="M445-80q-29 0-56-12t-45-35L127-403l21-23q14-15 34.5-18.5T221-438l99 53v-365q0-12.75 8.675-21.375 8.676-8.625 21.5-8.625 12.825 0 21.325 8.625T380-750v465l-144-77 156 198q10 12 23.76 18 13.76 6 29.24 6h205q38 0 64-26t26-64v-170q0-25.5-17.25-42.75T680-460H460v-60h219.646q50.148 0 85.251 35T800-400v170q0 63-43.5 106.5T650-80H445ZM203-665q-11.074-18.754-17.037-40.492Q180-727.229 180-750.246 180-821 229.725-870.5T350-920q70.55 0 120.275 49.738Q520-820.524 520-749.956q0 22.956-5.963 44.614Q508.074-683.685 497-665l-52-30q7-12 11-26t4-29.478Q460-796 427.882-828q-32.117-32-78-32Q304-860 272-827.917 240-795.833 240-750q0 15 4 29t11 26l-52 30Zm285 335Z" fill="blue" stroke="blue"/></svg>
|
After Width: | Height: | Size: 781 B |
@ -17,4 +17,6 @@
|
||||
|
||||
<drawables>
|
||||
<bitmap id="ErrorIcon" filename="error.svg"/>
|
||||
<bitmap id="GroupTypeIcon" filename="group_type.svg"/>
|
||||
<bitmap id="TapTypeIcon" filename="tap_type.svg"/>
|
||||
</drawables>
|
1
resources-icons-21/group_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="21" viewBox="0 -960 960 960" width="21" xmlns="http://www.w3.org/2000/svg"><path d="M479.858-160Q460-160 446-174.142q-14-14.141-14-34Q432-228 446.142-242q14.141-14 34-14Q500-256 514-241.858q14 14.141 14 34Q528-188 513.858-174q-14.141 14-34 14Zm0-272Q460-432 446-446.142q-14-14.141-14-34Q432-500 446.142-514q14.141-14 34-14Q500-528 514-513.858q14 14.141 14 34Q528-460 513.858-446q-14.141 14-34 14Zm0-272Q460-704 446-718.142q-14-14.141-14-34Q432-772 446.142-786q14.141-14 34-14Q500-800 514-785.858q14 14.141 14 34Q528-732 513.858-718q-14.141 14-34 14Z" fill="darkgrey" stroke="darkgrey"/></svg>
|
After Width: | Height: | Size: 605 B |
1
resources-icons-21/tap_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="21" viewBox="0 -960 960 960" width="21" xmlns="http://www.w3.org/2000/svg"><path d="M445-80q-29 0-56-12t-45-35L127-403l21-23q14-15 34.5-18.5T221-438l99 53v-365q0-12.75 8.675-21.375 8.676-8.625 21.5-8.625 12.825 0 21.325 8.625T380-750v465l-144-77 156 198q10 12 23.76 18 13.76 6 29.24 6h205q38 0 64-26t26-64v-170q0-25.5-17.25-42.75T680-460H460v-60h219.646q50.148 0 85.251 35T800-400v170q0 63-43.5 106.5T650-80H445ZM203-665q-11.074-18.754-17.037-40.492Q180-727.229 180-750.246 180-821 229.725-870.5T350-920q70.55 0 120.275 49.738Q520-820.524 520-749.956q0 22.956-5.963 44.614Q508.074-683.685 497-665l-52-30q7-12 11-26t4-29.478Q460-796 427.882-828q-32.117-32-78-32Q304-860 272-827.917 240-795.833 240-750q0 15 4 29t11 26l-52 30Zm285 335Z" fill="blue" stroke="blue"/></svg>
|
After Width: | Height: | Size: 781 B |
@ -17,4 +17,6 @@
|
||||
|
||||
<drawables>
|
||||
<bitmap id="ErrorIcon" filename="error.svg"/>
|
||||
<bitmap id="GroupTypeIcon" filename="group_type.svg"/>
|
||||
<bitmap id="TapTypeIcon" filename="tap_type.svg"/>
|
||||
</drawables>
|
1
resources-icons-24/group_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="24" viewBox="0 -960 960 960" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M479.858-160Q460-160 446-174.142q-14-14.141-14-34Q432-228 446.142-242q14.141-14 34-14Q500-256 514-241.858q14 14.141 14 34Q528-188 513.858-174q-14.141 14-34 14Zm0-272Q460-432 446-446.142q-14-14.141-14-34Q432-500 446.142-514q14.141-14 34-14Q500-528 514-513.858q14 14.141 14 34Q528-460 513.858-446q-14.141 14-34 14Zm0-272Q460-704 446-718.142q-14-14.141-14-34Q432-772 446.142-786q14.141-14 34-14Q500-800 514-785.858q14 14.141 14 34Q528-732 513.858-718q-14.141 14-34 14Z" fill="darkgrey" stroke="darkgrey"/></svg>
|
After Width: | Height: | Size: 605 B |
1
resources-icons-24/tap_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="24" viewBox="0 -960 960 960" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M445-80q-29 0-56-12t-45-35L127-403l21-23q14-15 34.5-18.5T221-438l99 53v-365q0-12.75 8.675-21.375 8.676-8.625 21.5-8.625 12.825 0 21.325 8.625T380-750v465l-144-77 156 198q10 12 23.76 18 13.76 6 29.24 6h205q38 0 64-26t26-64v-170q0-25.5-17.25-42.75T680-460H460v-60h219.646q50.148 0 85.251 35T800-400v170q0 63-43.5 106.5T650-80H445ZM203-665q-11.074-18.754-17.037-40.492Q180-727.229 180-750.246 180-821 229.725-870.5T350-920q70.55 0 120.275 49.738Q520-820.524 520-749.956q0 22.956-5.963 44.614Q508.074-683.685 497-665l-52-30q7-12 11-26t4-29.478Q460-796 427.882-828q-32.117-32-78-32Q304-860 272-827.917 240-795.833 240-750q0 15 4 29t11 26l-52 30Zm285 335Z" fill="blue" stroke="blue"/></svg>
|
After Width: | Height: | Size: 781 B |
@ -17,4 +17,6 @@
|
||||
|
||||
<drawables>
|
||||
<bitmap id="ErrorIcon" filename="error.svg"/>
|
||||
<bitmap id="GroupTypeIcon" filename="group_type.svg"/>
|
||||
<bitmap id="TapTypeIcon" filename="tap_type.svg"/>
|
||||
</drawables>
|
1
resources-icons-26/group_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="26" viewBox="0 -960 960 960" width="26" xmlns="http://www.w3.org/2000/svg"><path d="M479.858-160Q460-160 446-174.142q-14-14.141-14-34Q432-228 446.142-242q14.141-14 34-14Q500-256 514-241.858q14 14.141 14 34Q528-188 513.858-174q-14.141 14-34 14Zm0-272Q460-432 446-446.142q-14-14.141-14-34Q432-500 446.142-514q14.141-14 34-14Q500-528 514-513.858q14 14.141 14 34Q528-460 513.858-446q-14.141 14-34 14Zm0-272Q460-704 446-718.142q-14-14.141-14-34Q432-772 446.142-786q14.141-14 34-14Q500-800 514-785.858q14 14.141 14 34Q528-732 513.858-718q-14.141 14-34 14Z" fill="darkgrey" stroke="darkgrey"/></svg>
|
After Width: | Height: | Size: 605 B |
1
resources-icons-26/tap_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="26" viewBox="0 -960 960 960" width="26" xmlns="http://www.w3.org/2000/svg"><path d="M445-80q-29 0-56-12t-45-35L127-403l21-23q14-15 34.5-18.5T221-438l99 53v-365q0-12.75 8.675-21.375 8.676-8.625 21.5-8.625 12.825 0 21.325 8.625T380-750v465l-144-77 156 198q10 12 23.76 18 13.76 6 29.24 6h205q38 0 64-26t26-64v-170q0-25.5-17.25-42.75T680-460H460v-60h219.646q50.148 0 85.251 35T800-400v170q0 63-43.5 106.5T650-80H445ZM203-665q-11.074-18.754-17.037-40.492Q180-727.229 180-750.246 180-821 229.725-870.5T350-920q70.55 0 120.275 49.738Q520-820.524 520-749.956q0 22.956-5.963 44.614Q508.074-683.685 497-665l-52-30q7-12 11-26t4-29.478Q460-796 427.882-828q-32.117-32-78-32Q304-860 272-827.917 240-795.833 240-750q0 15 4 29t11 26l-52 30Zm285 335Z" fill="blue" stroke="blue"/></svg>
|
After Width: | Height: | Size: 781 B |
@ -17,4 +17,6 @@
|
||||
|
||||
<drawables>
|
||||
<bitmap id="ErrorIcon" filename="error.svg"/>
|
||||
<bitmap id="GroupTypeIcon" filename="group_type.svg"/>
|
||||
<bitmap id="TapTypeIcon" filename="tap_type.svg"/>
|
||||
</drawables>
|
1
resources-icons-28/group_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="28" viewBox="0 -960 960 960" width="28" xmlns="http://www.w3.org/2000/svg"><path d="M479.858-160Q460-160 446-174.142q-14-14.141-14-34Q432-228 446.142-242q14.141-14 34-14Q500-256 514-241.858q14 14.141 14 34Q528-188 513.858-174q-14.141 14-34 14Zm0-272Q460-432 446-446.142q-14-14.141-14-34Q432-500 446.142-514q14.141-14 34-14Q500-528 514-513.858q14 14.141 14 34Q528-460 513.858-446q-14.141 14-34 14Zm0-272Q460-704 446-718.142q-14-14.141-14-34Q432-772 446.142-786q14.141-14 34-14Q500-800 514-785.858q14 14.141 14 34Q528-732 513.858-718q-14.141 14-34 14Z" fill="darkgrey" stroke="darkgrey"/></svg>
|
After Width: | Height: | Size: 605 B |
1
resources-icons-28/tap_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="28" viewBox="0 -960 960 960" width="28" xmlns="http://www.w3.org/2000/svg"><path d="M445-80q-29 0-56-12t-45-35L127-403l21-23q14-15 34.5-18.5T221-438l99 53v-365q0-12.75 8.675-21.375 8.676-8.625 21.5-8.625 12.825 0 21.325 8.625T380-750v465l-144-77 156 198q10 12 23.76 18 13.76 6 29.24 6h205q38 0 64-26t26-64v-170q0-25.5-17.25-42.75T680-460H460v-60h219.646q50.148 0 85.251 35T800-400v170q0 63-43.5 106.5T650-80H445ZM203-665q-11.074-18.754-17.037-40.492Q180-727.229 180-750.246 180-821 229.725-870.5T350-920q70.55 0 120.275 49.738Q520-820.524 520-749.956q0 22.956-5.963 44.614Q508.074-683.685 497-665l-52-30q7-12 11-26t4-29.478Q460-796 427.882-828q-32.117-32-78-32Q304-860 272-827.917 240-795.833 240-750q0 15 4 29t11 26l-52 30Zm285 335Z" fill="blue" stroke="blue"/></svg>
|
After Width: | Height: | Size: 781 B |
@ -17,4 +17,6 @@
|
||||
|
||||
<drawables>
|
||||
<bitmap id="ErrorIcon" filename="error.svg"/>
|
||||
<bitmap id="GroupTypeIcon" filename="group_type.svg"/>
|
||||
<bitmap id="TapTypeIcon" filename="tap_type.svg"/>
|
||||
</drawables>
|
1
resources-icons-30/group_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="30" viewBox="0 -960 960 960" width="30" xmlns="http://www.w3.org/2000/svg"><path d="M479.858-160Q460-160 446-174.142q-14-14.141-14-34Q432-228 446.142-242q14.141-14 34-14Q500-256 514-241.858q14 14.141 14 34Q528-188 513.858-174q-14.141 14-34 14Zm0-272Q460-432 446-446.142q-14-14.141-14-34Q432-500 446.142-514q14.141-14 34-14Q500-528 514-513.858q14 14.141 14 34Q528-460 513.858-446q-14.141 14-34 14Zm0-272Q460-704 446-718.142q-14-14.141-14-34Q432-772 446.142-786q14.141-14 34-14Q500-800 514-785.858q14 14.141 14 34Q528-732 513.858-718q-14.141 14-34 14Z" fill="darkgrey" stroke="darkgrey"/></svg>
|
After Width: | Height: | Size: 605 B |
1
resources-icons-30/tap_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="30" viewBox="0 -960 960 960" width="30" xmlns="http://www.w3.org/2000/svg"><path d="M445-80q-29 0-56-12t-45-35L127-403l21-23q14-15 34.5-18.5T221-438l99 53v-365q0-12.75 8.675-21.375 8.676-8.625 21.5-8.625 12.825 0 21.325 8.625T380-750v465l-144-77 156 198q10 12 23.76 18 13.76 6 29.24 6h205q38 0 64-26t26-64v-170q0-25.5-17.25-42.75T680-460H460v-60h219.646q50.148 0 85.251 35T800-400v170q0 63-43.5 106.5T650-80H445ZM203-665q-11.074-18.754-17.037-40.492Q180-727.229 180-750.246 180-821 229.725-870.5T350-920q70.55 0 120.275 49.738Q520-820.524 520-749.956q0 22.956-5.963 44.614Q508.074-683.685 497-665l-52-30q7-12 11-26t4-29.478Q460-796 427.882-828q-32.117-32-78-32Q304-860 272-827.917 240-795.833 240-750q0 15 4 29t11 26l-52 30Zm285 335Z" fill="blue" stroke="blue"/></svg>
|
After Width: | Height: | Size: 781 B |
@ -17,4 +17,6 @@
|
||||
|
||||
<drawables>
|
||||
<bitmap id="ErrorIcon" filename="error.svg"/>
|
||||
<bitmap id="GroupTypeIcon" filename="group_type.svg"/>
|
||||
<bitmap id="TapTypeIcon" filename="tap_type.svg"/>
|
||||
</drawables>
|
1
resources-icons-32/group_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="32" viewBox="0 -960 960 960" width="32" xmlns="http://www.w3.org/2000/svg"><path d="M479.858-160Q460-160 446-174.142q-14-14.141-14-34Q432-228 446.142-242q14.141-14 34-14Q500-256 514-241.858q14 14.141 14 34Q528-188 513.858-174q-14.141 14-34 14Zm0-272Q460-432 446-446.142q-14-14.141-14-34Q432-500 446.142-514q14.141-14 34-14Q500-528 514-513.858q14 14.141 14 34Q528-460 513.858-446q-14.141 14-34 14Zm0-272Q460-704 446-718.142q-14-14.141-14-34Q432-772 446.142-786q14.141-14 34-14Q500-800 514-785.858q14 14.141 14 34Q528-732 513.858-718q-14.141 14-34 14Z" fill="darkgrey" stroke="darkgrey"/></svg>
|
After Width: | Height: | Size: 605 B |
1
resources-icons-32/tap_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="32" viewBox="0 -960 960 960" width="32" xmlns="http://www.w3.org/2000/svg"><path d="M445-80q-29 0-56-12t-45-35L127-403l21-23q14-15 34.5-18.5T221-438l99 53v-365q0-12.75 8.675-21.375 8.676-8.625 21.5-8.625 12.825 0 21.325 8.625T380-750v465l-144-77 156 198q10 12 23.76 18 13.76 6 29.24 6h205q38 0 64-26t26-64v-170q0-25.5-17.25-42.75T680-460H460v-60h219.646q50.148 0 85.251 35T800-400v170q0 63-43.5 106.5T650-80H445ZM203-665q-11.074-18.754-17.037-40.492Q180-727.229 180-750.246 180-821 229.725-870.5T350-920q70.55 0 120.275 49.738Q520-820.524 520-749.956q0 22.956-5.963 44.614Q508.074-683.685 497-665l-52-30q7-12 11-26t4-29.478Q460-796 427.882-828q-32.117-32-78-32Q304-860 272-827.917 240-795.833 240-750q0 15 4 29t11 26l-52 30Zm285 335Z" fill="blue" stroke="blue"/></svg>
|
After Width: | Height: | Size: 781 B |
@ -17,4 +17,6 @@
|
||||
|
||||
<drawables>
|
||||
<bitmap id="ErrorIcon" filename="error.svg"/>
|
||||
<bitmap id="GroupTypeIcon" filename="group_type.svg"/>
|
||||
<bitmap id="TapTypeIcon" filename="tap_type.svg"/>
|
||||
</drawables>
|
1
resources-icons-38/group_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="38" viewBox="0 -960 960 960" width="38" xmlns="http://www.w3.org/2000/svg"><path d="M479.858-160Q460-160 446-174.142q-14-14.141-14-34Q432-228 446.142-242q14.141-14 34-14Q500-256 514-241.858q14 14.141 14 34Q528-188 513.858-174q-14.141 14-34 14Zm0-272Q460-432 446-446.142q-14-14.141-14-34Q432-500 446.142-514q14.141-14 34-14Q500-528 514-513.858q14 14.141 14 34Q528-460 513.858-446q-14.141 14-34 14Zm0-272Q460-704 446-718.142q-14-14.141-14-34Q432-772 446.142-786q14.141-14 34-14Q500-800 514-785.858q14 14.141 14 34Q528-732 513.858-718q-14.141 14-34 14Z" fill="darkgrey" stroke="darkgrey"/></svg>
|
After Width: | Height: | Size: 605 B |
1
resources-icons-38/tap_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="38" viewBox="0 -960 960 960" width="38" xmlns="http://www.w3.org/2000/svg"><path d="M445-80q-29 0-56-12t-45-35L127-403l21-23q14-15 34.5-18.5T221-438l99 53v-365q0-12.75 8.675-21.375 8.676-8.625 21.5-8.625 12.825 0 21.325 8.625T380-750v465l-144-77 156 198q10 12 23.76 18 13.76 6 29.24 6h205q38 0 64-26t26-64v-170q0-25.5-17.25-42.75T680-460H460v-60h219.646q50.148 0 85.251 35T800-400v170q0 63-43.5 106.5T650-80H445ZM203-665q-11.074-18.754-17.037-40.492Q180-727.229 180-750.246 180-821 229.725-870.5T350-920q70.55 0 120.275 49.738Q520-820.524 520-749.956q0 22.956-5.963 44.614Q508.074-683.685 497-665l-52-30q7-12 11-26t4-29.478Q460-796 427.882-828q-32.117-32-78-32Q304-860 272-827.917 240-795.833 240-750q0 15 4 29t11 26l-52 30Zm285 335Z" fill="blue" stroke="blue"/></svg>
|
After Width: | Height: | Size: 781 B |
@ -17,4 +17,6 @@
|
||||
|
||||
<drawables>
|
||||
<bitmap id="ErrorIcon" filename="error.svg"/>
|
||||
<bitmap id="GroupTypeIcon" filename="group_type.svg"/>
|
||||
<bitmap id="TapTypeIcon" filename="tap_type.svg"/>
|
||||
</drawables>
|
1
resources-icons-42/group_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="42" viewBox="0 -960 960 960" width="42" xmlns="http://www.w3.org/2000/svg"><path d="M479.858-160Q460-160 446-174.142q-14-14.141-14-34Q432-228 446.142-242q14.141-14 34-14Q500-256 514-241.858q14 14.141 14 34Q528-188 513.858-174q-14.141 14-34 14Zm0-272Q460-432 446-446.142q-14-14.141-14-34Q432-500 446.142-514q14.141-14 34-14Q500-528 514-513.858q14 14.141 14 34Q528-460 513.858-446q-14.141 14-34 14Zm0-272Q460-704 446-718.142q-14-14.141-14-34Q432-772 446.142-786q14.141-14 34-14Q500-800 514-785.858q14 14.141 14 34Q528-732 513.858-718q-14.141 14-34 14Z" fill="darkgrey" stroke="darkgrey"/></svg>
|
After Width: | Height: | Size: 605 B |
1
resources-icons-42/tap_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="42" viewBox="0 -960 960 960" width="42" xmlns="http://www.w3.org/2000/svg"><path d="M445-80q-29 0-56-12t-45-35L127-403l21-23q14-15 34.5-18.5T221-438l99 53v-365q0-12.75 8.675-21.375 8.676-8.625 21.5-8.625 12.825 0 21.325 8.625T380-750v465l-144-77 156 198q10 12 23.76 18 13.76 6 29.24 6h205q38 0 64-26t26-64v-170q0-25.5-17.25-42.75T680-460H460v-60h219.646q50.148 0 85.251 35T800-400v170q0 63-43.5 106.5T650-80H445ZM203-665q-11.074-18.754-17.037-40.492Q180-727.229 180-750.246 180-821 229.725-870.5T350-920q70.55 0 120.275 49.738Q520-820.524 520-749.956q0 22.956-5.963 44.614Q508.074-683.685 497-665l-52-30q7-12 11-26t4-29.478Q460-796 427.882-828q-32.117-32-78-32Q304-860 272-827.917 240-795.833 240-750q0 15 4 29t11 26l-52 30Zm285 335Z" fill="blue" stroke="blue"/></svg>
|
After Width: | Height: | Size: 781 B |
@ -17,4 +17,6 @@
|
||||
|
||||
<drawables>
|
||||
<bitmap id="ErrorIcon" filename="error.svg"/>
|
||||
<bitmap id="GroupTypeIcon" filename="group_type.svg"/>
|
||||
<bitmap id="TapTypeIcon" filename="tap_type.svg"/>
|
||||
</drawables>
|
1
resources-icons-46/group_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="46" viewBox="0 -960 960 960" width="46" xmlns="http://www.w3.org/2000/svg"><path d="M479.858-160Q460-160 446-174.142q-14-14.141-14-34Q432-228 446.142-242q14.141-14 34-14Q500-256 514-241.858q14 14.141 14 34Q528-188 513.858-174q-14.141 14-34 14Zm0-272Q460-432 446-446.142q-14-14.141-14-34Q432-500 446.142-514q14.141-14 34-14Q500-528 514-513.858q14 14.141 14 34Q528-460 513.858-446q-14.141 14-34 14Zm0-272Q460-704 446-718.142q-14-14.141-14-34Q432-772 446.142-786q14.141-14 34-14Q500-800 514-785.858q14 14.141 14 34Q528-732 513.858-718q-14.141 14-34 14Z" fill="darkgrey" stroke="darkgrey"/></svg>
|
After Width: | Height: | Size: 605 B |
1
resources-icons-46/tap_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="46" viewBox="0 -960 960 960" width="46" xmlns="http://www.w3.org/2000/svg"><path d="M445-80q-29 0-56-12t-45-35L127-403l21-23q14-15 34.5-18.5T221-438l99 53v-365q0-12.75 8.675-21.375 8.676-8.625 21.5-8.625 12.825 0 21.325 8.625T380-750v465l-144-77 156 198q10 12 23.76 18 13.76 6 29.24 6h205q38 0 64-26t26-64v-170q0-25.5-17.25-42.75T680-460H460v-60h219.646q50.148 0 85.251 35T800-400v170q0 63-43.5 106.5T650-80H445ZM203-665q-11.074-18.754-17.037-40.492Q180-727.229 180-750.246 180-821 229.725-870.5T350-920q70.55 0 120.275 49.738Q520-820.524 520-749.956q0 22.956-5.963 44.614Q508.074-683.685 497-665l-52-30q7-12 11-26t4-29.478Q460-796 427.882-828q-32.117-32-78-32Q304-860 272-827.917 240-795.833 240-750q0 15 4 29t11 26l-52 30Zm285 335Z" fill="blue" stroke="blue"/></svg>
|
After Width: | Height: | Size: 781 B |
@ -17,4 +17,6 @@
|
||||
|
||||
<drawables>
|
||||
<bitmap id="ErrorIcon" filename="error.svg"/>
|
||||
<bitmap id="GroupTypeIcon" filename="group_type.svg"/>
|
||||
<bitmap id="TapTypeIcon" filename="tap_type.svg"/>
|
||||
</drawables>
|
1
resources-icons-48/group_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M479.858-160Q460-160 446-174.142q-14-14.141-14-34Q432-228 446.142-242q14.141-14 34-14Q500-256 514-241.858q14 14.141 14 34Q528-188 513.858-174q-14.141 14-34 14Zm0-272Q460-432 446-446.142q-14-14.141-14-34Q432-500 446.142-514q14.141-14 34-14Q500-528 514-513.858q14 14.141 14 34Q528-460 513.858-446q-14.141 14-34 14Zm0-272Q460-704 446-718.142q-14-14.141-14-34Q432-772 446.142-786q14.141-14 34-14Q500-800 514-785.858q14 14.141 14 34Q528-732 513.858-718q-14.141 14-34 14Z" fill="darkgrey" stroke="darkgrey"/></svg>
|
After Width: | Height: | Size: 606 B |
1
resources-icons-48/tap_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M445-80q-29 0-56-12t-45-35L127-403l21-23q14-15 34.5-18.5T221-438l99 53v-365q0-12.75 8.675-21.375 8.676-8.625 21.5-8.625 12.825 0 21.325 8.625T380-750v465l-144-77 156 198q10 12 23.76 18 13.76 6 29.24 6h205q38 0 64-26t26-64v-170q0-25.5-17.25-42.75T680-460H460v-60h219.646q50.148 0 85.251 35T800-400v170q0 63-43.5 106.5T650-80H445ZM203-665q-11.074-18.754-17.037-40.492Q180-727.229 180-750.246 180-821 229.725-870.5T350-920q70.55 0 120.275 49.738Q520-820.524 520-749.956q0 22.956-5.963 44.614Q508.074-683.685 497-665l-52-30q7-12 11-26t4-29.478Q460-796 427.882-828q-32.117-32-78-32Q304-860 272-827.917 240-795.833 240-750q0 15 4 29t11 26l-52 30Zm285 335Z" fill="blue" stroke="blue"/></svg>
|
After Width: | Height: | Size: 782 B |
@ -17,4 +17,6 @@
|
||||
|
||||
<drawables>
|
||||
<bitmap id="ErrorIcon" filename="error.svg"/>
|
||||
<bitmap id="GroupTypeIcon" filename="group_type.svg"/>
|
||||
<bitmap id="TapTypeIcon" filename="tap_type.svg"/>
|
||||
</drawables>
|
1
resources-icons-53/group_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="53" viewBox="0 -960 960 960" width="53" xmlns="http://www.w3.org/2000/svg"><path d="M479.858-160Q460-160 446-174.142q-14-14.141-14-34Q432-228 446.142-242q14.141-14 34-14Q500-256 514-241.858q14 14.141 14 34Q528-188 513.858-174q-14.141 14-34 14Zm0-272Q460-432 446-446.142q-14-14.141-14-34Q432-500 446.142-514q14.141-14 34-14Q500-528 514-513.858q14 14.141 14 34Q528-460 513.858-446q-14.141 14-34 14Zm0-272Q460-704 446-718.142q-14-14.141-14-34Q432-772 446.142-786q14.141-14 34-14Q500-800 514-785.858q14 14.141 14 34Q528-732 513.858-718q-14.141 14-34 14Z" fill="darkgrey" stroke="darkgrey"/></svg>
|
After Width: | Height: | Size: 605 B |
1
resources-icons-53/tap_type.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg height="53" viewBox="0 -960 960 960" width="53" xmlns="http://www.w3.org/2000/svg"><path d="M445-80q-29 0-56-12t-45-35L127-403l21-23q14-15 34.5-18.5T221-438l99 53v-365q0-12.75 8.675-21.375 8.676-8.625 21.5-8.625 12.825 0 21.325 8.625T380-750v465l-144-77 156 198q10 12 23.76 18 13.76 6 29.24 6h205q38 0 64-26t26-64v-170q0-25.5-17.25-42.75T680-460H460v-60h219.646q50.148 0 85.251 35T800-400v170q0 63-43.5 106.5T650-80H445ZM203-665q-11.074-18.754-17.037-40.492Q180-727.229 180-750.246 180-821 229.725-870.5T350-920q70.55 0 120.275 49.738Q520-820.524 520-749.956q0 22.956-5.963 44.614Q508.074-683.685 497-665l-52-30q7-12 11-26t4-29.478Q460-796 427.882-828q-32.117-32-78-32Q304-860 272-827.917 240-795.833 240-750q0 15 4 29t11 26l-52 30Zm285 335Z" fill="blue" stroke="blue"/></svg>
|
After Width: | Height: | Size: 781 B |
@ -23,4 +23,8 @@
|
||||
|
||||
<!-- Best be a public URL in order to work away from your home LAN and have a trusted HTTPS certificate -->
|
||||
<property id="config_url" type="string"></property>
|
||||
|
||||
<property id="types_representation" type="boolean"></property>
|
||||
|
||||
<property id="menu_alignment" type="boolean"></property>
|
||||
</properties>
|
||||
|
@ -42,4 +42,22 @@
|
||||
type="alphaNumeric"
|
||||
/>
|
||||
</setting>
|
||||
|
||||
<setting
|
||||
propertyKey="@Properties.types_representation"
|
||||
title="Representing types with icons (off) or with labels (on)"
|
||||
>
|
||||
<settingConfig
|
||||
type="boolean"
|
||||
/>
|
||||
</setting>
|
||||
|
||||
<setting
|
||||
propertyKey="@Properties.menu_alignment"
|
||||
title="Left (off) or Right (on) Menu Alignment"
|
||||
>
|
||||
<settingConfig
|
||||
type="boolean"
|
||||
/>
|
||||
</setting>
|
||||
</settings>
|
||||
|
@ -30,12 +30,12 @@ using Toybox.Timer;
|
||||
const bRadius = 10;
|
||||
|
||||
class Alert extends WatchUi.View {
|
||||
hidden var mTimer;
|
||||
hidden var mTimeout;
|
||||
hidden var mText;
|
||||
hidden var mFont;
|
||||
hidden var mFgcolor;
|
||||
hidden var mBgcolor;
|
||||
private var mTimer;
|
||||
private var mTimeout;
|
||||
private var mText;
|
||||
private var mFont;
|
||||
private var mFgcolor;
|
||||
private var mBgcolor;
|
||||
|
||||
function initialize(params as Lang.Dictionary) {
|
||||
View.initialize();
|
||||
|
@ -26,14 +26,14 @@ using Toybox.WatchUi;
|
||||
using Toybox.Communications;
|
||||
|
||||
class ErrorView extends ScalableView {
|
||||
hidden const cSettings as Lang.Dictionary = {
|
||||
private const cSettings as Lang.Dictionary = {
|
||||
:errorIconMargin => 7f
|
||||
};
|
||||
// Vertical spacing between the top of the face and the error icon
|
||||
hidden var mErrorIconMargin;
|
||||
hidden var mText as Lang.String;
|
||||
hidden var mErrorIcon;
|
||||
hidden var mTextArea;
|
||||
private var mErrorIconMargin;
|
||||
private var mText as Lang.String;
|
||||
private var mErrorIcon;
|
||||
private var mTextArea;
|
||||
|
||||
function initialize(text as Lang.String) {
|
||||
ScalableView.initialize();
|
||||
|
@ -24,20 +24,20 @@ using Toybox.WatchUi;
|
||||
using Toybox.Application.Properties;
|
||||
|
||||
class HomeAssistantApp extends Application.AppBase {
|
||||
hidden var mHaMenu;
|
||||
hidden var strNoApiKey as Lang.String;
|
||||
hidden var strNoApiUrl as Lang.String;
|
||||
hidden var strNoConfigUrl as Lang.String;
|
||||
hidden var strNoPhone as Lang.String;
|
||||
hidden var strNoInternet as Lang.String;
|
||||
hidden var strNoResponse as Lang.String;
|
||||
hidden var strNoMenu as Lang.String;
|
||||
hidden var strApiFlood as Lang.String;
|
||||
hidden var strConfigUrlNotFound as Lang.String;
|
||||
hidden var strUnhandledHttpErr as Lang.String;
|
||||
hidden var strTrailingSlashErr as Lang.String;
|
||||
hidden var mItemsToUpdate; // Array initialised by onReturnFetchMenuConfig()
|
||||
hidden var mNextItemToUpdate = 0; // Index into the above array
|
||||
private var mHaMenu;
|
||||
private var strNoApiKey as Lang.String;
|
||||
private var strNoApiUrl as Lang.String;
|
||||
private var strNoConfigUrl as Lang.String;
|
||||
private var strNoPhone as Lang.String;
|
||||
private var strNoInternet as Lang.String;
|
||||
private var strNoResponse as Lang.String;
|
||||
private var strNoMenu as Lang.String;
|
||||
private var strApiFlood as Lang.String;
|
||||
private var strConfigUrlNotFound as Lang.String;
|
||||
private var strUnhandledHttpErr as Lang.String;
|
||||
private var strTrailingSlashErr as Lang.String;
|
||||
private var mItemsToUpdate; // Array initialised by onReturnFetchMenuConfig()
|
||||
private var mNextItemToUpdate = 0; // Index into the above array
|
||||
|
||||
function initialize() {
|
||||
AppBase.initialize();
|
||||
@ -67,22 +67,22 @@ class HomeAssistantApp extends Application.AppBase {
|
||||
|
||||
if ((Properties.getValue("api_key") as Lang.String).length() == 0) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantMenuItem execScript(): No API key in the application settings.");
|
||||
System.println("HomeAssistantApp getInitialView(): No API key in the application settings.");
|
||||
}
|
||||
return [new ErrorView(strNoApiKey + "."), new ErrorDelegate()] as Lang.Array<WatchUi.Views or WatchUi.InputDelegates>;
|
||||
} else if (api_url.length() == 0) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantMenuItem execScript(): No API URL in the application settings.");
|
||||
System.println("HomeAssistantApp getInitialView(): No API URL in the application settings.");
|
||||
}
|
||||
return [new ErrorView(strNoApiUrl + "."), new ErrorDelegate()] as Lang.Array<WatchUi.Views or WatchUi.InputDelegates>;
|
||||
} else if (api_url.substring(-1, api_url.length()).equals("/")) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantMenuItem execScript(): API URL must not have a trailing slash '/'.");
|
||||
System.println("HomeAssistantApp getInitialView(): API URL must not have a trailing slash '/'.");
|
||||
}
|
||||
return [new ErrorView(strTrailingSlashErr + "."), new ErrorDelegate()] as Lang.Array<WatchUi.Views or WatchUi.InputDelegates>;
|
||||
} else if ((Properties.getValue("config_url") as Lang.String).length() == 0) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantMenuItem execScript(): No configuration URL in the application settings.");
|
||||
System.println("HomeAssistantApp getInitialView(): No configuration URL in the application settings.");
|
||||
}
|
||||
return [new ErrorView(strNoConfigUrl + "."), new ErrorDelegate()] as Lang.Array<WatchUi.Views or WatchUi.InputDelegates>;
|
||||
} else if (! System.getDeviceSettings().phoneConnected) {
|
||||
|
58
source/HomeAssistantIconMenuItem.mc
Normal file
@ -0,0 +1,58 @@
|
||||
//-----------------------------------------------------------------------------------
|
||||
//
|
||||
// Distributed under MIT Licence
|
||||
// See https://github.com/house-of-abbey/GarminHomeAssistant/blob/main/LICENSE.
|
||||
//
|
||||
//-----------------------------------------------------------------------------------
|
||||
//
|
||||
// GarminHomeAssistant is a Garmin IQ application written in Monkey C and routinely
|
||||
// tested on a Venu 2 device. The source code is provided at:
|
||||
// https://github.com/house-of-abbey/GarminHomeAssistant.
|
||||
//
|
||||
// P A Abbey & J D Abbey, 31 October 2023
|
||||
//
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
// Menu button that triggers a service.
|
||||
//
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
||||
using Toybox.Lang;
|
||||
using Toybox.WatchUi;
|
||||
using Toybox.Graphics;
|
||||
using Toybox.Application.Properties;
|
||||
|
||||
class HomeAssistantIconMenuItem extends WatchUi.IconMenuItem {
|
||||
private var mHomeAssistantService as HomeAssistantService;
|
||||
private var mService as Lang.String;
|
||||
|
||||
function initialize(
|
||||
label as Lang.String or Lang.Symbol,
|
||||
subLabel as Lang.String or Lang.Symbol or Null,
|
||||
identifier as Lang.Object or Null,
|
||||
service as Lang.String or Null,
|
||||
icon as Graphics.BitmapType or WatchUi.Drawable,
|
||||
options as {
|
||||
:alignment as WatchUi.MenuItem.Alignment
|
||||
} or Null,
|
||||
haService as HomeAssistantService
|
||||
) {
|
||||
WatchUi.IconMenuItem.initialize(
|
||||
label,
|
||||
subLabel,
|
||||
identifier,
|
||||
icon,
|
||||
options
|
||||
);
|
||||
|
||||
mHomeAssistantService = haService;
|
||||
mIdentifier = identifier;
|
||||
mService = service;
|
||||
}
|
||||
|
||||
function callService() as Void {
|
||||
mHomeAssistantService.call(mIdentifier as Lang.String, mService);
|
||||
}
|
||||
|
||||
}
|
@ -24,14 +24,8 @@ using Toybox.Graphics;
|
||||
using Toybox.Application.Properties;
|
||||
|
||||
class HomeAssistantMenuItem extends WatchUi.MenuItem {
|
||||
hidden var mApiKey as Lang.String;
|
||||
hidden var strNoPhone as Lang.String;
|
||||
hidden var strNoInternet as Lang.String;
|
||||
hidden var strNoResponse as Lang.String;
|
||||
hidden var strApiFlood as Lang.String;
|
||||
hidden var strApiUrlNotFound as Lang.String;
|
||||
hidden var strUnhandledHttpErr as Lang.String;
|
||||
hidden var mService as Lang.String;
|
||||
private var mHomeAssistantService as HomeAssistantService;
|
||||
private var mService as Lang.String;
|
||||
|
||||
function initialize(
|
||||
label as Lang.String or Lang.Symbol,
|
||||
@ -41,142 +35,22 @@ class HomeAssistantMenuItem extends WatchUi.MenuItem {
|
||||
options as {
|
||||
:alignment as WatchUi.MenuItem.Alignment,
|
||||
:icon as Graphics.BitmapType or WatchUi.Drawable or Lang.Symbol
|
||||
} or Null
|
||||
} or Null,
|
||||
haService as HomeAssistantService
|
||||
) {
|
||||
strNoPhone = WatchUi.loadResource($.Rez.Strings.NoPhone);
|
||||
strNoInternet = WatchUi.loadResource($.Rez.Strings.NoInternet);
|
||||
strNoResponse = WatchUi.loadResource($.Rez.Strings.NoResponse);
|
||||
strApiFlood = WatchUi.loadResource($.Rez.Strings.ApiFlood);
|
||||
strApiUrlNotFound = WatchUi.loadResource($.Rez.Strings.ApiUrlNotFound);
|
||||
strUnhandledHttpErr = WatchUi.loadResource($.Rez.Strings.UnhandledHttpErr);
|
||||
mApiKey = Properties.getValue("api_key");
|
||||
mService = service;
|
||||
WatchUi.MenuItem.initialize(
|
||||
label,
|
||||
subLabel,
|
||||
identifier,
|
||||
options
|
||||
);
|
||||
|
||||
mHomeAssistantService = haService;
|
||||
mService = service;
|
||||
}
|
||||
|
||||
// Callback function after completing the POST request to call a script.
|
||||
//
|
||||
function onReturnExecScript(responseCode as Lang.Number, data as Null or Lang.Dictionary or Lang.String) as Void {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantMenuItem onReturnExecScript() Response Code: " + responseCode);
|
||||
System.println("HomeAssistantMenuItem onReturnExecScript() Response Data: " + data);
|
||||
}
|
||||
if (responseCode == Communications.BLE_HOST_TIMEOUT || responseCode == Communications.BLE_CONNECTION_UNAVAILABLE) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantMenuItem onReturnExecScript() Response Code: BLE_HOST_TIMEOUT or BLE_CONNECTION_UNAVAILABLE, Bluetooth connection severed.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strNoPhone + "."), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
} else if (responseCode == Communications.BLE_QUEUE_FULL) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantMenuItem onReturnExecScript() Response Code: BLE_QUEUE_FULL, API calls too rapid.");
|
||||
}
|
||||
if (!(WatchUi.getCurrentView()[0] instanceof ErrorView)) {
|
||||
// Avoid pushing multiple ErrorViews
|
||||
WatchUi.pushView(new ErrorView(strApiFlood), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
}
|
||||
} else if (responseCode == Communications.NETWORK_REQUEST_TIMED_OUT) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantMenuItem onReturnExecScript() Response Code: NETWORK_REQUEST_TIMED_OUT, check Internet connection.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strNoResponse), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
} else if (responseCode == 404) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantMenuItem onReturnExecScript() Response Code: 404, page not found. Check API URL setting.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strApiUrlNotFound), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
} else if (responseCode == 200) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantMenuItem onReturnExecScript(): Service executed.");
|
||||
}
|
||||
var d = data as Lang.Array;
|
||||
var toast = "Executed";
|
||||
for(var i = 0; i < d.size(); i++) {
|
||||
if ((d[i].get("entity_id") as Lang.String).equals(mIdentifier)) {
|
||||
toast = (d[i].get("attributes") as Lang.Dictionary).get("friendly_name") as Lang.String;
|
||||
}
|
||||
}
|
||||
if (WatchUi has :showToast) {
|
||||
WatchUi.showToast(toast, null);
|
||||
} else {
|
||||
new Alert({
|
||||
:timeout => Globals.scAlertTimeout,
|
||||
:font => Graphics.FONT_MEDIUM,
|
||||
:text => toast,
|
||||
:fgcolor => Graphics.COLOR_WHITE,
|
||||
:bgcolor => Graphics.COLOR_BLACK
|
||||
}).pushView(WatchUi.SLIDE_IMMEDIATE);
|
||||
}
|
||||
} else {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantMenuItem onReturnExecScript(): Unhandled HTTP response code = " + responseCode);
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strUnhandledHttpErr + responseCode ), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
}
|
||||
}
|
||||
|
||||
function execScript() as Void {
|
||||
var options = {
|
||||
:method => Communications.HTTP_REQUEST_METHOD_POST,
|
||||
:headers => {
|
||||
"Content-Type" => Communications.REQUEST_CONTENT_TYPE_JSON,
|
||||
"Authorization" => "Bearer " + mApiKey
|
||||
},
|
||||
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON
|
||||
};
|
||||
if (! System.getDeviceSettings().phoneConnected) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantMenuItem execScript(): No Phone connection, skipping API call.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strNoPhone + "."), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
} else if (! System.getDeviceSettings().connectionAvailable) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantMenuItem execScript(): No Internet connection, skipping API call.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strNoInternet + "."), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
} else {
|
||||
// Updated SDK and got a new error
|
||||
// ERROR: venu: Cannot find symbol ':substring' on type 'PolyType<Null or $.Toybox.Lang.Object>'.
|
||||
var id = mIdentifier as Lang.String;
|
||||
if (mService == null) {
|
||||
var url = (Properties.getValue("api_url") as Lang.String) + "/services/" + id.substring(0, id.find(".")) + "/" + id.substring(id.find(".")+1, null);
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantMenuItem execScript() URL=" + url);
|
||||
System.println("HomeAssistantMenuItem execScript() mIdentifier=" + mIdentifier);
|
||||
}
|
||||
Communications.makeWebRequest(
|
||||
url,
|
||||
null,
|
||||
options,
|
||||
method(:onReturnExecScript)
|
||||
);
|
||||
} else {
|
||||
var url = (Properties.getValue("api_url") as Lang.String) + "/services/" + mService.substring(0, mService.find(".")) + "/" + mService.substring(mService.find(".")+1, null);
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantMenuItem execScript() URL=" + url);
|
||||
System.println("HomeAssistantMenuItem execScript() mService=" + mService);
|
||||
}
|
||||
Communications.makeWebRequest(
|
||||
url,
|
||||
{
|
||||
"entity_id" => id
|
||||
},
|
||||
options,
|
||||
method(:onReturnExecScript)
|
||||
);
|
||||
}
|
||||
if (Attention has :vibrate) {
|
||||
Attention.vibrate([
|
||||
new Attention.VibeProfile(50, 100), // On for 100ms
|
||||
new Attention.VibeProfile( 0, 100), // Off for 100ms
|
||||
new Attention.VibeProfile(50, 100) // On for 100ms
|
||||
]);
|
||||
}
|
||||
}
|
||||
function callService() as Void {
|
||||
mHomeAssistantService.call(mIdentifier as Lang.String, mService);
|
||||
}
|
||||
|
||||
}
|
||||
|
122
source/HomeAssistantMenuItemFactory.mc
Normal file
@ -0,0 +1,122 @@
|
||||
//-----------------------------------------------------------------------------------
|
||||
//
|
||||
// Distributed under MIT Licence
|
||||
// See https://github.com/house-of-abbey/GarminHomeAssistant/blob/main/LICENSE.
|
||||
//
|
||||
//-----------------------------------------------------------------------------------
|
||||
//
|
||||
// GarminHomeAssistant is a Garmin IQ application written in Monkey C and routinely
|
||||
// tested on a Venu 2 device. The source code is provided at:
|
||||
// https://github.com/house-of-abbey/GarminHomeAssistant.
|
||||
//
|
||||
// P A Abbey & J D Abbey & SomeoneOnEarth, 17 November 2023
|
||||
//
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
// MenuItems Factory.
|
||||
//
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
||||
using Toybox.Application;
|
||||
using Toybox.Lang;
|
||||
using Toybox.WatchUi;
|
||||
|
||||
class HomeAssistantMenuItemFactory {
|
||||
private var mMenuItemOptions as Lang.Dictionary;
|
||||
private var mLabelToggle as Lang.Dictionary;
|
||||
private var strMenuItemTap as Lang.String;
|
||||
private var bRepresentTypesWithLabels as Lang.Boolean;
|
||||
private var mTapTypeIcon as WatchUi.Bitmap;
|
||||
private var mGroupTypeIcon as WatchUi.Bitmap;
|
||||
private var mHomeAssistantService as HomeAssistantService;
|
||||
|
||||
private static var instance;
|
||||
|
||||
private function initialize() {
|
||||
mLabelToggle = {
|
||||
:enabled => WatchUi.loadResource($.Rez.Strings.MenuItemOn) as Lang.String,
|
||||
:disabled => WatchUi.loadResource($.Rez.Strings.MenuItemOff) as Lang.String
|
||||
};
|
||||
bRepresentTypesWithLabels = Application.Properties.getValue("types_representation") as Lang.Boolean;
|
||||
|
||||
var menuItemAlignment = Application.Properties.getValue("menu_alignment") as Lang.Boolean;
|
||||
if(menuItemAlignment){
|
||||
mMenuItemOptions = {
|
||||
:alignment => WatchUi.MenuItem.MENU_ITEM_LABEL_ALIGN_RIGHT
|
||||
};
|
||||
} else {
|
||||
mMenuItemOptions = {
|
||||
:alignment => WatchUi.MenuItem.MENU_ITEM_LABEL_ALIGN_LEFT
|
||||
};
|
||||
}
|
||||
|
||||
strMenuItemTap = WatchUi.loadResource($.Rez.Strings.MenuItemTap);
|
||||
mTapTypeIcon = new WatchUi.Bitmap({
|
||||
:rezId => $.Rez.Drawables.TapTypeIcon,
|
||||
:locX => WatchUi.LAYOUT_HALIGN_CENTER,
|
||||
:locY => WatchUi.LAYOUT_VALIGN_CENTER
|
||||
});
|
||||
|
||||
mGroupTypeIcon = new WatchUi.Bitmap({
|
||||
:rezId => $.Rez.Drawables.GroupTypeIcon,
|
||||
:locX => WatchUi.LAYOUT_HALIGN_CENTER,
|
||||
:locY => WatchUi.LAYOUT_VALIGN_CENTER
|
||||
});
|
||||
mHomeAssistantService = new HomeAssistantService();
|
||||
}
|
||||
|
||||
static function create() as HomeAssistantMenuItemFactory {
|
||||
if (instance == null) {
|
||||
instance = new HomeAssistantMenuItemFactory();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
function toggle(label as Lang.String or Lang.Symbol, identifier as Lang.Object or Null) as WatchUi.MenuItem {
|
||||
var subLabel = null;
|
||||
|
||||
if (bRepresentTypesWithLabels == true){
|
||||
subLabel=mLabelToggle;
|
||||
}
|
||||
|
||||
return new HomeAssistantToggleMenuItem(
|
||||
label,
|
||||
subLabel,
|
||||
identifier,
|
||||
false,
|
||||
mMenuItemOptions
|
||||
);
|
||||
}
|
||||
|
||||
function tap(label as Lang.String or Lang.Symbol, identifier as Lang.Object or Null, service as Lang.String or Null) as WatchUi.MenuItem {
|
||||
if (bRepresentTypesWithLabels) {
|
||||
return new HomeAssistantMenuItem(
|
||||
label,
|
||||
strMenuItemTap,
|
||||
identifier,
|
||||
service,
|
||||
mMenuItemOptions,
|
||||
mHomeAssistantService
|
||||
);
|
||||
} else {
|
||||
return new HomeAssistantIconMenuItem(
|
||||
label,
|
||||
null,
|
||||
identifier,
|
||||
service,
|
||||
mTapTypeIcon,
|
||||
mMenuItemOptions,
|
||||
mHomeAssistantService
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function group(definition as Lang.Dictionary) as WatchUi.MenuItem {
|
||||
if (bRepresentTypesWithLabels) {
|
||||
return new HomeAssistantViewMenuItem(definition);
|
||||
} else {
|
||||
return new HomeAssistantViewIconMenuItem(definition, mGroupTypeIcon, mMenuItemOptions);
|
||||
}
|
||||
}
|
||||
}
|
150
source/HomeAssistantService.mc
Normal file
@ -0,0 +1,150 @@
|
||||
//-----------------------------------------------------------------------------------
|
||||
//
|
||||
// Distributed under MIT Licence
|
||||
// See https://github.com/house-of-abbey/GarminHomeAssistant/blob/main/LICENSE.
|
||||
//
|
||||
//-----------------------------------------------------------------------------------
|
||||
//
|
||||
// GarminHomeAssistant is a Garmin IQ application written in Monkey C and routinely
|
||||
// tested on a Venu 2 device. The source code is provided at:
|
||||
// https://github.com/house-of-abbey/GarminHomeAssistant.
|
||||
//
|
||||
// P A Abbey & J D Abbey & SomeoneOnEarth, 19 November 2023
|
||||
//
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
// Calling a Home Assistant Service.
|
||||
//
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
||||
using Toybox.Lang;
|
||||
using Toybox.WatchUi;
|
||||
using Toybox.Graphics;
|
||||
using Toybox.Application.Properties;
|
||||
|
||||
class HomeAssistantService {
|
||||
private var mApiKey as Lang.String;
|
||||
private var strNoPhone as Lang.String;
|
||||
private var strNoInternet as Lang.String;
|
||||
private var strNoResponse as Lang.String;
|
||||
private var strApiFlood as Lang.String;
|
||||
private var strApiUrlNotFound as Lang.String;
|
||||
private var strUnhandledHttpErr as Lang.String;
|
||||
|
||||
function initialize() {
|
||||
strNoPhone = WatchUi.loadResource($.Rez.Strings.NoPhone);
|
||||
strNoInternet = WatchUi.loadResource($.Rez.Strings.NoInternet);
|
||||
strNoResponse = WatchUi.loadResource($.Rez.Strings.NoResponse);
|
||||
strApiFlood = WatchUi.loadResource($.Rez.Strings.ApiFlood);
|
||||
strApiUrlNotFound = WatchUi.loadResource($.Rez.Strings.ApiUrlNotFound);
|
||||
strUnhandledHttpErr = WatchUi.loadResource($.Rez.Strings.UnhandledHttpErr);
|
||||
mApiKey = Properties.getValue("api_key");
|
||||
}
|
||||
|
||||
// Callback function after completing the POST request to call a service.
|
||||
//
|
||||
function onReturnCall(responseCode as Lang.Number, data as Null or Lang.Dictionary or Lang.String, context as Lang.Object) as Void {
|
||||
var identifier = context as Lang.String;
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantService onReturnCall() Response Code: " + responseCode);
|
||||
System.println("HomeAssistantService onReturnCall() Response Data: " + data);
|
||||
}
|
||||
if (responseCode == Communications.BLE_HOST_TIMEOUT || responseCode == Communications.BLE_CONNECTION_UNAVAILABLE) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantService onReturnCall() Response Code: BLE_HOST_TIMEOUT or BLE_CONNECTION_UNAVAILABLE, Bluetooth connection severed.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strNoPhone + "."), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
} else if (responseCode == Communications.BLE_QUEUE_FULL) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantService onReturnCall() Response Code: BLE_QUEUE_FULL, API calls too rapid.");
|
||||
}
|
||||
if (!(WatchUi.getCurrentView()[0] instanceof ErrorView)) {
|
||||
// Avoid pushing multiple ErrorViews
|
||||
WatchUi.pushView(new ErrorView(strApiFlood), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
}
|
||||
} else if (responseCode == Communications.NETWORK_REQUEST_TIMED_OUT) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantService onReturnCall() Response Code: NETWORK_REQUEST_TIMED_OUT, check Internet connection.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strNoResponse), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
} else if (responseCode == 404) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantService onReturnCall() Response Code: 404, page not found. Check API URL setting.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strApiUrlNotFound), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
} else if (responseCode == 200) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantService onReturnCall(): Service executed.");
|
||||
}
|
||||
var d = data as Lang.Array;
|
||||
var toast = "Executed";
|
||||
for(var i = 0; i < d.size(); i++) {
|
||||
if ((d[i].get("entity_id") as Lang.String).equals(identifier)) {
|
||||
toast = (d[i].get("attributes") as Lang.Dictionary).get("friendly_name") as Lang.String;
|
||||
}
|
||||
}
|
||||
if (WatchUi has :showToast) {
|
||||
WatchUi.showToast(toast, null);
|
||||
} else {
|
||||
new Alert({
|
||||
:timeout => Globals.scAlertTimeout,
|
||||
:font => Graphics.FONT_MEDIUM,
|
||||
:text => toast,
|
||||
:fgcolor => Graphics.COLOR_WHITE,
|
||||
:bgcolor => Graphics.COLOR_BLACK
|
||||
}).pushView(WatchUi.SLIDE_IMMEDIATE);
|
||||
}
|
||||
} else {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantService onReturnCall(): Unhandled HTTP response code = " + responseCode);
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strUnhandledHttpErr + responseCode ), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
}
|
||||
}
|
||||
|
||||
function call(identifier as Lang.String, service as Lang.String) as Void {
|
||||
var options = {
|
||||
:method => Communications.HTTP_REQUEST_METHOD_POST,
|
||||
:headers => {
|
||||
"Content-Type" => Communications.REQUEST_CONTENT_TYPE_JSON,
|
||||
"Authorization" => "Bearer " + mApiKey
|
||||
},
|
||||
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON,
|
||||
:context => identifier
|
||||
};
|
||||
if (! System.getDeviceSettings().phoneConnected) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantService call(): No Phone connection, skipping API call.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strNoPhone + "."), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
} else if (! System.getDeviceSettings().connectionAvailable) {
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantService call(): No Internet connection, skipping API call.");
|
||||
}
|
||||
WatchUi.pushView(new ErrorView(strNoInternet + "."), new ErrorDelegate(), WatchUi.SLIDE_UP);
|
||||
} else {
|
||||
var url = (Properties.getValue("api_url") as Lang.String) + "/services/" + service.substring(0, service.find(".")) + "/" + service.substring(service.find(".")+1, null);
|
||||
if (Globals.scDebug) {
|
||||
System.println("HomeAssistantService call() URL=" + url);
|
||||
System.println("HomeAssistantService call() service=" + service);
|
||||
}
|
||||
Communications.makeWebRequest(
|
||||
url,
|
||||
{
|
||||
"entity_id" => identifier
|
||||
},
|
||||
options,
|
||||
method(:onReturnCall)
|
||||
);
|
||||
if (Attention has :vibrate) {
|
||||
Attention.vibrate([
|
||||
new Attention.VibeProfile(50, 100), // On for 100ms
|
||||
new Attention.VibeProfile( 0, 100), // Off for 100ms
|
||||
new Attention.VibeProfile(50, 100) // On for 100ms
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -25,23 +25,23 @@ using Toybox.Application.Properties;
|
||||
using Toybox.Timer;
|
||||
|
||||
class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
|
||||
hidden var mApiKey as Lang.String;
|
||||
hidden var strNoPhone as Lang.String;
|
||||
hidden var strNoInternet as Lang.String;
|
||||
hidden var strNoResponse as Lang.String;
|
||||
hidden var strApiFlood as Lang.String;
|
||||
hidden var strApiUrlNotFound as Lang.String;
|
||||
hidden var strUnhandledHttpErr as Lang.String;
|
||||
private var mApiKey as Lang.String;
|
||||
private var strNoPhone as Lang.String;
|
||||
private var strNoInternet as Lang.String;
|
||||
private var strNoResponse as Lang.String;
|
||||
private var strApiFlood as Lang.String;
|
||||
private var strApiUrlNotFound as Lang.String;
|
||||
private var strUnhandledHttpErr as Lang.String;
|
||||
|
||||
function initialize(
|
||||
label as Lang.String or Lang.Symbol,
|
||||
subLabel as Lang.String or Lang.Symbol or {
|
||||
label as Lang.String or Lang.Symbol,
|
||||
subLabel as Lang.String or Lang.Symbol or {
|
||||
:enabled as Lang.String or Lang.Symbol or Null,
|
||||
:disabled as Lang.String or Lang.Symbol or Null
|
||||
} or Null,
|
||||
identifier,
|
||||
enabled as Lang.Boolean,
|
||||
options as {
|
||||
enabled as Lang.Boolean,
|
||||
options as {
|
||||
:alignment as WatchUi.MenuItem.Alignment,
|
||||
:icon as Graphics.BitmapType or WatchUi.Drawable or Lang.Symbol
|
||||
} or Null
|
||||
@ -131,7 +131,6 @@ class HomeAssistantToggleMenuItem extends WatchUi.ToggleMenuItem {
|
||||
if (keepUpdating) {
|
||||
// Now this feels very "closely coupled" to the application, but it is the most reliable method instead of using a timer.
|
||||
getApp().updateNextMenuItem();
|
||||
System.println("HomeAssistantToggleMenuItem onReturnGetState(): Updated " + mIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,15 +18,15 @@
|
||||
//
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
||||
using Toybox.Application;
|
||||
using Toybox.Lang;
|
||||
using Toybox.Graphics;
|
||||
using Toybox.WatchUi;
|
||||
|
||||
class HomeAssistantView extends WatchUi.Menu2 {
|
||||
hidden var strMenuItemTap as Lang.String;
|
||||
// List of items that need to have their status updated periodically
|
||||
hidden var mListToggleItems = [];
|
||||
hidden var mListMenuItems = [];
|
||||
private var mListToggleItems = [];
|
||||
private var mListMenuItems = [];
|
||||
|
||||
function initialize(
|
||||
definition as Lang.Dictionary,
|
||||
@ -36,11 +36,6 @@ class HomeAssistantView extends WatchUi.Menu2 {
|
||||
:theme as WatchUi.MenuTheme or Null
|
||||
} or Null
|
||||
) {
|
||||
strMenuItemTap = WatchUi.loadResource($.Rez.Strings.MenuItemTap);
|
||||
var toggle_obj = {
|
||||
:enabled => WatchUi.loadResource($.Rez.Strings.MenuItemOn) as Lang.String,
|
||||
:disabled => WatchUi.loadResource($.Rez.Strings.MenuItemOff) as Lang.String
|
||||
};
|
||||
|
||||
if (options == null) {
|
||||
options = {
|
||||
@ -59,27 +54,13 @@ class HomeAssistantView extends WatchUi.Menu2 {
|
||||
var service = items[i].get("service") as Lang.String or Null;
|
||||
if (type != null && name != null && entity != null) {
|
||||
if (type.equals("toggle")) {
|
||||
var item = new HomeAssistantToggleMenuItem(
|
||||
name,
|
||||
toggle_obj,
|
||||
entity,
|
||||
false,
|
||||
null
|
||||
);
|
||||
var item = HomeAssistantMenuItemFactory.create().toggle(name, entity);
|
||||
addItem(item);
|
||||
mListToggleItems.add(item);
|
||||
} else if (type.equals("tap") && service != null) {
|
||||
addItem(
|
||||
new HomeAssistantMenuItem(
|
||||
name,
|
||||
strMenuItemTap,
|
||||
entity,
|
||||
service,
|
||||
null
|
||||
)
|
||||
);
|
||||
addItem( HomeAssistantMenuItemFactory.create().tap(name, entity, service));
|
||||
} else if (type.equals("group")) {
|
||||
var item = new HomeAssistantViewMenuItem(items[i]);
|
||||
var item = HomeAssistantMenuItemFactory.create().group(items[i]);
|
||||
addItem(item);
|
||||
mListMenuItems.add(item);
|
||||
}
|
||||
@ -89,10 +70,15 @@ class HomeAssistantView extends WatchUi.Menu2 {
|
||||
|
||||
function getItemsToUpdate() as Lang.Array<HomeAssistantToggleMenuItem> {
|
||||
var fullList = [];
|
||||
var lmi = mListMenuItems as Lang.Array<HomeAssistantViewMenuItem>;
|
||||
for(var i = 0; i < lmi.size(); i++) {
|
||||
fullList.addAll(lmi[i].getMenuView().getItemsToUpdate());
|
||||
|
||||
var lmi = mListMenuItems as Lang.Array<WatchUi.MenuItem>;
|
||||
for(var i = 0; i < mListMenuItems.size(); i++) {
|
||||
var item = lmi[i];
|
||||
if (item instanceof HomeAssistantViewMenuItem || item instanceof HomeAssistantViewIconMenuItem) {
|
||||
fullList.addAll(item.getMenuView().getItemsToUpdate());
|
||||
}
|
||||
}
|
||||
|
||||
return fullList.addAll(mListToggleItems);
|
||||
}
|
||||
|
||||
@ -124,7 +110,13 @@ class HomeAssistantViewDelegate extends WatchUi.Menu2InputDelegate {
|
||||
if (Globals.scDebug) {
|
||||
System.println(haItem.getLabel() + " " + haItem.getId());
|
||||
}
|
||||
haItem.execScript();
|
||||
haItem.callService();
|
||||
} else if (item instanceof HomeAssistantIconMenuItem) {
|
||||
var haItem = item as HomeAssistantIconMenuItem;
|
||||
if (Globals.scDebug) {
|
||||
System.println(haItem.getLabel() + " " + haItem.getId());
|
||||
}
|
||||
haItem.callService();
|
||||
} else if (item instanceof HomeAssistantViewMenuItem) {
|
||||
var haMenuItem = item as HomeAssistantViewMenuItem;
|
||||
if (Globals.scDebug) {
|
||||
@ -132,6 +124,13 @@ class HomeAssistantViewDelegate extends WatchUi.Menu2InputDelegate {
|
||||
}
|
||||
// No delegate state to be amended, so re-use 'self'.
|
||||
WatchUi.pushView(haMenuItem.getMenuView(), self, WatchUi.SLIDE_LEFT);
|
||||
} else if (item instanceof HomeAssistantViewIconMenuItem) {
|
||||
var haMenuItem = item as HomeAssistantViewIconMenuItem;
|
||||
if (Globals.scDebug) {
|
||||
System.println("IconMenu: " + haMenuItem.getLabel() + " " + haMenuItem.getId());
|
||||
}
|
||||
// No delegate state to be amended, so re-use 'self'.
|
||||
WatchUi.pushView(haMenuItem.getMenuView(), self, WatchUi.SLIDE_LEFT);
|
||||
} else {
|
||||
if (Globals.scDebug) {
|
||||
System.println(item.getLabel() + " " + item.getId());
|
||||
|
48
source/HomeAssistantViewIconMenuItem.mc
Normal file
@ -0,0 +1,48 @@
|
||||
//-----------------------------------------------------------------------------------
|
||||
//
|
||||
// Distributed under MIT Licence
|
||||
// See https://github.com/house-of-abbey/GarminHomeAssistant/blob/main/LICENSE.
|
||||
//
|
||||
//-----------------------------------------------------------------------------------
|
||||
//
|
||||
// GarminHomeAssistant is a Garmin IQ application written in Monkey C and routinely
|
||||
// tested on a Venu 2 device. The source code is provided at:
|
||||
// https://github.com/house-of-abbey/GarminHomeAssistant.
|
||||
//
|
||||
// P A Abbey & J D Abbey & SomeoneOnEarth, 16 November 2023
|
||||
//
|
||||
//
|
||||
// Description:
|
||||
//
|
||||
// Menu button with an icon that opens a sub-menu.
|
||||
//
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
||||
using Toybox.Lang;
|
||||
using Toybox.WatchUi;
|
||||
|
||||
class HomeAssistantViewIconMenuItem extends WatchUi.IconMenuItem {
|
||||
private var mMenu as HomeAssistantView;
|
||||
|
||||
function initialize(definition as Lang.Dictionary, icon as WatchUi.Drawable, options as {
|
||||
:alignment as WatchUi.MenuItem.Alignment
|
||||
} or Null) {
|
||||
var label = definition.get("name") as Lang.String;
|
||||
var identifier = definition.get("entity") as Lang.String;
|
||||
|
||||
WatchUi.IconMenuItem.initialize(
|
||||
label,
|
||||
null,
|
||||
identifier,
|
||||
icon,
|
||||
options
|
||||
);
|
||||
|
||||
mMenu = new HomeAssistantView(definition, null);
|
||||
}
|
||||
|
||||
function getMenuView() as HomeAssistantView {
|
||||
return mMenu;
|
||||
}
|
||||
|
||||
}
|
@ -22,7 +22,7 @@ using Toybox.Lang;
|
||||
using Toybox.WatchUi;
|
||||
|
||||
class HomeAssistantViewMenuItem extends WatchUi.MenuItem {
|
||||
hidden var mMenu as HomeAssistantView;
|
||||
private var mMenu as HomeAssistantView;
|
||||
|
||||
function initialize(definition as Lang.Dictionary) {
|
||||
// definitions.get(...) are Strings here as they have been checked by HomeAssistantView first
|
||||
|
@ -23,7 +23,7 @@ using Toybox.WatchUi;
|
||||
using Toybox.Math;
|
||||
|
||||
class ScalableView extends WatchUi.View {
|
||||
hidden var mScreenWidth;
|
||||
private var mScreenWidth;
|
||||
|
||||
function initialize() {
|
||||
View.initialize();
|
||||
|