Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
dontsovcmc committed Mar 15, 2019
2 parents 9f19c89 + 5e1fa66 commit e2fa28f
Show file tree
Hide file tree
Showing 12 changed files with 61 additions and 28 deletions.
2 changes: 1 addition & 1 deletion alphalogic_api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

VERSION_MAJOR = 0 # (System version)
VERSION_MINOR = 0 # (Tests version)
BUILD_NUMBER = 14 # (Issues version)
BUILD_NUMBER = 15 # (Issues version)
SNAPSHOT_NUMBER = 0

__version__ = '.'.join(map(str, (VERSION_MAJOR, VERSION_MINOR, BUILD_NUMBER))) if SNAPSHOT_NUMBER == 0 \
Expand Down
20 changes: 14 additions & 6 deletions alphalogic_api/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ def cmd_exception(self):
def cmd_alarm(self, where='here', when=datetime.datetime.now(), why=2):
return where
Example 3::
# The command hasn't arguments and return dict type
@command(result_type=dict)
def cmd_alarm(self):
return {'a': 1, 'b': 'second', 'c': [1,2,3], 'd' : [1, {'2': 3}, 3]}
:arg result_type: Command return type
"""
Expand Down Expand Up @@ -83,7 +90,7 @@ def run_one(self):
self.counter.val += 1
"""
def decorator(func):
def wrapped(device):
def wrapped(device, call_again=False):
with device.mutex:
if not device.flag_removing:
try:
Expand Down Expand Up @@ -115,11 +122,12 @@ def wrapped(device):
else:
mem_period = period

if time_spend < mem_period:
device.manager.tasks_pool.add_task(time_finish + mem_period - time_spend,
getattr(device, func.func_name))
else:
device.manager.tasks_pool.add_task(time_finish, getattr(device, func.func_name))
if call_again:
if time_spend < mem_period:
device.manager.tasks_pool.add_task(time_finish + mem_period - time_spend,
getattr(device, func.func_name))
else:
device.manager.tasks_pool.add_task(time_finish, getattr(device, func.func_name))

wrapped.runnable = True
wrapped.period_name = kwargs_r.keys()[0]
Expand Down
7 changes: 6 additions & 1 deletion alphalogic_api/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,16 @@ def prepare_existing_devices(self, id_parent):
object = class_name(class_name_str, child_id)
Manager.components_for_device[child_id] = []
self.prepare_for_work(object, child_id)
object.handle_prepare_for_work()

for child_id in super(Manager, self).children(id_parent):
self.prepare_existing_devices(child_id)

def call_handle_prepare_for_work(self, id_parent):
for child_id in super(Manager, self).children(id_parent):
self.call_handle_prepare_for_work(child_id)
object = self.nodes[child_id]
object.handle_prepare_for_work()

def create_object(self, object_id, user_name_display):
class_name_str = self.get_type(object_id)
class_name = Manager.dict_user_name_type_objects[user_name_display]
Expand Down
2 changes: 1 addition & 1 deletion alphalogic_api/multistub.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def call_helper(self, function_name, *args, **kwargs):
answer = getattr(kwargs['stub'], function_name)(kwargs['request'], timeout=options.args.timeout)
return answer

except grpc.RpcError, err:
except grpc.RpcError as err:
if err.code() == grpc.StatusCode.NOT_FOUND:
raise ComponentNotFound(err.message + ' ' + err.details())
elif err.code() == grpc.StatusCode.DEADLINE_EXCEEDED:
Expand Down
2 changes: 1 addition & 1 deletion alphalogic_api/objects/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,6 @@ def call_function(self):
.format(self.name(), '; '.join(info), self.device.id))
self.function(self.device, **function_dict)

except Exception, err:
except Exception as err:
t = traceback.format_exc()
log.error('Command \'{0}\' raise exception: {1}'.format(self.name(), decode_string(t)))
2 changes: 1 addition & 1 deletion alphalogic_api/objects/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ def owner(self):

class Event(AbstractEvent):
"""
Class Event inherits inherits all data elements and methods from :class:`~alphalogic_api.objects.event.AbstractEvent`.
Class Event inherits all data elements and methods from :class:`~alphalogic_api.objects.event.AbstractEvent`.
:arg priority: trivial, minor, major, critical or blocker
:arg args: name/type pairs in a tuple of tuples (argument name, argument type)
Expand Down
18 changes: 11 additions & 7 deletions alphalogic_api/objects/object.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,6 @@ def handle_defaults_loaded(self, **kwargs):
raise Exception('Unknown parameter {0}'.format(param_name))



class Root(Object):
"""
Root object inherits from :class:`~alphalogic_api.objects.Object`.
Expand Down Expand Up @@ -212,7 +211,7 @@ def __init__(self):
self.joinable = True
log.info('Root connected OK')

except Exception, err:
except Exception as err:
t = traceback.format_exc()
log.error(decode_string(t)) # cause Exception can raise before super(Root)
self.manager.tasks_pool.stop_operation_thread()
Expand All @@ -226,8 +225,9 @@ def init(self, id_root):
map(self.manager.delete_object, list_need_to_delete)
Manager.components_for_device[id_root] = []
self.manager.prepare_for_work(self, id_root)
self.handle_prepare_for_work()
self.manager.prepare_existing_devices(id_root)
self.manager.call_handle_prepare_for_work(id_root)
self.handle_prepare_for_work()

def join(self):
"""
Expand All @@ -244,8 +244,12 @@ def join(self):
t = traceback.format_exc()
log.error('Root join error: {0}'.format(decode_string(t)))
finally:
self.manager.tasks_pool.stop_operation_thread()
self.manager.multi_stub.channel.close()
if self.manager.g_thread.is_alive():
self.manager.g_thread.join()
try:
self.manager.tasks_pool.stop_operation_thread()
self.manager.multi_stub.channel.close()
if self.manager.g_thread.is_alive():
self.manager.g_thread.join()
except BaseException as err:
t = traceback.format_exc()
log.error('Root finally join error: {0}'.format(decode_string(t)))
log.info('Stub has stopped successfully')
4 changes: 3 additions & 1 deletion alphalogic_api/options.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import os
import sys
import argparse
Expand All @@ -20,7 +22,7 @@ def parse_arguments():
parser.add_argument('--help', action='store_true', help='Print help')
parser.add_argument('-h', '--host', default='localhost', help='Set host (default 127.0.0.1)')
parser.add_argument('-p', '--port', default=42001, type=int, help='Set port (default 42001)')
parser.add_argument('-l', '--log_level', default='info', type=str.lower, choices=log_levels)
parser.add_argument('-l', '--log_level', default='info', choices=log_levels) # type=str.lower, python3 не нравится str.lower
parser.add_argument('--log_max_file_size', type=int, default=1024*100, help='Set max file size for rotating log file, bytes. Default: 100кб')
parser.add_argument('--log_max_files', type=int, default=10, help='Set max files for rotating log file. Default=10')
parser.add_argument('--development_mode', action='store_true', help='Don\'t check configure if present')
Expand Down
2 changes: 1 addition & 1 deletion alphalogic_api/tasks_pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def run_operation_thread(self):
while not self.shutdown_flag.is_set():
tasks = self.queue_tasks.get_tasks(time.time())
if not(tasks is None):
result = self.thread_pool.map_async(lambda f: f(), tasks)
result = self.thread_pool.map_async(lambda f: f(call_again=True), tasks)
self.list_futures.append(result)
self.clear_done_futures()
time.sleep(0.001)
Expand Down
8 changes: 6 additions & 2 deletions alphalogic_api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,12 @@ def decode_string(s):
return unicode(s)


def epoch():
return datetime.datetime.utcfromtimestamp(0)


def milliseconds_from_epoch(dt):
return int((dt - datetime.datetime.utcfromtimestamp(0)).total_seconds() * 1000)
return int((dt - epoch()).total_seconds() * 1000)


def create_map_value(value_rpc, value):
Expand Down Expand Up @@ -166,7 +170,7 @@ def value_from_rpc(value_rpc):
return l
elif value_rpc.HasField('dict_value'):
d = dict()
map(lambda (key, x): d.update({key: value_from_rpc(x)}), value_rpc.dict_value.value.items())
map(lambda key, x: d.update({key: value_from_rpc(x)}), value_rpc.dict_value.value.items())
return d


Expand Down
18 changes: 14 additions & 4 deletions docs/alphalogic_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ To specify an adapter object (not Root object), create a class that inherits fro
Parameter
~~~~~~~~~
| You have to define parameter, depending on its value type:
| ParameterBool, ParameterLong, ParameterDouble, ParameterDatetime, ParameterString
| ParameterBool, ParameterLong, ParameterDouble, ParameterDatetime, ParameterString, ParameterList, ParameterDict
Example of parameter definition:
::
from alphalogic_api.objects import ParameterBool, ParameterLong, ParameterDouble, ParameterDatetime, ParameterString
from alphalogic_api.objects import ParameterBool, ParameterLong, ParameterDouble, ParameterDatetime, ParameterString, ParameterList, ParameterDict
...

message = ParameterString(default='Hello world!')
Expand All @@ -75,6 +75,10 @@ Parameter arguments are optional.
| | | 0 (ParameterDatetime)| |
| | |----------------------| |
| | | "" (ParameterString) | |
| | |----------------------| |
| | | [] (ParameterList) | |
| | |----------------------| |
| | | {} (ParameterDict) | |
+-------------+---------------------------+----------------------+----------------------------+
| visible | | A parameter type that | Visible.runtime | | Visible.runtime - used |
| | | specifies its features | | | to transfer data from |
Expand Down Expand Up @@ -125,6 +129,10 @@ To build a value list for the parameter, it is required that both arguments 'cho
::
param_tmp = ParameterLong(visible=Visible.setup, access=Access.read_write, default=1, choices=((1, 'First'), (2, 'Second')))

Second approach to build value list for parameter:
::
param_tmp = ParameterLong(visible=Visible.setup, access=Access.read_write, default=1, choices=(1, 2))

Be careful to assign a value (not an enumeration member's name) to 'default' argument if the 'choices' argument provides enumeration with descriptions:
::
param_tmp2 = ParameterBool(default=True, choices=((True, 'On'), (False, 'Off')))
Expand Down Expand Up @@ -186,13 +194,15 @@ The @ special character is used to indicate a decorator.

Command
~~~~~~~
Possible values for result type are: unicode, datetime.datetime, int, float, bool, list, dict.
Here is the definition of the class Command:

.. autoclass:: command
:members:


Run functions
~~~
~~~~~~~
There is easy way to do some job periodicaly. You can define a lot of run functions in the root or object.

.. autoclass:: run
Expand Down Expand Up @@ -241,7 +251,7 @@ In the case of parameter changes, you can use whichever name of the handler func
4) Handler for configure Object after creation by user
::
number = ParameterLong(visible=Visible.setup)
def handle_defaults_loaded(self):
def handle_defaults_loaded(self, **kwargs):
self.displayName.val = str(self.number.val)

5) Handler is executed before work of object
Expand Down
4 changes: 2 additions & 2 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Navigate to the ``\bin`` folder of the installed composite Alphalogic adapter an
from alphalogic_api.objects import Root, Object
from alphalogic_api.attributes import Visible, Access
from alphalogic_api.objects import MajorEvent
from alphalogic_api.objects import ParameterBool, ParameterLong, ParameterDouble, ParameterDatetime, ParameterString
from alphalogic_api.objects import ParameterBool, ParameterLong, ParameterDouble, ParameterDatetime, ParameterString, ParameterList, ParameterDict
from alphalogic_api.decorators import command, run
from alphalogic_api.logger import log

Expand Down Expand Up @@ -124,7 +124,7 @@ The use of the library can be demonstrated via the following example of the Send
from alphalogic_api import options
from alphalogic_api.objects import Root, Object
from alphalogic_api.attributes import Visible, Access
from alphalogic_api.objects import ParameterBool, ParameterLong, ParameterDouble, ParameterDatetime, ParameterString
from alphalogic_api.objects import ParameterBool, ParameterLong, ParameterDouble, ParameterDatetime, ParameterString, ParameterList, ParameterDict
from alphalogic_api.decorators import command, run
from alphalogic_api.logger import log

Expand Down

0 comments on commit e2fa28f

Please sign in to comment.