Coverage for custom_components/appliance_autonotify/const.py: 100%

89 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-10-14 15:14 +0000

1"""Constants for Appliance Auto Notify""" 

2 

3from typing import Final 

4 

5DOMAIN: Final[str] = "appliance_autonotify" 

6SUPERNOTIFY_DOMAIN: Final[str] = "supernotify" 

7 

8CONF_START_TITLE: Final[str] = "start_title" 

9CONF_START_MESSAGE: Final[str] = "start_message" 

10CONF_END_TITLE: Final[str] = "end_title" 

11CONF_END_MESSAGE: Final[str] = "end_message" 

12# notify entities, used only without Supernotify 

13CONF_TARGETS: Final[str] = "targets" 

14# as the `target` and `custom_target` of supernotify.notify 

15CONF_TARGET: Final[str] = "target" 

16CONF_CUSTOM_TARGET: Final[str] = "custom_target" 

17CONF_DELIVERIES: Final[str] = "deliveries" 

18# whether progress is told with ordinary notifications, the Live Activity is kept up to date regardless 

19CONF_NOTIFY_PROGRESS: Final[str] = "notify_progress" 

20# whether the start and the end are told with ordinary notifications, the Live Activity is opened and closed regardless 

21CONF_NOTIFY_START: Final[str] = "notify_start" 

22CONF_NOTIFY_END: Final[str] = "notify_end" 

23# whether the end of a phase, such as an oven getting up to heat, is told with an ordinary notification 

24CONF_NOTIFY_PHASE: Final[str] = "notify_phase" 

25# whether the program goes beside the name in the title of a Live Activity with a timer, for those short enough to fit 

26CONF_PROGRAM_IN_TITLE: Final[str] = "program_in_title" 

27# path of the dashboard opened by a tap on a notification, the app is opened where it was last if there's none 

28CONF_DASHBOARD: Final[str] = "dashboard" 

29LOVELACE_DOMAIN: Final[str] = "lovelace" 

30# the dashboard Home Assistant starts with has no path of its own in the list of them 

31DEFAULT_DASHBOARD: Final[str] = "lovelace" 

32DEFAULT_DASHBOARD_TITLE: Final[str] = "Overview" 

33# the one entry that isn't an appliance, holding whether appliances found are set up without asking 

34TYPE_DISCOVERY: Final[str] = "discovery" 

35CONF_AUTO_DISCOVER: Final[str] = "auto_discover" 

36# an appliance with no integration of its own, known only by the power it draws 

37TYPE_POWER: Final[str] = "power" 

38CONF_POWER_ENTITY: Final[str] = "power_entity" 

39CONF_THRESHOLD: Final[str] = "threshold" 

40CONF_GRACE_PERIOD: Final[str] = "grace_period" 

41CONF_MIN_DURATION: Final[str] = "min_duration" 

42# the smart plug the appliance is on, offered as a button to switch off once it has finished 

43CONF_SWITCH_ENTITY: Final[str] = "switch_entity" 

44# whether that button is offered, for a plug chosen but better left on 

45CONF_SWITCH_OFF_BUTTON: Final[str] = "switch_off_button" 

46# watts above which the appliance is running 

47DEFAULT_THRESHOLD: Final[float] = 1 

48# seconds at or below the threshold before the cycle is over, so short drop outs are ignored 

49DEFAULT_GRACE_PERIOD: Final[float] = 60 

50# seconds above the threshold before it counts as a cycle, so a door opened or a button pressed isn't one 

51DEFAULT_MIN_DURATION: Final[float] = 0 

52 

53# English only for the MVP 

54DISCOVERY_TITLE: Final[str] = "Automatic discovery" 

55NAME_PLACEHOLDER: Final[str] = "{name}" 

56# the program under way, as Home Assistant shows it, and nothing at all for an appliance that reports none 

57PROGRAM_PLACEHOLDER: Final[str] = "{program}" 

58DEFAULT_TITLE: Final[str] = "{name}" 

59DEFAULT_START_MESSAGE: Final[str] = "{name} started" 

60DEFAULT_END_MESSAGE: Final[str] = "{name} is finished" 

61PROGRESS_MESSAGE: Final[str] = "{progress}% complete" 

62 

63# minutes after which the end is told again, for as long as nobody says the appliance has been seen to 

64CONF_REMINDER: Final[str] = "reminder" 

65# how many times it's told again 

66CONF_REMINDER_REPEATS: Final[str] = "reminder_repeats" 

67DEFAULT_REMINDER_REPEATS: Final[int] = 3 

68# minutes for Remind Later, when no reminder is set 

69DEFAULT_SNOOZE: Final[int] = 30 

70# buttons on the end notification, each followed by the entry id of the appliance 

71ACTION_FINISHED: Final[str] = "APPLIANCE_FINISHED_" 

72ACTION_REMIND: Final[str] = "APPLIANCE_REMIND_" 

73ACTION_SWITCH_OFF: Final[str] = "APPLIANCE_SWITCH_OFF_" 

74# by the language of Home Assistant, English for any other 

75ACTION_TITLES: Final[dict[str, dict[str, str]]] = { 

76 "en": {ACTION_FINISHED: "Finished", ACTION_REMIND: "Remind Later", ACTION_SWITCH_OFF: "Switch Off"}, 

77 "it": {ACTION_FINISHED: "Finito", ACTION_REMIND: "Ricordamelo dopo", ACTION_SWITCH_OFF: "Spegni presa"}, 

78} 

79MOBILE_ACTION_EVENT: Final[str] = "mobile_app_notification_action" 

80# the text of the Android status bar chip, which shows it in full only up to about 7 characters 

81PROGRESS_CHIP: Final[str] = "{progress}%" 

82PREHEAT_PHASE: Final[str] = "Pre-heating" 

83FAST_PREHEAT_PHASE: Final[str] = "Fast pre-heat" 

84PREHEAT_MESSAGE: Final[str] = "{phase}, {current} of {target}{unit}" 

85PREHEATED_MESSAGE: Final[str] = "{name} is pre-heated" 

86# the title of a Live Activity with a timer, which iOS shows on the Lock Screen in place of the message 

87LIVE_TITLE: Final[str] = "{title} · {phase}" 

88# what an oven up to heat is doing, and how hot it is 

89OVEN_MESSAGE: Final[str] = "{program}, {current}{unit}" 

90SUPERNOTIFY_PRESENT: Final[str] = "Supernotify is installed, so mobile apps will show a Live Activity for each cycle." 

91SUPERNOTIFY_MISSING: Final[str] = ( 

92 "**Supernotify is not installed.** Only a plain start and end notification can be sent, to every phone with the " 

93 "Home Assistant app, with no Live Activity. Install Supernotify from HACS for the full experience." 

94) 

95 

96# translation key, per vendor platform, of the entity whose state follows the appliance cycle 

97CYCLE_KEYS: Final[dict[str, str]] = {"home_connect": "operation_state"} 

98PROGRESS_KEY: Final[str] = "program_progress" 

99FINISH_TIME_KEY: Final[str] = "program_finish_time" 

100# selects, unlike the others, of the program under way, and of the one chosen, which is all an oven reports 

101PROGRAM_KEYS: Final[tuple[str, ...]] = ("active_program", "selected_program") 

102# an oven warming up has no progress of its own, only how hot it is and how hot it's to be 

103TARGET_TEMPERATURE_KEY: Final[str] = "setpoint_temperature" 

104CAVITY_TEMPERATURE_KEY: Final[str] = "oven_current_cavity_temperature" 

105PREHEAT_FINISHED_KEYS: Final[tuple[str, ...]] = ("preheat_finished", "regular_preheat_finished") 

106FAST_PREHEAT_KEY: Final[str] = "fast_pre_heat" 

107# domain, by translation key, of each entity of an appliance that's made use of 

108ENTITY_DOMAINS: Final[dict[str, str]] = { 

109 PROGRESS_KEY: "sensor", 

110 FINISH_TIME_KEY: "sensor", 

111 **dict.fromkeys(PROGRAM_KEYS, "select"), 

112 TARGET_TEMPERATURE_KEY: "number", 

113 CAVITY_TEMPERATURE_KEY: "sensor", 

114 **dict.fromkeys(PREHEAT_FINISHED_KEYS, "sensor"), 

115 FAST_PREHEAT_KEY: "switch", 

116} 

117# degrees between Live Activity updates of an oven up to heat, whose temperature never stops wandering 

118TEMPERATURE_STEP: Final[float] = 5 

119# seconds before an oven saying it's up to heat is believed, since one switched off says so too, just before it's off 

120PREHEAT_SETTLE: Final[float] = 3 

121# an event sensor is `off` until whatever it tells of has happened 

122STATES_EVENT_ON: Final[tuple[str, ...]] = ("present", "confirmed", "on") 

123 

124STATE_RUN: Final[str] = "run" 

125# a cycle already under way, so not a new start when `run` follows 

126STATES_ACTIVE: Final[tuple[str, ...]] = ("run", "pause", "actionrequired") 

127# the cycle is over, an oven switched off goes straight from `run` to `inactive` without ever being `finished` 

128STATES_FINISHED: Final[tuple[str, ...]] = ("finished", "inactive") 

129# over too unless `run` soon follows, an oven being `ready` for a moment as it starts or has its settings changed 

130STATES_SETTLING: Final[tuple[str, ...]] = ("ready",) 

131# seconds an appliance is left to settle before the cycle is over 

132CYCLE_SETTLE: Final[float] = 10 

133# seconds a Live Activity is left to open before anything more is sent to it, since a push sent straight after the 

134# start can reach a phone ahead of it, and then be overwritten by the start, with no bar and no program 

135LIVE_SETTLE: Final[float] = 5 

136# the cycle is over without finishing, so the Live Activity goes without an end notification 

137STATES_ABANDONED: Final[tuple[str, ...]] = ("error", "aborting") 

138 

139# percentage points between Live Activity updates, since mobile platforms throttle frequent ones 

140PROGRESS_STEP: Final[int] = 5 

141# percentage points between ordinary notifications of progress, where those are asked for 

142PROGRESS_NOTIFY_STEP: Final[int] = 10 

143# from here on the end is in sight and the bar is being watched, so it's kept closer to the appliance 

144PROGRESS_FINAL: Final[int] = 90 

145PROGRESS_FINAL_STEP: Final[int] = 2 

146 

147MOBILE_PUSH_TRANSPORT: Final[str] = "mobile_push" 

148# Android notification channel of its own, made with sound on the first notification, since a Live Update in the 

149# app's default channel arrives without a sound 

150ANDROID_CHANNEL: Final[str] = "Appliances" 

151# platform of the notify entities used when there's no Supernotify and none have been chosen 

152MOBILE_APP_PLATFORM: Final[str] = "mobile_app" 

153 

154DEFAULT_ICON: Final[str] = "mdi:progress-clock" 

155TYPE_OVEN: Final[str] = "oven" 

156# the type of a Home Connect appliance, by how its programs are named 

157APPLIANCE_TYPES: Final[dict[str, str]] = { 

158 "dishcare_dishwasher_program_": "dishwasher", 

159 "laundry_care_washer_program_": "washer", 

160 "laundry_care_washer_dryer_program_": "washer_dryer", 

161 "laundry_care_dryer_program_": "dryer", 

162 "cooking_oven_program_": TYPE_OVEN, 

163 "cooking_hob_program_": "hob", 

164 "cooking_common_program_hood_": "hood", 

165 "consumer_products_coffee_maker_program_": "coffee_maker", 

166 "consumer_products_cleaning_robot_program_": "cleaning_robot", 

167 "heating_ventilation_air_conditioning_air_conditioner_program_": "air_conditioner", 

168} 

169TYPE_ICONS: Final[dict[str, str]] = { 

170 "dishwasher": "mdi:dishwasher", 

171 "washer": "mdi:washing-machine", 

172 "washer_dryer": "mdi:washing-machine", 

173 "dryer": "mdi:tumble-dryer", 

174 TYPE_OVEN: "mdi:stove", 

175 "hob": "mdi:pot-steam", 

176 "hood": "mdi:fan", 

177 "coffee_maker": "mdi:coffee-maker", 

178 "cleaning_robot": "mdi:robot-vacuum", 

179 "air_conditioner": "mdi:air-conditioner", 

180} 

181# the types whose phases are worth a notification unless it's turned off, an oven up to heat being waited 

182# for where a dishwasher starting to rinse isn't 

183PHASES_NOTIFIED: Final[tuple[str, ...]] = (TYPE_OVEN,) 

184# matched against the device name where the type isn't known, first hit wins 

185ICONS: Final[dict[str, str]] = { 

186 "dishwasher": "mdi:dishwasher", 

187 # Italian names 

188 "lavastoviglie": "mdi:dishwasher", 

189 "lavasciuga": "mdi:washing-machine", 

190 "lavatrice": "mdi:washing-machine", 

191 "asciugatrice": "mdi:tumble-dryer", 

192 "microonde": "mdi:microwave", 

193 "forno": "mdi:stove", 

194 "caffè": "mdi:coffee-maker", 

195 "caffe": "mdi:coffee-maker", 

196 "cappa": "mdi:fan", 

197 "piano cottura": "mdi:pot-steam", 

198 "aspirapolvere": "mdi:robot-vacuum", 

199 "bollitore": "mdi:kettle", 

200 "dryer": "mdi:tumble-dryer", 

201 "wash": "mdi:washing-machine", 

202 "oven": "mdi:stove", 

203 "microwave": "mdi:microwave", 

204 "coffee": "mdi:coffee-maker", 

205 "hood": "mdi:fan", 

206 "hob": "mdi:pot-steam", 

207 "vacuum": "mdi:robot-vacuum", 

208 "kettle": "mdi:kettle", 

209}