Blame view

src/monitoring/tasks.py 7.09 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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
    def handleTasks(self):
        self.timers["tasks"] = self.timer_tasks
        # TODO check majordome and alert_manager status
        if self.majordome_task is None:
            try:
                self.monitoring_task = TaskId.objects.get(task="majordome")
            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
91
    '''
6c2793c2   jeremy   Update
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
        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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
    # 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
124
    '''
257abe9b   Jeremy   Added comments
125
126
        Parse status returned by plc
    '''
ce470283   Jeremy   Plc simulator fin...
127
128
129
    def parseStatus(self, status_plc):
        try:
            status = {}
fe5613f5   jeremy   Update plc protocol
130
131
132
133
134
135
136
137
            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...
138
139
140
141
142
143
144
145
        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
146
    '''
fe5613f5   jeremy   Update plc protocol
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
        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
169
170
        Save status returned by plc
    '''
ce470283   Jeremy   Plc simulator fin...
171
172
173
174
    def saveStatus(self):
        outside = WeatherWatch()
        inside = SiteWatch()
        for key, value in self.status_plc.items():
fe5613f5   jeremy   Update plc protocol
175
            if self.isOutside(key):
ce470283   Jeremy   Plc simulator fin...
176
                outside.setAttribute(key, value)
fe5613f5   jeremy   Update plc protocol
177
            elif self.isInside(key):
ce470283   Jeremy   Plc simulator fin...
178
179
180
181
182
183
184
                inside.setAttribute(key, value)
        outside.setGlobalStatus()
        inside.setGlobalStatus()
        outside.save()
        inside.save()
        return 0

257abe9b   Jeremy   Added comments
185
186
187
    '''
        Function called by the main loop to handle the plc status
    '''
4cb0ff36   Jeremy   Update
188
189
    def handleTimerStatus(self):
        self.timers["timer_status"] = self.timer_status
678838ed   Jeremy   Weather ans insid...
190
        status_plc = self.plc.getStatus()
ce470283   Jeremy   Plc simulator fin...
191
192
        if (self.plc.isError(status_plc)):
            if (settings.DEBUG and DEBUG_FILE):
e8e6f017   Jeremy   Reworked devices ...
193
                log.info("Invalid status returned : " + str(self.status_plc))
e8e6f017   Jeremy   Reworked devices ...
194
            return (1)
ce470283   Jeremy   Plc simulator fin...
195
196
197
198
199
        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
200

257abe9b   Jeremy   Added comments
201
202
203
    '''
        Main loop
    '''
4cb0ff36   Jeremy   Update
204
205
206
207
208
209
    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
210
                if (timer_value <= 0):
ef60c3ec   Jeremy   Majordome and mon...
211
                    if (timer_name in self.functions):
4cb0ff36   Jeremy   Update
212
213
                        self.functions[timer_name]()
                    else:
ce470283   Jeremy   Plc simulator fin...
214
                        if (settings.DEBUG and DEBUG_FILE):
4cb0ff36   Jeremy   Update
215
                            log.info("Timer : " + str(timer_name) + "is not known by the monitoring")
bca9a283   Jeremy   Reworked the sche...
216
                        self.logDB("Timer " + str(timer_name) + " unknown")
ce470283   Jeremy   Plc simulator fin...
217
                if (settings.DEBUG and DEBUG_FILE):
4cb0ff36   Jeremy   Update
218
                    log.info("Timer : " + str(timer_name) + " executed by monitoring")
ef60c3ec   Jeremy   Majordome and mon...
219
220
221
222
223
        return (0)

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