Add monitor enabled parsing

This commit is contained in:
Roberto Alsina 2020-02-05 18:21:32 -03:00
parent 6e18d870eb
commit a409fcaa69
7 changed files with 428 additions and 2 deletions

147
tests/fixtures/disabled_monitor.txt vendored Normal file
View File

@ -0,0 +1,147 @@
HDMI-A-0 connected (normal left inverted right x axis y axis)
Identifier: 0x54
Timestamp: 81697863
Subpixel: unknown
Clones:
CRTCs: 0 1 2 3
Transform: 1.000000 0.000000 0.000000
0.000000 1.000000 0.000000
0.000000 0.000000 1.000000
filter:
EDID:
00ffffffffffff004c2d200d47515a5a
321c010380341d782a9315a655519c27
115054bfef80714f81c0810081809500
a9c0b3000101023a801871382d40582c
450009252100001e000000fd00324b1e
5111000a202020202020000000fc0053
3234463335300a2020202020000000ff
0048345a4b4330303436380a202001ae
020311b14690041f13120365030c0010
00011d00bc52d01e20b8285540092521
00001e8c0ad090204031200c40550009
25210000188c0ad08a20e02d10103e96
00092521000018000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000051
GAMMA_LUT_SIZE: 4096
range: (0, -1)
DEGAMMA_LUT_SIZE: 4096
range: (0, -1)
GAMMA_LUT: 0
range: (0, 65535)
CTM: 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 1
DEGAMMA_LUT: 0
range: (0, 65535)
TearFree: auto
supported: off, on, auto
vrr_capable: 0
range: (0, 1)
max bpc: 8
range: (8, 16)
underscan vborder: 0
range: (0, 128)
underscan hborder: 0
range: (0, 128)
underscan: off
supported: off, on, auto
scaling mode: None
supported: None, Full, Center, Full aspect
link-status: Good
supported: Good, Bad
CONNECTOR_ID: 69
supported: 69
non-desktop: 0
range: (0, 1)
1920x1080 (0x5f) 148.500MHz +HSync +VSync +preferred
h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 67.50KHz
v: height 1080 start 1084 end 1089 total 1125 clock 60.00Hz
1920x1080 (0x60) 148.500MHz +HSync +VSync
h: width 1920 start 2448 end 2492 total 2640 skew 0 clock 56.25KHz
v: height 1080 start 1084 end 1089 total 1125 clock 50.00Hz
1920x1080 (0x61) 148.352MHz +HSync +VSync
h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 67.43KHz
v: height 1080 start 1084 end 1089 total 1125 clock 59.94Hz
1680x1050 (0x62) 119.000MHz +HSync -VSync
h: width 1680 start 1728 end 1760 total 1840 skew 0 clock 64.67KHz
v: height 1050 start 1053 end 1059 total 1080 clock 59.88Hz
1600x900 (0x63) 108.000MHz +HSync +VSync
h: width 1600 start 1624 end 1704 total 1800 skew 0 clock 60.00KHz
v: height 900 start 901 end 904 total 1000 clock 60.00Hz
1280x1024 (0x64) 135.000MHz +HSync +VSync
h: width 1280 start 1296 end 1440 total 1688 skew 0 clock 79.98KHz
v: height 1024 start 1025 end 1028 total 1066 clock 75.02Hz
1280x1024 (0x65) 108.000MHz +HSync +VSync
h: width 1280 start 1328 end 1440 total 1688 skew 0 clock 63.98KHz
v: height 1024 start 1025 end 1028 total 1066 clock 60.02Hz
1440x900 (0x66) 88.750MHz +HSync -VSync
h: width 1440 start 1488 end 1520 total 1600 skew 0 clock 55.47KHz
v: height 900 start 903 end 909 total 926 clock 59.90Hz
1280x800 (0x67) 71.000MHz +HSync -VSync
h: width 1280 start 1328 end 1360 total 1440 skew 0 clock 49.31KHz
v: height 800 start 803 end 809 total 823 clock 59.91Hz
1152x864 (0x68) 108.000MHz +HSync +VSync
h: width 1152 start 1216 end 1344 total 1600 skew 0 clock 67.50KHz
v: height 864 start 865 end 868 total 900 clock 75.00Hz
1280x720 (0x69) 74.250MHz +HSync +VSync
h: width 1280 start 1390 end 1430 total 1650 skew 0 clock 45.00KHz
v: height 720 start 725 end 730 total 750 clock 60.00Hz
1280x720 (0x6a) 74.250MHz +HSync +VSync
h: width 1280 start 1720 end 1760 total 1980 skew 0 clock 37.50KHz
v: height 720 start 725 end 730 total 750 clock 50.00Hz
1280x720 (0x6b) 74.176MHz +HSync +VSync
h: width 1280 start 1390 end 1430 total 1650 skew 0 clock 44.96KHz
v: height 720 start 725 end 730 total 750 clock 59.94Hz
1024x768 (0x6c) 78.750MHz +HSync +VSync
h: width 1024 start 1040 end 1136 total 1312 skew 0 clock 60.02KHz
v: height 768 start 769 end 772 total 800 clock 75.03Hz
1024x768 (0x6d) 75.000MHz -HSync -VSync
h: width 1024 start 1048 end 1184 total 1328 skew 0 clock 56.48KHz
v: height 768 start 771 end 777 total 806 clock 70.07Hz
1024x768 (0x6e) 65.000MHz -HSync -VSync
h: width 1024 start 1048 end 1184 total 1344 skew 0 clock 48.36KHz
v: height 768 start 771 end 777 total 806 clock 60.00Hz
832x624 (0x6f) 57.284MHz -HSync -VSync
h: width 832 start 864 end 928 total 1152 skew 0 clock 49.73KHz
v: height 624 start 625 end 628 total 667 clock 74.55Hz
800x600 (0x70) 50.000MHz +HSync +VSync
h: width 800 start 856 end 976 total 1040 skew 0 clock 48.08KHz
v: height 600 start 637 end 643 total 666 clock 72.19Hz
800x600 (0x71) 49.500MHz +HSync +VSync
h: width 800 start 816 end 896 total 1056 skew 0 clock 46.88KHz
v: height 600 start 601 end 604 total 625 clock 75.00Hz
800x600 (0x72) 40.000MHz +HSync +VSync
h: width 800 start 840 end 968 total 1056 skew 0 clock 37.88KHz
v: height 600 start 601 end 605 total 628 clock 60.32Hz
800x600 (0x73) 36.000MHz +HSync +VSync
h: width 800 start 824 end 896 total 1024 skew 0 clock 35.16KHz
v: height 600 start 601 end 603 total 625 clock 56.25Hz
720x576 (0x74) 27.000MHz -HSync -VSync
h: width 720 start 732 end 796 total 864 skew 0 clock 31.25KHz
v: height 576 start 581 end 586 total 625 clock 50.00Hz
720x480 (0x75) 27.027MHz -HSync -VSync
h: width 720 start 736 end 798 total 858 skew 0 clock 31.50KHz
v: height 480 start 489 end 495 total 525 clock 60.00Hz
720x480 (0x76) 27.000MHz -HSync -VSync
h: width 720 start 736 end 798 total 858 skew 0 clock 31.47KHz
v: height 480 start 489 end 495 total 525 clock 59.94Hz
640x480 (0x77) 31.500MHz -HSync -VSync
h: width 640 start 656 end 720 total 840 skew 0 clock 37.50KHz
v: height 480 start 481 end 484 total 500 clock 75.00Hz
640x480 (0x78) 31.500MHz -HSync -VSync
h: width 640 start 664 end 704 total 832 skew 0 clock 37.86KHz
v: height 480 start 489 end 492 total 520 clock 72.81Hz
640x480 (0x79) 30.240MHz -HSync -VSync
h: width 640 start 704 end 768 total 864 skew 0 clock 35.00KHz
v: height 480 start 483 end 486 total 525 clock 66.67Hz
640x480 (0x7a) 25.200MHz -HSync -VSync
h: width 640 start 656 end 752 total 800 skew 0 clock 31.50KHz
v: height 480 start 490 end 492 total 525 clock 60.00Hz
640x480 (0x7b) 25.175MHz -HSync -VSync
h: width 640 start 656 end 752 total 800 skew 0 clock 31.47KHz
v: height 480 start 490 end 492 total 525 clock 59.94Hz
720x400 (0x7c) 28.320MHz -HSync +VSync
h: width 720 start 738 end 846 total 900 skew 0 clock 31.47KHz
v: height 400 start 412 end 414 total 449 clock 70.08Hz

232
tests/fixtures/replicated.txt vendored Normal file
View File

@ -0,0 +1,232 @@
Screen 0: minimum 320 x 200, current 1920 x 1080, maximum 16384 x 16384
eDP connected primary 1920x1080+0+0 (0x56) normal (normal left inverted right x axis y axis) 309mm x 173mm
Identifier: 0x53
Timestamp: 81425529
Subpixel: unknown
Gamma: 1.0:1.0:1.0
Brightness: 1.0
Clones:
CRTC: 0
CRTCs: 0 1 2 3
Transform: 1.000000 0.000000 0.000000
0.000000 1.000000 0.000000
0.000000 0.000000 1.000000
filter:
EDID:
00ffffffffffff000daed41400000000
241a0104a51f11780228659759548e27
1e505400000001010101010101010101
010101010101b43b804a71383440503c
680035ad10000018000000fe004e3134
304843412d4541430a20000000fe0043
4d4e0a202020202020202020000000fe
004e3134304843412d4541430a200005
GAMMA_LUT_SIZE: 4096
range: (0, -1)
DEGAMMA_LUT_SIZE: 4096
range: (0, -1)
GAMMA_LUT: 0
range: (0, 65535)
CTM: 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 1
DEGAMMA_LUT: 0
range: (0, 65535)
TearFree: auto
supported: off, on, auto
vrr_capable: 0
range: (0, 1)
abm level: 0
range: (0, 4)
max bpc: 8
range: (8, 16)
underscan vborder: 0
range: (0, 128)
underscan hborder: 0
range: (0, 128)
underscan: off
supported: off, on, auto
scaling mode: None
supported: None, Full, Center, Full aspect
link-status: Good
supported: Good, Bad
CONNECTOR_ID: 64
supported: 64
non-desktop: 0
range: (0, 1)
1920x1080 (0x56) 152.840MHz -HSync -VSync *current +preferred
h: width 1920 start 2000 end 2060 total 2250 skew 0 clock 67.93KHz
v: height 1080 start 1086 end 1094 total 1132 clock 60.01Hz
1680x1050 (0x57) 152.840MHz -HSync -VSync
h: width 1680 start 2000 end 2060 total 2250 skew 0 clock 67.93KHz
v: height 1050 start 1086 end 1094 total 1132 clock 60.01Hz
1280x1024 (0x58) 152.840MHz -HSync -VSync
h: width 1280 start 2000 end 2060 total 2250 skew 0 clock 67.93KHz
v: height 1024 start 1086 end 1094 total 1132 clock 60.01Hz
1440x900 (0x59) 152.840MHz -HSync -VSync
h: width 1440 start 2000 end 2060 total 2250 skew 0 clock 67.93KHz
v: height 900 start 1086 end 1094 total 1132 clock 60.01Hz
1280x800 (0x5a) 152.840MHz -HSync -VSync
h: width 1280 start 2000 end 2060 total 2250 skew 0 clock 67.93KHz
v: height 800 start 1086 end 1094 total 1132 clock 60.01Hz
1280x720 (0x5b) 152.840MHz -HSync -VSync
h: width 1280 start 2000 end 2060 total 2250 skew 0 clock 67.93KHz
v: height 720 start 1086 end 1094 total 1132 clock 60.01Hz
1024x768 (0x5c) 152.840MHz -HSync -VSync
h: width 1024 start 2000 end 2060 total 2250 skew 0 clock 67.93KHz
v: height 768 start 1086 end 1094 total 1132 clock 60.01Hz
800x600 (0x5d) 152.840MHz -HSync -VSync
h: width 800 start 2000 end 2060 total 2250 skew 0 clock 67.93KHz
v: height 600 start 1086 end 1094 total 1132 clock 60.01Hz
640x480 (0x5e) 152.840MHz -HSync -VSync
h: width 640 start 2000 end 2060 total 2250 skew 0 clock 67.93KHz
v: height 480 start 1086 end 1094 total 1132 clock 60.01Hz
HDMI-A-0 connected 1920x1080+0+0 (0x5f) normal (normal left inverted right x axis y axis) 521mm x 293mm
Identifier: 0x54
Timestamp: 81425529
Subpixel: unknown
Gamma: 1.0:1.0:1.0
Brightness: 1.0
Clones:
CRTC: 1
CRTCs: 0 1 2 3
Transform: 1.000000 0.000000 0.000000
0.000000 1.000000 0.000000
0.000000 0.000000 1.000000
filter:
EDID:
00ffffffffffff004c2d200d47515a5a
321c010380341d782a9315a655519c27
115054bfef80714f81c0810081809500
a9c0b3000101023a801871382d40582c
450009252100001e000000fd00324b1e
5111000a202020202020000000fc0053
3234463335300a2020202020000000ff
0048345a4b4330303436380a202001ae
020311b14690041f13120365030c0010
00011d00bc52d01e20b8285540092521
00001e8c0ad090204031200c40550009
25210000188c0ad08a20e02d10103e96
00092521000018000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000051
GAMMA_LUT_SIZE: 4096
range: (0, -1)
DEGAMMA_LUT_SIZE: 4096
range: (0, -1)
GAMMA_LUT: 0
range: (0, 65535)
CTM: 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 1
DEGAMMA_LUT: 0
range: (0, 65535)
TearFree: auto
supported: off, on, auto
vrr_capable: 0
range: (0, 1)
max bpc: 8
range: (8, 16)
underscan vborder: 0
range: (0, 128)
underscan hborder: 0
range: (0, 128)
underscan: off
supported: off, on, auto
scaling mode: None
supported: None, Full, Center, Full aspect
link-status: Good
supported: Good, Bad
CONNECTOR_ID: 69
supported: 69
non-desktop: 0
range: (0, 1)
1920x1080 (0x5f) 148.500MHz +HSync +VSync *current +preferred
h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 67.50KHz
v: height 1080 start 1084 end 1089 total 1125 clock 60.00Hz
1920x1080 (0x60) 148.500MHz +HSync +VSync
h: width 1920 start 2448 end 2492 total 2640 skew 0 clock 56.25KHz
v: height 1080 start 1084 end 1089 total 1125 clock 50.00Hz
1920x1080 (0x61) 148.352MHz +HSync +VSync
h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 67.43KHz
v: height 1080 start 1084 end 1089 total 1125 clock 59.94Hz
1680x1050 (0x62) 119.000MHz +HSync -VSync
h: width 1680 start 1728 end 1760 total 1840 skew 0 clock 64.67KHz
v: height 1050 start 1053 end 1059 total 1080 clock 59.88Hz
1600x900 (0x63) 108.000MHz +HSync +VSync
h: width 1600 start 1624 end 1704 total 1800 skew 0 clock 60.00KHz
v: height 900 start 901 end 904 total 1000 clock 60.00Hz
1280x1024 (0x64) 135.000MHz +HSync +VSync
h: width 1280 start 1296 end 1440 total 1688 skew 0 clock 79.98KHz
v: height 1024 start 1025 end 1028 total 1066 clock 75.02Hz
1280x1024 (0x65) 108.000MHz +HSync +VSync
h: width 1280 start 1328 end 1440 total 1688 skew 0 clock 63.98KHz
v: height 1024 start 1025 end 1028 total 1066 clock 60.02Hz
1440x900 (0x66) 88.750MHz +HSync -VSync
h: width 1440 start 1488 end 1520 total 1600 skew 0 clock 55.47KHz
v: height 900 start 903 end 909 total 926 clock 59.90Hz
1280x800 (0x67) 71.000MHz +HSync -VSync
h: width 1280 start 1328 end 1360 total 1440 skew 0 clock 49.31KHz
v: height 800 start 803 end 809 total 823 clock 59.91Hz
1152x864 (0x68) 108.000MHz +HSync +VSync
h: width 1152 start 1216 end 1344 total 1600 skew 0 clock 67.50KHz
v: height 864 start 865 end 868 total 900 clock 75.00Hz
1280x720 (0x69) 74.250MHz +HSync +VSync
h: width 1280 start 1390 end 1430 total 1650 skew 0 clock 45.00KHz
v: height 720 start 725 end 730 total 750 clock 60.00Hz
1280x720 (0x6a) 74.250MHz +HSync +VSync
h: width 1280 start 1720 end 1760 total 1980 skew 0 clock 37.50KHz
v: height 720 start 725 end 730 total 750 clock 50.00Hz
1280x720 (0x6b) 74.176MHz +HSync +VSync
h: width 1280 start 1390 end 1430 total 1650 skew 0 clock 44.96KHz
v: height 720 start 725 end 730 total 750 clock 59.94Hz
1024x768 (0x6c) 78.750MHz +HSync +VSync
h: width 1024 start 1040 end 1136 total 1312 skew 0 clock 60.02KHz
v: height 768 start 769 end 772 total 800 clock 75.03Hz
1024x768 (0x6d) 75.000MHz -HSync -VSync
h: width 1024 start 1048 end 1184 total 1328 skew 0 clock 56.48KHz
v: height 768 start 771 end 777 total 806 clock 70.07Hz
1024x768 (0x6e) 65.000MHz -HSync -VSync
h: width 1024 start 1048 end 1184 total 1344 skew 0 clock 48.36KHz
v: height 768 start 771 end 777 total 806 clock 60.00Hz
832x624 (0x6f) 57.284MHz -HSync -VSync
h: width 832 start 864 end 928 total 1152 skew 0 clock 49.73KHz
v: height 624 start 625 end 628 total 667 clock 74.55Hz
800x600 (0x70) 50.000MHz +HSync +VSync
h: width 800 start 856 end 976 total 1040 skew 0 clock 48.08KHz
v: height 600 start 637 end 643 total 666 clock 72.19Hz
800x600 (0x71) 49.500MHz +HSync +VSync
h: width 800 start 816 end 896 total 1056 skew 0 clock 46.88KHz
v: height 600 start 601 end 604 total 625 clock 75.00Hz
800x600 (0x72) 40.000MHz +HSync +VSync
h: width 800 start 840 end 968 total 1056 skew 0 clock 37.88KHz
v: height 600 start 601 end 605 total 628 clock 60.32Hz
800x600 (0x73) 36.000MHz +HSync +VSync
h: width 800 start 824 end 896 total 1024 skew 0 clock 35.16KHz
v: height 600 start 601 end 603 total 625 clock 56.25Hz
720x576 (0x74) 27.000MHz -HSync -VSync
h: width 720 start 732 end 796 total 864 skew 0 clock 31.25KHz
v: height 576 start 581 end 586 total 625 clock 50.00Hz
720x480 (0x75) 27.027MHz -HSync -VSync
h: width 720 start 736 end 798 total 858 skew 0 clock 31.50KHz
v: height 480 start 489 end 495 total 525 clock 60.00Hz
720x480 (0x76) 27.000MHz -HSync -VSync
h: width 720 start 736 end 798 total 858 skew 0 clock 31.47KHz
v: height 480 start 489 end 495 total 525 clock 59.94Hz
640x480 (0x77) 31.500MHz -HSync -VSync
h: width 640 start 656 end 720 total 840 skew 0 clock 37.50KHz
v: height 480 start 481 end 484 total 500 clock 75.00Hz
640x480 (0x78) 31.500MHz -HSync -VSync
h: width 640 start 664 end 704 total 832 skew 0 clock 37.86KHz
v: height 480 start 489 end 492 total 520 clock 72.81Hz
640x480 (0x79) 30.240MHz -HSync -VSync
h: width 640 start 704 end 768 total 864 skew 0 clock 35.00KHz
v: height 480 start 483 end 486 total 525 clock 66.67Hz
640x480 (0x7a) 25.200MHz -HSync -VSync
h: width 640 start 656 end 752 total 800 skew 0 clock 31.50KHz
v: height 480 start 490 end 492 total 525 clock 60.00Hz
640x480 (0x7b) 25.175MHz -HSync -VSync
h: width 640 start 656 end 752 total 800 skew 0 clock 31.47KHz
v: height 480 start 490 end 492 total 525 clock 59.94Hz
720x400 (0x7c) 28.320MHz -HSync +VSync
h: width 720 start 738 end 846 total 900 skew 0 clock 31.47KHz
v: height 400 start 412 end 414 total 449 clock 70.08Hz

View File

@ -20,3 +20,10 @@ def test_parse_modes(test_data):
data = test_data.read("monitor_1.txt", deserialize=False).splitlines() data = test_data.read("monitor_1.txt", deserialize=False).splitlines()
m = Monitor(data) m = Monitor(data)
assert len(m.modes) == 9 assert len(m.modes) == 9
assert m.enabled
def test_disabled_monitor(test_data):
data = test_data.read("disabled_monitor.txt", deserialize=False).splitlines()
m = Monitor(data)
assert m.enabled is False

View File

@ -11,3 +11,9 @@ def test_parse_data(test_data):
def test_parse_with_disconnected_monitors(test_data): def test_parse_with_disconnected_monitors(test_data):
data = test_data.read("fisa_sample.txt", deserialize=False).splitlines() data = test_data.read("fisa_sample.txt", deserialize=False).splitlines()
parse_data(data) parse_data(data)
def test_replicated_monitors(test_data):
data = test_data.read("replicated.txt", deserialize=False).splitlines()
screen = parse_data(data)
assert screen.monitors["eDP"].replica_of == ["HDMI-A-0"]

View File

@ -378,7 +378,8 @@ class Window(QObject):
self.ui.sceneView.scale(scale_factor, scale_factor) self.ui.sceneView.scale(scale_factor, scale_factor)
def get_xrandr_info(self): def get_xrandr_info(self):
self.monitors = xrandr.parse_data(xrandr.read_data()) self.screen = xrandr.parse_data(xrandr.read_data())
self.screen.update_replica_of()
data = subprocess.check_output(["xrandr"]).decode("utf-8").splitlines() data = subprocess.check_output(["xrandr"]).decode("utf-8").splitlines()
name = None name = None

View File

@ -56,6 +56,12 @@ class Mode:
class Monitor: class Monitor:
"""Object representing a monitor according to xrandr.""" """Object representing a monitor according to xrandr."""
res_x = 0
res_y = 0
pos_x = 0
pos_y = 0
enabled = False
def __init__(self, data): def __init__(self, data):
"""Initialize a monitor object out of data from xrandr --verbose. """Initialize a monitor object out of data from xrandr --verbose.
@ -64,9 +70,12 @@ class Monitor:
self.header = data.pop(0) self.header = data.pop(0)
self.output = parse.search("{}{:s}", self.header)[0] self.output = parse.search("{}{:s}", self.header)[0]
self.replica_of = []
if "disconnected" in self.header: if "disconnected" in self.header:
# No modes, no pos, no fields, no nothing. # No modes, no pos, no fields, no nothing.
return return
self.enabled = "+" in self.header
if self.enabled:
self.pos_x, self.pos_y = parse.search("+{:d}+{:d}", self.header) self.pos_x, self.pos_y = parse.search("+{:d}+{:d}", self.header)
modes_data = _split_by_lines_matching("^ [^ ]", data) modes_data = _split_by_lines_matching("^ [^ ]", data)

View File

@ -5,6 +5,20 @@ import subprocess
from .monitor import Monitor, _split_by_lines_matching from .monitor import Monitor, _split_by_lines_matching
def is_replica_of(a, b):
"""Return True if monitor a is a replica of b.
Replica means same resolution and position.
"""
return (
a.pos_x == b.pos_x
and a.pos_y == b.pos_y
and a.res_x == b.res_x
and a.res_y == b.res_y
and b.enabled
)
class Screen: class Screen:
"""A Screen is a collection of monitors.""" """A Screen is a collection of monitors."""
@ -13,6 +27,16 @@ class Screen:
for monitor_data in _split_by_lines_matching(r"^[^ \t].*", data[1:]): for monitor_data in _split_by_lines_matching(r"^[^ \t].*", data[1:]):
m = Monitor(monitor_data) m = Monitor(monitor_data)
self.monitors[m.output] = m self.monitors[m.output] = m
self.update_replica_of()
def update_replica_of(self):
"""Decide which monitors are replicas of each other and
mark them as such."""
for a in self.monitors:
self.monitors[a].replica_of = []
for b in self.monitors:
if a != b and is_replica_of(self.monitors[a], self.monitors[b]):
self.monitors[a].replica_of.append(b)
def read_data(): def read_data():