Continue JSON interface.
authorBenjamin Braatz <benjamin.braatz@graph-it.com>
Wed, 30 Jun 2021 12:35:13 +0000 (14:35 +0200)
committerBenjamin Braatz <benjamin.braatz@graph-it.com>
Wed, 30 Jun 2021 12:35:13 +0000 (14:35 +0200)
controlpi_plugins/graphjson.py

index 4cb1911353207720203acea7de75ddb24710c1d1..53688a418aa02cee5899236a36494f8364dd820c 100644 (file)
@@ -36,31 +36,36 @@ class GraphJSON(BasePlugin):
                                     'items': {'type': 'string'}}},
                    'required': ['url', 'crt', 'node', 'mac attribute',
                                 'interface']}
-    
+
     async def _receive(self, message: Message) -> None:
         if ('target' in message and message['target'] == self.name and
                 'command' in message):
             if message['command'] == 'pull conf':
                 conf = await self._call('attribut',
-                                        [self._guid,
-                                         f"{self.conf['node']}_{self.conf['conf attribute']}"])
+                                        [self._guid, self._confattribute])
                 if conf != self._conf:
                     await self.bus.send(Message(self.name,
                                                 {'event': 'conf changed',
                                                  'new conf': conf}))
-                    # TODO: Write file
+                    try:
+                        with open(sys.argv[1], 'w') as conf_file:
+                            conf_file.write(conf)
+                    except IndexError:
+                        pass
             elif message['command'] == 'sync state':
                 sync = await self._call('attribut',
-                                        [self._guid,
-                                         f"{self.conf['node']}_{self.conf['sync attribute']}"])
-        if 'state' in message and message['sender'] in self.conf['sync states']:
+                                        [self._guid, self._syncattribute])
+
+
+        if ('state' in message and
+                message['sender'] in self.conf['sync states']):
             self._states[message['sender']] = message['state']
 
     async def _call(self, method, params):
         await self._lock.acquire()
         self._call_id += 1
-        request = { 'jsonrpc': '2.0', 'method': method,
-                    'params': params, 'id': self._call_id }
+        request = {'jsonrpc': '2.0', 'method': method,
+                   'params': params, 'id': self._call_id}
         message = msgpack.packb(request)
         size = struct.pack('<i', len(message))
         self._writer.write(size)
@@ -93,35 +98,57 @@ class GraphJSON(BasePlugin):
         self._ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
         self._ssl_ctx.load_cert_chain(self.conf['crt'])
         self._call_id = 0
-        sends = [MessageTemplate({'event': {'const': 'conf changed'},
-                                  'new conf': {'type': 'object'}})]
-        receives = [MessageTemplate({'target': {'const': self.name},
-                                     'command': {'const': 'pull conf'}}),
-                    MessageTemplate({'target': {'const': self.name},
-                                     'command': {'const': 'sync state'}})]
-        self._states = {}
-        for state in self.conf['sync states']:
-            sends.append(MessageTemplate({'target': {'const': state},
-                                          'command': {'const': 'set state'}}))
-            receives.append(MessageTemplate({'sender': {'const': state},
-                                             'state': {}}))
+        sends = []
+        receives = []
+        if 'conf attribute' in self.conf:
+            self._confattribute = (self.conf['node'] + '_' +
+                                   self.conf['conf attribute'])
+            sends.append(MessageTemplate({'event': {'const': 'conf changed'},
+                                          'new conf': {'type': 'string'}}))
+            receives.append(MessageTemplate({'target': {'const': self.name},
+                                             'command':
+                                             {'const': 'pull conf'}}))
+            self._conf = ''
+            try:
+                with open(sys.argv[1]) as json_data:
+                    self._conf = json_data
+            except IndexError, FileNotFoundError:
+                pass
+        if 'sync attribute' in self.conf:
+            self._syncattribute = (self.conf['node'] + '_' +
+                                   self.conf['sync attribute'])
+            receives.append(MessageTemplate({'target': {'const': self.name},
+                                             'command':
+                                             {'const': 'sync state'}}))
+            self._sync = ''
+            self._states = {}
+            for state in self.conf['sync states']:
+                sends.append(MessageTemplate({'target': {'const': state},
+                                              'command':
+                                              {'const': 'set state'}}))
+                receives.append(MessageTemplate({'sender': {'const': state},
+                                                 'state': {}}))
+                self._states[state] = None
         self.bus.register(self.name, 'GraphJSON',
                           sends, receives, self._receive)
 
     async def run(self) -> None:
-        """Open connection and test it."""
+        """Open connection and get node instance for MAC address."""
         self._lock = asyncio.Lock()
         (self._reader, self._writer) = await asyncio.open_connection(
                 self._host, self._port, ssl=self._ssl_ctx)
+        # Read banner:
         banner_size = await self._reader.readexactly(4)
         banner_size = struct.unpack('<i', banner_size)[0]
         banner_message = await self._reader.readexactly(banner_size)
+        # Get own MAC address:
         sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
         info = fcntl.ioctl(sock.fileno(), 0x8927,
                            struct.pack('256s',
                                        bytes(self.conf['interface'],
                                              'utf-8')[:15]))
         mac = ':'.join('%02x' % b for b in info[18:24])
+        # Get node instance:
+        mac_attribute = f"{self.conf['node']}_{self.conf['mac attribute']}"
         self._guid = await self._call('attributsknoten',
-                                      [f"{self.conf['node']}_{self.conf['mac attribute']}",
-                                       mac])
+                                      [mac_attribute, mac])