mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-01-16 14:05:03 +00:00
Compare commits
637 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98d3a4a2fa | ||
|
|
1702c69b73 | ||
|
|
722d28b1b3 | ||
|
|
ef7da0d7af | ||
|
|
77d8e63a31 | ||
|
|
d2d99d4bfa | ||
|
|
4bd71b04bf | ||
|
|
c5bcd89695 | ||
|
|
c7cc98bff7 | ||
|
|
db60f8f1be | ||
|
|
e82efdde2d | ||
|
|
d00c8bed5f | ||
|
|
a91af6bd75 | ||
|
|
2d36b80800 | ||
|
|
e152b9a504 | ||
|
|
eac7c91327 | ||
|
|
ac0d5e59a0 | ||
|
|
78be8ec5f2 | ||
|
|
5fc4ff6027 | ||
|
|
63853739f3 | ||
|
|
c14193f9ac | ||
|
|
da179c01f5 | ||
|
|
0ded3e30f9 | ||
|
|
8d215930d9 | ||
|
|
b4edb021ee | ||
|
|
52caa98f33 | ||
|
|
4e041d1773 | ||
|
|
118bd5a54a | ||
|
|
116abbf962 | ||
|
|
a06333e1c3 | ||
|
|
d937dc14fc | ||
|
|
604f4ca22d | ||
|
|
2d7ad8ba2a | ||
|
|
e4a3933743 | ||
|
|
d6445861f5 | ||
|
|
03b076c8eb | ||
|
|
7c58221acc | ||
|
|
14f7c27b33 | ||
|
|
9ea65883b7 | ||
|
|
9d0020d999 | ||
|
|
fb44a3b93c | ||
|
|
6b7c5c01f8 | ||
|
|
1a3eb9a546 | ||
|
|
44c171c8f4 | ||
|
|
ae9833ffaa | ||
|
|
685c344785 | ||
|
|
e6f5142fc3 | ||
|
|
3c9ca1e527 | ||
|
|
452d0a5a39 | ||
|
|
8643ed2caf | ||
|
|
2787c7fc52 | ||
|
|
babc3e4f1a | ||
|
|
0a4ff82af0 | ||
|
|
b455e1af21 | ||
|
|
e12a5e95bf | ||
|
|
3e7144f7ef | ||
|
|
19e070ed76 | ||
|
|
b818c14713 | ||
|
|
63e7866890 | ||
|
|
922d1d8133 | ||
|
|
d26ea01ed9 | ||
|
|
4ebd1b53b5 | ||
|
|
0226b58b1e | ||
|
|
be41922c54 | ||
|
|
56f93c5491 | ||
|
|
8cfd58bb7e | ||
|
|
6ddfdc4b38 | ||
|
|
7640b95701 | ||
|
|
6c2abc7abd | ||
|
|
1849d118b4 | ||
|
|
22e7f004a5 | ||
|
|
0dcaacb038 | ||
|
|
cf8e673677 | ||
|
|
200080247a | ||
|
|
ba247ee8d6 | ||
|
|
b3617d04c8 | ||
|
|
85cf51876a | ||
|
|
b6f47168c0 | ||
|
|
1e755df9bb | ||
|
|
037f8ed043 | ||
|
|
e327d2d359 | ||
|
|
e832566168 | ||
|
|
252d037380 | ||
|
|
dd0f7a586e | ||
|
|
2feec62052 | ||
|
|
33a1b1697a | ||
|
|
955d68b3f3 | ||
|
|
0f28d46f34 | ||
|
|
275759143b | ||
|
|
3a4737b6f6 | ||
|
|
2b2308d5c2 | ||
|
|
185f03065e | ||
|
|
3803263598 | ||
|
|
358fa1a9c0 | ||
|
|
7fbbc9f2b8 | ||
|
|
f4f400f9b6 | ||
|
|
d3383db890 | ||
|
|
139e5370ea | ||
|
|
4f9fa05e3f | ||
|
|
7ab2574912 | ||
|
|
35167d77f9 | ||
|
|
bdd17dfa27 | ||
|
|
6443e00428 | ||
|
|
008279e867 | ||
|
|
c4a6d20791 | ||
|
|
61b4002e5a | ||
|
|
da63d0917e | ||
|
|
0228fd1c0f | ||
|
|
085ba134c4 | ||
|
|
a9fce3237c | ||
|
|
840fb21e15 | ||
|
|
6ab4d4d090 | ||
|
|
fcdee3b9fd | ||
|
|
4e15d7fe5a | ||
|
|
2a76e2b3f9 | ||
|
|
f9522a533a | ||
|
|
ec07ec84f7 | ||
|
|
0457bcf7fe | ||
|
|
ba0b2e169a | ||
|
|
bebcc3c6e1 | ||
|
|
8ed236abae | ||
|
|
8572191c1e | ||
|
|
4a9b1514e3 | ||
|
|
9c7e38b379 | ||
|
|
846e905ae1 | ||
|
|
00d2159d06 | ||
|
|
7019b62610 | ||
|
|
a583fdb72a | ||
|
|
33bf98303d | ||
|
|
b2f3aa9cfa | ||
|
|
31f6a4bcfd | ||
|
|
29b77f5629 | ||
|
|
f74fa35ca4 | ||
|
|
74231a428d | ||
|
|
8ba0920cc0 | ||
|
|
e23fe06fef | ||
|
|
79fd1f7424 | ||
|
|
2da8f8c9a8 | ||
|
|
743accd980 | ||
|
|
b445f68466 | ||
|
|
847e106b8d | ||
|
|
57f2d7c938 | ||
|
|
f0415d0d05 | ||
|
|
d2ebc340bd | ||
|
|
07fbe102bd | ||
|
|
319909539c | ||
|
|
00589488ac | ||
|
|
f25219c20a | ||
|
|
7c7ae65d40 | ||
|
|
0dcbb652df | ||
|
|
0649cea367 | ||
|
|
9f840fae41 | ||
|
|
c5aef18943 | ||
|
|
70d4a7054f | ||
|
|
b20009b247 | ||
|
|
9588564633 | ||
|
|
eef3b5fb31 | ||
|
|
7078ba55c7 | ||
|
|
e06be3ebe9 | ||
|
|
10046a9ed4 | ||
|
|
51f294c37f | ||
|
|
1990201215 | ||
|
|
be78d17af5 | ||
|
|
8a6d5ebd56 | ||
|
|
93c0b33958 | ||
|
|
dca21aa4dc | ||
|
|
ac09267173 | ||
|
|
ef63c1db02 | ||
|
|
f828cbecbd | ||
|
|
890abf4383 | ||
|
|
52c96cc2c3 | ||
|
|
4ab3cdb1ff | ||
|
|
2dfd647f63 | ||
|
|
7f054d5e98 | ||
|
|
43297c0341 | ||
|
|
6280aa90c9 | ||
|
|
ca497c8f47 | ||
|
|
1da481a8db | ||
|
|
c04d79931d | ||
|
|
dbd3ab2f70 | ||
|
|
36b5faa3d9 | ||
|
|
07bf74ab19 | ||
|
|
e356f57e1a | ||
|
|
86ad88969e | ||
|
|
7020480159 | ||
|
|
bc54856392 | ||
|
|
24a435c965 | ||
|
|
2897ec1d83 | ||
|
|
f075412a86 | ||
|
|
4f5bb4dc46 | ||
|
|
382c35924c | ||
|
|
88c332729f | ||
|
|
e9a6aa641b | ||
|
|
16bc2ca381 | ||
|
|
2fc1f45161 | ||
|
|
ef7eae50e4 | ||
|
|
2c50efd4c5 | ||
|
|
3ebe44be34 | ||
|
|
e7b322c303 | ||
|
|
08491bdf2a | ||
|
|
f1fa3c07fd | ||
|
|
b19b4ae26e | ||
|
|
7f8215199d | ||
|
|
dd060c4442 | ||
|
|
e782339dcc | ||
|
|
766ed3ab51 | ||
|
|
cd0e3f7001 | ||
|
|
29d5ecb13f | ||
|
|
2987f600bb | ||
|
|
5c23aeca48 | ||
|
|
6ef8ba3639 | ||
|
|
4f7ad4ccb9 | ||
|
|
e03b0dc1bb | ||
|
|
b75153b848 | ||
|
|
d70d33c5e3 | ||
|
|
7eb6748682 | ||
|
|
c92c750e55 | ||
|
|
225c6281b9 | ||
|
|
249e9f372e | ||
|
|
4dfab9a287 | ||
|
|
ec43749ba4 | ||
|
|
2e4202ccce | ||
|
|
4c16dd07b5 | ||
|
|
0c4ad1c4df | ||
|
|
eb90fb343d | ||
|
|
2967a0f968 | ||
|
|
7b2a8b17b7 | ||
|
|
89ca614d3d | ||
|
|
355df1341e | ||
|
|
78c17cd729 | ||
|
|
504c21204f | ||
|
|
8dba5a335b | ||
|
|
3d6d578663 | ||
|
|
a5e9d7ba55 | ||
|
|
5eb65fd723 | ||
|
|
e0dcde5c35 | ||
|
|
c6cfecdbbb | ||
|
|
30bdac93ee | ||
|
|
1228431bc2 | ||
|
|
5a2070de3f | ||
|
|
bc1645065c | ||
|
|
21f9795bcd | ||
|
|
a69bc94945 | ||
|
|
864c8ddf77 | ||
|
|
5764149306 | ||
|
|
9abd911a95 | ||
|
|
968f85b04e | ||
|
|
6e09ef35ab | ||
|
|
a36bce4d5e | ||
|
|
5374e58197 | ||
|
|
cbfa7d869b | ||
|
|
434fb1be59 | ||
|
|
dbec078dae | ||
|
|
e9a8e42525 | ||
|
|
8ad7b429a2 | ||
|
|
a1c27d64ad | ||
|
|
4814d0f769 | ||
|
|
b7d7196071 | ||
|
|
d8225a80b6 | ||
|
|
1b0d9ae904 | ||
|
|
7228733aad | ||
|
|
809639c3f9 | ||
|
|
24e59e1474 | ||
|
|
42c483f581 | ||
|
|
7ba0ecdf5c | ||
|
|
ece36b4042 | ||
|
|
ca5b35b39c | ||
|
|
8f804766e5 | ||
|
|
00207d1570 | ||
|
|
65747b6ad2 | ||
|
|
f7174e2492 | ||
|
|
5d7cdab933 | ||
|
|
c9fee785f9 | ||
|
|
dfc90e58dc | ||
|
|
2a5810b671 | ||
|
|
9d354fb0ed | ||
|
|
52494ca13e | ||
|
|
55cbd094be | ||
|
|
da5fd7e743 | ||
|
|
f6059e249f | ||
|
|
8545622c79 | ||
|
|
cf14706961 | ||
|
|
2f172c998a | ||
|
|
7945bce854 | ||
|
|
6d66c5adee | ||
|
|
8ccbed6d81 | ||
|
|
c3c58e3201 | ||
|
|
f547eb3a09 | ||
|
|
44cacc839b | ||
|
|
6dbe1b6f31 | ||
|
|
e15ed3c77f | ||
|
|
435879e19b | ||
|
|
17ccaecf5e | ||
|
|
dfebd47ef4 | ||
|
|
684b8db546 | ||
|
|
3c714f724d | ||
|
|
03e0dc5208 | ||
|
|
14991bce95 | ||
|
|
50b2c7d3af | ||
|
|
030d69c190 | ||
|
|
08fe408dc1 | ||
|
|
bdb007f6ed | ||
|
|
91abe4c09a | ||
|
|
82029894e4 | ||
|
|
3c1ed6e58a | ||
|
|
8999097100 | ||
|
|
72197e547f | ||
|
|
9b62849d9d | ||
|
|
d311b6fef9 | ||
|
|
4a642b1e36 | ||
|
|
de4f003c67 | ||
|
|
708ee1a8ff | ||
|
|
7196d0aba8 | ||
|
|
3b0a5285ab | ||
|
|
ae03b8cd7e | ||
|
|
cc159e306e | ||
|
|
0a43f43f66 | ||
|
|
0f924360c1 | ||
|
|
0a34f48e0a | ||
|
|
870f2f8fa6 | ||
|
|
aa61479adc | ||
|
|
522c107ce6 | ||
|
|
cb29775004 | ||
|
|
fccbb55344 | ||
|
|
b2402402d9 | ||
|
|
f0a3b27e3b | ||
|
|
57ebd2b608 | ||
|
|
695ff5487f | ||
|
|
66cd39c013 | ||
|
|
fc91ba7c1e | ||
|
|
1cad1976ee | ||
|
|
91eec8c258 | ||
|
|
d2c308c009 | ||
|
|
a4a99f4a9b | ||
|
|
eb114b4a95 | ||
|
|
93e8d50e55 | ||
|
|
3c6fc978d4 | ||
|
|
01ddf1721c | ||
|
|
1ee87c0499 | ||
|
|
f8ae6264f7 | ||
|
|
3e56859943 | ||
|
|
945db8a233 | ||
|
|
823f7447c3 | ||
|
|
6e4fa48b9d | ||
|
|
7e8f216afb | ||
|
|
b09c151738 | ||
|
|
56cf54a644 | ||
|
|
169e897748 | ||
|
|
748b1ca147 | ||
|
|
2e636082bb | ||
|
|
9204ad2701 | ||
|
|
8feb7a142c | ||
|
|
d990930b19 | ||
|
|
4d67279827 | ||
|
|
a78b29b0a1 | ||
|
|
2c36c0f2cb | ||
|
|
2eaf21b1e0 | ||
|
|
099e387570 | ||
|
|
c4755f23cd | ||
|
|
9c4650b4af | ||
|
|
43d7fab04d | ||
|
|
d2b7e71c4a | ||
|
|
ab6d44e604 | ||
|
|
0dc2e9d134 | ||
|
|
3a024b8d4c | ||
|
|
05e2422cb4 | ||
|
|
fc5d4f946d | ||
|
|
45c1e25e4f | ||
|
|
f11bdcfd53 | ||
|
|
9888fbf047 | ||
|
|
9171610e34 | ||
|
|
7a8c1f3165 | ||
|
|
008a052045 | ||
|
|
93a5f2e3b2 | ||
|
|
0e4edca08a | ||
|
|
f9925f9ec9 | ||
|
|
f283f82bbc | ||
|
|
ab5dd5f756 | ||
|
|
e22c71853f | ||
|
|
8bf27ecbd9 | ||
|
|
d94d003050 | ||
|
|
25c4d94366 | ||
|
|
91dda3213e | ||
|
|
b41dd23c7f | ||
|
|
14ad0eee48 | ||
|
|
56e106ff32 | ||
|
|
b67424c1e1 | ||
|
|
c366ee9d12 | ||
|
|
5ec97f2e31 | ||
|
|
98c20464d7 | ||
|
|
b1aa9c3306 | ||
|
|
db6ab3ee98 | ||
|
|
2ccf4be559 | ||
|
|
ce86255119 | ||
|
|
d69e81972e | ||
|
|
3f9d306a34 | ||
|
|
14c3914e5c | ||
|
|
b5337572c4 | ||
|
|
1d1b4f0790 | ||
|
|
ccdd8005d0 | ||
|
|
1d184f0f5e | ||
|
|
2ed9e632c6 | ||
|
|
ecba28c9cd | ||
|
|
06e8cac597 | ||
|
|
1dfdd4dd28 | ||
|
|
48585469f6 | ||
|
|
f9ba562b0b | ||
|
|
5c63a49071 | ||
|
|
3d224496a8 | ||
|
|
73addfefe7 | ||
|
|
af0e2180bd | ||
|
|
a431015853 | ||
|
|
788244fbf4 | ||
|
|
282230b28e | ||
|
|
dc010ce28c | ||
|
|
5a3597f2a7 | ||
|
|
5b889ea59c | ||
|
|
faa6e20034 | ||
|
|
82a97f8c1f | ||
|
|
6557d21aa8 | ||
|
|
a733ed69cb | ||
|
|
9877ba93a0 | ||
|
|
669f9e71bc | ||
|
|
5d2f20efd5 | ||
|
|
06dccdd97f | ||
|
|
e705f67333 | ||
|
|
4903b99eb5 | ||
|
|
38ab6626fc | ||
|
|
b44bc8fae3 | ||
|
|
7d72d54862 | ||
|
|
0a218cebb4 | ||
|
|
ed6ad6ae76 | ||
|
|
1689b15d95 | ||
|
|
010fdde45c | ||
|
|
10509991c1 | ||
|
|
c686ee394d | ||
|
|
985902092e | ||
|
|
944b72e2a8 | ||
|
|
d074be323c | ||
|
|
0098401584 | ||
|
|
0d7d5fe380 | ||
|
|
1cb9fb6058 | ||
|
|
5076ba405e | ||
|
|
3c60dfdf7b | ||
|
|
5d44b5f3ef | ||
|
|
40cdd4c1e7 | ||
|
|
f5753109d5 | ||
|
|
51e338749a | ||
|
|
e37fb33afe | ||
|
|
47af06578a | ||
|
|
ad0cbba0b1 | ||
|
|
c7a3282dd9 | ||
|
|
fd593baa07 | ||
|
|
88f1230620 | ||
|
|
cad558980f | ||
|
|
e879aba801 | ||
|
|
114fdb9545 | ||
|
|
1886ddfbaf | ||
|
|
39d2c3aab6 | ||
|
|
3cd8a1f310 | ||
|
|
b457886ee3 | ||
|
|
e27c041256 | ||
|
|
5fcafe0b38 | ||
|
|
8250246f34 | ||
|
|
d9bcaa0b1d | ||
|
|
dd6e26ae4b | ||
|
|
fac1dd3d61 | ||
|
|
e573749aa0 | ||
|
|
f22bf60eb6 | ||
|
|
d1b99fdda3 | ||
|
|
e1a4cfca4e | ||
|
|
8a43824f3d | ||
|
|
b948fc7264 | ||
|
|
d9f891dfb1 | ||
|
|
a9524bcc33 | ||
|
|
4b537cb79d | ||
|
|
1484c26434 | ||
|
|
36e8dc9fa5 | ||
|
|
8feb7037aa | ||
|
|
d8863142c7 | ||
|
|
061109c901 | ||
|
|
f95b50c99d | ||
|
|
def5cc273c | ||
|
|
e01d2c9569 | ||
|
|
415dbbb195 | ||
|
|
765d90214d | ||
|
|
36fd1dcda9 | ||
|
|
812b9b731b | ||
|
|
e80a68485d | ||
|
|
535f4ccb8e | ||
|
|
7bbdf43452 | ||
|
|
59881d6b3b | ||
|
|
085e198409 | ||
|
|
81f27fcbde | ||
|
|
50dae0ef69 | ||
|
|
e0fdefa28e | ||
|
|
f6a826505c | ||
|
|
68ac506a25 | ||
|
|
1150d9e497 | ||
|
|
633a946f26 | ||
|
|
8e01455140 | ||
|
|
b373ab8708 | ||
|
|
cb752850ff | ||
|
|
08c929699f | ||
|
|
1862090a89 | ||
|
|
1ea80c3fab | ||
|
|
1676f5a956 | ||
|
|
cdc9cdbe95 | ||
|
|
28e8a1fb11 | ||
|
|
5f1b92ca62 | ||
|
|
c58a1874ca | ||
|
|
f4fb9cd173 | ||
|
|
ad4a6e9383 | ||
|
|
decdaf9f1f | ||
|
|
27382a6be1 | ||
|
|
34440af1c5 | ||
|
|
c0e3da9214 | ||
|
|
d50ad7345d | ||
|
|
95016c3ec6 | ||
|
|
f8f5c2474c | ||
|
|
b997e9a135 | ||
|
|
c7ccac2fe6 | ||
|
|
05885f568e | ||
|
|
b500b9f6cc | ||
|
|
e784c08f80 | ||
|
|
45ea5cc875 | ||
|
|
a006698bb2 | ||
|
|
e365944dc3 | ||
|
|
c33dcb78d0 | ||
|
|
e48ec3af7c | ||
|
|
4b9d7d1a1f | ||
|
|
d6133905b2 | ||
|
|
741b401d8c | ||
|
|
cb661313c2 | ||
|
|
3c794849bd | ||
|
|
753b4e69ee | ||
|
|
b502007fff | ||
|
|
1e6d65fe53 | ||
|
|
72515a79ca | ||
|
|
b286008403 | ||
|
|
c8e3f752db | ||
|
|
33c3822b7c | ||
|
|
97701ef3c4 | ||
|
|
d2eadcd2f5 | ||
|
|
6589f8c4f4 | ||
|
|
13dabc09c7 | ||
|
|
eb80f38813 | ||
|
|
0fc6a73b30 | ||
|
|
aa38b13adf | ||
|
|
6a79f41367 | ||
|
|
88263ccc77 | ||
|
|
9d15704b78 | ||
|
|
832060e8ad | ||
|
|
5d5652907b | ||
|
|
477d7957e3 | ||
|
|
41b39a5d3b | ||
|
|
6972b544ec | ||
|
|
1bd9eca806 | ||
|
|
a203eef9a6 | ||
|
|
f583b84951 | ||
|
|
8f319a4405 | ||
|
|
862a5ebd12 | ||
|
|
cb89bd3908 | ||
|
|
54dd424b01 | ||
|
|
b6b88086f3 | ||
|
|
b2ec99e663 | ||
|
|
74c101628b | ||
|
|
ea28b8afa4 | ||
|
|
f5d7c90be1 | ||
|
|
62b6c5193a | ||
|
|
6d9ea8a13c | ||
|
|
9abac555c3 | ||
|
|
f742f850eb | ||
|
|
83ca24b32a | ||
|
|
484e7c2102 | ||
|
|
f416e12dac | ||
|
|
1a140ab5c8 | ||
|
|
006c5f8655 | ||
|
|
b0e2985f5e | ||
|
|
cbb57411a0 | ||
|
|
28c1172db3 | ||
|
|
e708946f4c | ||
|
|
b9fff95215 | ||
|
|
7cd3a143a0 | ||
|
|
7248e90762 | ||
|
|
ceef883ad8 | ||
|
|
8a98924ad7 | ||
|
|
9526b9b6fe | ||
|
|
741f694733 | ||
|
|
8f2ef9082b | ||
|
|
e7dcc088d6 | ||
|
|
f036c3f1cc | ||
|
|
d3c64be229 | ||
|
|
5404309193 | ||
|
|
635b4d2432 | ||
|
|
3fc9ff3abf | ||
|
|
41833c8aad | ||
|
|
fdf9778f46 | ||
|
|
1e676f5a6b | ||
|
|
0af944176a | ||
|
|
6fe13b6a92 | ||
|
|
4f562e0d8e | ||
|
|
fdae50a972 | ||
|
|
277886b092 | ||
|
|
75c407ca01 | ||
|
|
2b40c5a55c | ||
|
|
cffe55428a | ||
|
|
f51708e01d | ||
|
|
3e6b98894d | ||
|
|
25faa7e702 | ||
|
|
c6dab1fe9a | ||
|
|
c9178aef76 | ||
|
|
aa8b349711 | ||
|
|
6194948259 | ||
|
|
ff6e898091 | ||
|
|
c43503eb27 | ||
|
|
2373d0ace7 | ||
|
|
f10ac6da06 | ||
|
|
e90b9fe5e3 | ||
|
|
da73365c2f | ||
|
|
3f9253a550 | ||
|
|
0ed316eaa4 | ||
|
|
5f80e12faf | ||
|
|
64d92fdfce | ||
|
|
6c400c80a2 | ||
|
|
9846d87a40 | ||
|
|
e952f3d775 | ||
|
|
726f2083db | ||
|
|
436db82006 | ||
|
|
5938869e7a | ||
|
|
4bad8585e5 | ||
|
|
468aff6e3f | ||
|
|
a30062db71 | ||
|
|
d0a2ccd7d6 | ||
|
|
84099b1d0b | ||
|
|
1b7dd2dd2a | ||
|
|
e5d4ba48fb |
27
.github/ISSUE_TEMPLATE/rfi_request.md
vendored
Normal file
27
.github/ISSUE_TEMPLATE/rfi_request.md
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
name: Request for Information
|
||||
about: Request specific information about capabilities of the framework
|
||||
title: "[RFI]-"
|
||||
labels: RFI
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**What is your request?**
|
||||
Please provide as much detail as possible.
|
||||
|
||||
|
||||
**What is the intended use case**
|
||||
- [ ] Essentials Standalone Application
|
||||
- [ ] Essentials + SIMPL Windows Hybrid
|
||||
|
||||
**User Interface Requirements**
|
||||
- [ ] Not Applicable (logic only)
|
||||
- [ ] Crestron Smart Graphics Touchpanel
|
||||
- [ ] Cisco Touch10
|
||||
- [ ] Mobile Control
|
||||
- [ ] Crestron CH5 Touchpanel interface
|
||||
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the request here.
|
||||
172
.github/workflows/docker.yml
vendored
172
.github/workflows/docker.yml
vendored
@@ -32,7 +32,6 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
# Fetch all tags
|
||||
- name: Fetch tags
|
||||
run: git fetch --tags
|
||||
@@ -41,12 +40,11 @@ jobs:
|
||||
shell: powershell
|
||||
run: |
|
||||
$version = ./.github/scripts/GenerateVersionNumber.ps1
|
||||
Write-Output "::set-env name=VERSION::$version"
|
||||
echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||
# Use the version number to set the version of the assemblies
|
||||
- name: Update AssemblyInfo.cs
|
||||
shell: powershell
|
||||
run: |
|
||||
Write-Output ${{ env.VERSION }}
|
||||
./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }}
|
||||
- name: restore Nuget Packages
|
||||
run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion
|
||||
@@ -60,7 +58,7 @@ jobs:
|
||||
- name: Build Solution
|
||||
shell: powershell
|
||||
run: |
|
||||
Invoke-Expression "docker run --rm --mount type=bind,source=""$($Env:GITHUB_WORKSPACE)"",target=""c:/project"" pepperdash/sspbuilder:v1.4.1 c:\cihelpers\vsidebuild.exe -Solution ""c:\project\$($Env:SOLUTION_FILE).sln"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)"
|
||||
Invoke-Expression "docker run --rm --mount type=bind,source=""$($Env:GITHUB_WORKSPACE)"",target=""c:/project"" pepperdash/sspbuilder c:\cihelpers\vsidebuild.exe -Solution ""c:\project\$($Env:SOLUTION_FILE).sln"" -BuildSolutionConfiguration $($ENV:BUILD_TYPE)"
|
||||
# Zip up the output files as needed
|
||||
- name: Zip Build Output
|
||||
shell: powershell
|
||||
@@ -80,16 +78,9 @@ jobs:
|
||||
with:
|
||||
name: Version
|
||||
path: ${{env.GITHUB_HOME}}\output\version.txt
|
||||
# Create the release on the source repo
|
||||
- name: Create tag for non-rc builds
|
||||
if: contains(env.VERSION, 'alpha') || contains(env.VERSION, 'beta')
|
||||
run: |
|
||||
git tag $($Env:VERSION)
|
||||
git push --tags origin
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
# using contributor's version to allow for pointing at the right commit
|
||||
if: contains(env.VERSION,'-rc-') || contains(env.VERSION,'-hotfix-')
|
||||
uses: fleskesvor/create-release@feature/support-target-commitish
|
||||
with:
|
||||
tag_name: ${{ env.VERSION }}
|
||||
@@ -123,7 +114,7 @@ jobs:
|
||||
Get-ChildItem "./Version"
|
||||
$version = Get-Content -Path ./Version/version.txt
|
||||
Write-Host "Version: $version"
|
||||
Write-Output "::set-env name=VERSION::$version"
|
||||
echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||
Remove-Item -Path ./Version/version.txt
|
||||
Remove-Item -Path ./Version
|
||||
- name: Download Build output
|
||||
@@ -152,160 +143,3 @@ jobs:
|
||||
run: nuget push **/*.nupkg -source github
|
||||
- name: Publish nuget package to nuget.org
|
||||
run: nuget push **/*.nupkg -Source https://api.nuget.org/v3/index.json
|
||||
# This step always runs and pushes the build to the internal build rep
|
||||
Internal_Push_Output:
|
||||
needs: Build_Project
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: check Github ref
|
||||
run: ${{toJson(github.ref)}}
|
||||
# Checkout the repo
|
||||
- name: Checkout Builds Repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.BUILDS_TOKEN }}
|
||||
repository: PepperDash-Engineering/essentials-builds
|
||||
ref: ${{ Env.GITHUB_REF }}
|
||||
# Download the version artifact from the build job
|
||||
- name: Download Build Version Info
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: Version
|
||||
- name: Check Directory
|
||||
run: Get-ChildItem "./"
|
||||
# Set the version number environment variable from the file we just downloaded
|
||||
- name: Set Version Number
|
||||
shell: powershell
|
||||
run: |
|
||||
Get-ChildItem "./Version"
|
||||
$version = Get-Content -Path ./Version/version.txt
|
||||
Write-Host "Version: $version"
|
||||
Write-Output "::set-env name=VERSION::$version"
|
||||
Remove-Item -Path ./Version/version.txt
|
||||
Remove-Item -Path ./Version
|
||||
# Checkout/Create the branch
|
||||
- name: Create new branch
|
||||
run: git checkout -b $($Env:GITHUB_REF -replace "refs/heads/")
|
||||
# Download the build output into the repo
|
||||
- name: Download Build output
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: Build
|
||||
path: ./
|
||||
- name: Check directory
|
||||
run: Get-ChildItem ./
|
||||
# Unzip the build package file
|
||||
- name: Unzip Build file
|
||||
run: |
|
||||
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
|
||||
Remove-Item -Path .\*.zip
|
||||
- name: Check directory again
|
||||
run: Get-ChildItem ./
|
||||
# Copy Contents of output folder to root directory
|
||||
- name: Copy Files to root & delete output directory
|
||||
run: |
|
||||
Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
|
||||
Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
|
||||
Remove-Item -Path .\output -Recurse
|
||||
# Commits the build output to the branch and tags it with the version
|
||||
- name: Commit build output and tag the commit
|
||||
shell: powershell
|
||||
run: |
|
||||
git config user.email "actions@pepperdash.com"
|
||||
git config user.name "GitHub Actions"
|
||||
git add .
|
||||
$commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
|
||||
Write-Host "Commit: $commit"
|
||||
git commit -m $commit
|
||||
git tag $($Env:VERSION)
|
||||
# Push the commit
|
||||
- name: Push to Builds Repo
|
||||
shell: powershell
|
||||
run: |
|
||||
$branch = $($Env:GITHUB_REF) -replace "refs/heads/"
|
||||
Write-Host "Branch: $branch"
|
||||
git push -u origin $($branch) --force
|
||||
# Push the tags
|
||||
- name: Push tags
|
||||
run: git push --tags origin
|
||||
- name: Check Directory
|
||||
run: Get-ChildItem ./
|
||||
# This step only runs if the branch is main or release/ runs and pushes the build to the public build repo
|
||||
Public_Push_Output:
|
||||
needs: Build_Project
|
||||
runs-on: windows-latest
|
||||
if: contains(github.ref, 'main') || contains(github.ref, '/release/')
|
||||
steps:
|
||||
# Checkout the repo
|
||||
- name: check Github ref
|
||||
run: ${{toJson(github.ref)}}
|
||||
- name: Checkout Builds Repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.BUILDS_TOKEN }}
|
||||
repository: PepperDash/Essentials-Builds
|
||||
ref: ${{ Env.GITHUB_REF }}
|
||||
# Download the version artifact from the build job
|
||||
- name: Download Build Version Info
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: Version
|
||||
- name: Check Directory
|
||||
run: Get-ChildItem "./"
|
||||
# Set the version number environment variable from the file we just downloaded
|
||||
- name: Set Version Number
|
||||
shell: powershell
|
||||
run: |
|
||||
Get-ChildItem "./Version"
|
||||
$version = Get-Content -Path ./Version/version.txt
|
||||
Write-Host "Version: $version"
|
||||
Write-Output "::set-env name=VERSION::$version"
|
||||
Remove-Item -Path ./Version/version.txt
|
||||
Remove-Item -Path ./Version
|
||||
# Checkout/Create the branch
|
||||
- name: Create new branch
|
||||
run: git checkout -b $($Env:GITHUB_REF -replace "refs/heads/")
|
||||
# Download the build output into the repo
|
||||
- name: Download Build output
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: Build
|
||||
path: ./
|
||||
- name: Check directory
|
||||
run: Get-ChildItem ./
|
||||
# Unzip the build package file
|
||||
- name: Unzip Build file
|
||||
run: |
|
||||
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
|
||||
Remove-Item -Path .\*.zip
|
||||
- name: Check directory again
|
||||
run: Get-ChildItem ./
|
||||
# Copy Contents of output folder to root directory
|
||||
- name: Copy Files to root & delete output directory
|
||||
run: |
|
||||
Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
|
||||
Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
|
||||
Remove-Item -Path .\output -Recurse
|
||||
# Commits the build output to the branch and tags it with the version
|
||||
- name: Commit build output and tag the commit
|
||||
shell: powershell
|
||||
run: |
|
||||
git config user.email "actions@pepperdash.com"
|
||||
git config user.name "GitHub Actions"
|
||||
git add .
|
||||
$commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
|
||||
Write-Host "Commit: $commit"
|
||||
git commit -m $commit
|
||||
git tag $($Env:VERSION)
|
||||
# Push the commit
|
||||
- name: Push to Builds Repo
|
||||
shell: powershell
|
||||
run: |
|
||||
$branch = $($Env:GITHUB_REF) -replace "refs/heads/"
|
||||
Write-Host "Branch: $branch"
|
||||
git push -u origin $($branch) --force
|
||||
# Push the tags
|
||||
- name: Push tags
|
||||
run: git push --tags origin
|
||||
- name: Check Directory
|
||||
run: Get-ChildItem ./
|
||||
|
||||
160
.github/workflows/main.yml
vendored
160
.github/workflows/main.yml
vendored
@@ -24,25 +24,18 @@ jobs:
|
||||
# First we checkout the source repo
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v2
|
||||
# And any submodules
|
||||
- name: Checkout submodules
|
||||
shell: bash
|
||||
run: |
|
||||
git config --global url."https://github.com/".insteadOf "git@github.com:"
|
||||
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
|
||||
git submodule sync --recursive
|
||||
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
# Generate the appropriate version number
|
||||
- name: Set Version Number
|
||||
shell: powershell
|
||||
env:
|
||||
TAG_NAME: ${{ github.event.release.tag_name }}
|
||||
run: Write-Output "::set-env name=VERSION::$($Env:TAG_NAME)"
|
||||
run: echo "VERSION=$($Env:TAG_NAME)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||
# Use the version number to set the version of the assemblies
|
||||
- name: Update AssemblyInfo.cs
|
||||
shell: powershell
|
||||
run: |
|
||||
Write-Output ${{ env.VERSION }}
|
||||
./.github/scripts/UpdateAssemblyVersion.ps1 ${{ env.VERSION }}
|
||||
- name: restore Nuget Packages
|
||||
run: nuget install .\packages.config -OutputDirectory .\packages -ExcludeVersion
|
||||
@@ -101,7 +94,7 @@ jobs:
|
||||
Get-ChildItem "./Version"
|
||||
$version = Get-Content -Path ./Version/version.txt
|
||||
Write-Host "Version: $version"
|
||||
Write-Output "::set-env name=VERSION::$version"
|
||||
echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||
Remove-Item -Path ./Version/version.txt
|
||||
Remove-Item -Path ./Version
|
||||
- name: Download Build output
|
||||
@@ -130,148 +123,3 @@ jobs:
|
||||
run: nuget push **/*.nupkg -source github
|
||||
- name: Publish nuget package to nuget.org
|
||||
run: nuget push **/*.nupkg -Source https://api.nuget.org/v3/index.json
|
||||
Internal_Push_Output:
|
||||
needs: Build_Project
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
# Checkout the repo
|
||||
- name: Checkout Builds Repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.BUILDS_TOKEN }}
|
||||
repository: PepperDash-Engineering/essentials-builds
|
||||
ref: ${{ Env.GITHUB_REF }}
|
||||
# Download the version artifact from the build job
|
||||
- name: Download Build Version Info
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: Version
|
||||
- name: Check Directory
|
||||
run: Get-ChildItem "./"
|
||||
# Set the version number environment variable from the file we just downloaded
|
||||
- name: Set Version Number
|
||||
shell: powershell
|
||||
run: |
|
||||
Get-ChildItem "./Version"
|
||||
$version = Get-Content -Path ./Version/version.txt
|
||||
Write-Host "Version: $version"
|
||||
Write-Output "::set-env name=VERSION::$version"
|
||||
Remove-Item -Path ./Version/version.txt
|
||||
Remove-Item -Path ./Version
|
||||
# Checkout/Create the branch
|
||||
- name: Checkout main branch
|
||||
run: git checkout main
|
||||
# Download the build output into the repo
|
||||
- name: Download Build output
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: Build
|
||||
path: ./
|
||||
- name: Check directory
|
||||
run: Get-ChildItem ./
|
||||
# Unzip the build package file
|
||||
- name: Unzip Build file
|
||||
run: |
|
||||
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
|
||||
Remove-Item -Path .\*.zip
|
||||
- name: Check directory again
|
||||
run: Get-ChildItem ./
|
||||
# Copy Contents of output folder to root directory
|
||||
- name: Copy Files to root & delete output directory
|
||||
run: |
|
||||
Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
|
||||
Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
|
||||
Remove-Item -Path .\output -Recurse
|
||||
# Commits the build output to the branch and tags it with the version
|
||||
- name: Commit build output and tag the commit
|
||||
shell: powershell
|
||||
run: |
|
||||
git config user.email "actions@pepperdash.com"
|
||||
git config user.name "GitHub Actions"
|
||||
git add .
|
||||
$commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
|
||||
Write-Host "Commit: $commit"
|
||||
git commit -m $commit
|
||||
git tag $($Env:VERSION)
|
||||
# Push the commit
|
||||
- name: Push to Builds Repo
|
||||
shell: powershell
|
||||
run: git push -u origin main --force
|
||||
# Push the tags
|
||||
- name: Push tags
|
||||
run: git push --tags origin
|
||||
- name: Check Directory
|
||||
run: Get-ChildItem ./
|
||||
# This step only runs if the branch is main or release/ runs and pushes the build to the public build repo
|
||||
Public_Push_Output:
|
||||
needs: Build_Project
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
# Checkout the repo
|
||||
- name: Checkout Builds Repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.BUILDS_TOKEN }}
|
||||
repository: PepperDash/Essentials-Builds
|
||||
ref: ${{ Env.GITHUB_REF }}
|
||||
# Download the version artifact from the build job
|
||||
- name: Download Build Version Info
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: Version
|
||||
- name: Check Directory
|
||||
run: Get-ChildItem "./"
|
||||
# Set the version number environment variable from the file we just downloaded
|
||||
- name: Set Version Number
|
||||
shell: powershell
|
||||
run: |
|
||||
Get-ChildItem "./Version"
|
||||
$version = Get-Content -Path ./Version/version.txt
|
||||
Write-Host "Version: $version"
|
||||
Write-Output "::set-env name=VERSION::$version"
|
||||
Remove-Item -Path ./Version/version.txt
|
||||
Remove-Item -Path ./Version
|
||||
# Checkout main branch
|
||||
- name: Create new branch
|
||||
run: git checkout main
|
||||
# Download the build output into the repo
|
||||
- name: Download Build output
|
||||
uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: Build
|
||||
path: ./
|
||||
- name: Check directory
|
||||
run: Get-ChildItem ./
|
||||
# Unzip the build package file
|
||||
- name: Unzip Build file
|
||||
run: |
|
||||
Get-ChildItem .\*.zip | Expand-Archive -DestinationPath .\
|
||||
Remove-Item -Path .\*.zip
|
||||
- name: Check directory again
|
||||
run: Get-ChildItem ./
|
||||
# Copy Contents of output folder to root directory
|
||||
- name: Copy Files to root & delete output directory
|
||||
run: |
|
||||
Remove-Item -Path .\* -Include @("*.cpz","*.md","*.cplz","*.json","*.dll","*.clz")
|
||||
Get-ChildItem -Path .\output\* | Copy-Item -Destination .\
|
||||
Remove-Item -Path .\output -Recurse
|
||||
# Commits the build output to the branch and tags it with the version
|
||||
- name: Commit build output and tag the commit
|
||||
shell: powershell
|
||||
run: |
|
||||
git config user.email "actions@pepperdash.com"
|
||||
git config user.name "GitHub Actions"
|
||||
git add .
|
||||
$commit = "Build $($Env:GITHUB_RUN_NUMBER) from commit: https://github.com/$($Env:GITHUB_REPOSITORY)/commit/$($Env:GITHUB_SHA)"
|
||||
Write-Host "Commit: $commit"
|
||||
git commit -m $commit
|
||||
git tag $($Env:VERSION)
|
||||
# Push the commit
|
||||
- name: Push to Builds Repo
|
||||
shell: powershell
|
||||
run: git push -u origin main --force
|
||||
# Push the tags
|
||||
- name: Push tags
|
||||
run: git push --tags origin
|
||||
- name: Check Directory
|
||||
run: Get-ChildItem ./
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -388,3 +388,4 @@ MigrationBackup/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
essentials-framework/Essentials Interfaces/PepperDash_Essentials_Interfaces/PepperDash_Essentials_Interfaces.csproj
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,6 +1,3 @@
|
||||
[submodule "essentials-framework/pepperdashcore-builds"]
|
||||
path = essentials-framework/pepperdashcore-builds
|
||||
url = https://github.com/ndorin/PepperDashCore-Builds.git
|
||||
[submodule "Essentials-Template-UI"]
|
||||
path = Essentials-Template-UI
|
||||
url = https://github.com/PepperDash/Essentials-Template-UI.git
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -70,6 +70,14 @@ namespace PepperDash.Essentials.Bridges
|
||||
/// Range reports the highest supported HDCP state level for the corresponding input card
|
||||
/// </summary>
|
||||
public uint HdcpSupportCapability { get; set; }
|
||||
/// <summary>
|
||||
/// DM Chassis Stream Input Start (1), Stop (2), Pause (3) with Feedback
|
||||
/// </summary>
|
||||
public uint InputStreamCardStatus { get; set; }
|
||||
/// <summary>
|
||||
/// DM Chassis Stream Output Start (1), Stop (2), Pause (3) with Feedback
|
||||
/// </summary>
|
||||
public uint OutputStreamCardStatus { get; set; }
|
||||
#endregion
|
||||
|
||||
#region Serials
|
||||
@@ -115,6 +123,8 @@ namespace PepperDash.Essentials.Bridges
|
||||
InputUsb = 700; //701-899
|
||||
HdcpSupportState = 1000; //1001-1199
|
||||
HdcpSupportCapability = 1200; //1201-1399
|
||||
InputStreamCardStatus = 1500; //1501-1532
|
||||
OutputStreamCardStatus = 1600; //1601-1632
|
||||
|
||||
|
||||
//Serial
|
||||
@@ -145,6 +155,8 @@ namespace PepperDash.Essentials.Bridges
|
||||
OutputEndpointOnline = OutputEndpointOnline + joinOffset;
|
||||
HdcpSupportState = HdcpSupportState + joinOffset;
|
||||
HdcpSupportCapability = HdcpSupportCapability + joinOffset;
|
||||
InputStreamCardStatus = InputStreamCardStatus + joinOffset;
|
||||
OutputStreamCardStatus = OutputStreamCardStatus + joinOffset;
|
||||
OutputDisabledByHdcp = OutputDisabledByHdcp + joinOffset;
|
||||
TxAdvancedIsPresent = TxAdvancedIsPresent + joinOffset;
|
||||
}
|
||||
|
||||
@@ -12,11 +12,11 @@ using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Fusion;
|
||||
using PepperDash.Essentials.Devices.Common;
|
||||
using PepperDash.Essentials.DM;
|
||||
using PepperDash.Essentials.Fusion;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
//using PepperDash.Essentials.Room.MobileControl;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
@@ -36,6 +36,7 @@ namespace PepperDash.Essentials
|
||||
Thread.MaxNumberOfUserThreads = 400;
|
||||
Global.ControlSystem = this;
|
||||
DeviceManager.Initialize(this);
|
||||
SecretsManager.Initialize();
|
||||
SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true;
|
||||
}
|
||||
|
||||
@@ -53,7 +54,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
if (Debug.DoNotLoadOnNextBoot)
|
||||
{
|
||||
CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Loads configuration file",
|
||||
CrestronConsole.AddNewConsoleCommand(s => CrestronInvoke.BeginInvoke((o) => GoWithLoad()), "go", "Loads configuration file",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
}
|
||||
|
||||
@@ -71,7 +72,7 @@ namespace PepperDash.Essentials
|
||||
CrestronConsole.AddNewConsoleCommand(s =>
|
||||
{
|
||||
foreach (var tl in TieLineCollection.Default)
|
||||
CrestronConsole.ConsoleCommandResponse(" {0}\r", tl);
|
||||
CrestronConsole.ConsoleCommandResponse(" {0}\r\n", tl);
|
||||
},
|
||||
"listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
@@ -85,8 +86,8 @@ namespace PepperDash.Essentials
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(s =>
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r" +
|
||||
"System URL: {0}\r" +
|
||||
CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r\n" +
|
||||
"System URL: {0}\r\n" +
|
||||
"Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl);
|
||||
}, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
@@ -130,7 +131,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) // Handles 3-series running Windows CE OS
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on 3-series Appliance", Global.AssemblyVersion);
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on {1} Appliance", Global.AssemblyVersion, Global.ProcessorSeries.ToString());
|
||||
|
||||
// Check if User/ProgramX exists
|
||||
if (Directory.Exists(Global.ApplicationDirectoryPathPrefix + dirSeparator + "User"
|
||||
@@ -290,33 +291,14 @@ namespace PepperDash.Essentials
|
||||
|
||||
DeviceManager.ActivateAll();
|
||||
|
||||
var mobileControl = DeviceManager.GetDeviceForKey("appServer") as IMobileControl;
|
||||
var mobileControl = GetMobileControlDevice();
|
||||
|
||||
if (mobileControl == null) return;
|
||||
|
||||
mobileControl.LinkSystemMonitorToAppServer();
|
||||
//LinkSystemMonitorToAppServer();
|
||||
|
||||
}
|
||||
|
||||
//void LinkSystemMonitorToAppServer()
|
||||
//{
|
||||
// var sysMon = DeviceManager.GetDeviceForKey("systemMonitor") as PepperDash.Essentials.Core.Monitoring.SystemMonitorController;
|
||||
|
||||
// var appServer = DeviceManager.GetDeviceForKey("appServer") as MobileControlSystemController;
|
||||
|
||||
|
||||
// if (sysMon != null && appServer != null)
|
||||
// {
|
||||
// var key = sysMon.Key + "-" + appServer.Key;
|
||||
// var messenger = new PepperDash.Essentials.AppServer.Messengers.SystemMonitorMessenger
|
||||
// (key, sysMon, "/device/systemMonitor");
|
||||
|
||||
// messenger.RegisterWithAppServer(appServer);
|
||||
|
||||
// DeviceManager.AddDevice(messenger);
|
||||
// }
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Reads all devices from config and adds them to DeviceManager
|
||||
/// </summary>
|
||||
@@ -327,7 +309,11 @@ namespace PepperDash.Essentials
|
||||
DeviceManager.AddDevice(new PepperDash.Essentials.Core.Devices.CrestronProcessor("processor"));
|
||||
|
||||
// Add global System Monitor device
|
||||
DeviceManager.AddDevice(new PepperDash.Essentials.Core.Monitoring.SystemMonitorController("systemMonitor"));
|
||||
if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance)
|
||||
{
|
||||
DeviceManager.AddDevice(
|
||||
new PepperDash.Essentials.Core.Monitoring.SystemMonitorController("systemMonitor"));
|
||||
}
|
||||
|
||||
foreach (var devConf in ConfigReader.ConfigObject.Devices)
|
||||
{
|
||||
@@ -338,7 +324,12 @@ namespace PepperDash.Essentials
|
||||
// Skip this to prevent unnecessary warnings
|
||||
if (devConf.Key == "processor")
|
||||
{
|
||||
if (devConf.Type.ToLower() != Global.ControlSystem.ControllerPrompt.ToLower())
|
||||
var prompt = Global.ControlSystem.ControllerPrompt;
|
||||
|
||||
var typeMatch = String.Equals(devConf.Type, prompt, StringComparison.OrdinalIgnoreCase) &&
|
||||
String.Equals(devConf.Type, prompt.Replace("-", ""), StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (!typeMatch)
|
||||
Debug.Console(0,
|
||||
"WARNING: Config file defines processor type as '{0}' but actual processor is '{1}'! Some ports may not be available",
|
||||
devConf.Type.ToUpper(), Global.ControlSystem.ControllerPrompt.ToUpper());
|
||||
@@ -390,19 +381,14 @@ namespace PepperDash.Essentials
|
||||
if (newDev == null)
|
||||
newDev = PepperDash.Essentials.Core.DeviceFactory.GetDevice(devConf);
|
||||
|
||||
//
|
||||
//if (newDev == null)
|
||||
// newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf);
|
||||
//
|
||||
|
||||
if (newDev != null)
|
||||
DeviceManager.AddDevice(newDev);
|
||||
else
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key);
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "ERROR: Creating device {0}. Skipping device. \r{1}", devConf.Key, e);
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "ERROR: Creating device {0}. Skipping device. \r{1}", devConf.Key, e);
|
||||
}
|
||||
}
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Devices Loaded.");
|
||||
@@ -452,19 +438,34 @@ namespace PepperDash.Essentials
|
||||
var room = EssentialsRoomConfigHelper.GetRoomObject(roomConfig) as EssentialsRoomBase;
|
||||
if (room != null)
|
||||
{
|
||||
// default IPID
|
||||
uint fusionIpId = 0xf1;
|
||||
|
||||
// default to no join map key
|
||||
string fusionJoinMapKey = string.Empty;
|
||||
|
||||
if (room.Config.Properties["fusion"] != null)
|
||||
{
|
||||
Debug.Console(2, "Custom Fusion config found. Using custom values");
|
||||
|
||||
var fusionConfig = room.Config.Properties["fusion"].ToObject<EssentialsRoomFusionConfig>();
|
||||
|
||||
if (fusionConfig != null)
|
||||
{
|
||||
fusionIpId = fusionConfig.IpIdInt;
|
||||
fusionJoinMapKey = fusionConfig.JoinMapKey;
|
||||
}
|
||||
}
|
||||
|
||||
if (room is EssentialsHuddleSpaceRoom)
|
||||
{
|
||||
DeviceManager.AddDevice(room);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion");
|
||||
DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase((EssentialsHuddleSpaceRoom)room, 0xf1));
|
||||
DeviceManager.AddDevice(new Core.Fusion.EssentialsHuddleSpaceFusionSystemControllerBase(room, fusionIpId, fusionJoinMapKey));
|
||||
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
|
||||
// Mobile Control bridge
|
||||
//var bridge = new MobileConrolEssentialsHuddleSpaceRoomBridge(room as EssentialsHuddleSpaceRoom);
|
||||
//AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present
|
||||
//DeviceManager.AddDevice(bridge);
|
||||
|
||||
CreateMobileControlBridge(room);
|
||||
}
|
||||
@@ -473,13 +474,21 @@ namespace PepperDash.Essentials
|
||||
DeviceManager.AddDevice(room);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion");
|
||||
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, 0xf1));
|
||||
DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, fusionIpId, fusionJoinMapKey));
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge...");
|
||||
// Mobile Control bridge
|
||||
//var bridge = new MobileConrolEssentialsHuddleSpaceRoomBridge(room);
|
||||
//AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present
|
||||
//DeviceManager.AddDevice(bridge);
|
||||
|
||||
CreateMobileControlBridge(room);
|
||||
}
|
||||
else if (room is EssentialsTechRoom)
|
||||
{
|
||||
DeviceManager.AddDevice(room);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice,
|
||||
"Room is EssentialsTechRoom, Attempting to add to DeviceManager with Fusion");
|
||||
DeviceManager.AddDevice(new EssentialsTechRoomFusionSystemController((EssentialsTechRoom)room, fusionIpId, fusionJoinMapKey));
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Mobile Control Bridge");
|
||||
|
||||
CreateMobileControlBridge(room);
|
||||
}
|
||||
@@ -500,40 +509,55 @@ namespace PepperDash.Essentials
|
||||
|
||||
private static void CreateMobileControlBridge(EssentialsRoomBase room)
|
||||
{
|
||||
var mobileControl = DeviceManager.GetDeviceForKey("appServer") as IMobileControl;
|
||||
var mobileControl = GetMobileControlDevice();
|
||||
|
||||
if (mobileControl == null) return;
|
||||
|
||||
mobileControl.CreateMobileControlRoomBridge(room);
|
||||
mobileControl.CreateMobileControlRoomBridge(room, mobileControl);
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Mobile Control Bridge Added...");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helps add the post activation steps that link bridges to main controller
|
||||
/// </summary>
|
||||
/// <param name="bridge"></param>
|
||||
//void AddBridgePostActivationHelper(MobileControlBridgeBase bridge)
|
||||
//{
|
||||
// bridge.AddPostActivationAction(() =>
|
||||
// {
|
||||
// var parent = DeviceManager.AllDevices.FirstOrDefault(d => d.Key == "appServer") as MobileControlSystemController;
|
||||
// if (parent == null)
|
||||
// {
|
||||
// Debug.Console(0, bridge, "ERROR: Cannot connect app server room bridge. System controller not present");
|
||||
// return;
|
||||
// }
|
||||
// Debug.Console(0, bridge, "Linking to parent controller");
|
||||
// bridge.AddParent(parent);
|
||||
// parent.AddBridge(bridge);
|
||||
// });
|
||||
//}
|
||||
private static IMobileControl GetMobileControlDevice()
|
||||
{
|
||||
var mobileControlList = DeviceManager.AllDevices.OfType<IMobileControl>().ToList();
|
||||
|
||||
if (mobileControlList.Count > 1)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Warning,
|
||||
"Multiple instances of Mobile Control Server found.");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (mobileControlList.Count > 0)
|
||||
{
|
||||
return mobileControlList[0];
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Mobile Control not enabled for this system");
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires up a logo server if not already running
|
||||
/// </summary>
|
||||
void LoadLogoServer()
|
||||
{
|
||||
if (ConfigReader.ConfigObject.Rooms == null)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "No rooms configured. Bypassing Logo server startup.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
!ConfigReader.ConfigObject.Rooms.Any(
|
||||
CheckRoomConfig))
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "No rooms configured to use system Logo server. Bypassing Logo server startup");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
LogoServer = new HttpLogoServer(8080, Global.DirectorySeparator + "html" + Global.DirectorySeparator + "logo");
|
||||
@@ -543,5 +567,38 @@ namespace PepperDash.Essentials
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "NOTICE: Logo server cannot be started. Likely already running in another program");
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckRoomConfig(DeviceConfig c)
|
||||
{
|
||||
string logoDark = null;
|
||||
string logoLight = null;
|
||||
string logo = null;
|
||||
|
||||
try
|
||||
{
|
||||
if (c.Properties["logoDark"] != null)
|
||||
{
|
||||
logoDark = c.Properties["logoDark"].Value<string>("type");
|
||||
}
|
||||
|
||||
if (c.Properties["logoLight"] != null)
|
||||
{
|
||||
logoLight = c.Properties["logoLight"].Value<string>("type");
|
||||
}
|
||||
|
||||
if (c.Properties["logo"] != null)
|
||||
{
|
||||
logo = c.Properties["logo"].Value<string>("type");
|
||||
}
|
||||
|
||||
return ((logoDark != null && logoDark == "system") ||
|
||||
(logoLight != null && logoLight == "system") || (logo != null && logo == "system"));
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Unable to find logo information in any room config");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,6 +225,14 @@
|
||||
"2": "Output 2",
|
||||
"3": "Output 3",
|
||||
"4": "Output 4"
|
||||
},
|
||||
"inputSlotSupportsHdcp2":{
|
||||
"1": "false",
|
||||
"2": "false",
|
||||
"3": "false",
|
||||
"4": "false",
|
||||
"5": "false",
|
||||
"6": "false"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -16,8 +16,8 @@ namespace PepperDash.Essentials.Fusion
|
||||
{
|
||||
BooleanSigData CodecIsInCall;
|
||||
|
||||
public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId)
|
||||
: base(room, ipId)
|
||||
public EssentialsHuddleVtc1FusionController(EssentialsHuddleVtc1Room room, uint ipId, string joinMapKey)
|
||||
: base(room, ipId, joinMapKey)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -55,25 +55,25 @@ namespace PepperDash.Essentials.Fusion
|
||||
// Map FusionRoom Attributes:
|
||||
|
||||
// Codec volume
|
||||
var codecVolume = FusionRoom.CreateOffsetUshortSig(50, "Volume - Fader01", eSigIoMask.InputOutputSig);
|
||||
var codecVolume = FusionRoom.CreateOffsetUshortSig(JoinMap.VolumeFader1.JoinNumber, JoinMap.VolumeFader1.AttributeName, eSigIoMask.InputOutputSig);
|
||||
codecVolume.OutputSig.UserObject = new Action<ushort>(b => (codec as IBasicVolumeWithFeedback).SetVolume(b));
|
||||
(codec as IBasicVolumeWithFeedback).VolumeLevelFeedback.LinkInputSig(codecVolume.InputSig);
|
||||
|
||||
// In Call Status
|
||||
CodecIsInCall = FusionRoom.CreateOffsetBoolSig(69, "Conf - VC 1 In Call", eSigIoMask.InputSigOnly);
|
||||
CodecIsInCall = FusionRoom.CreateOffsetBoolSig(JoinMap.VcCodecInCall.JoinNumber, JoinMap.VcCodecInCall.AttributeName, eSigIoMask.InputSigOnly);
|
||||
codec.CallStatusChange += new EventHandler<PepperDash.Essentials.Devices.Common.Codec.CodecCallStatusItemChangeEventArgs>(codec_CallStatusChange);
|
||||
|
||||
// Online status
|
||||
if (codec is ICommunicationMonitor)
|
||||
{
|
||||
var c = codec as ICommunicationMonitor;
|
||||
var codecOnline = FusionRoom.CreateOffsetBoolSig(122, "Online - VC 1", eSigIoMask.InputSigOnly);
|
||||
var codecOnline = FusionRoom.CreateOffsetBoolSig(JoinMap.VcCodecOnline.JoinNumber, JoinMap.VcCodecOnline.AttributeName, eSigIoMask.InputSigOnly);
|
||||
codecOnline.InputSig.BoolValue = c.CommunicationMonitor.Status == MonitorStatus.IsOk;
|
||||
c.CommunicationMonitor.StatusChange += (o, a) =>
|
||||
{
|
||||
codecOnline.InputSig.BoolValue = a.Status == MonitorStatus.IsOk;
|
||||
};
|
||||
Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key, "Online - VC 1");
|
||||
Debug.Console(0, this, "Linking '{0}' communication monitor to Fusion '{1}'", codec.Key, JoinMap.VcCodecOnline.AttributeName);
|
||||
}
|
||||
|
||||
// Codec IP Address
|
||||
@@ -101,10 +101,10 @@ namespace PepperDash.Essentials.Fusion
|
||||
|
||||
if (codecHasIpInfo)
|
||||
{
|
||||
codecIpAddressSig = FusionRoom.CreateOffsetStringSig(121, "IP Address - VC", eSigIoMask.InputSigOnly);
|
||||
codecIpAddressSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpAddress.JoinNumber, JoinMap.VcCodecIpAddress.AttributeName, eSigIoMask.InputSigOnly);
|
||||
codecIpAddressSig.InputSig.StringValue = codecIpAddress;
|
||||
|
||||
codecIpPortSig = FusionRoom.CreateOffsetStringSig(150, "IP Port - VC", eSigIoMask.InputSigOnly);
|
||||
codecIpPortSig = FusionRoom.CreateOffsetStringSig(JoinMap.VcCodecIpPort.JoinNumber, JoinMap.VcCodecIpPort.AttributeName, eSigIoMask.InputSigOnly);
|
||||
codecIpPortSig.InputSig.StringValue = codecIpPort.ToString();
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace PepperDash.Essentials.Fusion
|
||||
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
|
||||
}
|
||||
|
||||
var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId);
|
||||
var codecAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Codec", tempAsset.InstanceId);
|
||||
codecAsset.PowerOn.OutputSig.UserObject = codecPowerOnAction;
|
||||
codecAsset.PowerOff.OutputSig.UserObject = codecPowerOffAction;
|
||||
codec.StandbyIsOnFeedback.LinkComplementInputSig(codecAsset.PowerOn.InputSig);
|
||||
@@ -166,20 +166,19 @@ namespace PepperDash.Essentials.Fusion
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(RequestFullRoomSchedule, "FusReqRoomSchedule", "Requests schedule of the room for the next 24 hours", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(ModifyMeetingEndTimeConsoleHelper, "FusReqRoomSchMod", "Ends or extends a meeting by the specified time", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(CreateAsHocMeeting, "FusCreateMeeting", "Creates and Ad Hoc meeting for on hour or until the next meeting", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(CreateAdHocMeeting, "FusCreateMeeting", "Creates and Ad Hoc meeting for on hour or until the next meeting", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
// Room to fusion room
|
||||
Room.OnFeedback.LinkInputSig(FusionRoom.SystemPowerOn.InputSig);
|
||||
|
||||
// Moved to
|
||||
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(84, "Display 1 - Current Source", eSigIoMask.InputSigOnly);
|
||||
CurrentRoomSourceNameSig = FusionRoom.CreateOffsetStringSig(JoinMap.Display1CurrentSourceName.JoinNumber, JoinMap.Display1CurrentSourceName.AttributeName, eSigIoMask.InputSigOnly);
|
||||
// Don't think we need to get current status of this as nothing should be alive yet.
|
||||
(Room as EssentialsHuddleVtc1Room).CurrentSourceChange += Room_CurrentSourceInfoChange;
|
||||
|
||||
|
||||
FusionRoom.SystemPowerOn.OutputSig.SetSigFalseAction((Room as EssentialsHuddleVtc1Room).PowerOnToDefaultOrLastSource);
|
||||
FusionRoom.SystemPowerOff.OutputSig.SetSigFalseAction(() => (Room as EssentialsHuddleVtc1Room).RunRouteAction("roomOff", Room.SourceListKey));
|
||||
// NO!! room.RoomIsOn.LinkComplementInputSig(FusionRoom.SystemPowerOff.InputSig);
|
||||
|
||||
|
||||
CrestronEnvironment.EthernetEventHandler += CrestronEnvironment_EthernetEventHandler;
|
||||
@@ -197,9 +196,9 @@ namespace PepperDash.Essentials.Fusion
|
||||
uint i = 1;
|
||||
foreach (var kvp in setTopBoxes)
|
||||
{
|
||||
TryAddRouteActionSigs("Display 1 - Source TV " + i, 188 + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.AttributeName + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
i++;
|
||||
if (i > 5) // We only have five spots
|
||||
if (i > JoinMap.Display1SetTopBoxSourceStart.JoinSpan) // We only have five spots
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -207,7 +206,7 @@ namespace PepperDash.Essentials.Fusion
|
||||
i = 1;
|
||||
foreach (var kvp in discPlayers)
|
||||
{
|
||||
TryAddRouteActionSigs("Display 1 - Source DVD " + i, 181 + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
TryAddRouteActionSigs(JoinMap.Display1DiscPlayerSourceStart.AttributeName + " " + i, JoinMap.Display1DiscPlayerSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
i++;
|
||||
if (i > 5) // We only have five spots
|
||||
break;
|
||||
@@ -217,9 +216,9 @@ namespace PepperDash.Essentials.Fusion
|
||||
i = 1;
|
||||
foreach (var kvp in laptops)
|
||||
{
|
||||
TryAddRouteActionSigs("Display 1 - Source Laptop " + i, 166 + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
TryAddRouteActionSigs(JoinMap.Display1LaptopSourceStart.AttributeName + " " + i, JoinMap.Display1LaptopSourceStart.JoinNumber + i, kvp.Key, kvp.Value.SourceDevice);
|
||||
i++;
|
||||
if (i > 10) // We only have ten spots???
|
||||
if (i > JoinMap.Display1LaptopSourceStart.JoinSpan) // We only have ten spots???
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -273,14 +272,17 @@ namespace PepperDash.Essentials.Fusion
|
||||
// Display to fusion room sigs
|
||||
FusionRoom.DisplayPowerOn.OutputSig.UserObject = dispPowerOnAction;
|
||||
FusionRoom.DisplayPowerOff.OutputSig.UserObject = dispPowerOffAction;
|
||||
defaultDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
|
||||
|
||||
var defaultDisplayTwoWay = defaultDisplay as IHasPowerControlWithFeedback;
|
||||
if (defaultDisplayTwoWay != null)
|
||||
{
|
||||
defaultDisplayTwoWay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
|
||||
}
|
||||
|
||||
if (defaultDisplay is IDisplayUsage)
|
||||
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
|
||||
|
||||
|
||||
|
||||
MapDisplayToRoomJoins(1, 158, defaultDisplay);
|
||||
|
||||
MapDisplayToRoomJoins(1, JoinMap.Display1Start.JoinNumber, defaultDisplay);
|
||||
|
||||
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(defaultDisplay.Key));
|
||||
|
||||
@@ -302,8 +304,18 @@ namespace PepperDash.Essentials.Fusion
|
||||
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display", tempAsset.InstanceId);
|
||||
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
|
||||
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
|
||||
defaultDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
|
||||
// NO!! display.PowerIsOn.LinkComplementInputSig(dispAsset.PowerOff.InputSig);
|
||||
|
||||
|
||||
var defaultTwoWayDisplay = defaultDisplay as IHasPowerControlWithFeedback;
|
||||
if (defaultTwoWayDisplay != null)
|
||||
{
|
||||
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
|
||||
if (defaultDisplay is IDisplayUsage)
|
||||
(defaultDisplay as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
|
||||
|
||||
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
|
||||
}
|
||||
|
||||
// Use extension methods
|
||||
dispAsset.TrySetMakeModel(defaultDisplay);
|
||||
dispAsset.TryLinkAssetErrorToCommunication(defaultDisplay);
|
||||
@@ -315,7 +327,7 @@ namespace PepperDash.Essentials.Fusion
|
||||
|
||||
}
|
||||
|
||||
protected override void MapDisplayToRoomJoins(int displayIndex, int joinOffset, DisplayBase display)
|
||||
protected override void MapDisplayToRoomJoins(int displayIndex, uint joinOffset, DisplayBase display)
|
||||
{
|
||||
string displayName = string.Format("Display {0} - ", displayIndex);
|
||||
|
||||
@@ -325,12 +337,17 @@ namespace PepperDash.Essentials.Fusion
|
||||
// Power on
|
||||
var defaultDisplayPowerOn = FusionRoom.CreateOffsetBoolSig((uint)joinOffset, displayName + "Power On", eSigIoMask.InputOutputSig);
|
||||
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOn(); });
|
||||
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
||||
|
||||
// Power Off
|
||||
var defaultDisplayPowerOff = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 1, displayName + "Power Off", eSigIoMask.InputOutputSig);
|
||||
defaultDisplayPowerOn.OutputSig.UserObject = new Action<bool>(b => { if (!b) display.PowerOff(); }); ;
|
||||
display.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
||||
|
||||
var displayTwoWay = display as IHasPowerControlWithFeedback;
|
||||
if (displayTwoWay != null)
|
||||
{
|
||||
displayTwoWay.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
||||
displayTwoWay.PowerIsOnFeedback.LinkInputSig(defaultDisplayPowerOn.InputSig);
|
||||
}
|
||||
|
||||
// Current Source
|
||||
var defaultDisplaySourceNone = FusionRoom.CreateOffsetBoolSig((uint)joinOffset + 8, displayName + "Source None", eSigIoMask.InputOutputSig);
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Fusion;
|
||||
|
||||
namespace PepperDash.Essentials.Fusion
|
||||
{
|
||||
public class EssentialsTechRoomFusionSystemController : EssentialsHuddleSpaceFusionSystemControllerBase
|
||||
{
|
||||
public EssentialsTechRoomFusionSystemController(EssentialsTechRoom room, uint ipId, string joinMapKey)
|
||||
: base(room, ipId, joinMapKey)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void SetUpDisplay()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
var displays = (Room as EssentialsTechRoom).Displays;
|
||||
|
||||
Debug.Console(1, this, "Setting up Static Assets for {0} Displays", displays.Count);
|
||||
|
||||
foreach (var display in displays.Values.Cast<DisplayBase>())
|
||||
{
|
||||
var disp = display; // Local scope variable
|
||||
|
||||
Debug.Console(2, this, "Setting up Static Asset for {0}", disp.Key);
|
||||
|
||||
disp.UsageTracker = new UsageTracking(disp) { UsageIsTracked = true };
|
||||
disp.UsageTracker.DeviceUsageEnded += UsageTracker_DeviceUsageEnded;
|
||||
|
||||
var dispPowerOnAction = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
disp.PowerOn();
|
||||
}
|
||||
});
|
||||
var dispPowerOffAction = new Action<bool>(b =>
|
||||
{
|
||||
if (!b)
|
||||
{
|
||||
disp.PowerOff();
|
||||
}
|
||||
});
|
||||
|
||||
var deviceConfig = ConfigReader.ConfigObject.GetDeviceForKey(disp.Key);
|
||||
|
||||
FusionAsset tempAsset;
|
||||
|
||||
if (FusionStaticAssets.ContainsKey(deviceConfig.Uid))
|
||||
{
|
||||
// Used existing asset
|
||||
tempAsset = FusionStaticAssets[deviceConfig.Uid];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a new asset
|
||||
tempAsset = new FusionAsset(FusionRoomGuids.GetNextAvailableAssetNumber(FusionRoom),
|
||||
disp.Name, "Display", "");
|
||||
FusionStaticAssets.Add(deviceConfig.Uid, tempAsset);
|
||||
}
|
||||
|
||||
var dispAsset = FusionRoom.CreateStaticAsset(tempAsset.SlotNumber, tempAsset.Name, "Display",
|
||||
tempAsset.InstanceId);
|
||||
|
||||
if (dispAsset != null)
|
||||
{
|
||||
dispAsset.PowerOn.OutputSig.UserObject = dispPowerOnAction;
|
||||
dispAsset.PowerOff.OutputSig.UserObject = dispPowerOffAction;
|
||||
|
||||
// Use extension methods
|
||||
dispAsset.TrySetMakeModel(disp);
|
||||
dispAsset.TryLinkAssetErrorToCommunication(disp);
|
||||
}
|
||||
|
||||
var defaultTwoWayDisplay = disp as IHasPowerControlWithFeedback;
|
||||
if (defaultTwoWayDisplay != null)
|
||||
{
|
||||
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(FusionRoom.DisplayPowerOn.InputSig);
|
||||
if (disp is IDisplayUsage)
|
||||
{
|
||||
(disp as IDisplayUsage).LampHours.LinkInputSig(FusionRoom.DisplayUsage.InputSig);
|
||||
}
|
||||
|
||||
if(dispAsset != null)
|
||||
defaultTwoWayDisplay.PowerIsOnFeedback.LinkInputSig(dispAsset.PowerOn.InputSig);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "Error setting up displays in Fusion: {0}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,14 +71,10 @@
|
||||
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="PepperDash_Core, Version=1.0.41.31808, Culture=neutral, processorArchitecture=MSIL">
|
||||
<Reference Include="PepperDash_Core, Version=1.0.42.30563, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\PepperDashCore\lib\net35\PepperDash_Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PepperDash_Essentials_DM, Version=1.0.0.19343, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\essentials-framework\Essentials DM\Essentials_DM\bin\PepperDash_Essentials_DM.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SimplSharpCustomAttributesInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll</HintPath>
|
||||
@@ -137,19 +133,22 @@
|
||||
<Compile Include="Devices\Amplifier.cs" />
|
||||
<Compile Include="ControlSystem.cs" />
|
||||
<Compile Include="Fusion\EssentialsHuddleVtc1FusionController.cs" />
|
||||
<Compile Include="Fusion\EssentialsTechRoomFusionSystemController.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Room\Config\EssentialsDualDisplayRoomPropertiesConfig.cs" />
|
||||
<Compile Include="Room\Config\EssentialsNDisplayRoomPropertiesConfig.cs" />
|
||||
<Compile Include="Room\Config\DDVC01RoomPropertiesConfig.cs" />
|
||||
<Compile Include="Room\Config\SimplRoomPropertiesConfig.cs" />
|
||||
<Compile Include="Room\Config\EssentialsPresentationPropertiesConfig.cs" />
|
||||
<Compile Include="Room\Config\EssentialsHuddleRoomPropertiesConfig.cs" />
|
||||
<Compile Include="Room\Config\EssentialsHuddleVtc1PropertiesConfig.cs" />
|
||||
<Compile Include="Room\Config\EssentialsRoomEmergencyConfig.cs" />
|
||||
<Compile Include="Room\Config\EssentialsTechRoomConfig.cs" />
|
||||
<Compile Include="Room\Emergency\EsentialsRoomEmergencyContactClosure.cs" />
|
||||
<Compile Include="Room\Types\EssentialsDualDisplayRoom.cs" />
|
||||
<Compile Include="Room\Types\EssentialsHuddleVtc1Room.cs" />
|
||||
<Compile Include="Room\Types\EssentialsNDisplayRoomBase.cs" />
|
||||
<Compile Include="Room\Config\EssentialsRoomConfig.cs" />
|
||||
<Compile Include="Room\Types\EssentialsTechRoom.cs" />
|
||||
<Compile Include="UIDrivers\Environment Drivers\EssentialsEnvironmentDriver.cs" />
|
||||
<Compile Include="UIDrivers\Environment Drivers\EssentialsLightingDriver.cs" />
|
||||
<Compile Include="UIDrivers\Environment Drivers\EssentialsShadeDriver.cs" />
|
||||
@@ -215,6 +214,10 @@
|
||||
<Project>{892B761C-E479-44CE-BD74-243E9214AF13}</Project>
|
||||
<Name>Essentials Devices Common</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\essentials-framework\Essentials DM\Essentials_DM\PepperDash_Essentials_DM.csproj">
|
||||
<Project>{9199CE8A-0C9F-4952-8672-3EED798B284F}</Project>
|
||||
<Name>PepperDash_Essentials_DM</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
|
||||
<ProjectExtensions>
|
||||
|
||||
@@ -22,30 +22,25 @@ namespace PepperDash.Essentials.Room.Config
|
||||
public static Device GetRoomObject(DeviceConfig roomConfig)
|
||||
{
|
||||
var typeName = roomConfig.Type.ToLower();
|
||||
|
||||
if (typeName == "huddle")
|
||||
{
|
||||
var huddle = new EssentialsHuddleSpaceRoom(roomConfig);
|
||||
|
||||
return huddle;
|
||||
return new EssentialsHuddleSpaceRoom(roomConfig);
|
||||
}
|
||||
else if (typeName == "huddlevtc1")
|
||||
{
|
||||
var rm = new EssentialsHuddleVtc1Room(roomConfig);
|
||||
|
||||
return rm;
|
||||
}
|
||||
else if (typeName == "ddvc01Bridge")
|
||||
{
|
||||
return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing.
|
||||
}
|
||||
else if (typeName == "dualdisplay")
|
||||
{
|
||||
var rm = new EssentialsDualDisplayRoom(roomConfig);
|
||||
if (typeName == "huddlevtc1")
|
||||
{
|
||||
return new EssentialsHuddleVtc1Room(roomConfig);
|
||||
}
|
||||
if (typeName == "ddvc01bridge")
|
||||
{
|
||||
return new Device(roomConfig.Key, roomConfig.Name); // placeholder device that does nothing.
|
||||
}
|
||||
if (typeName == "dualdisplay")
|
||||
{
|
||||
return new EssentialsDualDisplayRoom(roomConfig);
|
||||
}
|
||||
|
||||
return rm;
|
||||
}
|
||||
|
||||
return null;
|
||||
return typeName != "techroom" ? null : new EssentialsTechRoom(roomConfig);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -182,6 +177,9 @@ namespace PepperDash.Essentials.Room.Config
|
||||
[JsonProperty("volumes")]
|
||||
public EssentialsRoomVolumesConfig Volumes { get; set; }
|
||||
|
||||
[JsonProperty("fusion")]
|
||||
public EssentialsRoomFusionConfig Fusion { get; set; }
|
||||
|
||||
[JsonProperty("zeroVolumeWhenSwtichingVolumeDevices")]
|
||||
public bool ZeroVolumeWhenSwtichingVolumeDevices { get; set; }
|
||||
|
||||
@@ -198,9 +196,20 @@ namespace PepperDash.Essentials.Room.Config
|
||||
public string DefaultAudioKey { get; set; }
|
||||
[JsonProperty("sourceListKey")]
|
||||
public string SourceListKey { get; set; }
|
||||
[JsonProperty("destinationListKey")]
|
||||
public string DestinationListKey { get; set; }
|
||||
[JsonProperty("defaultSourceItem")]
|
||||
public string DefaultSourceItem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the room supports advanced sharing
|
||||
/// </summary>
|
||||
[JsonProperty("supportsAdvancedSharing")]
|
||||
public bool SupportsAdvancedSharing { get; set; }
|
||||
/// <summary>
|
||||
/// Indicates if non-tech users can change the share mode
|
||||
/// </summary>
|
||||
[JsonProperty("userCanChangeShareMode")]
|
||||
public bool UserCanChangeShareMode { get; set; }
|
||||
}
|
||||
|
||||
public class EssentialsConferenceRoomPropertiesConfig : EssentialsAvRoomPropertiesConfig
|
||||
@@ -225,6 +234,32 @@ namespace PepperDash.Essentials.Room.Config
|
||||
|
||||
}
|
||||
|
||||
public class EssentialsRoomFusionConfig
|
||||
{
|
||||
public uint IpIdInt
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return Convert.ToUInt32(IpId, 16);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new FormatException(string.Format("ERROR:Unable to convert IP ID: {0} to hex. Error:\n{1}", IpId));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("ipId")]
|
||||
public string IpId { get; set; }
|
||||
|
||||
[JsonProperty("joinMapKey")]
|
||||
public string JoinMapKey { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class EssentialsRoomMicrophonePrivacyConfig
|
||||
{
|
||||
[JsonProperty("deviceKey")]
|
||||
|
||||
72
PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs
Normal file
72
PepperDashEssentials/Room/Config/EssentialsTechRoomConfig.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Room.Config
|
||||
{
|
||||
public class EssentialsTechRoomConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// The key of the dummy device used to enable routing
|
||||
/// </summary>
|
||||
[JsonProperty("dummySourceKey")]
|
||||
public string DummySourceKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The keys of the displays assigned to this room
|
||||
/// </summary>
|
||||
[JsonProperty("displays")]
|
||||
public List<string> Displays { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The keys of the tuners assinged to this room
|
||||
/// </summary>
|
||||
[JsonProperty("tuners")]
|
||||
public List<string> Tuners { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// PIN to access the room as a normal user
|
||||
/// </summary>
|
||||
[JsonProperty("userPin")]
|
||||
public string UserPin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// PIN to access the room as a tech user
|
||||
/// </summary>
|
||||
[JsonProperty("techPin")]
|
||||
public string TechPin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name of the presets file. Path prefix is assumed to be /html/presets/lists/
|
||||
/// </summary>
|
||||
[JsonProperty("presetsFileName")]
|
||||
public string PresetsFileName { get; set; }
|
||||
|
||||
[JsonProperty("scheduledEvents")]
|
||||
public List<ScheduledEventConfig> ScheduledEvents { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the room is the primary when true
|
||||
/// </summary>
|
||||
[JsonProperty("isPrimary")]
|
||||
public bool IsPrimary { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates which tuners should mirror preset recall when two rooms are configured in a primary->secondary scenario
|
||||
/// </summary>
|
||||
[JsonProperty("mirroredTuners")]
|
||||
public Dictionary<uint, string> MirroredTuners { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the room
|
||||
/// </summary>
|
||||
[JsonProperty("isTvPresetsProvider")]
|
||||
public bool IsTvPresetsProvider;
|
||||
|
||||
public EssentialsTechRoomConfig()
|
||||
{
|
||||
Displays = new List<string>();
|
||||
Tuners = new List<string>();
|
||||
ScheduledEvents = new List<ScheduledEventConfig>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,19 +8,19 @@ using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Room.Config
|
||||
{
|
||||
public class DDVC01RoomPropertiesConfig : EssentialsHuddleVtc1PropertiesConfig
|
||||
public class SimplRoomPropertiesConfig : EssentialsHuddleVtc1PropertiesConfig
|
||||
{
|
||||
[JsonProperty("roomPhoneNumber")]
|
||||
public string RoomPhoneNumber { get; set; }
|
||||
[JsonProperty("roomURI")]
|
||||
public string RoomURI { get; set; }
|
||||
[JsonProperty("speedDials")]
|
||||
public List<DDVC01SpeedDial> SpeedDials { get; set; }
|
||||
public List<SimplSpeedDial> SpeedDials { get; set; }
|
||||
[JsonProperty("volumeSliderNames")]
|
||||
public List<string> VolumeSliderNames { get; set; }
|
||||
}
|
||||
|
||||
public class DDVC01SpeedDial
|
||||
public class SimplSpeedDial
|
||||
{
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
@@ -274,28 +274,45 @@ namespace PepperDash.Essentials
|
||||
|
||||
CallTypeFeedback = new IntFeedback(() => 0);
|
||||
|
||||
SourceListKey = "default";
|
||||
SetSourceListKey();
|
||||
EnablePowerOnToLastSource = true;
|
||||
}
|
||||
|
||||
private void SetSourceListKey()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey))
|
||||
{
|
||||
SetSourceListKey(PropertiesConfig.SourceListKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetSourceListKey(Key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void InitializeDisplay(DisplayBase disp)
|
||||
{
|
||||
if (disp != null)
|
||||
{
|
||||
// Link power, warming, cooling to display
|
||||
disp.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||
var dispTwoWay = disp as IHasPowerControlWithFeedback;
|
||||
if (dispTwoWay != null)
|
||||
{
|
||||
dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (!disp.PowerIsOnFeedback.BoolValue)
|
||||
disp.CurrentSourceInfo = null;
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
if (disp.PowerIsOnFeedback.BoolValue)
|
||||
{
|
||||
SetDefaultLevels();
|
||||
}
|
||||
};
|
||||
if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||
{
|
||||
if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
|
||||
disp.CurrentSourceInfo = null;
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
if (dispTwoWay.PowerIsOnFeedback.BoolValue)
|
||||
{
|
||||
SetDefaultLevels();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
@@ -329,7 +346,6 @@ namespace PepperDash.Essentials
|
||||
|
||||
this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight();
|
||||
this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark();
|
||||
this.SourceListKey = PropertiesConfig.SourceListKey;
|
||||
this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
||||
this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
|
||||
|
||||
@@ -579,8 +595,8 @@ namespace PepperDash.Essentials
|
||||
|
||||
|
||||
|
||||
if (dest is IPower)
|
||||
(dest as IPower).PowerOff();
|
||||
if (dest is IHasPowerControl)
|
||||
(dest as IHasPowerControl).PowerOff();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -176,15 +176,19 @@ namespace PepperDash.Essentials
|
||||
if (disp != null)
|
||||
{
|
||||
// Link power, warming, cooling to display
|
||||
disp.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||
{
|
||||
if (!disp.PowerIsOnFeedback.BoolValue)
|
||||
CurrentSourceInfo = null;
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
};
|
||||
var dispTwoWay = disp as IHasPowerControlWithFeedback;
|
||||
if (dispTwoWay != null)
|
||||
{
|
||||
dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||
{
|
||||
if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
|
||||
CurrentSourceInfo = null;
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
@@ -197,11 +201,25 @@ namespace PepperDash.Essentials
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
};
|
||||
}
|
||||
|
||||
SetSourceListKey();
|
||||
|
||||
SourceListKey = "default";
|
||||
EnablePowerOnToLastSource = true;
|
||||
}
|
||||
|
||||
private void SetSourceListKey()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey))
|
||||
{
|
||||
SetSourceListKey(PropertiesConfig.SourceListKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetSourceListKey(Key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected override void CustomSetConfig(DeviceConfig config)
|
||||
{
|
||||
var newPropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleRoomPropertiesConfig>(config.Properties.ToString());
|
||||
@@ -252,7 +270,6 @@ namespace PepperDash.Essentials
|
||||
|
||||
this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight();
|
||||
this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark();
|
||||
this.SourceListKey = PropertiesConfig.SourceListKey;
|
||||
this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
||||
this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
|
||||
|
||||
@@ -495,8 +512,8 @@ namespace PepperDash.Essentials
|
||||
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
dest.ReleaseRoute();
|
||||
if (dest is IPower)
|
||||
(dest as IPower).PowerOff();
|
||||
if (dest is IHasPowerControl)
|
||||
(dest as IHasPowerControl).PowerOff();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -13,12 +13,14 @@ using PepperDash.Essentials.Room.Config;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
using PepperDash.Essentials.Devices.Common.AudioCodec;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class EssentialsHuddleVtc1Room : EssentialsRoomBase, IHasCurrentSourceInfoChange,
|
||||
IPrivacy, IHasCurrentVolumeControls, IRunRouteAction, IRunDefaultCallRoute, IHasVideoCodec, IHasAudioCodec, IHasDefaultDisplay, IHasInCallFeedback
|
||||
{
|
||||
{
|
||||
private bool _codecExternalSourceChange;
|
||||
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
|
||||
@@ -50,20 +52,6 @@ namespace PepperDash.Essentials
|
||||
|
||||
//************************
|
||||
|
||||
public override string SourceListKey
|
||||
{
|
||||
get
|
||||
{
|
||||
return _SourceListKey;
|
||||
}
|
||||
set
|
||||
{
|
||||
_SourceListKey = value;
|
||||
SetCodecExternalSources();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected override Func<bool> OnFeedbackFunc
|
||||
{
|
||||
get
|
||||
@@ -189,6 +177,14 @@ namespace PepperDash.Essentials
|
||||
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
||||
|
||||
var vc = VideoCodec as IHasExternalSourceSwitching;
|
||||
if (vc != null && !_codecExternalSourceChange)
|
||||
{
|
||||
vc.SetSelectedSource(CurrentSourceInfoKey);
|
||||
}
|
||||
|
||||
_codecExternalSourceChange = false;
|
||||
}
|
||||
}
|
||||
SourceListItem _CurrentSourceInfo;
|
||||
@@ -272,19 +268,23 @@ namespace PepperDash.Essentials
|
||||
if (disp != null)
|
||||
{
|
||||
// Link power, warming, cooling to display
|
||||
disp.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||
var dispTwoWay = disp as IHasPowerControlWithFeedback;
|
||||
if (dispTwoWay != null)
|
||||
{
|
||||
dispTwoWay.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (!disp.PowerIsOnFeedback.BoolValue)
|
||||
CurrentSourceInfo = null;
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
if (disp.PowerIsOnFeedback.BoolValue)
|
||||
{
|
||||
SetDefaultLevels();
|
||||
}
|
||||
};
|
||||
if (dispTwoWay.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||
{
|
||||
if (!dispTwoWay.PowerIsOnFeedback.BoolValue)
|
||||
CurrentSourceInfo = null;
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
if (dispTwoWay.PowerIsOnFeedback.BoolValue)
|
||||
{
|
||||
SetDefaultLevels();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
@@ -313,7 +313,7 @@ namespace PepperDash.Essentials
|
||||
|
||||
|
||||
VideoCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
|
||||
VideoCodec.IsReadyChange += (o, a) => this.SetCodecExternalSources();
|
||||
VideoCodec.IsReadyChange += (o, a) => { this.SetCodecExternalSources(); SetCodecBranding(); };
|
||||
|
||||
if (AudioCodec != null)
|
||||
AudioCodec.CallStatusChange += (o, a) => this.InCallFeedback.FireUpdate();
|
||||
@@ -327,7 +327,8 @@ namespace PepperDash.Essentials
|
||||
|
||||
CallTypeFeedback = new IntFeedback(() => 0);
|
||||
|
||||
SourceListKey = "default";
|
||||
SetSourceListKey();
|
||||
|
||||
EnablePowerOnToLastSource = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -336,6 +337,21 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void SetSourceListKey()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(PropertiesConfig.SourceListKey))
|
||||
{
|
||||
SetSourceListKey(PropertiesConfig.SourceListKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetSourceListKey(Key);
|
||||
}
|
||||
|
||||
SetCodecExternalSources();
|
||||
}
|
||||
|
||||
protected override void CustomSetConfig(DeviceConfig config)
|
||||
{
|
||||
var newPropertiesConfig = JsonConvert.DeserializeObject<EssentialsHuddleVtc1PropertiesConfig>(config.Properties.ToString());
|
||||
@@ -359,13 +375,14 @@ namespace PepperDash.Essentials
|
||||
this.LogoUrlLightBkgnd = PropertiesConfig.LogoLight.GetLogoUrlLight();
|
||||
this.LogoUrlDarkBkgnd = PropertiesConfig.LogoDark.GetLogoUrlDark();
|
||||
|
||||
this.SourceListKey = PropertiesConfig.SourceListKey;
|
||||
this.DefaultSourceItem = PropertiesConfig.DefaultSourceItem;
|
||||
this.DefaultVolume = (ushort)(PropertiesConfig.Volumes.Master.Level * 65535 / 100);
|
||||
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -382,6 +399,8 @@ namespace PepperDash.Essentials
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Shutting down room");
|
||||
|
||||
RunRouteAction("roomOff");
|
||||
VideoCodec.StopSharing();
|
||||
VideoCodec.StandbyActivate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -405,6 +424,12 @@ namespace PepperDash.Essentials
|
||||
return true;
|
||||
}
|
||||
|
||||
public void RunRouteActionCodec(string routeKey, string sourceListKey)
|
||||
{
|
||||
_codecExternalSourceChange = true;
|
||||
RunRouteAction(routeKey, sourceListKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -424,10 +449,14 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
if (string.IsNullOrEmpty(sourceListKey))
|
||||
{
|
||||
Debug.Console(1, this, "No sourceListKey present. RunRouteAction assumes default source list.");
|
||||
RunRouteAction(routeKey, new Action(() => { }));
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "sourceListKey present but not yet implemented");
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -575,6 +604,28 @@ namespace PepperDash.Essentials
|
||||
|
||||
OnFeedback.FireUpdate();
|
||||
|
||||
if (OnFeedback.BoolValue)
|
||||
{
|
||||
if (VideoCodec.UsageTracker.InUseTracker.InUseFeedback.BoolValue)
|
||||
{
|
||||
Debug.Console(1, this, "Video Codec in use, deactivating standby on codec");
|
||||
VideoCodec.StandbyDeactivate();
|
||||
}
|
||||
|
||||
if (VideoCodec.StandbyIsOnFeedback.BoolValue)
|
||||
{
|
||||
VideoCodec.StandbyDeactivate();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "Video codec not in standby. No need to wake.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "Room OnFeedback state: {0}", OnFeedback.BoolValue);
|
||||
}
|
||||
|
||||
// report back when done
|
||||
if (successCallback != null)
|
||||
successCallback();
|
||||
@@ -635,8 +686,9 @@ namespace PepperDash.Essentials
|
||||
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
dest.ReleaseRoute();
|
||||
if (dest is IPower)
|
||||
(dest as IPower).PowerOff();
|
||||
if (dest is IHasPowerControl)
|
||||
(dest as IHasPowerControl).PowerOff();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -688,40 +740,54 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Setup the external sources for the Cisco Touch 10 devices that support IHasExternalSourceSwitch
|
||||
/// </summary>
|
||||
private void SetCodecExternalSources()
|
||||
{
|
||||
var videoCodecWithExternalSwitching = VideoCodec as IHasExternalSourceSwitching;
|
||||
/// <summary>
|
||||
/// Setup the external sources for the Cisco Touch 10 devices that support IHasExternalSourceSwitch
|
||||
/// </summary>
|
||||
private void SetCodecExternalSources()
|
||||
{
|
||||
var videoCodecWithExternalSwitching = VideoCodec as IHasExternalSourceSwitching;
|
||||
|
||||
if (videoCodecWithExternalSwitching == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
string codecTieLine = "";
|
||||
codecTieLine = ConfigReader.ConfigObject.TieLines.SingleOrDefault(x => x.DestinationKey == VideoCodec.Key).DestinationPort;
|
||||
videoCodecWithExternalSwitching.ClearExternalSources();
|
||||
videoCodecWithExternalSwitching.RunRouteAction = RunRouteAction;
|
||||
var srcList = ConfigReader.ConfigObject.SourceLists.SingleOrDefault(x => x.Key == SourceListKey).Value.OrderBy(kv => kv.Value.Order); ;
|
||||
if (videoCodecWithExternalSwitching == null || !videoCodecWithExternalSwitching.ExternalSourceListEnabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var kvp in srcList)
|
||||
{
|
||||
var srcConfig = kvp.Value;
|
||||
try
|
||||
{
|
||||
// Get the tie line that the external switcher is connected to
|
||||
string codecInputConnectorName = ConfigReader.ConfigObject.TieLines.SingleOrDefault(
|
||||
x => x.DestinationKey == VideoCodec.Key && x.DestinationPort == videoCodecWithExternalSwitching.ExternalSourceInputPort).DestinationPort;
|
||||
|
||||
if (kvp.Key != DefaultCodecRouteString && kvp.Key != "roomOff")
|
||||
{
|
||||
videoCodecWithExternalSwitching.ClearExternalSources();
|
||||
videoCodecWithExternalSwitching.RunRouteAction = RunRouteActionCodec;
|
||||
var srcList = ConfigReader.ConfigObject.SourceLists.SingleOrDefault(x => x.Key == SourceListKey).Value.OrderBy(kv => kv.Value.Order); ;
|
||||
|
||||
videoCodecWithExternalSwitching.AddExternalSource(codecTieLine, kvp.Key, srcConfig.PreferredName, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceType.desktop);
|
||||
videoCodecWithExternalSwitching.SetExternalSourceState(kvp.Key, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceMode.Ready);
|
||||
foreach (var kvp in srcList)
|
||||
{
|
||||
var srcConfig = kvp.Value;
|
||||
|
||||
if (kvp.Key != DefaultCodecRouteString && kvp.Key != "roomOff")
|
||||
{
|
||||
videoCodecWithExternalSwitching.AddExternalSource(codecInputConnectorName, kvp.Key, srcConfig.PreferredName, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceType.desktop);
|
||||
videoCodecWithExternalSwitching.SetExternalSourceState(kvp.Key, PepperDash.Essentials.Devices.Common.VideoCodec.Cisco.eExternalSourceMode.Ready);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(2, this, "Error setting codec external sources: {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void SetCodecBranding()
|
||||
{
|
||||
var vcWithBranding = VideoCodec as IHasBranding;
|
||||
|
||||
if (vcWithBranding == null) return;
|
||||
|
||||
Debug.Console(1, this, "Setting Codec Branding");
|
||||
vcWithBranding.InitializeBranding(Key);
|
||||
}
|
||||
|
||||
#region IPrivacy Members
|
||||
|
||||
|
||||
517
PepperDashEssentials/Room/Types/EssentialsTechRoom.cs
Normal file
517
PepperDashEssentials/Room/Types/EssentialsTechRoom.cs
Normal file
@@ -0,0 +1,517 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.Scheduler;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.DeviceTypeInterfaces;
|
||||
using PepperDash.Essentials.Core.Presets;
|
||||
using PepperDash.Essentials.Devices.Common;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class EssentialsTechRoom : EssentialsRoomBase, ITvPresetsProvider, IBridgeAdvanced, IRunDirectRouteAction
|
||||
{
|
||||
private readonly EssentialsTechRoomConfig _config;
|
||||
private readonly Dictionary<string, TwoWayDisplayBase> _displays;
|
||||
|
||||
private readonly DevicePresetsModel _tunerPresets;
|
||||
private readonly Dictionary<string, IRSetTopBoxBase> _tuners;
|
||||
|
||||
private Dictionary<string, string> _currentPresets;
|
||||
private ScheduledEventGroup _roomScheduledEventGroup;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override Func<bool> IsWarmingFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
return _displays.All(kv => kv.Value.IsWarmingUpFeedback.BoolValue);
|
||||
};
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override Func<bool> IsCoolingFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
return _displays.All(kv => kv.Value.IsCoolingDownFeedback.BoolValue);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public EssentialsTechRoom(DeviceConfig config) : base(config)
|
||||
{
|
||||
_config = config.Properties.ToObject<EssentialsTechRoomConfig>();
|
||||
|
||||
_tunerPresets = new DevicePresetsModel(String.Format("{0}-presets", config.Key), _config.PresetsFileName);
|
||||
|
||||
_tunerPresets.SetFileName(_config.PresetsFileName);
|
||||
|
||||
_tunerPresets.PresetRecalled += TunerPresetsOnPresetRecalled;
|
||||
|
||||
_tuners = GetDevices<IRSetTopBoxBase>(_config.Tuners);
|
||||
_displays = GetDevices<TwoWayDisplayBase>(_config.Displays);
|
||||
|
||||
RoomPowerIsOnFeedback = new BoolFeedback(() => RoomPowerIsOn);
|
||||
|
||||
SetUpTunerPresetsFeedback();
|
||||
|
||||
SubscribeToDisplayFeedbacks();
|
||||
|
||||
CreateOrUpdateScheduledEvents();
|
||||
}
|
||||
|
||||
public Dictionary<string, StringFeedback> CurrentPresetsFeedbacks { get; private set; }
|
||||
|
||||
public Dictionary<string, IRSetTopBoxBase> Tuners
|
||||
{
|
||||
get { return _tuners; }
|
||||
}
|
||||
|
||||
public Dictionary<string, TwoWayDisplayBase> Displays
|
||||
{
|
||||
get { return _displays; }
|
||||
}
|
||||
|
||||
public BoolFeedback RoomPowerIsOnFeedback { get; private set; }
|
||||
|
||||
public bool RoomPowerIsOn
|
||||
{
|
||||
get { return _displays.All(kv => kv.Value.PowerIsOnFeedback.BoolValue); }
|
||||
}
|
||||
|
||||
#region ITvPresetsProvider Members
|
||||
|
||||
public DevicePresetsModel TvPresets
|
||||
{
|
||||
get { return _tunerPresets; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void TunerPresetsOnPresetRecalled(ISetTopBoxNumericKeypad device, string channel)
|
||||
{
|
||||
//Debug.Console(2, this, "TunerPresetsOnPresetRecalled");
|
||||
|
||||
if (!_currentPresets.ContainsKey(device.Key))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Debug.Console(2, this, "Tuner Key: {0} Channel: {1}", device.Key, channel);
|
||||
|
||||
_currentPresets[device.Key] = channel;
|
||||
|
||||
if (CurrentPresetsFeedbacks.ContainsKey(device.Key))
|
||||
{
|
||||
CurrentPresetsFeedbacks[device.Key].FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetUpTunerPresetsFeedback()
|
||||
{
|
||||
_currentPresets = new Dictionary<string, string>();
|
||||
CurrentPresetsFeedbacks = new Dictionary<string, StringFeedback>();
|
||||
|
||||
foreach (var setTopBox in _tuners)
|
||||
{
|
||||
var tuner = setTopBox.Value;
|
||||
_currentPresets.Add(tuner.Key, String.Empty);
|
||||
CurrentPresetsFeedbacks.Add(tuner.Key, new StringFeedback(() => _currentPresets[tuner.Key]));
|
||||
}
|
||||
}
|
||||
|
||||
private void SubscribeToDisplayFeedbacks()
|
||||
{
|
||||
foreach (var display in _displays)
|
||||
{
|
||||
display.Value.PowerIsOnFeedback.OutputChange +=
|
||||
(sender, args) =>
|
||||
{
|
||||
RoomPowerIsOnFeedback.InvokeFireUpdate();
|
||||
IsWarmingUpFeedback.InvokeFireUpdate();
|
||||
IsCoolingDownFeedback.InvokeFireUpdate();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateOrUpdateScheduledEvents()
|
||||
{
|
||||
var eventsConfig = _config.ScheduledEvents;
|
||||
|
||||
GetOrCreateScheduleGroup();
|
||||
|
||||
foreach (var eventConfig in eventsConfig)
|
||||
{
|
||||
CreateOrUpdateSingleEvent(eventConfig);
|
||||
}
|
||||
|
||||
_roomScheduledEventGroup.UserGroupCallBack += HandleScheduledEvent;
|
||||
}
|
||||
|
||||
private void GetOrCreateScheduleGroup()
|
||||
{
|
||||
if (_roomScheduledEventGroup == null)
|
||||
{
|
||||
_roomScheduledEventGroup = Scheduler.GetEventGroup(Key) ?? new ScheduledEventGroup(Key);
|
||||
|
||||
Scheduler.AddEventGroup(_roomScheduledEventGroup);
|
||||
}
|
||||
|
||||
_roomScheduledEventGroup.RetrieveAllEvents();
|
||||
}
|
||||
|
||||
private void CreateOrUpdateSingleEvent(ScheduledEventConfig scheduledEvent)
|
||||
{
|
||||
if (!_roomScheduledEventGroup.ScheduledEvents.ContainsKey(scheduledEvent.Key))
|
||||
{
|
||||
SchedulerUtilities.CreateEventFromConfig(scheduledEvent, _roomScheduledEventGroup, HandleScheduledEvent);
|
||||
return;
|
||||
}
|
||||
|
||||
var roomEvent = _roomScheduledEventGroup.ScheduledEvents[scheduledEvent.Key];
|
||||
|
||||
//if (SchedulerUtilities.CheckEventTimeForMatch(roomEvent, DateTime.Parse(scheduledEvent.Time)) &&
|
||||
// SchedulerUtilities.CheckEventRecurrenceForMatch(roomEvent, scheduledEvent.Days))
|
||||
//{
|
||||
// Debug.Console(1, this, "Existing event matches new event properties. Nothing to update");
|
||||
// return;
|
||||
//}
|
||||
|
||||
Debug.Console(1, this,
|
||||
"Existing event does not match new config properties. Deleting existing event '{0}' and creating new event from configuration",
|
||||
roomEvent.Name);
|
||||
|
||||
_roomScheduledEventGroup.DeleteEvent(roomEvent);
|
||||
|
||||
SchedulerUtilities.CreateEventFromConfig(scheduledEvent, _roomScheduledEventGroup, HandleScheduledEvent);
|
||||
}
|
||||
|
||||
public void AddOrUpdateScheduledEvent(ScheduledEventConfig scheduledEvent)
|
||||
{
|
||||
//update config based on key of scheduleEvent
|
||||
GetOrCreateScheduleGroup();
|
||||
var existingEventIndex = _config.ScheduledEvents.FindIndex((e) => e.Key == scheduledEvent.Key);
|
||||
|
||||
if (existingEventIndex < 0)
|
||||
{
|
||||
_config.ScheduledEvents.Add(scheduledEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
_config.ScheduledEvents[existingEventIndex] = scheduledEvent;
|
||||
}
|
||||
|
||||
//create or update event based on config
|
||||
CreateOrUpdateSingleEvent(scheduledEvent);
|
||||
//save config
|
||||
Config.Properties = JToken.FromObject(_config);
|
||||
|
||||
CustomSetConfig(Config);
|
||||
//Fire Event
|
||||
OnScheduledEventUpdate();
|
||||
}
|
||||
|
||||
public List<ScheduledEventConfig> GetScheduledEvents()
|
||||
{
|
||||
return _config.ScheduledEvents ?? new List<ScheduledEventConfig>();
|
||||
}
|
||||
|
||||
private void OnScheduledEventUpdate()
|
||||
{
|
||||
var handler = ScheduledEventsChanged;
|
||||
|
||||
if (handler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
handler(this, new ScheduledEventEventArgs {ScheduledEvents = _config.ScheduledEvents});
|
||||
}
|
||||
|
||||
public event EventHandler<ScheduledEventEventArgs> ScheduledEventsChanged;
|
||||
|
||||
private void HandleScheduledEvent(ScheduledEvent schevent, ScheduledEventCommon.eCallbackReason type)
|
||||
{
|
||||
var eventConfig = _config.ScheduledEvents.FirstOrDefault(e => e.Key == schevent.Name);
|
||||
|
||||
if (eventConfig == null)
|
||||
{
|
||||
Debug.Console(1, this, "Event with name {0} not found", schevent.Name);
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "Running actions for event {0}", schevent.Name);
|
||||
|
||||
if (eventConfig.Acknowledgeable)
|
||||
{
|
||||
schevent.Acknowledge();
|
||||
}
|
||||
|
||||
CrestronInvoke.BeginInvoke((o) =>
|
||||
{
|
||||
Debug.Console(2, this, "There are {0} actions to execute for this event.", eventConfig.Actions.Count);
|
||||
|
||||
foreach (var a in eventConfig.Actions)
|
||||
{
|
||||
Debug.Console(2, this,
|
||||
@"Attempting to run action:
|
||||
DeviceKey: {0}
|
||||
MethodName: {1}
|
||||
Params: {2}"
|
||||
, a.DeviceKey, a.MethodName, a.Params);
|
||||
DeviceJsonApi.DoDeviceAction(a);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void RoomPowerOn()
|
||||
{
|
||||
Debug.Console(2, this, "Room Powering On");
|
||||
|
||||
var dummySource = DeviceManager.GetDeviceForKey(_config.DummySourceKey) as IRoutingOutputs;
|
||||
|
||||
if (dummySource == null)
|
||||
{
|
||||
Debug.Console(1, this, "Unable to get source with key: {0}", _config.DummySourceKey);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var display in _displays)
|
||||
{
|
||||
RunDirectRoute(dummySource, display.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public void RoomPowerOff()
|
||||
{
|
||||
Debug.Console(2, this, "Room Powering Off");
|
||||
|
||||
foreach (var display in _displays)
|
||||
{
|
||||
display.Value.PowerOff();
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<string, T> GetDevices<T>(ICollection<string> config) where T : IKeyed
|
||||
{
|
||||
try
|
||||
{
|
||||
var returnValue = DeviceManager.AllDevices.OfType<T>()
|
||||
.Where(d => config.Contains(d.Key))
|
||||
.ToDictionary(d => d.Key, d => d);
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Error,
|
||||
"Error getting devices. Check Essentials Configuration");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
#region Overrides of EssentialsRoomBase
|
||||
|
||||
protected override Func<bool> OnFeedbackFunc
|
||||
{
|
||||
get { return () => RoomPowerIsOn; }
|
||||
}
|
||||
|
||||
protected override void EndShutdown()
|
||||
{
|
||||
}
|
||||
|
||||
public override void SetDefaultLevels()
|
||||
{
|
||||
}
|
||||
|
||||
public override void PowerOnToDefaultOrLastSource()
|
||||
{
|
||||
}
|
||||
|
||||
public override bool RunDefaultPresentRoute()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void RoomVacatedForTimeoutPeriod(object o)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IBridgeAdvanced
|
||||
|
||||
public void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
|
||||
var joinMap = new EssentialsTechRoomJoinMap(joinStart);
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!String.IsNullOrEmpty(joinMapSerialized))
|
||||
{
|
||||
joinMap = JsonConvert.DeserializeObject<EssentialsTechRoomJoinMap>(joinMapSerialized);
|
||||
}
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
uint i;
|
||||
if (_config.IsPrimary)
|
||||
{
|
||||
Debug.Console(1, this, "Linking Primary system Tuner Preset Mirroring");
|
||||
if (_config.MirroredTuners != null && _config.MirroredTuners.Count > 0)
|
||||
{
|
||||
foreach (var tuner in _config.MirroredTuners)
|
||||
{
|
||||
var f = CurrentPresetsFeedbacks[tuner.Value];
|
||||
|
||||
if (f == null)
|
||||
{
|
||||
Debug.Console(1, this, "Unable to find feedback with key: {0}", tuner.Value);
|
||||
continue;
|
||||
}
|
||||
|
||||
var join = joinMap.CurrentPreset.JoinNumber + tuner.Key;
|
||||
f.LinkInputSig(trilist.StringInput[(uint)(join)]);
|
||||
Debug.Console(1, this, "Linked Current Preset feedback for tuner: {0} to serial join: {1}", tuner.Value, join);
|
||||
}
|
||||
}
|
||||
|
||||
//i = 0;
|
||||
//foreach (var feedback in CurrentPresetsFeedbacks)
|
||||
//{
|
||||
// feedback.Value.LinkInputSig(trilist.StringInput[(uint) (joinMap.CurrentPreset.JoinNumber + i)]);
|
||||
// i++;
|
||||
//}
|
||||
|
||||
trilist.OnlineStatusChange += (device, args) =>
|
||||
{
|
||||
if (!args.DeviceOnLine)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var feedback in CurrentPresetsFeedbacks)
|
||||
{
|
||||
feedback.Value.FireUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "Linking Secondary system Tuner Preset Mirroring");
|
||||
|
||||
if (_config.MirroredTuners != null && _config.MirroredTuners.Count > 0)
|
||||
{
|
||||
foreach (var tuner in _config.MirroredTuners)
|
||||
{
|
||||
var t = _tuners[tuner.Value];
|
||||
|
||||
if (t == null)
|
||||
{
|
||||
Debug.Console(1, this, "Unable to find tuner with key: {0}", tuner.Value);
|
||||
continue;
|
||||
}
|
||||
|
||||
var join = joinMap.CurrentPreset.JoinNumber + tuner.Key;
|
||||
trilist.SetStringSigAction(join, s => _tunerPresets.Dial(s, t));
|
||||
Debug.Console(1, this, "Linked preset recall action for tuner: {0} to serial join: {1}", tuner.Value, join);
|
||||
}
|
||||
|
||||
//foreach (var setTopBox in _tuners)
|
||||
//{
|
||||
// var tuner = setTopBox;
|
||||
|
||||
// trilist.SetStringSigAction(joinMap.CurrentPreset.JoinNumber + i, s => _tunerPresets.Dial(s, tuner.Value));
|
||||
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private class EssentialsTechRoomJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
[JoinName("currentPreset")]
|
||||
public JoinDataComplete CurrentPreset = new JoinDataComplete(new JoinData {JoinNumber = 1, JoinSpan = 16},
|
||||
new JoinMetadata {Description = "Current Tuner Preset", JoinType = eJoinType.Serial});
|
||||
|
||||
public EssentialsTechRoomJoinMap(uint joinStart) : base(joinStart, typeof(EssentialsTechRoomJoinMap))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#region IRunDirectRouteAction Members
|
||||
|
||||
private void RunDirectRoute(IRoutingOutputs source, IRoutingSink dest)
|
||||
{
|
||||
if (dest == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", dest.Key);
|
||||
return;
|
||||
}
|
||||
|
||||
if (source == null)
|
||||
{
|
||||
dest.ReleaseRoute();
|
||||
if (dest is IHasPowerControl)
|
||||
(dest as IHasPowerControl).PowerOff();
|
||||
}
|
||||
else
|
||||
{
|
||||
dest.ReleaseAndMakeRoute(source, eRoutingSignalType.Video);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to route directly between a source and destination
|
||||
/// </summary>
|
||||
/// <param name="sourceKey"></param>
|
||||
/// <param name="destinationKey"></param>
|
||||
public void RunDirectRoute(string sourceKey, string destinationKey)
|
||||
{
|
||||
IRoutingSink dest = null;
|
||||
|
||||
dest = DeviceManager.GetDeviceForKey(destinationKey) as IRoutingSink;
|
||||
|
||||
var source = DeviceManager.GetDeviceForKey(sourceKey) as IRoutingOutputs;
|
||||
|
||||
if (source == null || dest == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot route unknown source or destination '{0}' to {1}", sourceKey, destinationKey);
|
||||
return;
|
||||
}
|
||||
RunDirectRoute(source, dest);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class ScheduledEventEventArgs : EventArgs
|
||||
{
|
||||
public List<ScheduledEventConfig> ScheduledEvents;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Crestron.SimplSharp.Net.Http;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
@@ -16,12 +13,12 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
HttpServer Server;
|
||||
readonly HttpServer _server;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
string FileDirectory;
|
||||
readonly string _fileDirectory;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@@ -45,18 +42,17 @@ namespace PepperDash.Essentials
|
||||
//{ ".js", "application/javascript" },
|
||||
//{ ".json", "application/json" },
|
||||
//{ ".map", "application/x-navimap" },
|
||||
{ ".pdf", "application.pdf" },
|
||||
{ ".pdf", "application/pdf" },
|
||||
{ ".png", "image/png" },
|
||||
//{ ".txt", "text/plain" },
|
||||
};
|
||||
|
||||
Server = new HttpServer();
|
||||
Server.Port = port;
|
||||
FileDirectory = directory;
|
||||
Server.OnHttpRequest += new OnHttpRequestHandler(Server_OnHttpRequest);
|
||||
Server.Open();
|
||||
_server = new HttpServer {Port = port};
|
||||
_fileDirectory = directory;
|
||||
_server.OnHttpRequest += Server_OnHttpRequest;
|
||||
_server.Open();
|
||||
|
||||
CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
|
||||
CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -67,27 +63,40 @@ namespace PepperDash.Essentials
|
||||
var path = args.Request.Path;
|
||||
Debug.Console(2, "HTTP Request with path: '{0}'", args.Request.Path);
|
||||
|
||||
if (File.Exists(FileDirectory + path))
|
||||
try
|
||||
{
|
||||
string filePath = path.Replace('/', '\\');
|
||||
string localPath = string.Format(@"{0}{1}", FileDirectory, filePath);
|
||||
|
||||
Debug.Console(2, "HTTP Logo Server attempting to find file: '{0}'", localPath);
|
||||
if (File.Exists(localPath))
|
||||
if (File.Exists(_fileDirectory + path))
|
||||
{
|
||||
args.Response.Header.ContentType = GetContentType(new FileInfo(localPath).Extension);
|
||||
args.Response.ContentStream = new FileStream(localPath, FileMode.Open, FileAccess.Read);
|
||||
var filePath = path.Replace('/', '\\');
|
||||
var localPath = string.Format(@"{0}{1}", _fileDirectory, filePath);
|
||||
|
||||
Debug.Console(2, "HTTP Logo Server attempting to find file: '{0}'", localPath);
|
||||
if (File.Exists(localPath))
|
||||
{
|
||||
args.Response.Header.ContentType = GetContentType(new FileInfo(localPath).Extension);
|
||||
args.Response.ContentStream = new FileStream(localPath, FileMode.Open, FileAccess.Read);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(2, "HTTP Logo Server Cannot find file '{0}'", localPath);
|
||||
args.Response.ContentString = string.Format("Not found: '{0}'", filePath);
|
||||
args.Response.Code = 404;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(2, "HTTP Logo Server Cannot find file '{0}'", localPath);
|
||||
args.Response.ContentString = string.Format("Not found: '{0}'", filePath);
|
||||
Debug.Console(2, "HTTP Logo Server: '{0}' does not exist", _fileDirectory + path);
|
||||
args.Response.ContentString = string.Format("Not found: '{0}'", _fileDirectory + path);
|
||||
args.Response.Code = 404;
|
||||
}
|
||||
}
|
||||
else
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.Console(2, "HTTP Logo Server: '{0}' does not exist", FileDirectory + path);
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Exception getting file: {0}", ex.Message);
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Stack Trace: {0}", ex.StackTrace);
|
||||
|
||||
args.Response.Code = 400;
|
||||
args.Response.ContentString = string.Format("invalid request");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +106,7 @@ namespace PepperDash.Essentials
|
||||
void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
|
||||
{
|
||||
if (programEventType == eProgramStatusEventType.Stopping)
|
||||
Server.Close();
|
||||
_server.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -107,11 +116,7 @@ namespace PepperDash.Essentials
|
||||
/// <returns></returns>
|
||||
public static string GetContentType(string extension)
|
||||
{
|
||||
string type;
|
||||
if (ExtensionContentTypes.ContainsKey(extension))
|
||||
type = ExtensionContentTypes[extension];
|
||||
else
|
||||
type = "text/plain";
|
||||
var type = ExtensionContentTypes.ContainsKey(extension) ? ExtensionContentTypes[extension] : "text/plain";
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,14 +120,22 @@ namespace PepperDash.Essentials
|
||||
/// 1206
|
||||
/// </summary>
|
||||
public const uint VCRecentsVisible = 1206;
|
||||
/// <summary>
|
||||
/// 1207
|
||||
/// </summary>
|
||||
public const uint VCCameraVisible = 1207;
|
||||
|
||||
/// <summary>
|
||||
/// 1208
|
||||
/// </summary>
|
||||
public const uint VCSelfViewLayoutVisible = 1208;
|
||||
public const uint VCCameraAutoVisible = 1208;
|
||||
|
||||
/// <summary>
|
||||
/// 1209
|
||||
/// </summary>
|
||||
public const uint VCCameraManualVisible = 1209;
|
||||
|
||||
/// <summary>
|
||||
/// 1210
|
||||
/// </summary>
|
||||
public const uint VCCameraOffVisible = 1210;
|
||||
|
||||
/// <summary>
|
||||
/// 1211 - 1215
|
||||
/// </summary>
|
||||
@@ -225,6 +233,59 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public const uint VCMinMaxEnable = 1256;
|
||||
|
||||
/// <summary>
|
||||
/// 1260
|
||||
/// </summary>
|
||||
public const uint VCCameraModeBarVisible = 1260;
|
||||
|
||||
/// <summary>
|
||||
/// 1261
|
||||
/// </summary>
|
||||
public const uint VCCameraSelectBarWithoutModeVisible = 1261;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 1271
|
||||
/// </summary>
|
||||
public const uint VCCameraZoomIn = 1271;
|
||||
/// <summary>
|
||||
/// 1272
|
||||
/// </summary>
|
||||
public const uint VCCameraZoomOut = 1272;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 1280
|
||||
/// </summary>
|
||||
public const uint VCCameraPresetSavedLabelVisible = 1280;
|
||||
/// <summary>
|
||||
/// 1281
|
||||
/// </summary>
|
||||
public const uint VCCameraPreset1 = 1281;
|
||||
/// <summary>
|
||||
/// 1282
|
||||
/// </summary>
|
||||
public const uint VCCameraPreset2 = 1282;
|
||||
/// <summary>
|
||||
/// 1283
|
||||
/// </summary>
|
||||
public const uint VCCameraPreset3 = 1283;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 1291
|
||||
/// </summary>
|
||||
public const uint VCCameraPreset1Visible = 1291;
|
||||
/// <summary>
|
||||
/// 1292
|
||||
/// </summary>
|
||||
public const uint VCCameraPreset2Visible = 1292;
|
||||
/// <summary>
|
||||
/// 1293
|
||||
/// </summary>
|
||||
public const uint VCCameraPreset3Visible = 1293;
|
||||
|
||||
|
||||
// Letter joins start at 2921;
|
||||
|
||||
//******************************************************
|
||||
|
||||
@@ -33,6 +33,21 @@
|
||||
/// </summary>
|
||||
public const uint VCLayoutsList = 1205;
|
||||
|
||||
/// <summary>
|
||||
/// 1206 VC Camera Mode horizontal list
|
||||
/// </summary>
|
||||
public const uint VCCameraMode = 1206;
|
||||
|
||||
/// <summary>
|
||||
/// 1207 VC Camera Mode Dpad
|
||||
/// </summary>
|
||||
public const uint VCCameraDpad = 1207;
|
||||
|
||||
/// <summary>
|
||||
/// 1208 VC Camera Select
|
||||
/// </summary>
|
||||
public const uint VCCameraSelect = 1208;
|
||||
|
||||
|
||||
//******************************************************
|
||||
// General
|
||||
|
||||
@@ -41,6 +41,21 @@ namespace PepperDash.Essentials
|
||||
public const uint VCRecentListTimeTextStart = 1231;
|
||||
// RANGE IN USE
|
||||
public const uint VCRecentListTimeTextEnd = 1260;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 1281
|
||||
/// </summary>
|
||||
public const uint VCCameraPresetLabel1 = 1281;
|
||||
/// <summary>
|
||||
/// 1282
|
||||
/// </summary>
|
||||
public const uint VCCameraPresetLabel2 = 1282;
|
||||
/// <summary>
|
||||
/// 1283
|
||||
/// </summary>
|
||||
public const uint VCCameraPresetLabel3 = 1283;
|
||||
|
||||
/// <summary>
|
||||
/// 1291 - the current layout mode
|
||||
/// </summary>
|
||||
|
||||
@@ -349,7 +349,7 @@ namespace PepperDash.Essentials
|
||||
// Check if the popup interlock is shown, and if one of the header popups is current, then show the carets subpage
|
||||
if (e.IsShown)
|
||||
{
|
||||
if (e.NewJoin == Parent.EnvironmentDriver.BackgroundSubpageJoin)
|
||||
if (Parent.EnvironmentDriver != null && e.NewJoin == Parent.EnvironmentDriver.BackgroundSubpageJoin)
|
||||
headerPopupShown = true;
|
||||
else if (e.NewJoin == UIBoolJoin.HeaderActiveCallsListVisible)
|
||||
headerPopupShown = true;
|
||||
|
||||
@@ -1,80 +1,81 @@
|
||||
using System;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.UI;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.SmartObjects;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EssentialsPanelMainInterfaceDriver : PanelDriverBase
|
||||
{
|
||||
CTimer InactivityTimer;
|
||||
|
||||
/// <summary>
|
||||
/// Assign the appropriate A/V driver.
|
||||
/// Want to keep the AvDriver alive, because it may hold states
|
||||
/// </summary>
|
||||
public IAVDriver AvDriver { get; set; }
|
||||
|
||||
public EssentialsHeaderDriver HeaderDriver { get; set; }
|
||||
|
||||
public EssentialsEnvironmentDriver EnvironmentDriver { get; set; }
|
||||
|
||||
public PanelDriverBase CurrentChildDriver { get; private set; }
|
||||
|
||||
using System;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.UI;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.SmartObjects;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EssentialsPanelMainInterfaceDriver : PanelDriverBase, IHasScreenSaverController
|
||||
{
|
||||
CTimer InactivityTimer;
|
||||
|
||||
/// <summary>
|
||||
/// Assign the appropriate A/V driver.
|
||||
/// Want to keep the AvDriver alive, because it may hold states
|
||||
/// </summary>
|
||||
public IAVDriver AvDriver { get; set;}
|
||||
|
||||
public EssentialsHeaderDriver HeaderDriver { get; set; }
|
||||
|
||||
public EssentialsEnvironmentDriver EnvironmentDriver { get; set; }
|
||||
|
||||
public PanelDriverBase CurrentChildDriver { get; private set; }
|
||||
|
||||
public ScreenSaverController ScreenSaverController { get; set; }
|
||||
|
||||
private readonly long _timeoutMs;
|
||||
|
||||
CrestronTouchpanelPropertiesConfig Config;
|
||||
|
||||
/// <summary>
|
||||
/// The main interlock for popups
|
||||
/// </summary>
|
||||
//public JoinedSigInterlock PopupInterlock { get; private set; }
|
||||
|
||||
public EssentialsPanelMainInterfaceDriver(BasicTriListWithSmartObject trilist,
|
||||
CrestronTouchpanelPropertiesConfig config)
|
||||
: base(trilist)
|
||||
{
|
||||
Config = config;
|
||||
|
||||
_timeoutMs = Config.ScreenSaverTimeoutMin * 60 * 1000;
|
||||
|
||||
var tsx52or60 = trilist as Tswx52ButtonVoiceControl;
|
||||
|
||||
private readonly long _timeoutMs;
|
||||
|
||||
CrestronTouchpanelPropertiesConfig Config;
|
||||
|
||||
/// <summary>
|
||||
/// The main interlock for popups
|
||||
/// </summary>
|
||||
//public JoinedSigInterlock PopupInterlock { get; private set; }
|
||||
|
||||
public EssentialsPanelMainInterfaceDriver(BasicTriListWithSmartObject trilist,
|
||||
CrestronTouchpanelPropertiesConfig config)
|
||||
: base(trilist)
|
||||
{
|
||||
Config = config;
|
||||
|
||||
_timeoutMs = Config.ScreenSaverTimeoutMin * 60 * 1000;
|
||||
|
||||
var tsx52or60 = trilist as Tswx52ButtonVoiceControl;
|
||||
|
||||
if (tsx52or60 != null)
|
||||
{
|
||||
tsx52or60.ExtenderTouchDetectionReservedSigs.Use();
|
||||
tsx52or60.ExtenderTouchDetectionReservedSigs.DeviceExtenderSigChange += ExtenderTouchDetectionReservedSigs_DeviceExtenderSigChange;
|
||||
tsx52or60.ExtenderTouchDetectionReservedSigs.Time.UShortValue = 1;
|
||||
ManageInactivityTimer();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var tswx70 = trilist as TswX70Base;
|
||||
if (tswx70 != null)
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var tswx70 = trilist as TswX70Base;
|
||||
if (tswx70 != null)
|
||||
{
|
||||
tswx70.ExtenderTouchDetectionReservedSigs.Use();
|
||||
tswx70.ExtenderTouchDetectionReservedSigs.DeviceExtenderSigChange += ExtenderTouchDetectionReservedSigs_DeviceExtenderSigChange;
|
||||
tswx70.ExtenderTouchDetectionReservedSigs.Time.UShortValue = 1;
|
||||
ManageInactivityTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ExtenderTouchDetectionReservedSigs_DeviceExtenderSigChange(Crestron.SimplSharpPro.DeviceExtender currentDeviceExtender, Crestron.SimplSharpPro.SigEventArgs args)
|
||||
{
|
||||
|
||||
ManageInactivityTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ExtenderTouchDetectionReservedSigs_DeviceExtenderSigChange(Crestron.SimplSharpPro.DeviceExtender currentDeviceExtender, Crestron.SimplSharpPro.SigEventArgs args)
|
||||
{
|
||||
|
||||
if (args.Sig.BoolValue)
|
||||
{
|
||||
ManageInactivityTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ManageInactivityTimer()
|
||||
@@ -87,46 +88,52 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
InactivityTimer = new CTimer((o) => InactivityTimerExpired(), _timeoutMs);
|
||||
}
|
||||
}
|
||||
|
||||
void InactivityTimerExpired()
|
||||
{
|
||||
InactivityTimer.Stop();
|
||||
InactivityTimer.Dispose();
|
||||
InactivityTimer = null;
|
||||
|
||||
ScreenSaverController.Show();
|
||||
}
|
||||
|
||||
public override void Show()
|
||||
{
|
||||
CurrentChildDriver = null;
|
||||
ShowSubDriver(AvDriver as PanelDriverBase);
|
||||
base.Show();
|
||||
}
|
||||
|
||||
public override void Hide()
|
||||
{
|
||||
TriList.BooleanInput[AvDriver.StartPageVisibleJoin].BoolValue = false;
|
||||
base.Hide();
|
||||
}
|
||||
|
||||
void ShowSubDriver(PanelDriverBase driver)
|
||||
{
|
||||
CurrentChildDriver = driver;
|
||||
if (driver == null)
|
||||
return;
|
||||
this.Hide();
|
||||
driver.Show();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void BackButtonPressed()
|
||||
{
|
||||
if(CurrentChildDriver != null)
|
||||
CurrentChildDriver.BackButtonPressed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InactivityTimerExpired()
|
||||
{
|
||||
InactivityTimer.Stop();
|
||||
InactivityTimer.Dispose();
|
||||
InactivityTimer = null;
|
||||
|
||||
ScreenSaverController.Show();
|
||||
}
|
||||
|
||||
public override void Show()
|
||||
{
|
||||
CurrentChildDriver = null;
|
||||
ShowSubDriver(AvDriver as PanelDriverBase);
|
||||
|
||||
base.Show();
|
||||
}
|
||||
|
||||
public override void Hide()
|
||||
{
|
||||
TriList.BooleanInput[AvDriver.StartPageVisibleJoin].BoolValue = false;
|
||||
base.Hide();
|
||||
}
|
||||
|
||||
void ShowSubDriver(PanelDriverBase driver)
|
||||
{
|
||||
CurrentChildDriver = driver;
|
||||
if (driver == null)
|
||||
return;
|
||||
this.Hide();
|
||||
driver.Show();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void BackButtonPressed()
|
||||
{
|
||||
if(CurrentChildDriver != null)
|
||||
CurrentChildDriver.BackButtonPressed();
|
||||
}
|
||||
}
|
||||
|
||||
public interface IHasScreenSaverController
|
||||
{
|
||||
ScreenSaverController ScreenSaverController { get; }
|
||||
}
|
||||
}
|
||||
@@ -114,7 +114,7 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
/// The parent driver for this
|
||||
/// </summary>
|
||||
PanelDriverBase Parent;
|
||||
public PanelDriverBase Parent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// All children attached to this driver. For hiding and showing as a group.
|
||||
@@ -305,9 +305,9 @@ namespace PepperDash.Essentials
|
||||
TriList.SetSigFalseAction(UIBoolJoin.ShowPowerOffPress, EndMeetingPress);
|
||||
|
||||
TriList.SetSigFalseAction(UIBoolJoin.DisplayPowerTogglePress, () =>
|
||||
{
|
||||
if (CurrentRoom != null && CurrentRoom.DefaultDisplay is IPower)
|
||||
(CurrentRoom.DefaultDisplay as IPower).PowerToggle();
|
||||
{
|
||||
if (CurrentRoom != null && CurrentRoom.DefaultDisplay is IHasPowerControl)
|
||||
(CurrentRoom.DefaultDisplay as IHasPowerControl).PowerToggle();
|
||||
});
|
||||
|
||||
base.Show();
|
||||
@@ -984,8 +984,8 @@ namespace PepperDash.Essentials
|
||||
(previousDev as IDvr).UnlinkButtons(TriList);
|
||||
if (previousDev is INumericKeypad)
|
||||
(previousDev as INumericKeypad).UnlinkButtons(TriList);
|
||||
if (previousDev is IPower)
|
||||
(previousDev as IPower).UnlinkButtons(TriList);
|
||||
if (previousDev is IHasPowerControl)
|
||||
(previousDev as IHasPowerControl).UnlinkButtons(TriList);
|
||||
if (previousDev is ITransport)
|
||||
(previousDev as ITransport).UnlinkButtons(TriList);
|
||||
//if (previousDev is IRadio)
|
||||
@@ -1044,8 +1044,8 @@ namespace PepperDash.Essentials
|
||||
(dev as IDvr).LinkButtons(TriList);
|
||||
if (dev is INumericKeypad)
|
||||
(dev as INumericKeypad).LinkButtons(TriList);
|
||||
if (dev is IPower)
|
||||
(dev as IPower).LinkButtons(TriList);
|
||||
if (dev is IHasPowerControl)
|
||||
(dev as IHasPowerControl).LinkButtons(TriList);
|
||||
if (dev is ITransport)
|
||||
(dev as ITransport).LinkButtons(TriList);
|
||||
//if (dev is IRadio)
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
/// The parent driver for this
|
||||
/// </summary>
|
||||
PanelDriverBase Parent;
|
||||
public PanelDriverBase Parent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// All children attached to this driver. For hiding and showing as a group.
|
||||
@@ -319,8 +319,8 @@ namespace PepperDash.Essentials
|
||||
|
||||
TriList.SetSigFalseAction(UIBoolJoin.DisplayPowerTogglePress, () =>
|
||||
{
|
||||
if (CurrentRoom != null && CurrentRoom.DefaultDisplay is IPower)
|
||||
(CurrentRoom.DefaultDisplay as IPower).PowerToggle();
|
||||
if (CurrentRoom != null && CurrentRoom.DefaultDisplay is IHasPowerControl)
|
||||
(CurrentRoom.DefaultDisplay as IHasPowerControl).PowerToggle();
|
||||
});
|
||||
|
||||
SetupNextMeetingTimer();
|
||||
@@ -1293,8 +1293,8 @@ namespace PepperDash.Essentials
|
||||
(previousDev as IDvr).UnlinkButtons(TriList);
|
||||
if (previousDev is INumericKeypad)
|
||||
(previousDev as INumericKeypad).UnlinkButtons(TriList);
|
||||
if (previousDev is IPower)
|
||||
(previousDev as IPower).UnlinkButtons(TriList);
|
||||
if (previousDev is IHasPowerControl)
|
||||
(previousDev as IHasPowerControl).UnlinkButtons(TriList);
|
||||
if (previousDev is ITransport)
|
||||
(previousDev as ITransport).UnlinkButtons(TriList);
|
||||
}
|
||||
@@ -1351,8 +1351,8 @@ namespace PepperDash.Essentials
|
||||
(dev as IDvr).LinkButtons(TriList);
|
||||
if (dev is INumericKeypad)
|
||||
(dev as INumericKeypad).LinkButtons(TriList);
|
||||
if (dev is IPower)
|
||||
(dev as IPower).LinkButtons(TriList);
|
||||
if (dev is IHasPowerControl)
|
||||
(dev as IHasPowerControl).LinkButtons(TriList);
|
||||
if (dev is ITransport)
|
||||
(dev as ITransport).LinkButtons(TriList);
|
||||
}
|
||||
@@ -1430,6 +1430,7 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public interface IAVDriver
|
||||
{
|
||||
PanelDriverBase Parent { get; }
|
||||
JoinedSigInterlock PopupInterlock { get; }
|
||||
void ShowNotificationRibbon(string message, int timeout);
|
||||
void HideNotificationRibbon();
|
||||
|
||||
@@ -18,9 +18,11 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
/// The parent driver for this
|
||||
/// </summary>
|
||||
EssentialsPanelMainInterfaceDriver Parent;
|
||||
private readonly EssentialsPanelMainInterfaceDriver _parent;
|
||||
|
||||
|
||||
private JoinedSigInterlock PositionInterlock;
|
||||
|
||||
CTimer PositionTimer;
|
||||
|
||||
uint PositionTimeoutMs;
|
||||
@@ -32,34 +34,56 @@ namespace PepperDash.Essentials
|
||||
public ScreenSaverController(EssentialsPanelMainInterfaceDriver parent, CrestronTouchpanelPropertiesConfig config)
|
||||
: base(parent.TriList)
|
||||
{
|
||||
Parent = parent;
|
||||
_parent = parent;
|
||||
|
||||
PositionTimeoutMs = config.ScreenSaverMovePositionIntervalMs;
|
||||
|
||||
TriList.SetSigFalseAction(UIBoolJoin.MCScreenSaverClosePress, () => this.Hide());
|
||||
PositionJoins = new List<uint>() { UIBoolJoin.MCScreenSaverPosition1Visible, UIBoolJoin.MCScreenSaverPosition2Visible, UIBoolJoin.MCScreenSaverPosition3Visible, UIBoolJoin.MCScreenSaverPosition4Visible };
|
||||
|
||||
PositionInterlock = new JoinedSigInterlock(parent.TriList);
|
||||
|
||||
var cmdName = String.Format("shwscrsvr-{0}", parent.TriList.ID);
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand((o) => Show(), cmdName, "Shows Panel Screensaver", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
TriList.SetSigFalseAction(UIBoolJoin.MCScreenSaverClosePress, Hide);
|
||||
}
|
||||
|
||||
public override void Show()
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.MCScreenSaverVisible, true);
|
||||
Parent.AvDriver.PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.MCScreenSaverVisible);
|
||||
//TriList.SetBool(UIBoolJoin.MCScreenSaverVisible, true);
|
||||
if (_parent.AvDriver != null)
|
||||
{
|
||||
_parent.AvDriver.PopupInterlock.ShowInterlocked(UIBoolJoin.MCScreenSaverVisible);
|
||||
}
|
||||
|
||||
CurrentPositionIndex = 0;
|
||||
SetCurrentPosition();
|
||||
ShowCurrentPosition();
|
||||
StartPositionTimer();
|
||||
|
||||
base.Show();
|
||||
}
|
||||
|
||||
public override void Hide()
|
||||
{
|
||||
Debug.Console(1, "Hiding ScreenSaverController");
|
||||
|
||||
if (PositionTimer != null)
|
||||
{
|
||||
PositionTimer.Stop();
|
||||
PositionTimer.Dispose();
|
||||
PositionTimer = null;
|
||||
}
|
||||
|
||||
ClearAllPositions();
|
||||
|
||||
TriList.SetBool(UIBoolJoin.MCScreenSaverVisible, false);
|
||||
Parent.AvDriver.PopupInterlock.HideAndClear();
|
||||
//TriList.SetBool(UIBoolJoin.MCScreenSaverVisible, false);
|
||||
if (_parent.AvDriver != null)
|
||||
{
|
||||
_parent.AvDriver.PopupInterlock.HideAndClear();
|
||||
}
|
||||
|
||||
base.Hide();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void StartPositionTimer()
|
||||
{
|
||||
if (PositionTimer == null)
|
||||
@@ -77,7 +101,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
IncrementPositionIndex();
|
||||
|
||||
SetCurrentPosition();
|
||||
ShowCurrentPosition();
|
||||
|
||||
StartPositionTimer();
|
||||
}
|
||||
@@ -97,20 +121,16 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
|
||||
//
|
||||
void SetCurrentPosition()
|
||||
void ShowCurrentPosition()
|
||||
{
|
||||
ClearAllPositions();
|
||||
|
||||
// Set based on current index
|
||||
TriList.SetBool(PositionJoins[CurrentPositionIndex], true);
|
||||
PositionInterlock.ShowInterlocked(PositionJoins[CurrentPositionIndex]);
|
||||
}
|
||||
|
||||
void ClearAllPositions()
|
||||
{
|
||||
foreach (var join in PositionJoins)
|
||||
{
|
||||
TriList.SetBool(join, false);
|
||||
}
|
||||
Debug.Console(1, "Hiding all screensaver positions");
|
||||
PositionInterlock.HideAndClear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
using PepperDash.Core;
|
||||
@@ -13,6 +14,7 @@ using PepperDash.Essentials.Core.SmartObjects;
|
||||
using PepperDash.Essentials.Core.Touchpanels.Keyboards;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||
|
||||
namespace PepperDash.Essentials.UIDrivers.VC
|
||||
{
|
||||
@@ -41,6 +43,11 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
/// </summary>
|
||||
JoinedSigInterlock VCControlsInterlock;
|
||||
|
||||
/// <summary>
|
||||
/// For the camera control mode (auto/manual/off)
|
||||
/// </summary>
|
||||
JoinedSigInterlock VCCameraControlModeInterlock;
|
||||
|
||||
/// <summary>
|
||||
/// For the different staging bars: Active, inactive
|
||||
/// </summary>
|
||||
@@ -58,6 +65,12 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
SmartObjectDynamicList RecentCallsList;
|
||||
|
||||
SmartObjectDynamicList DirectoryList;
|
||||
|
||||
SmartObjectDPad CameraPtzPad;
|
||||
|
||||
SmartObjectDynamicList CameraModeList;
|
||||
|
||||
SmartObjectDynamicList CameraSelectList;
|
||||
|
||||
BoolFeedback DirectoryBackButtonVisibleFeedback;
|
||||
|
||||
@@ -76,6 +89,8 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
|
||||
bool CodecHasFavorites;
|
||||
|
||||
bool ShowCameraModeControls;
|
||||
|
||||
CTimer BackspaceTimer;
|
||||
|
||||
|
||||
@@ -118,6 +133,9 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
LocalPrivacyIsMuted = new BoolFeedback(() => false);
|
||||
|
||||
VCControlsInterlock = new JoinedSigInterlock(triList);
|
||||
VCCameraControlModeInterlock = new JoinedSigInterlock(triList);
|
||||
|
||||
|
||||
if (CodecHasFavorites)
|
||||
VCControlsInterlock.SetButDontShow(UIBoolJoin.VCKeypadWithFavoritesVisible);
|
||||
else
|
||||
@@ -161,6 +179,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
|
||||
SetupDirectoryList();
|
||||
|
||||
|
||||
SearchStringBackspaceVisibleFeedback = new BoolFeedback(() => SearchStringBuilder.Length > 0);
|
||||
SearchStringBackspaceVisibleFeedback.LinkInputSig(triList.BooleanInput[UIBoolJoin.VCDirectoryBackspaceVisible]);
|
||||
|
||||
@@ -196,6 +215,8 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
|
||||
if(HeaderDriver.HeaderButtonsAreSetUp)
|
||||
HeaderDriver.ComputeHeaderCallStatus(Codec);
|
||||
|
||||
SetupCameraControls();
|
||||
}
|
||||
|
||||
void SetupAddresses()
|
||||
@@ -377,6 +398,8 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
/// </summary>
|
||||
void ShowIncomingModal(CodecActiveCallItem call)
|
||||
{
|
||||
Debug.Console(1, "Showing Incoming Call Modal");
|
||||
|
||||
(Parent as IAVWithVCDriver).PrepareForCodecIncomingCall();
|
||||
IncomingCallModal = new ModalDialog(TriList);
|
||||
string msg;
|
||||
@@ -392,13 +415,19 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
msg = string.Format("Incoming video call from: {0}", call.Name);
|
||||
}
|
||||
|
||||
if (Parent.PopupInterlock.IsShown)
|
||||
|
||||
// Hide screensaver
|
||||
var screenSaverParent = Parent.Parent as IHasScreenSaverController;
|
||||
|
||||
if (screenSaverParent != null)
|
||||
{
|
||||
if (Parent.PopupInterlock.CurrentJoin == UIBoolJoin.MCScreenSaverVisible)
|
||||
{
|
||||
Parent.PopupInterlock.HideAndClear();
|
||||
}
|
||||
screenSaverParent.ScreenSaverController.Hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, "Parent.Parent is null or does not implement IHasScreenSaverController");
|
||||
}
|
||||
|
||||
|
||||
IncomingCallModal.PresentModalDialog(2, "Incoming Call", icon, msg,
|
||||
"Ignore", "Accept", false, false, b =>
|
||||
@@ -450,6 +479,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
TriList.SetSigFalseAction(UIBoolJoin.VCStagingDirectoryPress, ShowDirectory);
|
||||
TriList.SetSigFalseAction(UIBoolJoin.VCStagingKeypadPress, ShowKeypad);
|
||||
TriList.SetSigFalseAction(UIBoolJoin.VCStagingRecentsPress, ShowRecents);
|
||||
TriList.SetSigFalseAction(UIBoolJoin.VCStagingCameraPress, ShowCameraControls);
|
||||
TriList.SetSigFalseAction(UIBoolJoin.VCStagingConnectPress, ConnectPress);
|
||||
TriList.SetSigFalseAction(UIBoolJoin.CallEndPress, () =>
|
||||
{
|
||||
@@ -467,6 +497,393 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
});
|
||||
}
|
||||
|
||||
void SetupCameraControls()
|
||||
{
|
||||
CameraPtzPad = new SmartObjectDPad(TriList.SmartObjects[UISmartObjectJoin.VCCameraDpad], true);
|
||||
|
||||
// If the codec supports camera auto or off, we need to show the mode selector subpage
|
||||
ShowCameraModeControls = Codec is IHasCameraAutoMode || Codec is IHasCameraOff;
|
||||
|
||||
if (ShowCameraModeControls)
|
||||
{
|
||||
CameraModeList = new SmartObjectDynamicList(TriList.SmartObjects[UISmartObjectJoin.VCCameraMode], true, 0);
|
||||
|
||||
VCControlsInterlock.StatusChanged += new EventHandler<StatusChangedEventArgs>(VCControlsInterlock_StatusChanged);
|
||||
|
||||
|
||||
var codecOffCameras = Codec as IHasCameraOff;
|
||||
|
||||
var codecAutoCameras = Codec as IHasCameraAutoMode;
|
||||
|
||||
if (codecAutoCameras != null)
|
||||
{
|
||||
CameraModeList.SetItemButtonAction(1,(b) => codecAutoCameras.CameraAutoModeOn());
|
||||
TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanInput["Item 1 Visible"].BoolValue = true;
|
||||
codecAutoCameras.CameraAutoModeIsOnFeedback.LinkInputSig(CameraModeList.SmartObject.BooleanInput["Item 1 Selected"]);
|
||||
//TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanOutput["Item 1 Pressed"].SetSigFalseAction(
|
||||
//() => codecAutoCameras.CameraAutoModeOn());
|
||||
|
||||
|
||||
codecAutoCameras.CameraAutoModeIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (a.BoolValue)
|
||||
{
|
||||
SetCameraManualModeButtonFeedback(false);
|
||||
|
||||
if (VCControlsInterlock.CurrentJoin == UIBoolJoin.VCCameraModeBarVisible)
|
||||
{
|
||||
VCCameraControlModeInterlock.ShowInterlocked(UIBoolJoin.VCCameraAutoVisible);
|
||||
}
|
||||
else
|
||||
{
|
||||
VCCameraControlModeInterlock.SetButDontShow(UIBoolJoin.VCCameraAutoVisible);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowCameraManualMode();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
// Manual button always visible
|
||||
CameraModeList.SetItemButtonAction(2, (b) => ShowCameraManualMode());
|
||||
|
||||
TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanInput["Item 2 Visible"].BoolValue = true;
|
||||
//TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanOutput["Item 2 Pressed"].SetSigFalseAction(
|
||||
// () => ShowCameraManualMode());
|
||||
|
||||
if (codecOffCameras != null)
|
||||
{
|
||||
TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanInput["Item 3 Visible"].BoolValue = true;
|
||||
codecOffCameras.CameraIsOffFeedback.LinkInputSig(CameraModeList.SmartObject.BooleanInput["Item 3 Selected"]);
|
||||
CameraModeList.SetItemButtonAction(3, (b) => codecOffCameras.CameraOff());
|
||||
//TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanOutput["Item 3 Pressed"].SetSigFalseAction(
|
||||
// () => codecOffCameras.CameraOff());
|
||||
|
||||
codecOffCameras.CameraIsOffFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (a.BoolValue)
|
||||
{
|
||||
SetCameraManualModeButtonFeedback(false);
|
||||
|
||||
if (VCControlsInterlock.CurrentJoin == UIBoolJoin.VCCameraModeBarVisible)
|
||||
{
|
||||
VCCameraControlModeInterlock.ShowInterlocked(UIBoolJoin.VCCameraOffVisible);
|
||||
}
|
||||
else
|
||||
{
|
||||
VCCameraControlModeInterlock.SetButDontShow(UIBoolJoin.VCCameraOffVisible);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowCameraManualMode();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
var camerasCodec = Codec as IHasCameras;
|
||||
|
||||
if(camerasCodec != null)
|
||||
{
|
||||
//CameraSelectList = new SmartObjectDynamicList(TriList.SmartObjects[UISmartObjectJoin.VCCameraSelect], true, 0);
|
||||
|
||||
var so = TriList.SmartObjects[UISmartObjectJoin.VCCameraSelect];
|
||||
|
||||
so.SigChange += SmartObject_SigChange;
|
||||
|
||||
for (uint i = 1; i <= camerasCodec.Cameras.Count; i++)
|
||||
{
|
||||
var cameraKey = camerasCodec.Cameras[(int)i - 1].Key;
|
||||
Debug.Console(1, "Setting up action for Camera {0} with Key: {1} for button Item {0} Pressed", i, cameraKey);
|
||||
|
||||
//TODO: Fix camera selection action. For some reson this action doesn't execute when the buttons are pressed
|
||||
|
||||
var sig = so.BooleanOutput[String.Format("Item {0} Pressed", i)];
|
||||
|
||||
so.BooleanOutput[string.Format("Item {0} Pressed", i)].SetSigFalseAction(
|
||||
() => camerasCodec.SelectCamera(cameraKey));
|
||||
}
|
||||
|
||||
so.UShortInput["Set Number of Items"].UShortValue = (ushort)camerasCodec.Cameras.Count;
|
||||
//TriList.SmartObjects[UISmartObjectJoin.VCCameraSelect].UShortOutput["Item Clicked"].SetUShortSigAction(
|
||||
// (u) =>
|
||||
// {
|
||||
// var cameraKey = camerasCodec.Cameras[u - 1].Key;
|
||||
// Debug.Console(1, "Selecting Camera {0} with Key: {1}", u, cameraKey);
|
||||
// camerasCodec.SelectCamera(cameraKey);
|
||||
// });
|
||||
|
||||
|
||||
// Set the names for the cameras
|
||||
for (int i = 1; i <= camerasCodec.Cameras.Count; i++)
|
||||
{
|
||||
so.StringInput[string.Format("Set Item {0} Text", i)].StringValue = camerasCodec.Cameras[i - 1].Name;
|
||||
}
|
||||
|
||||
SetCameraSelectedFeedback();
|
||||
camerasCodec.CameraSelected += camerasCodec_CameraSelected;
|
||||
MapCameraActions();
|
||||
}
|
||||
|
||||
SetupPresets();
|
||||
|
||||
}
|
||||
|
||||
void SmartObject_SigChange(GenericBase currentDevice, SmartObjectEventArgs args)
|
||||
{
|
||||
var uo = args.Sig.UserObject;
|
||||
if (uo is Action<bool>)
|
||||
(uo as Action<bool>)(args.Sig.BoolValue);
|
||||
else if (uo is Action<ushort>)
|
||||
(uo as Action<ushort>)(args.Sig.UShortValue);
|
||||
else if (uo is Action<string>)
|
||||
(uo as Action<string>)(args.Sig.StringValue);
|
||||
}
|
||||
|
||||
void VCControlsInterlock_StatusChanged(object sender, StatusChangedEventArgs e)
|
||||
{
|
||||
// Need to hide the camera mode interlock if the mode bar gets hidden
|
||||
if (e.PreviousJoin == UIBoolJoin.VCCameraModeBarVisible)
|
||||
VCCameraControlModeInterlock.Hide();
|
||||
|
||||
// These deal with hiding/showing the camera select bar if no mode controls are visible (tied to manual controls being visible)
|
||||
if(!ShowCameraModeControls)
|
||||
{
|
||||
if(e.PreviousJoin == UIBoolJoin.VCCameraManualVisible)
|
||||
TriList.SetBool(UIBoolJoin.VCCameraSelectBarWithoutModeVisible, false);
|
||||
|
||||
if (e.NewJoin == UIBoolJoin.VCCameraManualVisible)
|
||||
TriList.SetBool(UIBoolJoin.VCCameraSelectBarWithoutModeVisible, true);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Shows the preset saved label for 2 seconds
|
||||
/// </summary>
|
||||
void ShowPresetStoreFeedback()
|
||||
{
|
||||
TriList.BooleanInput[UIBoolJoin.VCCameraPresetSavedLabelVisible].BoolValue = true;
|
||||
|
||||
var timer = new CTimer((o) => TriList.BooleanInput[UIBoolJoin.VCCameraPresetSavedLabelVisible].BoolValue = false, 2000);
|
||||
}
|
||||
|
||||
void presetsCodec_CodecRoomPresetsListHasChanged(object sender, EventArgs e)
|
||||
{
|
||||
SetupPresets();
|
||||
}
|
||||
|
||||
|
||||
void camerasCodec_CameraSelected(object sender, CameraSelectedEventArgs e)
|
||||
{
|
||||
MapCameraActions();
|
||||
|
||||
SetCameraSelectedFeedback();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the feedback for the button of the selected camera
|
||||
/// </summary>
|
||||
void SetCameraSelectedFeedback()
|
||||
{
|
||||
var camerasCodec = Codec as IHasCameras;
|
||||
|
||||
for (int i = 1; i <= camerasCodec.Cameras.Count; i++)
|
||||
{
|
||||
var cameraSelected = camerasCodec.SelectedCameraFeedback.StringValue;
|
||||
var state = false;
|
||||
if (cameraSelected == camerasCodec.Cameras[i - 1].Key)
|
||||
{
|
||||
state = true;
|
||||
}
|
||||
|
||||
TriList.SmartObjects[UISmartObjectJoin.VCCameraSelect].BooleanInput[string.Format("Item {0} Selected", i)].BoolValue = state;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SetupPresets()
|
||||
{
|
||||
var presetsCodec = Codec as IHasCodecRoomPresets;
|
||||
if (presetsCodec != null)
|
||||
{
|
||||
uint holdTime = 5000;
|
||||
presetsCodec.CodecRoomPresetsListHasChanged += new EventHandler<EventArgs>(presetsCodec_CodecRoomPresetsListHasChanged);
|
||||
|
||||
var preset = 1;
|
||||
if (presetsCodec.NearEndPresets[preset - 1] != null && presetsCodec.NearEndPresets[preset - 1].Defined)
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.VCCameraPreset1Visible, true);
|
||||
TriList.BooleanOutput[UIBoolJoin.VCCameraPreset1].SetSigHeldAction(
|
||||
holdTime, ShowPresetStoreFeedback,() => presetsCodec.CodecRoomPresetStore(preset, presetsCodec.NearEndPresets[preset - 1].Description),
|
||||
() => presetsCodec.CodecRoomPresetSelect(preset));
|
||||
TriList.StringInput[UIStringJoin.VCCameraPresetLabel1].StringValue = presetsCodec.NearEndPresets[preset - 1].Description;
|
||||
}
|
||||
else
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.VCCameraPreset1Visible, false);
|
||||
}
|
||||
|
||||
if (presetsCodec.NearEndPresets[1] != null && presetsCodec.NearEndPresets[1].Defined)
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.VCCameraPreset2Visible, true);
|
||||
TriList.BooleanOutput[UIBoolJoin.VCCameraPreset2].SetSigHeldAction(
|
||||
holdTime, ShowPresetStoreFeedback, () => presetsCodec.CodecRoomPresetStore(preset, presetsCodec.NearEndPresets[preset - 1].Description),
|
||||
() => presetsCodec.CodecRoomPresetSelect(preset));
|
||||
TriList.StringInput[UIStringJoin.VCCameraPresetLabel2].StringValue = presetsCodec.NearEndPresets[1].Description;
|
||||
}
|
||||
else
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.VCCameraPreset2Visible, false);
|
||||
}
|
||||
|
||||
if (presetsCodec.NearEndPresets[2] != null && presetsCodec.NearEndPresets[2].Defined)
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.VCCameraPreset3Visible, true);
|
||||
TriList.BooleanOutput[UIBoolJoin.VCCameraPreset3].SetSigHeldAction(
|
||||
holdTime, ShowPresetStoreFeedback, () => presetsCodec.CodecRoomPresetStore(preset, presetsCodec.NearEndPresets[preset - 1].Description),
|
||||
() => presetsCodec.CodecRoomPresetSelect(preset));
|
||||
TriList.StringInput[UIStringJoin.VCCameraPresetLabel3].StringValue = presetsCodec.NearEndPresets[2].Description;
|
||||
}
|
||||
else
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.VCCameraPreset3Visible, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps button actions to the selected camera
|
||||
/// </summary>
|
||||
void MapCameraActions()
|
||||
{
|
||||
// Now we setup the button actions for the manual controls
|
||||
var camerasCodec = Codec as IHasCameras;
|
||||
|
||||
if (camerasCodec != null && camerasCodec.SelectedCamera != null)
|
||||
{
|
||||
|
||||
var dpad = CameraPtzPad;
|
||||
|
||||
var camera = camerasCodec.SelectedCamera as IHasCameraPtzControl;
|
||||
if (camera != null)
|
||||
{
|
||||
if (camerasCodec.SelectedCamera.CanTilt)
|
||||
{
|
||||
dpad.SigUp.SetBoolSigAction((b) =>
|
||||
{
|
||||
if (b)
|
||||
camera.TiltUp();
|
||||
else
|
||||
camera.TiltStop();
|
||||
});
|
||||
dpad.SigDown.SetBoolSigAction((b) =>
|
||||
{
|
||||
if (b)
|
||||
camera.TiltDown();
|
||||
else
|
||||
camera.TiltStop();
|
||||
});
|
||||
}
|
||||
|
||||
if (camerasCodec.SelectedCamera.CanPan)
|
||||
{
|
||||
dpad.SigLeft.SetBoolSigAction((b) =>
|
||||
{
|
||||
if (b)
|
||||
camera.PanLeft();
|
||||
else
|
||||
camera.PanStop();
|
||||
});
|
||||
dpad.SigRight.SetBoolSigAction((b) =>
|
||||
{
|
||||
if (b)
|
||||
camera.PanRight();
|
||||
else
|
||||
camera.PanStop();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//dpad.SigCenter.SetSigFalseAction(() => camera.PositionHome());
|
||||
|
||||
//var homeButton = dpad.BooleanOutput["Home"];
|
||||
//if (homeButton != null)
|
||||
//{
|
||||
// homeButton.SetSigFalseAction(() => camera.PositionHome());
|
||||
//}
|
||||
|
||||
if (camerasCodec.SelectedCamera.CanZoom)
|
||||
{
|
||||
TriList.BooleanOutput[UIBoolJoin.VCCameraZoomIn].SetBoolSigAction((b) =>
|
||||
{
|
||||
if (b)
|
||||
camera.ZoomIn();
|
||||
else
|
||||
camera.ZoomStop();
|
||||
});
|
||||
TriList.BooleanOutput[UIBoolJoin.VCCameraZoomOut].SetBoolSigAction((b) =>
|
||||
{
|
||||
if (b)
|
||||
camera.ZoomOut();
|
||||
else
|
||||
camera.ZoomStop();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Determines if codec is in manual camera control mode and shows feedback
|
||||
void ShowCameraManualMode()
|
||||
{
|
||||
var inManualMode = true;
|
||||
|
||||
var codecOffCameras = Codec as IHasCameraOff;
|
||||
|
||||
var codecAutoCameras = Codec as IHasCameraAutoMode;
|
||||
|
||||
if (codecOffCameras != null && codecOffCameras.CameraIsOffFeedback.BoolValue)
|
||||
{
|
||||
inManualMode = false;
|
||||
}
|
||||
|
||||
// Clear auto mode
|
||||
if (codecAutoCameras != null )
|
||||
{
|
||||
if (codecAutoCameras.CameraAutoModeIsOnFeedback.BoolValue)
|
||||
{
|
||||
codecAutoCameras.CameraAutoModeOff();
|
||||
inManualMode = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (inManualMode)
|
||||
{
|
||||
VCCameraControlModeInterlock.SetButDontShow(UIBoolJoin.VCCameraManualVisible);
|
||||
|
||||
if (VCControlsInterlock.CurrentJoin == UIBoolJoin.VCCameraModeBarVisible)
|
||||
VCCameraControlModeInterlock.Show();
|
||||
}
|
||||
|
||||
SetCameraManualModeButtonFeedback(inManualMode);
|
||||
|
||||
}
|
||||
|
||||
void SetCameraManualModeButtonFeedback(bool state)
|
||||
{
|
||||
// Set button feedback for manual mode
|
||||
TriList.SmartObjects[UISmartObjectJoin.VCCameraMode].BooleanInput["Item 2 Selected"].BoolValue = state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -927,7 +1344,32 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
/// </summary>
|
||||
void ShowCameraControls()
|
||||
{
|
||||
VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCCameraVisible);
|
||||
if (ShowCameraModeControls)
|
||||
{
|
||||
VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCCameraModeBarVisible);
|
||||
|
||||
if (VCCameraControlModeInterlock.CurrentJoin != 0)
|
||||
{
|
||||
VCCameraControlModeInterlock.Show();
|
||||
}
|
||||
else
|
||||
{
|
||||
var codecAutoCamera = Codec as IHasCameraAutoMode;
|
||||
if (codecAutoCamera != null)
|
||||
{
|
||||
ShowCameraManualMode();
|
||||
VCCameraControlModeInterlock.Show();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just show the manual camera control page
|
||||
VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCCameraManualVisible);
|
||||
}
|
||||
|
||||
|
||||
|
||||
StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingCameraPress);
|
||||
}
|
||||
|
||||
@@ -960,7 +1402,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
||||
/// </summary>
|
||||
void ShowSelfViewLayout()
|
||||
{
|
||||
VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCSelfViewLayoutVisible);
|
||||
VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCCameraAutoVisible);
|
||||
StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingSelfViewLayoutPress);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.Reflection;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.EthernetCommunication;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
@@ -76,15 +78,15 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
/// <summary>
|
||||
/// Bridge API using EISC
|
||||
/// </summary>
|
||||
public class EiscApiAdvanced : BridgeApi
|
||||
public class EiscApiAdvanced : BridgeApi, ICommunicationMonitor
|
||||
{
|
||||
public EiscApiPropertiesConfig PropertiesConfig { get; private set; }
|
||||
|
||||
protected Dictionary<string, JoinMapBaseAdvanced> JoinMaps { get; private set; }
|
||||
|
||||
public ThreeSeriesTcpIpEthernetIntersystemCommunications Eisc { get; private set; }
|
||||
public BasicTriList Eisc { get; private set; }
|
||||
|
||||
public EiscApiAdvanced(DeviceConfig dc) :
|
||||
public EiscApiAdvanced(DeviceConfig dc, BasicTriList eisc) :
|
||||
base(dc.Key)
|
||||
{
|
||||
JoinMaps = new Dictionary<string, JoinMapBaseAdvanced>();
|
||||
@@ -92,44 +94,107 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
PropertiesConfig = dc.Properties.ToObject<EiscApiPropertiesConfig>();
|
||||
//PropertiesConfig = JsonConvert.DeserializeObject<EiscApiPropertiesConfig>(dc.Properties.ToString());
|
||||
|
||||
Eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(PropertiesConfig.Control.IpIdInt, PropertiesConfig.Control.TcpSshProperties.Address, Global.ControlSystem);
|
||||
Eisc = eisc;
|
||||
|
||||
Eisc.SigChange += Eisc_SigChange;
|
||||
|
||||
AddPostActivationAction( () =>
|
||||
CommunicationMonitor = new CrestronGenericBaseCommunicationMonitor(this, Eisc, 120000, 300000);
|
||||
|
||||
AddPostActivationAction(LinkDevices);
|
||||
AddPostActivationAction(LinkRooms);
|
||||
AddPostActivationAction(RegisterEisc);
|
||||
}
|
||||
|
||||
public override bool CustomActivate()
|
||||
{
|
||||
CommunicationMonitor.Start();
|
||||
return base.CustomActivate();
|
||||
}
|
||||
|
||||
public override bool Deactivate()
|
||||
{
|
||||
CommunicationMonitor.Stop();
|
||||
return base.Deactivate();
|
||||
}
|
||||
|
||||
private void LinkDevices()
|
||||
{
|
||||
Debug.Console(1, this, "Linking Devices...");
|
||||
|
||||
if (PropertiesConfig.Devices == null)
|
||||
{
|
||||
Debug.Console(1, this, "Linking Devices...");
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "No devices linked to this bridge");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var d in PropertiesConfig.Devices)
|
||||
foreach (var d in PropertiesConfig.Devices)
|
||||
{
|
||||
var device = DeviceManager.GetDeviceForKey(d.DeviceKey);
|
||||
|
||||
if (device == null)
|
||||
{
|
||||
var device = DeviceManager.GetDeviceForKey(d.DeviceKey);
|
||||
|
||||
if (device == null) continue;
|
||||
|
||||
Debug.Console(1, this, "Linking Device: '{0}'", device.Key);
|
||||
|
||||
if (!typeof (IBridgeAdvanced).IsAssignableFrom(device.GetType().GetCType()))
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice,
|
||||
"{0} is not compatible with this bridge type. Please use 'eiscapi' instead, or updae the device.",
|
||||
device.Key);
|
||||
continue;
|
||||
}
|
||||
|
||||
var bridge = device as IBridgeAdvanced;
|
||||
if (bridge != null) bridge.LinkToApi(Eisc, d.JoinStart, d.JoinMapKey, this);
|
||||
continue;
|
||||
}
|
||||
|
||||
var registerResult = Eisc.Register();
|
||||
Debug.Console(1, this, "Linking Device: '{0}'", device.Key);
|
||||
|
||||
if (registerResult != eDeviceRegistrationUnRegistrationResponse.Success)
|
||||
if (!typeof (IBridgeAdvanced).IsAssignableFrom(device.GetType().GetCType()))
|
||||
{
|
||||
Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Registration result: {0}", registerResult);
|
||||
return;
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice,
|
||||
"{0} is not compatible with this bridge type. Please use 'eiscapi' instead, or updae the device.",
|
||||
device.Key);
|
||||
continue;
|
||||
}
|
||||
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "EISC registration successful");
|
||||
});
|
||||
var bridge = device as IBridgeAdvanced;
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.LinkToApi(Eisc, d.JoinStart, d.JoinMapKey, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterEisc()
|
||||
{
|
||||
if (Eisc.Registered)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var registerResult = Eisc.Register();
|
||||
|
||||
if (registerResult != eDeviceRegistrationUnRegistrationResponse.Success)
|
||||
{
|
||||
Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Registration result: {0}", registerResult);
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "EISC registration successful");
|
||||
}
|
||||
|
||||
public void LinkRooms()
|
||||
{
|
||||
Debug.Console(1, this, "Linking Rooms...");
|
||||
|
||||
if (PropertiesConfig.Rooms == null)
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "No rooms linked to this bridge.");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var room in PropertiesConfig.Rooms)
|
||||
{
|
||||
var rm = DeviceManager.GetDeviceForKey(room.RoomKey) as IBridgeAdvanced;
|
||||
|
||||
if (rm == null)
|
||||
{
|
||||
Debug.Console(1, this, Debug.ErrorLogLevel.Notice,
|
||||
"Room {0} does not implement IBridgeAdvanced. Skipping...", room.RoomKey);
|
||||
continue;
|
||||
}
|
||||
|
||||
rm.LinkToApi(Eisc, room.JoinStart, room.JoinMapKey, this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -152,7 +217,7 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
/// <summary>
|
||||
/// Prints all the join maps on this bridge
|
||||
/// </summary>
|
||||
public void PrintJoinMaps()
|
||||
public virtual void PrintJoinMaps()
|
||||
{
|
||||
Debug.Console(0, this, "Join Maps for EISC IPID: {0}", Eisc.ID.ToString("X"));
|
||||
|
||||
@@ -247,7 +312,7 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
/// </summary>
|
||||
/// <param name="currentDevice"></param>
|
||||
/// <param name="args"></param>
|
||||
void Eisc_SigChange(object currentDevice, SigEventArgs args)
|
||||
protected void Eisc_SigChange(object currentDevice, SigEventArgs args)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -270,6 +335,12 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
Debug.Console(2, this, "Error in Eisc_SigChange handler: {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
#region Implementation of ICommunicationMonitor
|
||||
|
||||
public StatusMonitorBase CommunicationMonitor { get; private set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class EiscApiPropertiesConfig
|
||||
@@ -280,6 +351,9 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
[JsonProperty("devices")]
|
||||
public List<ApiDevicePropertiesConfig> Devices { get; set; }
|
||||
|
||||
[JsonProperty("rooms")]
|
||||
public List<ApiRoomPropertiesConfig> Rooms { get; set; }
|
||||
|
||||
|
||||
public class ApiDevicePropertiesConfig
|
||||
{
|
||||
@@ -293,21 +367,52 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
public string JoinMapKey { get; set; }
|
||||
}
|
||||
|
||||
public class ApiRoomPropertiesConfig
|
||||
{
|
||||
[JsonProperty("roomKey")]
|
||||
public string RoomKey { get; set; }
|
||||
|
||||
[JsonProperty("joinStart")]
|
||||
public uint JoinStart { get; set; }
|
||||
|
||||
[JsonProperty("joinMapKey")]
|
||||
public string JoinMapKey { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class EiscApiAdvancedFactory : EssentialsDeviceFactory<EiscApiAdvanced>
|
||||
{
|
||||
public EiscApiAdvancedFactory()
|
||||
{
|
||||
TypeNames = new List<string> { "eiscapiadv", "eiscapiadvanced" };
|
||||
TypeNames = new List<string> { "eiscapiadv", "eiscapiadvanced", "vceiscapiadv", "vceiscapiadvanced" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new EiscApiAdvanced Device");
|
||||
|
||||
return new EiscApiAdvanced(dc);
|
||||
|
||||
var controlProperties = CommFactory.GetControlPropertiesConfig(dc);
|
||||
|
||||
switch (dc.Type.ToLower())
|
||||
{
|
||||
case "eiscapiadv":
|
||||
case "eiscapiadvanced":
|
||||
{
|
||||
var eisc = new ThreeSeriesTcpIpEthernetIntersystemCommunications(controlProperties.IpIdInt,
|
||||
controlProperties.TcpSshProperties.Address, Global.ControlSystem);
|
||||
return new EiscApiAdvanced(dc, eisc);
|
||||
}
|
||||
case "vceiscapiadv":
|
||||
case "vceiscapiadvanced":
|
||||
{
|
||||
var eisc = new VirtualControlEISCClient(controlProperties.IpIdInt, InitialParametersClass.RoomId,
|
||||
Global.ControlSystem);
|
||||
return new EiscApiAdvanced(dc, eisc);
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
/// <param name="joinStart">Join this join map will start at</param>
|
||||
/// <param name="type">Type of the child join map</param>
|
||||
public AppleTvJoinMap(uint joinStart, Type type) : base(joinStart, type)
|
||||
{
|
||||
}
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,6 +76,14 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
public JoinDataComplete HdcpSupportCapability = new JoinDataComplete(new JoinData { JoinNumber = 1201, JoinSpan = 32 },
|
||||
new JoinMetadata { Description = "DM Chassis Input HDCP Support Capability", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
|
||||
|
||||
[JoinName("InputStreamCardState")]
|
||||
public JoinDataComplete InputStreamCardState = new JoinDataComplete(new JoinData { JoinNumber = 1501, JoinSpan = 32 },
|
||||
new JoinMetadata { Description = "DM Chassis Stream Input Start (1), Stop (2), Pause (3) with Feedback", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
|
||||
|
||||
[JoinName("OutputStreamCardState")]
|
||||
public JoinDataComplete OutputStreamCardState = new JoinDataComplete(new JoinData { JoinNumber = 1601, JoinSpan = 32 },
|
||||
new JoinMetadata { Description = "DM Chassis Stream Output Start (1), Stop (2), Pause (3) with Feedback", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Analog });
|
||||
|
||||
[JoinName("InputNames")]
|
||||
public JoinDataComplete InputNames = new JoinDataComplete(new JoinData { JoinNumber = 101, JoinSpan = 32 },
|
||||
new JoinMetadata { Description = "DM Chassis Input Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
|
||||
|
||||
@@ -154,7 +154,7 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
|
||||
[JoinName("PirSensitivityInVacantState")]
|
||||
public JoinDataComplete PirSensitivityInVacantState = new JoinDataComplete(new JoinData { JoinNumber = 8, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Occ Sensor Ultrasonic Sensitivity in Vacant State", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog });
|
||||
new JoinMetadata { Description = "Occ Sensor PIR Sensitivity in Vacant State", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Analog });
|
||||
|
||||
[JoinName("Name")]
|
||||
public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
|
||||
|
||||
@@ -1,131 +1,274 @@
|
||||
using System;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash_Essentials_Core.Bridges.JoinMaps
|
||||
namespace PepperDash.Essentials.Core.Bridges.JoinMaps
|
||||
{
|
||||
public class GlsPartitionSensorJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
[JoinName("IsOnline")]
|
||||
public JoinDataComplete IsOnline = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 1,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Is Online",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
public class GlsPartitionSensorJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
[JoinName("IsOnline")]
|
||||
public JoinDataComplete IsOnline = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 1,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Is Online",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("Name")]
|
||||
public JoinDataComplete Name = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 1,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Name",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
[JoinName("Name")]
|
||||
public JoinDataComplete Name = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 1,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Name",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("Enable")]
|
||||
public JoinDataComplete Enable = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 2,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Enable",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
[JoinName("Enable")]
|
||||
public JoinDataComplete Enable = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 2,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Enable",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("PartitionSensed")]
|
||||
public JoinDataComplete PartitionSensed = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 3,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Partition Sensed",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
[JoinName("PartitionSensed")]
|
||||
public JoinDataComplete PartitionSensed = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 3,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Partition Sensed",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("PartitionNotSensed")]
|
||||
public JoinDataComplete PartitionNotSensed = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 4,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Partition Not Sensed",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
[JoinName("PartitionNotSensed")]
|
||||
public JoinDataComplete PartitionNotSensed = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 4,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Partition Not Sensed",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("IncreaseSensitivity")]
|
||||
public JoinDataComplete IncreaseSensitivity = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 6,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Increase Sensitivity",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
[JoinName("IncreaseSensitivity")]
|
||||
public JoinDataComplete IncreaseSensitivity = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 6,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Increase Sensitivity",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("DecreaseSensitivity")]
|
||||
public JoinDataComplete DecreaseSensitivity = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 7,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Decrease Sensitivity",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
[JoinName("DecreaseSensitivity")]
|
||||
public JoinDataComplete DecreaseSensitivity = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 7,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Decrease Sensitivity",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("Sensitivity")]
|
||||
public JoinDataComplete Sensitivity = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 2,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Sensitivity",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
[JoinName("Sensitivity")]
|
||||
public JoinDataComplete Sensitivity = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 2,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Sensitivity",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to use when instantiating this Join Map without inheriting from it
|
||||
/// </summary>
|
||||
/// <param name="joinStart">Join this join map will start at</param>
|
||||
public GlsPartitionSensorJoinMap(uint joinStart)
|
||||
: this(joinStart, typeof (GlsPartitionSensorJoinMap))
|
||||
{
|
||||
public GlsPartitionSensorJoinMap(uint joinStart)
|
||||
: this(joinStart, typeof(GlsPartitionSensorJoinMap))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to use when extending this Join map
|
||||
/// </summary>
|
||||
/// <param name="joinStart">Join this join map will start at</param>
|
||||
/// <param name="type">Type of the child join map</param>
|
||||
protected GlsPartitionSensorJoinMap(uint joinStart, Type type)
|
||||
: base(joinStart, type)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace PepperDash_Essentials_Core.Bridges.JoinMaps
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Obsolete("use PepperDash.Essentials.Core.Bridges.JoinMaps version")]
|
||||
public class GlsPartitionSensorJoinMap:JoinMapBaseAdvanced
|
||||
{
|
||||
[JoinName("IsOnline")]
|
||||
public JoinDataComplete IsOnline = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 1,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Is Online",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("Name")]
|
||||
public JoinDataComplete Name = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 1,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Name",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("Enable")]
|
||||
public JoinDataComplete Enable = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 2,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Enable",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("PartitionSensed")]
|
||||
public JoinDataComplete PartitionSensed = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 3,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Partition Sensed",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("PartitionNotSensed")]
|
||||
public JoinDataComplete PartitionNotSensed = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 4,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Partition Not Sensed",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("IncreaseSensitivity")]
|
||||
public JoinDataComplete IncreaseSensitivity = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 6,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Increase Sensitivity",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("DecreaseSensitivity")]
|
||||
public JoinDataComplete DecreaseSensitivity = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 7,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Decrease Sensitivity",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("Sensitivity")]
|
||||
public JoinDataComplete Sensitivity = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 2,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sensor Sensitivity",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to use when instantiating this Join Map without inheriting from it
|
||||
/// </summary>
|
||||
/// <param name="joinStart">Join this join map will start at</param>
|
||||
public GlsPartitionSensorJoinMap(uint joinStart)
|
||||
: this(joinStart, typeof(GlsPartitionSensorJoinMap))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to use when extending this Join map
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Bridges
|
||||
{
|
||||
/// <summary>
|
||||
/// Join map for IRBlurayBase devices
|
||||
/// </summary>
|
||||
public class IRBlurayBaseJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
[JoinName("PowerOn")]
|
||||
public JoinDataComplete PowerOn = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Power On", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("PowerOff")]
|
||||
public JoinDataComplete PowerOff = new JoinDataComplete(new JoinData { JoinNumber = 2, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Power Off", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("PowerToggle")]
|
||||
public JoinDataComplete PowerToggle = new JoinDataComplete(new JoinData { JoinNumber = 3, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Power Toggle", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Up")]
|
||||
public JoinDataComplete Up = new JoinDataComplete(new JoinData { JoinNumber = 4, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Nav Up", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Down")]
|
||||
public JoinDataComplete Down = new JoinDataComplete(new JoinData { JoinNumber = 5, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Nav Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Left")]
|
||||
public JoinDataComplete Left = new JoinDataComplete(new JoinData { JoinNumber = 6, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Nav Left", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Right")]
|
||||
public JoinDataComplete Right = new JoinDataComplete(new JoinData { JoinNumber = 7, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Nav Right", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Select")]
|
||||
public JoinDataComplete Select = new JoinDataComplete(new JoinData { JoinNumber = 8, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Select", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Menu")]
|
||||
public JoinDataComplete Menu = new JoinDataComplete(new JoinData { JoinNumber = 9, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Menu", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Exit")]
|
||||
public JoinDataComplete Exit = new JoinDataComplete(new JoinData { JoinNumber = 10, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Exit", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Digit0")]
|
||||
public JoinDataComplete Digit0 = new JoinDataComplete(new JoinData { JoinNumber = 11, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Digit 0", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Digit1")]
|
||||
public JoinDataComplete Digit1 = new JoinDataComplete(new JoinData { JoinNumber = 12, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Digit 1", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Digit2")]
|
||||
public JoinDataComplete Digit2 = new JoinDataComplete(new JoinData { JoinNumber = 13, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Digit 2", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Digit3")]
|
||||
public JoinDataComplete Digit3 = new JoinDataComplete(new JoinData { JoinNumber = 14, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Digit 3", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Digit4")]
|
||||
public JoinDataComplete Digit4 = new JoinDataComplete(new JoinData { JoinNumber = 15, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Digit 4", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Digit5")]
|
||||
public JoinDataComplete Digit5 = new JoinDataComplete(new JoinData { JoinNumber = 16, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Digit 5", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Digit6")]
|
||||
public JoinDataComplete Digit6 = new JoinDataComplete(new JoinData { JoinNumber = 17, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Digit 6", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Digit7")]
|
||||
public JoinDataComplete Digit7 = new JoinDataComplete(new JoinData { JoinNumber = 18, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Digit 7", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Digit8")]
|
||||
public JoinDataComplete Digit8 = new JoinDataComplete(new JoinData { JoinNumber = 19, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Digit 8", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Digit9")]
|
||||
public JoinDataComplete Digit9 = new JoinDataComplete(new JoinData { JoinNumber = 20, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Digit 9", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("KeypadClear")]
|
||||
public JoinDataComplete KeypadClear = new JoinDataComplete(new JoinData { JoinNumber = 21, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Keypad Clear", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("KeypadEnter")]
|
||||
public JoinDataComplete KeypadEnter = new JoinDataComplete(new JoinData { JoinNumber = 22, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Keypad Enter", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("ChannelUp")]
|
||||
public JoinDataComplete ChannelUp = new JoinDataComplete(new JoinData { JoinNumber = 23, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "STB Channel Up", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("ChannelDown")]
|
||||
public JoinDataComplete ChannelDown = new JoinDataComplete(new JoinData { JoinNumber = 24, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "STB Channel Down", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("LastChannel")]
|
||||
public JoinDataComplete LastChannel = new JoinDataComplete(new JoinData { JoinNumber = 25, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Last Channel", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Guide")]
|
||||
public JoinDataComplete Guide = new JoinDataComplete(new JoinData { JoinNumber = 26, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Guide", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Info")]
|
||||
public JoinDataComplete Info = new JoinDataComplete(new JoinData { JoinNumber = 27, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Info", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Red")]
|
||||
public JoinDataComplete Red = new JoinDataComplete(new JoinData { JoinNumber = 28, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Red", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Green")]
|
||||
public JoinDataComplete Green = new JoinDataComplete(new JoinData { JoinNumber = 29, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Green", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Yellow")]
|
||||
public JoinDataComplete Yellow = new JoinDataComplete(new JoinData { JoinNumber = 30, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Yellow", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Blue")]
|
||||
public JoinDataComplete Blue = new JoinDataComplete(new JoinData { JoinNumber = 31, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Blue", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
|
||||
[JoinName("Play")]
|
||||
public JoinDataComplete Play = new JoinDataComplete(new JoinData { JoinNumber = 33, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Play", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Pause")]
|
||||
public JoinDataComplete Pause = new JoinDataComplete(new JoinData { JoinNumber = 34, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Pause", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Stop")]
|
||||
public JoinDataComplete Stop = new JoinDataComplete(new JoinData { JoinNumber = 35, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Stop", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("FFwd")]
|
||||
public JoinDataComplete FFwd = new JoinDataComplete(new JoinData { JoinNumber = 36, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "FFwd", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Rewind")]
|
||||
public JoinDataComplete Rewind = new JoinDataComplete(new JoinData { JoinNumber = 37, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Rewind", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("ChapPlus")]
|
||||
public JoinDataComplete ChapPlus = new JoinDataComplete(new JoinData { JoinNumber = 38, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Chapter Plus", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("ChapMinus")]
|
||||
public JoinDataComplete ChapMinus = new JoinDataComplete(new JoinData { JoinNumber = 39, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Chapter Minus", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Replay")]
|
||||
public JoinDataComplete Replay = new JoinDataComplete(new JoinData { JoinNumber = 40, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Replay", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Record")]
|
||||
public JoinDataComplete Record = new JoinDataComplete(new JoinData { JoinNumber = 41, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Record", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("HasKeypadAccessoryButton1")]
|
||||
public JoinDataComplete HasKeypadAccessoryButton1 = new JoinDataComplete(new JoinData { JoinNumber = 42, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Has Keypad Accessory Button 1", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("HasKeypadAccessoryButton2")]
|
||||
public JoinDataComplete HasKeypadAccessoryButton2 = new JoinDataComplete(new JoinData { JoinNumber = 43, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Has Keypad Accessory Button 2", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("KeypadAccessoryButton1Press")]
|
||||
public JoinDataComplete KeypadAccessoryButton1Press = new JoinDataComplete(new JoinData { JoinNumber = 42, JoinSpan = 2 },
|
||||
new JoinMetadata { Description = "Keypad Accessory Button 1 Press", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("KeypadAccessoryButton2Press")]
|
||||
public JoinDataComplete KeypadAccessoryButton2Press = new JoinDataComplete(new JoinData { JoinNumber = 43, JoinSpan = 2 },
|
||||
new JoinMetadata { Description = "Keypad Accessory Button 2 Press", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Name")]
|
||||
public JoinDataComplete Name = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Name", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("KeypadAccessoryButton1Label")]
|
||||
public JoinDataComplete KeypadAccessoryButton1Label = new JoinDataComplete(new JoinData { JoinNumber = 42, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Keypad Accessory Button 1 Label", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("KeypadAccessoryButton2Label")]
|
||||
public JoinDataComplete KeypadAccessoryButton2Label = new JoinDataComplete(new JoinData { JoinNumber = 43, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Keypad Accessory Button 1 Label", JoinCapabilities = eJoinCapabilities.ToSIMPL, JoinType = eJoinType.Serial });
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to use when instantiating this Join Map without inheriting from it
|
||||
/// </summary>
|
||||
/// <param name="joinStart">Join this join map will start at</param>
|
||||
public IRBlurayBaseJoinMap(uint joinStart)
|
||||
: this(joinStart, typeof(IRBlurayBaseJoinMap))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to use when extending this Join map
|
||||
/// </summary>
|
||||
/// <param name="joinStart">Join this join map will start at</param>
|
||||
/// <param name="type">Type of the child join map</param>
|
||||
protected IRBlurayBaseJoinMap(uint joinStart, Type type)
|
||||
: base(joinStart, type)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
using System;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core.Bridges
|
||||
{
|
||||
public class SetTopBoxControllerJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
namespace PepperDash.Essentials.Core.Bridges
|
||||
{
|
||||
public class SetTopBoxControllerJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
[JoinName("PowerOn")]
|
||||
public JoinDataComplete PowerOn = new JoinDataComplete(new JoinData { JoinNumber = 1, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "STB Power On", JoinCapabilities = eJoinCapabilities.FromSIMPL, JoinType = eJoinType.Digital });
|
||||
@@ -236,5 +236,5 @@ namespace PepperDash.Essentials.Core.Bridges
|
||||
: base(joinStart, type)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,8 +11,10 @@ using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public class CecPortController : Device, IBasicCommunication
|
||||
public class CecPortController : Device, IBasicCommunicationWithStreamDebugging
|
||||
{
|
||||
public CommunicationStreamDebugging StreamDebugging { get; private set; }
|
||||
|
||||
public event EventHandler<GenericCommMethodReceiveBytesArgs> BytesReceived;
|
||||
public event EventHandler<GenericCommMethodReceiveTextArgs> TextReceived;
|
||||
|
||||
@@ -23,6 +25,8 @@ namespace PepperDash.Essentials.Core
|
||||
public CecPortController(string key, Func<EssentialsControlPropertiesConfig, ICec> postActivationFunc,
|
||||
EssentialsControlPropertiesConfig config):base(key)
|
||||
{
|
||||
StreamDebugging = new CommunicationStreamDebugging(key);
|
||||
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
Port = postActivationFunc(config);
|
||||
@@ -50,15 +54,21 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
void OnDataReceived(string s)
|
||||
{
|
||||
var bytesHandler = BytesReceived;
|
||||
var bytesHandler = BytesReceived;
|
||||
if (bytesHandler != null)
|
||||
{
|
||||
var bytes = Encoding.GetEncoding(28591).GetBytes(s);
|
||||
if (StreamDebugging.RxStreamDebuggingIsEnabled)
|
||||
Debug.Console(0, this, "Received: '{0}'", ComTextHelper.GetEscapedText(bytes));
|
||||
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
|
||||
}
|
||||
var textHandler = TextReceived;
|
||||
if (textHandler != null)
|
||||
textHandler(this, new GenericCommMethodReceiveTextArgs(s));
|
||||
if (textHandler != null)
|
||||
{
|
||||
if (StreamDebugging.RxStreamDebuggingIsEnabled)
|
||||
Debug.Console(0, this, "Received: '{0}'", s);
|
||||
textHandler(this, new GenericCommMethodReceiveTextArgs(s));
|
||||
}
|
||||
}
|
||||
|
||||
#region IBasicCommunication Members
|
||||
@@ -67,6 +77,8 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
if (Port == null)
|
||||
return;
|
||||
if (StreamDebugging.TxStreamDebuggingIsEnabled)
|
||||
Debug.Console(0, this, "Sending {0} characters of text: '{1}'", text.Length, text);
|
||||
Port.StreamCec.Send.StringValue = text;
|
||||
}
|
||||
|
||||
@@ -75,6 +87,8 @@ namespace PepperDash.Essentials.Core
|
||||
if (Port == null)
|
||||
return;
|
||||
var text = Encoding.GetEncoding(28591).GetString(bytes, 0, bytes.Length);
|
||||
if (StreamDebugging.TxStreamDebuggingIsEnabled)
|
||||
Debug.Console(0, this, "Sending {0} bytes: '{1}'", bytes.Length, ComTextHelper.GetEscapedText(bytes));
|
||||
Port.StreamCec.Send.StringValue = text;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,11 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
private void RegisterAndConfigureComPort()
|
||||
{
|
||||
if (Port == null)
|
||||
{
|
||||
Debug.Console(0,this,Debug.ErrorLogLevel.Error, "Configured com Port for this device does not exist.");
|
||||
return;
|
||||
}
|
||||
if (Port.Parent is CrestronControlSystem)
|
||||
{
|
||||
var result = Port.Register();
|
||||
@@ -87,18 +92,20 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
void OnDataReceived(string s)
|
||||
{
|
||||
|
||||
var bytesHandler = BytesReceived;
|
||||
if (bytesHandler != null)
|
||||
{
|
||||
var bytes = Encoding.GetEncoding(28591).GetBytes(s);
|
||||
if (StreamDebugging.RxStreamDebuggingIsEnabled)
|
||||
Debug.Console(0, this, "Received: '{0}'", ComTextHelper.GetEscapedText(bytes));
|
||||
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
|
||||
}
|
||||
var textHandler = TextReceived;
|
||||
if (textHandler != null)
|
||||
{
|
||||
if (StreamDebugging.RxStreamDebuggingIsEnabled)
|
||||
Debug.Console(0, this, "Recevied: '{0}'", s);
|
||||
|
||||
if (StreamDebugging.RxStreamDebuggingIsEnabled)
|
||||
Debug.Console(0, this, "Received: '{0}'", s);
|
||||
textHandler(this, new GenericCommMethodReceiveTextArgs(s));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,120 +1,120 @@
|
||||
using System;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DM;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CommFactory
|
||||
{
|
||||
public static EssentialsControlPropertiesConfig GetControlPropertiesConfig(DeviceConfig deviceConfig)
|
||||
{
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject<EssentialsControlPropertiesConfig>
|
||||
(deviceConfig.Properties["control"].ToString());
|
||||
//Debug.Console(2, "Control TEST: {0}", JsonConvert.SerializeObject(controlConfig));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
Debug.Console(0, "ERROR: [{0}] Control properties deserialize failed:\r{1}", deviceConfig.Key, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a comm method of either com port, TCP, SSH, and puts this into the DeviceManager
|
||||
/// </summary>
|
||||
/// <param name="deviceConfig">The Device config object</param>
|
||||
public static IBasicCommunication CreateCommForDevice(DeviceConfig deviceConfig)
|
||||
{
|
||||
EssentialsControlPropertiesConfig controlConfig = GetControlPropertiesConfig(deviceConfig);
|
||||
if (controlConfig == null)
|
||||
return null;
|
||||
|
||||
IBasicCommunication comm = null;
|
||||
try
|
||||
{
|
||||
var c = controlConfig.TcpSshProperties;
|
||||
switch (controlConfig.Method)
|
||||
{
|
||||
case eControlMethod.Com:
|
||||
comm = new ComPortController(deviceConfig.Key + "-com", GetComPort, controlConfig.ComParams, controlConfig);
|
||||
break;
|
||||
case eControlMethod.Cec:
|
||||
comm = new CecPortController(deviceConfig.Key + "-cec", GetCecPort, controlConfig);
|
||||
break;
|
||||
case eControlMethod.IR:
|
||||
break;
|
||||
case eControlMethod.Ssh:
|
||||
{
|
||||
var ssh = new GenericSshClient(deviceConfig.Key + "-ssh", c.Address, c.Port, c.Username, c.Password);
|
||||
ssh.AutoReconnect = c.AutoReconnect;
|
||||
if(ssh.AutoReconnect)
|
||||
ssh.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
||||
comm = ssh;
|
||||
break;
|
||||
}
|
||||
case eControlMethod.Tcpip:
|
||||
{
|
||||
var tcp = new GenericTcpIpClient(deviceConfig.Key + "-tcp", c.Address, c.Port, c.BufferSize);
|
||||
tcp.AutoReconnect = c.AutoReconnect;
|
||||
if (tcp.AutoReconnect)
|
||||
tcp.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
||||
comm = tcp;
|
||||
break;
|
||||
}
|
||||
case eControlMethod.Udp:
|
||||
{
|
||||
var udp = new GenericUdpServer(deviceConfig.Key + "-udp", c.Address, c.Port, c.BufferSize);
|
||||
comm = udp;
|
||||
break;
|
||||
}
|
||||
case eControlMethod.Telnet:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, "Cannot create communication from JSON:\r{0}\r\rException:\r{1}",
|
||||
deviceConfig.Properties.ToString(), e);
|
||||
}
|
||||
|
||||
// put it in the device manager if it's the right flavor
|
||||
var comDev = comm as Device;
|
||||
if (comDev != null)
|
||||
DeviceManager.AddDevice(comDev);
|
||||
return comm;
|
||||
}
|
||||
|
||||
public static ComPort GetComPort(EssentialsControlPropertiesConfig config)
|
||||
{
|
||||
var comPar = config.ComParams;
|
||||
var dev = GetIComPortsDeviceFromManagedDevice(config.ControlPortDevKey);
|
||||
if (dev != null && config.ControlPortNumber <= dev.NumberOfComPorts)
|
||||
return dev.ComPorts[config.ControlPortNumber];
|
||||
Debug.Console(0, "GetComPort: Device '{0}' does not have com port {1}", config.ControlPortDevKey, config.ControlPortNumber);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an ICec port from a RoutingInput or RoutingOutput on a device
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
/// <returns></returns>
|
||||
public static ICec GetCecPort(ControlPropertiesConfig config)
|
||||
{
|
||||
using System;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DM;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class CommFactory
|
||||
{
|
||||
public static EssentialsControlPropertiesConfig GetControlPropertiesConfig(DeviceConfig deviceConfig)
|
||||
{
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject<EssentialsControlPropertiesConfig>
|
||||
(deviceConfig.Properties["control"].ToString());
|
||||
//Debug.Console(2, "Control TEST: {0}", JsonConvert.SerializeObject(controlConfig));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
Debug.Console(0, "ERROR: [{0}] Control properties deserialize failed:\r{1}", deviceConfig.Key, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a comm method of either com port, TCP, SSH, and puts this into the DeviceManager
|
||||
/// </summary>
|
||||
/// <param name="deviceConfig">The Device config object</param>
|
||||
public static IBasicCommunication CreateCommForDevice(DeviceConfig deviceConfig)
|
||||
{
|
||||
EssentialsControlPropertiesConfig controlConfig = GetControlPropertiesConfig(deviceConfig);
|
||||
if (controlConfig == null)
|
||||
return null;
|
||||
|
||||
IBasicCommunication comm = null;
|
||||
try
|
||||
{
|
||||
var c = controlConfig.TcpSshProperties;
|
||||
switch (controlConfig.Method)
|
||||
{
|
||||
case eControlMethod.Com:
|
||||
comm = new ComPortController(deviceConfig.Key + "-com", GetComPort, controlConfig.ComParams, controlConfig);
|
||||
break;
|
||||
case eControlMethod.Cec:
|
||||
comm = new CecPortController(deviceConfig.Key + "-cec", GetCecPort, controlConfig);
|
||||
break;
|
||||
case eControlMethod.IR:
|
||||
break;
|
||||
case eControlMethod.Ssh:
|
||||
{
|
||||
var ssh = new GenericSshClient(deviceConfig.Key + "-ssh", c.Address, c.Port, c.Username, c.Password);
|
||||
ssh.AutoReconnect = c.AutoReconnect;
|
||||
if(ssh.AutoReconnect)
|
||||
ssh.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
||||
comm = ssh;
|
||||
break;
|
||||
}
|
||||
case eControlMethod.Tcpip:
|
||||
{
|
||||
var tcp = new GenericTcpIpClient(deviceConfig.Key + "-tcp", c.Address, c.Port, c.BufferSize);
|
||||
tcp.AutoReconnect = c.AutoReconnect;
|
||||
if (tcp.AutoReconnect)
|
||||
tcp.AutoReconnectIntervalMs = c.AutoReconnectIntervalMs;
|
||||
comm = tcp;
|
||||
break;
|
||||
}
|
||||
case eControlMethod.Udp:
|
||||
{
|
||||
var udp = new GenericUdpServer(deviceConfig.Key + "-udp", c.Address, c.Port, c.BufferSize);
|
||||
comm = udp;
|
||||
break;
|
||||
}
|
||||
case eControlMethod.Telnet:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, "Cannot create communication from JSON:\r{0}\r\rException:\r{1}",
|
||||
deviceConfig.Properties.ToString(), e);
|
||||
}
|
||||
|
||||
// put it in the device manager if it's the right flavor
|
||||
var comDev = comm as Device;
|
||||
if (comDev != null)
|
||||
DeviceManager.AddDevice(comDev);
|
||||
return comm;
|
||||
}
|
||||
|
||||
public static ComPort GetComPort(EssentialsControlPropertiesConfig config)
|
||||
{
|
||||
var comPar = config.ComParams;
|
||||
var dev = GetIComPortsDeviceFromManagedDevice(config.ControlPortDevKey);
|
||||
if (dev != null && config.ControlPortNumber <= dev.NumberOfComPorts)
|
||||
return dev.ComPorts[config.ControlPortNumber];
|
||||
Debug.Console(0,Debug.ErrorLogLevel.Notice, "GetComPort: Device '{0}' does not have com port {1}", config.ControlPortDevKey, config.ControlPortNumber);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an ICec port from a RoutingInput or RoutingOutput on a device
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
/// <returns></returns>
|
||||
public static ICec GetCecPort(ControlPropertiesConfig config)
|
||||
{
|
||||
var dev = DeviceManager.GetDeviceForKey(config.ControlPortDevKey);
|
||||
|
||||
if (dev != null)
|
||||
@@ -147,64 +147,64 @@ namespace PepperDash.Essentials.Core
|
||||
Debug.Console(0, "GetCecPort: '{0}' - Configuration missing 'ControlPortName'", config.ControlPortDevKey);
|
||||
}
|
||||
}
|
||||
Debug.Console(0, "GetCecPort: Device '{0}' is not a valid device.", config.ControlPortDevKey);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper to grab the IComPorts device for this PortDeviceKey. Key "controlSystem" will
|
||||
/// return the ControlSystem object from the Global class.
|
||||
/// </summary>
|
||||
/// <returns>IComPorts device or null if the device is not found or does not implement IComPorts</returns>
|
||||
public static IComPorts GetIComPortsDeviceFromManagedDevice(string ComPortDevKey)
|
||||
{
|
||||
if ((ComPortDevKey.Equals("controlSystem", System.StringComparison.OrdinalIgnoreCase)
|
||||
|| ComPortDevKey.Equals("processor", System.StringComparison.OrdinalIgnoreCase))
|
||||
&& Global.ControlSystem is IComPorts)
|
||||
return Global.ControlSystem;
|
||||
else
|
||||
{
|
||||
var dev = DeviceManager.GetDeviceForKey(ComPortDevKey) as IComPorts;
|
||||
if (dev == null)
|
||||
Debug.Console(0, "ComPortConfig: Cannot find com port device '{0}'", ComPortDevKey);
|
||||
return dev;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EssentialsControlPropertiesConfig :
|
||||
PepperDash.Core.ControlPropertiesConfig
|
||||
{
|
||||
|
||||
[JsonConverter(typeof(ComSpecJsonConverter))]
|
||||
public ComPort.ComPortSpec ComParams { get; set; }
|
||||
|
||||
public string CresnetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to provide uint conversion of string CresnetId
|
||||
/// </summary>
|
||||
public uint CresnetIdInt
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return Convert.ToUInt32(CresnetId, 16);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new FormatException(string.Format("ERROR:Unable to convert Cresnet ID: {0} to hex. Error:\n{1}", CresnetId));
|
||||
}
|
||||
}
|
||||
Debug.Console(0, "GetCecPort: Device '{0}' is not a valid device.", config.ControlPortDevKey);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string InfinetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Helper to grab the IComPorts device for this PortDeviceKey. Key "controlSystem" will
|
||||
/// return the ControlSystem object from the Global class.
|
||||
/// </summary>
|
||||
/// <returns>IComPorts device or null if the device is not found or does not implement IComPorts</returns>
|
||||
public static IComPorts GetIComPortsDeviceFromManagedDevice(string ComPortDevKey)
|
||||
{
|
||||
if ((ComPortDevKey.Equals("controlSystem", System.StringComparison.OrdinalIgnoreCase)
|
||||
|| ComPortDevKey.Equals("processor", System.StringComparison.OrdinalIgnoreCase))
|
||||
&& Global.ControlSystem is IComPorts)
|
||||
return Global.ControlSystem;
|
||||
else
|
||||
{
|
||||
var dev = DeviceManager.GetDeviceForKey(ComPortDevKey) as IComPorts;
|
||||
if (dev == null)
|
||||
Debug.Console(0, "ComPortConfig: Cannot find com port device '{0}'", ComPortDevKey);
|
||||
return dev;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EssentialsControlPropertiesConfig :
|
||||
PepperDash.Core.ControlPropertiesConfig
|
||||
{
|
||||
|
||||
[JsonConverter(typeof(ComSpecJsonConverter))]
|
||||
public ComPort.ComPortSpec ComParams { get; set; }
|
||||
|
||||
public string CresnetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to provide uint conversion of string CresnetId
|
||||
/// </summary>
|
||||
public uint CresnetIdInt
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return Convert.ToUInt32(CresnetId, 16);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new FormatException(string.Format("ERROR:Unable to convert Cresnet ID: {0} to hex. Error:\n{1}", CresnetId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string InfinetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Attepmts to provide uiont conversion of string InifinetId
|
||||
/// </summary>
|
||||
@@ -221,13 +221,13 @@ namespace PepperDash.Essentials.Core
|
||||
throw new FormatException(string.Format("ERROR:Unable to conver Infinet ID: {0} to hex. Error:\n{1}", InfinetId));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class IrControlSpec
|
||||
{
|
||||
public string PortDeviceKey { get; set; }
|
||||
public uint PortNumber { get; set; }
|
||||
public string File { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class IrControlSpec
|
||||
{
|
||||
public string PortDeviceKey { get; set; }
|
||||
public uint PortNumber { get; set; }
|
||||
public string File { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
Communication = comm;
|
||||
PortGather = new CommunicationGather(Communication, '\x0d');
|
||||
PortGather.LineReceived += this.Port_LineReceived;
|
||||
//PortGather.LineReceived += this.Port_LineReceived;
|
||||
CommunicationMonitor = new GenericCommunicationMonitor(this, Communication, props.CommunicationMonitorProperties);
|
||||
LineEnding = props.LineEnding;
|
||||
}
|
||||
@@ -47,13 +47,6 @@ namespace PepperDash.Essentials.Core
|
||||
return true;
|
||||
}
|
||||
|
||||
void Port_LineReceived(object dev, GenericCommMethodReceiveTextArgs args)
|
||||
{
|
||||
if (Debug.Level == 2)
|
||||
Debug.Console(2, this, "RX: '{0}'",
|
||||
ShowHexResponse ? ComTextHelper.GetEscapedText(args.Text) : args.Text);
|
||||
}
|
||||
|
||||
void SendLine(string s)
|
||||
{
|
||||
//if (Debug.Level == 2)
|
||||
|
||||
@@ -25,6 +25,7 @@ namespace PepperDash.Essentials.Core
|
||||
public GenericComm(DeviceConfig config)
|
||||
: base(config)
|
||||
{
|
||||
|
||||
PropertiesConfig = CommFactory.GetControlPropertiesConfig(config);
|
||||
|
||||
var commPort = CommFactory.CreateCommForDevice(config);
|
||||
@@ -96,7 +97,6 @@ namespace PepperDash.Essentials.Core
|
||||
// this is a permanent event handler. This cannot be -= from event
|
||||
CommPort.TextReceived += (s, a) =>
|
||||
{
|
||||
Debug.Console(2, this, "RX: {0}", a.Text);
|
||||
trilist.SetString(joinMap.TextReceived.JoinNumber, a.Text);
|
||||
};
|
||||
trilist.SetStringSigAction(joinMap.SendText.JoinNumber, s => CommPort.SendText(s));
|
||||
|
||||
@@ -33,7 +33,6 @@ namespace PepperDash.Essentials.Core
|
||||
string url = string.Format("http://{0}/{1}", Client.HostName, path);
|
||||
request.Url = new UrlParser(url);
|
||||
HttpClient.DISPATCHASYNC_ERROR error = Client.DispatchAsyncEx(request, Response, request);
|
||||
Debug.Console(2, this, "GenericHttpClient SentRequest TX:'{0}'", url);
|
||||
}
|
||||
public void SendText(string format, params object[] items)
|
||||
{
|
||||
@@ -41,7 +40,6 @@ namespace PepperDash.Essentials.Core
|
||||
string url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items));
|
||||
request.Url = new UrlParser(url);
|
||||
HttpClient.DISPATCHASYNC_ERROR error = Client.DispatchAsyncEx(request, Response, request);
|
||||
Debug.Console(2, this, "GenericHttpClient SentRequest TX:'{0}'", url);
|
||||
}
|
||||
|
||||
public void SendTextNoResponse(string format, params object[] items)
|
||||
@@ -50,7 +48,6 @@ namespace PepperDash.Essentials.Core
|
||||
string url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items));
|
||||
request.Url = new UrlParser(url);
|
||||
Client.Dispatch(request);
|
||||
Debug.Console(2, this, "GenericHttpClient SentRequest TX:'{0}'", url);
|
||||
}
|
||||
|
||||
private void Response(HttpClientResponse response, HTTP_CALLBACK_ERROR error, object request)
|
||||
@@ -63,10 +60,6 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
if (ResponseRecived != null)
|
||||
ResponseRecived(this, new GenericHttpClientEventArgs(responseReceived.ContentString, (request as HttpClientRequest).Url.ToString(), error));
|
||||
|
||||
Debug.Console(2, this, "GenericHttpClient ResponseReceived");
|
||||
Debug.Console(2, this, "RX:{0}", responseReceived.ContentString);
|
||||
Debug.Console(2, this, "TX:{0}", (request as HttpClientRequest).Url.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,83 +1,83 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Crestron.SimplSharpPro;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static class IRPortHelper
|
||||
{
|
||||
public static string IrDriverPathPrefix
|
||||
{
|
||||
get
|
||||
{
|
||||
return Global.FilePathPrefix + "IR" + Global.DirectorySeparator;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds either the ControlSystem or a device controller that contains IR ports and
|
||||
/// returns a port from the hardware device
|
||||
/// </summary>
|
||||
/// <param name="propsToken"></param>
|
||||
/// <returns>IrPortConfig object. The port and or filename will be empty/null
|
||||
/// if valid values don't exist on config</returns>
|
||||
public static IrOutPortConfig GetIrPort(JToken propsToken)
|
||||
{
|
||||
var control = propsToken["control"];
|
||||
if (control == null)
|
||||
return null;
|
||||
if (control["method"].Value<string>() != "ir")
|
||||
{
|
||||
Debug.Console(0, "IRPortHelper called with non-IR properties");
|
||||
return null;
|
||||
}
|
||||
|
||||
var port = new IrOutPortConfig();
|
||||
|
||||
var portDevKey = control.Value<string>("controlPortDevKey");
|
||||
var portNum = control.Value<uint>("controlPortNumber");
|
||||
if (portDevKey == null || portNum == 0)
|
||||
{
|
||||
Debug.Console(1, "WARNING: Properties is missing port device or port number");
|
||||
return port;
|
||||
}
|
||||
|
||||
IIROutputPorts irDev = null;
|
||||
if (portDevKey.Equals("controlSystem", StringComparison.OrdinalIgnoreCase)
|
||||
|| portDevKey.Equals("processor", StringComparison.OrdinalIgnoreCase))
|
||||
irDev = Global.ControlSystem;
|
||||
else
|
||||
irDev = DeviceManager.GetDeviceForKey(portDevKey) as IIROutputPorts;
|
||||
|
||||
if (irDev == null)
|
||||
{
|
||||
Debug.Console(1, "[Config] Error, device with IR ports '{0}' not found", portDevKey);
|
||||
return port;
|
||||
}
|
||||
|
||||
if (portNum <= irDev.NumberOfIROutputPorts) // success!
|
||||
{
|
||||
var file = IrDriverPathPrefix + control["irFile"].Value<string>();
|
||||
port.Port = irDev.IROutputPorts[portNum];
|
||||
port.FileName = file;
|
||||
return port; // new IrOutPortConfig { Port = irDev.IROutputPorts[portNum], FileName = file };
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, "[Config] Error, device '{0}' IR port {1} out of range",
|
||||
portDevKey, portNum);
|
||||
return port;
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Crestron.SimplSharpPro;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static class IRPortHelper
|
||||
{
|
||||
public static string IrDriverPathPrefix
|
||||
{
|
||||
get
|
||||
{
|
||||
return Global.FilePathPrefix + "IR" + Global.DirectorySeparator;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds either the ControlSystem or a device controller that contains IR ports and
|
||||
/// returns a port from the hardware device
|
||||
/// </summary>
|
||||
/// <param name="propsToken"></param>
|
||||
/// <returns>IrPortConfig object. The port and or filename will be empty/null
|
||||
/// if valid values don't exist on config</returns>
|
||||
public static IrOutPortConfig GetIrPort(JToken propsToken)
|
||||
{
|
||||
var control = propsToken["control"];
|
||||
if (control == null)
|
||||
return null;
|
||||
if (control["method"].Value<string>() != "ir")
|
||||
{
|
||||
Debug.Console(0, "IRPortHelper called with non-IR properties");
|
||||
return null;
|
||||
}
|
||||
|
||||
var port = new IrOutPortConfig();
|
||||
|
||||
var portDevKey = control.Value<string>("controlPortDevKey");
|
||||
var portNum = control.Value<uint>("controlPortNumber");
|
||||
if (portDevKey == null || portNum == 0)
|
||||
{
|
||||
Debug.Console(1, "WARNING: Properties is missing port device or port number");
|
||||
return port;
|
||||
}
|
||||
|
||||
IIROutputPorts irDev = null;
|
||||
if (portDevKey.Equals("controlSystem", StringComparison.OrdinalIgnoreCase)
|
||||
|| portDevKey.Equals("processor", StringComparison.OrdinalIgnoreCase))
|
||||
irDev = Global.ControlSystem;
|
||||
else
|
||||
irDev = DeviceManager.GetDeviceForKey(portDevKey) as IIROutputPorts;
|
||||
|
||||
if (irDev == null)
|
||||
{
|
||||
Debug.Console(1, "[Config] Error, device with IR ports '{0}' not found", portDevKey);
|
||||
return port;
|
||||
}
|
||||
|
||||
if (portNum <= irDev.NumberOfIROutputPorts) // success!
|
||||
{
|
||||
var file = IrDriverPathPrefix + control["irFile"].Value<string>();
|
||||
port.Port = irDev.IROutputPorts[portNum];
|
||||
port.FileName = file;
|
||||
return port; // new IrOutPortConfig { Port = irDev.IROutputPorts[portNum], FileName = file };
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, "[Config] Error, device '{0}' IR port {1} out of range",
|
||||
portDevKey, portNum);
|
||||
return port;
|
||||
}
|
||||
}
|
||||
|
||||
public static IROutputPort GetIrOutputPort(DeviceConfig dc)
|
||||
@@ -124,7 +124,7 @@ namespace PepperDash.Essentials.Core
|
||||
Debug.Console(0, "WARNING: device with IR ports '{0}' not found", portDevKey);
|
||||
return null;
|
||||
}
|
||||
if (portNum >= irDev.NumberOfIROutputPorts)
|
||||
if (portNum > irDev.NumberOfIROutputPorts)
|
||||
{
|
||||
Debug.Console(0, "WARNING: device '{0}' IR port {1} out of range",
|
||||
portDevKey, portNum);
|
||||
@@ -134,10 +134,9 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
var port = irDev.IROutputPorts[portNum];
|
||||
|
||||
port.LoadIRDriver(Global.FilePathPrefix + "IR" + Global.DirectorySeparator + control["irFile"].Value<string>());
|
||||
|
||||
|
||||
return port;
|
||||
|
||||
}
|
||||
|
||||
public static IrOutputPortController GetIrOutputPortController(DeviceConfig config)
|
||||
@@ -149,87 +148,88 @@ namespace PepperDash.Essentials.Core
|
||||
return null;
|
||||
}
|
||||
|
||||
var irDevice = new IrOutputPortController(config.Key, GetIrOutputPort, config);
|
||||
var postActivationFunc = new Func<DeviceConfig,IROutputPort> (GetIrOutputPort);
|
||||
var irDevice = new IrOutputPortController(config.Key + "-ir", postActivationFunc, config);
|
||||
|
||||
return irDevice;
|
||||
}
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
/// Returns a ready-to-go IrOutputPortController from a DeviceConfig object.
|
||||
/// </summary>
|
||||
public static IrOutputPortController GetIrOutputPortController(DeviceConfig devConf)
|
||||
{
|
||||
var irControllerKey = devConf.Key + "-ir";
|
||||
if (devConf.Properties == null)
|
||||
{
|
||||
Debug.Console(0, "[{0}] WARNING: Device config does not include properties. IR will not function.", devConf.Key);
|
||||
return new IrOutputPortController(irControllerKey, null, "");
|
||||
}
|
||||
|
||||
var control = devConf.Properties["control"];
|
||||
if (control == null)
|
||||
{
|
||||
var c = new IrOutputPortController(irControllerKey, null, "");
|
||||
Debug.Console(0, c, "WARNING: Device config does not include control properties. IR will not function");
|
||||
return c;
|
||||
}
|
||||
|
||||
var portDevKey = control.Value<string>("controlPortDevKey");
|
||||
var portNum = control.Value<uint>("controlPortNumber");
|
||||
IIROutputPorts irDev = null;
|
||||
|
||||
if (portDevKey == null)
|
||||
{
|
||||
var c = new IrOutputPortController(irControllerKey, null, "");
|
||||
Debug.Console(0, c, "WARNING: control properties is missing ir device");
|
||||
return c;
|
||||
}
|
||||
|
||||
if (portNum == 0)
|
||||
{
|
||||
var c = new IrOutputPortController(irControllerKey, null, "");
|
||||
Debug.Console(0, c, "WARNING: control properties is missing ir port number");
|
||||
return c;
|
||||
}
|
||||
|
||||
if (portDevKey.Equals("controlSystem", StringComparison.OrdinalIgnoreCase)
|
||||
|| portDevKey.Equals("processor", StringComparison.OrdinalIgnoreCase))
|
||||
irDev = Global.ControlSystem;
|
||||
else
|
||||
irDev = DeviceManager.GetDeviceForKey(portDevKey) as IIROutputPorts;
|
||||
|
||||
if (irDev == null)
|
||||
{
|
||||
var c = new IrOutputPortController(irControllerKey, null, "");
|
||||
Debug.Console(0, c, "WARNING: device with IR ports '{0}' not found", portDevKey);
|
||||
return c;
|
||||
}
|
||||
|
||||
if (portNum <= irDev.NumberOfIROutputPorts) // success!
|
||||
return new IrOutputPortController(irControllerKey, irDev.IROutputPorts[portNum],
|
||||
IrDriverPathPrefix + control["irFile"].Value<string>());
|
||||
else
|
||||
{
|
||||
var c = new IrOutputPortController(irControllerKey, null, "");
|
||||
Debug.Console(0, c, "WARNING: device '{0}' IR port {1} out of range",
|
||||
portDevKey, portNum);
|
||||
return c;
|
||||
}
|
||||
/*
|
||||
/// <summary>
|
||||
/// Returns a ready-to-go IrOutputPortController from a DeviceConfig object.
|
||||
/// </summary>
|
||||
public static IrOutputPortController GetIrOutputPortController(DeviceConfig devConf)
|
||||
{
|
||||
var irControllerKey = devConf.Key + "-ir";
|
||||
if (devConf.Properties == null)
|
||||
{
|
||||
Debug.Console(0, "[{0}] WARNING: Device config does not include properties. IR will not function.", devConf.Key);
|
||||
return new IrOutputPortController(irControllerKey, null, "");
|
||||
}
|
||||
|
||||
var control = devConf.Properties["control"];
|
||||
if (control == null)
|
||||
{
|
||||
var c = new IrOutputPortController(irControllerKey, null, "");
|
||||
Debug.Console(0, c, "WARNING: Device config does not include control properties. IR will not function");
|
||||
return c;
|
||||
}
|
||||
|
||||
var portDevKey = control.Value<string>("controlPortDevKey");
|
||||
var portNum = control.Value<uint>("controlPortNumber");
|
||||
IIROutputPorts irDev = null;
|
||||
|
||||
if (portDevKey == null)
|
||||
{
|
||||
var c = new IrOutputPortController(irControllerKey, null, "");
|
||||
Debug.Console(0, c, "WARNING: control properties is missing ir device");
|
||||
return c;
|
||||
}
|
||||
|
||||
if (portNum == 0)
|
||||
{
|
||||
var c = new IrOutputPortController(irControllerKey, null, "");
|
||||
Debug.Console(0, c, "WARNING: control properties is missing ir port number");
|
||||
return c;
|
||||
}
|
||||
|
||||
if (portDevKey.Equals("controlSystem", StringComparison.OrdinalIgnoreCase)
|
||||
|| portDevKey.Equals("processor", StringComparison.OrdinalIgnoreCase))
|
||||
irDev = Global.ControlSystem;
|
||||
else
|
||||
irDev = DeviceManager.GetDeviceForKey(portDevKey) as IIROutputPorts;
|
||||
|
||||
if (irDev == null)
|
||||
{
|
||||
var c = new IrOutputPortController(irControllerKey, null, "");
|
||||
Debug.Console(0, c, "WARNING: device with IR ports '{0}' not found", portDevKey);
|
||||
return c;
|
||||
}
|
||||
|
||||
if (portNum <= irDev.NumberOfIROutputPorts) // success!
|
||||
return new IrOutputPortController(irControllerKey, irDev.IROutputPorts[portNum],
|
||||
IrDriverPathPrefix + control["irFile"].Value<string>());
|
||||
else
|
||||
{
|
||||
var c = new IrOutputPortController(irControllerKey, null, "");
|
||||
Debug.Console(0, c, "WARNING: device '{0}' IR port {1} out of range",
|
||||
portDevKey, portNum);
|
||||
return c;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper to help in IR port creation
|
||||
/// </summary>
|
||||
public class IrOutPortConfig
|
||||
{
|
||||
public IROutputPort Port { get; set; }
|
||||
public string FileName { get; set; }
|
||||
|
||||
public IrOutPortConfig()
|
||||
{
|
||||
FileName = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper to help in IR port creation
|
||||
/// </summary>
|
||||
public class IrOutPortConfig
|
||||
{
|
||||
public IROutputPort Port { get; set; }
|
||||
public string FileName { get; set; }
|
||||
|
||||
public IrOutPortConfig()
|
||||
{
|
||||
FileName = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Config
|
||||
{
|
||||
@@ -23,11 +20,24 @@ namespace PepperDash.Essentials.Core.Config
|
||||
[JsonProperty("sourceLists")]
|
||||
public Dictionary<string, Dictionary<string, SourceListItem>> SourceLists { get; set; }
|
||||
|
||||
[JsonProperty("tieLines")]
|
||||
[JsonProperty("destinationLists")]
|
||||
public Dictionary<string, Dictionary<string,DestinationListItem>> DestinationLists { get; set; }
|
||||
|
||||
[JsonProperty("tieLines")]
|
||||
public List<TieLineConfig> TieLines { get; set; }
|
||||
|
||||
[JsonProperty("joinMaps")]
|
||||
public Dictionary<string, string> JoinMaps { get; set; }
|
||||
public Dictionary<string, JObject> JoinMaps { get; set; }
|
||||
|
||||
public BasicConfig()
|
||||
{
|
||||
Info = new InfoConfig();
|
||||
Devices = new List<DeviceConfig>();
|
||||
SourceLists = new Dictionary<string, Dictionary<string, SourceListItem>>();
|
||||
DestinationLists = new Dictionary<string, Dictionary<string, DestinationListItem>>();
|
||||
TieLines = new List<TieLineConfig>();
|
||||
JoinMaps = new Dictionary<string, JObject>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks SourceLists for a given list and returns it if found. Otherwise, returns null
|
||||
@@ -40,6 +50,21 @@ namespace PepperDash.Essentials.Core.Config
|
||||
return SourceLists[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a DestinationListItem based on the key
|
||||
/// </summary>
|
||||
/// <param name="key">key of the item to retrieve</param>
|
||||
/// <returns>DestinationListItem if the key exists, null otherwise</returns>
|
||||
public Dictionary<string, DestinationListItem> GetDestinationListForKey(string key)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key) || !DestinationLists.ContainsKey(key))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return DestinationLists[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks Devices for an item with a Key that matches and returns it if found. Otherwise, retunes null
|
||||
/// </summary>
|
||||
|
||||
@@ -30,7 +30,19 @@ namespace PepperDash.Essentials.Core.Config
|
||||
|
||||
[JsonProperty("properties")]
|
||||
[JsonConverter(typeof(DevicePropertiesConverter))]
|
||||
public JToken Properties { get; set; }
|
||||
public JToken Properties { get; set; }
|
||||
|
||||
public DeviceConfig(DeviceConfig dc)
|
||||
{
|
||||
Key = dc.Key;
|
||||
Uid = dc.Uid;
|
||||
Name = dc.Name;
|
||||
Group = dc.Group;
|
||||
Type = dc.Type;
|
||||
Properties = JToken.FromObject(dc.Properties);
|
||||
}
|
||||
|
||||
public DeviceConfig() {}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,183 +1,254 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// Loads the ConfigObject from the file
|
||||
/// </summary>
|
||||
public class ConfigReader
|
||||
{
|
||||
public static EssentialsConfig ConfigObject { get; private set; }
|
||||
|
||||
public static bool LoadConfig2()
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading unmerged system/template portal configuration file.");
|
||||
try
|
||||
{
|
||||
// Check for local config file first
|
||||
var filePath = Global.FilePathPrefix + ConfigWriter.LocalConfigFolder + Global.DirectorySeparator + Global.ConfigFileName;
|
||||
|
||||
bool localConfigFound = false;
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to load Local config file: '{0}'", filePath);
|
||||
|
||||
// Check for local config directory first
|
||||
|
||||
var configFiles = GetConfigFiles(filePath);
|
||||
|
||||
if (configFiles != null)
|
||||
{
|
||||
if (configFiles.Length > 1)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"****Error: Multiple Local Configuration files present. Please ensure only a single file exists and reset program.****");
|
||||
return false;
|
||||
}
|
||||
else if(configFiles.Length == 1)
|
||||
{
|
||||
localConfigFound = true;
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Found Local config file: '{0}'", filePath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice,
|
||||
"Local Configuration file not present.", filePath);
|
||||
|
||||
}
|
||||
|
||||
// Check for Portal Config
|
||||
if(!localConfigFound)
|
||||
{
|
||||
filePath = Global.FilePathPrefix + Global.ConfigFileName;
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to load Portal config file: '{0}'", filePath);
|
||||
|
||||
configFiles = GetConfigFiles(filePath);
|
||||
|
||||
if (configFiles != null)
|
||||
{
|
||||
Debug.Console(2, "{0} config files found matching pattern", configFiles.Length);
|
||||
|
||||
if (configFiles.Length > 1)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"****Error: Multiple Portal Configuration files present. Please ensure only a single file exists and reset program.****");
|
||||
return false;
|
||||
}
|
||||
else if (configFiles.Length == 1)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Found Portal config file: '{0}'", filePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "No config file found.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"ERROR: Portal Configuration file not present. Please load file and reset program.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the actual file path
|
||||
filePath = configFiles[0].FullName;
|
||||
|
||||
// Read the file
|
||||
using (StreamReader fs = new StreamReader(filePath))
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading config file: '{0}'", filePath);
|
||||
|
||||
if (localConfigFound)
|
||||
{
|
||||
ConfigObject = JObject.Parse(fs.ReadToEnd()).ToObject<EssentialsConfig>();
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Successfully Loaded Local Config");
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var doubleObj = JObject.Parse(fs.ReadToEnd());
|
||||
ConfigObject = PortalConfigReader.MergeConfigs(doubleObj).ToObject<EssentialsConfig>();
|
||||
|
||||
// Extract SystemUrl and TemplateUrl into final config output
|
||||
|
||||
if (doubleObj["system_url"] != null)
|
||||
{
|
||||
ConfigObject.SystemUrl = doubleObj["system_url"].Value<string>();
|
||||
}
|
||||
|
||||
if (doubleObj["template_url"] != null)
|
||||
{
|
||||
ConfigObject.TemplateUrl = doubleObj["template_url"].Value<string>();
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Successfully Loaded Merged Config");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "ERROR: Config load failed: \r{0}", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all the files from the directory specified.
|
||||
/// </summary>
|
||||
/// <param name="filePath"></param>
|
||||
/// <returns></returns>
|
||||
public static FileInfo[] GetConfigFiles(string filePath)
|
||||
{
|
||||
// Get the directory
|
||||
var dir = Path.GetDirectoryName(filePath);
|
||||
|
||||
if (Directory.Exists(dir))
|
||||
{
|
||||
Debug.Console(1, "Searching in Directory '{0}'", dir);
|
||||
// Get the directory info
|
||||
var dirInfo = new DirectoryInfo(dir);
|
||||
|
||||
// Get the file name
|
||||
var fileName = Path.GetFileName(filePath);
|
||||
Debug.Console(1, "For Config Files matching: '{0}'", fileName);
|
||||
|
||||
// Get the files that match from the directory
|
||||
return dirInfo.GetFiles(fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice,
|
||||
"Directory not found: ", dir);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the group for a given device key in config
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetGroupForDeviceKey(string key)
|
||||
{
|
||||
var dev = ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
|
||||
return dev == null ? null : dev.Group;
|
||||
}
|
||||
|
||||
}
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// Loads the ConfigObject from the file
|
||||
/// </summary>
|
||||
public class ConfigReader
|
||||
{
|
||||
public const string LocalConfigPresent =
|
||||
@"
|
||||
***************************************************
|
||||
************* Using Local config file *************
|
||||
***************************************************";
|
||||
|
||||
public static EssentialsConfig ConfigObject { get; private set; }
|
||||
|
||||
public static bool LoadConfig2()
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading unmerged system/template portal configuration file.");
|
||||
try
|
||||
{
|
||||
// Check for local config file first
|
||||
var filePath = Global.FilePathPrefix + ConfigWriter.LocalConfigFolder + Global.DirectorySeparator + Global.ConfigFileName;
|
||||
|
||||
bool localConfigFound = false;
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to load Local config file: '{0}'", filePath);
|
||||
|
||||
// Check for local config directory first
|
||||
|
||||
var configFiles = GetConfigFiles(filePath);
|
||||
|
||||
if (configFiles != null)
|
||||
{
|
||||
if (configFiles.Length > 1)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"****Error: Multiple Local Configuration files present. Please ensure only a single file exists and reset program.****");
|
||||
return false;
|
||||
}
|
||||
if(configFiles.Length == 1)
|
||||
{
|
||||
localConfigFound = true;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice,
|
||||
"Local Configuration file not present.", filePath);
|
||||
|
||||
}
|
||||
|
||||
// Check for Portal Config
|
||||
if(!localConfigFound)
|
||||
{
|
||||
filePath = Global.FilePathPrefix + Global.ConfigFileName;
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to load Portal config file: '{0}'", filePath);
|
||||
|
||||
configFiles = GetConfigFiles(filePath);
|
||||
|
||||
if (configFiles != null)
|
||||
{
|
||||
Debug.Console(2, "{0} config files found matching pattern", configFiles.Length);
|
||||
|
||||
if (configFiles.Length > 1)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"****Error: Multiple Portal Configuration files present. Please ensure only a single file exists and reset program.****");
|
||||
return false;
|
||||
}
|
||||
else if (configFiles.Length == 1)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Found Portal config file: '{0}'", filePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "No config file found.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"ERROR: Portal Configuration file not present. Please load file and reset program.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the actual file path
|
||||
filePath = configFiles[0].FullName;
|
||||
|
||||
// Generate debug statement if using a local file.
|
||||
if (localConfigFound)
|
||||
{
|
||||
GetLocalFileMessage(filePath);
|
||||
}
|
||||
|
||||
// Read the file
|
||||
using (StreamReader fs = new StreamReader(filePath))
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading config file: '{0}'", filePath);
|
||||
|
||||
if (localConfigFound)
|
||||
{
|
||||
ConfigObject = JObject.Parse(fs.ReadToEnd()).ToObject<EssentialsConfig>();
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Successfully Loaded Local Config");
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var doubleObj = JObject.Parse(fs.ReadToEnd());
|
||||
ConfigObject = PortalConfigReader.MergeConfigs(doubleObj).ToObject<EssentialsConfig>();
|
||||
|
||||
// Extract SystemUrl and TemplateUrl into final config output
|
||||
|
||||
if (doubleObj["system_url"] != null)
|
||||
{
|
||||
ConfigObject.SystemUrl = doubleObj["system_url"].Value<string>();
|
||||
}
|
||||
|
||||
if (doubleObj["template_url"] != null)
|
||||
{
|
||||
ConfigObject.TemplateUrl = doubleObj["template_url"].Value<string>();
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Successfully Loaded Merged Config");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "ERROR: Config load failed: \r{0}", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all the files from the directory specified.
|
||||
/// </summary>
|
||||
/// <param name="filePath"></param>
|
||||
/// <returns></returns>
|
||||
public static FileInfo[] GetConfigFiles(string filePath)
|
||||
{
|
||||
// Get the directory
|
||||
var dir = Path.GetDirectoryName(filePath);
|
||||
|
||||
if (Directory.Exists(dir))
|
||||
{
|
||||
Debug.Console(1, "Searching in Directory '{0}'", dir);
|
||||
// Get the directory info
|
||||
var dirInfo = new DirectoryInfo(dir);
|
||||
|
||||
// Get the file name
|
||||
var fileName = Path.GetFileName(filePath);
|
||||
Debug.Console(1, "For Config Files matching: '{0}'", fileName);
|
||||
|
||||
// Get the files that match from the directory
|
||||
return dirInfo.GetFiles(fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice,
|
||||
"Directory not found: ", dir);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the group for a given device key in config
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetGroupForDeviceKey(string key)
|
||||
{
|
||||
var dev = ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
|
||||
return dev == null ? null : dev.Group;
|
||||
}
|
||||
|
||||
private static void GetLocalFileMessage(string filePath)
|
||||
{
|
||||
var filePathLength = filePath.Length + 2;
|
||||
var debugStringWidth = filePathLength + 12;
|
||||
|
||||
if (debugStringWidth < 51)
|
||||
{
|
||||
debugStringWidth = 51;
|
||||
}
|
||||
var qualifier = (filePathLength % 2 != 0)
|
||||
? " Using Local Config File "
|
||||
: " Using Local Config File ";
|
||||
var bookend1 = (debugStringWidth - qualifier.Length) / 2;
|
||||
var bookend2 = (debugStringWidth - filePathLength) / 2;
|
||||
|
||||
|
||||
var newDebugString = new StringBuilder()
|
||||
.Append(CrestronEnvironment.NewLine)
|
||||
// Line 1
|
||||
.Append(new string('*', debugStringWidth))
|
||||
.Append(CrestronEnvironment.NewLine)
|
||||
// Line 2
|
||||
.Append(new string('*', debugStringWidth))
|
||||
.Append(CrestronEnvironment.NewLine)
|
||||
// Line 3
|
||||
.Append(new string('*', 2))
|
||||
.Append(new string(' ', debugStringWidth - 4))
|
||||
.Append(new string('*', 2))
|
||||
.Append(CrestronEnvironment.NewLine)
|
||||
// Line 4
|
||||
.Append(new string('*', 2))
|
||||
.Append(new string(' ', bookend1 - 2))
|
||||
.Append(qualifier)
|
||||
.Append(new string(' ', bookend1 - 2))
|
||||
.Append(new string('*', 2))
|
||||
.Append(CrestronEnvironment.NewLine)
|
||||
// Line 5
|
||||
.Append(new string('*', 2))
|
||||
.Append(new string(' ', bookend2 - 2))
|
||||
.Append(" " + filePath + " ")
|
||||
.Append(new string(' ', bookend2 - 2))
|
||||
.Append(new string('*', 2))
|
||||
.Append(CrestronEnvironment.NewLine)
|
||||
// Line 6
|
||||
.Append(new string('*', 2))
|
||||
.Append(new string(' ', debugStringWidth - 4))
|
||||
.Append(new string('*', 2))
|
||||
.Append(CrestronEnvironment.NewLine)
|
||||
// Line 7
|
||||
.Append(new string('*', debugStringWidth))
|
||||
.Append(CrestronEnvironment.NewLine)
|
||||
// Line 8
|
||||
.Append(new string('*', debugStringWidth));
|
||||
|
||||
Debug.Console(2, Debug.ErrorLogLevel.Notice, "Found Local config file: '{0}'", filePath);
|
||||
Debug.Console(0, newDebugString.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,162 +1,162 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// Responsible for updating config at runtime, and writing the updates out to a local file
|
||||
/// </summary>
|
||||
public class ConfigWriter
|
||||
{
|
||||
public const string LocalConfigFolder = "LocalConfig";
|
||||
|
||||
public const long WriteTimeout = 30000;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// Responsible for updating config at runtime, and writing the updates out to a local file
|
||||
/// </summary>
|
||||
public class ConfigWriter
|
||||
{
|
||||
public const string LocalConfigFolder = "LocalConfig";
|
||||
|
||||
public const long WriteTimeout = 30000;
|
||||
|
||||
public static CTimer WriteTimer;
|
||||
static CCriticalSection fileLock = new CCriticalSection();
|
||||
|
||||
/// <summary>
|
||||
/// Updates the config properties of a device
|
||||
/// </summary>
|
||||
/// <param name="deviceKey"></param>
|
||||
/// <param name="properties"></param>
|
||||
/// <returns></returns>
|
||||
public static bool UpdateDeviceProperties(string deviceKey, JToken properties)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
// Get the current device config
|
||||
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(deviceKey));
|
||||
|
||||
if (deviceConfig != null)
|
||||
{
|
||||
// Replace the current properties JToken with the new one passed into this method
|
||||
deviceConfig.Properties = properties;
|
||||
|
||||
Debug.Console(1, "Updated properties of device: '{0}'", deviceKey);
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
||||
ResetTimer();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
public static bool UpdateDeviceConfig(DeviceConfig config)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(config.Key));
|
||||
|
||||
if (deviceConfig != null)
|
||||
{
|
||||
deviceConfig = config;
|
||||
|
||||
Debug.Console(1, "Updated config of device: '{0}'", config.Key);
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
||||
ResetTimer();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
public static bool UpdateRoomConfig(DeviceConfig config)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
var deviceConfig = ConfigReader.ConfigObject.Rooms.FirstOrDefault(d => d.Key.Equals(config.Key));
|
||||
|
||||
if (deviceConfig != null)
|
||||
{
|
||||
deviceConfig = config;
|
||||
|
||||
Debug.Console(1, "Updated config of device: '{0}'", config.Key);
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
||||
ResetTimer();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets (or starts) the write timer
|
||||
/// </summary>
|
||||
static void ResetTimer()
|
||||
{
|
||||
if (WriteTimer == null)
|
||||
WriteTimer = new CTimer(WriteConfigFile, WriteTimeout);
|
||||
|
||||
WriteTimer.Reset(WriteTimeout);
|
||||
|
||||
Debug.Console(1, "Config File write timer has been reset.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the current config to a file in the LocalConfig subfolder
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static void WriteConfigFile(object o)
|
||||
{
|
||||
var filePath = Global.FilePathPrefix + LocalConfigFolder + Global.DirectorySeparator + "configurationFile.json";
|
||||
|
||||
var configData = JsonConvert.SerializeObject(ConfigReader.ConfigObject);
|
||||
|
||||
WriteFile(filePath, configData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes
|
||||
/// </summary>
|
||||
/// <param name="filepath"></param>
|
||||
/// <param name="o"></param>
|
||||
public static void WriteFile(string filePath, string configData)
|
||||
{
|
||||
if (WriteTimer != null)
|
||||
WriteTimer.Stop();
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Writing Configuration to file");
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to write config file: '{0}'", filePath);
|
||||
|
||||
try
|
||||
{
|
||||
if (fileLock.TryEnter())
|
||||
{
|
||||
using (StreamWriter sw = new StreamWriter(filePath))
|
||||
{
|
||||
sw.Write(configData);
|
||||
sw.Flush();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to enter FileLock");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: Config write failed: \r{0}", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (fileLock != null && !fileLock.Disposed)
|
||||
fileLock.Leave();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
static CCriticalSection fileLock = new CCriticalSection();
|
||||
|
||||
/// <summary>
|
||||
/// Updates the config properties of a device
|
||||
/// </summary>
|
||||
/// <param name="deviceKey"></param>
|
||||
/// <param name="properties"></param>
|
||||
/// <returns></returns>
|
||||
public static bool UpdateDeviceProperties(string deviceKey, JToken properties)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
// Get the current device config
|
||||
var deviceConfig = ConfigReader.ConfigObject.Devices.FirstOrDefault(d => d.Key.Equals(deviceKey));
|
||||
|
||||
if (deviceConfig != null)
|
||||
{
|
||||
// Replace the current properties JToken with the new one passed into this method
|
||||
deviceConfig.Properties = properties;
|
||||
|
||||
Debug.Console(1, "Updated properties of device: '{0}'", deviceKey);
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
||||
ResetTimer();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
public static bool UpdateDeviceConfig(DeviceConfig config)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
var deviceConfigIndex = ConfigReader.ConfigObject.Devices.FindIndex(d => d.Key.Equals(config.Key));
|
||||
|
||||
if (deviceConfigIndex >= 0)
|
||||
{
|
||||
ConfigReader.ConfigObject.Devices[deviceConfigIndex] = config;
|
||||
|
||||
Debug.Console(1, "Updated config of device: '{0}'", config.Key);
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
||||
ResetTimer();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
public static bool UpdateRoomConfig(DeviceConfig config)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
var roomConfigIndex = ConfigReader.ConfigObject.Rooms.FindIndex(d => d.Key.Equals(config.Key));
|
||||
|
||||
if (roomConfigIndex >= 0)
|
||||
{
|
||||
ConfigReader.ConfigObject.Rooms[roomConfigIndex] = config;
|
||||
|
||||
Debug.Console(1, "Updated room of device: '{0}'", config.Key);
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
||||
ResetTimer();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets (or starts) the write timer
|
||||
/// </summary>
|
||||
static void ResetTimer()
|
||||
{
|
||||
if (WriteTimer == null)
|
||||
WriteTimer = new CTimer(WriteConfigFile, WriteTimeout);
|
||||
|
||||
WriteTimer.Reset(WriteTimeout);
|
||||
|
||||
Debug.Console(1, "Config File write timer has been reset.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the current config to a file in the LocalConfig subfolder
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static void WriteConfigFile(object o)
|
||||
{
|
||||
var filePath = Global.FilePathPrefix + LocalConfigFolder + Global.DirectorySeparator + "configurationFile.json";
|
||||
|
||||
var configData = JsonConvert.SerializeObject(ConfigReader.ConfigObject);
|
||||
|
||||
WriteFile(filePath, configData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes
|
||||
/// </summary>
|
||||
/// <param name="filepath"></param>
|
||||
/// <param name="o"></param>
|
||||
public static void WriteFile(string filePath, string configData)
|
||||
{
|
||||
if (WriteTimer != null)
|
||||
WriteTimer.Stop();
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Writing Configuration to file");
|
||||
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to write config file: '{0}'", filePath);
|
||||
|
||||
try
|
||||
{
|
||||
if (fileLock.TryEnter())
|
||||
{
|
||||
using (StreamWriter sw = new StreamWriter(filePath))
|
||||
{
|
||||
sw.Write(configData);
|
||||
sw.Flush();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Unable to enter FileLock");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: Config write failed: \r{0}", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (fileLock != null && !fileLock.Disposed)
|
||||
fileLock.Leave();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,13 @@ namespace PepperDash.Essentials.Core.Config
|
||||
|
||||
[JsonProperty("rooms")]
|
||||
public List<DeviceConfig> Rooms { get; set; }
|
||||
|
||||
|
||||
public EssentialsConfig()
|
||||
: base()
|
||||
{
|
||||
Rooms = new List<DeviceConfig>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using System;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.Reflection;
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace PepperDash.Essentials.Core.Config
|
||||
// }
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>,
|
||||
/// The OS Version of the processor (Firmware Version)
|
||||
/// </summary>
|
||||
[JsonProperty("osVersion")]
|
||||
@@ -92,5 +92,18 @@ namespace PepperDash.Essentials.Core.Config
|
||||
// return Crestron.SimplSharp.CrestronEnvironment.OSVersion.Firmware;
|
||||
// }
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// The information gathered by the processor at runtime about it's NICs and their IP addresses.
|
||||
/// </summary>
|
||||
[JsonProperty("ipInfo")]
|
||||
public Dictionary<short, EthernetAdapterInfo> IpInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
return Global.EthernetAdapterInfoCollection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -73,21 +73,21 @@ namespace PepperDash.Essentials.Core.CrestronIO.Cards
|
||||
string cardType;
|
||||
if (!_config.Cards.TryGetValue(i, out cardType))
|
||||
{
|
||||
Debug.Console(1, this, "No card found for slot {0}", i);
|
||||
Debug.Console(0, this, "No card found for slot {0}", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(cardType))
|
||||
{
|
||||
Debug.Console(0, this, "No card specified for slot {0}", i);
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
Func<uint, C3CardControllerBase> cardBuilder;
|
||||
if (!_cardDict.TryGetValue(cardType.ToLower(), out cardBuilder))
|
||||
{
|
||||
Debug.Console(0, "Unable to find factory for 3-Series card type {0}.", cardType);
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
|
||||
@@ -1,38 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO
|
||||
{
|
||||
[Description("Wrapper class for Digital Input")]
|
||||
public class GenericDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput
|
||||
{
|
||||
public DigitalInput InputPort { get; private set; }
|
||||
|
||||
public BoolFeedback InputStateFeedback { get; private set; }
|
||||
|
||||
Func<bool> InputStateFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () => InputPort.State;
|
||||
}
|
||||
}
|
||||
public class GenericDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput
|
||||
{
|
||||
public DigitalInput InputPort { get; private set; }
|
||||
|
||||
public BoolFeedback InputStateFeedback { get; private set; }
|
||||
|
||||
Func<bool> InputStateFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () => InputPort.State;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public GenericDigitalInputDevice(string key, string name, Func<IOPortConfig, DigitalInput> postActivationFunc,
|
||||
IOPortConfig config)
|
||||
: base(key, name)
|
||||
{
|
||||
InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc);
|
||||
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
@@ -40,15 +41,15 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
|
||||
InputPort.Register();
|
||||
|
||||
InputPort.StateChange += InputPort_StateChange;
|
||||
InputPort.StateChange += InputPort_StateChange;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
#region Events
|
||||
|
||||
void InputPort_StateChange(DigitalInput digitalInput, DigitalInputEventArgs args)
|
||||
{
|
||||
void InputPort_StateChange(DigitalInput digitalInput, DigitalInputEventArgs args)
|
||||
{
|
||||
InputStateFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
@@ -81,7 +82,7 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
}
|
||||
if (ioPortDevice == null)
|
||||
{
|
||||
Debug.Console(0, "GetDigitalInput: Device '0' is not a valid IRelayPorts Device", dc.PortDeviceKey);
|
||||
Debug.Console(0, "GetDigitalInput: Device '0' is not a valid IDigitalInputPorts Device", dc.PortDeviceKey);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -99,13 +100,13 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
|
||||
#region Bridge Linking
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new IDigitalInputJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
var joinMap = new IDigitalInputJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<IDigitalInputJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
@@ -115,19 +116,19 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
// Link feedback for input state
|
||||
InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "Unable to link device '{0}'. Input is null", Key);
|
||||
Debug.Console(1, this, "Error: {0}", e);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
// Link feedback for input state
|
||||
InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "Unable to link device '{0}'. Input is null", Key);
|
||||
Debug.Console(1, this, "Error: {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +145,7 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new Generic Relay Device");
|
||||
Debug.Console(1, "Factory Attempting to create new Generic Digital Input Device");
|
||||
|
||||
var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString());
|
||||
|
||||
@@ -158,7 +159,7 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -4,15 +4,21 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a generic digital input deviced tied to a versiport
|
||||
/// </summary>
|
||||
public class GenericVersiportDigitalInputDevice : EssentialsDevice, IDigitalInput
|
||||
public class GenericVersiportDigitalInputDevice : EssentialsBridgeableDevice, IDigitalInput
|
||||
{
|
||||
public Versiport InputPort { get; private set; }
|
||||
|
||||
@@ -26,17 +32,29 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
}
|
||||
}
|
||||
|
||||
public GenericVersiportDigitalInputDevice(string key, Versiport inputPort, IOPortConfig props):
|
||||
base(key)
|
||||
public GenericVersiportDigitalInputDevice(string key, string name, Func<IOPortConfig, Versiport> postActivationFunc, IOPortConfig config) :
|
||||
base(key, name)
|
||||
{
|
||||
InputStateFeedback = new BoolFeedback(InputStateFeedbackFunc);
|
||||
InputPort = inputPort;
|
||||
InputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalInput);
|
||||
if (props.DisablePullUpResistor)
|
||||
InputPort.DisablePullUpResistor = true;
|
||||
InputPort.VersiportChange += new VersiportEventHandler(InputPort_VersiportChange);
|
||||
|
||||
Debug.Console(1, this, "Created GenericVersiportDigitalInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", props.PortNumber, InputPort.DisablePullUpResistor);
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
InputPort = postActivationFunc(config);
|
||||
|
||||
InputPort.Register();
|
||||
|
||||
InputPort.SetVersiportConfiguration(eVersiportConfiguration.DigitalInput);
|
||||
if (config.DisablePullUpResistor)
|
||||
InputPort.DisablePullUpResistor = true;
|
||||
|
||||
InputPort.VersiportChange += InputPort_VersiportChange;
|
||||
|
||||
|
||||
|
||||
Debug.Console(1, this, "Created GenericVersiportDigitalInputDevice on port '{0}'. DisablePullUpResistor: '{1}'", config.PortNumber, InputPort.DisablePullUpResistor);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void InputPort_VersiportChange(Versiport port, VersiportEventArgs args)
|
||||
@@ -46,5 +64,105 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
if(args.Event == eVersiportEvent.DigitalInChange)
|
||||
InputStateFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
|
||||
#region Bridge Linking
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new IDigitalInputJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<IDigitalInputJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
// Link feedback for input state
|
||||
InputStateFeedback.LinkInputSig(trilist.BooleanInput[joinMap.InputState.JoinNumber]);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "Unable to link device '{0}'. Input is null", Key);
|
||||
Debug.Console(1, this, "Error: {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public static Versiport GetVersiportDigitalInput(IOPortConfig dc)
|
||||
{
|
||||
|
||||
IIOPorts ioPortDevice;
|
||||
|
||||
if (dc.PortDeviceKey.Equals("processor"))
|
||||
{
|
||||
if (!Global.ControlSystem.SupportsVersiport)
|
||||
{
|
||||
Debug.Console(0, "GetVersiportDigitalInput: Processor does not support Versiports");
|
||||
return null;
|
||||
}
|
||||
ioPortDevice = Global.ControlSystem;
|
||||
}
|
||||
else
|
||||
{
|
||||
var ioPortDev = DeviceManager.GetDeviceForKey(dc.PortDeviceKey) as IIOPorts;
|
||||
if (ioPortDev == null)
|
||||
{
|
||||
Debug.Console(0, "GetVersiportDigitalInput: Device {0} is not a valid device", dc.PortDeviceKey);
|
||||
return null;
|
||||
}
|
||||
ioPortDevice = ioPortDev;
|
||||
}
|
||||
if (ioPortDevice == null)
|
||||
{
|
||||
Debug.Console(0, "GetVersiportDigitalInput: Device '0' is not a valid IIOPorts Device", dc.PortDeviceKey);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (dc.PortNumber > ioPortDevice.NumberOfVersiPorts)
|
||||
{
|
||||
Debug.Console(0, "GetVersiportDigitalInput: Device {0} does not contain a port {1}", dc.PortDeviceKey, dc.PortNumber);
|
||||
}
|
||||
|
||||
return ioPortDevice.VersiPorts[dc.PortNumber];
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class GenericVersiportDigitalInputDeviceFactory : EssentialsDeviceFactory<GenericVersiportDigitalInputDevice>
|
||||
{
|
||||
public GenericVersiportDigitalInputDeviceFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "versiportinput" };
|
||||
}
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new Generic Versiport Device");
|
||||
|
||||
var props = JsonConvert.DeserializeObject<IOPortConfig>(dc.Properties.ToString());
|
||||
|
||||
if (props == null) return null;
|
||||
|
||||
var portDevice = new GenericVersiportDigitalInputDevice(dc.Key, dc.Name, GenericVersiportDigitalInputDevice.GetVersiportDigitalInput, props);
|
||||
|
||||
return portDevice;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a generic device controlled by relays
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.CrestronIO
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a generic device controlled by relays
|
||||
/// </summary>
|
||||
[Description("Wrapper class for a Relay")]
|
||||
public class GenericRelayDevice : EssentialsBridgeableDevice, ISwitchedOutput
|
||||
{
|
||||
public Relay RelayOutput { get; private set; }
|
||||
|
||||
public class GenericRelayDevice : EssentialsBridgeableDevice, ISwitchedOutput
|
||||
{
|
||||
public Relay RelayOutput { get; private set; }
|
||||
|
||||
public BoolFeedback OutputIsOnFeedback { get; private set; }
|
||||
|
||||
//Maintained for compatibility with PepperDash.Essentials.Core.Devices.CrestronProcessor
|
||||
@@ -94,11 +94,11 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
|
||||
#region Events
|
||||
|
||||
void RelayOutput_StateChange(Relay relay, RelayEventArgs args)
|
||||
{
|
||||
void RelayOutput_StateChange(Relay relay, RelayEventArgs args)
|
||||
{
|
||||
OutputIsOnFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
@@ -119,33 +119,33 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
OpenRelay();
|
||||
else
|
||||
CloseRelay();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ISwitchedOutput Members
|
||||
|
||||
void ISwitchedOutput.On()
|
||||
{
|
||||
CloseRelay();
|
||||
}
|
||||
|
||||
void ISwitchedOutput.Off()
|
||||
{
|
||||
OpenRelay();
|
||||
}
|
||||
|
||||
|
||||
#region ISwitchedOutput Members
|
||||
|
||||
void ISwitchedOutput.On()
|
||||
{
|
||||
CloseRelay();
|
||||
}
|
||||
|
||||
void ISwitchedOutput.Off()
|
||||
{
|
||||
OpenRelay();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Bridge Linking
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new GenericRelayControllerJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
var joinMap = new GenericRelayControllerJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<GenericRelayControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
@@ -155,26 +155,26 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
if (RelayOutput == null)
|
||||
{
|
||||
Debug.Console(1, this, "Unable to link device '{0}'. Relay is null", Key);
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
trilist.SetBoolSigAction(joinMap.Relay.JoinNumber, b =>
|
||||
{
|
||||
if (b)
|
||||
CloseRelay();
|
||||
else
|
||||
OpenRelay();
|
||||
});
|
||||
|
||||
// feedback for relay state
|
||||
|
||||
}
|
||||
|
||||
if (RelayOutput == null)
|
||||
{
|
||||
Debug.Console(1, this, "Unable to link device '{0}'. Relay is null", Key);
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
trilist.SetBoolSigAction(joinMap.Relay.JoinNumber, b =>
|
||||
{
|
||||
if (b)
|
||||
CloseRelay();
|
||||
else
|
||||
OpenRelay();
|
||||
});
|
||||
|
||||
// feedback for relay state
|
||||
|
||||
OutputIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.Relay.JoinNumber]);
|
||||
}
|
||||
|
||||
@@ -202,54 +202,54 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
return portDevice;
|
||||
|
||||
|
||||
/*
|
||||
if (props.PortDeviceKey == "processor")
|
||||
portDevice = Global.ControlSystem as IRelayPorts;
|
||||
else
|
||||
portDevice = DeviceManager.GetDeviceForKey(props.PortDeviceKey) as IRelayPorts;
|
||||
|
||||
if (portDevice == null)
|
||||
Debug.Console(0, "Unable to add relay device with key '{0}'. Port Device does not support relays", key);
|
||||
else
|
||||
{
|
||||
var cs = (portDevice as CrestronControlSystem);
|
||||
|
||||
if (cs != null)
|
||||
{
|
||||
// The relay is on a control system processor
|
||||
if (!cs.SupportsRelay || props.PortNumber > cs.NumberOfRelayPorts)
|
||||
{
|
||||
Debug.Console(0, "Port Device: {0} does not support relays or does not have enough relays");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The relay is on another device type
|
||||
|
||||
if (props.PortNumber > portDevice.NumberOfRelayPorts)
|
||||
{
|
||||
Debug.Console(0, "Port Device: {0} does not have enough relays");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Relay relay = portDevice.RelayPorts[props.PortNumber];
|
||||
|
||||
if (!relay.Registered)
|
||||
{
|
||||
if (relay.Register() == eDeviceRegistrationUnRegistrationResponse.Success)
|
||||
return new GenericRelayDevice(key, relay);
|
||||
else
|
||||
Debug.Console(0, "Attempt to register relay {0} on device with key '{1}' failed.", props.PortNumber, props.PortDeviceKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new GenericRelayDevice(key, relay);
|
||||
}
|
||||
|
||||
// Future: Check if portDevice is 3-series card or other non control system that supports versiports
|
||||
}
|
||||
/*
|
||||
if (props.PortDeviceKey == "processor")
|
||||
portDevice = Global.ControlSystem as IRelayPorts;
|
||||
else
|
||||
portDevice = DeviceManager.GetDeviceForKey(props.PortDeviceKey) as IRelayPorts;
|
||||
|
||||
if (portDevice == null)
|
||||
Debug.Console(0, "Unable to add relay device with key '{0}'. Port Device does not support relays", key);
|
||||
else
|
||||
{
|
||||
var cs = (portDevice as CrestronControlSystem);
|
||||
|
||||
if (cs != null)
|
||||
{
|
||||
// The relay is on a control system processor
|
||||
if (!cs.SupportsRelay || props.PortNumber > cs.NumberOfRelayPorts)
|
||||
{
|
||||
Debug.Console(0, "Port Device: {0} does not support relays or does not have enough relays");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The relay is on another device type
|
||||
|
||||
if (props.PortNumber > portDevice.NumberOfRelayPorts)
|
||||
{
|
||||
Debug.Console(0, "Port Device: {0} does not have enough relays");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Relay relay = portDevice.RelayPorts[props.PortNumber];
|
||||
|
||||
if (!relay.Registered)
|
||||
{
|
||||
if (relay.Register() == eDeviceRegistrationUnRegistrationResponse.Success)
|
||||
return new GenericRelayDevice(key, relay);
|
||||
else
|
||||
Debug.Console(0, "Attempt to register relay {0} on device with key '{1}' failed.", props.PortNumber, props.PortDeviceKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new GenericRelayDevice(key, relay);
|
||||
}
|
||||
|
||||
// Future: Check if portDevice is 3-series card or other non control system that supports versiports
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
@@ -258,7 +258,7 @@ namespace PepperDash.Essentials.Core.CrestronIO
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -130,6 +130,12 @@ namespace PepperDash.Essentials.Core
|
||||
void Hardware_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
|
||||
{
|
||||
Debug.Console(2, this, "OnlineStatusChange Event. Online = {0}", args.DeviceOnLine);
|
||||
|
||||
if (!Hardware.Registered)
|
||||
{
|
||||
return; // protects in cases where device has been unregistered and feedbacks would attempt to access null sigs.
|
||||
}
|
||||
|
||||
foreach (var feedback in Feedbacks)
|
||||
{
|
||||
if (feedback != null)
|
||||
@@ -179,7 +185,7 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public static eDeviceRegistrationUnRegistrationResponse RegisterWithLogging(this GenericBase device, string key)
|
||||
{
|
||||
var result = device.Register();
|
||||
var result = device.Register();
|
||||
var level = result == eDeviceRegistrationUnRegistrationResponse.Success ?
|
||||
Debug.ErrorLogLevel.Notice : Debug.ErrorLogLevel.Error;
|
||||
Debug.Console(0, level, "Register device result: '{0}', type '{1}', result {2}", key, device, result);
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace PepperDash.Essentials.Core.DeviceInfo
|
||||
{
|
||||
public class DeviceInfo
|
||||
{
|
||||
public string HostName { get; set; }
|
||||
public string IpAddress { get; set; }
|
||||
public string MacAddress { get; set; }
|
||||
public string SerialNumber { get; set; }
|
||||
public string FirmwareVersion { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceInfo
|
||||
{
|
||||
public class DeviceInfoEventArgs:EventArgs
|
||||
{
|
||||
public DeviceInfo DeviceInfo { get; set; }
|
||||
|
||||
public DeviceInfoEventArgs()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public DeviceInfoEventArgs(DeviceInfo devInfo)
|
||||
{
|
||||
DeviceInfo = devInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceInfo
|
||||
{
|
||||
public interface IDeviceInfoProvider:IKeyed
|
||||
{
|
||||
DeviceInfo DeviceInfo { get; }
|
||||
|
||||
event DeviceInfoChangeHandler DeviceInfoChanged;
|
||||
|
||||
void UpdateDeviceInfo();
|
||||
}
|
||||
|
||||
public delegate void DeviceInfoChangeHandler(IKeyed device, DeviceInfoEventArgs args);
|
||||
}
|
||||
@@ -6,7 +6,7 @@ using PepperDash.Essentials.Core.SmartObjects;
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
|
||||
public interface IDiscPlayerControls : IColor, IDPad, INumericKeypad, IPower, ITransport, IUiDisplayInfo
|
||||
public interface IDiscPlayerControls : IColor, IDPad, INumericKeypad, IHasPowerControl, ITransport, IUiDisplayInfo
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface IHasBranding
|
||||
{
|
||||
bool BrandingEnabled { get; }
|
||||
void InitializeBranding(string roomKey);
|
||||
}
|
||||
}
|
||||
|
||||
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
{
|
||||
[Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")]
|
||||
public interface IHasBranding
|
||||
{
|
||||
bool BrandingEnabled { get; }
|
||||
void InitializeBranding(string roomKey);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface IHasFarEndContentStatus
|
||||
{
|
||||
BoolFeedback ReceivingContent { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface IHasPhoneDialing
|
||||
{
|
||||
BoolFeedback PhoneOffHookFeedback { get; }
|
||||
StringFeedback CallerIdNameFeedback { get; }
|
||||
StringFeedback CallerIdNumberFeedback { get; }
|
||||
void DialPhoneCall(string number);
|
||||
void EndPhoneCall();
|
||||
void SendDtmfToPhone(string digit);
|
||||
}
|
||||
}
|
||||
|
||||
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
{
|
||||
[Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")]
|
||||
public interface IHasPhoneDialing
|
||||
{
|
||||
BoolFeedback PhoneOffHookFeedback { get; }
|
||||
StringFeedback CallerIdNameFeedback { get; }
|
||||
StringFeedback CallerIdNumberFeedback { get; }
|
||||
void DialPhoneCall(string number);
|
||||
void EndPhoneCall();
|
||||
void SendDtmfToPhone(string digit);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface ILanguageDefinition
|
||||
{
|
||||
string LocaleName { get; set; }
|
||||
string FriendlyName { get; set; }
|
||||
bool Enable { get; set; }
|
||||
List<LanguageLabel> UiLabels { get; set; }
|
||||
List<LanguageLabel> Sources { get; set; }
|
||||
List<LanguageLabel> Destinations { get; set; }
|
||||
List<LanguageLabel> SourceGroupNames { get; set; }
|
||||
List<LanguageLabel> DestinationGroupNames { get; set; }
|
||||
List<LanguageLabel> RoomNames { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
{
|
||||
[Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")]
|
||||
public interface ILanguageDefinition
|
||||
{
|
||||
string LocaleName { get; set; }
|
||||
string FriendlyName { get; set; }
|
||||
bool Enable { get; set; }
|
||||
List<LanguageLabel> UiLabels { get; set; }
|
||||
List<LanguageLabel> Sources { get; set; }
|
||||
List<LanguageLabel> Destinations { get; set; }
|
||||
List<LanguageLabel> SourceGroupNames { get; set; }
|
||||
List<LanguageLabel> DestinationGroupNames { get; set; }
|
||||
List<LanguageLabel> RoomNames { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
|
||||
public interface ILanguageProvider
|
||||
{
|
||||
ILanguageDefinition CurrentLanguage { get; set; }
|
||||
|
||||
event EventHandler CurrentLanguageChanged;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
{
|
||||
[Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")]
|
||||
public interface ILanguageProvider
|
||||
{
|
||||
ILanguageDefinition CurrentLanguage { get; set; }
|
||||
|
||||
event EventHandler CurrentLanguageChanged;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,11 +8,9 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
/// </summary>
|
||||
public interface IMobileControl : IKeyed
|
||||
{
|
||||
void CreateMobileControlRoomBridge(EssentialsRoomBase room);
|
||||
void CreateMobileControlRoomBridge(EssentialsRoomBase room, IMobileControl parent);
|
||||
|
||||
void LinkSystemMonitorToAppServer();
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -22,10 +20,16 @@ namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
event EventHandler<EventArgs> UserCodeChanged;
|
||||
|
||||
event EventHandler<EventArgs> UserPromptedForCode;
|
||||
|
||||
event EventHandler<EventArgs> ClientJoined;
|
||||
|
||||
string UserCode { get; }
|
||||
|
||||
string QrCodeUrl { get; }
|
||||
|
||||
string QrCodeChecksum { get; }
|
||||
|
||||
string McServerUrl { get; }
|
||||
|
||||
string RoomName { get; }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.SmartObjects;
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace PepperDash.Essentials.Core
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public interface INumericKeypad
|
||||
public interface INumericKeypad:IKeyed
|
||||
{
|
||||
void Digit0(bool pressRelease);
|
||||
void Digit1(bool pressRelease);
|
||||
|
||||
@@ -14,35 +14,64 @@ using PepperDash.Essentials.Core.SmartObjects;
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// Defines the ability to power a device on and off
|
||||
/// </summary>
|
||||
[Obsolete("Will be replaced by IHasPowerControlWithFeedback")]
|
||||
public interface IPower
|
||||
{
|
||||
void PowerOn();
|
||||
void PowerOff();
|
||||
void PowerToggle();
|
||||
BoolFeedback PowerIsOnFeedback { get; }
|
||||
BoolFeedback PowerIsOnFeedback { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds feedback for current power state
|
||||
/// </summary>
|
||||
public interface IHasPowerControlWithFeedback : IHasPowerControl
|
||||
{
|
||||
BoolFeedback PowerIsOnFeedback { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the ability to power a device on and off
|
||||
/// </summary>
|
||||
public interface IHasPowerControl
|
||||
{
|
||||
void PowerOn();
|
||||
void PowerOff();
|
||||
void PowerToggle();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static class IPowerExtensions
|
||||
public static class IHasPowerControlExtensions
|
||||
{
|
||||
public static void LinkButtons(this IPower dev, BasicTriList triList)
|
||||
public static void LinkButtons(this IHasPowerControl dev, BasicTriList triList)
|
||||
{
|
||||
triList.SetSigFalseAction(101, dev.PowerOn);
|
||||
triList.SetSigFalseAction(102, dev.PowerOff);
|
||||
triList.SetSigFalseAction(103, dev.PowerToggle);
|
||||
dev.PowerIsOnFeedback.LinkInputSig(triList.BooleanInput[101]);
|
||||
|
||||
var fbdev = dev as IHasPowerControlWithFeedback;
|
||||
if (fbdev != null)
|
||||
{
|
||||
fbdev.PowerIsOnFeedback.LinkInputSig(triList.BooleanInput[101]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void UnlinkButtons(this IPower dev, BasicTriList triList)
|
||||
public static void UnlinkButtons(this IHasPowerControl dev, BasicTriList triList)
|
||||
{
|
||||
triList.ClearBoolSigAction(101);
|
||||
triList.ClearBoolSigAction(102);
|
||||
triList.ClearBoolSigAction(103);
|
||||
dev.PowerIsOnFeedback.UnlinkInputSig(triList.BooleanInput[101]);
|
||||
|
||||
var fbdev = dev as IHasPowerControlWithFeedback;
|
||||
if (fbdev != null)
|
||||
{
|
||||
fbdev.PowerIsOnFeedback.UnlinkInputSig(triList.BooleanInput[101]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@ namespace PepperDash.Essentials.Core
|
||||
/// </summary>
|
||||
bool HasDpad { get; }
|
||||
|
||||
PepperDash.Essentials.Core.Presets.DevicePresetsModel PresetsModel { get; }
|
||||
PepperDash.Essentials.Core.Presets.DevicePresetsModel TvPresets { get; }
|
||||
void LoadPresets(string filePath);
|
||||
|
||||
void DvrList(bool pressRelease);
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
using PepperDash.Essentials.Core.Presets;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
public interface ITvPresetsProvider
|
||||
{
|
||||
DevicePresetsModel TvPresets { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.DeviceTypeInterfaces
|
||||
{
|
||||
public class LanguageLabel
|
||||
{
|
||||
public string Key { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string DisplayText { get; set; }
|
||||
public uint JoinNumber { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
namespace PepperDash_Essentials_Core.DeviceTypeInterfaces
|
||||
{
|
||||
[Obsolete("Use PepperDash.Essentials.Core.DeviceTypeInterfaces")]
|
||||
public class LanguageLabel
|
||||
{
|
||||
public string Key { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string DisplayText { get; set; }
|
||||
public uint JoinNumber { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public class DestinationListItem
|
||||
{
|
||||
[JsonProperty("sinkKey")]
|
||||
public string SinkKey { get; set; }
|
||||
|
||||
private EssentialsDevice _sinkDevice;
|
||||
|
||||
[JsonIgnore]
|
||||
public EssentialsDevice SinkDevice
|
||||
{
|
||||
get { return _sinkDevice ?? (_sinkDevice = DeviceManager.GetDeviceForKey(SinkKey) as EssentialsDevice); }
|
||||
}
|
||||
|
||||
[JsonProperty("preferredName")]
|
||||
public string PreferredName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Name))
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
return SinkDevice == null ? "---" : SinkDevice.Name;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonProperty("includeInDestinationList")]
|
||||
public bool IncludeInDestinationList { get; set; }
|
||||
|
||||
[JsonProperty("order")]
|
||||
public int Order { get; set; }
|
||||
|
||||
[JsonProperty("surfaceLocation")]
|
||||
public int SurfaceLocation { get; set; }
|
||||
|
||||
[JsonProperty("verticalLocation")]
|
||||
public int VerticalLocation { get; set; }
|
||||
|
||||
[JsonProperty("horizontalLocation")]
|
||||
public int HorizontalLocation { get; set; }
|
||||
|
||||
[JsonProperty("sinkType")]
|
||||
public eRoutingSignalType SinkType { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -20,8 +20,23 @@ namespace PepperDash.Essentials.Core
|
||||
/// <param name="json"></param>
|
||||
public static void DoDeviceActionWithJson(string json)
|
||||
{
|
||||
var action = JsonConvert.DeserializeObject<DeviceActionWrapper>(json);
|
||||
DoDeviceAction(action);
|
||||
if (String.IsNullOrEmpty(json))
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse(
|
||||
"Please provide a JSON object matching the format {\"deviceKey\":\"myDevice\", \"methodName\":\"someMethod\", \"params\": [\"param1\", true]}.\r\nIf the method has no parameters, the \"params\" object may be omitted.");
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
var action = JsonConvert.DeserializeObject<DeviceActionWrapper>(json);
|
||||
|
||||
DoDeviceAction(action);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse("Incorrect format for JSON. Please check that the format matches {\"deviceKey\":\"myDevice\", \"methodName\":\"someMethod\", \"params\": [\"param1\", true]}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -33,29 +48,47 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
var key = action.DeviceKey;
|
||||
var obj = FindObjectOnPath(key);
|
||||
if (obj == null)
|
||||
return;
|
||||
if (obj == null)
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse("Unable to find object at path {0}", key);
|
||||
return;
|
||||
}
|
||||
|
||||
CType t = obj.GetType();
|
||||
var method = t.GetMethod(action.MethodName);
|
||||
if (method == null)
|
||||
{
|
||||
Debug.Console(0, "Method '{0}' not found", action.MethodName);
|
||||
return;
|
||||
}
|
||||
var mParams = method.GetParameters();
|
||||
// Add empty params if not provided
|
||||
if (action.Params == null) action.Params = new object[0];
|
||||
if (mParams.Length > action.Params.Length)
|
||||
{
|
||||
Debug.Console(0, "Method '{0}' requires {1} params", action.MethodName, mParams.Length);
|
||||
return;
|
||||
}
|
||||
object[] convertedParams = mParams
|
||||
.Select((p, i) => Convert.ChangeType(action.Params[i], p.ParameterType,
|
||||
System.Globalization.CultureInfo.InvariantCulture))
|
||||
.ToArray();
|
||||
object ret = method.Invoke(obj, convertedParams);
|
||||
if (action.Params == null)
|
||||
{
|
||||
//no params, so setting action.Params to empty array
|
||||
action.Params = new object[0];
|
||||
}
|
||||
|
||||
CType t = obj.GetType();
|
||||
try
|
||||
{
|
||||
var methods = t.GetMethods().Where(m => m.Name == action.MethodName).ToList();
|
||||
|
||||
var method = methods.Count == 1 ? methods[0] : methods.FirstOrDefault(m => m.GetParameters().Length == action.Params.Length);
|
||||
|
||||
if (method == null)
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse(
|
||||
"Unable to find method with name {0} and that matches parameters {1}", action.MethodName,
|
||||
action.Params);
|
||||
return;
|
||||
}
|
||||
var mParams = method.GetParameters();
|
||||
|
||||
var convertedParams = mParams
|
||||
.Select((p, i) => Convert.ChangeType(action.Params[i], p.ParameterType,
|
||||
System.Globalization.CultureInfo.InvariantCulture))
|
||||
.ToArray();
|
||||
var ret = method.Invoke(obj, convertedParams);
|
||||
|
||||
CrestronConsole.ConsoleCommandResponse("Method {0} successfully called on device {1}", method.Name,
|
||||
action.DeviceKey);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse("Unable to call method with name {0}. {1}", action.MethodName,
|
||||
ex.Message);}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -83,13 +116,13 @@ namespace PepperDash.Essentials.Core
|
||||
/// <returns></returns>
|
||||
public static object GetPropertyByName(string deviceObjectPath, string propertyName)
|
||||
{
|
||||
var obj = FindObjectOnPath(deviceObjectPath);
|
||||
if(obj == null)
|
||||
var dev = FindObjectOnPath(deviceObjectPath);
|
||||
if(dev == null)
|
||||
return "{ \"error\":\"No Device\"}";
|
||||
|
||||
object prop = dev.GetType().GetCType().GetProperty(propertyName).GetValue(dev, null);
|
||||
|
||||
CType t = obj.GetType();
|
||||
|
||||
var prop = t.GetProperty(propertyName);
|
||||
// var prop = t.GetProperty(propertyName);
|
||||
if (prop != null)
|
||||
{
|
||||
return prop;
|
||||
|
||||
@@ -1,342 +1,355 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
|
||||
using PepperDash.Core;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public static class DeviceManager
|
||||
{
|
||||
private static readonly CCriticalSection DeviceCriticalSection = new CCriticalSection();
|
||||
private static readonly CEvent AllowAddDevicesCEvent = new CEvent(false, true);
|
||||
//public static List<Device> Devices { get { return _Devices; } }
|
||||
//static List<Device> _Devices = new List<Device>();
|
||||
|
||||
static readonly Dictionary<string, IKeyed> Devices = new Dictionary<string, IKeyed>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a copy of all the devices in a list
|
||||
/// </summary>
|
||||
public static List<IKeyed> AllDevices { get { return new List<IKeyed>(Devices.Values); } }
|
||||
|
||||
public static bool AddDeviceEnabled;
|
||||
|
||||
public static void Initialize(CrestronControlSystem cs)
|
||||
{
|
||||
AddDeviceEnabled = true;
|
||||
CrestronConsole.AddNewConsoleCommand(ListDeviceCommStatuses, "devcommstatus", "Lists the communication status of all devices",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(ListDeviceFeedbacks, "devfb", "Lists current feedbacks",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(ListDevices, "devlist", "Lists current managed devices",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(DeviceJsonApi.DoDeviceActionWithJson, "devjson", "",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetProperties(s)), "devprops", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetMethods(s)), "devmethods", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetApiMethods(s)), "apimethods", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(SimulateComReceiveOnDevice, "devsimreceive",
|
||||
"Simulates incoming data on a com device", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(s => SetDeviceStreamDebugging(s), "setdevicestreamdebug", "set comm debug [deviceKey] [off/rx/tx/both] ([minutes])", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s => DisableAllDeviceStreamDebugging(), "disableallstreamdebug", "disables stream debugging on all devices", ConsoleAccessLevelEnum.AccessOperator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls activate steps on all Device class items
|
||||
/// </summary>
|
||||
public static void ActivateAll()
|
||||
{
|
||||
try
|
||||
{
|
||||
DeviceCriticalSection.Enter();
|
||||
AddDeviceEnabled = false;
|
||||
// PreActivate all devices
|
||||
foreach (var d in Devices.Values)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (d is Device)
|
||||
(d as Device).PreActivate();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, d, "ERROR: Device PreActivation failure:\r{0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Activate all devices
|
||||
foreach (var d in Devices.Values)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (d is Device)
|
||||
(d as Device).Activate();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, d, "ERROR: Device Activation failure:\r{0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// PostActivate all devices
|
||||
foreach (var d in Devices.Values)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (d is Device)
|
||||
(d as Device).PostActivate();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, d, "ERROR: Device PostActivation failure:\r{0}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeviceCriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls activate on all Device class items
|
||||
/// </summary>
|
||||
public static void DeactivateAll()
|
||||
{
|
||||
try
|
||||
{
|
||||
DeviceCriticalSection.Enter();
|
||||
foreach (var d in Devices.Values.OfType<Device>())
|
||||
{
|
||||
d.Deactivate();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeviceCriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
//static void ListMethods(string devKey)
|
||||
//{
|
||||
// var dev = GetDeviceForKey(devKey);
|
||||
// if(dev != null)
|
||||
// {
|
||||
// var type = dev.GetType().GetCType();
|
||||
// var methods = type.GetMethods(BindingFlags.Public|BindingFlags.Instance);
|
||||
// var sb = new StringBuilder();
|
||||
// sb.AppendLine(string.Format("{2} methods on [{0}] ({1}):", dev.Key, type.Name, methods.Length));
|
||||
// foreach (var m in methods)
|
||||
// {
|
||||
// sb.Append(string.Format("{0}(", m.Name));
|
||||
// var pars = m.GetParameters();
|
||||
// foreach (var p in pars)
|
||||
// sb.Append(string.Format("({1}){0} ", p.Name, p.ParameterType.Name));
|
||||
// sb.AppendLine(")");
|
||||
// }
|
||||
// CrestronConsole.ConsoleCommandResponse(sb.ToString());
|
||||
// }
|
||||
//}
|
||||
|
||||
private static void ListDevices(string s)
|
||||
{
|
||||
Debug.Console(0, "{0} Devices registered with Device Manager:", Devices.Count);
|
||||
var sorted = Devices.Values.ToList();
|
||||
sorted.Sort((a, b) => a.Key.CompareTo(b.Key));
|
||||
|
||||
foreach (var d in sorted)
|
||||
{
|
||||
var name = d is IKeyName ? (d as IKeyName).Name : "---";
|
||||
Debug.Console(0, " [{0}] {1}", d.Key, name);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ListDeviceFeedbacks(string devKey)
|
||||
{
|
||||
var dev = GetDeviceForKey(devKey);
|
||||
if (dev == null)
|
||||
{
|
||||
Debug.Console(0, "Device '{0}' not found", devKey);
|
||||
return;
|
||||
}
|
||||
var statusDev = dev as IHasFeedback;
|
||||
if (statusDev == null)
|
||||
{
|
||||
Debug.Console(0, "Device '{0}' does not have visible feedbacks", devKey);
|
||||
return;
|
||||
}
|
||||
statusDev.DumpFeedbacksToConsole(true);
|
||||
}
|
||||
|
||||
//static void ListDeviceCommands(string devKey)
|
||||
//{
|
||||
// var dev = GetDeviceForKey(devKey);
|
||||
// if (dev == null)
|
||||
// {
|
||||
// Debug.Console(0, "Device '{0}' not found", devKey);
|
||||
// return;
|
||||
// }
|
||||
// Debug.Console(0, "This needs to be reworked. Stay tuned.", devKey);
|
||||
//}
|
||||
|
||||
private static void ListDeviceCommStatuses(string input)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (var dev in Devices.Values.OfType<ICommunicationMonitor>())
|
||||
{
|
||||
sb.Append(string.Format("{0}: {1}\r", dev,
|
||||
dev.CommunicationMonitor.Status));
|
||||
}
|
||||
CrestronConsole.ConsoleCommandResponse(sb.ToString());
|
||||
}
|
||||
|
||||
|
||||
//static void DoDeviceCommand(string command)
|
||||
//{
|
||||
// Debug.Console(0, "Not yet implemented. Stay tuned");
|
||||
//}
|
||||
|
||||
public static void AddDevice(IKeyed newDev)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!DeviceCriticalSection.TryEnter())
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Currently unable to add devices to Device Manager. Please try again");
|
||||
return;
|
||||
}
|
||||
// Check for device with same key
|
||||
//var existingDevice = _Devices.FirstOrDefault(d => d.Key.Equals(newDev.Key, StringComparison.OrdinalIgnoreCase));
|
||||
////// If it exists, remove or warn??
|
||||
//if (existingDevice != null)
|
||||
|
||||
if (!AddDeviceEnabled)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "All devices have been activated. Adding new devices is not allowed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Devices.ContainsKey(newDev.Key))
|
||||
{
|
||||
Debug.Console(0, newDev, "WARNING: A device with this key already exists. Not added to manager");
|
||||
return;
|
||||
}
|
||||
Devices.Add(newDev.Key, newDev);
|
||||
//if (!(_Devices.Contains(newDev)))
|
||||
// _Devices.Add(newDev);
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeviceCriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddDevice(IEnumerable<IKeyed> devicesToAdd)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!DeviceCriticalSection.TryEnter())
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"Currently unable to add devices to Device Manager. Please try again");
|
||||
return;
|
||||
}
|
||||
if (!AddDeviceEnabled)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"All devices have been activated. Adding new devices is not allowed.");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var dev in devicesToAdd)
|
||||
{
|
||||
try
|
||||
{
|
||||
Devices.Add(dev.Key, dev);
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
Debug.Console(0, "Error adding device with key {0} to Device Manager: {1}\r\nStack Trace: {2}",
|
||||
dev.Key, ex.Message, ex.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeviceCriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveDevice(IKeyed newDev)
|
||||
{
|
||||
try
|
||||
{
|
||||
DeviceCriticalSection.Enter();
|
||||
if (newDev == null)
|
||||
return;
|
||||
if (Devices.ContainsKey(newDev.Key))
|
||||
Devices.Remove(newDev.Key);
|
||||
//if (_Devices.Contains(newDev))
|
||||
// _Devices.Remove(newDev);
|
||||
else
|
||||
Debug.Console(0, "Device manager: Device '{0}' does not exist in manager. Cannot remove", newDev.Key);
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeviceCriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<string> GetDeviceKeys()
|
||||
{
|
||||
//return _Devices.Select(d => d.Key).ToList();
|
||||
return Devices.Keys;
|
||||
}
|
||||
|
||||
public static IEnumerable<IKeyed> GetDevices()
|
||||
{
|
||||
//return _Devices.Select(d => d.Key).ToList();
|
||||
return Devices.Values;
|
||||
}
|
||||
|
||||
public static IKeyed GetDeviceForKey(string key)
|
||||
{
|
||||
//return _Devices.FirstOrDefault(d => d.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
|
||||
if (key != null && Devices.ContainsKey(key))
|
||||
return Devices[key];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Console handler that simulates com port data receive
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
public static void SimulateComReceiveOnDevice(string s)
|
||||
{
|
||||
// devcomsim:1 xyzabc
|
||||
var match = Regex.Match(s, @"(\S*)\s*(.*)");
|
||||
if (match.Groups.Count < 3)
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse(" Format: devsimreceive:P <device key> <string to send>");
|
||||
return;
|
||||
}
|
||||
//Debug.Console(2, "**** {0} - {1} ****", match.Groups[1].Value, match.Groups[2].Value);
|
||||
|
||||
var com = GetDeviceForKey(match.Groups[1].Value) as ComPortController;
|
||||
if (com == null)
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse("'{0}' is not a comm port device", match.Groups[1].Value);
|
||||
return;
|
||||
}
|
||||
com.SimulateReceive(match.Groups[2].Value);
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
|
||||
using PepperDash.Core;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public static class DeviceManager
|
||||
{
|
||||
public static event EventHandler<EventArgs> AllDevicesActivated;
|
||||
|
||||
private static readonly CCriticalSection DeviceCriticalSection = new CCriticalSection();
|
||||
private static readonly CEvent AllowAddDevicesCEvent = new CEvent(false, true);
|
||||
//public static List<Device> Devices { get { return _Devices; } }
|
||||
//static List<Device> _Devices = new List<Device>();
|
||||
|
||||
static readonly Dictionary<string, IKeyed> Devices = new Dictionary<string, IKeyed>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a copy of all the devices in a list
|
||||
/// </summary>
|
||||
public static List<IKeyed> AllDevices { get { return new List<IKeyed>(Devices.Values); } }
|
||||
|
||||
public static bool AddDeviceEnabled;
|
||||
|
||||
public static void Initialize(CrestronControlSystem cs)
|
||||
{
|
||||
AddDeviceEnabled = true;
|
||||
CrestronConsole.AddNewConsoleCommand(ListDeviceCommStatuses, "devcommstatus", "Lists the communication status of all devices",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(ListDeviceFeedbacks, "devfb", "Lists current feedbacks",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(ListDevices, "devlist", "Lists current managed devices",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(DeviceJsonApi.DoDeviceActionWithJson, "devjson", "",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetProperties(s)), "devprops", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetMethods(s)), "devmethods", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s => CrestronConsole.ConsoleCommandResponse(DeviceJsonApi.GetApiMethods(s)), "apimethods", "", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(SimulateComReceiveOnDevice, "devsimreceive",
|
||||
"Simulates incoming data on a com device", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(SetDeviceStreamDebugging, "setdevicestreamdebug", "set comm debug [deviceKey] [off/rx/tx/both] ([minutes])", ConsoleAccessLevelEnum.AccessOperator);
|
||||
CrestronConsole.AddNewConsoleCommand(s => DisableAllDeviceStreamDebugging(), "disableallstreamdebug", "disables stream debugging on all devices", ConsoleAccessLevelEnum.AccessOperator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls activate steps on all Device class items
|
||||
/// </summary>
|
||||
public static void ActivateAll()
|
||||
{
|
||||
try
|
||||
{
|
||||
DeviceCriticalSection.Enter();
|
||||
AddDeviceEnabled = false;
|
||||
// PreActivate all devices
|
||||
foreach (var d in Devices.Values)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (d is Device)
|
||||
(d as Device).PreActivate();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, d, "ERROR: Device PreActivation failure:\r{0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Activate all devices
|
||||
foreach (var d in Devices.Values)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (d is Device)
|
||||
(d as Device).Activate();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, d, "ERROR: Device Activation failure:\r{0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// PostActivate all devices
|
||||
foreach (var d in Devices.Values)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (d is Device)
|
||||
(d as Device).PostActivate();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, d, "ERROR: Device PostActivation failure:\r{0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
OnAllDevicesActivated();
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeviceCriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnAllDevicesActivated()
|
||||
{
|
||||
var handler = AllDevicesActivated;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(null, new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls activate on all Device class items
|
||||
/// </summary>
|
||||
public static void DeactivateAll()
|
||||
{
|
||||
try
|
||||
{
|
||||
DeviceCriticalSection.Enter();
|
||||
foreach (var d in Devices.Values.OfType<Device>())
|
||||
{
|
||||
d.Deactivate();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeviceCriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
//static void ListMethods(string devKey)
|
||||
//{
|
||||
// var dev = GetDeviceForKey(devKey);
|
||||
// if(dev != null)
|
||||
// {
|
||||
// var type = dev.GetType().GetCType();
|
||||
// var methods = type.GetMethods(BindingFlags.Public|BindingFlags.Instance);
|
||||
// var sb = new StringBuilder();
|
||||
// sb.AppendLine(string.Format("{2} methods on [{0}] ({1}):", dev.Key, type.Name, methods.Length));
|
||||
// foreach (var m in methods)
|
||||
// {
|
||||
// sb.Append(string.Format("{0}(", m.Name));
|
||||
// var pars = m.GetParameters();
|
||||
// foreach (var p in pars)
|
||||
// sb.Append(string.Format("({1}){0} ", p.Name, p.ParameterType.Name));
|
||||
// sb.AppendLine(")");
|
||||
// }
|
||||
// CrestronConsole.ConsoleCommandResponse(sb.ToString());
|
||||
// }
|
||||
//}
|
||||
|
||||
private static void ListDevices(string s)
|
||||
{
|
||||
Debug.Console(0, "{0} Devices registered with Device Manager:", Devices.Count);
|
||||
var sorted = Devices.Values.ToList();
|
||||
sorted.Sort((a, b) => a.Key.CompareTo(b.Key));
|
||||
|
||||
foreach (var d in sorted)
|
||||
{
|
||||
var name = d is IKeyName ? (d as IKeyName).Name : "---";
|
||||
Debug.Console(0, " [{0}] {1}", d.Key, name);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ListDeviceFeedbacks(string devKey)
|
||||
{
|
||||
var dev = GetDeviceForKey(devKey);
|
||||
if (dev == null)
|
||||
{
|
||||
Debug.Console(0, "Device '{0}' not found", devKey);
|
||||
return;
|
||||
}
|
||||
var statusDev = dev as IHasFeedback;
|
||||
if (statusDev == null)
|
||||
{
|
||||
Debug.Console(0, "Device '{0}' does not have visible feedbacks", devKey);
|
||||
return;
|
||||
}
|
||||
statusDev.DumpFeedbacksToConsole(true);
|
||||
}
|
||||
|
||||
//static void ListDeviceCommands(string devKey)
|
||||
//{
|
||||
// var dev = GetDeviceForKey(devKey);
|
||||
// if (dev == null)
|
||||
// {
|
||||
// Debug.Console(0, "Device '{0}' not found", devKey);
|
||||
// return;
|
||||
// }
|
||||
// Debug.Console(0, "This needs to be reworked. Stay tuned.", devKey);
|
||||
//}
|
||||
|
||||
private static void ListDeviceCommStatuses(string input)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (var dev in Devices.Values.OfType<ICommunicationMonitor>())
|
||||
{
|
||||
sb.Append(string.Format("{0}: {1}\r", dev,
|
||||
dev.CommunicationMonitor.Status));
|
||||
}
|
||||
CrestronConsole.ConsoleCommandResponse(sb.ToString());
|
||||
}
|
||||
|
||||
|
||||
//static void DoDeviceCommand(string command)
|
||||
//{
|
||||
// Debug.Console(0, "Not yet implemented. Stay tuned");
|
||||
//}
|
||||
|
||||
public static void AddDevice(IKeyed newDev)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!DeviceCriticalSection.TryEnter())
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Currently unable to add devices to Device Manager. Please try again");
|
||||
return;
|
||||
}
|
||||
// Check for device with same key
|
||||
//var existingDevice = _Devices.FirstOrDefault(d => d.Key.Equals(newDev.Key, StringComparison.OrdinalIgnoreCase));
|
||||
////// If it exists, remove or warn??
|
||||
//if (existingDevice != null)
|
||||
|
||||
if (!AddDeviceEnabled)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "All devices have been activated. Adding new devices is not allowed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Devices.ContainsKey(newDev.Key))
|
||||
{
|
||||
Debug.Console(0, newDev, "WARNING: A device with this key already exists. Not added to manager");
|
||||
return;
|
||||
}
|
||||
Devices.Add(newDev.Key, newDev);
|
||||
//if (!(_Devices.Contains(newDev)))
|
||||
// _Devices.Add(newDev);
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeviceCriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddDevice(IEnumerable<IKeyed> devicesToAdd)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!DeviceCriticalSection.TryEnter())
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"Currently unable to add devices to Device Manager. Please try again");
|
||||
return;
|
||||
}
|
||||
if (!AddDeviceEnabled)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error,
|
||||
"All devices have been activated. Adding new devices is not allowed.");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var dev in devicesToAdd)
|
||||
{
|
||||
try
|
||||
{
|
||||
Devices.Add(dev.Key, dev);
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
Debug.Console(0, "Error adding device with key {0} to Device Manager: {1}\r\nStack Trace: {2}",
|
||||
dev.Key, ex.Message, ex.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeviceCriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveDevice(IKeyed newDev)
|
||||
{
|
||||
try
|
||||
{
|
||||
DeviceCriticalSection.Enter();
|
||||
if (newDev == null)
|
||||
return;
|
||||
if (Devices.ContainsKey(newDev.Key))
|
||||
Devices.Remove(newDev.Key);
|
||||
//if (_Devices.Contains(newDev))
|
||||
// _Devices.Remove(newDev);
|
||||
else
|
||||
Debug.Console(0, "Device manager: Device '{0}' does not exist in manager. Cannot remove", newDev.Key);
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeviceCriticalSection.Leave();
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<string> GetDeviceKeys()
|
||||
{
|
||||
//return _Devices.Select(d => d.Key).ToList();
|
||||
return Devices.Keys;
|
||||
}
|
||||
|
||||
public static IEnumerable<IKeyed> GetDevices()
|
||||
{
|
||||
//return _Devices.Select(d => d.Key).ToList();
|
||||
return Devices.Values;
|
||||
}
|
||||
|
||||
public static IKeyed GetDeviceForKey(string key)
|
||||
{
|
||||
//return _Devices.FirstOrDefault(d => d.Key.Equals(key, StringComparison.OrdinalIgnoreCase));
|
||||
if (key != null && Devices.ContainsKey(key))
|
||||
return Devices[key];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Console handler that simulates com port data receive
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
public static void SimulateComReceiveOnDevice(string s)
|
||||
{
|
||||
// devcomsim:1 xyzabc
|
||||
var match = Regex.Match(s, @"(\S*)\s*(.*)");
|
||||
if (match.Groups.Count < 3)
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse(" Format: devsimreceive:P <device key> <string to send>");
|
||||
return;
|
||||
}
|
||||
//Debug.Console(2, "**** {0} - {1} ****", match.Groups[1].Value, match.Groups[2].Value);
|
||||
|
||||
var com = GetDeviceForKey(match.Groups[1].Value) as ComPortController;
|
||||
if (com == null)
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse("'{0}' is not a comm port device", match.Groups[1].Value);
|
||||
return;
|
||||
}
|
||||
com.SimulateReceive(match.Groups[2].Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -347,9 +360,9 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
var device = GetDeviceForKey(s);
|
||||
|
||||
if (device == null) return;
|
||||
var inputPorts = (device as IRoutingInputsOutputs).InputPorts;
|
||||
var outputPorts = (device as IRoutingInputsOutputs).OutputPorts;
|
||||
if (device == null) return;
|
||||
var inputPorts = ((device as IRoutingInputs) != null) ? (device as IRoutingInputs).InputPorts : null;
|
||||
var outputPorts = ((device as IRoutingOutputs) != null) ? (device as IRoutingOutputs).OutputPorts : null;
|
||||
if (inputPorts != null)
|
||||
{
|
||||
Debug.Console(0, "Device {0} has {1} Input Ports:", s, inputPorts.Count);
|
||||
@@ -366,82 +379,91 @@ namespace PepperDash.Essentials.Core
|
||||
Debug.Console(0, "{0}", routingOutputPort.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to set the debug level of a device
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
public static void SetDeviceStreamDebugging(string s)
|
||||
{
|
||||
var args = s.Split(' ');
|
||||
|
||||
var deviceKey = args[0];
|
||||
var setting = args[1];
|
||||
|
||||
var timeout= String.Empty;
|
||||
|
||||
if (args.Length >= 3)
|
||||
{
|
||||
timeout = args[2];
|
||||
}
|
||||
|
||||
var device = GetDeviceForKey(deviceKey) as IStreamDebugging;
|
||||
|
||||
if (device == null)
|
||||
{
|
||||
Debug.Console(0, "Unable to get device with key: {0}", deviceKey);
|
||||
return;
|
||||
}
|
||||
|
||||
eStreamDebuggingSetting debugSetting;
|
||||
|
||||
try
|
||||
{
|
||||
debugSetting = (eStreamDebuggingSetting)Enum.Parse(typeof(eStreamDebuggingSetting), setting, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(0, "Unable to convert setting value. Please use off/rx/tx/both");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(timeout))
|
||||
{
|
||||
try
|
||||
{
|
||||
var min = Convert.ToUInt32(timeout);
|
||||
|
||||
device.StreamDebugging.SetDebuggingWithSpecificTimeout(debugSetting, min);
|
||||
Debug.Console(0, "Device: '{0}' debug level set to {1) for {2} minutes", deviceKey, debugSetting, min);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, "Unable to convert minutes or settings value. Please use an integer value for minutes. Errro: {0}", e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
device.StreamDebugging.SetDebuggingWithDefaultTimeout(debugSetting);
|
||||
Debug.Console(0, "Device: '{0}' debug level set to {1) for default time (30 minutes)", deviceKey, debugSetting);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets stream debugging settings to off for all devices
|
||||
/// </summary>
|
||||
public static void DisableAllDeviceStreamDebugging()
|
||||
{
|
||||
foreach (var device in AllDevices)
|
||||
{
|
||||
var streamDevice = device as IStreamDebugging;
|
||||
|
||||
if (streamDevice != null)
|
||||
{
|
||||
streamDevice.StreamDebugging.SetDebuggingWithDefaultTimeout(eStreamDebuggingSetting.Off);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to set the debug level of a device
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
public static void SetDeviceStreamDebugging(string s)
|
||||
{
|
||||
if (String.IsNullOrEmpty(s) || s.Contains("?"))
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse(
|
||||
@"SETDEVICESTREAMDEBUG [{deviceKey}] [OFF |TX | RX | BOTH] [timeOutInMinutes]
|
||||
{deviceKey} [OFF | TX | RX | BOTH] - Device to set stream debugging on, and which setting to use
|
||||
timeOutInMinutes - Set timeout for stream debugging. Default is 30 minutes");
|
||||
return;
|
||||
}
|
||||
|
||||
var args = s.Split(' ');
|
||||
|
||||
var deviceKey = args[0];
|
||||
var setting = args[1];
|
||||
|
||||
var timeout= String.Empty;
|
||||
|
||||
if (args.Length >= 3)
|
||||
{
|
||||
timeout = args[2];
|
||||
}
|
||||
|
||||
var device = GetDeviceForKey(deviceKey) as IStreamDebugging;
|
||||
|
||||
if (device == null)
|
||||
{
|
||||
Debug.Console(0, "Unable to get device with key: {0}", deviceKey);
|
||||
return;
|
||||
}
|
||||
|
||||
eStreamDebuggingSetting debugSetting;
|
||||
|
||||
try
|
||||
{
|
||||
debugSetting = (eStreamDebuggingSetting)Enum.Parse(typeof(eStreamDebuggingSetting), setting, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(0, "Unable to convert setting value. Please use off/rx/tx/both");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(timeout))
|
||||
{
|
||||
try
|
||||
{
|
||||
var min = Convert.ToUInt32(timeout);
|
||||
|
||||
device.StreamDebugging.SetDebuggingWithSpecificTimeout(debugSetting, min);
|
||||
Debug.Console(0, "Device: '{0}' debug level set to {1) for {2} minutes", deviceKey, debugSetting, min);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, "Unable to convert minutes or settings value. Please use an integer value for minutes. Errro: {0}", e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
device.StreamDebugging.SetDebuggingWithDefaultTimeout(debugSetting);
|
||||
Debug.Console(0, "Device: '{0}' debug level set to {1} for default time (30 minutes)", deviceKey, debugSetting);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets stream debugging settings to off for all devices
|
||||
/// </summary>
|
||||
public static void DisableAllDeviceStreamDebugging()
|
||||
{
|
||||
foreach (var device in AllDevices)
|
||||
{
|
||||
var streamDevice = device as IStreamDebugging;
|
||||
|
||||
if (streamDevice != null)
|
||||
{
|
||||
streamDevice.StreamDebugging.SetDebuggingWithDefaultTimeout(eStreamDebuggingSetting.Off);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Devices
|
||||
{
|
||||
public class GenericIrController: EssentialsBridgeableDevice
|
||||
{
|
||||
//data storage for bridging
|
||||
private BasicTriList _trilist;
|
||||
private uint _joinStart;
|
||||
private string _joinMapKey;
|
||||
private EiscApiAdvanced _bridge;
|
||||
|
||||
private readonly IrOutputPortController _port;
|
||||
|
||||
public string[] IrCommands {get { return _port.IrFileCommands; }}
|
||||
|
||||
public GenericIrController(string key, string name, IrOutputPortController irPort) : base(key, name)
|
||||
{
|
||||
_port = irPort;
|
||||
|
||||
if (_port == null)
|
||||
{
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Error, "IR Port is null, device will not function");
|
||||
return;
|
||||
}
|
||||
DeviceManager.AddDevice(_port);
|
||||
|
||||
_port.DriverLoaded.OutputChange += DriverLoadedOnOutputChange;
|
||||
}
|
||||
|
||||
private void DriverLoadedOnOutputChange(object sender, FeedbackEventArgs args)
|
||||
{
|
||||
if (!args.BoolValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_trilist == null || _bridge == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LinkToApi(_trilist, _joinStart, _joinMapKey, _bridge);
|
||||
}
|
||||
|
||||
#region Overrides of EssentialsBridgeableDevice
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
//if driver isn't loaded yet, store the variables until it is loaded, then call the LinkToApi method again
|
||||
if (!_port.DriverIsLoaded)
|
||||
{
|
||||
_trilist = trilist;
|
||||
_joinStart = joinStart;
|
||||
_joinMapKey = joinMapKey;
|
||||
_bridge = bridge;
|
||||
return;
|
||||
}
|
||||
|
||||
var joinMap = new GenericIrControllerJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<GenericIrControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
for (uint i = 0; i < _port.IrFileCommands.Length; i++)
|
||||
{
|
||||
var cmd = _port.IrFileCommands[i];
|
||||
var joinData = new JoinDataComplete(new JoinData {JoinNumber = i, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = cmd,
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
joinData.SetJoinOffset(joinStart);
|
||||
|
||||
joinMap.Joins.Add(cmd,joinData);
|
||||
|
||||
trilist.SetBoolSigAction(joinData.JoinNumber, (b) => Press(cmd, b));
|
||||
}
|
||||
|
||||
joinMap.PrintJoinMapInfo();
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void Press(string command, bool pressRelease)
|
||||
{
|
||||
_port.PressRelease(command, pressRelease);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class GenericIrControllerJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
public GenericIrControllerJoinMap(uint joinStart) : base(joinStart)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class GenericIrControllerFactory : EssentialsDeviceFactory<GenericIrController>
|
||||
{
|
||||
public GenericIrControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string> {"genericIrController"};
|
||||
}
|
||||
#region Overrides of EssentialsDeviceFactory<GenericIRController>
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new Generic IR Controller Device");
|
||||
|
||||
var irPort = IRPortHelper.GetIrOutputPortController(dc);
|
||||
|
||||
return new GenericIrController(dc.Key, dc.Name, irPort);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public interface IHasDspPresets
|
||||
{
|
||||
List<IDspPreset> Presets { get; }
|
||||
|
||||
void RecallPreset(IDspPreset preset);
|
||||
|
||||
}
|
||||
|
||||
public interface IDspPreset
|
||||
{
|
||||
string Name { get; }
|
||||
}
|
||||
}
|
||||
@@ -21,10 +21,14 @@ namespace PepperDash.Essentials.Core
|
||||
uint IrPortUid;
|
||||
IROutputPort IrPort;
|
||||
|
||||
public BoolFeedback DriverLoaded { get; private set; }
|
||||
|
||||
public ushort StandardIrPulseTime { get; set; }
|
||||
public string DriverFilepath { get; private set; }
|
||||
public bool DriverIsLoaded { get; private set; }
|
||||
|
||||
public string[] IrFileCommands { get { return IrPort.AvailableStandardIRCmds(IrPortUid); } }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for IrDevice base class. If a null port is provided, this class will
|
||||
/// still function without trying to talk to a port.
|
||||
@@ -33,6 +37,8 @@ namespace PepperDash.Essentials.Core
|
||||
: base(key)
|
||||
{
|
||||
//if (port == null) throw new ArgumentNullException("port");
|
||||
|
||||
DriverLoaded = new BoolFeedback(() => DriverIsLoaded);
|
||||
IrPort = port;
|
||||
if (port == null)
|
||||
{
|
||||
@@ -46,12 +52,34 @@ namespace PepperDash.Essentials.Core
|
||||
DeviceConfig config)
|
||||
: base(key)
|
||||
{
|
||||
DriverLoaded = new BoolFeedback(() => DriverIsLoaded);
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
IrPort = postActivationFunc(config);
|
||||
|
||||
if (IrPort == null)
|
||||
{
|
||||
Debug.Console(0, this, "WARNING No valid IR Port assigned to controller. IR will not function");
|
||||
return;
|
||||
}
|
||||
|
||||
var filePath = Global.FilePathPrefix + "ir" + Global.DirectorySeparator + config.Properties["control"]["irFile"].Value<string>();
|
||||
Debug.Console(1, "*************Attempting to load IR file: {0}***************", filePath);
|
||||
|
||||
LoadDriver(filePath);
|
||||
|
||||
PrintAvailableCommands();
|
||||
});
|
||||
}
|
||||
|
||||
public void PrintAvailableCommands()
|
||||
{
|
||||
Debug.Console(2, this, "Available IR Commands in IR File {0}", IrPortUid);
|
||||
foreach (var cmd in IrPort.AvailableIRCmds())
|
||||
{
|
||||
Debug.Console(2, this, "{0}", cmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -60,20 +88,23 @@ namespace PepperDash.Essentials.Core
|
||||
/// <param name="path"></param>
|
||||
public void LoadDriver(string path)
|
||||
{
|
||||
Debug.Console(2, this, "***Loading IR File***");
|
||||
if (string.IsNullOrEmpty(path)) path = DriverFilepath;
|
||||
try
|
||||
{
|
||||
IrPortUid = IrPort.LoadIRDriver(path);
|
||||
DriverFilepath = path;
|
||||
StandardIrPulseTime = 200;
|
||||
DriverIsLoaded = true;
|
||||
}
|
||||
try
|
||||
{
|
||||
IrPortUid = IrPort.LoadIRDriver(path);
|
||||
DriverFilepath = path;
|
||||
StandardIrPulseTime = 200;
|
||||
DriverIsLoaded = true;
|
||||
|
||||
DriverLoaded.FireUpdate();
|
||||
}
|
||||
catch
|
||||
{
|
||||
DriverIsLoaded = false;
|
||||
var message = string.Format("WARNING IR Driver '{0}' failed to load", path);
|
||||
Debug.Console(0, this, message);
|
||||
ErrorLog.Error(message);
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Error, message);
|
||||
DriverLoaded.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Devices
|
||||
{
|
||||
@@ -52,6 +54,8 @@ namespace PepperDash.Essentials.Core.Devices
|
||||
Name = config.Name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Used by the extending class to allow for any custom actions to be taken (tell the ConfigWriter to write config, etc)
|
||||
/// </summary>
|
||||
|
||||
@@ -130,10 +130,24 @@ namespace PepperDash.Essentials.Core
|
||||
[JsonProperty("sourceListKey")]
|
||||
public string SourceListKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the device associated with this source is controllable
|
||||
/// </summary>
|
||||
[JsonProperty("isControllable")]
|
||||
public bool IsControllable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the device associated with this source has audio available
|
||||
/// </summary>
|
||||
[JsonProperty("isAudioSource")]
|
||||
public bool IsAudioSource { get; set; }
|
||||
|
||||
public SourceListItem()
|
||||
{
|
||||
Icon = "Blank";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class SourceRouteListItem
|
||||
|
||||
@@ -20,10 +20,13 @@ namespace PepperDash.Essentials.Core
|
||||
public IrOutputPortController IrPort { get; private set; }
|
||||
public ushort IrPulseTime { get; set; }
|
||||
|
||||
protected override Func<bool> PowerIsOnFeedbackFunc
|
||||
{
|
||||
get { return () => _PowerIsOn; }
|
||||
}
|
||||
[Obsolete("This property will be removed in version 2.0.0")]
|
||||
public override BoolFeedback PowerIsOnFeedback { get; protected set; }
|
||||
|
||||
protected Func<bool> PowerIsOnFeedbackFunc
|
||||
{
|
||||
get { return () => _PowerIsOn; }
|
||||
}
|
||||
protected override Func<bool> IsCoolingDownFeedbackFunc
|
||||
{
|
||||
get { return () => _IsCoolingDown; }
|
||||
@@ -33,7 +36,7 @@ namespace PepperDash.Essentials.Core
|
||||
get { return () => _IsWarmingUp; }
|
||||
}
|
||||
|
||||
bool _PowerIsOn;
|
||||
bool _PowerIsOn;
|
||||
bool _IsWarmingUp;
|
||||
bool _IsCoolingDown;
|
||||
|
||||
@@ -43,11 +46,14 @@ namespace PepperDash.Essentials.Core
|
||||
IrPort = new IrOutputPortController(key + "-ir", port, irDriverFilepath);
|
||||
DeviceManager.AddDevice(IrPort);
|
||||
|
||||
PowerIsOnFeedback.OutputChange += (o, a) => {
|
||||
Debug.Console(2, this, "Power on={0}", _PowerIsOn);
|
||||
if (_PowerIsOn) StartWarmingTimer();
|
||||
else StartCoolingTimer();
|
||||
};
|
||||
PowerIsOnFeedback = new BoolFeedback(PowerIsOnFeedbackFunc);
|
||||
|
||||
PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
Debug.Console(2, this, "Power on={0}", _PowerIsOn);
|
||||
if (_PowerIsOn) StartWarmingTimer();
|
||||
else StartCoolingTimer();
|
||||
};
|
||||
IsWarmingUpFeedback.OutputChange += (o, a) => Debug.Console(2, this, "Warming up={0}", _IsWarmingUp);
|
||||
IsCoolingDownFeedback.OutputChange += (o, a) => Debug.Console(2, this, "Cooling down={0}", _IsCoolingDown);
|
||||
|
||||
@@ -110,21 +116,21 @@ namespace PepperDash.Essentials.Core
|
||||
public override void PowerOn()
|
||||
{
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_ON, IrPulseTime);
|
||||
_PowerIsOn = true;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
_PowerIsOn = true;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
public override void PowerOff()
|
||||
{
|
||||
_PowerIsOn = false;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
_PowerIsOn = false;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER_OFF, IrPulseTime);
|
||||
}
|
||||
|
||||
public override void PowerToggle()
|
||||
{
|
||||
_PowerIsOn = false;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
_PowerIsOn = false;
|
||||
PowerIsOnFeedback.FireUpdate();
|
||||
IrPort.Pulse(IROutputStandardCommands.IROut_POWER, IrPulseTime);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,131 +1,118 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.DM;
|
||||
using Crestron.SimplSharpPro.DM.Endpoints;
|
||||
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class DisplayBase : EssentialsDevice, IHasFeedback, IRoutingSinkWithSwitching, IPower, IWarmingCooling, IUsageTracking
|
||||
{
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
|
||||
public string CurrentSourceInfoKey { get; set; }
|
||||
public SourceListItem CurrentSourceInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CurrentSourceInfo;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == _CurrentSourceInfo) return;
|
||||
|
||||
var handler = CurrentSourceChange;
|
||||
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
||||
|
||||
_CurrentSourceInfo = value;
|
||||
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
||||
}
|
||||
}
|
||||
SourceListItem _CurrentSourceInfo;
|
||||
|
||||
public BoolFeedback PowerIsOnFeedback { get; protected set; }
|
||||
public BoolFeedback IsCoolingDownFeedback { get; protected set; }
|
||||
public BoolFeedback IsWarmingUpFeedback { get; private set; }
|
||||
|
||||
public UsageTracking UsageTracker { get; set; }
|
||||
|
||||
public uint WarmupTime { get; set; }
|
||||
public uint CooldownTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Bool Func that will provide a value for the PowerIsOn Output. Must be implemented
|
||||
/// by concrete sub-classes
|
||||
/// </summary>
|
||||
abstract protected Func<bool> PowerIsOnFeedbackFunc { get; }
|
||||
abstract protected Func<bool> IsCoolingDownFeedbackFunc { get; }
|
||||
abstract protected Func<bool> IsWarmingUpFeedbackFunc { get; }
|
||||
|
||||
|
||||
protected CTimer WarmupTimer;
|
||||
protected CTimer CooldownTimer;
|
||||
|
||||
#region IRoutingInputs Members
|
||||
|
||||
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
protected DisplayBase(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
PowerIsOnFeedback = new BoolFeedback("PowerOnFeedback", PowerIsOnFeedbackFunc);
|
||||
IsCoolingDownFeedback = new BoolFeedback("IsCoolingDown", IsCoolingDownFeedbackFunc);
|
||||
IsWarmingUpFeedback = new BoolFeedback("IsWarmingUp", IsWarmingUpFeedbackFunc);
|
||||
|
||||
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||
|
||||
PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange;
|
||||
}
|
||||
|
||||
void PowerIsOnFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
if (UsageTracker != null)
|
||||
{
|
||||
if (PowerIsOnFeedback.BoolValue)
|
||||
UsageTracker.StartDeviceUsage();
|
||||
else
|
||||
UsageTracker.EndDeviceUsage();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void PowerOn();
|
||||
public abstract void PowerOff();
|
||||
public abstract void PowerToggle();
|
||||
|
||||
public virtual FeedbackCollection<Feedback> Feedbacks
|
||||
{
|
||||
get
|
||||
{
|
||||
return new FeedbackCollection<Feedback>
|
||||
{
|
||||
PowerIsOnFeedback,
|
||||
IsCoolingDownFeedback,
|
||||
IsWarmingUpFeedback
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void ExecuteSwitch(object selector);
|
||||
|
||||
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey,
|
||||
EiscApiAdvanced bridge)
|
||||
{
|
||||
var inputNumber = 0;
|
||||
var inputKeys = new List<string>();
|
||||
|
||||
var joinMap = new DisplayControllerJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.DM;
|
||||
using Crestron.SimplSharpPro.DM.Endpoints;
|
||||
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class DisplayBase : EssentialsDevice, IHasFeedback, IRoutingSinkWithSwitching, IHasPowerControl, IWarmingCooling, IUsageTracking, IPower
|
||||
{
|
||||
public event SourceInfoChangeHandler CurrentSourceChange;
|
||||
|
||||
public string CurrentSourceInfoKey { get; set; }
|
||||
public SourceListItem CurrentSourceInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CurrentSourceInfo;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == _CurrentSourceInfo) return;
|
||||
|
||||
var handler = CurrentSourceChange;
|
||||
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.WillChange);
|
||||
|
||||
_CurrentSourceInfo = value;
|
||||
|
||||
if (handler != null)
|
||||
handler(_CurrentSourceInfo, ChangeType.DidChange);
|
||||
}
|
||||
}
|
||||
SourceListItem _CurrentSourceInfo;
|
||||
|
||||
public BoolFeedback IsCoolingDownFeedback { get; protected set; }
|
||||
public BoolFeedback IsWarmingUpFeedback { get; private set; }
|
||||
|
||||
[Obsolete("This property will be removed in version 2.0.0")]
|
||||
public abstract BoolFeedback PowerIsOnFeedback { get; protected set; }
|
||||
|
||||
public UsageTracking UsageTracker { get; set; }
|
||||
|
||||
public uint WarmupTime { get; set; }
|
||||
public uint CooldownTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Bool Func that will provide a value for the PowerIsOn Output. Must be implemented
|
||||
/// by concrete sub-classes
|
||||
/// </summary>
|
||||
abstract protected Func<bool> IsCoolingDownFeedbackFunc { get; }
|
||||
abstract protected Func<bool> IsWarmingUpFeedbackFunc { get; }
|
||||
|
||||
|
||||
protected CTimer WarmupTimer;
|
||||
protected CTimer CooldownTimer;
|
||||
|
||||
#region IRoutingInputs Members
|
||||
|
||||
public RoutingPortCollection<RoutingInputPort> InputPorts { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
protected DisplayBase(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
IsCoolingDownFeedback = new BoolFeedback("IsCoolingDown", IsCoolingDownFeedbackFunc);
|
||||
IsWarmingUpFeedback = new BoolFeedback("IsWarmingUp", IsWarmingUpFeedbackFunc);
|
||||
|
||||
InputPorts = new RoutingPortCollection<RoutingInputPort>();
|
||||
|
||||
}
|
||||
|
||||
public abstract void PowerOn();
|
||||
public abstract void PowerOff();
|
||||
public abstract void PowerToggle();
|
||||
|
||||
public virtual FeedbackCollection<Feedback> Feedbacks
|
||||
{
|
||||
get
|
||||
{
|
||||
return new FeedbackCollection<Feedback>
|
||||
{
|
||||
IsCoolingDownFeedback,
|
||||
IsWarmingUpFeedback
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void ExecuteSwitch(object selector);
|
||||
|
||||
protected void LinkDisplayToApi(DisplayBase displayDevice, BasicTriList trilist, uint joinStart, string joinMapKey,
|
||||
EiscApiAdvanced bridge)
|
||||
{
|
||||
var inputNumber = 0;
|
||||
var inputKeys = new List<string>();
|
||||
|
||||
var joinMap = new DisplayControllerJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<DisplayControllerJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
@@ -137,163 +124,198 @@ namespace PepperDash.Essentials.Core
|
||||
Debug.Console(0,this,"Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
Debug.Console(0, "Linking to Display: {0}", displayDevice.Name);
|
||||
|
||||
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = displayDevice.Name;
|
||||
|
||||
var commMonitor = displayDevice as ICommunicationMonitor;
|
||||
if (commMonitor != null)
|
||||
{
|
||||
commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||
}
|
||||
|
||||
var inputNumberFeedback = new IntFeedback(() => inputNumber);
|
||||
|
||||
// Two way feedbacks
|
||||
var twoWayDisplay = displayDevice as TwoWayDisplayBase;
|
||||
|
||||
if (twoWayDisplay != null)
|
||||
{
|
||||
trilist.SetBool(joinMap.IsTwoWayDisplay.JoinNumber, true);
|
||||
|
||||
twoWayDisplay.CurrentInputFeedback.OutputChange += (o, a) => Debug.Console(0, "CurrentInputFeedback_OutputChange {0}", a.StringValue);
|
||||
|
||||
|
||||
inputNumberFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputSelect.JoinNumber]);
|
||||
}
|
||||
|
||||
// Power Off
|
||||
trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, () =>
|
||||
{
|
||||
inputNumber = 102;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
displayDevice.PowerOff();
|
||||
});
|
||||
|
||||
displayDevice.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (!a.BoolValue)
|
||||
{
|
||||
inputNumber = 102;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
inputNumber = 0;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
displayDevice.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]);
|
||||
|
||||
// PowerOn
|
||||
trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, () =>
|
||||
{
|
||||
inputNumber = 0;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
displayDevice.PowerOn();
|
||||
});
|
||||
|
||||
|
||||
displayDevice.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]);
|
||||
|
||||
for (int i = 0; i < displayDevice.InputPorts.Count; i++)
|
||||
{
|
||||
if (i < joinMap.InputNamesOffset.JoinSpan)
|
||||
{
|
||||
inputKeys.Add(displayDevice.InputPorts[i].Key);
|
||||
var tempKey = inputKeys.ElementAt(i);
|
||||
trilist.SetSigTrueAction((ushort)(joinMap.InputSelectOffset.JoinNumber + i),
|
||||
() => displayDevice.ExecuteSwitch(displayDevice.InputPorts[tempKey].Selector));
|
||||
Debug.Console(2, displayDevice, "Setting Input Select Action on Digital Join {0} to Input: {1}",
|
||||
joinMap.InputSelectOffset.JoinNumber + i, displayDevice.InputPorts[tempKey].Key.ToString());
|
||||
trilist.StringInput[(ushort)(joinMap.InputNamesOffset.JoinNumber + i)].StringValue = displayDevice.InputPorts[i].Key.ToString();
|
||||
}
|
||||
else
|
||||
Debug.Console(0, displayDevice, Debug.ErrorLogLevel.Warning, "Device has {0} inputs. The Join Map allows up to {1} inputs. Discarding inputs {2} - {3} from bridge.",
|
||||
displayDevice.InputPorts.Count, joinMap.InputNamesOffset.JoinSpan, i + 1, displayDevice.InputPorts.Count);
|
||||
}
|
||||
|
||||
Debug.Console(2, displayDevice, "Setting Input Select Action on Analog Join {0}", joinMap.InputSelect);
|
||||
trilist.SetUShortSigAction(joinMap.InputSelect.JoinNumber, (a) =>
|
||||
{
|
||||
if (a == 0)
|
||||
{
|
||||
displayDevice.PowerOff();
|
||||
inputNumber = 0;
|
||||
}
|
||||
else if (a > 0 && a < displayDevice.InputPorts.Count && a != inputNumber)
|
||||
{
|
||||
displayDevice.ExecuteSwitch(displayDevice.InputPorts.ElementAt(a - 1).Selector);
|
||||
inputNumber = a;
|
||||
}
|
||||
else if (a == 102)
|
||||
{
|
||||
displayDevice.PowerToggle();
|
||||
|
||||
}
|
||||
if (twoWayDisplay != null)
|
||||
inputNumberFeedback.FireUpdate();
|
||||
});
|
||||
|
||||
|
||||
var volumeDisplay = displayDevice as IBasicVolumeControls;
|
||||
if (volumeDisplay == null) return;
|
||||
|
||||
trilist.SetBoolSigAction(joinMap.VolumeUp.JoinNumber, volumeDisplay.VolumeUp);
|
||||
trilist.SetBoolSigAction(joinMap.VolumeDown.JoinNumber, volumeDisplay.VolumeDown);
|
||||
trilist.SetSigTrueAction(joinMap.VolumeMute.JoinNumber, volumeDisplay.MuteToggle);
|
||||
|
||||
var volumeDisplayWithFeedback = volumeDisplay as IBasicVolumeWithFeedback;
|
||||
|
||||
if (volumeDisplayWithFeedback == null) return;
|
||||
trilist.SetSigTrueAction(joinMap.VolumeMuteOn.JoinNumber, volumeDisplayWithFeedback.MuteOn);
|
||||
trilist.SetSigTrueAction(joinMap.VolumeMuteOff.JoinNumber, volumeDisplayWithFeedback.MuteOff);
|
||||
|
||||
|
||||
trilist.SetUShortSigAction(joinMap.VolumeLevel.JoinNumber, volumeDisplayWithFeedback.SetVolume);
|
||||
volumeDisplayWithFeedback.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[joinMap.VolumeLevel.JoinNumber]);
|
||||
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMute.JoinNumber]);
|
||||
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMuteOn.JoinNumber]);
|
||||
volumeDisplayWithFeedback.MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class TwoWayDisplayBase : DisplayBase
|
||||
{
|
||||
public StringFeedback CurrentInputFeedback { get; private set; }
|
||||
|
||||
abstract protected Func<string> CurrentInputFeedbackFunc { get; }
|
||||
|
||||
|
||||
public static MockDisplay DefaultDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_DefaultDisplay == null)
|
||||
_DefaultDisplay = new MockDisplay("default", "Default Display");
|
||||
return _DefaultDisplay;
|
||||
}
|
||||
}
|
||||
static MockDisplay _DefaultDisplay;
|
||||
|
||||
public TwoWayDisplayBase(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
CurrentInputFeedback = new StringFeedback(CurrentInputFeedbackFunc);
|
||||
|
||||
WarmupTime = 7000;
|
||||
CooldownTime = 15000;
|
||||
|
||||
Feedbacks.Add(CurrentInputFeedback);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Debug.Console(1, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
Debug.Console(0, "Linking to Display: {0}", displayDevice.Name);
|
||||
|
||||
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = displayDevice.Name;
|
||||
|
||||
var commMonitor = displayDevice as ICommunicationMonitor;
|
||||
if (commMonitor != null)
|
||||
{
|
||||
commMonitor.CommunicationMonitor.IsOnlineFeedback.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||
}
|
||||
|
||||
var inputNumberFeedback = new IntFeedback(() => inputNumber);
|
||||
|
||||
// Two way feedbacks
|
||||
var twoWayDisplay = displayDevice as TwoWayDisplayBase;
|
||||
|
||||
if (twoWayDisplay != null)
|
||||
{
|
||||
trilist.SetBool(joinMap.IsTwoWayDisplay.JoinNumber, true);
|
||||
|
||||
twoWayDisplay.CurrentInputFeedback.OutputChange += (o, a) => Debug.Console(0, "CurrentInputFeedback_OutputChange {0}", a.StringValue);
|
||||
|
||||
|
||||
inputNumberFeedback.LinkInputSig(trilist.UShortInput[joinMap.InputSelect.JoinNumber]);
|
||||
}
|
||||
|
||||
// Power Off
|
||||
trilist.SetSigTrueAction(joinMap.PowerOff.JoinNumber, () =>
|
||||
{
|
||||
inputNumber = 102;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
displayDevice.PowerOff();
|
||||
});
|
||||
|
||||
var twoWayDisplayDevice = displayDevice as TwoWayDisplayBase;
|
||||
if (twoWayDisplayDevice != null)
|
||||
{
|
||||
twoWayDisplayDevice.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (!a.BoolValue)
|
||||
{
|
||||
inputNumber = 102;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
inputNumber = 0;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
twoWayDisplayDevice.PowerIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.PowerOff.JoinNumber]);
|
||||
twoWayDisplayDevice.PowerIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PowerOn.JoinNumber]);
|
||||
}
|
||||
|
||||
// PowerOn
|
||||
trilist.SetSigTrueAction(joinMap.PowerOn.JoinNumber, () =>
|
||||
{
|
||||
inputNumber = 0;
|
||||
inputNumberFeedback.FireUpdate();
|
||||
displayDevice.PowerOn();
|
||||
});
|
||||
|
||||
|
||||
|
||||
for (int i = 0; i < displayDevice.InputPorts.Count; i++)
|
||||
{
|
||||
if (i < joinMap.InputNamesOffset.JoinSpan)
|
||||
{
|
||||
inputKeys.Add(displayDevice.InputPorts[i].Key);
|
||||
var tempKey = inputKeys.ElementAt(i);
|
||||
trilist.SetSigTrueAction((ushort)(joinMap.InputSelectOffset.JoinNumber + i),
|
||||
() => displayDevice.ExecuteSwitch(displayDevice.InputPorts[tempKey].Selector));
|
||||
Debug.Console(2, displayDevice, "Setting Input Select Action on Digital Join {0} to Input: {1}",
|
||||
joinMap.InputSelectOffset.JoinNumber + i, displayDevice.InputPorts[tempKey].Key.ToString());
|
||||
trilist.StringInput[(ushort)(joinMap.InputNamesOffset.JoinNumber + i)].StringValue = displayDevice.InputPorts[i].Key.ToString();
|
||||
}
|
||||
else
|
||||
Debug.Console(0, displayDevice, Debug.ErrorLogLevel.Warning, "Device has {0} inputs. The Join Map allows up to {1} inputs. Discarding inputs {2} - {3} from bridge.",
|
||||
displayDevice.InputPorts.Count, joinMap.InputNamesOffset.JoinSpan, i + 1, displayDevice.InputPorts.Count);
|
||||
}
|
||||
|
||||
Debug.Console(2, displayDevice, "Setting Input Select Action on Analog Join {0}", joinMap.InputSelect);
|
||||
trilist.SetUShortSigAction(joinMap.InputSelect.JoinNumber, (a) =>
|
||||
{
|
||||
if (a == 0)
|
||||
{
|
||||
displayDevice.PowerOff();
|
||||
inputNumber = 0;
|
||||
}
|
||||
else if (a > 0 && a < displayDevice.InputPorts.Count && a != inputNumber)
|
||||
{
|
||||
displayDevice.ExecuteSwitch(displayDevice.InputPorts.ElementAt(a - 1).Selector);
|
||||
inputNumber = a;
|
||||
}
|
||||
else if (a == 102)
|
||||
{
|
||||
displayDevice.PowerToggle();
|
||||
|
||||
}
|
||||
if (twoWayDisplay != null)
|
||||
inputNumberFeedback.FireUpdate();
|
||||
});
|
||||
|
||||
|
||||
var volumeDisplay = displayDevice as IBasicVolumeControls;
|
||||
if (volumeDisplay == null) return;
|
||||
|
||||
trilist.SetBoolSigAction(joinMap.VolumeUp.JoinNumber, volumeDisplay.VolumeUp);
|
||||
trilist.SetBoolSigAction(joinMap.VolumeDown.JoinNumber, volumeDisplay.VolumeDown);
|
||||
trilist.SetSigTrueAction(joinMap.VolumeMute.JoinNumber, volumeDisplay.MuteToggle);
|
||||
|
||||
var volumeDisplayWithFeedback = volumeDisplay as IBasicVolumeWithFeedback;
|
||||
|
||||
if (volumeDisplayWithFeedback == null) return;
|
||||
trilist.SetSigTrueAction(joinMap.VolumeMuteOn.JoinNumber, volumeDisplayWithFeedback.MuteOn);
|
||||
trilist.SetSigTrueAction(joinMap.VolumeMuteOff.JoinNumber, volumeDisplayWithFeedback.MuteOff);
|
||||
|
||||
|
||||
trilist.SetUShortSigAction(joinMap.VolumeLevel.JoinNumber, volumeDisplayWithFeedback.SetVolume);
|
||||
volumeDisplayWithFeedback.VolumeLevelFeedback.LinkInputSig(trilist.UShortInput[joinMap.VolumeLevel.JoinNumber]);
|
||||
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMute.JoinNumber]);
|
||||
volumeDisplayWithFeedback.MuteFeedback.LinkInputSig(trilist.BooleanInput[joinMap.VolumeMuteOn.JoinNumber]);
|
||||
volumeDisplayWithFeedback.MuteFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.VolumeMuteOff.JoinNumber]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class TwoWayDisplayBase : DisplayBase, IRoutingFeedback, IHasPowerControlWithFeedback
|
||||
{
|
||||
public StringFeedback CurrentInputFeedback { get; private set; }
|
||||
|
||||
abstract protected Func<string> CurrentInputFeedbackFunc { get; }
|
||||
|
||||
public override BoolFeedback PowerIsOnFeedback { get; protected set; }
|
||||
|
||||
abstract protected Func<bool> PowerIsOnFeedbackFunc { get; }
|
||||
|
||||
|
||||
public static MockDisplay DefaultDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_DefaultDisplay == null)
|
||||
_DefaultDisplay = new MockDisplay("default", "Default Display");
|
||||
return _DefaultDisplay;
|
||||
}
|
||||
}
|
||||
static MockDisplay _DefaultDisplay;
|
||||
|
||||
public TwoWayDisplayBase(string key, string name)
|
||||
: base(key, name)
|
||||
{
|
||||
CurrentInputFeedback = new StringFeedback(CurrentInputFeedbackFunc);
|
||||
|
||||
WarmupTime = 7000;
|
||||
CooldownTime = 15000;
|
||||
|
||||
PowerIsOnFeedback = new BoolFeedback("PowerOnFeedback", PowerIsOnFeedbackFunc);
|
||||
|
||||
Feedbacks.Add(CurrentInputFeedback);
|
||||
Feedbacks.Add(PowerIsOnFeedback);
|
||||
|
||||
PowerIsOnFeedback.OutputChange += PowerIsOnFeedback_OutputChange;
|
||||
|
||||
}
|
||||
|
||||
void PowerIsOnFeedback_OutputChange(object sender, EventArgs e)
|
||||
{
|
||||
if (UsageTracker != null)
|
||||
{
|
||||
if (PowerIsOnFeedback.BoolValue)
|
||||
UsageTracker.StartDeviceUsage();
|
||||
else
|
||||
UsageTracker.EndDeviceUsage();
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler<RoutingNumericEventArgs> NumericSwitchChange;
|
||||
|
||||
/// <summary>
|
||||
/// Raise an event when the status of a switch object changes.
|
||||
/// </summary>
|
||||
/// <param name="e">Arguments defined as IKeyName sender, output, input, and eRoutingSignalType</param>
|
||||
protected void OnSwitchChange(RoutingNumericEventArgs e)
|
||||
{
|
||||
var newEvent = NumericSwitchChange;
|
||||
if (newEvent != null) newEvent(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public static class JsonExtensions
|
||||
{
|
||||
public static List<JToken> FindTokens(this JToken containerToken, string name)
|
||||
{
|
||||
List<JToken> matches = new List<JToken>();
|
||||
FindTokens(containerToken, name, matches);
|
||||
return matches;
|
||||
}
|
||||
|
||||
private static void FindTokens(JToken containerToken, string name, List<JToken> matches)
|
||||
{
|
||||
if (containerToken.Type == JTokenType.Object)
|
||||
{
|
||||
foreach (JProperty child in containerToken.Children<JProperty>())
|
||||
{
|
||||
if (child.Name == name)
|
||||
{
|
||||
matches.Add(child.Value);
|
||||
}
|
||||
FindTokens(child.Value, name, matches);
|
||||
}
|
||||
}
|
||||
else if (containerToken.Type == JTokenType.Array)
|
||||
{
|
||||
foreach (JToken child in containerToken.Children())
|
||||
{
|
||||
FindTokens(child, name, matches);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@ using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.GeneralIO;
|
||||
using Crestron.SimplSharp.Reflection;
|
||||
using PepperDash.Core;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.CrestronIO;
|
||||
@@ -67,13 +69,13 @@ namespace PepperDash.Essentials.Core
|
||||
/// <returns></returns>
|
||||
public static void AddFactoryForType(string typeName, Func<DeviceConfig, IKeyed> method)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
|
||||
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
|
||||
DeviceFactory.FactoryMethods.Add(typeName, new DeviceFactoryWrapper() { FactoryMethod = method});
|
||||
}
|
||||
|
||||
public static void AddFactoryForType(string typeName, string description, CType cType, Func<DeviceConfig, IKeyed> method)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
|
||||
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Adding factory method for type '{0}'", typeName);
|
||||
|
||||
if(FactoryMethods.ContainsKey(typeName))
|
||||
{
|
||||
@@ -83,33 +85,81 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
var wrapper = new DeviceFactoryWrapper() { CType = cType, Description = description, FactoryMethod = method };
|
||||
DeviceFactory.FactoryMethods.Add(typeName, wrapper);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The factory method for Core "things". Also iterates the Factory methods that have
|
||||
/// been loaded from plugins
|
||||
/// </summary>
|
||||
/// <param name="dc"></param>
|
||||
/// <returns></returns>
|
||||
public static IKeyed GetDevice(DeviceConfig dc)
|
||||
{
|
||||
var key = dc.Key;
|
||||
var name = dc.Name;
|
||||
var type = dc.Type;
|
||||
var properties = dc.Properties;
|
||||
|
||||
var typeName = dc.Type.ToLower();
|
||||
|
||||
// Check for types that have been added by plugin dlls.
|
||||
if (FactoryMethods.ContainsKey(typeName))
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from Essentials Core", dc.Type);
|
||||
return FactoryMethods[typeName].FactoryMethod(dc);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void CheckForSecrets(IEnumerable<JProperty> obj)
|
||||
{
|
||||
foreach (var prop in obj.Where(prop => prop.Value as JObject != null))
|
||||
{
|
||||
if (prop.Name.ToLower() == "secret")
|
||||
{
|
||||
var secret = GetSecret(prop.Children().First().ToObject<SecretsPropertiesConfig>());
|
||||
//var secret = GetSecret(JsonConvert.DeserializeObject<SecretsPropertiesConfig>(prop.Children().First().ToString()));
|
||||
prop.Parent.Replace(secret);
|
||||
}
|
||||
var recurseProp = prop.Value as JObject;
|
||||
if (recurseProp == null) return;
|
||||
CheckForSecrets(recurseProp.Properties());
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetSecret(SecretsPropertiesConfig data)
|
||||
{
|
||||
var secretProvider = SecretsManager.GetSecretProviderByKey(data.Provider);
|
||||
if (secretProvider == null) return null;
|
||||
var secret = secretProvider.GetSecret(data.Key);
|
||||
if (secret != null) return (string) secret.Value;
|
||||
Debug.Console(1,
|
||||
"Unable to retrieve secret {0}{1} - Make sure you've added it to the secrets provider",
|
||||
data.Provider, data.Key);
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The factory method for Core "things". Also iterates the Factory methods that have
|
||||
/// been loaded from plugins
|
||||
/// </summary>
|
||||
/// <param name="dc"></param>
|
||||
/// <returns></returns>
|
||||
public static IKeyed GetDevice(DeviceConfig dc)
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from Essentials Core", dc.Type);
|
||||
|
||||
var localDc = new DeviceConfig(dc);
|
||||
|
||||
var key = localDc.Key;
|
||||
var name = localDc.Name;
|
||||
var type = localDc.Type;
|
||||
var properties = localDc.Properties;
|
||||
//var propRecurse = properties;
|
||||
|
||||
var typeName = localDc.Type.ToLower();
|
||||
|
||||
|
||||
var jObject = properties as JObject;
|
||||
if (jObject != null)
|
||||
{
|
||||
var jProp = jObject.Properties();
|
||||
|
||||
CheckForSecrets(jProp);
|
||||
}
|
||||
|
||||
Debug.Console(2, "typeName = {0}", typeName);
|
||||
// Check for types that have been added by plugin dlls.
|
||||
return !FactoryMethods.ContainsKey(typeName) ? null : FactoryMethods[typeName].FactoryMethod(localDc);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Exception occurred while creating device {0}: {1}", dc.Key, ex.Message);
|
||||
|
||||
Debug.Console(2, "{0}", ex.StackTrace);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prints the type names and associated metadata from the FactoryMethods collection.
|
||||
/// </summary>
|
||||
|
||||
@@ -3,8 +3,9 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash_Essentials_Core
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public class IsReadyEventArgs : EventArgs
|
||||
{
|
||||
@@ -16,6 +17,27 @@ namespace PepperDash_Essentials_Core
|
||||
}
|
||||
}
|
||||
|
||||
public interface IHasReady
|
||||
{
|
||||
event EventHandler<IsReadyEventArgs> IsReadyEvent;
|
||||
bool IsReady { get; }
|
||||
}
|
||||
}
|
||||
|
||||
namespace PepperDash_Essentials_Core
|
||||
{
|
||||
[Obsolete("Use PepperDash.Essentials.Core")]
|
||||
public class IsReadyEventArgs : EventArgs
|
||||
{
|
||||
public bool IsReady { get; set; }
|
||||
|
||||
public IsReadyEventArgs(bool data)
|
||||
{
|
||||
IsReady = data;
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use PepperDash.Essentials.Core")]
|
||||
public interface IHasReady
|
||||
{
|
||||
event EventHandler<IsReadyEventArgs> IsReadyEvent;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core.Fusion
|
||||
{
|
||||
public class EssentialsHuddleSpaceRoomFusionRoomJoinMap : JoinMapBaseAdvanced
|
||||
{
|
||||
|
||||
// Processor Attributes
|
||||
[JoinName("ProcessorIp1")]
|
||||
public JoinDataComplete ProcessorIp1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1, AttributeName = "Info - Processor - IP 1" },
|
||||
new JoinMetadata { Description = "Info - Processor - IP 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorIp2")]
|
||||
public JoinDataComplete ProcessorIp2 = new JoinDataComplete(new JoinData { JoinNumber = 51, JoinSpan = 1, AttributeName = "Info - Processor - IP 2" },
|
||||
new JoinMetadata { Description = "Info - Processor - IP 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorGateway")]
|
||||
public JoinDataComplete ProcessorGateway = new JoinDataComplete(new JoinData { JoinNumber = 52, JoinSpan = 1, AttributeName = "Info - Processor - Gateway" },
|
||||
new JoinMetadata { Description = "Info - Processor - Gateway", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorHostname")]
|
||||
public JoinDataComplete ProcessorHostname = new JoinDataComplete(new JoinData { JoinNumber = 53, JoinSpan = 1, AttributeName = "Info - Processor - Hostname" },
|
||||
new JoinMetadata { Description = "Info - Processor - Hostname", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorDomain")]
|
||||
public JoinDataComplete ProcessorDomain = new JoinDataComplete(new JoinData { JoinNumber = 54, JoinSpan = 1, AttributeName = "Info - Processor - Domain" },
|
||||
new JoinMetadata { Description = "Info - Processor - Domain", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorDns1")]
|
||||
public JoinDataComplete ProcessorDns1 = new JoinDataComplete(new JoinData { JoinNumber = 55, JoinSpan = 1, AttributeName = "Info - Processor - DNS 1" },
|
||||
new JoinMetadata { Description = "Info - Processor - DNS 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorDns2")]
|
||||
public JoinDataComplete ProcessorDns2 = new JoinDataComplete(new JoinData { JoinNumber = 56, JoinSpan = 1, AttributeName = "Info - Processor - DNS 2" },
|
||||
new JoinMetadata { Description = "Info - Processor - DNS 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorMac1")]
|
||||
public JoinDataComplete ProcessorMac1 = new JoinDataComplete(new JoinData { JoinNumber = 57, JoinSpan = 1, AttributeName = "Info - Processor - MAC 1" },
|
||||
new JoinMetadata { Description = "Info - Processor - MAC 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorMac2")]
|
||||
public JoinDataComplete ProcessorMac2 = new JoinDataComplete(new JoinData { JoinNumber = 58, JoinSpan = 1, AttributeName = "Info - Processor - MAC 2" },
|
||||
new JoinMetadata { Description = "Info - Processor - MAC 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorNetMask1")]
|
||||
public JoinDataComplete ProcessorNetMask1 = new JoinDataComplete(new JoinData { JoinNumber = 59, JoinSpan = 1, AttributeName = "Info - Processor - Net Mask 1" },
|
||||
new JoinMetadata { Description = "Info - Processor - Net Mask 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorNetMask2")]
|
||||
public JoinDataComplete ProcessorNetMask2 = new JoinDataComplete(new JoinData { JoinNumber = 60, JoinSpan = 1, AttributeName = "Info - Processor - Net Mask 2" },
|
||||
new JoinMetadata { Description = "Info - Processor - Net Mask 2", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorFirmware")]
|
||||
public JoinDataComplete ProcessorFirmware = new JoinDataComplete(new JoinData { JoinNumber = 61, JoinSpan = 1, AttributeName = "Info - Processor - Firmware" },
|
||||
new JoinMetadata { Description = "Info - Processor - Firmware", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProgramNameStart")]
|
||||
public JoinDataComplete ProgramNameStart = new JoinDataComplete(new JoinData { JoinNumber = 62, JoinSpan = 10, AttributeName = "Info - Processor - Program" },
|
||||
new JoinMetadata { Description = "Info - Processor - Program", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("ProcessorReboot")]
|
||||
public JoinDataComplete ProcessorReboot = new JoinDataComplete(new JoinData { JoinNumber = 74, JoinSpan = 1, AttributeName = "Processor - Reboot" },
|
||||
new JoinMetadata { Description = "Processor - Reboot", JoinCapabilities = eJoinCapabilities.FromFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
// Volume Controls
|
||||
[JoinName("VolumeFader1")]
|
||||
public JoinDataComplete VolumeFader1 = new JoinDataComplete(new JoinData { JoinNumber = 50, JoinSpan = 1, AttributeName = "Volume - Fader01" },
|
||||
new JoinMetadata { Description = "Volume - Fader01", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Analog });
|
||||
|
||||
// Codec Info
|
||||
[JoinName("VcCodecInCall")]
|
||||
public JoinDataComplete VcCodecInCall = new JoinDataComplete(new JoinData { JoinNumber = 69, JoinSpan = 1, AttributeName = "Conf - VC 1 In Call" },
|
||||
new JoinMetadata { Description = "Conf - VC 1 In Call", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("VcCodecOnline")]
|
||||
public JoinDataComplete VcCodecOnline = new JoinDataComplete(new JoinData { JoinNumber = 122, JoinSpan = 1, AttributeName = "Online - VC 1" },
|
||||
new JoinMetadata { Description = "Online - VC 1", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("VcCodecIpAddress")]
|
||||
public JoinDataComplete VcCodecIpAddress = new JoinDataComplete(new JoinData { JoinNumber = 121, JoinSpan = 1, AttributeName = "IP Address - VC" },
|
||||
new JoinMetadata { Description = "IP Address - VC", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
[JoinName("VcCodecIpPort")]
|
||||
public JoinDataComplete VcCodecIpPort = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 1, AttributeName = "IP Port - VC" },
|
||||
new JoinMetadata { Description = "IP Port - VC", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
// Source Attributes
|
||||
[JoinName("Display1CurrentSourceName")]
|
||||
public JoinDataComplete Display1CurrentSourceName = new JoinDataComplete(new JoinData { JoinNumber = 84, JoinSpan = 1, AttributeName = "Display 1 - Current Source" },
|
||||
new JoinMetadata { Description = "Display 1 - Current Source", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Serial });
|
||||
|
||||
|
||||
// Device Online Status
|
||||
[JoinName("TouchpanelOnlineStart")]
|
||||
public JoinDataComplete TouchpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 150, JoinSpan = 10, AttributeName = "Online - Touch Panel" },
|
||||
new JoinMetadata { Description = "Online - Touch Panel", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("XpanelOnlineStart")]
|
||||
public JoinDataComplete XpanelOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 160, JoinSpan = 5, AttributeName = "Online - XPanel" },
|
||||
new JoinMetadata { Description = "Online - XPanel", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("DisplayOnlineStart")]
|
||||
public JoinDataComplete DisplayOnlineStart = new JoinDataComplete(new JoinData { JoinNumber = 170, JoinSpan = 10, AttributeName = "Online - Display" },
|
||||
new JoinMetadata { Description = "Online - Display", JoinCapabilities = eJoinCapabilities.ToFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Display1LaptopSourceStart")]
|
||||
public JoinDataComplete Display1LaptopSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 166, JoinSpan = 5, AttributeName = "Display 1 - Source Laptop" },
|
||||
new JoinMetadata { Description = "Display 1 - Source Laptop", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Display1DiscPlayerSourceStart")]
|
||||
public JoinDataComplete Display1DiscPlayerSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 181, JoinSpan = 5, AttributeName = "Display 1 - Source Disc Player" },
|
||||
new JoinMetadata { Description = "Display 1 - Source Disc Player", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
[JoinName("Display1SetTopBoxSourceStart")]
|
||||
public JoinDataComplete Display1SetTopBoxSourceStart = new JoinDataComplete(new JoinData { JoinNumber = 188, JoinSpan = 5, AttributeName = "Display 1 - Source TV" },
|
||||
new JoinMetadata { Description = "Display 1 - Source TV", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
// Display 1
|
||||
[JoinName("Display1Start")]
|
||||
public JoinDataComplete Display1Start = new JoinDataComplete(new JoinData { JoinNumber = 158, JoinSpan = 1 },
|
||||
new JoinMetadata { Description = "Display 1 Start", JoinCapabilities = eJoinCapabilities.ToFromFusion, JoinType = eJoinType.Digital });
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to use when instantiating this Join Map without inheriting from it
|
||||
/// </summary>
|
||||
/// <param name="joinStart">Join this join map will start at</param>
|
||||
public EssentialsHuddleSpaceRoomFusionRoomJoinMap(uint joinStart)
|
||||
: base(joinStart, typeof(EssentialsHuddleSpaceRoomFusionRoomJoinMap))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to use when extending this Join map
|
||||
/// </summary>
|
||||
/// <param name="joinStart">Join this join map will start at</param>
|
||||
/// <param name="type">Type of the child join map</param>
|
||||
public EssentialsHuddleSpaceRoomFusionRoomJoinMap(uint joinStart, Type type) : base(joinStart, type)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash_Essentials_Core.Gateways
|
||||
{
|
||||
public class CenCn2Controller
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,7 @@ using Crestron.SimplSharpPro.DeviceSupport;
|
||||
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash_Essentials_Core;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public class EthernetAdapterInfo
|
||||
{
|
||||
public EthernetAdapterType Type { get; set; }
|
||||
public bool DhcpIsOn { get; set; }
|
||||
public string Hostname { get; set; }
|
||||
public string MacAddress { get; set; }
|
||||
public string IpAddress { get; set; }
|
||||
public string Subnet { get; set; }
|
||||
public string Gateway { get; set; }
|
||||
public string Dns1 { get; set; }
|
||||
public string Dns2 { get; set; }
|
||||
public string Dns3 { get; set; }
|
||||
public string Domain { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,175 +1,182 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Crestron.SimplSharp.CrestronDataStore;
|
||||
using Crestron.SimplSharpPro;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.License;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Schema;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public static class Global
|
||||
{
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using Crestron.SimplSharp;
|
||||
using System.Collections.Generic;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Crestron.SimplSharp.CrestronDataStore;
|
||||
using Crestron.SimplSharpPro;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.License;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Schema;
|
||||
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public static class Global
|
||||
{
|
||||
public static CrestronControlSystem ControlSystem { get; set; }
|
||||
|
||||
public static LicenseManager LicenseManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The file path prefix to the folder containing configuration files
|
||||
/// </summary>
|
||||
public static string FilePathPrefix { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The file path prefix to the applciation directory
|
||||
/// </summary>
|
||||
public static string ApplicationDirectoryPathPrefix
|
||||
{
|
||||
get
|
||||
{
|
||||
return Crestron.SimplSharp.CrestronIO.Directory.GetApplicationDirectory();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the directory separator character based on the running OS
|
||||
/// </summary>
|
||||
public static char DirectorySeparator
|
||||
{
|
||||
get
|
||||
{
|
||||
return System.IO.Path.DirectorySeparatorChar;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wildcarded config file name for global reference
|
||||
/// </summary>
|
||||
public const string ConfigFileName = "*configurationFile*.json";
|
||||
|
||||
/// <summary>
|
||||
/// Sets the file path prefix
|
||||
/// </summary>
|
||||
/// <param name="prefix"></param>
|
||||
public static void SetFilePathPrefix(string prefix)
|
||||
{
|
||||
FilePathPrefix = prefix;
|
||||
}
|
||||
|
||||
static string _AssemblyVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Assembly Version of Essentials
|
||||
/// </summary>
|
||||
/// <returns>The Assembly Version at Runtime</returns>
|
||||
public static string AssemblyVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return _AssemblyVersion;
|
||||
}
|
||||
private set
|
||||
{
|
||||
_AssemblyVersion = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the Assembly version to the version of the Essentials Library
|
||||
/// </summary>
|
||||
/// <param name="assemblyVersion"></param>
|
||||
public static void SetAssemblyVersion(string assemblyVersion)
|
||||
{
|
||||
AssemblyVersion = assemblyVersion;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if the running version meets or exceed the minimum specified version. For beta versions (0.xx.yy), will always return true.
|
||||
/// </summary>
|
||||
/// <param name="minimumVersion">Minimum specified version in format of xx.yy.zz</param>
|
||||
/// <returns>Returns true if the running version meets or exceeds the minimum specified version</returns>
|
||||
public static bool IsRunningMinimumVersionOrHigher(string minimumVersion)
|
||||
{
|
||||
Debug.Console(2, "Comparing running version '{0}' to minimum version '{1}'", AssemblyVersion, minimumVersion);
|
||||
|
||||
if (String.IsNullOrEmpty(minimumVersion))
|
||||
{
|
||||
Debug.Console(0,"Plugin does not specify a minimum version. Loading plugin may not work as expected. Proceeding with loading plugin");
|
||||
return true;
|
||||
}
|
||||
|
||||
var runtimeVersion = Regex.Match(AssemblyVersion, @"^(\d*).(\d*).(\d*).*");
|
||||
|
||||
var runtimeVersionMajor = Int16.Parse(runtimeVersion.Groups[1].Value);
|
||||
var runtimeVersionMinor = Int16.Parse(runtimeVersion.Groups[2].Value);
|
||||
var runtimeVersionBuild = Int16.Parse(runtimeVersion.Groups[3].Value);
|
||||
|
||||
var runtimeVer = new Version(runtimeVersionMajor, runtimeVersionMinor, runtimeVersionBuild);
|
||||
|
||||
Version minimumVer;
|
||||
try
|
||||
{
|
||||
minimumVer = new Version(minimumVersion);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(2, "unable to parse minimum version {0}. Bypassing plugin load.", minimumVersion);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Check for beta build version
|
||||
if (runtimeVer.Major != 0)
|
||||
{
|
||||
return runtimeVer.CompareTo(minimumVer) >= 0;
|
||||
}
|
||||
|
||||
Debug.Console(2, "Running Local Build. Bypassing Dependency Check.");
|
||||
return true;
|
||||
|
||||
/*
|
||||
var minVersion = Regex.Match(minimumVersion, @"^(\d*).(\d*).(\d*)$");
|
||||
|
||||
if(!minVersion.Success)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
var minVersionMajor = Int16.Parse(minVersion.Groups[1].Value);
|
||||
var minVersionMinor = Int16.Parse(minVersion.Groups[2].Value);
|
||||
var minVersionBuild = Int16.Parse(minVersion.Groups[3].Value);
|
||||
|
||||
|
||||
|
||||
if (minVersionMajor > runtimeVersionMajor)
|
||||
return false;
|
||||
|
||||
if (minVersionMinor > runtimeVersionMinor)
|
||||
return false;
|
||||
|
||||
if (minVersionBuild > runtimeVersionBuild)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
*/
|
||||
}
|
||||
|
||||
static Global()
|
||||
{
|
||||
// Fire up CrestronDataStoreStatic
|
||||
var err = CrestronDataStoreStatic.InitCrestronDataStore();
|
||||
if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
|
||||
{
|
||||
CrestronConsole.PrintLine("Error starting CrestronDataStoreStatic: {0}", err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public static eDevicePlatform Platform { get { return CrestronEnvironment.DevicePlatform; } }
|
||||
|
||||
public static Dictionary<short, EthernetAdapterInfo> EthernetAdapterInfoCollection { get; private set; }
|
||||
|
||||
public static LicenseManager LicenseManager { get; set; }
|
||||
|
||||
public static eCrestronSeries ProcessorSeries { get { return CrestronEnvironment.ProgramCompatibility; } }
|
||||
|
||||
/// <summary>
|
||||
/// The file path prefix to the folder containing configuration files
|
||||
/// </summary>
|
||||
public static string FilePathPrefix { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The file path prefix to the applciation directory
|
||||
/// </summary>
|
||||
public static string ApplicationDirectoryPathPrefix
|
||||
{
|
||||
get
|
||||
{
|
||||
return Crestron.SimplSharp.CrestronIO.Directory.GetApplicationDirectory();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the directory separator character based on the running OS
|
||||
/// </summary>
|
||||
public static char DirectorySeparator
|
||||
{
|
||||
get
|
||||
{
|
||||
return System.IO.Path.DirectorySeparatorChar;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wildcarded config file name for global reference
|
||||
/// </summary>
|
||||
public const string ConfigFileName = "*configurationFile*.json";
|
||||
|
||||
/// <summary>
|
||||
/// Sets the file path prefix
|
||||
/// </summary>
|
||||
/// <param name="prefix"></param>
|
||||
public static void SetFilePathPrefix(string prefix)
|
||||
{
|
||||
FilePathPrefix = prefix;
|
||||
}
|
||||
|
||||
static string _AssemblyVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Assembly Version of Essentials
|
||||
/// </summary>
|
||||
/// <returns>The Assembly Version at Runtime</returns>
|
||||
public static string AssemblyVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return _AssemblyVersion;
|
||||
}
|
||||
private set
|
||||
{
|
||||
_AssemblyVersion = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the Assembly version to the version of the Essentials Library
|
||||
/// </summary>
|
||||
/// <param name="assemblyVersion"></param>
|
||||
public static void SetAssemblyVersion(string assemblyVersion)
|
||||
{
|
||||
AssemblyVersion = assemblyVersion;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if the running version meets or exceed the minimum specified version. For beta versions (0.xx.yy), will always return true.
|
||||
/// </summary>
|
||||
/// <param name="minimumVersion">Minimum specified version in format of xx.yy.zz</param>
|
||||
/// <returns>Returns true if the running version meets or exceeds the minimum specified version</returns>
|
||||
public static bool IsRunningMinimumVersionOrHigher(string minimumVersion)
|
||||
{
|
||||
Debug.Console(2, "Comparing running version '{0}' to minimum version '{1}'", AssemblyVersion, minimumVersion);
|
||||
|
||||
if (String.IsNullOrEmpty(minimumVersion))
|
||||
{
|
||||
Debug.Console(0,"Plugin does not specify a minimum version. Loading plugin may not work as expected. Proceeding with loading plugin");
|
||||
return true;
|
||||
}
|
||||
|
||||
var runtimeVersion = Regex.Match(AssemblyVersion, @"^(\d*).(\d*).(\d*).*");
|
||||
|
||||
var runtimeVersionMajor = Int16.Parse(runtimeVersion.Groups[1].Value);
|
||||
var runtimeVersionMinor = Int16.Parse(runtimeVersion.Groups[2].Value);
|
||||
var runtimeVersionBuild = Int16.Parse(runtimeVersion.Groups[3].Value);
|
||||
|
||||
var runtimeVer = new Version(runtimeVersionMajor, runtimeVersionMinor, runtimeVersionBuild);
|
||||
|
||||
Version minimumVer;
|
||||
try
|
||||
{
|
||||
minimumVer = new Version(minimumVersion);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Console(2, "unable to parse minimum version {0}. Bypassing plugin load.", minimumVersion);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Check for beta build version
|
||||
if (runtimeVer.Major != 0)
|
||||
{
|
||||
return runtimeVer.CompareTo(minimumVer) >= 0;
|
||||
}
|
||||
|
||||
Debug.Console(2, "Running Local Build. Bypassing Dependency Check.");
|
||||
return true;
|
||||
|
||||
/*
|
||||
var minVersion = Regex.Match(minimumVersion, @"^(\d*).(\d*).(\d*)$");
|
||||
|
||||
if(!minVersion.Success)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
var minVersionMajor = Int16.Parse(minVersion.Groups[1].Value);
|
||||
var minVersionMinor = Int16.Parse(minVersion.Groups[2].Value);
|
||||
var minVersionBuild = Int16.Parse(minVersion.Groups[3].Value);
|
||||
|
||||
|
||||
|
||||
if (minVersionMajor > runtimeVersionMajor)
|
||||
return false;
|
||||
|
||||
if (minVersionMinor > runtimeVersionMinor)
|
||||
return false;
|
||||
|
||||
if (minVersionBuild > runtimeVersionBuild)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
*/
|
||||
}
|
||||
|
||||
static Global()
|
||||
{
|
||||
// Fire up CrestronDataStoreStatic
|
||||
var err = CrestronDataStoreStatic.InitCrestronDataStore();
|
||||
if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
|
||||
{
|
||||
CrestronConsole.PrintLine("Error starting CrestronDataStoreStatic: {0}", err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.Reflection;
|
||||
using Crestron.SimplSharp.Scheduler;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core.Fusion;
|
||||
using PepperDash.Essentials.Room.Config;
|
||||
using Activator = System.Activator;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
@@ -14,13 +17,17 @@ namespace PepperDash.Essentials.Core
|
||||
/// </summary>
|
||||
public static class Scheduler
|
||||
{
|
||||
private static Dictionary<string, ScheduledEventGroup> EventGroups = new Dictionary<string,ScheduledEventGroup>();
|
||||
private static readonly Dictionary<string, ScheduledEventGroup> EventGroups = new Dictionary<string,ScheduledEventGroup>();
|
||||
|
||||
static Scheduler()
|
||||
{
|
||||
CrestronConsole.AddNewConsoleCommand(ClearEventsFromGroup, "ClearAllEvents", "Clears all scheduled events for this group", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(ListAllEventGroups, "ListAllEventGroups", "Lists all the event groups by key", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(ListAllEventsForGroup, "ListEventsForGroup",
|
||||
"Lists all events for the given group", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -29,12 +36,26 @@ namespace PepperDash.Essentials.Core
|
||||
/// <param name="groupName"></param>
|
||||
static void ClearEventsFromGroup(string groupName)
|
||||
{
|
||||
if (!EventGroups.ContainsKey(groupName))
|
||||
{
|
||||
Debug.Console(0,
|
||||
"[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.",
|
||||
groupName);
|
||||
return;
|
||||
}
|
||||
|
||||
var group = EventGroups[groupName];
|
||||
|
||||
if (group != null)
|
||||
{
|
||||
group.ClearAllEvents();
|
||||
|
||||
Debug.Console(0, "[Scheduler]: All events deleted from group '{0}'", groupName);
|
||||
}
|
||||
else
|
||||
Debug.Console(0, "[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.", groupName);
|
||||
Debug.Console(0,
|
||||
"[Scheduler]: Unable to delete events from group '{0}'. Group not found in EventGroups dictionary.",
|
||||
groupName);
|
||||
}
|
||||
|
||||
static void ListAllEventGroups(string command)
|
||||
@@ -46,10 +67,36 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
}
|
||||
|
||||
static void ListAllEventsForGroup(string args)
|
||||
{
|
||||
Debug.Console(0, "Getting events for group {0}...", args);
|
||||
|
||||
ScheduledEventGroup group;
|
||||
|
||||
if (!EventGroups.TryGetValue(args, out group))
|
||||
{
|
||||
Debug.Console(0, "Unabled to get event group for key {0}", args);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var evt in group.ScheduledEvents)
|
||||
{
|
||||
Debug.Console(0,
|
||||
@"
|
||||
****Event key {0}****
|
||||
Event date/time: {1}
|
||||
Persistent: {2}
|
||||
Acknowlegable: {3}
|
||||
Recurrence: {4}
|
||||
Recurrence Days: {5}
|
||||
********************", evt.Key, evt.Value.DateAndTime, evt.Value.Persistent, evt.Value.Acknowledgeable,
|
||||
evt.Value.Recurrence.Recurrence, evt.Value.Recurrence.RecurrenceDays);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the event group to the global list
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public static void AddEventGroup(ScheduledEventGroup eventGroup)
|
||||
{
|
||||
@@ -67,6 +114,13 @@ namespace PepperDash.Essentials.Core
|
||||
if(!EventGroups.ContainsKey(eventGroup.Name))
|
||||
EventGroups.Remove(eventGroup.Name);
|
||||
}
|
||||
|
||||
public static ScheduledEventGroup GetEventGroup(string key)
|
||||
{
|
||||
ScheduledEventGroup returnValue;
|
||||
|
||||
return EventGroups.TryGetValue(key, out returnValue) ? returnValue : null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class SchedulerUtilities
|
||||
@@ -135,5 +189,90 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
return isMatch;
|
||||
}
|
||||
|
||||
public static bool CheckEventTimeForMatch(ScheduledEvent evnt, DateTime time)
|
||||
{
|
||||
return evnt.DateAndTime.Hour == time.Hour && evnt.DateAndTime.Minute == time.Minute;
|
||||
}
|
||||
|
||||
public static bool CheckEventRecurrenceForMatch(ScheduledEvent evnt, ScheduledEventCommon.eWeekDays days)
|
||||
{
|
||||
return evnt.Recurrence.RecurrenceDays == days;
|
||||
}
|
||||
|
||||
public static void CreateEventFromConfig(ScheduledEventConfig config, ScheduledEventGroup group, ScheduledEvent.UserEventCallBack handler)
|
||||
{
|
||||
if (group == null)
|
||||
{
|
||||
Debug.Console(0, "Unable to create event. Group is null");
|
||||
return;
|
||||
}
|
||||
var scheduledEvent = new ScheduledEvent(config.Key, group)
|
||||
{
|
||||
Acknowledgeable = config.Acknowledgeable,
|
||||
Persistent = config.Persistent
|
||||
};
|
||||
|
||||
scheduledEvent.UserCallBack += handler;
|
||||
|
||||
scheduledEvent.DateAndTime.SetFirstDayOfWeek(ScheduledEventCommon.eFirstDayOfWeek.Sunday);
|
||||
|
||||
var eventTime = DateTime.Parse(config.Time);
|
||||
|
||||
if (DateTime.Now > eventTime)
|
||||
{
|
||||
eventTime = eventTime.AddDays(1);
|
||||
}
|
||||
|
||||
Debug.Console(2, "[Scheduler] Current Date day of week: {0} recurrence days: {1}", eventTime.DayOfWeek,
|
||||
config.Days);
|
||||
|
||||
var dayOfWeekConverted = ConvertDayOfWeek(eventTime);
|
||||
|
||||
Debug.Console(1, "[Scheduler] eventTime Day: {0}", dayOfWeekConverted);
|
||||
|
||||
while (!dayOfWeekConverted.IsFlagSet(config.Days))
|
||||
{
|
||||
eventTime = eventTime.AddDays(1);
|
||||
|
||||
dayOfWeekConverted = ConvertDayOfWeek(eventTime);
|
||||
}
|
||||
|
||||
scheduledEvent.DateAndTime.SetAbsoluteEventTime(eventTime);
|
||||
|
||||
scheduledEvent.Recurrence.Weekly(config.Days);
|
||||
|
||||
if (config.Enable)
|
||||
{
|
||||
scheduledEvent.Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
scheduledEvent.Disable();
|
||||
}
|
||||
}
|
||||
|
||||
private static ScheduledEventCommon.eWeekDays ConvertDayOfWeek(DateTime eventTime)
|
||||
{
|
||||
return (ScheduledEventCommon.eWeekDays) Enum.Parse(typeof(ScheduledEventCommon.eWeekDays), eventTime.DayOfWeek.ToString(), true);
|
||||
}
|
||||
|
||||
private static bool IsFlagSet<T>(this T value, T flag) where T : struct
|
||||
{
|
||||
CheckIsEnum<T>(true);
|
||||
|
||||
var lValue = Convert.ToInt64(value);
|
||||
var lFlag = Convert.ToInt64(flag);
|
||||
|
||||
return (lValue & lFlag) != 0;
|
||||
}
|
||||
|
||||
private static void CheckIsEnum<T>(bool withFlags)
|
||||
{
|
||||
if (!typeof(T).IsEnum)
|
||||
throw new ArgumentException(string.Format("Type '{0}' is not an enum", typeof(T).FullName));
|
||||
if (withFlags && !Attribute.IsDefined(typeof(T), typeof(FlagsAttribute)))
|
||||
throw new ArgumentException(string.Format("Type '{0}' doesn't have the 'Flags' attribute", typeof(T).FullName));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Interfaces
|
||||
{
|
||||
public interface ILogStrings : IKeyed
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a class that is capable of logging a string
|
||||
/// </summary>
|
||||
void SendToLog(IKeyed device, string logMessage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Interfaces
|
||||
{
|
||||
public interface ILogStringsWithLevel : IKeyed
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a class that is capable of logging a string with an int level
|
||||
/// </summary>
|
||||
void SendToLog(IKeyed device, Debug.ErrorLogLevel level,string logMessage);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,7 +25,7 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
var joinMap = ConfigReader.ConfigObject.JoinMaps[joinMapKey];
|
||||
|
||||
return joinMap;
|
||||
return joinMap.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -45,16 +45,33 @@ namespace PepperDash.Essentials.Core
|
||||
/// <returns></returns>
|
||||
public static Dictionary<string, JoinData> TryGetJoinMapAdvancedForDevice(string joinMapKey)
|
||||
{
|
||||
if (string.IsNullOrEmpty(joinMapKey))
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(joinMapKey))
|
||||
return null;
|
||||
|
||||
if (!ConfigReader.ConfigObject.JoinMaps.ContainsKey(joinMapKey))
|
||||
{
|
||||
Debug.Console(2, "No Join Map found in config with key: '{0}'", joinMapKey);
|
||||
return null;
|
||||
}
|
||||
|
||||
Debug.Console(2, "Attempting to load custom join map with key: {0}", joinMapKey);
|
||||
|
||||
var joinMapJToken = ConfigReader.ConfigObject.JoinMaps[joinMapKey];
|
||||
|
||||
if (joinMapJToken == null)
|
||||
return null;
|
||||
|
||||
var joinMapData = joinMapJToken.ToObject<Dictionary<string, JoinData>>();
|
||||
|
||||
return joinMapData;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(2, "Error getting join map for key: '{0}'. Error: {1}", joinMapKey, e);
|
||||
return null;
|
||||
|
||||
var joinMapSerialzed = ConfigReader.ConfigObject.JoinMaps[joinMapKey];
|
||||
|
||||
if (joinMapSerialzed == null) return null;
|
||||
|
||||
var joinMapData = JsonConvert.DeserializeObject<Dictionary<string, JoinData>>(joinMapSerialzed);
|
||||
|
||||
return joinMapData;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -216,7 +233,10 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
|
||||
|
||||
PrintJoinMapInfo();
|
||||
if (Debug.Level > 0)
|
||||
{
|
||||
PrintJoinMapInfo();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -266,7 +286,7 @@ namespace PepperDash.Essentials.Core
|
||||
@"Join Number: {0} | JoinSpan: '{1}' | Description: '{2}' | Type: '{3}' | Capabilities: '{4}'",
|
||||
join.Value.JoinNumber,
|
||||
join.Value.JoinSpan,
|
||||
String.IsNullOrEmpty(join.Value.Metadata.Description) ? join.Value.Metadata.Label: join.Value.Metadata.Description,
|
||||
String.IsNullOrEmpty(join.Value.AttributeName) ? join.Value.Metadata.Label : join.Value.AttributeName,
|
||||
join.Value.Metadata.JoinType.ToString(),
|
||||
join.Value.Metadata.JoinCapabilities.ToString());
|
||||
}
|
||||
@@ -288,7 +308,7 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(2, "No mathcing key found in join map for: '{0}'", customJoinData.Key);
|
||||
Debug.Console(2, "No matching key found in join map for: '{0}'", customJoinData.Key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,7 +347,10 @@ namespace PepperDash.Essentials.Core
|
||||
None = 0,
|
||||
ToSIMPL = 1,
|
||||
FromSIMPL = 2,
|
||||
ToFromSIMPL = ToSIMPL | FromSIMPL
|
||||
ToFromSIMPL = ToSIMPL | FromSIMPL,
|
||||
ToFusion = 4,
|
||||
FromFusion = 8,
|
||||
ToFromFusion = ToFusion | FromFusion,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
@@ -340,7 +363,7 @@ namespace PepperDash.Essentials.Core
|
||||
DigitalAnalog = Digital | Analog,
|
||||
DigitalSerial = Digital | Serial,
|
||||
AnalogSerial = Analog | Serial,
|
||||
DigitalAnalogSerial = Digital | Analog | Serial
|
||||
DigitalAnalogSerial = Digital | Analog | Serial,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -394,7 +417,7 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Data describing the join. Can be
|
||||
/// Data describing the join. Can be overridden from configuratino
|
||||
/// </summary>
|
||||
public class JoinData
|
||||
{
|
||||
@@ -408,6 +431,11 @@ namespace PepperDash.Essentials.Core
|
||||
/// </summary>
|
||||
[JsonProperty("joinSpan")]
|
||||
public uint JoinSpan { get; set; }
|
||||
/// <summary>
|
||||
/// Fusion Attribute Name (optional)
|
||||
/// </summary>
|
||||
[JsonProperty("attributeName")]
|
||||
public string AttributeName { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -419,6 +447,10 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
private JoinData _data;
|
||||
public JoinMetadata Metadata { get; set; }
|
||||
/// <summary>
|
||||
/// To store some future information as you please
|
||||
/// </summary>
|
||||
public object UserObject { get; private set; }
|
||||
|
||||
public JoinDataComplete(JoinData data, JoinMetadata metadata)
|
||||
{
|
||||
@@ -449,6 +481,11 @@ namespace PepperDash.Essentials.Core
|
||||
get { return _data.JoinSpan; }
|
||||
}
|
||||
|
||||
public string AttributeName
|
||||
{
|
||||
get { return _data.AttributeName; }
|
||||
}
|
||||
|
||||
public void SetCustomJoinData(JoinData customJoinData)
|
||||
{
|
||||
_data = customJoinData;
|
||||
|
||||
@@ -88,8 +88,12 @@ namespace PepperDash.Essentials.Core.Privacy
|
||||
else
|
||||
Debug.Console(0, this, "Unable to add Red LED device");
|
||||
|
||||
DeviceManager.AllDevicesActivated += (o, a) =>
|
||||
{
|
||||
CheckPrivacyMode();
|
||||
};
|
||||
|
||||
AddPostActivationAction(() => {
|
||||
CheckPrivacyMode();
|
||||
PrivacyDevice.PrivacyModeIsOnFeedback.OutputChange -= PrivacyModeIsOnFeedback_OutputChange;
|
||||
PrivacyDevice.PrivacyModeIsOnFeedback.OutputChange += PrivacyModeIsOnFeedback_OutputChange;
|
||||
});
|
||||
|
||||
@@ -64,30 +64,34 @@ namespace PepperDash.Essentials.Core
|
||||
initialStatus = MonitorStatus.InWarning;
|
||||
prefix = "2:";
|
||||
}
|
||||
else if (InWarning.Count() > 0)
|
||||
else if (IsOk.Count() > 0)
|
||||
initialStatus = MonitorStatus.IsOk;
|
||||
else
|
||||
initialStatus = MonitorStatus.StatusUnknown;
|
||||
|
||||
// Build the error message string
|
||||
if (InError.Count() > 0 || InWarning.Count() > 0)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(prefix);
|
||||
if (InError.Count() > 0)
|
||||
{
|
||||
// Do string splits and joins
|
||||
sb.Append(string.Format("{0} Errors:", InError.Count()));
|
||||
foreach (var mon in InError)
|
||||
sb.Append(string.Format("{0}, ", mon.Parent.Key));
|
||||
}
|
||||
if (InWarning.Count() > 0)
|
||||
{
|
||||
sb.Append(string.Format("{0} Warnings:", InWarning.Count()));
|
||||
foreach (var mon in InWarning)
|
||||
sb.Append(string.Format("{0}, ", mon.Parent.Key));
|
||||
}
|
||||
Message = sb.ToString();
|
||||
}
|
||||
if (InError.Count() > 0 || InWarning.Count() > 0)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(prefix);
|
||||
if (InError.Count() > 0)
|
||||
{
|
||||
// Do string splits and joins
|
||||
sb.Append(string.Format("{0} Errors:", InError.Count()));
|
||||
foreach (var mon in InError)
|
||||
sb.Append(string.Format("{0}, ", mon.Parent.Key));
|
||||
}
|
||||
if (InWarning.Count() > 0)
|
||||
{
|
||||
sb.Append(string.Format("{0} Warnings:", InWarning.Count()));
|
||||
foreach (var mon in InWarning)
|
||||
sb.Append(string.Format("{0}, ", mon.Parent.Key));
|
||||
}
|
||||
Message = sb.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
Message = "Room Ok.";
|
||||
}
|
||||
|
||||
// Want to fire even if status doesn't change because the message may.
|
||||
Status = initialStatus;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,460 +1,539 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.GeneralIO;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Bridges;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
[Description("Wrapper class for Single Technology GLS Occupancy Sensors")]
|
||||
public class GlsOccupancySensorBaseController : CrestronGenericBridgeableBaseDevice, IOccupancyStatusProvider
|
||||
{
|
||||
public GlsOccupancySensorBase OccSensor { get; private set; }
|
||||
[Description("Wrapper class for Single Technology GLS Occupancy Sensors")]
|
||||
[ConfigSnippet("\"properties\": {\"control\": {\"method\": \"cresnet\",\"cresnetId\": \"97\"},\"enablePir\": true,\"enableLedFlash\": true,\"enableRawStates\":true,\"remoteTimeout\": 30,\"internalPhotoSensorMinChange\": 0,\"externalPhotoSensorMinChange\": 0}")]
|
||||
public abstract class GlsOccupancySensorBaseController : CrestronGenericBridgeableBaseDevice, IOccupancyStatusProvider
|
||||
{
|
||||
public GlsOccupancySensorPropertiesConfig PropertiesConfig { get; private set; }
|
||||
|
||||
public BoolFeedback RoomIsOccupiedFeedback { get; private set; }
|
||||
protected GlsOccupancySensorBase OccSensor;
|
||||
|
||||
public BoolFeedback GraceOccupancyDetectedFeedback { get; private set; }
|
||||
public BoolFeedback RoomIsOccupiedFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback RawOccupancyFeedback { get; private set; }
|
||||
public BoolFeedback GraceOccupancyDetectedFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback PirSensorEnabledFeedback { get; private set; }
|
||||
public BoolFeedback RawOccupancyFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback LedFlashEnabledFeedback { get; private set; }
|
||||
public BoolFeedback PirSensorEnabledFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback ShortTimeoutEnabledFeedback { get; private set; }
|
||||
public BoolFeedback LedFlashEnabledFeedback { get; private set; }
|
||||
|
||||
public IntFeedback PirSensitivityInVacantStateFeedback { get; private set; }
|
||||
public BoolFeedback ShortTimeoutEnabledFeedback { get; private set; }
|
||||
|
||||
public IntFeedback PirSensitivityInOccupiedStateFeedback { get; private set; }
|
||||
public IntFeedback PirSensitivityInVacantStateFeedback { get; private set; }
|
||||
|
||||
public IntFeedback CurrentTimeoutFeedback { get; private set; }
|
||||
public IntFeedback PirSensitivityInOccupiedStateFeedback { get; private set; }
|
||||
|
||||
public IntFeedback LocalTimoutFeedback { get; private set; }
|
||||
public IntFeedback CurrentTimeoutFeedback { get; private set; }
|
||||
|
||||
public IntFeedback InternalPhotoSensorValue { get; set; }
|
||||
public IntFeedback LocalTimoutFeedback { get; private set; }
|
||||
|
||||
public IntFeedback ExternalPhotoSensorValue { get; set; }
|
||||
public IntFeedback InternalPhotoSensorValue { get; set; }
|
||||
|
||||
// Debug properties
|
||||
public bool InTestMode { get; private set; }
|
||||
public IntFeedback ExternalPhotoSensorValue { get; set; }
|
||||
|
||||
public bool TestRoomIsOccupiedFeedback { get; private set; }
|
||||
// Debug properties
|
||||
public bool InTestMode { get; private set; }
|
||||
|
||||
public Func<bool> RoomIsOccupiedFeedbackFunc
|
||||
public bool TestRoomIsOccupiedFeedback { get; private set; }
|
||||
|
||||
public Func<bool> RoomIsOccupiedFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () => InTestMode ? TestRoomIsOccupiedFeedback : OccSensor.OccupancyDetectedFeedback.BoolValue;
|
||||
}
|
||||
}
|
||||
|
||||
protected GlsOccupancySensorBaseController(string key, DeviceConfig config)
|
||||
: this(key, config.Name, config)
|
||||
{
|
||||
}
|
||||
|
||||
protected GlsOccupancySensorBaseController(string key, string name, DeviceConfig config)
|
||||
: base(key, name)
|
||||
{
|
||||
get
|
||||
|
||||
var props = config.Properties.ToObject<GlsOccupancySensorPropertiesConfig>();
|
||||
|
||||
if (props != null)
|
||||
{
|
||||
return () => InTestMode ? TestRoomIsOccupiedFeedback : OccSensor.OccupancyDetectedFeedback.BoolValue;
|
||||
}
|
||||
}
|
||||
|
||||
public GlsOccupancySensorBaseController(string key, Func<DeviceConfig, GlsOccupancySensorBase> preActivationFunc,
|
||||
DeviceConfig config)
|
||||
: base(key, config.Name)
|
||||
{
|
||||
|
||||
|
||||
AddPreActivationAction(() =>
|
||||
{
|
||||
OccSensor = preActivationFunc(config);
|
||||
|
||||
RegisterCrestronGenericBase(OccSensor);
|
||||
|
||||
RegisterGlsOdtSensorBaseController(OccSensor);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public GlsOccupancySensorBaseController(string key, string name) : base(key, name) {}
|
||||
|
||||
protected void RegisterGlsOdtSensorBaseController(GlsOccupancySensorBase occSensor)
|
||||
{
|
||||
OccSensor = occSensor;
|
||||
|
||||
RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc);
|
||||
|
||||
PirSensorEnabledFeedback = new BoolFeedback(() => OccSensor.PirEnabledFeedback.BoolValue);
|
||||
|
||||
LedFlashEnabledFeedback = new BoolFeedback(() => OccSensor.LedFlashEnabledFeedback.BoolValue);
|
||||
|
||||
ShortTimeoutEnabledFeedback = new BoolFeedback(() => OccSensor.ShortTimeoutEnabledFeedback.BoolValue);
|
||||
|
||||
PirSensitivityInVacantStateFeedback =
|
||||
new IntFeedback(() => OccSensor.PirSensitivityInVacantStateFeedback.UShortValue);
|
||||
|
||||
PirSensitivityInOccupiedStateFeedback =
|
||||
new IntFeedback(() => OccSensor.PirSensitivityInOccupiedStateFeedback.UShortValue);
|
||||
|
||||
CurrentTimeoutFeedback = new IntFeedback(() => OccSensor.CurrentTimeoutFeedback.UShortValue);
|
||||
|
||||
LocalTimoutFeedback = new IntFeedback(() => OccSensor.LocalTimeoutFeedback.UShortValue);
|
||||
|
||||
GraceOccupancyDetectedFeedback =
|
||||
new BoolFeedback(() => OccSensor.GraceOccupancyDetectedFeedback.BoolValue);
|
||||
|
||||
RawOccupancyFeedback = new BoolFeedback(() => OccSensor.RawOccupancyFeedback.BoolValue);
|
||||
|
||||
InternalPhotoSensorValue = new IntFeedback(() => OccSensor.InternalPhotoSensorValueFeedback.UShortValue);
|
||||
|
||||
ExternalPhotoSensorValue = new IntFeedback(() => OccSensor.ExternalPhotoSensorValueFeedback.UShortValue);
|
||||
|
||||
OccSensor.BaseEvent += OccSensor_BaseEvent;
|
||||
|
||||
OccSensor.GlsOccupancySensorChange += OccSensor_GlsOccupancySensorChange;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Catches events for feedbacks on the base class. Any extending wrapper class should call this delegate after it checks for it's own event IDs.
|
||||
/// </summary>
|
||||
/// <param name="device"></param>
|
||||
/// <param name="args"></param>
|
||||
protected virtual void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args)
|
||||
{
|
||||
switch (args.EventId)
|
||||
{
|
||||
case GlsOccupancySensorBase.PirEnabledFeedbackEventId:
|
||||
PirSensorEnabledFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.LedFlashEnabledFeedbackEventId:
|
||||
LedFlashEnabledFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.ShortTimeoutEnabledFeedbackEventId:
|
||||
ShortTimeoutEnabledFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.PirSensitivityInOccupiedStateFeedbackEventId:
|
||||
PirSensitivityInOccupiedStateFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.PirSensitivityInVacantStateFeedbackEventId:
|
||||
PirSensitivityInVacantStateFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args)
|
||||
{
|
||||
Debug.Console(2, this, "GlsOccupancySensorChange EventId: {0}", args.EventId);
|
||||
|
||||
switch (args.EventId)
|
||||
{
|
||||
case Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomVacantFeedbackEventId:
|
||||
case Crestron.SimplSharpPro.GeneralIO.GlsOccupancySensorBase.RoomOccupiedFeedbackEventId:
|
||||
Debug.Console(1, this, "Occupancy State: {0}", OccSensor.OccupancyDetectedFeedback.BoolValue);
|
||||
RoomIsOccupiedFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.TimeoutFeedbackEventId:
|
||||
CurrentTimeoutFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.TimeoutLocalFeedbackEventId:
|
||||
LocalTimoutFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.GraceOccupancyDetectedFeedbackEventId:
|
||||
GraceOccupancyDetectedFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.RawOccupancyFeedbackEventId:
|
||||
RawOccupancyFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.InternalPhotoSensorValueFeedbackEventId:
|
||||
InternalPhotoSensorValue.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.ExternalPhotoSensorValueFeedbackEventId:
|
||||
ExternalPhotoSensorValue.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetTestMode(bool mode)
|
||||
{
|
||||
InTestMode = mode;
|
||||
|
||||
Debug.Console(1, this, "In Mock Mode: '{0}'", InTestMode);
|
||||
}
|
||||
|
||||
public void SetTestOccupiedState(bool state)
|
||||
{
|
||||
if (!InTestMode)
|
||||
Debug.Console(1, "Mock mode not enabled");
|
||||
else
|
||||
{
|
||||
TestRoomIsOccupiedFeedback = state;
|
||||
|
||||
RoomIsOccupiedFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables the PIR sensor
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public void SetPirEnable(bool state)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
OccSensor.EnablePir.BoolValue = state;
|
||||
OccSensor.DisablePir.BoolValue = !state;
|
||||
PropertiesConfig = props;
|
||||
}
|
||||
else
|
||||
{
|
||||
OccSensor.EnablePir.BoolValue = state;
|
||||
OccSensor.DisablePir.BoolValue = !state;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables the LED Flash
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public void SetLedFlashEnable(bool state)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
OccSensor.EnableLedFlash.BoolValue = state;
|
||||
OccSensor.DisableLedFlash.BoolValue = !state;
|
||||
}
|
||||
else
|
||||
{
|
||||
OccSensor.EnableLedFlash.BoolValue = state;
|
||||
OccSensor.DisableLedFlash.BoolValue = !state;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables short timeout based on state
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public void SetShortTimeoutState(bool state)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
OccSensor.EnableShortTimeout.BoolValue = state;
|
||||
OccSensor.DisableShortTimeout.BoolValue = !state;
|
||||
}
|
||||
else
|
||||
{
|
||||
OccSensor.EnableShortTimeout.BoolValue = state;
|
||||
OccSensor.DisableShortTimeout.BoolValue = !state;
|
||||
}
|
||||
}
|
||||
|
||||
public void IncrementPirSensitivityInOccupiedState(bool pressRelease)
|
||||
{
|
||||
OccSensor.IncrementPirSensitivityInOccupiedState.BoolValue = pressRelease;
|
||||
}
|
||||
|
||||
public void DecrementPirSensitivityInOccupiedState(bool pressRelease)
|
||||
{
|
||||
OccSensor.DecrementPirSensitivityInOccupiedState.BoolValue = pressRelease;
|
||||
}
|
||||
|
||||
public void IncrementPirSensitivityInVacantState(bool pressRelease)
|
||||
{
|
||||
OccSensor.IncrementPirSensitivityInVacantState.BoolValue = pressRelease;
|
||||
}
|
||||
|
||||
public void DecrementPirSensitivityInVacantState(bool pressRelease)
|
||||
{
|
||||
OccSensor.DecrementPirSensitivityInVacantState.BoolValue = pressRelease;
|
||||
}
|
||||
|
||||
public void ForceOccupied()
|
||||
{
|
||||
OccSensor.ForceOccupied.BoolValue = true;
|
||||
}
|
||||
|
||||
public void ForceVacant()
|
||||
{
|
||||
OccSensor.ForceVacant.BoolValue = true;
|
||||
}
|
||||
|
||||
public void EnableRawStates(bool state)
|
||||
{
|
||||
OccSensor.EnableRawStates.BoolValue = state;
|
||||
}
|
||||
|
||||
public void SetRemoteTimeout(ushort time)
|
||||
{
|
||||
OccSensor.RemoteTimeout.UShortValue = time;
|
||||
}
|
||||
|
||||
public void SetInternalPhotoSensorMinChange(ushort value)
|
||||
{
|
||||
OccSensor.InternalPhotoSensorMinimumChange.UShortValue = value;
|
||||
}
|
||||
|
||||
public void SetExternalPhotoSensorMinChange(ushort value)
|
||||
{
|
||||
OccSensor.ExternalPhotoSensorMinimumChange.UShortValue = value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected void LinkOccSensorToApi(GlsOccupancySensorBaseController occController, BasicTriList trilist,
|
||||
uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new GlsOccupancySensorBaseJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<GlsOccupancySensorBaseJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
Debug.Console(1, this, "props are null. Unable to deserialize into GlsOccupancySensorPropertiesConfig");
|
||||
}
|
||||
|
||||
Debug.Console(1, occController, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
#region Single and Dual Sensor Stuff
|
||||
occController.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name;
|
||||
|
||||
trilist.OnlineStatusChange += (d, args) =>
|
||||
{
|
||||
if (args.DeviceOnLine)
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name;
|
||||
}
|
||||
};
|
||||
OccSensor.OnlineStatusChange += (o, a) =>
|
||||
{
|
||||
if (a.DeviceOnLine)
|
||||
{
|
||||
ApplySettingsToSensorFromConfig();
|
||||
}
|
||||
};
|
||||
|
||||
// Occupied status
|
||||
trilist.SetSigTrueAction(joinMap.ForceOccupied.JoinNumber, occController.ForceOccupied);
|
||||
trilist.SetSigTrueAction(joinMap.ForceVacant.JoinNumber, occController.ForceVacant);
|
||||
occController.RoomIsOccupiedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RoomOccupiedFeedback.JoinNumber]);
|
||||
occController.RoomIsOccupiedFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.RoomVacantFeedback.JoinNumber]);
|
||||
occController.RawOccupancyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyFeedback.JoinNumber]);
|
||||
trilist.SetBoolSigAction(joinMap.EnableRawStates.JoinNumber, occController.EnableRawStates);
|
||||
if (OccSensor.IsOnline)
|
||||
{
|
||||
ApplySettingsToSensorFromConfig();
|
||||
|
||||
// Timouts
|
||||
trilist.SetUShortSigAction(joinMap.Timeout.JoinNumber, occController.SetRemoteTimeout);
|
||||
occController.CurrentTimeoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.Timeout.JoinNumber]);
|
||||
occController.LocalTimoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeoutLocalFeedback.JoinNumber]);
|
||||
|
||||
// LED Flash
|
||||
trilist.SetSigTrueAction(joinMap.EnableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(true));
|
||||
trilist.SetSigTrueAction(joinMap.DisableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(false));
|
||||
occController.LedFlashEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.EnableLedFlash.JoinNumber]);
|
||||
|
||||
// Short Timeout
|
||||
trilist.SetSigTrueAction(joinMap.EnableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(true));
|
||||
trilist.SetSigTrueAction(joinMap.DisableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(false));
|
||||
occController.ShortTimeoutEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableShortTimeout.JoinNumber]);
|
||||
|
||||
// PIR Sensor
|
||||
trilist.SetSigTrueAction(joinMap.EnablePir.JoinNumber, () => occController.SetPirEnable(true));
|
||||
trilist.SetSigTrueAction(joinMap.DisablePir.JoinNumber, () => occController.SetPirEnable(false));
|
||||
occController.PirSensorEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnablePir.JoinNumber]);
|
||||
|
||||
// PIR Sensitivity in Occupied State
|
||||
trilist.SetBoolSigAction(joinMap.IncrementPirInOccupiedState.JoinNumber, occController.IncrementPirSensitivityInOccupiedState);
|
||||
trilist.SetBoolSigAction(joinMap.DecrementPirInOccupiedState.JoinNumber, occController.DecrementPirSensitivityInOccupiedState);
|
||||
occController.PirSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInOccupiedState.JoinNumber]);
|
||||
|
||||
// PIR Sensitivity in Vacant State
|
||||
trilist.SetBoolSigAction(joinMap.IncrementPirInVacantState.JoinNumber, occController.IncrementPirSensitivityInVacantState);
|
||||
trilist.SetBoolSigAction(joinMap.DecrementPirInVacantState.JoinNumber, occController.DecrementPirSensitivityInVacantState);
|
||||
occController.PirSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.PirSensitivityInVacantState.JoinNumber]);
|
||||
#endregion
|
||||
|
||||
#region Dual Technology Sensor Stuff
|
||||
var odtOccController = occController as GlsOdtOccupancySensorController;
|
||||
|
||||
if (odtOccController == null) return;
|
||||
// OR When Vacated
|
||||
trilist.SetBoolSigAction(joinMap.OrWhenVacated.JoinNumber, odtOccController.SetOrWhenVacatedState);
|
||||
odtOccController.OrWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OrWhenVacated.JoinNumber]);
|
||||
|
||||
// AND When Vacated
|
||||
trilist.SetBoolSigAction(joinMap.AndWhenVacated.JoinNumber, odtOccController.SetAndWhenVacatedState);
|
||||
odtOccController.AndWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AndWhenVacated.JoinNumber]);
|
||||
|
||||
// Ultrasonic A Sensor
|
||||
trilist.SetSigTrueAction(joinMap.EnableUsA.JoinNumber, () => odtOccController.SetUsAEnable(true));
|
||||
trilist.SetSigTrueAction(joinMap.DisableUsA.JoinNumber, () => odtOccController.SetUsAEnable(false));
|
||||
odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsA.JoinNumber]);
|
||||
|
||||
// Ultrasonic B Sensor
|
||||
trilist.SetSigTrueAction(joinMap.EnableUsB.JoinNumber, () => odtOccController.SetUsBEnable(true));
|
||||
trilist.SetSigTrueAction(joinMap.DisableUsB.JoinNumber, () => odtOccController.SetUsBEnable(false));
|
||||
odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsB.JoinNumber]);
|
||||
|
||||
// US Sensitivity in Occupied State
|
||||
trilist.SetBoolSigAction(joinMap.IncrementUsInOccupiedState.JoinNumber, odtOccController.IncrementUsSensitivityInOccupiedState);
|
||||
trilist.SetBoolSigAction(joinMap.DecrementUsInOccupiedState.JoinNumber, odtOccController.DecrementUsSensitivityInOccupiedState);
|
||||
odtOccController.UltrasonicSensitivityInOccupiedStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInOccupiedState.JoinNumber]);
|
||||
|
||||
// US Sensitivity in Vacant State
|
||||
trilist.SetBoolSigAction(joinMap.IncrementUsInVacantState.JoinNumber, odtOccController.IncrementUsSensitivityInVacantState);
|
||||
trilist.SetBoolSigAction(joinMap.DecrementUsInVacantState.JoinNumber, odtOccController.DecrementUsSensitivityInVacantState);
|
||||
odtOccController.UltrasonicSensitivityInVacantStateFeedback.LinkInputSig(trilist.UShortInput[joinMap.UsSensitivityInVacantState.JoinNumber]);
|
||||
|
||||
//Sensor Raw States
|
||||
odtOccController.RawOccupancyPirFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyPirFeedback.JoinNumber]);
|
||||
odtOccController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]);
|
||||
|
||||
#endregion
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
|
||||
/// <summary>
|
||||
/// Applies any sensor settings defined in config
|
||||
/// </summary>
|
||||
protected virtual void ApplySettingsToSensorFromConfig()
|
||||
{
|
||||
LinkOccSensorToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||
Debug.Console(1, this, "Attempting to apply settings to sensor from config");
|
||||
|
||||
if (PropertiesConfig.EnablePir != null)
|
||||
{
|
||||
Debug.Console(1, this, "EnablePir found, attempting to set value from config");
|
||||
SetPirEnable((bool)PropertiesConfig.EnablePir);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "EnablePir null, no value specified in config");
|
||||
}
|
||||
|
||||
if (PropertiesConfig.EnableLedFlash != null)
|
||||
{
|
||||
Debug.Console(1, this, "EnableLedFlash found, attempting to set value from config");
|
||||
SetLedFlashEnable((bool)PropertiesConfig.EnableLedFlash);
|
||||
}
|
||||
|
||||
if (PropertiesConfig.RemoteTimeout != null)
|
||||
{
|
||||
Debug.Console(1, this, "RemoteTimeout found, attempting to set value from config");
|
||||
SetRemoteTimeout((ushort)PropertiesConfig.RemoteTimeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(1, this, "RemoteTimeout null, no value specified in config");
|
||||
}
|
||||
|
||||
if (PropertiesConfig.ShortTimeoutState != null)
|
||||
{
|
||||
SetShortTimeoutState((bool)PropertiesConfig.ShortTimeoutState);
|
||||
}
|
||||
|
||||
if (PropertiesConfig.EnableRawStates != null)
|
||||
{
|
||||
EnableRawStates((bool)PropertiesConfig.EnableRawStates);
|
||||
}
|
||||
|
||||
if (PropertiesConfig.InternalPhotoSensorMinChange != null)
|
||||
{
|
||||
SetInternalPhotoSensorMinChange((ushort)PropertiesConfig.InternalPhotoSensorMinChange);
|
||||
}
|
||||
|
||||
if (PropertiesConfig.ExternalPhotoSensorMinChange != null)
|
||||
{
|
||||
SetExternalPhotoSensorMinChange((ushort)PropertiesConfig.ExternalPhotoSensorMinChange);
|
||||
}
|
||||
}
|
||||
|
||||
#region PreActivation
|
||||
protected void RegisterGlsOccupancySensorBaseController(GlsOccupancySensorBase occSensor)
|
||||
{
|
||||
OccSensor = occSensor;
|
||||
|
||||
private static GlsOirCCn GetGlsOirCCn(DeviceConfig dc)
|
||||
{
|
||||
var control = CommFactory.GetControlPropertiesConfig(dc);
|
||||
var cresnetId = control.CresnetIdInt;
|
||||
var branchId = control.ControlPortNumber;
|
||||
var parentKey = string.IsNullOrEmpty(control.ControlPortDevKey) ? "processor" : control.ControlPortDevKey;
|
||||
RoomIsOccupiedFeedback = new BoolFeedback(RoomIsOccupiedFeedbackFunc);
|
||||
|
||||
if (parentKey.Equals("processor", StringComparison.CurrentCultureIgnoreCase))
|
||||
PirSensorEnabledFeedback = new BoolFeedback(() => OccSensor.PirEnabledFeedback.BoolValue);
|
||||
|
||||
LedFlashEnabledFeedback = new BoolFeedback(() => OccSensor.LedFlashEnabledFeedback.BoolValue);
|
||||
|
||||
ShortTimeoutEnabledFeedback = new BoolFeedback(() => OccSensor.ShortTimeoutEnabledFeedback.BoolValue);
|
||||
|
||||
PirSensitivityInVacantStateFeedback =
|
||||
new IntFeedback(() => OccSensor.PirSensitivityInVacantStateFeedback.UShortValue);
|
||||
|
||||
PirSensitivityInOccupiedStateFeedback =
|
||||
new IntFeedback(() => OccSensor.PirSensitivityInOccupiedStateFeedback.UShortValue);
|
||||
|
||||
CurrentTimeoutFeedback = new IntFeedback(() => OccSensor.CurrentTimeoutFeedback.UShortValue);
|
||||
|
||||
LocalTimoutFeedback = new IntFeedback(() => OccSensor.LocalTimeoutFeedback.UShortValue);
|
||||
|
||||
GraceOccupancyDetectedFeedback =
|
||||
new BoolFeedback(() => OccSensor.GraceOccupancyDetectedFeedback.BoolValue);
|
||||
|
||||
RawOccupancyFeedback = new BoolFeedback(() => OccSensor.RawOccupancyFeedback.BoolValue);
|
||||
|
||||
InternalPhotoSensorValue = new IntFeedback(() => OccSensor.InternalPhotoSensorValueFeedback.UShortValue);
|
||||
|
||||
ExternalPhotoSensorValue = new IntFeedback(() => OccSensor.ExternalPhotoSensorValueFeedback.UShortValue);
|
||||
|
||||
OccSensor.BaseEvent += OccSensor_BaseEvent;
|
||||
|
||||
OccSensor.GlsOccupancySensorChange += OccSensor_GlsOccupancySensorChange;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Catches events for feedbacks on the base class. Any extending wrapper class should call this delegate after it checks for it's own event IDs.
|
||||
/// </summary>
|
||||
/// <param name="device"></param>
|
||||
/// <param name="args"></param>
|
||||
protected virtual void OccSensor_GlsOccupancySensorChange(GlsOccupancySensorBase device, GlsOccupancySensorChangeEventArgs args)
|
||||
{
|
||||
switch (args.EventId)
|
||||
{
|
||||
case GlsOccupancySensorBase.PirEnabledFeedbackEventId:
|
||||
PirSensorEnabledFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.LedFlashEnabledFeedbackEventId:
|
||||
LedFlashEnabledFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.ShortTimeoutEnabledFeedbackEventId:
|
||||
ShortTimeoutEnabledFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.PirSensitivityInOccupiedStateFeedbackEventId:
|
||||
PirSensitivityInOccupiedStateFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.PirSensitivityInVacantStateFeedbackEventId:
|
||||
PirSensitivityInVacantStateFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OccSensor_BaseEvent(Crestron.SimplSharpPro.GenericBase device, Crestron.SimplSharpPro.BaseEventArgs args)
|
||||
{
|
||||
Debug.Console(2, this, "GlsOccupancySensorChange EventId: {0}", args.EventId);
|
||||
|
||||
switch (args.EventId)
|
||||
{
|
||||
case GlsOccupancySensorBase.RoomVacantFeedbackEventId:
|
||||
case GlsOccupancySensorBase.RoomOccupiedFeedbackEventId:
|
||||
Debug.Console(1, this, "Occupancy State: {0}", OccSensor.OccupancyDetectedFeedback.BoolValue);
|
||||
RoomIsOccupiedFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.TimeoutFeedbackEventId:
|
||||
CurrentTimeoutFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.TimeoutLocalFeedbackEventId:
|
||||
LocalTimoutFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.GraceOccupancyDetectedFeedbackEventId:
|
||||
GraceOccupancyDetectedFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.RawOccupancyFeedbackEventId:
|
||||
RawOccupancyFeedback.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.InternalPhotoSensorValueFeedbackEventId:
|
||||
InternalPhotoSensorValue.FireUpdate();
|
||||
break;
|
||||
case GlsOccupancySensorBase.ExternalPhotoSensorValueFeedbackEventId:
|
||||
ExternalPhotoSensorValue.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetTestMode(bool mode)
|
||||
{
|
||||
InTestMode = mode;
|
||||
|
||||
Debug.Console(1, this, "In Mock Mode: '{0}'", InTestMode);
|
||||
}
|
||||
|
||||
public void SetTestOccupiedState(bool state)
|
||||
{
|
||||
if (!InTestMode)
|
||||
Debug.Console(1, "Mock mode not enabled");
|
||||
else
|
||||
{
|
||||
TestRoomIsOccupiedFeedback = state;
|
||||
|
||||
RoomIsOccupiedFeedback.FireUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables the PIR sensor
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public void SetPirEnable(bool state)
|
||||
{
|
||||
Debug.Console(1, this, "Setting EnablePir to: {0}", state);
|
||||
|
||||
OccSensor.EnablePir.BoolValue = state;
|
||||
OccSensor.DisablePir.BoolValue = !state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables the LED Flash
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public void SetLedFlashEnable(bool state)
|
||||
{
|
||||
OccSensor.EnableLedFlash.BoolValue = state;
|
||||
OccSensor.DisableLedFlash.BoolValue = !state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables short timeout based on state
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
public void SetShortTimeoutState(bool state)
|
||||
{
|
||||
OccSensor.EnableShortTimeout.BoolValue = state;
|
||||
OccSensor.DisableShortTimeout.BoolValue = !state;
|
||||
}
|
||||
|
||||
public void IncrementPirSensitivityInOccupiedState(bool pressRelease)
|
||||
{
|
||||
OccSensor.IncrementPirSensitivityInOccupiedState.BoolValue = pressRelease;
|
||||
}
|
||||
|
||||
public void DecrementPirSensitivityInOccupiedState(bool pressRelease)
|
||||
{
|
||||
OccSensor.DecrementPirSensitivityInOccupiedState.BoolValue = pressRelease;
|
||||
}
|
||||
|
||||
public void IncrementPirSensitivityInVacantState(bool pressRelease)
|
||||
{
|
||||
OccSensor.IncrementPirSensitivityInVacantState.BoolValue = pressRelease;
|
||||
}
|
||||
|
||||
public void DecrementPirSensitivityInVacantState(bool pressRelease)
|
||||
{
|
||||
OccSensor.DecrementPirSensitivityInVacantState.BoolValue = pressRelease;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pulse ForceOccupied on the sensor for .5 seconds
|
||||
/// </summary>
|
||||
public void ForceOccupied()
|
||||
{
|
||||
CrestronInvoke.BeginInvoke((o) =>
|
||||
{
|
||||
ForceOccupied(true);
|
||||
CrestronEnvironment.Sleep(500);
|
||||
ForceOccupied(false);
|
||||
});
|
||||
}
|
||||
|
||||
public void ForceOccupied(bool value)
|
||||
{
|
||||
OccSensor.ForceOccupied.BoolValue = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pulse ForceVacant on the sensor for .5 seconds
|
||||
/// </summary>
|
||||
public void ForceVacant()
|
||||
{
|
||||
CrestronInvoke.BeginInvoke((o) =>
|
||||
{
|
||||
Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOirCCn", parentKey);
|
||||
return new GlsOirCCn(cresnetId, Global.ControlSystem);
|
||||
}
|
||||
var cresnetBridge = DeviceManager.GetDeviceForKey(parentKey) as IHasCresnetBranches;
|
||||
ForceVacant(true);
|
||||
CrestronEnvironment.Sleep(500);
|
||||
ForceVacant(false);
|
||||
});
|
||||
}
|
||||
|
||||
if (cresnetBridge != null)
|
||||
{
|
||||
Debug.Console(0, "Device {0} is a valid cresnet master - creating new GlsOirCCn", parentKey);
|
||||
return new GlsOirCCn(cresnetId, cresnetBridge.CresnetBranches[branchId]);
|
||||
}
|
||||
Debug.Console(0, "Device {0} is not a valid cresnet master", parentKey);
|
||||
return null;
|
||||
}
|
||||
#endregion
|
||||
public void ForceVacant(bool value)
|
||||
{
|
||||
OccSensor.ForceVacant.BoolValue = value;
|
||||
}
|
||||
|
||||
public class GlsOccupancySensorBaseControllerFactory : EssentialsDeviceFactory<GlsOccupancySensorBaseController>
|
||||
{
|
||||
public GlsOccupancySensorBaseControllerFactory()
|
||||
{
|
||||
TypeNames = new List<string>() { "glsoirccn" };
|
||||
}
|
||||
public void EnableRawStates(bool state)
|
||||
{
|
||||
OccSensor.EnableRawStates.BoolValue = state;
|
||||
}
|
||||
|
||||
public void SetRemoteTimeout(ushort time)
|
||||
{
|
||||
Debug.Console(1, this, "Setting RemoteTimout to: {0}", time);
|
||||
|
||||
OccSensor.RemoteTimeout.UShortValue = time;
|
||||
}
|
||||
|
||||
public void SetInternalPhotoSensorMinChange(ushort value)
|
||||
{
|
||||
OccSensor.InternalPhotoSensorMinimumChange.UShortValue = value;
|
||||
}
|
||||
|
||||
public void SetExternalPhotoSensorMinChange(ushort value)
|
||||
{
|
||||
OccSensor.ExternalPhotoSensorMinimumChange.UShortValue = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to print current occ settings to console.
|
||||
/// </summary>
|
||||
public virtual void GetSettings()
|
||||
{
|
||||
var dash = new string('*', 50);
|
||||
CrestronConsole.PrintLine(string.Format("{0}\n", dash));
|
||||
|
||||
Debug.Console(0, this, "Vacancy Detected: {0}",
|
||||
OccSensor.VacancyDetectedFeedback.BoolValue);
|
||||
|
||||
Debug.Console(0, this, "Timeout Current: {0} | Local: {1}",
|
||||
OccSensor.CurrentTimeoutFeedback.UShortValue,
|
||||
OccSensor.LocalTimeoutFeedback.UShortValue);
|
||||
|
||||
Debug.Console(0, this, "Short Timeout Enabled: {0}",
|
||||
OccSensor.ShortTimeoutEnabledFeedback.BoolValue);
|
||||
|
||||
Debug.Console(0, this, "PIR Sensor Enabled: {0} | Sensitivity Occupied: {1} | Sensitivity Vacant: {2}",
|
||||
OccSensor.PirEnabledFeedback.BoolValue,
|
||||
OccSensor.PirSensitivityInOccupiedStateFeedback.UShortValue,
|
||||
OccSensor.PirSensitivityInVacantStateFeedback.UShortValue);
|
||||
|
||||
CrestronConsole.PrintLine(string.Format("{0}\n", dash));
|
||||
}
|
||||
|
||||
protected void LinkOccSensorToApi(GlsOccupancySensorBaseController occController, BasicTriList trilist,
|
||||
uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
var joinMap = new GlsOccupancySensorBaseJoinMap(joinStart);
|
||||
|
||||
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(joinMapSerialized))
|
||||
joinMap = JsonConvert.DeserializeObject<GlsOccupancySensorBaseJoinMap>(joinMapSerialized);
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
|
||||
}
|
||||
|
||||
Debug.Console(1, occController, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
|
||||
|
||||
occController.IsOnline.LinkInputSig(trilist.BooleanInput[joinMap.IsOnline.JoinNumber]);
|
||||
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name;
|
||||
|
||||
trilist.OnlineStatusChange += (d, args) =>
|
||||
{
|
||||
if (args.DeviceOnLine)
|
||||
{
|
||||
trilist.StringInput[joinMap.Name.JoinNumber].StringValue = occController.Name;
|
||||
}
|
||||
};
|
||||
|
||||
LinkSingleTechSensorToApi(occController, trilist, joinMap);
|
||||
|
||||
LinkDualTechSensorToApi(occController, trilist, joinMap);
|
||||
}
|
||||
|
||||
private static void LinkDualTechSensorToApi(GlsOccupancySensorBaseController occController, BasicTriList trilist,
|
||||
GlsOccupancySensorBaseJoinMap joinMap)
|
||||
{
|
||||
var odtOccController = occController as GlsOdtOccupancySensorController;
|
||||
|
||||
if (odtOccController == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// OR When Vacated
|
||||
trilist.SetBoolSigAction(joinMap.OrWhenVacated.JoinNumber, odtOccController.SetOrWhenVacatedState);
|
||||
odtOccController.OrWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.OrWhenVacated.JoinNumber]);
|
||||
|
||||
// AND When Vacated
|
||||
trilist.SetBoolSigAction(joinMap.AndWhenVacated.JoinNumber, odtOccController.SetAndWhenVacatedState);
|
||||
odtOccController.AndWhenVacatedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.AndWhenVacated.JoinNumber]);
|
||||
|
||||
// Ultrasonic A Sensor
|
||||
trilist.SetSigTrueAction(joinMap.EnableUsA.JoinNumber, () => odtOccController.SetUsAEnable(true));
|
||||
trilist.SetSigTrueAction(joinMap.DisableUsA.JoinNumber, () => odtOccController.SetUsAEnable(false));
|
||||
odtOccController.UltrasonicAEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsA.JoinNumber]);
|
||||
|
||||
// Ultrasonic B Sensor
|
||||
trilist.SetSigTrueAction(joinMap.EnableUsB.JoinNumber, () => odtOccController.SetUsBEnable(true));
|
||||
trilist.SetSigTrueAction(joinMap.DisableUsB.JoinNumber, () => odtOccController.SetUsBEnable(false));
|
||||
odtOccController.UltrasonicBEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableUsB.JoinNumber]);
|
||||
|
||||
// US Sensitivity in Occupied State
|
||||
trilist.SetBoolSigAction(joinMap.IncrementUsInOccupiedState.JoinNumber,
|
||||
odtOccController.IncrementUsSensitivityInOccupiedState);
|
||||
trilist.SetBoolSigAction(joinMap.DecrementUsInOccupiedState.JoinNumber,
|
||||
odtOccController.DecrementUsSensitivityInOccupiedState);
|
||||
odtOccController.UltrasonicSensitivityInOccupiedStateFeedback.LinkInputSig(
|
||||
trilist.UShortInput[joinMap.UsSensitivityInOccupiedState.JoinNumber]);
|
||||
|
||||
// US Sensitivity in Vacant State
|
||||
trilist.SetBoolSigAction(joinMap.IncrementUsInVacantState.JoinNumber,
|
||||
odtOccController.IncrementUsSensitivityInVacantState);
|
||||
trilist.SetBoolSigAction(joinMap.DecrementUsInVacantState.JoinNumber,
|
||||
odtOccController.DecrementUsSensitivityInVacantState);
|
||||
odtOccController.UltrasonicSensitivityInVacantStateFeedback.LinkInputSig(
|
||||
trilist.UShortInput[joinMap.UsSensitivityInVacantState.JoinNumber]);
|
||||
|
||||
//Sensor Raw States
|
||||
odtOccController.RawOccupancyPirFeedback.LinkInputSig(
|
||||
trilist.BooleanInput[joinMap.RawOccupancyPirFeedback.JoinNumber]);
|
||||
odtOccController.RawOccupancyUsFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyUsFeedback.JoinNumber]);
|
||||
}
|
||||
|
||||
private static void LinkSingleTechSensorToApi(GlsOccupancySensorBaseController occController, BasicTriList trilist,
|
||||
GlsOccupancySensorBaseJoinMap joinMap)
|
||||
{
|
||||
// Occupied status
|
||||
trilist.SetBoolSigAction(joinMap.ForceOccupied.JoinNumber, occController.ForceOccupied);
|
||||
trilist.SetBoolSigAction(joinMap.ForceVacant.JoinNumber, occController.ForceVacant);
|
||||
occController.RoomIsOccupiedFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RoomOccupiedFeedback.JoinNumber]);
|
||||
occController.RoomIsOccupiedFeedback.LinkComplementInputSig(
|
||||
trilist.BooleanInput[joinMap.RoomVacantFeedback.JoinNumber]);
|
||||
occController.RawOccupancyFeedback.LinkInputSig(trilist.BooleanInput[joinMap.RawOccupancyFeedback.JoinNumber]);
|
||||
trilist.SetBoolSigAction(joinMap.EnableRawStates.JoinNumber, occController.EnableRawStates);
|
||||
|
||||
// Timouts
|
||||
trilist.SetUShortSigAction(joinMap.Timeout.JoinNumber, occController.SetRemoteTimeout);
|
||||
occController.CurrentTimeoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.Timeout.JoinNumber]);
|
||||
occController.LocalTimoutFeedback.LinkInputSig(trilist.UShortInput[joinMap.TimeoutLocalFeedback.JoinNumber]);
|
||||
|
||||
// LED Flash
|
||||
trilist.SetSigTrueAction(joinMap.EnableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(true));
|
||||
trilist.SetSigTrueAction(joinMap.DisableLedFlash.JoinNumber, () => occController.SetLedFlashEnable(false));
|
||||
occController.LedFlashEnabledFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.EnableLedFlash.JoinNumber]);
|
||||
|
||||
// Short Timeout
|
||||
trilist.SetSigTrueAction(joinMap.EnableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(true));
|
||||
trilist.SetSigTrueAction(joinMap.DisableShortTimeout.JoinNumber, () => occController.SetShortTimeoutState(false));
|
||||
occController.ShortTimeoutEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnableShortTimeout.JoinNumber]);
|
||||
|
||||
// PIR Sensor
|
||||
trilist.SetSigTrueAction(joinMap.EnablePir.JoinNumber, () => occController.SetPirEnable(true));
|
||||
trilist.SetSigTrueAction(joinMap.DisablePir.JoinNumber, () => occController.SetPirEnable(false));
|
||||
occController.PirSensorEnabledFeedback.LinkInputSig(trilist.BooleanInput[joinMap.EnablePir.JoinNumber]);
|
||||
|
||||
// PIR Sensitivity in Occupied State
|
||||
trilist.SetBoolSigAction(joinMap.IncrementPirInOccupiedState.JoinNumber,
|
||||
occController.IncrementPirSensitivityInOccupiedState);
|
||||
trilist.SetBoolSigAction(joinMap.DecrementPirInOccupiedState.JoinNumber,
|
||||
occController.DecrementPirSensitivityInOccupiedState);
|
||||
occController.PirSensitivityInOccupiedStateFeedback.LinkInputSig(
|
||||
trilist.UShortInput[joinMap.PirSensitivityInOccupiedState.JoinNumber]);
|
||||
|
||||
// PIR Sensitivity in Vacant State
|
||||
trilist.SetBoolSigAction(joinMap.IncrementPirInVacantState.JoinNumber,
|
||||
occController.IncrementPirSensitivityInVacantState);
|
||||
trilist.SetBoolSigAction(joinMap.DecrementPirInVacantState.JoinNumber,
|
||||
occController.DecrementPirSensitivityInVacantState);
|
||||
occController.PirSensitivityInVacantStateFeedback.LinkInputSig(
|
||||
trilist.UShortInput[joinMap.PirSensitivityInVacantState.JoinNumber]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override EssentialsDevice BuildDevice(DeviceConfig dc)
|
||||
{
|
||||
Debug.Console(1, "Factory Attempting to create new GlsOccupancySensorBaseController Device");
|
||||
|
||||
return new GlsOccupancySensorBaseController(dc.Key, GetGlsOirCCn, dc);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace PepperDash.Essentials.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines configuration properties for Crestron GLS series occupancy sensors
|
||||
/// </summary>
|
||||
public class GlsOccupancySensorPropertiesConfig
|
||||
{
|
||||
// Single Technology Sensors (PIR): GlsOccupancySensorBase
|
||||
[JsonProperty("enablePir")]
|
||||
public bool? EnablePir { get; set; }
|
||||
|
||||
[JsonProperty("enableLedFlash")]
|
||||
public bool? EnableLedFlash { get; set; }
|
||||
|
||||
[JsonProperty("shortTimeoutState")]
|
||||
public bool? ShortTimeoutState { get; set; }
|
||||
|
||||
[JsonProperty("enableRawStates")]
|
||||
public bool? EnableRawStates { get; set; }
|
||||
|
||||
[JsonProperty("remoteTimeout")]
|
||||
public ushort? RemoteTimeout { get; set; }
|
||||
|
||||
[JsonProperty("internalPhotoSensorMinChange")]
|
||||
public ushort? InternalPhotoSensorMinChange { get; set; }
|
||||
|
||||
[JsonProperty("externalPhotoSensorMinChange")]
|
||||
public ushort? ExternalPhotoSensorMinChange { get; set; }
|
||||
|
||||
// Dual Technology Sensors: GlsOdtCCn
|
||||
[JsonProperty("enableUsA")]
|
||||
public bool? EnableUsA { get; set; }
|
||||
|
||||
[JsonProperty("enableUsB")]
|
||||
public bool? EnableUsB { get; set; }
|
||||
|
||||
[JsonProperty("orWhenVacatedState")]
|
||||
public bool? OrWhenVacatedState { get; set; }
|
||||
|
||||
[JsonProperty("andWhenVacatedState")]
|
||||
public bool? AndWhenVacatedState { get; set; }
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user