redzed 25.12.30__py3-none-any.whl → 26.2.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
redzed/debug.py CHANGED
@@ -1,26 +1,37 @@
1
1
  """
2
- Debug level.
2
+ Debug levels.
3
+ - - - - - -
4
+ Part of the redzed package.
5
+ Docs: https://redzed.readthedocs.io/en/latest/
6
+ Home: https://github.com/xitop/redzed/
3
7
  """
4
8
  from __future__ import annotations
5
9
 
6
- __all__ = ['get_debug_level', 'set_debug_level']
7
-
8
10
  import logging
9
11
  import os
10
12
 
11
13
  from . import circuit
12
14
 
15
+ __all__ = ['get_debug_level', 'set_debug_level']
16
+
13
17
  _logger = logging.getLogger(__package__)
14
- _debug_handler: logging.StreamHandler|None = None
15
18
 
16
19
 
17
- class _CircuitTimeFormatter(logging.Formatter):
18
- """Formatter for debug level 3."""
19
- def format(self, record: logging.LogRecord) -> str:
20
- msg = super().format(record)
21
- if get_debug_level() >= 3:
22
- msg = f"{circuit.get_circuit().runtime():.03f} {msg}"
23
- return msg
20
+ def get_level_from_env() -> int|None:
21
+ if (env_level := os.environ.get('REDZED_DEBUG', '')) == '':
22
+ return None
23
+ try:
24
+ level = int(env_level)
25
+ except Exception:
26
+ pass
27
+ else:
28
+ if 0 <= level <= 3:
29
+ return level
30
+ _logger.warning(
31
+ "Envvar 'REDZED_DEBUG' should be: 0 (disabled), 1 (normal), "
32
+ + "2 (verbose) or 3 (verbose with circuit timestamps)")
33
+ _logger.error("Ignoring REDZED_DEBUG='%s'. Please use a correct value.", env_level)
34
+ return None
24
35
 
25
36
 
26
37
  class _DebugLevel:
@@ -31,56 +42,62 @@ class _DebugLevel:
31
42
  """
32
43
 
33
44
  def __init__(self) -> None:
34
- self._level = -1 # make sure the set_level's core will run
35
- self.set_level(self._get_level_from_env())
36
-
37
- def _get_level_from_env(self) -> int:
38
- try:
39
- level = os.environ['REDZED_DEBUG']
40
- except KeyError:
41
- return 0
42
- level = level.strip()
43
- if not level:
44
- return 0
45
- if level in {'0', '1', '2', '3'}:
46
- return int(level)
47
- _logger.warning(
48
- "Envvar 'REDZED_DEBUG' should be: 0 (disabled), 1 (normal), "
49
- + "2 (verbose) or 3 (verbose with circuit timestamps)")
50
- _logger.warning("Ignoring REDZED_DEBUG='%s'. Please use a correct value.", level)
51
- return 0
52
-
53
- def get_level(self) -> int:
45
+ if (level := get_level_from_env()) is None:
46
+ level = 0
47
+ self._level = level
48
+ _logger.debug("[Logging] Debug level: %d", level)
49
+
50
+ @property
51
+ def level(self) -> int:
54
52
  return self._level
55
53
 
56
- def set_level(self, level: int) -> None:
54
+ @level.setter
55
+ def level(self, level: int) -> None:
57
56
  """Set debug level."""
58
- global _debug_handler # pylint: disable=global-statement
59
-
60
- if not isinstance(level, int):
61
- raise TypeError(f"Expected an integer, got {level!r}")
62
57
  if level == self._level:
63
58
  return
59
+ if not isinstance(level, int):
60
+ raise TypeError(f"Expected an integer, got {level!r}")
64
61
  if not 0 <= level <= 3:
65
62
  raise ValueError(f"Debug level must be an integer 0 to 3, but got {level}")
66
- # self._level is -1 on initial call
67
- if self._level >= 0:
68
- _logger.debug("Debug level: %d -> %d", self._level, level)
69
- elif level > 0:
70
- _logger.debug("Debug level: %d", level)
63
+ _logger.debug("[Logging] Debug level: %d -> %d", self._level, level)
71
64
  self._level = level
72
- if level == 0:
73
- if _debug_handler is not None:
74
- _logger.removeHandler(_debug_handler)
75
- _debug_handler = None
76
- _logger.setLevel(logging.WARNING)
77
- elif not _logger.hasHandlers() and _debug_handler is None:
78
- _logger.addHandler(_debug_handler := logging.StreamHandler())
79
- _debug_handler.setFormatter(_CircuitTimeFormatter("%(levelname)s - %(message)s"))
80
- _logger.setLevel(logging.DEBUG)
81
65
 
82
66
 
83
- _global_debug_level = _DebugLevel()
67
+ _debug_level = _DebugLevel()
68
+
69
+
70
+ def get_debug_level():
71
+ """Get the debug level."""
72
+ return _debug_level.level
84
73
 
85
- get_debug_level = _global_debug_level.get_level
86
- set_debug_level = _global_debug_level.set_level
74
+
75
+ def set_debug_level(level):
76
+ """
77
+ Set the debug level.
78
+
79
+ Also make sure debug messages will be logged or printed.
80
+ For this purpose, if there is no handler, add an own stream handler.
81
+ """
82
+ _debug_level.level = level
83
+ if circuit.get_circuit().get_state() in [
84
+ circuit.CircuitState.UNDER_CONSTRUCTION, circuit.CircuitState.CLOSED]:
85
+ return
86
+ if level > 0:
87
+ if not _logger.hasHandlers():
88
+ _logger.addHandler(logging.StreamHandler())
89
+ _logger.propagate = False
90
+ _logger.setLevel(logging.DEBUG)
91
+ else:
92
+ _logger.setLevel(logging.NOTSET if _logger.propagate else logging.INFO)
93
+
94
+
95
+ class _CircuitTimeFilter(logging.Filter):
96
+ """Filter adding timestamsps in debug level 3."""
97
+ def filter(self, record: logging.LogRecord) -> bool:
98
+ if _debug_level.level >= 3 and isinstance(record.msg, str):
99
+ record.msg = f"{circuit.get_circuit().runtime():.03f} {record.msg}"
100
+ return True
101
+
102
+
103
+ _logger.addFilter(_CircuitTimeFilter())
redzed/formula_trigger.py CHANGED
@@ -194,12 +194,8 @@ class Formula(base_block.BlockOrFormula):
194
194
  self._evaluate_active = False
195
195
  return triggers
196
196
 
197
- def formula(name: str, *args, **kwargs) -> Callable[[_FUNC], _FUNC]:
197
+ def formula(func: _FUNC) -> _FUNC:
198
198
  """@formula() creates a Formula block with the decorated function."""
199
- if 'func' in kwargs:
200
- # Argument func=... will be supplied by us
201
- raise TypeError("@formula() got an unexpected keyword argument 'func='")
202
- def decorator(func: _FUNC) -> _FUNC:
203
- Formula(name, *args, func=func, **kwargs)
204
- return func
205
- return decorator
199
+ comment = '' if func.__doc__ is None else inspect.cleandoc(func.__doc__).partition('\n')[0]
200
+ Formula(func.__name__, func=func, comment=comment)
201
+ return func
redzed/initializers.py CHANGED
@@ -2,8 +2,8 @@
2
2
  Block initializers.
3
3
  - - - - - -
4
4
  Part of the redzed package.
5
- # Docs: https://redzed.readthedocs.io/en/latest/
6
- # Project home: https://github.com/xitop/redzed/
5
+ Docs: https://redzed.readthedocs.io/en/latest/
6
+ Project home: https://github.com/xitop/redzed/
7
7
  """
8
8
  from __future__ import annotations
9
9
 
@@ -18,7 +18,7 @@ import typing as t
18
18
 
19
19
  from . import block
20
20
  from .undef import UNDEF, UndefType
21
- from .utils import check_async_func, time_period
21
+ from .utils import time_period
22
22
 
23
23
 
24
24
  _LONG_TIMEOUT = 60 # threshold for a "long timeout" debug message
@@ -225,19 +225,18 @@ class InitTask(AsyncInitializer):
225
225
 
226
226
  def __init__(
227
227
  self,
228
- coro_func: Callable[..., Awaitable[t.Any]],
228
+ aw_func: Callable[..., Awaitable[t.Any]],
229
229
  *args: t.Any,
230
230
  timeout: float|str = 10.0
231
231
  ) -> None:
232
232
  """Similar to InitFunction, but asynchonous."""
233
- check_async_func(coro_func)
234
233
  super().__init__(timeout)
235
- self._corofunc = coro_func
234
+ self._aw_func = aw_func
236
235
  self._args = args
237
236
 
238
237
  async def _async_get_init(self) -> t.Any:
239
238
  async with asyncio.timeout(self._timeout):
240
- return await self._corofunc(*self._args)
239
+ return await self._aw_func(*self._args)
241
240
 
242
241
 
243
242
  class InitWait(AsyncInitializer):
redzed/py.typed ADDED
File without changes
redzed/signal_shutdown.py CHANGED
@@ -2,8 +2,8 @@
2
2
  Stop the runner with a signal.
3
3
  - - - - - -
4
4
  Part of the redzed package.
5
- # Docs: https://redzed.readthedocs.io/en/latest/
6
- # Project home: https://github.com/xitop/redzed/
5
+ Docs: https://redzed.readthedocs.io/en/latest/
6
+ Project home: https://github.com/xitop/redzed/
7
7
  """
8
8
  from __future__ import annotations
9
9
 
@@ -55,7 +55,7 @@ class TerminatingSignal:
55
55
  """A signal handler."""
56
56
  # - we need the _threadsafe variant of call_soon
57
57
  # - get_running loop() and get_circuit() will succeed,
58
- # because this handler is active only during edzed.run()
58
+ # because this handler is active only during redzed.run()
59
59
  msg = f"Signal {self._signame!r} caught"
60
60
  call_soon = asyncio.get_running_loop().call_soon_threadsafe
61
61
  call_soon(_logger.warning, "%s", msg)
redzed/undef.py CHANGED
@@ -2,8 +2,8 @@
2
2
  The UNDEF singleton constant.
3
3
  - - - - - -
4
4
  Part of the redzed package.
5
- # Docs: https://redzed.readthedocs.io/en/latest/
6
- # Home: https://github.com/xitop/redzed/
5
+ Docs: https://redzed.readthedocs.io/en/latest/
6
+ Home: https://github.com/xitop/redzed/
7
7
  """
8
8
  from __future__ import annotations
9
9
 
@@ -8,7 +8,7 @@ import asyncio
8
8
  from collections.abc import Awaitable
9
9
  import typing as t
10
10
 
11
- __all__ = ['BufferShutDown', 'cancel_shield', 'MsgSync']
11
+ __all__ = ['BufferShutDown', 'cancel_shield']
12
12
 
13
13
  try:
14
14
  BufferShutDown = asyncio.QueueShutDown # Python 3.13+
@@ -18,105 +18,6 @@ except AttributeError:
18
18
 
19
19
 
20
20
  _T = t.TypeVar("_T")
21
- _MISSING = object()
22
-
23
- class MsgSync(t.Generic[_T]):
24
- """
25
- Task synchronization based on sending messages of type _T.
26
-
27
- The count of unread message is always either zero or one,
28
- because messages are not queued. A new message replaces
29
- the previous unread one, if any.
30
-
31
- An existing unread message is available immediately.
32
- Otherwise the recipient must wait and will be awakened when
33
- a new message arrives. Reading a message consumes it,
34
- so each message can reach only one receiver.
35
- """
36
-
37
- def __init__(self) -> None:
38
- self._msg: t.Any = _MISSING
39
- self._shutdown = False
40
- self._has_data = asyncio.Event() # valid before shutdown
41
- self._draining = False # valid after shutdown
42
-
43
- def shutdown(self) -> None:
44
- """
45
- Disallow sending immediately. Disallow receiving after the MsgSync gets empty.
46
-
47
- Calls to .send() will raise BufferShutDown.
48
-
49
- If a message was sent before shutdown and is waiting, it can be
50
- normally received before the receiver shuts down too. After
51
- the shutdown all blocked callers will be unblocked with BufferShutDown.
52
- Calls to .recv() will raise BufferShutDown as well.
53
- """
54
- self._shutdown = True
55
- self._draining = self._has_data.is_set()
56
- if not self._draining:
57
- # wakeup all waiters
58
- self._has_data.set()
59
-
60
- def is_shutdown(self) -> bool:
61
- """Check if the buffer was shut down."""
62
- return self._shutdown
63
-
64
- def send(self, msg: _T) -> None:
65
- """
66
- Send a message to one receiver.
67
-
68
- If the previously sent message hasn't been received yet,
69
- the new message overwrites it.
70
- """
71
- if self._shutdown:
72
- raise BufferShutDown("The buffer was shut down")
73
- self._msg = msg
74
- self._has_data.set()
75
-
76
- def clear(self) -> None:
77
- """Remove the waiting message."""
78
- if self._shutdown:
79
- self._draining = False
80
- else:
81
- self._has_data.clear()
82
- self._msg = _MISSING
83
-
84
- def has_data(self) -> bool:
85
- """Return True only if there is a waiting message."""
86
- return self._draining if self._shutdown else self._has_data.is_set()
87
-
88
- async def _recv(self) -> _T:
89
- """Receive (consume) a message."""
90
- while not self._has_data.is_set():
91
- await self._has_data.wait()
92
- if not self._shutdown:
93
- self._has_data.clear()
94
- elif self._draining:
95
- self._draining = False
96
- else:
97
- raise BufferShutDown("The buffer was shut down")
98
- msg, self._msg = self._msg, _MISSING
99
- return t.cast(_T, msg)
100
-
101
- async def recv(self, timeout: float | None = None, default: t.Any = _MISSING) -> t.Any:
102
- """
103
- Receive a message with optional timeout.
104
-
105
- If a message is not available, wait until it arrives.
106
-
107
- If a timeout [seconds] is given, return the default value
108
- if no message is received before the timeout period elapses.
109
- Without a default, raise the TimeoutError.
110
- """
111
- if timeout is None:
112
- return await self._recv()
113
- try:
114
- async with asyncio.timeout(timeout):
115
- return await self._recv()
116
- except TimeoutError:
117
- if default is not _MISSING:
118
- return default
119
- raise
120
21
 
121
22
 
122
23
  async def cancel_shield(aw: Awaitable[_T]) -> _T:
@@ -4,12 +4,11 @@ Small utilities.
4
4
  from __future__ import annotations
5
5
 
6
6
  __all__ = [
7
- 'check_async_coro', 'check_async_func', 'check_identifier', 'func_call_string',
7
+ 'check_identifier', 'func_name', 'func_call_string',
8
8
  'is_multiple', 'tasks_are_eager', 'to_tuple']
9
9
 
10
10
  import asyncio
11
11
  from collections.abc import Callable, Mapping, Sequence
12
- import inspect
13
12
  import itertools
14
13
  import logging
15
14
  import typing as t
@@ -24,7 +23,7 @@ def check_identifier(name: t.Any, msg_prefix: str) -> None:
24
23
  if not name:
25
24
  raise ValueError(f"{msg_prefix} cannot be an empty string")
26
25
  if not name.isidentifier():
27
- raise ValueError(f"{msg_prefix} must be a valid identifier, got '{name!r}'")
26
+ raise ValueError(f"{msg_prefix} must be a valid identifier, got '{name}'")
28
27
 
29
28
 
30
29
  def is_multiple(arg: t.Any) -> bool:
@@ -50,19 +49,29 @@ def to_tuple(args: _T_item|Sequence[_T_item]) -> tuple[_T_item, ...]:
50
49
  return t.cast(tuple[_T_item], (args,))
51
50
 
52
51
 
53
- # must not touch *kwargs* # pylint: disable-next=dangerous-default-value
52
+ def func_name(func: Callable[..., t.Any]) -> str:
53
+ """Return the name of a callable."""
54
+ if not callable(func):
55
+ raise TypeError(f"{func!r} is not callable")
56
+ if (name := getattr(func, '__name__', None)) is not None:
57
+ return name
58
+ # callable objects with __call__ do not have a __name__
59
+ if not isinstance(func, type) and (hasattr(ftype := type(func), '__call__')):
60
+ return f'{ftype.__name__}.__call__'
61
+ # fail-safe default, though there is no such type of callable
62
+ return ftype.__name__
63
+
64
+
54
65
  def func_call_string(
55
66
  func: Callable[..., t.Any]|None,
56
67
  args: Sequence[t.Any],
57
- kwargs: Mapping[str, t.Any] = {}
68
+ kwargs: Mapping[str, t.Any]|None = None
58
69
  ) -> str:
59
70
  """Convert args and kwargs to a printable string."""
60
- arglist = '(' + ', '.join(itertools.chain(
61
- (repr(a) for a in args),
62
- (f"{k}={v!r}" for k, v in kwargs.items()))) + ')'
63
- if func is None:
64
- return arglist
65
- return func.__name__ + arglist
71
+ agen = (repr(a) for a in args)
72
+ gen = itertools.chain(agen, (f"{k}={v!r}" for k, v in kwargs.items())) if kwargs else agen
73
+ arglist = f"({', '.join(gen)})"
74
+ return arglist if func is None else func_name(func) + arglist
66
75
 
67
76
 
68
77
  def tasks_are_eager() -> bool:
@@ -81,36 +90,3 @@ def tasks_are_eager() -> bool:
81
90
  flag = True
82
91
  asyncio.create_task(test_task())
83
92
  return flag
84
-
85
-
86
- def check_async_coro(arg: t.Any) -> None:
87
- """
88
- Check if arg is a coroutine object.
89
-
90
- Raise a TypeError with a descriptive message if it isn't.
91
- """
92
- if inspect.iscoroutine(arg):
93
- return
94
- if inspect.iscoroutinefunction(arg):
95
- received = f"an async function '{arg.__name__}'. Did you mean '{arg.__name__}()'?"
96
- else:
97
- received = repr(arg)
98
- raise TypeError(f"Expected a coroutine, but got {received}")
99
-
100
-
101
- def check_async_func(arg: t.Any) -> None:
102
- """
103
- Check if *arg* is an async function.
104
-
105
- Raise a TypeError with a descriptive message if it isn't.
106
- """
107
- if inspect.iscoroutinefunction(arg):
108
- return
109
- if inspect.iscoroutine(arg):
110
- received = (f"a coroutine '{arg.__name__}()'. "
111
- + f"Did you mean '{arg.__name__}' without parentheses?")
112
- elif callable(arg):
113
- received = f"a non-async function/callable '{arg.__name__}'"
114
- else:
115
- received = repr(arg)
116
- raise TypeError(f"Expected an async function, but got {received}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: redzed
3
- Version: 25.12.30
3
+ Version: 26.2.4
4
4
  Summary: An asyncio-based library for building small automated systems
5
5
  Author-email: Vlado Potisk <redzed@poti.sk>
6
6
  License-Expression: MIT
@@ -8,7 +8,7 @@ Project-URL: homepage, https://github.com/xitop/redzed
8
8
  Project-URL: repository, https://github.com/xitop/redzed
9
9
  Project-URL: documentation, https://redzed.readthedocs.io/en/latest/
10
10
  Keywords: automation,finite-state machine
11
- Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Development Status :: 4 - Beta
12
12
  Classifier: Intended Audience :: Developers
13
13
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
14
14
  Classifier: Programming Language :: Python :: 3
@@ -0,0 +1,30 @@
1
+ redzed/__init__.py,sha256=IVRc3KnMDB9N_M0fiii8X84I6_AEjhmOqtrzAJbvuzY,1097
2
+ redzed/base_block.py,sha256=A1ZxEIH8jsNXj3z3HvzgAVshUsMoFtqIoR41-U2vMaw,5187
3
+ redzed/block.py,sha256=_Qp8DQ1Ojb_PuGcYy2xS4gkhUeQymIx69iJaKHUM9jQ,11768
4
+ redzed/circuit.py,sha256=6C1mmg83Z_mjCHUpLlU9mdK4297cjrBycIuUUnjSB5E,31894
5
+ redzed/cron_service.py,sha256=0RSIte6zkbF4mSojrPoVFMHkVep1OZ2Mv2BtG3YiPTs,11372
6
+ redzed/debug.py,sha256=hsHbBxPOOUVL_utfiRnkRh49FszDvHsCZ9xAqxawUIU,2868
7
+ redzed/formula_trigger.py,sha256=lkBMeLVrcvqA71WGGapj9hitm52-dATMgT5QFhC1lOY,7360
8
+ redzed/initializers.py,sha256=1vqnxvQTRYJunAOmYMuZAOL9sr1GPP9Wz2FK92o4wVc,7740
9
+ redzed/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ redzed/signal_shutdown.py,sha256=BAolHuMw-P86R8cSIebjsvUDZOSt-PanKFA0iQS1GIc,2078
11
+ redzed/undef.py,sha256=0Q70QdtbmCHbAmFwJJ7L8CILi1-hxYOKU5nlR5EyH9I,892
12
+ redzed/blocklib/__init__.py,sha256=au7jbjO_RUFzK5U4STk-7pc1DTVA0OVh2W_aKsx1Y3s,557
13
+ redzed/blocklib/counter.py,sha256=pUT5Np31gk1rP2LqaTjJdzdyyS8NhpD9104Re_MtLpY,1251
14
+ redzed/blocklib/fsm.py,sha256=3UVQyKwZstL96jf3HYfuvN6R49uOMXVo20MFz9EpGkc,24746
15
+ redzed/blocklib/inputs.py,sha256=YtKtbDUtXyQyUTNadniwyxCA_-UPCgrrY17EipfXcaI,6223
16
+ redzed/blocklib/outputs.py,sha256=77FwFzh3q1Ri7tsAi39fmojD0vMmwBTSAYEjf1ZABpg,13964
17
+ redzed/blocklib/repeat.py,sha256=R4f0WjTTnqpiYOHDCHucmGdp6ChyVozLaZDaE-Nx7Tc,3146
18
+ redzed/blocklib/timedate.py,sha256=bmYZx6ToYsuD3UQzc1zxD2ddvovzF0A63-y4Pnkrm6Q,5225
19
+ redzed/blocklib/timeinterval.py,sha256=alK68glDdWPD9SWxZ97pEzhQIReC41RMdXrRIRZsyuE,6878
20
+ redzed/blocklib/timer.py,sha256=fCQTbmBOqo7pc6k32yj7JoyUM9XbdgHOXzu2tRiOiJE,1483
21
+ redzed/blocklib/validator.py,sha256=6r0qtPIJ2neCP32WhI7tGxEUus_ji6kx_jrzHd2_M9I,1312
22
+ redzed/utils/__init__.py,sha256=Yo8cj1f1HQj862UOdCsXOkMg4kfq1c5S3HJDhuiE5os,326
23
+ redzed/utils/async_utils.py,sha256=ABwloG7YKqRwfIwWsXNaGlNPc7MdEdq29-aRGRDsBgk,1075
24
+ redzed/utils/data_utils.py,sha256=hesExhPcM2-IZPbDXAuGCUMpCI4YiNodp_ZJUj0_h9I,2952
25
+ redzed/utils/time_utils.py,sha256=eCqk4T4ipn4hgzL8-4Usn1W6kkTyRCuQ9-BMSvnELww,8524
26
+ redzed-26.2.4.dist-info/licenses/LICENSE.txt,sha256=brj9B7uNdzUvTJON_5Eibf7zeLRhcMuBYMInalu0KlI,1091
27
+ redzed-26.2.4.dist-info/METADATA,sha256=nQARn1_dngD-r1UBeYDVthqAwmqy6taWhJhDlP14kNo,2055
28
+ redzed-26.2.4.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
29
+ redzed-26.2.4.dist-info/top_level.txt,sha256=7Rt0BRMqaJ0AGAmrd2JDqmqSY4cmQeW--7u6KDV1gZg,7
30
+ redzed-26.2.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Vlado Potisk <redzed@poti.sk>
3
+ Copyright (c) 2025-2026 Vlado Potisk <redzed@poti.sk>
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,28 +0,0 @@
1
- redzed/__init__.py,sha256=eyvuX8qwxEFuiP6jOu4x1qv-AmHJAGKOziV1dKCNWWA,1098
2
- redzed/base_block.py,sha256=NzJhY0POAJUyfp9EcQG2RvXM472vAV5iWG5LdsScpso,5191
3
- redzed/block.py,sha256=0iwK8Pb5LJ0xzoOt5dkx-FeWplzUzAWHOWfah368u7s,12012
4
- redzed/circuit.py,sha256=VkcAZZg5HfEdboUZ_vMnElI9E4MprwaoBveN8-hUvZw,31095
5
- redzed/cron_service.py,sha256=f-YR0w2U0dpipX271cyUYXvsvJunpE3mywuV7SkFE_k,10581
6
- redzed/debug.py,sha256=QeWHpfTZADPB6nY0zrj1Aqo91Wd9HB9bAJVgq_d3hCo,2767
7
- redzed/formula_trigger.py,sha256=0_TVbR1wCQ0Wv7NlJtcfD-iDUbmTBlbVCSdbKDw_tX0,7516
8
- redzed/initializers.py,sha256=oF5Wkdu2REFdfuCEdo8kS-9N2uW2dhdzYWoibILB3ks,7804
9
- redzed/signal_shutdown.py,sha256=KjL6Kq9K0m_2nerjo7hryNFPhgdNTmSyTOfDi-SMsjA,2081
10
- redzed/undef.py,sha256=iPxcUIKBDh5wqjdr8qvs9EQkx5s52ryNDY22at-PF0c,896
11
- redzed/blocklib/__init__.py,sha256=au7jbjO_RUFzK5U4STk-7pc1DTVA0OVh2W_aKsx1Y3s,557
12
- redzed/blocklib/counter.py,sha256=XvJPOarg6RZ9H-GrWFQrt3JJnGk9YGc1B7NOpF6ju4A,1125
13
- redzed/blocklib/fsm.py,sha256=6Qv4pOsF-FOEBm9NQUSD6F2yLfb0chvbpvbrgg3sIk8,23492
14
- redzed/blocklib/inputs.py,sha256=hhfU2Id7oJfmhZB-_PoowXBfYDuw9OQyceg_AprJVVs,7218
15
- redzed/blocklib/outputs.py,sha256=hoBPr_978PyhR6OzD0rxou34PFukIRD1pIpK6JNgqQE,12894
16
- redzed/blocklib/repeat.py,sha256=hkIO7qgm4wS32dcKkkfL_DjnoKWf-l3k2DfRiRUk6iE,2500
17
- redzed/blocklib/timedate.py,sha256=78wqiH1mUz5zoz3ZgDOmsPaYYmQLypgt9IfmLUcH9Cw,5196
18
- redzed/blocklib/timeinterval.py,sha256=hxPhao1Gm9q_NOp6WdjmsStkrfwkadH5uJh-Hli9D-4,6752
19
- redzed/blocklib/timer.py,sha256=X3CoqwGJ46oLw0R5u0HK1a11VpcZdTWvPbWOkFjZrDI,1520
20
- redzed/utils/__init__.py,sha256=Yo8cj1f1HQj862UOdCsXOkMg4kfq1c5S3HJDhuiE5os,326
21
- redzed/utils/async_utils.py,sha256=Vknijh9rABL8GcJbYv6a7I4qO2VLerMsGTr5wiGWbjo,4486
22
- redzed/utils/data_utils.py,sha256=xiaVnEJF7Q9oGFqqTOyiVyzI-sG0lYHxImfyFcXjwFI,3542
23
- redzed/utils/time_utils.py,sha256=eCqk4T4ipn4hgzL8-4Usn1W6kkTyRCuQ9-BMSvnELww,8524
24
- redzed-25.12.30.dist-info/licenses/LICENSE.txt,sha256=HwuPxdAOIKlSWHESVtk6Zov7d0BZaPu74eruoZc5UN8,1086
25
- redzed-25.12.30.dist-info/METADATA,sha256=LiyTs38Xa48jh2ozWNw1uUICaNKrTg7xWSUd1vEHTK0,2058
26
- redzed-25.12.30.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
- redzed-25.12.30.dist-info/top_level.txt,sha256=7Rt0BRMqaJ0AGAmrd2JDqmqSY4cmQeW--7u6KDV1gZg,7
28
- redzed-25.12.30.dist-info/RECORD,,