16
16
- hotend_1_temperature (optional)
17
17
- hotend_N_temperature (optional, N = hotend index starting at 1)
18
18
"""
19
- import logging
20
19
import asyncio
20
+ import logging
21
+ from datetime import datetime , timedelta
22
+ from typing import Any , Dict , Optional
23
+
21
24
import aiohttp
22
25
import async_timeout
23
-
24
- from datetime import timedelta , datetime
25
- from typing import Optional , Dict , Any
26
-
27
- import voluptuous as vol
28
-
29
- from . import DOMAIN
30
26
import homeassistant .helpers .config_validation as cv
31
- from homeassistant .helpers .typing import HomeAssistantType , StateType
32
- from homeassistant .helpers .aiohttp_client import async_get_clientsession
27
+ import voluptuous as vol
33
28
from homeassistant .components .sensor import PLATFORM_SCHEMA
34
29
from homeassistant .const import (
35
- CONF_HOST , CONF_SCAN_INTERVAL , CONF_SENSORS , TEMP_CELSIUS , CONF_NAME
30
+ CONF_HOST ,
31
+ CONF_NAME ,
32
+ CONF_SCAN_INTERVAL ,
33
+ CONF_SENSORS ,
34
+ TEMP_CELSIUS ,
36
35
)
36
+ from homeassistant .helpers .aiohttp_client import async_get_clientsession
37
37
from homeassistant .helpers .entity import Entity
38
+ from homeassistant .helpers .typing import HomeAssistantType , StateType
38
39
from homeassistant .util import Throttle
39
40
41
+ from . import DOMAIN
42
+
40
43
_LOGGER = logging .getLogger (__name__ )
41
44
42
45
SENSOR_TYPES = {
43
- 'status' : ['Printer status' , '' , 'mdi:printer-3d' ],
44
- 'state' : ['Print job state' , '' , 'mdi:printer-3d-nozzle' ],
45
- 'progress' : ['Print job progress' , '%' , 'mdi:progress-clock' ],
46
- 'bed_temperature' : ['Bed temperature' , TEMP_CELSIUS , 'mdi:thermometer' ],
47
- 'bed_temperature_target' : ['Bed temperature target' , TEMP_CELSIUS , 'mdi:thermometer' ],
48
- 'hotend_1_temperature' : ['Hotend 1 temperature' , TEMP_CELSIUS , 'mdi:thermometer' ],
49
- 'hotend_1_temperature_target' : ['Hotend 1 temperature target' , TEMP_CELSIUS , 'mdi:thermometer' ],
50
- 'hotend_2_temperature' : ['Hotend 2 temperature' , TEMP_CELSIUS , 'mdi:thermometer' ],
51
- 'hotend_2_temperature_target' : ['Hotend 2 temperature target' , TEMP_CELSIUS , 'mdi:thermometer' ],
46
+ "status" : ["Printer status" , "" , "mdi:printer-3d" ],
47
+ "state" : ["Print job state" , "" , "mdi:printer-3d-nozzle" ],
48
+ "progress" : ["Print job progress" , "%" , "mdi:progress-clock" ],
49
+ "bed_temperature" : ["Bed temperature" , TEMP_CELSIUS , "mdi:thermometer" ],
50
+ "bed_temperature_target" : [
51
+ "Bed temperature target" ,
52
+ TEMP_CELSIUS ,
53
+ "mdi:thermometer" ,
54
+ ],
55
+ "hotend_1_temperature" : ["Hotend 1 temperature" , TEMP_CELSIUS , "mdi:thermometer" ],
56
+ "hotend_1_temperature_target" : [
57
+ "Hotend 1 temperature target" ,
58
+ TEMP_CELSIUS ,
59
+ "mdi:thermometer" ,
60
+ ],
61
+ "hotend_2_temperature" : ["Hotend 2 temperature" , TEMP_CELSIUS , "mdi:thermometer" ],
62
+ "hotend_2_temperature_target" : [
63
+ "Hotend 2 temperature target" ,
64
+ TEMP_CELSIUS ,
65
+ "mdi:thermometer" ,
66
+ ],
52
67
}
53
68
54
- CONF_DECIMAL = 'decimal'
55
-
56
- PLATFORM_SCHEMA = PLATFORM_SCHEMA .extend ({
57
- vol .Required (CONF_HOST ): cv .string ,
58
- vol .Required (CONF_NAME ): cv .string ,
59
- vol .Optional (CONF_DECIMAL , default = 2 ): cv .positive_int ,
60
- vol .Required (CONF_SENSORS , default = list (SENSOR_TYPES )):
61
- vol .All (cv .ensure_list , [vol .In (SENSOR_TYPES )]),
62
- })
69
+ CONF_DECIMAL = "decimal"
70
+
71
+ PLATFORM_SCHEMA = PLATFORM_SCHEMA .extend (
72
+ {
73
+ vol .Required (CONF_HOST ): cv .string ,
74
+ vol .Required (CONF_NAME ): cv .string ,
75
+ vol .Optional (CONF_DECIMAL , default = 2 ): cv .positive_int ,
76
+ vol .Required (CONF_SENSORS , default = list (SENSOR_TYPES )): vol .All (
77
+ cv .ensure_list , [vol .In (SENSOR_TYPES )]
78
+ ),
79
+ }
80
+ )
63
81
64
82
65
83
MIN_TIME_BETWEEN_UPDATES = timedelta (seconds = 10 )
66
- BASE_URL = ' http://{0}/api/v1'
84
+ BASE_URL = " http://{0}/api/v1"
67
85
68
86
69
- async def async_setup_platform (hass : HomeAssistantType , config , async_add_entities , discovery_info = None ):
87
+ async def async_setup_platform (
88
+ hass : HomeAssistantType , config , async_add_entities , discovery_info = None
89
+ ):
70
90
"""Setup the Ultimaker printer sensors"""
71
91
session = async_get_clientsession (hass )
72
92
data = UltimakerStatusData (session , config .get (CONF_HOST ))
@@ -80,14 +100,21 @@ async def async_setup_platform(hass: HomeAssistantType, config, async_add_entiti
80
100
unit = SENSOR_TYPES [sensor ][1 ]
81
101
icon = SENSOR_TYPES [sensor ][2 ]
82
102
83
- _LOGGER .debug (f"Adding Ultimaker printer sensor: { name } , { sensor_type } , { unit } , { icon } " )
84
- entities .append (UltimakerStatusSensor (data , name , sensor_type , unit , icon , config .get (CONF_DECIMAL )))
103
+ _LOGGER .debug (
104
+ f"Adding Ultimaker printer sensor: { name } , { sensor_type } , { unit } , { icon } "
105
+ )
106
+ entities .append (
107
+ UltimakerStatusSensor (
108
+ data , name , sensor_type , unit , icon , config .get (CONF_DECIMAL )
109
+ )
110
+ )
85
111
86
112
async_add_entities (entities , True )
87
113
88
114
89
115
class UltimakerStatusData (object ):
90
116
"""Handle Ultimaker object and limit updates"""
117
+
91
118
def __init__ (self , session , host ):
92
119
if host :
93
120
self ._url_printer = BASE_URL .format (host ) + "/printer"
@@ -106,8 +133,8 @@ async def async_update(self):
106
133
self ._data |= await self .fetch_data (self ._url_print_job )
107
134
self ._data |= await self .fetch_data (self ._url_system )
108
135
except aiohttp .ClientError :
109
- self ._data = {' status' : ' not connected' }
110
- self ._data [' sampleTime' ] = datetime .now ()
136
+ self ._data = {" status" : " not connected" }
137
+ self ._data [" sampleTime" ] = datetime .now ()
111
138
112
139
async def fetch_data (self , url ):
113
140
try :
@@ -117,9 +144,13 @@ async def fetch_data(self, url):
117
144
_LOGGER .warning (f"Printer { self ._host } is offline" )
118
145
raise err
119
146
except asyncio .TimeoutError :
120
- _LOGGER .error (f" Timeout error occurred while polling ultimaker printer using url { url } " )
147
+ _LOGGER .error (
148
+ f" Timeout error occurred while polling ultimaker printer using url { url } "
149
+ )
121
150
except Exception as err :
122
- _LOGGER .error (f"Unknown error occurred while polling Ultimaker printer using { url } -> error: { err } " )
151
+ _LOGGER .error (
152
+ f"Unknown error occurred while polling Ultimaker printer using { url } -> error: { err } "
153
+ )
123
154
return {}
124
155
125
156
try :
@@ -137,7 +168,9 @@ def latest_data(self):
137
168
class UltimakerStatusSensor (Entity ):
138
169
"""Representation of a Ultimaker status sensor"""
139
170
140
- def __init__ (self , data : UltimakerStatusData , name , sensor_type , unit , icon , decimal ):
171
+ def __init__ (
172
+ self , data : UltimakerStatusData , name , sensor_type , unit , icon , decimal
173
+ ):
141
174
"""Initialize the sensor."""
142
175
self ._data = data
143
176
self ._name = name
@@ -172,7 +205,7 @@ def unit_of_measurement(self) -> Optional[str]:
172
205
def device_state_attributes (self ) -> Optional [Dict [str , Any ]]:
173
206
attr = {}
174
207
if self ._last_updated is not None :
175
- attr [' Last Updated' ] = self ._last_updated
208
+ attr [" Last Updated" ] = self ._last_updated
176
209
return attr
177
210
178
211
async def async_update (self ):
@@ -181,42 +214,42 @@ async def async_update(self):
181
214
data = self ._data .latest_data
182
215
183
216
if data :
184
- self ._last_updated = data .get (' sampleTime' , None )
217
+ self ._last_updated = data .get (" sampleTime" , None )
185
218
186
- if self ._type == ' status' :
187
- self ._state = data .get (' status' , ' not connected' )
219
+ if self ._type == " status" :
220
+ self ._state = data .get (" status" , " not connected" )
188
221
189
- elif self ._type == ' state' :
190
- self ._state = data .get (' state' , None )
222
+ elif self ._type == " state" :
223
+ self ._state = data .get (" state" , None )
191
224
if self ._state :
192
- self ._state = self ._state .replace ('_' , ' ' )
225
+ self ._state = self ._state .replace ("_" , " " )
193
226
194
- elif self ._type == ' progress' :
195
- self ._state = data .get (' progress' , 0 )
227
+ elif self ._type == " progress" :
228
+ self ._state = data .get (" progress" , 0 )
196
229
if self ._state :
197
230
self ._state *= 100
198
231
self ._state = self ._state
199
232
200
- elif ' bed' in self ._type :
201
- bed = data .get (' bed' , None )
202
- if ' temperature' in self ._type and bed :
203
- temperature = bed .get (' temperature' , None )
233
+ elif " bed" in self ._type :
234
+ bed = data .get (" bed" , None )
235
+ if " temperature" in self ._type and bed :
236
+ temperature = bed .get (" temperature" , None )
204
237
if temperature :
205
- if ' target' in self ._type :
206
- self ._state = temperature .get (' target' , None )
238
+ if " target" in self ._type :
239
+ self ._state = temperature .get (" target" , None )
207
240
else :
208
- self ._state = temperature .get (' current' , None )
241
+ self ._state = temperature .get (" current" , None )
209
242
210
- elif ' hotend' in self ._type :
211
- head = data .get (' heads' , [None ])[0 ]
243
+ elif " hotend" in self ._type :
244
+ head = data .get (" heads" , [None ])[0 ]
212
245
if head :
213
246
idx = int (self ._type .split ("_" )[1 ]) - 1
214
- extruder = head [' extruders' ][idx ]
215
- hot_end = extruder [' hotend' ]
216
- temperature = hot_end [' temperature' ]
217
- if ' target' in self ._type :
218
- self ._state = temperature .get (' target' , None )
247
+ extruder = head [" extruders" ][idx ]
248
+ hot_end = extruder [" hotend" ]
249
+ temperature = hot_end [" temperature" ]
250
+ if " target" in self ._type :
251
+ self ._state = temperature .get (" target" , None )
219
252
else :
220
- self ._state = temperature .get (' current' , None )
253
+ self ._state = temperature .get (" current" , None )
221
254
222
255
_LOGGER .debug (f"Device: { self ._type } State: { self ._state } " )
0 commit comments