from hat import util mlog: logging.Logger = logging.getLogger(__name__) """Module logger""" class DeviceInfo(typing.NamedTuple): addr: udp.Address location: str server: str service: str DeviceInfoCb = aio.AsyncCallable[[DeviceInfo], None] """Device info callback""" util.register_type_alias('DeviceInfoCb') default_multicast_addr = udp.Address('239.255.255.250', 1900) async def discover(device_info_cb: DeviceInfoCb, multicast_addr: udp.Address = default_multicast_addr, local_name: str = 'hat') -> 'DiscoveryServer': """Create discovery server""" endpoint = await udp.create(udp.Address('0.0.0.0', multicast_addr.port)) srv = DiscoveryServer() srv._endpoint = endpoint srv._device_info_cb = device_info_cb srv._multicast_addr = multicast_addr srv._local_name = local_name
"""Python ctypes wrapper for duktape JavaScript interpreter""" from pathlib import Path import ctypes import sys import typing from hat import util Data = typing.Union[None, bool, int, float, str, typing.List['Data'], typing.Dict[str, 'Data'], typing.Callable] """Supported data types""" util.register_type_alias('Data') class EvalError(Exception): """Evaluation error""" class Interpreter: """JavaScript interpreter High-level python wrapper for duktape JavaScript interpreter. Current implementation caches all function objects for preventing garbage collection. """
class BinaryCounterValue(typing.NamedTuple): value: int """value in range [-2^31, 2^31-1]""" sequence: int overflow: bool adjusted: bool invalid: bool DataValue = typing.Union[SingleValue, DoubleValue, StepPositionValue, BitstringValue, NormalizedValue, ScaledValue, FloatingValue, BinaryCounterValue] """Data value""" util.register_type_alias('DataValue') CommandValue = typing.Union[SingleValue, DoubleValue, RegulatingValue, NormalizedValue, ScaledValue, FloatingValue] """Command value""" util.register_type_alias('CommandValue') class Quality(typing.NamedTuple): invalid: bool not_topical: bool substituted: bool blocked: bool overflow: typing.Optional[bool] """Overflow is ``None`` in case of `SingleValue` and `DoubleValue` (otherwise can not be ``None``)"""
from hat.drivers.modbus import common from hat.drivers.modbus import encoder from hat.drivers.modbus import messages from hat.drivers.modbus import transport mlog: logging.Logger = logging.getLogger(__name__) """Module logger""" SlaveCb = aio.AsyncCallable[['Slave'], None] """Slave callback Args: slave: slave instance """ util.register_type_alias('SlaveCb') ReadCb = aio.AsyncCallable[ ['Slave', int, common.DataType, int, typing.Optional[int]], typing.Union[typing.List[int], common.Error]] """Read callback Args: slave: slave instance device_id: device identifier data_type: data type start_address: staring address quantity: number of registers Returns: list of register values or error
"""Statechart module""" import collections import itertools import pathlib import typing import xml.etree.ElementTree from hat import aio from hat import util EventName = str """Event name""" util.register_type_alias('EventName') StateName = str """State name""" util.register_type_alias('StateName') ActionName = str """Action name""" util.register_type_alias('ActionName') ConditionName = str """Condition name""" util.register_type_alias('ConditionName') class Event(typing.NamedTuple): """Event instance"""
import logging import pathlib import ssl import typing from hat import aio from hat import json from hat import util mlog: logging.Logger = logging.getLogger(__name__) """Module logger""" ConnectionCb = typing.Callable[['Connection'], None] """Connection callback""" util.register_type_alias('ConnectionCb') async def connect(address: str, *, autoflush_delay: typing.Optional[float] = 0.2, ) -> 'Connection': """Connect to remote server Address represents remote WebSocket URL formated as ``<schema>://<host>:<port>/<path>`` where ``<schema>`` is ``ws`` or ``wss``. Argument `autoflush_delay` defines maximum time delay for automatic synchronization of `local_data` changes. If `autoflush_delay` is set to ``None``, automatic synchronization is disabled and user is responsible for calling :meth:`Connection.flush_local_data`. If `autoflush_delay` is
raise CancelledWithResultError(result, f.exception()) from exc if f.cancelled(): raise asyncio.TimeoutError() return f.result() Executor = typing.Callable[..., typing.Awaitable] """Executor coroutine This coroutine takes a function and its arguments, executes the function in executor and returns the result. """ util.register_type_alias('Executor') def create_executor( *args: typing.Any, executor_cls: typing.Type = concurrent.futures.ThreadPoolExecutor, # NOQA loop: typing.Optional[asyncio.AbstractEventLoop] = None) -> Executor: """Create `asyncio.loop.run_in_executor` wrapper. Wrapped executor is created from `executor_cls` with provided `args`. Args: args: executor args executor_cls: executor class loop: asyncio loop
optional: bool = False class TypeRef(typing.NamedTuple): module: str name: str Type = typing.Union[TypeRef, 'BooleanType', 'IntegerType', 'BitStringType', 'OctetStringType', 'NullType', 'ObjectIdentifierType', 'StringType', 'ExternalType', 'RealType', 'EnumeratedType', 'EmbeddedPDVType', 'ChoiceType', 'SetType', 'SetOfType', 'SequenceType', 'SequenceOfType', 'EntityType', 'UnsupportedType', 'PrefixedType'] """Type""" util.register_type_alias('Type') class BooleanType(typing.NamedTuple): pass class IntegerType(typing.NamedTuple): pass class BitStringType(typing.NamedTuple): pass class OctetStringType(typing.NamedTuple):
from hat.drivers.iec104 import _iec104 from hat.drivers.iec104 import common mlog: logging.Logger = logging.getLogger(__name__) """Module logger""" InterrogateCb = aio.AsyncCallable[['Connection', int], typing.Optional[typing.List[common.Data]]] """Interrogate callback This method is called when local peer receives interrogate request. Called with asdu address, returns list of data. If ``None`` is returned, negative response is sent. """ util.register_type_alias('InterrogateCb') CounterInterrogateCb = aio.AsyncCallable[ ['Connection', int, common.FreezeCode], typing.Optional[typing.List[common.Data]]] """Counter interrogate callback This method is called when local peer receives counter interrogate request. Called with asdu address and freeze code, returns list of data. If ``None`` is returned, negative response is sent. """ util.register_type_alias('CounterInterrogateCb') CommandCb = aio.AsyncCallable[['Connection', typing.List[common.Command]], bool]
class Node(typing.NamedTuple): """Abstract syntax tree node. Node names are identifiers of parser's definitions and values are other nodes or string values representing matched `Literal`, `Class` or `Dot` leafs. """ name: str value: typing.List[typing.Union['Node', str]] Action = typing.Callable[[Node, typing.List], typing.Any] """Action""" util.register_type_alias('Action') def walk_ast(node: Node, actions: typing.Dict[str, Action], default_action: typing.Optional[Action] = None ) -> typing.Any: """Simple depth-first abstract syntax tree parser. Actions are key value pairs where keys represent node names and values are callables that should be called for appropriate node. Each callable receives matched node and list of results from recursively applying this function on child nodes. For nodes which name doesn't match any action, default action is used. If default action is not defined and node name doesn't match action, result is None and recursion is stopped.
import itertools import json import pathlib import typing import urllib.parse import jsonpatch import jsonschema.validators import yaml from hat import util Array: typing.Type = typing.List['Data'] """JSON Array""" util.register_type_alias('Array') Object: typing.Type = typing.Dict[str, 'Data'] """JSON Object""" util.register_type_alias('Object') Data: typing.Type = typing.Union[None, bool, int, float, str, Array, Object] """JSON data type identifier.""" util.register_type_alias('Data') Format = enum.Enum('Format', ['JSON', 'YAML']) """Encoding format""" Path: typing.Type = typing.Union[int, str, typing.List['Path']] """Data path""" util.register_type_alias('Path')
import sys import threading import asyncio import functools import typing import PySide2.QtCore import PySide2.QtWebEngineWidgets import PySide2.QtWidgets from hat import aio from hat import util QtExecutor = typing.Callable[..., typing.Awaitable[typing.Any]] """First argument is Callable called with additional arguments""" util.register_type_alias('QtExecutor') AsyncMain = typing.Callable[..., typing.Awaitable[typing.Any]] """First argument is QtExecutor""" util.register_type_alias('AsyncMain') def run(async_main: AsyncMain, *args, **kwargs): """Run Qt application with additional asyncio thread Args: async_main: asyncio main entry point args: aditional positional arguments passed to `async_main` kwargs: aditional keyword arguments passed to `async_main` """