Blame view

src/monitoring/tasks.py 7.25 KB
5b5566ab   haribo   added celery
1
from __future__ import absolute_import
a190892c   haribo   Date: 05/07/2016
2
from django.conf import settings
ddf59dd4   haribo   Remaniement :
3
from common.models import *
5b5566ab   haribo   added celery
4
from celery.task import Task
ddf59dd4   haribo   Remaniement :
5
from devices.PLC import PLCController
4cb0ff36   Jeremy   Update
6
from utils.JDManipulator import *
6c2793c2   jeremy   Update
7
import json
bca9a283   Jeremy   Reworked the sche...
8
import utils.Logger as L
c72eb17a   Jeremy   Update celery task
9
10
11
import majordome.tasks
import alert_manager.tasks

4cb0ff36   Jeremy   Update
12
log = L.setupLogger("MonitoringTaskLogger", "Monitoring")
c5a3b4a0   haribo   Date: 05/07/2016
13

ce470283   Jeremy   Plc simulator fin...
14
15
16
DEBUG_FILE = False


65149de7   Jeremy   Update
17
18
'''
    Infinite task created at the program's start.
4cb0ff36   Jeremy   Update
19
    Checks the plc status, parse it, analyse it, store it in db
65149de7   Jeremy   Update
20
'''
257abe9b   Jeremy   Added comments
21
22


ef60c3ec   Jeremy   Majordome and mon...
23
24
25
class Monitoring(Task):
    timers = {}
    functions = {}
5b5566ab   haribo   added celery
26
27

    def run(self):
c72eb17a   Jeremy   Update celery task
28
        self.createTask()
65149de7   Jeremy   Update
29
        self.setContext()
4cb0ff36   Jeremy   Update
30
        self.setTime()
c72eb17a   Jeremy   Update celery task
31
        self.setTasks()
4cb0ff36   Jeremy   Update
32
        self.loop()
a190892c   haribo   Date: 05/07/2016
33

c72eb17a   Jeremy   Update celery task
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
    def createTask(self):
        try:
            TaskId.objects.find(task="monitoring").delete()
        except Exception as e:
            log.info(str(e))
            return 1
        TaskId.objects.create(task_id=self.request.id, task="monitoring")
        return 0

    def setTasks(self):
        try:
            self.majordome_task = TaskId.objects.get(task="majordome")
            self.alert_task = TaskId.objects.get(task="alert_manager")
        except Exception as e:
            self.majordome_task = None
            self.alert_task = None
        return 0

65149de7   Jeremy   Update
52
    def setContext(self):
ddf59dd4   haribo   Remaniement :
53
        self.plc = PLCController()
4cb0ff36   Jeremy   Update
54
        self.state = "RUNNING"
65149de7   Jeremy   Update
55
        return (0)
c5a3b4a0   haribo   Date: 05/07/2016
56

4cb0ff36   Jeremy   Update
57
    def setTime(self):
ef60c3ec   Jeremy   Majordome and mon...
58
        self.timer_status = 2
c72eb17a   Jeremy   Update celery task
59
60
61
62
63
        self.timer_tasks = 5
        self.timers = {"timer_status": self.timer_status,
                       "tasks": self.timer_tasks}
        self.functions = {"timer_status": self.handleTimerStatus,
                          "tasks": self.handleTasks}
4cb0ff36   Jeremy   Update
64
        return (0)
21598bc6   haribo   Date: 01/08/2016
65

bca9a283   Jeremy   Reworked the sche...
66
67
68
    def logDB(self, message: str):
        Log.objects.create(agent='Monitoring', message=message)

257abe9b   Jeremy   Added comments
69
70
71
    '''
        Function called by the main loop to check if the majordome and alert_manager are running
    '''
c72eb17a   Jeremy   Update celery task
72
73
74
75
76
    def handleTasks(self):
        self.timers["tasks"] = self.timer_tasks
        # TODO check majordome and alert_manager status
        if self.majordome_task is None:
            try:
ed1bf194   Etienne Pallier   bugfix task major...
77
78
79
                # (EP) bugfix !!!
                #self.monitoring_task = TaskId.objects.get(task="majordome")
                self.majordome_task = TaskId.objects.get(task="majordome")
c72eb17a   Jeremy   Update celery task
80
81
82
83
84
85
86
87
88
89
90
91
92
            except Exception as e:
                majordome.tasks.Majordome.apply_async()
                if settings.DEBUG and DEBUG_FILE:
                    log.info(str(e))
        if self.alert_task is None:
            try:
                self.alert_task = TaskId.objects.get(task="alert_manager")
            except Exception as e:
                alert_manager.tasks.AlertListener.apply_async()
                if settings.DEBUG and DEBUG_FILE:
                    log.info(str(e))
        return 0

257abe9b   Jeremy   Added comments
93
    '''
6c2793c2   jeremy   Update
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
        Check if all devices info are consitants
    '''
    def isStatusValid(self):
        return True

    '''
        Extract content from the status dictionary
    '''
    def extractFromDict(self, status):
        synthesis = {}
        devices = status["device"]
        for device in devices:
            for value in device["values"]:
                synthesis[value["name"]] = value["value"]
                synthesis[value["name"] + "_unit"] = value["unit"]
        return synthesis

fe5613f5   jeremy   Update plc protocol
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
    # TODO ATTENTION SI DEUX DEVICES ONT LE MEME NOM
    def saveContent(self, content):
        devices = content["device"]
        for device in devices:
            status = PlcDeviceStatus()
            try:
                database_device = PlcDevice.objects.get(name=device["name"])
            except Exception as e:
                plc = Plc.objects.first()
                database_device = PlcDevice.objects.create(device=plc, name=device["name"])
            status.device = database_device
            for value in device["values"]:
                status.setValue(value["name"], value["value"], value["unit"])
            status.save()

6c2793c2   jeremy   Update
126
    '''
257abe9b   Jeremy   Added comments
127
128
        Parse status returned by plc
    '''
ce470283   Jeremy   Plc simulator fin...
129
130
131
    def parseStatus(self, status_plc):
        try:
            status = {}
fe5613f5   jeremy   Update plc protocol
132
133
134
135
136
137
138
139
            dict = json.loads(status_plc)[0]
            if dict["name"] == "STATUS":
                if self.isStatusValid():
                    status = self.extractFromDict(dict)
                    self.saveContent(dict)
                else:
                    # TODO HANDLE ERROR HERE
                    pass
ce470283   Jeremy   Plc simulator fin...
140
141
142
143
144
145
146
147
        except Exception as e:
            if DEBUG_FILE and settings.DEBUG:
                log.info(str(e))
            self.status_plc = {}
            return 1
        self.status_plc = status
        return 0

257abe9b   Jeremy   Added comments
148
    '''
fe5613f5   jeremy   Update plc protocol
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
        Check if string is ouside
    '''
    def isOutside(self, key):
        if key.find('Outside') != -1 or key.find('Rain') != -1\
                or key.find("Wind") != -1 or key.find("Sky") != -1:
            return True
        elif key == "Pressure":
            return True
        elif key == "DewPoint":
            return True
        return False

    def isInside(self, key):
        if key.find('Inside') != -1 or key.find('Door') != -1:
            return True
        elif key == "status":
            return True
        elif key == "current":
            return True
        return False

    '''
257abe9b   Jeremy   Added comments
171
172
        Save status returned by plc
    '''
ce470283   Jeremy   Plc simulator fin...
173
174
175
176
    def saveStatus(self):
        outside = WeatherWatch()
        inside = SiteWatch()
        for key, value in self.status_plc.items():
fe5613f5   jeremy   Update plc protocol
177
            if self.isOutside(key):
ce470283   Jeremy   Plc simulator fin...
178
                outside.setAttribute(key, value)
fe5613f5   jeremy   Update plc protocol
179
            elif self.isInside(key):
ce470283   Jeremy   Plc simulator fin...
180
181
182
183
184
185
186
                inside.setAttribute(key, value)
        outside.setGlobalStatus()
        inside.setGlobalStatus()
        outside.save()
        inside.save()
        return 0

257abe9b   Jeremy   Added comments
187
188
189
    '''
        Function called by the main loop to handle the plc status
    '''
4cb0ff36   Jeremy   Update
190
191
    def handleTimerStatus(self):
        self.timers["timer_status"] = self.timer_status
678838ed   Jeremy   Weather ans insid...
192
        status_plc = self.plc.getStatus()
ce470283   Jeremy   Plc simulator fin...
193
194
        if (self.plc.isError(status_plc)):
            if (settings.DEBUG and DEBUG_FILE):
e8e6f017   Jeremy   Reworked devices ...
195
                log.info("Invalid status returned : " + str(self.status_plc))
e8e6f017   Jeremy   Reworked devices ...
196
            return (1)
ed1bf194   Etienne Pallier   bugfix task major...
197
        # (EP) if parseStatus() = THERE WAS AN ERROR !!!
ce470283   Jeremy   Plc simulator fin...
198
199
200
201
202
        if self.parseStatus(status_plc):
            if (settings.DEBUG and DEBUG_FILE):
                log.info("Invalid status returned : " + str(self.status_plc))
            return 1
        return self.saveStatus()
21598bc6   haribo   Date: 01/08/2016
203

257abe9b   Jeremy   Added comments
204
205
206
    '''
        Main loop
    '''
4cb0ff36   Jeremy   Update
207
208
209
210
211
212
    def loop(self):
        while (self.state != "SHUTDOWN"):
            minimal_timer = min(self.timers, key=self.timers.get)
            time.sleep(self.timers[minimal_timer])
            self.timers = {key: value - self.timers[minimal_timer] for key, value in self.timers.items()}
            for timer_name, timer_value in self.timers.items():
4cb0ff36   Jeremy   Update
213
                if (timer_value <= 0):
ef60c3ec   Jeremy   Majordome and mon...
214
                    if (timer_name in self.functions):
4cb0ff36   Jeremy   Update
215
216
                        self.functions[timer_name]()
                    else:
ce470283   Jeremy   Plc simulator fin...
217
                        if (settings.DEBUG and DEBUG_FILE):
4cb0ff36   Jeremy   Update
218
                            log.info("Timer : " + str(timer_name) + "is not known by the monitoring")
bca9a283   Jeremy   Reworked the sche...
219
                        self.logDB("Timer " + str(timer_name) + " unknown")
ce470283   Jeremy   Plc simulator fin...
220
                if (settings.DEBUG and DEBUG_FILE):
4cb0ff36   Jeremy   Update
221
                    log.info("Timer : " + str(timer_name) + " executed by monitoring")
ef60c3ec   Jeremy   Majordome and mon...
222
223
224
225
226
        return (0)

if (__name__ == "__main__"):
    m = Monitoring()
    m.run()