Device API

class fsapi.net.device.Method(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

WebAPI method (discovered ones)

class fsapi.net.device.Status(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

All possible response statuses discovered in firmware binaries.

FS_FAIL = 'FS_FAIL'

If the parameters given in the url are mot matching the node criteria, the request will fail. In addition, this API returns FS_FAIL whenever an invalid response is received.

FS_LIST_END = 'FS_LIST_END'

The navigated item is not present within the selected list.

FS_NODE_BLOCKED = 'FS_NODE_BLOCKED'

Certain commands can only be used when the unit is in the correct mode.

FS_NODE_DOES_NOT_EXIST = 'FS_NODE_DOES_NOT_EXIST'

The referenced node is not available on the target device.

FS_OK = 'FS_OK'

If everything goes right the status is set to FS_OK

FS_PACKET_BAD = 'FS_PACKET_BAD'

This status code will be returned if a value should be applied to a read-only node and therefore can not be executed.

FS_REPLY_TOO_BIG = 'FS_REPLY_TOO_BIG'

Response code for requests that result in a large output.

FS_REQUEST_INVALID = 'FS_REQUEST_INVALID'

Same as FS_FAIL, but the command has not been executed yet.

FS_TIMEOUT = 'FS_TIMEOUT'

The device takes too long to respond.

FS_UNKNOWN_STATUS = 'FS_UNKNOWN_STATUS'

API status to mark invalid status codes.

class fsapi.net.device.FSResponse(method: Method, node: Node, status: Status)

De-serialized response of a XML request.

method: Method

The used API method

node: Node

The de-serialized node with its value (may be None)

status: Status

The status of this response

property success: bool

Returns whether the response has been parsed successfully.

class fsapi.net.device.FSDevice(host: str, port: int = 80, pin: str = '1234', sid: int = -1, config: FSNetConfiguration = None, create_session=False)

Client to communicate with FS devices.

This class acts as a HTTP client that automatically parses XML responses and wraps their values to the corresponding nodes.

>>> device = FSDevice("127.0.0.1")
>>> response = device.get(nodes / "netRemote.sys.info.version")
>>> if response.success:
...     version: str = response.node.value

When querying list nodes, there is a possiblity to choose the current navigation item:

>>> response = device.get_list(nodes / "...", _pos=5)

To enable session usage, just let the device request a new session and the session id will be sent within all requests.

>>> device.new_session() # new value will be applied directly
>>> response = device.get(nodes / "...")
>>> status = device.close_session()
Parameters:
  • host (str) – the target host

  • port (int, optional) – the web server port, defaults to 80

  • pin (str, optional) – the PIN to use, defaults to FS_DEFAULT_PIN

  • sid (int, optional) – initial session id, can be set using create_session, defaults to -1

  • config (FSNetConfiguration, optional) – the network configuration, defaults to None

  • create_session (bool, optional) – indicates whether a new session should be created, defaults to False

get_url(method: Method, *elements, **parameters) str

Creates a new URL that can be used to perform an API request.

Example:
>>> device.get_url(Method.GET_NOTIFIES)
'http://127.0.0.1:80/fsapi/GET_NOTIFIES?pin=1234'
Parameters:

method (Method) – the API method

Returns:

the fully qualified URL

Return type:

str

node_request(method: Method, node: type | str | NodePath, config: FSNetConfiguration = None, **argv) FSResponse

Performs a single webAPI request.

This method can be called in different situations and will always behave the same: First, it creates the URL to be called. Next, the result of that call will be converted into an FSResponse object.

Warning

Use this function only if you known what you are doing, otherwise you may run into errors.

Parameters:
  • method (Method) – the API method to use

  • node (_NodeType) – the

  • config (FSNetConfiguration, optional) – _description_, defaults to None

Returns:

_description_

Return type:

FSResponse

node_request_multiple(method: Method, nodes: List[type | str | NodePath], config: FSNetConfiguration = None, **argv) List[FSResponse]

Performs a multiple node request.

Parameters:
  • method (Method) – the API method

  • nodes (t.List[_NodeType]) – the list of nodes to query

  • config (FSNetConfiguration, optional) – the network configuration, defaults to None

Returns:

a list of response objects storing the de-serialized data.

Return type:

t.List[FSResponse]

request(path: str, config: FSNetConfiguration, **argv) ElementTree | None

Performs a HTTP request and parses its XML response.

This method will try to avoid raising exceptions and returns None on invalid response data. The PIN has to be included in the optional arguments of this function.

Parameters:
  • path (str) – the request uri without leading slash, e.g. “fsapi/GET/netRemote.sys.info.version”

  • config (FSNetConfiguration) – the network configuration

Returns:

the parsed XML response as element tree

Return type:

ElementTree.ElementTree | None

FSAPI Wrapper

fsapi.net.wrap(device: FSDevice) _Wrapper

Creates a new API wrapper for the given device.

With the returned wrapper object, the most important nodes can be accessed using simple attribute syntax:

>>> device = FSDevice("127.0.0.1")
>>> api = wrap(device)
>>> name: str = api.friendly_name

Note that every access will fire an HTTP request to the desired target device. It is also possible to use this method as a decorator (property is optionall):

>>> class Foo:
...    @wrap
...    @property
...    def api(self):
...        return self.device
...
Parameters:

device (FSDevice) – the controller implementing the FSAPI

Returns:

a new API wrapper

Return type:

_Wrapper

class fsapi.net._wrap._Wrapper(device: FSDevice)

Web FSAPI wrapper class.

This class stores the most common nodes to control devices using the FSAPI. Standard nodes can be accessed via attribute access and list nodes should be handled differently. List nodes start with ls_.

Instances of this class can be retrieved by calling the exported wrap() method:

>>> device = FSDevice("127.0.0.1")
>>> api = wrap(device)

Standard nodes can be accessed and controlled with ease:

>>> api.friendly_name
'MEDION'
>>> api.volume
3
>>> api.friendly_name = "MEDION2"
>>> api.friendly_name
'MEDION2'

Inaccessable nodes or blocked nodes will return a None value and immutable nodes will raise an AttributeError on modification. List nodes behave special:

>>> api.ls_eqpresets(_pos=4)
[...]
>>> api.ls_eqpresets = 1

Use the assignment to select an item and the function call operator to query a range of items.

property device: FSDevice

The linked device

get_field(name: str) APICall | ListAPICall

Returns a field of this instance named by the provided string.

Parameters:

name (str) – the field’s name

Returns:

the api call wrapper instance

Return type:

t.Union[APICall, ListAPICall]

class fsapi.net._wrap.APICall(node_path: str)

Generic API call using simple node definitions.

This class will enable checks during runtime that prevents changing immutable values.

Important: This class is strongly typed. In order to enable static type checking this class is annotated with a type variable.

>>> class Foo:
...     value: APICall[int] = APICall("foo.bar")
...
>>> foo = Foo()
>>> foo.value
5
Parameters:

node_path (str) – the node’s path

get(wrapper: _Wrapper) _T | None

Returns the value for the linked node.

Parameters:

wrapper (_Wrapper) – the API wrapper instance

Returns:

the fetched value or None if an error occurred

Return type:

_T | None

put(wrapper: _Wrapper, value: _T) None

Sets a new value for the linked node.

Parameters:
  • wrapper (_Wrapper) – the API wrapper instance

  • value (_T) – the new value to be applied

Raises:

AttributeError – if the linked node is readonly

class fsapi.net._wrap.ListAPICall(node_path: str)

Representation for a list API call.

This class behaves differently compared to standard API call variables as it fetches more than one item and can take query arguments.

>>> api = wrap(device)
>>> api.ls_eqpresets(_pos=2, max_items=3)
[...]
  • _pos: the starting index position within the list (-1 for all items)

  • max_items: the number of items that should be returned

get(wrapper: _Wrapper, **argv) List[NodeListItem]

Returns a list of items.

Parameters:

wrapper (_Wrapper) – the api wrapper instance

Returns:

the list returned by the device

Return type:

t.List[NodeListItem]

put(wrapper: _Wrapper, value: int) None

Selects an item within the context of this list node.

Parameters:
  • wrapper (_Wrapper) – the API wrapper instance

  • value (int) – the key of an item (index position)

Raises:

TypeError – if the provided value is not an integer