On Friday, May 6, 2016 at 3:55:03 PM UTC+2, Cédric Krier wrote:
>
> On 2016-05-06 05:41, edbo....@gmail.com <javascript:> wrote: 
> > Hello, 
> > 
> > I think I'm using the Model. __post_setup__ class not correctly, but how 
> > I'm using it is working in Tryton-3.6.5 but not in Tryton-4.0.0 and 
> maybe 
> > there are other ways to do it. 
> > 
> > What I'm trying to do, is to build an IOT-platform into Tryton where 
> agents 
> > can connect to and update several values they allowed to change. To 
> > minimize database-queries and updating database-records or inserting new 
> > ones, I build a dict which lives in memory. The agents send the new 
> values 
> > in and Tryton will update the values in the dict, and a cron-job will 
> > archive those values into the database at certain moments. The new 
> values 
> > are also used to trigger events like sending mail, executing scripts 
> etc. 
> > 
> > To create the dict in memory I'm using the __post_setup__ class to 
> populate 
> > the dict with the several values. 
> > 
> >     @classmethod 
> >     def __post_setup__(cls): 
> >         super(Trigger, cls).__post_setup__() 
> > 
> >         # get the triggers 
> >         triggers = cls.search( [('id', '>', 0 )] ) 
> >         
> >         if triggers: 
> >             # Build the datastructure in memory 
> >             for trigger in cls.browse( triggers ): 
> > 
> >                 sensors = [] 
> >                 on_activate = [] 
> >                 on_deactivate = [] 
> >                 
> >                 # get the sensors and conditions 
> >                 for sensor in trigger.sensor: 
> >                     if len(sensor.condition) > 2: 
> >                         sensors.append({ 
> >                             "id"        : sensor.id, 
> >                             "sensor"    : sensor.sensor.id, 
> >                             "condition" : sensor.condition, 
> >                             }) 
> >                                     
> >                 # only add the trigger to the list when there are 
> >                 # sensors and conditions 
> >                 if len(sensors): 
> >                     MEM_TRIGGERS.append({ 
> >                         "id"         : trigger.id, 
> >                         "name"       : trigger.name, 
> >                         "sequence"   : trigger.sequence, 
> >                         "min_delay"  : trigger.minimum_time_delay, 
> >                         "min_active" : trigger.minimum_time_active, 
> >                         "when"       : datetime.datetime.utcnow(), 
> >                         "activated"  : trigger.activated, 
> >                         "enabled"    : trigger.enabled, 
> >                         "sensors"    : sensors 
> >                     }) 
> > 
> > I have extended the ir.trigger with 
> > sensor = fields.One2Many('iot.triggersensors', 'trigger', 'Sensor') 
> > 
> > And the iot.triggersensors 
> > 
> > class TriggerSensor(ModelSQL, ModelView): 
> >     "TriggerSensor" 
> >     __name__ = 'iot.triggersensors' 
> > 
> >     name = fields.Char('Name') 
> >     trigger = fields.Many2One('ir.trigger', 'Trigger', 
> > domain=[('on_sensor','=',True)], ondelete='CASCADE') 
> >     condition = fields.Char('Condition') 
> > 
> > 
> > This is working in Tryton version 3.65, but in 4.0.0 I get 
> > 
> >   File "/home/ed/ERP/iot/trytond-4.0.0/trytond/pool.py", line 229, in 
> setup 
> >     cls.__post_setup__() 
> >   File "/home/ed/ERP/iot/trytond-4.0.0/trytond/modules/iot/iot.py", line 
> > 1173, in __post_setup__ 
> >     for sensor in trigger.sensor: 
> >   File "/home/ed/ERP/iot/trytond-4.0.0/trytond/model/modelstorage.py", 
> line 
> > 1352, in __getattr__ 
> >     read_data = self.read(list(ids), ffields.keys()) 
> >   File "/home/ed/ERP/iot/trytond-4.0.0/trytond/model/modelsql.py", line 
> > 744, in read 
> >     getter_result = field.get(ids, cls, fname, values=result) 
> >   File 
> "/home/ed/ERP/iot/trytond-4.0.0/trytond/model/fields/one2many.py", 
> > line 86, in get 
> >     field = Relation._fields[self.field] 
> > AttributeError: type object 'iot.triggersensors' has no attribute 
> '_fields' 
> > 
> > So my question is, are there other methods to accomplish this (after the 
> > Tryton-server is started create a dict into memory)? or is this a bug in 
> > Tryton-4.0.0? 
>
> It is definitely not a bug in 4.0. Your code was working before by 
> chance. The ORM should never be used during the initialization of the 
> Pool. Your code doesn't work any more probably because of the 
> optimization of the pool initialization. 
>
> Hmm, ok, but the documentation says "Setup the class AFTER added into the 
trytond.pool.Pool". So IMO this means that the class is added into the pool 
and then __post_setup__ will be called.

 

> Also you should be careful with global variable, your structure is 
> probably not thread-safe. 
>

I don't use global. In my iot.py I have
MEM_SENSORS = {}      # store sensor values in memory

just below values like
__metaclass__ = PoolMeta
logger = logging.getLogger(__name__)
STATES = {
    'readonly': ~Eval('active', True),
    }
DEPENDS = ['active']

So I think this is not global and I have written an alternative 
write-function for the agents, so the agents are just like clients but very 
restricted in their possibilities. But you are right about not being 
thread-safe. That's why I'm thinking to put Tryton-celery in between. But I 
have to dig deeper into that and maybe I can solve this issue with that.
 

> Finally, are you sure you need this? Of course database query is 
> expensive but included in all the stack of a request, I don't think it 
> has so much effect. 
>

I'm running the system on a BeagleBone Black and it's running surprisingly 
well! even better then I have thought of. I have one agent which also runs 
on the BB and collects data from 8 sensors at several intervals (minimal 
interval 2 sec, maximum interval 5 minutes). The memory consumption of 
postgresql, tryton-server and agent is around 30MB and the CPU is running 
around 30% load. Connecting with the client to get the archived values will 
take some seconds, but that's not a problem.

I'm switched to the memory-part because the BB couldn't keep up with 
updating the records in the database and starts to swap. I also tried to 
use sqlite in memory, but the same happened. So I need this kind of 
behavior and it's just working well.


 

> -- 
> Cédric Krier - B2CK SPRL 
> Email/Jabber: cedric...@b2ck.com <javascript:> 
> Tel: +32 472 54 46 59 
> Website: http://www.b2ck.com/ 
>

-- 
You received this message because you are subscribed to the Google Groups 
"tryton-dev" group.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/tryton-dev/e1239559-ef17-4009-9a23-905debb7e6ed%40googlegroups.com.

Reply via email to