mobilus-client 0.1.dev0__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.
Files changed (41) hide show
  1. mobilus_client/__init__.py +0 -0
  2. mobilus_client/__main__.py +60 -0
  3. mobilus_client/app.py +63 -0
  4. mobilus_client/config.py +20 -0
  5. mobilus_client/messages/__init__.py +0 -0
  6. mobilus_client/messages/encryptor.py +88 -0
  7. mobilus_client/messages/factory.py +66 -0
  8. mobilus_client/messages/serializer.py +20 -0
  9. mobilus_client/messages/status.py +7 -0
  10. mobilus_client/messages/validator.py +16 -0
  11. mobilus_client/mqtt_client.py +87 -0
  12. mobilus_client/proto/__init__.py +20 -0
  13. mobilus_client/proto/call_events_request.proto +15 -0
  14. mobilus_client/proto/call_events_request_pb2.py +38 -0
  15. mobilus_client/proto/call_events_request_pb2.pyi +63 -0
  16. mobilus_client/proto/current_state_request.proto +4 -0
  17. mobilus_client/proto/current_state_request_pb2.py +36 -0
  18. mobilus_client/proto/current_state_request_pb2.pyi +20 -0
  19. mobilus_client/proto/current_state_response.proto +15 -0
  20. mobilus_client/proto/current_state_response_pb2.py +38 -0
  21. mobilus_client/proto/current_state_response_pb2.pyi +63 -0
  22. mobilus_client/proto/devices_list_request.proto +4 -0
  23. mobilus_client/proto/devices_list_request_pb2.py +36 -0
  24. mobilus_client/proto/devices_list_request_pb2.pyi +20 -0
  25. mobilus_client/proto/devices_list_response.proto +16 -0
  26. mobilus_client/proto/devices_list_response_pb2.py +38 -0
  27. mobilus_client/proto/devices_list_response_pb2.pyi +68 -0
  28. mobilus_client/proto/login_request.proto +6 -0
  29. mobilus_client/proto/login_request_pb2.py +36 -0
  30. mobilus_client/proto/login_request_pb2.pyi +30 -0
  31. mobilus_client/proto/login_response.proto +10 -0
  32. mobilus_client/proto/login_response_pb2.py +36 -0
  33. mobilus_client/proto/login_response_pb2.pyi +42 -0
  34. mobilus_client/registries/key.py +33 -0
  35. mobilus_client/registries/message.py +43 -0
  36. mobilus_client/utils/encryption.py +21 -0
  37. mobilus_client/utils/types.py +23 -0
  38. mobilus_client-0.1.dev0.dist-info/METADATA +118 -0
  39. mobilus_client-0.1.dev0.dist-info/RECORD +41 -0
  40. mobilus_client-0.1.dev0.dist-info/WHEEL +4 -0
  41. mobilus_client-0.1.dev0.dist-info/licenses/LICENSE +21 -0
File without changes
@@ -0,0 +1,60 @@
1
+ import argparse
2
+ import logging
3
+ import sys
4
+ from typing import Tuple, Dict
5
+ from mobilus_client.config import Config
6
+ from mobilus_client.app import App
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+
11
+ def main() -> None:
12
+ parser = argparse.ArgumentParser(
13
+ description="Run Mobilus Client with specific commands and parameters."
14
+ )
15
+ parser.add_argument('--host', required=True, help="Cosmo GTW address")
16
+ parser.add_argument('--login', required=True, help="User login")
17
+ parser.add_argument('--password', required=True, help="User password")
18
+ parser.add_argument('--verbose', action='store_true', help="Enable verbose logging")
19
+ parser.add_argument('commands', nargs='+', help="Commands to run")
20
+
21
+ # Parse arguments
22
+ args = parser.parse_args()
23
+
24
+ # Create a config object
25
+ config = Config(
26
+ gateway_host=args.host,
27
+ user_login=args.login,
28
+ user_password=args.password,
29
+ )
30
+
31
+ # Set up logging
32
+ logging.basicConfig(
33
+ stream=sys.stdout,
34
+ level=logging.DEBUG if args.verbose else logging.WARNING,
35
+ format='{"name": "[%(name)s]", "levelname": "%(levelname)s", "message": "%(message)s"}'
36
+ )
37
+
38
+ commands = []
39
+ for command_str in args.commands:
40
+ command, params = _parse_command(command_str)
41
+ commands.append((command, params))
42
+
43
+ app = App(config)
44
+ responses = app.call(commands)
45
+ print(responses)
46
+
47
+
48
+ def _parse_command(command_str: str) -> Tuple[str, Dict[str, str]]:
49
+ """
50
+ " Parse a command string into a command and a dictionary of parameters. "
51
+ " Example: 'command:param1=value1,param2=value2' "
52
+ " Returns: ('command', {'param1': 'value1', 'param2': 'value2'}) "
53
+ """
54
+ command, *params = command_str.split(':', 1)
55
+ params_dict = dict(param.split('=') for param in params[0].split(',')) if params else {}
56
+ return command, params_dict
57
+
58
+
59
+ if __name__ == '__main__':
60
+ main()
mobilus_client/app.py ADDED
@@ -0,0 +1,63 @@
1
+ import logging
2
+ import socket
3
+ from typing import Dict, List, Tuple
4
+ from mobilus_client.config import Config
5
+ from mobilus_client.messages.serializer import MessageSerializer
6
+ from mobilus_client.mqtt_client import MqttClient
7
+ from mobilus_client.registries.message import MessageRegistry
8
+ from mobilus_client.registries.key import KeyRegistry
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ class App:
14
+ def __init__(self, config: Config) -> None:
15
+ self.config = config
16
+ self.message_registry = MessageRegistry()
17
+ self.key_registry = KeyRegistry(config.user_key)
18
+ self.client = MqttClient(
19
+ client_id=config.client_id,
20
+ transport=config.gateway_protocol,
21
+ userdata={
22
+ "config": config,
23
+ "key_registry": self.key_registry,
24
+ "message_registry": self.message_registry,
25
+ }
26
+ )
27
+
28
+ def call(self, commands: List[Tuple[str, Dict[str, str]]]) -> str:
29
+ if not commands:
30
+ return self._empty_response()
31
+
32
+ try:
33
+ # Connect to the MQTT broker and start the loop
34
+ self.client.connect(self.config.gateway_host, self.config.gateway_port, 60)
35
+ self.client.loop_start()
36
+
37
+ # Wait for the client to authenticate
38
+ self.client.authenticated_event.wait(timeout=self.config.auth_timeout_period)
39
+
40
+ if not self.client.authenticated_event.is_set():
41
+ logger.error("Failed to authenticate with the gateway host")
42
+ return self._empty_response()
43
+
44
+ # Execute the provided commands
45
+ for command, params in commands:
46
+ self.client.send_request(command, **params)
47
+
48
+ # Wait for the completion event to be triggered
49
+ self.client.completed_event.wait(timeout=self.config.timeout_period)
50
+ except socket.gaierror:
51
+ logger.error("Failed to connect to the gateway host")
52
+ except TimeoutError:
53
+ logger.error("Timeout occurred")
54
+ finally:
55
+ self.client.disconnect()
56
+
57
+ # Return serialized responses from the message registry
58
+ return MessageSerializer.serialize_list_to_json(
59
+ self.message_registry.get_responses()
60
+ )
61
+
62
+ def _empty_response(self) -> str:
63
+ return MessageSerializer.serialize_list_to_json([])
@@ -0,0 +1,20 @@
1
+ import random
2
+ from dataclasses import dataclass
3
+ from mobilus_client.utils.encryption import create_key
4
+
5
+
6
+ @dataclass
7
+ class Config:
8
+ gateway_host: str
9
+ user_login: str
10
+ user_password: str
11
+
12
+ auth_timeout_period: float = 30
13
+ client_id: str = ''.join(random.choice('0123456789ABCDEF') for _ in range(12))
14
+ gateway_port: int = 8884
15
+ gateway_protocol: str = "websockets"
16
+ timeout_period: float = 30
17
+ user_key: bytes = b''
18
+
19
+ def __post_init__(self) -> None:
20
+ self.user_key = create_key(self.user_password)
File without changes
@@ -0,0 +1,88 @@
1
+ import struct
2
+ import time
3
+ from google.protobuf.message import DecodeError
4
+ from typing import cast, Optional
5
+ from mobilus_client.registries.key import KeyRegistry
6
+ from mobilus_client.proto import (
7
+ CallEventsRequest,
8
+ CurrentStateRequest,
9
+ CurrentStateResponse,
10
+ DevicesListRequest,
11
+ DevicesListResponse,
12
+ LoginRequest,
13
+ LoginResponse
14
+ )
15
+ from mobilus_client.utils.encryption import create_iv, decrypt_body, encrypt_body
16
+ from mobilus_client.utils.types import MessageRequest, MessageResponse
17
+
18
+
19
+ class MessageEncryptor:
20
+ CATEGORY_MAP = {
21
+ 1: LoginRequest,
22
+ 2: LoginResponse,
23
+ 3: DevicesListRequest,
24
+ 4: DevicesListResponse,
25
+ 13: CallEventsRequest,
26
+ 26: CurrentStateRequest,
27
+ 27: CurrentStateResponse,
28
+ }
29
+ CLASS_TO_CATEGORY_MAP = {v: k for k, v in CATEGORY_MAP.items()}
30
+
31
+ @staticmethod
32
+ def encrypt(message: MessageRequest, client_id: str, key_registry: KeyRegistry) -> bytes:
33
+ category = MessageEncryptor.CLASS_TO_CATEGORY_MAP.get(type(message))
34
+ body = message.SerializeToString()
35
+ timestamp = int(time.time())
36
+ length = 13
37
+
38
+ private_key = key_registry.get_encryption_key(type(message))
39
+
40
+ if private_key is None:
41
+ encrypted_body = body
42
+ else:
43
+ iv = create_iv(timestamp)
44
+ encrypted_body = encrypt_body(private_key, iv, body)
45
+
46
+ return (
47
+ struct.pack('>IBI', length, category, timestamp) +
48
+ bytes.fromhex(client_id) +
49
+ struct.pack('>2B', 4, 0) +
50
+ encrypted_body
51
+ )
52
+
53
+ @staticmethod
54
+ def decrypt(encrypted_message: bytes, key_registry: KeyRegistry) -> Optional[MessageResponse]:
55
+ # Define header format and calculate size
56
+ header_format = '>IBI6sBB'
57
+ header_size = struct.calcsize(header_format)
58
+
59
+ # Do early return if message is too short
60
+ if len(encrypted_message) < header_size:
61
+ return None
62
+
63
+ # Unpack header
64
+ length, category, timestamp, user_id, platform, response_code = struct.unpack(
65
+ header_format, encrypted_message[:header_size])
66
+
67
+ # Extract encrypted body
68
+ encrypted_body = encrypted_message[header_size:]
69
+
70
+ # Choose proper klass
71
+ message_klass = MessageEncryptor.CATEGORY_MAP.get(category)
72
+ if message_klass is None:
73
+ return None
74
+
75
+ # Choose proper decryption key
76
+ key = key_registry.get_decryption_key(message_klass)
77
+
78
+ # Decrypt body
79
+ iv = create_iv(timestamp)
80
+ body = decrypt_body(key, iv, encrypted_body)
81
+
82
+ try:
83
+ message = cast(MessageResponse, message_klass())
84
+ message.ParseFromString(body)
85
+ except DecodeError:
86
+ return None
87
+
88
+ return message
@@ -0,0 +1,66 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Any, Optional
3
+ from mobilus_client.proto import (
4
+ CallEvent,
5
+ CallEventsRequest,
6
+ CurrentStateRequest,
7
+ DevicesListRequest,
8
+ LoginRequest,
9
+ )
10
+ from mobilus_client.utils.types import MessageRequest
11
+
12
+
13
+ class MessageBuilder(ABC):
14
+ @abstractmethod
15
+ def build(self, **kwargs: Any) -> Optional[MessageRequest]:
16
+ pass
17
+
18
+
19
+ class LoginMessageBuilder(MessageBuilder):
20
+ def build(self, **kwargs: Any) -> Optional[LoginRequest]:
21
+ if 'login' not in kwargs or 'password' not in kwargs:
22
+ return None
23
+
24
+ request = LoginRequest()
25
+ request.login = str(kwargs['login'])
26
+ request.password = bytes(kwargs['password'])
27
+ return request
28
+
29
+
30
+ class DevicesListMessageBuilder(MessageBuilder):
31
+ def build(self, **kwargs: Any) -> DevicesListRequest:
32
+ return DevicesListRequest()
33
+
34
+
35
+ class CurrentStateMessageBuilder(MessageBuilder):
36
+ def build(self, **kwargs: Any) -> CurrentStateRequest:
37
+ return CurrentStateRequest()
38
+
39
+
40
+ class CallEventsMessageBuilder(MessageBuilder):
41
+ def build(self, **kwargs: Any) -> Optional[CallEventsRequest]:
42
+ if 'device_id' not in kwargs or 'value' not in kwargs:
43
+ return None
44
+
45
+ event = CallEvent()
46
+ event.event_number = int(kwargs.get('event_number', 6))
47
+ event.device_id = int(kwargs['device_id'])
48
+ event.value = str(kwargs['value'])
49
+
50
+ request = CallEventsRequest()
51
+ request.events.append(event)
52
+ return request
53
+
54
+
55
+ class MessageFactory:
56
+ _builders = {
57
+ "call_events": CallEventsMessageBuilder(),
58
+ "current_state": CurrentStateMessageBuilder(),
59
+ "devices_list": DevicesListMessageBuilder(),
60
+ "login": LoginMessageBuilder(),
61
+ }
62
+
63
+ @staticmethod
64
+ def create_message(message_name: str, **kwargs: Any) -> Optional[MessageRequest]:
65
+ builder = MessageFactory._builders.get(message_name)
66
+ return builder.build(**kwargs) if builder else None
@@ -0,0 +1,20 @@
1
+ import json
2
+ from google.protobuf.json_format import MessageToJson
3
+ from mobilus_client.utils.types import MessageResponse
4
+
5
+
6
+ class MessageSerializer:
7
+ @staticmethod
8
+ def serialize_to_json(message: MessageResponse) -> str:
9
+ return MessageToJson(message)
10
+
11
+ @staticmethod
12
+ def serialize_list_to_json(messages: list[MessageResponse]) -> str:
13
+ return json.dumps(
14
+ [
15
+ json.loads(
16
+ MessageSerializer.serialize_to_json(message)
17
+ )
18
+ for message in messages
19
+ ]
20
+ )
@@ -0,0 +1,7 @@
1
+ from enum import Enum
2
+
3
+
4
+ class MessageStatus(Enum):
5
+ SUCCESS = 0
6
+ AUTHENTICATION_ERROR = 1
7
+ UNKNOWN_MESSAGE = 2
@@ -0,0 +1,16 @@
1
+ from typing import Optional, Union
2
+ from mobilus_client.messages.status import MessageStatus
3
+ from mobilus_client.proto import LoginResponse
4
+ from mobilus_client.utils.types import MessageRequest, MessageResponse
5
+
6
+
7
+ class MessageValidator():
8
+ @staticmethod
9
+ def validate(message: Optional[Union[MessageRequest, MessageResponse]]) -> MessageStatus:
10
+ if message is None:
11
+ return MessageStatus.UNKNOWN_MESSAGE
12
+
13
+ if isinstance(message, LoginResponse) and message.login_status == 1:
14
+ return MessageStatus.AUTHENTICATION_ERROR
15
+
16
+ return MessageStatus.SUCCESS
@@ -0,0 +1,87 @@
1
+ import logging
2
+ import paho.mqtt.client as mqtt
3
+ import threading
4
+ from typing import Any, Dict, cast
5
+ from mobilus_client.messages.encryptor import MessageEncryptor
6
+ from mobilus_client.messages.factory import MessageFactory
7
+ from mobilus_client.messages.status import MessageStatus
8
+ from mobilus_client.messages.validator import MessageValidator
9
+ from mobilus_client.proto import (LoginRequest, LoginResponse)
10
+ from mobilus_client.utils.types import MessageRequest
11
+
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class MqttClient(mqtt.Client):
17
+ _userdata: Dict[str, Any]
18
+
19
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
20
+ super().__init__(*args, **kwargs)
21
+ self.authenticated_event = threading.Event()
22
+ self.completed_event = threading.Event()
23
+ self.enable_logger(logger)
24
+
25
+ def send_request(self, command: str, **params: Any) -> None:
26
+ if not self.is_connected():
27
+ logger.error(f"Sending request - {command} failed. Client is not connected.")
28
+ return
29
+
30
+ message = MessageFactory.create_message(command, **params)
31
+ status = MessageValidator.validate(message)
32
+
33
+ if status != MessageStatus.SUCCESS:
34
+ logger.error(f"Command - {command} returned an error - {status.name}")
35
+ self.disconnect()
36
+ return
37
+
38
+ if not isinstance(message, LoginRequest):
39
+ self._userdata['message_registry'].register_request(message)
40
+
41
+ encrypted_message = MessageEncryptor.encrypt(
42
+ cast(MessageRequest, message),
43
+ self._userdata["config"].client_id,
44
+ self._userdata['key_registry']
45
+ )
46
+
47
+ self.publish("module", encrypted_message)
48
+
49
+ def on_disconnect(self, client: mqtt.Client, userdata: Any, reason_code: Any) -> None: # type: ignore
50
+ logger.info(f"Disconnected with result code - {reason_code}")
51
+
52
+ def on_connect(self, client: mqtt.Client, userdata: Any, flags: Any, reason_code: Any) -> None: # type: ignore
53
+ client.subscribe([
54
+ (userdata["config"].client_id, 0),
55
+ ("clients", 0)
56
+ ])
57
+
58
+ def on_subscribe(self, client: mqtt.Client, userdata: Any, mid: Any, granted_qos: Any) -> None: # type: ignore
59
+ self.send_request(
60
+ "login",
61
+ login=userdata["config"].user_login,
62
+ password=userdata["config"].user_key
63
+ )
64
+
65
+ def on_message(self, client: mqtt.Client, userdata: Any, message: Any) -> None: # type: ignore
66
+ logger.info(f"Received message on topic - {message.topic}")
67
+
68
+ message = MessageEncryptor.decrypt(message.payload, userdata["key_registry"])
69
+ logger.info(f"Decrypted message - {type(message).__name__}")
70
+
71
+ status = MessageValidator.validate(message)
72
+
73
+ if status != MessageStatus.SUCCESS:
74
+ logger.error(f"Message - {type(message).__name__} returned an error - {status.name}")
75
+ self.disconnect()
76
+ return
77
+
78
+ logger.info(f"Message - {type(message).__name__} validated successfully")
79
+
80
+ if isinstance(message, LoginResponse):
81
+ userdata["key_registry"].register_keys(message)
82
+ self.authenticated_event.set()
83
+ else:
84
+ userdata["message_registry"].register_response(message)
85
+
86
+ if userdata["message_registry"].all_responses_received():
87
+ self.completed_event.set()
@@ -0,0 +1,20 @@
1
+ from mobilus_client.proto.call_events_request_pb2 import CallEventsRequest, CallEvent
2
+ from mobilus_client.proto.current_state_request_pb2 import CurrentStateRequest
3
+ from mobilus_client.proto.current_state_response_pb2 import CurrentStateResponse, CurrentStateEvent
4
+ from mobilus_client.proto.devices_list_request_pb2 import DevicesListRequest
5
+ from mobilus_client.proto.devices_list_response_pb2 import DevicesListResponse, Device
6
+ from mobilus_client.proto.login_request_pb2 import LoginRequest
7
+ from mobilus_client.proto.login_response_pb2 import LoginResponse
8
+
9
+ __all__ = [
10
+ "CallEvent",
11
+ "CallEventsRequest",
12
+ "CurrentStateRequest",
13
+ "CurrentStateResponse",
14
+ "CurrentStateEvent",
15
+ "Device",
16
+ "DevicesListRequest",
17
+ "DevicesListResponse",
18
+ "LoginRequest",
19
+ "LoginResponse"
20
+ ]
@@ -0,0 +1,15 @@
1
+ syntax = "proto2";
2
+
3
+ message CallEvent {
4
+ optional int64 id = 1;
5
+ optional int64 device_id = 2;
6
+ optional int32 event_number = 3;
7
+ optional string value = 4;
8
+ optional int32 platform = 5;
9
+ optional int64 user = 6;
10
+ optional int64 inserttime = 7;
11
+ }
12
+
13
+ message CallEventsRequest {
14
+ repeated CallEvent events = 1;
15
+ }
@@ -0,0 +1,38 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # NO CHECKED-IN PROTOBUF GENCODE
4
+ # source: call_events_request.proto
5
+ # Protobuf Python Version: 5.28.1
6
+ """Generated protocol buffer code."""
7
+ from google.protobuf import descriptor as _descriptor
8
+ from google.protobuf import descriptor_pool as _descriptor_pool
9
+ from google.protobuf import runtime_version as _runtime_version
10
+ from google.protobuf import symbol_database as _symbol_database
11
+ from google.protobuf.internal import builder as _builder
12
+ _runtime_version.ValidateProtobufRuntimeVersion(
13
+ _runtime_version.Domain.PUBLIC,
14
+ 5,
15
+ 28,
16
+ 1,
17
+ '',
18
+ 'call_events_request.proto'
19
+ )
20
+ # @@protoc_insertion_point(imports)
21
+
22
+ _sym_db = _symbol_database.Default()
23
+
24
+
25
+
26
+
27
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19\x63\x61ll_events_request.proto\"\x83\x01\n\tCallEvent\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x11\n\tdevice_id\x18\x02 \x01(\x03\x12\x14\n\x0c\x65vent_number\x18\x03 \x01(\x05\x12\r\n\x05value\x18\x04 \x01(\t\x12\x10\n\x08platform\x18\x05 \x01(\x05\x12\x0c\n\x04user\x18\x06 \x01(\x03\x12\x12\n\ninserttime\x18\x07 \x01(\x03\"/\n\x11\x43\x61llEventsRequest\x12\x1a\n\x06\x65vents\x18\x01 \x03(\x0b\x32\n.CallEvent')
28
+
29
+ _globals = globals()
30
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
31
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'call_events_request_pb2', _globals)
32
+ if not _descriptor._USE_C_DESCRIPTORS:
33
+ DESCRIPTOR._loaded_options = None
34
+ _globals['_CALLEVENT']._serialized_start=30
35
+ _globals['_CALLEVENT']._serialized_end=161
36
+ _globals['_CALLEVENTSREQUEST']._serialized_start=163
37
+ _globals['_CALLEVENTSREQUEST']._serialized_end=210
38
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,63 @@
1
+ """
2
+ @generated by mypy-protobuf. Do not edit manually!
3
+ isort:skip_file
4
+ """
5
+
6
+ import builtins
7
+ import collections.abc
8
+ import google.protobuf.descriptor
9
+ import google.protobuf.internal.containers
10
+ import google.protobuf.message
11
+ import typing
12
+
13
+ DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
14
+
15
+ @typing.final
16
+ class CallEvent(google.protobuf.message.Message):
17
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
18
+
19
+ ID_FIELD_NUMBER: builtins.int
20
+ DEVICE_ID_FIELD_NUMBER: builtins.int
21
+ EVENT_NUMBER_FIELD_NUMBER: builtins.int
22
+ VALUE_FIELD_NUMBER: builtins.int
23
+ PLATFORM_FIELD_NUMBER: builtins.int
24
+ USER_FIELD_NUMBER: builtins.int
25
+ INSERTTIME_FIELD_NUMBER: builtins.int
26
+ id: builtins.int
27
+ device_id: builtins.int
28
+ event_number: builtins.int
29
+ value: builtins.str
30
+ platform: builtins.int
31
+ user: builtins.int
32
+ inserttime: builtins.int
33
+ def __init__(
34
+ self,
35
+ *,
36
+ id: builtins.int | None = ...,
37
+ device_id: builtins.int | None = ...,
38
+ event_number: builtins.int | None = ...,
39
+ value: builtins.str | None = ...,
40
+ platform: builtins.int | None = ...,
41
+ user: builtins.int | None = ...,
42
+ inserttime: builtins.int | None = ...,
43
+ ) -> None: ...
44
+ def HasField(self, field_name: typing.Literal["device_id", b"device_id", "event_number", b"event_number", "id", b"id", "inserttime", b"inserttime", "platform", b"platform", "user", b"user", "value", b"value"]) -> builtins.bool: ...
45
+ def ClearField(self, field_name: typing.Literal["device_id", b"device_id", "event_number", b"event_number", "id", b"id", "inserttime", b"inserttime", "platform", b"platform", "user", b"user", "value", b"value"]) -> None: ...
46
+
47
+ global___CallEvent = CallEvent
48
+
49
+ @typing.final
50
+ class CallEventsRequest(google.protobuf.message.Message):
51
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
52
+
53
+ EVENTS_FIELD_NUMBER: builtins.int
54
+ @property
55
+ def events(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___CallEvent]: ...
56
+ def __init__(
57
+ self,
58
+ *,
59
+ events: collections.abc.Iterable[global___CallEvent] | None = ...,
60
+ ) -> None: ...
61
+ def ClearField(self, field_name: typing.Literal["events", b"events"]) -> None: ...
62
+
63
+ global___CallEventsRequest = CallEventsRequest
@@ -0,0 +1,4 @@
1
+ syntax = "proto2";
2
+
3
+ message CurrentStateRequest {
4
+ }
@@ -0,0 +1,36 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # NO CHECKED-IN PROTOBUF GENCODE
4
+ # source: current_state_request.proto
5
+ # Protobuf Python Version: 5.28.1
6
+ """Generated protocol buffer code."""
7
+ from google.protobuf import descriptor as _descriptor
8
+ from google.protobuf import descriptor_pool as _descriptor_pool
9
+ from google.protobuf import runtime_version as _runtime_version
10
+ from google.protobuf import symbol_database as _symbol_database
11
+ from google.protobuf.internal import builder as _builder
12
+ _runtime_version.ValidateProtobufRuntimeVersion(
13
+ _runtime_version.Domain.PUBLIC,
14
+ 5,
15
+ 28,
16
+ 1,
17
+ '',
18
+ 'current_state_request.proto'
19
+ )
20
+ # @@protoc_insertion_point(imports)
21
+
22
+ _sym_db = _symbol_database.Default()
23
+
24
+
25
+
26
+
27
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1b\x63urrent_state_request.proto\"\x15\n\x13\x43urrentStateRequest')
28
+
29
+ _globals = globals()
30
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
31
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'current_state_request_pb2', _globals)
32
+ if not _descriptor._USE_C_DESCRIPTORS:
33
+ DESCRIPTOR._loaded_options = None
34
+ _globals['_CURRENTSTATEREQUEST']._serialized_start=31
35
+ _globals['_CURRENTSTATEREQUEST']._serialized_end=52
36
+ # @@protoc_insertion_point(module_scope)
@@ -0,0 +1,20 @@
1
+ """
2
+ @generated by mypy-protobuf. Do not edit manually!
3
+ isort:skip_file
4
+ """
5
+
6
+ import google.protobuf.descriptor
7
+ import google.protobuf.message
8
+ import typing
9
+
10
+ DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
11
+
12
+ @typing.final
13
+ class CurrentStateRequest(google.protobuf.message.Message):
14
+ DESCRIPTOR: google.protobuf.descriptor.Descriptor
15
+
16
+ def __init__(
17
+ self,
18
+ ) -> None: ...
19
+
20
+ global___CurrentStateRequest = CurrentStateRequest
@@ -0,0 +1,15 @@
1
+ syntax = "proto2";
2
+
3
+ message CurrentStateEvent {
4
+ optional int64 id = 1;
5
+ optional int64 device_id = 2;
6
+ optional int32 event_number = 3;
7
+ optional string value = 4;
8
+ optional int32 platform = 5;
9
+ optional int64 user = 6;
10
+ optional int64 inserttime = 7;
11
+ }
12
+
13
+ message CurrentStateResponse {
14
+ repeated CurrentStateEvent events = 1;
15
+ }