77from aiohttp .hdrs import REFERER , USER_AGENT
88import defusedxml .ElementTree as element_tree
99
10- from .data import Device , DownstreamChannel , UpstreamChannel
10+ from .data import (
11+ Device ,
12+ DownstreamChannel ,
13+ UpstreamChannel ,
14+ CmStatus ,
15+ ServiceFlow ,
16+ Temperature ,
17+ )
1118from . import exceptions
1219
1320_LOGGER = logging .getLogger (__name__ )
1926CMD_DEVICES = 123
2027CMD_DOWNSTREAM = 10
2128CMD_UPSTREAM = 11
29+ CMD_TEMPERATURE = 136
30+ CMD_CMSTATUS = 144
2231
2332
2433class ConnectBox :
@@ -44,8 +53,12 @@ def __init__(
4453 self .devices : List [Device ] = []
4554 self .ds_channels : List [DownstreamChannel ] = []
4655 self .us_channels : List [UpstreamChannel ] = []
56+ self .cmstatus : Optional [CmStatus ] = None
57+ self .upstream_service_flows : List [ServiceFlow ] = []
58+ self .downstream_service_flows : List [ServiceFlow ] = []
59+ self .temperature : Optional [Temperature ] = None
4760
48- async def async_get_devices (self ) -> List [ Device ] :
61+ async def async_get_devices (self ):
4962 """Scan for new devices and return a list with found device IDs."""
5063 if self .token is None :
5164 await self .async_initialize_token ()
@@ -132,6 +145,75 @@ async def async_get_upstream(self):
132145 self .token = None
133146 raise exceptions .ConnectBoxNoDataAvailable () from None
134147
148+ async def async_get_cmstatus_and_service_flows (self ):
149+ """Get various status information."""
150+ if self .token is None :
151+ await self .async_initialize_token ()
152+
153+ self .cmstatus = None
154+ self .downstream_service_flows = []
155+ self .upstream_service_flows = []
156+ raw = await self ._async_ws_function (CMD_CMSTATUS )
157+
158+ try :
159+ xml_root = element_tree .fromstring (raw )
160+ self .cmstatus = CmStatus (
161+ provisioningStatus = xml_root .find ("provisioning_st" ).text ,
162+ cmComment = xml_root .find ("cm_comment" ).text ,
163+ cmDocsisMode = xml_root .find ("cm_docsis_mode" ).text ,
164+ cmNetworkAccess = xml_root .find ("cm_network_access" ).text ,
165+ numberOfCpes = int (xml_root .find ("NumberOfCpes" ).text ),
166+ firmwareFilename = xml_root .find ("FileName" ).text ,
167+ dMaxCpes = int (xml_root .find ("dMaxCpes" ).text ),
168+ bpiEnable = int (xml_root .find ("bpiEnable" ).text ),
169+ )
170+ for elmt_service_flow in xml_root .iter ("serviceflow" ):
171+ service_flow = ServiceFlow (
172+ id = int (elmt_service_flow .find ("Sfid" ).text ),
173+ pMaxTrafficRate = int (elmt_service_flow .find ("pMaxTrafficRate" ).text ),
174+ pMaxTrafficBurst = int (
175+ elmt_service_flow .find ("pMaxTrafficBurst" ).text
176+ ),
177+ pMinReservedRate = int (
178+ elmt_service_flow .find ("pMinReservedRate" ).text
179+ ),
180+ pMaxConcatBurst = int (elmt_service_flow .find ("pMaxConcatBurst" ).text ),
181+ pSchedulingType = int (elmt_service_flow .find ("pSchedulingType" ).text ),
182+ )
183+ direction = int (elmt_service_flow .find ("direction" ).text )
184+ if direction == 1 :
185+ self .downstream_service_flows .append (service_flow )
186+ elif direction == 2 :
187+ self .upstream_service_flows .append (service_flow )
188+ else :
189+ raise element_tree .ParseError (
190+ "Unknown service flow direction '{}'" .format (direction )
191+ )
192+ except (element_tree .ParseError , TypeError ):
193+ _LOGGER .warning ("Can't read cmstatus from %s" , self .host )
194+ self .token = None
195+ raise exceptions .ConnectBoxNoDataAvailable () from None
196+
197+ async def async_get_temperature (self ):
198+ """Get temperature information (in degrees Celsius)."""
199+ if self .token is None :
200+ await self .async_initialize_token ()
201+
202+ self .temperature = None
203+ raw = await self ._async_ws_function (CMD_TEMPERATURE )
204+
205+ f_to_c = lambda f : (5.0 / 9 ) * (f - 32 )
206+ try :
207+ xml_root = element_tree .fromstring (raw )
208+ self .temperature = Temperature (
209+ tunerTemperature = f_to_c (int (xml_root .find ("TunnerTemperature" ).text )),
210+ temperature = f_to_c (int (xml_root .find ("Temperature" ).text )),
211+ )
212+ except (element_tree .ParseError , TypeError ):
213+ _LOGGER .warning ("Can't read temperature from %s" , self .host )
214+ self .token = None
215+ raise exceptions .ConnectBoxNoDataAvailable () from None
216+
135217 async def async_close_session (self ) -> None :
136218 """Logout and close session."""
137219 if not self .token :
0 commit comments