Пример #1
0
 def __init__(self, daemon, cfg):
     super(RS485, self).__init__(daemon, cfg)
     daemon.knx_read_cbs.append(self.process_knx)
     daemon.value_direct_cbs.append(self.process_direct)
     log.debug("{} obj_list: {!r}".format(self.device_name, self.obj_list))
     self._reader = None
     self._writer = None
Пример #2
0
 async def process_knx(self, cmd):
     msg = None
     log.debug("avr processes knx command '%r'" % cmd)
     try:
         if cmd[0] == 'P':
             if cmd[1:3] == "on" and self.get_value_by_avr("power") != "on":
                 msg = "PO"
             elif cmd[1:4] == "off" and self.get_value_by_avr("power") != "off":
                 msg = "PF"
         elif cmd[0] == 'V':
             new_vol = int(cmd[1:])
             if new_vol != self.get_value_by_avr("volume"):
                 avr_vol = round(new_vol * (185.0 / 255.0))
                 msg = "%03dVL" % avr_vol
                 self.set_value_for_avr("volume", new_vol)
         elif cmd[0] == 'F':
             new_fn = int(cmd[1:3])
             if new_fn in range (0,32) and new_fn != self.get_value_by_avr("fn"):
                 msg = "%02dFN" % new_fn
                 self.set_value_for_avr("fn", new_fn)
         if msg:
             await self.send_avr(msg)
         return True
     except:
         return False
Пример #3
0
    async def handle_ac(self):
        log_msg = []
        while True:
            self._client.receive_info()
            group_value_dict = {}

            for o in self.obj_list:
                ac_obj = o["ac_object"]

                try:
                    value = getattr(self._client, ac_obj)

                    if value == "A":
                        value = 0
                    elif value == "B":
                        value = 1
                except KeyError:
                    continue

                if value == o["value"]:
                    log_msg.append("{!r}: {!r}".format(ac_obj, value))
                    continue

                group_value_dict[o["knx_group"]] = str(value)
                o["value"] = value

            if group_value_dict:
                await self.d.set_group_value_dict(group_value_dict)

            if log_msg:
                log.debug(self.device_name + " skipped objects: " +
                          ', '.join(log_msg))
                log_msg = []

            await asyncio.sleep(self.poll_interval)
Пример #4
0
 def __init__(self, daemon, cfg):
     super(PioneerAVR, self).__init__(daemon, cfg)
     self.avr_reader = None
     self.avr_writer = None
     self.accu_word = None
     daemon.knx_read_cbs.append(self.process_knx)
     log.debug("{} obj_list: {!r}".format(self.device_name, self.obj_list))
Пример #5
0
 async def poll_ups(self):
     while True:
         hello = (chr(0) + chr(6) + "status").encode('ascii')
         log.debug("{} polling APCD: {!r}".format(self.device_name, hello))
         self.ups_writer.write(hello)
         await self.ups_writer.drain()
         await asyncio.sleep(self.poll_interval)
Пример #6
0
 async def _write_mqtt(self, knx_group, knx_val, debug_msg):
     if not self._mqtt_client:
         return
     objects = []
     request_status = False
     for item in self.obj_list:
         if item["knx_group"] == knx_group:
             objects.append(item)
             request_status = "request_status" in item
     for o in objects:
         if "publish_topic" in o:
             topic = o["publish_topic"]
             prev_val = o["value"]
             if "valmap" in o:
                 payload = o["valmap"][knx_val]
             else:
                 payload = knx_val
             log.info(f"{debug_msg} topic {topic} updating {prev_val}=>{knx_val} ({payload})")
             try:
                 await self._mqtt_client.publish(topic, payload, qos=1, retain=True)
                 o["value"] = knx_val
             except MqttCodeError as error:
                 log.error(f"{debug_msg} MqttCodeError {error} on topic {topic}")
     if objects and request_status and "status_object" in self.cfg and self._mqtt_client and not knx_group in self.status_pending_for_groups:
         so = self.cfg["status_object"]
         delay = so.get("delay", 10.0)
         topic = so["topic"]
         payload = so["payload"]
         await asyncio.sleep(delay)
         try:
             await self._mqtt_client.publish(topic, payload, qos=1, retain=True)
             log.debug(f"{debug_msg} requested status topic {topic} payload=>{payload}")
             self.status_pending_for_groups.append(knx_group)
         except MqttCodeError as error:
             log.error(f"{debug_msg} MqttCodeError {error} on topic {topic}")
Пример #7
0
    async def handle_rs485(self):
        while True:
            try:
                line = await self._reader.readline()
                cmd = line.decode('utf-8').strip()
                log.debug(self.device_name + " received: '" + cmd + "'")
                (key, val) = cmd.split('=')

                o = self._get_obj_by_key(key)
                if "receive" in o["enabled"]:
                    if "valmap" in o and val in o["valmap"]:
                        knxval = o["valmap"][val]
                    else:
                        knxval = val
                    await self.d.set_group_value_dict({o["knx_group"]: knxval})
                else:
                    log.warning(
                        f"{self.device_name} command key {key} is not a receiving object!"
                    )

            except ValueError:
                log.warning("{} couldn't parse command {!r}!".format(
                    self.device_name, line))
            except StopIteration:
                log.warning(
                    f"{self.device_name} command key {key} not configured!")
Пример #8
0
 async def process_direct(self, knx_group, value):
     try:
         o = self.get_obj_by_knxgrp(knx_group)
         log.debug(
             f"{self.device_name} update internal state knx_group={knx_group} value={value}"
         )
         o["value"] = value
     except StopIteration:
         return
Пример #9
0
 def __init__(self, daemon, cfg):
     super(DaikinAC, self).__init__(daemon, cfg)
     daemon.knx_read_cbs.append(self.process_knx)
     self.poll_interval = "poll_interval" in cfg and cfg[
         "poll_interval"] or 10
     for obj in cfg["objects"]:
         if obj["enabled"]:
             obj.update({"value": None})
     log.debug("{} obj_list: {!r}".format(self.device_name, self.obj_list))
Пример #10
0
 async def _card_removed(self, card):
     log.debug(f"{self.device_name} FOB {card} removed!")
     key = str(card.value)
     if key in self.objs_by_fob:
         for obj in self.objs_by_fob[key]:
             knx_group = obj["knx_group"]
             delay = obj["delay"]
             await asyncio.sleep(delay)
             log.debug(f"{self.device_name} stopping {knx_group}")
             await self.d.set_group_value_dict({knx_group: "off"})
Пример #11
0
 async def process_direct(self, group, value):
     log.debug(f"{self.device_name} process_direct(group={group}, value={value})")
     try:
         o = self._get_output_obj_by_knxgrp_and_value(group, value)
         if o:
             await self.set_gpio(o, value)
         else:
             log.debug(f"{self.device_name} no gpio output found.")
     except StopIteration:
         return
Пример #12
0
 async def write_rs485(self, o, value, debug_msg):
     rs485key = o["rs485key"]
     if "valmap" in o:
         val = next(
             (key for key, val in o["valmap"].items() if val == value),
             value)
     else:
         val = value
     cmd = (rs485key + '=' + val)
     log.debug(f"{debug_msg} writing RS485 command {cmd}")
     self._writer.write((cmd + '\r\n').encode(encoding='ascii'))
     await self._writer.drain()
Пример #13
0
 async def process_knx(self, cmd):
     try:
         knx_grp, raw = cmd.split("=")
         value = raw.strip()
         log.debug(f"{self.device_name} process_knx(group={knx_grp}, value={value})")
         o = self._get_output_obj_by_knxgrp_and_value(knx_grp, value)
         if o:
             await self.set_gpio(o, value)
         else:
             log.debug(f"{self.device_name} no gpio output found.")
         return True
     except:
         return False
Пример #14
0
 def receive_info(self):
     try:
         self._cached_ctrl_fields = self._get(
             "/aircon/get_control_info")
         log.debug("Daikin AC Control Fields {!r}".format(
             self._cached_ctrl_fields))
         self._cached_sens_fields = self._get(
             "/aircon/get_sensor_info")
         log.debug("Daikin AC Sensor Fields {!r}".format(
             self._cached_sens_fields))
     except ConnectionError as e:
         log.warning(
             "Daikin AC Couldn't perform API read {!r}".format(e))
Пример #15
0
 async def send_knx(self, sequence):
     async with self._knx_lock:
         xml = '<write>' + sequence + '</write>\n\x04'
         log.debug("sending to knx:{!r}".format(xml))
         self.knx_client_writer.write(xml.encode(encoding='utf_8'))
         await self.knx_client_writer.drain()
         data = await asyncio.wait_for(self.knx_client_reader.readline(),
                                       timeout=30.0)
         decoded = data.decode()
         if "<write status='error'>" in decoded:
             log.error("LinKNX {}".format(decoded[1:-1]))
         else:
             log.debug("LinKNX {!r}".format(decoded))
Пример #16
0
    async def process_values(self, query):
        group_value_dict = {}
        for obj in self.obj_list:
            sensor = obj["sensor"]
            group = obj["knx_group"]
            debug_msg = "%s->%s" % (sensor, group)

            if sensor in query and obj["enabled"]:
                try:
                    value = float(query[sensor])
                    if value == -9999:
                        log.debug(
                            "bogus value for {}, ignored!".format(debug_msg))
                        continue
                    debug_msg += " numeric value: {0:g}".format(value)
                    conversion = obj["conversion"]
                    if conversion and conversion in self.Unit_converter:
                        value = round(self.Unit_converter[conversion](value),
                                      2)
                        debug_msg += "^={0:g}".format(value)

                    hysteresis = obj["hysteresis"]
                    prev_val = obj["value"]
                    if type(hysteresis) == str and "%" in hysteresis and abs(
                            value - prev_val) <= float(
                                hysteresis.strip('%')) * value * 0.01 or type(
                                    hysteresis) == float and abs(
                                        value - prev_val) <= hysteresis:
                        log.debug(
                            "{0}-{1:g} < {2:g} hysteresis, ignored!".format(
                                debug_msg, prev_val, hysteresis))
                        continue
                    elif prev_val == value:
                        log.debug("{!r} unchanged, ignored!".format(debug_msg))
                        continue
                    group_value_dict[group] = "%.2f" % value

                except ValueError:
                    value = query[sensor]
                    debug_msg += " non-numeric value:", value
                    if group in self.previous_values and value == self.previous_values[
                            group]:
                        log.debug("{!r} unchanged, ignored!".format(debug_msg))
                        continue
                    group_value_dict[group] = value

                obj["value"] = value
                log.debug(debug_msg)

        if group_value_dict:
            await self.d.set_group_value_dict(group_value_dict)
Пример #17
0
    async def knx_server_handler(self, reader, writer):
        data = await reader.readline()
        cmd = data.decode()

        addr = writer.get_extra_info('peername')
        log.debug("Received %r from %r" % (cmd, addr))

        parse_errors = []
        for callback in self.knx_read_cbs:
            if not await callback(cmd):
                parse_errors.append(callback)
        if parse_errors:
            log.error(
                "Couldn't parse linknx command: {!r} in callback {!r}".format(
                    cmd, parse_errors))
        writer.close()
Пример #18
0
 async def handle(self, request):
     query = request.rel_url.query
     log.debug(f"{self.device_name} handle: {query!r}")
     if "toggle" in query:
         if not "key" in query:
             log.warning(
                 f"{self.device_name} no FOB key given when handling {query!r}!"
             )
             return web.Response(status=403, text="Forbidden\n")
         fobkey = query["key"]
         fobname = self.d.cfg["fobs"].get(fobkey, "unknown")
         for item in self.obj_list:
             if "opener" in item:
                 opener = item
             if "lock" in item:
                 lock = item
         if lock["value"] == "close":
             if fobkey in lock["allowed_fobs"]:
                 log.warning(
                     f"{self.device_name} {fobname}' FOB ({fobkey}) validated for unlocking!"
                 )
                 await self.d.set_group_value_dict(
                     {lock["knx_group"]: "open"})
                 lockdelay = lock["delay"]
                 await asyncio.sleep(lock["delay"])
                 log.warning(
                     f"{self.device_name} lockdelay waited for {lockdelay}s"
                 )
             else:
                 log.warning(
                     f"{self.device_name} {fobname}' FOB ({fobkey}) not allowed to unlock!"
                 )
                 return web.Response(status=403, text="Forbidden\n")
         if fobkey in opener["allowed_fobs"]:
             log.info(
                 f"{self.device_name} {fobname}'s FOB validated ({fobkey}) for opening!"
             )
             await self.d.set_group_value_dict({opener["knx_group"]: "on"})
             await asyncio.sleep(opener["delay"])
             await self.d.set_group_value_dict({opener["knx_group"]: "off"})
             return web.Response(text="success\n")
         else:
             log.warning(
                 f"{self.device_name} {fobname}'s FOB ({fobkey}) not allowed to open!"
             )
             return web.Response(status=403, text="Forbidden\n")
     return web.Response(status=404, text="Not found\n")
Пример #19
0
 def __init__(self, cfg, daemon):
     super(Rdm6300Reader, self).__init__(cfg["serialDevice"])
     self.d = daemon
     self.device_name = cfg["name"]
     self.fobs = daemon.cfg["fobs"]
     self.forbidden_fobs = daemon.cfg["forbidden_fobs"]
     self.throttle_delay = "throttle_delay" in cfg and cfg(
         "throttle_delay") or 5
     self.objs_by_fob = {}
     for o in cfg["objects"]:
         for key in o["allowed_fobs"]:
             if o["enabled"]:
                 if key not in self.objs_by_fob:
                     self.objs_by_fob[key] = []
                 d = {"knx_group": o["knx_group"], "delay": o["delay"]}
                 self.objs_by_fob[key].append(d)
     log.debug(f"{self.device_name} objs_by_fob: {self.objs_by_fob!r}")
Пример #20
0
    async def handle_sm(self):
        log.debug('handle_sm...')
        from pymodbus.constants import Endian
        from pymodbus.payload import BinaryPayloadDecoder
        self._BE = Endian.Big
        if self.cfg["modbus_wordorder"] == "LE":
            self.wordorder = Endian.Little
        else:
            self.wordorder = Endian.Big
        self.modbus_bin_pay_dec = BinaryPayloadDecoder
        while True:
            group_value_dict = {}

            for o in self.obj_list:
                register = o["register"]
                raw_val = self._read_modbus(o["data_type"], o["register"])
                if raw_val is None:
                    continue
                prev_val = o["value"]

                mag = o["magnitude"]
                value = round(raw_val * o["magnitude"], 3)

                debug_msg = "{} read {} raw={} => value={}".format(
                    self.device_name, o["knx_group"], raw_val, value)

                hysteresis = o["hysteresis"]
                if type(hysteresis) == str and "%" in hysteresis and abs(
                        value - prev_val) <= float(hysteresis.strip(
                            '%')) * value * 0.01 or type(hysteresis) in (
                                int,
                                float) and abs(value - prev_val) <= hysteresis:
                    log.debug("{}-{} < {} hysteresis, ignored!".format(
                        debug_msg, prev_val, hysteresis))
                    continue
                elif prev_val == value:
                    log.debug("{} unchanged, ignored!".format(debug_msg))
                    continue
                else:
                    log.debug("{} UPDATED from {}".format(debug_msg, prev_val))

                prec = o["precision"]
                str_value = "%.{}f".format(prec) % round(value, prec)
                group_value_dict[o["knx_group"]] = str_value

                o["value"] = value

            if group_value_dict:
                await self.d.set_group_value_dict(group_value_dict)

            await asyncio.sleep(self.poll_interval)
Пример #21
0
 def __init__(self, daemon, cfg):
     super(gpio, self).__init__(daemon, cfg)
     daemon.knx_read_cbs.append(self.process_knx)
     daemon.value_direct_cbs.append(self.process_direct)
     for o in cfg["objects"]:
         gpio_type = o["gpio_type"]
         gpio_pin = o["gpio_pin"]
         if o["enabled"] and gpio_type in self.GPIO_TYPE_MAP:
             gpio_obj = self.GPIO_TYPE_MAP[gpio_type][0](gpio_pin)
             o["gpio_object"] = gpio_obj
             o["gpio_direction"] = self.GPIO_TYPE_MAP[gpio_type][1]
             for key, val in o["actions"].items():
                 if o["gpio_direction"] == self.GPIO_DIRECTION_INPUT:
                     action = key
                     value = val
                 elif o["gpio_direction"] == self.GPIO_DIRECTION_OUTPUT:
                     action = val
                     value = key
                 if action in self.GPIO_ACTION_MAP:
                     actioncbname = self.GPIO_ACTION_MAP[action]
                     if hasattr(gpio_obj, actioncbname):
                         actioncb = (lambda value: lambda evt: self.gpio_action(evt, o["knx_group"], value))(value)
                         if o["gpio_direction"] == self.GPIO_DIRECTION_INPUT:
                             setattr(gpio_obj, actioncbname, actioncb)
                             log.debug(f"{self.device_name} init. on callback='{actioncbname}' set value='{value}' for {o!r}")
                         else:
                             o["set_cb"] = getattr(gpio_obj, actioncbname)
                             log.debug(f"{self.device_name} init. on value change to '{value}', call='{actioncbname}' for {o!r}")
                     else:
                         log.warning(f"{self.device_name} init illegal action '{actioncbname}' for {gpio_obj!r}")
     log.debug("{} obj_list: {!r}".format(self.device_name, self.obj_list))
Пример #22
0
 async def mqtt_handle(self, messages, obj):
     group_value_dict = {}
     async for message in messages:
         payload = message.payload.decode()
         try:
             jsonobj = loads(payload)
         except ValueError:
             jsonobj = None
             value = str(payload)
         objects = self._get_objects_by_topic(message.topic)
         for o in objects:
             knx_group = o["knx_group"]
             if jsonobj and "valmap" in o:
                 for key, valdict in o["valmap"].items():
                     if key in jsonobj:
                         prop = jsonobj[key]
                         if type(valdict) == dict and prop in valdict:
                             value = valdict[prop]
                         else:
                             value = str(prop)
                     else:
                         value = None
                         continue
             prev_val = o["value"]
             if value == None:
                 pass
             elif prev_val != value:
                 o["value"] = value
                 group_value_dict[knx_group] = value
                 log.debug(f"{self.device_name} mqtt topic={message.topic} payload={payload} knx_group={knx_group} updated value {prev_val}=>{value}")
                 if group_value_dict:
                     await self.d.set_group_value_dict(group_value_dict)
             else:
                 log.debug(f"{self.device_name} mqtt topic={message.topic} payload={payload} knx_group={knx_group} value={value} unchanged, ignored")
             if knx_group in self.status_pending_for_groups:
                 self.status_pending_for_groups.remove(knx_group)
Пример #23
0
 async def set_gpio(self, o, value):
     log.debug(f"{self.device_name} set_gpio({o!r}, {value})")
     try:
         gpio_obj = o["gpio_object"]
         prev_value = gpio_obj.value
         set_cb = o["set_cb"]
         log.info(f"{self.device_name} set_gpio prev_active={prev_value}->{value}. calling {set_cb!r}...")
         set_cb()
         if "actuate_seconds" in o:
             delay = o["actuate_seconds"]
             log.debug(f"{self.device_name} waiting {delay} s")
             await asyncio.sleep(delay)
             gpio_obj.value = prev_value
             log.debug(f"{self.device_name} restored previous state")
     except (TypeError, AttributeError):
         log.warning(f"{self.device_name} set_gpio illegal action '{value}' for {gpio_obj!r}")
Пример #24
0
    async def process_knx(self, cmd):
        msg = None
        try:
            knx_grp, raw = cmd.split("=")
            debug_msg = "{} knx group {} raw={}".format(
                self.device_name, knx_grp, raw)

            try:
                ac_obj = self.get_obj_by_knxgrp(knx_grp)["ac_object"]
            except StopIteration:
                log.debug(
                    "{} no AC object for given KNX group, ignored".format(
                        debug_msg))
                return True

            if ac_obj == "fan_rate":
                if raw == "0":
                    value = "A"
                elif raw == "1":
                    value = "B"
            elif raw in ["off", "false", "disable", "stop", "inactive"]:
                value = 0
            elif raw in ["on", "true", "enable", "start", "active"]:
                value = 1
            else:
                value = raw

            if str(value) == str(self._get_value_by_acobj(ac_obj)):
                log.debug(
                    "{} ac_obj {} unchanged value {}->{}, ignored!".format(
                        debug_msg, ac_obj,
                        str(self._get_value_by_acobj(ac_obj)), str(value)))
                return True

            log.debug("{} ac_obj {} updated value {}=>{}".format(
                debug_msg, ac_obj, self._get_value_by_acobj(ac_obj), value))
            setattr(self._client, ac_obj, value)
            return True

        except:
            return False
Пример #25
0
 async def handle(self, request):
     log.debug("handle: {!r}".format(request.rel_url.query))
     await self.process_values(request.rel_url.query)
     return web.Response(text="success\n")
Пример #26
0
    async def handle_ups(self):
        while True:
            data = await self.ups_reader.readuntil(b'\x00\x00')
            debug_msg = []

            if not data:
                break

            data = data.decode('ascii')
            m = re.match(self.expression, data, re.DOTALL)

            if m:
                group_value_dict = {}
                for idx, o in enumerate(self.obj_list):
                    group = o["knx_group"]
                    val = m.groups(0)[idx]
                    debug_line = "idx: {} group: {} val: {}".format(
                        idx, group, val)
                    prev_val = o["value"]
                    try:
                        value = float(val)
                        debug_line += " numeric value: {0:g}".format(value)
                        hysteresis = o["hysteresis"]
                        if type(hysteresis
                                ) == str and "%" in hysteresis and abs(
                                    value - prev_val) <= float(
                                        hysteresis.strip('%')
                                    ) * value * 0.01 or type(
                                        hysteresis) == float and abs(
                                            value - prev_val) <= hysteresis:
                            debug_msg.append(
                                "{}-{:g} < {:g} hysteresis, ignored!".format(
                                    debug_line, prev_val, hysteresis))
                            continue
                        elif prev_val == value:
                            debug_msg.append(
                                "{} unchanged, ignored!".format(debug_line))
                            continue
                        group_value_dict[group] = "%.2f" % value

                    except ValueError:
                        if val == "ONLINE":
                            value = "true"
                        elif val == "ONBATT":
                            value = "false"
                        debug_line += " non-numeric value: ->{}".format(value)
                        if prev_val == value:
                            debug_msg.append(
                                "{} unchanged, ignored!".format(debug_line))
                            continue
                        group_value_dict[group] = value

                    o["value"] = value
                    debug_msg.append(debug_line)

                log.debug("{} {!r}\t".format(self.device_name, data) +
                          "\n\t".join(debug_msg))

                if group_value_dict:
                    await self.d.set_group_value_dict(group_value_dict)

            else:
                log.warning("{} Couldn't parse {!r}".format(
                    self.device_name, data))
Пример #27
0
 async def send_avr(self, data):
     log.debug("sending to avr: '%s'" % data)
     self.avr_writer.write((data+'\r').encode(encoding='ascii'))
     self.avr_writer.drain()
Пример #28
0
    async def handle_avr(self):
        while True:
            group_value_dict = {}
            data = await self.avr_reader.readline()

            if not data:
                break

            line = data.decode('ascii')
            log.debug('avr received {!r}'.format(line))

            if line.startswith('FL02'):
              if line == "FL022020202020202020202020202020\r\n":
                self.accu_word = self.accu_word and self.accu_word.rstrip() or ""
                self.set_value_for_avr("display_text", self.accu_word)
                group_value_dict[self.get_knx_by_avr("display_text")] = self.get_value_by_avr("display_text")
                log.debug("display_text complete! '%s'" % self.get_value_by_avr("display_text"))
              else:
                new_word = bytes.fromhex(line[4:-2]).decode('iso8859_15')
                if self.accu_word == None:
                    self.accu_word = new_word
                    log.debug("1START new_word={!r} accu_word={!r}".format(new_word, self.accu_word))
                elif self.accu_word[-13:] != new_word[:-1]:
                    if not self.get_value_by_avr("display_text") or new_word not in self.get_value_by_avr("display_text"):
                        self.set_value_for_avr("display_text", None)
                        self.accu_word = new_word
                        group_value_dict[self.get_knx_by_avr("display_text")] = self.accu_word
                        log.debug("CHANGE new_word={!r} accu_word={!r}".format(new_word, self.accu_word))
                    else:
                        log.debug("STARTOVER new_word={!r} accu_word={!r}".format(new_word, self.accu_word))
                else:
                  self.accu_word += new_word[-1:]
                  log.debug("+++++ new_word={!r} accu_word={!r}".format(new_word, self.accu_word))
                if not self.get_value_by_avr("display_text") and self.accu_word[-1] != ' ':
                  group_value_dict[self.get_knx_by_avr("display_text")] = self.accu_word.rstrip()
                  log.debug("COMMIT new_word={!r} accu_word={!r}".format(new_word, self.accu_word))

            elif line.startswith('VOL'):
              avr_volume = int(line[3:])
              new_volume = round(avr_volume * (255.0 / 185.0))
              if new_volume != self.get_value_by_avr("volume"):
                self.set_value_for_avr("volume", new_volume)
                group_value_dict[self.get_knx_by_avr("volume")] = self.get_value_by_avr("volume")

            elif line.startswith('PWR'):
              if line[3] == '0':
                self.set_value_for_avr("power", "on")
              else:
                self.set_value_for_avr("power", "off")
              group_value_dict[self.get_knx_by_avr("power")] = self.get_value_by_avr("power")
              self.set_value_for_avr("display_text", None)
              group_value_dict[self.get_knx_by_avr("display_text")] = self.get_value_by_avr("display_text")

            elif line.startswith('FN'):
              new_fn = int(line[2:4])
              if new_fn != self.get_value_by_avr("fn"):
                self.set_value_for_avr("fn", new_fn)
                group_value_dict[self.get_knx_by_avr("fn")] = self.get_value_by_avr("fn")
                self.set_value_for_avr("display_text", None)
                group_value_dict[self.get_knx_by_avr("display_text")] = self.get_value_by_avr("display_text")

            if group_value_dict:
                await self.d.set_group_value_dict(group_value_dict)