המדריך הבא מסביר איך אפשר להשתמש בצמתים שונים של Automation DSL כדי ליצור אוטומציה.
כל ה-DSL של האוטומציה ממוקם בתוך צומת automation יחיד. הצומת automation יוצר את הגבול בין ההקשר החיצוני של שפת Kotlin לבין ההקשר המוטמע של DSL.
תהליך עבודה עוקב
הזרימה העוקבת היא סוג ברירת המחדל של זרימת אוטומציה.
הנה תבנית בסיסית מאוד של שפת תיאור אוטומציה (Automation DSL) שמשתמשת בזרימה רציפה שכוללת התחלה, תנאי ופעולה:
import com.google.home.automation.action
import com.google.home.automation.automation
import com.google.home.automation.condition
import com.google.home.automation.sequential
import com.google.home.automation.starter
...
automation {
sequential {
starter<_>(...)
condition {...}
action {...}
}
}
אפשר לשפר את התוצאה על ידי הוספת צמתים נוספים.
מתחילים
צמתי התחלה מגדירים את הנסיבות הראשוניות שמפעילות אוטומציה. לדוגמה, שינוי במצב או בערך. לכל אוטומציה צריך להיות לפחות starter אחד, אחרת האימות ייכשל. כדי להוסיף יותר מפעולה אחת להפעלת אוטומציה, צריך להשתמש בצומת select.
חבילת התחלה שמבוססת על מאפיין של תכונה
כשמצהירים על צומת התחלתי שמבוסס על מאפיין trait, מציינים:
- המכשיר
- סוג המכשיר שאליו התכונה שייכת
- המאפיין
starter<_>(thermostat, TemperatureSensorDevice, TemperatureMeasurement)
פרמטר סוג המכשיר הוא חובה כי הוא מאפשר לכם לציין את סוג המכשיר בתוך מכשיר שאליו מתייחסת האוטומציה. לדוגמה, מכשיר יכול להיות מורכב מ-FanDevice ומ-HeatingCoolingUnitDevice, שניהם מכילים את המאפיין OnOff. כשמציינים את סוג המכשיר, אין ספק לגבי החלק במכשיר שמפעיל את האוטומציה.
חבילת Starter על סמך אירוע
כשמגדירים צומת התחלה שמבוסס על אירוע, צריך לציין:
- המכשיר
- סוג המכשיר שאליו התכונה שייכת
- האירוע
starter<_>(doorBell, GoogleDoorbellDevice, DoorbellPressed)
תבנית התחלתית שמבוססת על מבנה ואירוע, עם פרמטרים
חלק מהאירועים יכולים לכלול פרמטרים, ולכן צריך לכלול גם את הפרמטרים האלה בקוד ההתחלה.
לדוגמה, סימן תחילת הפעולה הזה משתמש במאפיין Time של התכונה ScheduledTimeEvent כדי להפעיל את האוטומציה בשעה 7:00 בבוקר:
val earlyMorning = starter<_>(structure, Time.ScheduledTimeEvent) {
parameter(Time.ScheduledTimeEvent.clockTime(
LocalTime.of(7, 0, 0, 0)))
}
התחלה על סמך מזג האוויר
אתם יכולים לציין תנאי מזג אוויר נוכחיים או צפויים בהנחיה לדוגמה באמצעות המאפיין Weather:
val weatherState = starter<_>(structure, trait = Weather)
אפשר לראות את הדוגמה Close the blinds if it is likely to rain (סגירת התריסים אם צפוי גשם) בדף Example automations (דוגמאות לאוטומציות).
מפעיל ידני
סימן הפעלה ידני הוא סוג מיוחד של סימן הפעלה שמאפשר למשתמש להפעיל את האוטומציה באופן ידני.
כשמגדירים סימן ידני לתחילת פעולה:
- אל תציינו תכונה או סוג מכשיר.
- מספקים רכיב בממשק המשתמש שקורא ל-
Automation.execute().
כשמציבים הפעלה ידנית בתהליך select יחד עם הפעלה אחרת, ההפעלה הידנית מבטלת את ההפעלה האחרת:
select {
manualStarter()
starter<_>(thermostat, TemperatureSensorDevice, TemperatureMeasurement)
}
חשוב לזכור שכל condition צומת אחרי סימן לתחילת פעולה ידני ייבדק,
ויכול לחסום את הרצה של האוטומציה, בהתאם לcondition
ביטוי.
אחת הדרכים להגדיר את האוטומציה כך שצמתי condition לא יחסמו אוטומציה שהופעלה באמצעות התחלה ידנית היא להציב את ההתחלה האחרת בתהליך רציף נפרד יחד עם condition שלה:
automation_graph {
sequential {
select {
sequential {
starter<_>(...)
condition {...}
}
sequential {
manualStarter()
}
}
action {...}
}
}
הפניה לערך של מאפיין
כדי להשתמש בערך של מאפיין בביטוי, משתמשים בתחביר הבא.
עם stateReader:
val time = stateReader<_>(structure, Structure, Time)
val currTime = time.currentTime
עם starter:
val starterNode = starter<_>(device1, LaundryWasherDevice, OnOff)
condition() {
expression = starterNode.onOff equals true
}
צמתי תנאים וביטויים
צומת של תנאי מייצג נקודת החלטה שקובעת אם האוטומציה תימשך או לא. באוטומציה יכולים להיות כמה צמתים (nodes) של condition.
אם הביטוי של צומת condition כלשהו מחזיר את הערך false, הביצוע של כל האוטומציה מסתיים.
בצומת condition, אפשר לשלב כמה קריטריונים של תנאים באמצעות אופרטורים שונים, כל עוד הביטוי מוערך כערך בוליאני יחיד. אם הערך שמתקבל הוא true, התנאי מתקיים והאוטומציה ממשיכה להפעיל את הצומת הבא. אם הערך הוא false, האוטומציה מפסיקה לפעול בשלב הזה.
הביטויים מורכבים באופן דומה לביטויים ב-Kotlin, והם יכולים להכיל ערכים פרימיטיביים כמו מספרים, תווים, מחרוזות וערכים בוליאניים, וגם ערכי Enum. קיבוץ של ביטויי משנה באמצעות סוגריים מאפשר לכם לשלוט בסדר שבו הם מוערכים.
דוגמה ל-condition שמשלב כמה ביטויי משנה לביטוי אחד:
condition() {
val expr1 = starterNode.lockState equals DlLockState.Unlocked
val expr2 = stateReaderNode.lockState equals true
val expr3 = occupancySensingDevice.occupied notEquals 0
val expr4 = timeStateReaderNode
.currentTime
.between(
timeStateReaderNode.sunsetTime,
timeStateReaderNode.sunriseTime)
expression = (expr1 and expr2) or (expr3 and expr4)
}
אפשר להפנות לערך של מאפיין שהגישה אליו מתבצעת דרך starter:
val starterNode = starter<_>(device, OnOff)
condition() { expression = starterNode.onOff equals true }
stateReader
דרך נוספת להפניה לערכי מאפייני מאפיינים בצומת condition היא באמצעות צומת stateReader.
כדי לעשות את זה, קודם צריך לתעד את ערך מאפיין המאפיין בצומת stateReader. הפונקציה stateReader מקבלת את structure ואת המאפיין כארגומנטים:
import com.google.home.automation.stateReader
...
val filterMonitoringState = stateReader<_>(structure, ActivatedCarbonFilterMonitoring)
אחר כך מפנים אל stateReader בצומת condition:
condition() {
expression =
filterMonitoringState.changeIndication
.equals(ChangeIndicationEnum.Warning)
}
אפשר להשתמש בכמה תנאים stateReaders בצומת condition באמצעות אופרטורים להשוואה ואופרטורים לוגיים:
val armState = stateReader<_>(doorLock, DoorLockDevice, ArmDisarm )
val doorLockState = stateReader<_>(doorLock, DoorLockDevice, DoorLock)
condition() {
expression =
(armState.armState equals true)
and
(doorLockState.lockState equals true)
}
משך התנאי
בנוסף לביטוי בוליאני בתנאי, אפשר לציין לוח זמנים שבו הביטוי צריך להיות נכון כדי להפעיל את הפעולות האוטומטיות. לדוגמה, אפשר להגדיר תנאי שמופעל רק אם האור דולק במשך עשר דקות.
condition {
expression(lightStateReader.onOff == true)
forDuration(Duration.ofMinutes(10))
}
ההשהיה יכולה להימשך בין 5 שניות ל-24 שעות.
צמתי פעולה
בצומת הפעולה מתבצעת העבודה של האוטומציה.
בדוגמה הזו, הפעולה מפעילה את הפקודה broadcast() של המאפיין AssistantBroadcast:
action(device, SpeakerDevice) {
command(AssistantBroadcast.broadcast("Intruder detected!"))
}
ייבוא דפי פירוט חשבון
כשמפתחים אוטומציות, לא תמיד ברור איך לייבא לקוד רכיבים שונים של ממשקי ה-API של Home.
מאפייני מאפיינים מיובאים מאובייקט Companion של המאפיין:
import com.google.home.matter.standard.OnOff.Companion.onOff
מבני נתונים שמוגדרים על ידי מאפיין מיובאים ממחלקת המאפיינים, שהשם שלה מסתיים ב-Trait-:
import com.google.home.matter.standard.MediaPlaybackTrait.PlaybackStateEnum
פקודות של מאפיינים מיובאות מאובייקט Companion של המאפיין:
import com.google.home.matter.standard.Thermostat.Companion.setTemperatureSetpointHold