Compare commits
965 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
653efb41a2 | ||
|
|
571ba2f350 | ||
|
|
220cfbf7ae | ||
|
|
db130f646e | ||
|
|
5510c9ff57 | ||
|
|
ebf4e921ee | ||
|
|
d068542c94 | ||
|
|
19fa310f43 | ||
|
|
87772cb76b | ||
|
|
50207a42bf | ||
|
|
a0e6942537 | ||
|
|
c37397acca | ||
|
|
498afe377b | ||
|
|
d43ac7fb92 | ||
|
|
11105944be | ||
|
|
c7fa4ff212 | ||
|
|
96ba58af8c | ||
|
|
d485d1b820 | ||
|
|
8f60a3a12a | ||
|
|
940027ab19 | ||
|
|
24b3f27364 | ||
|
|
5265c6281f | ||
|
|
8acae28c59 | ||
|
|
0061d5e159 | ||
|
|
5d14454185 | ||
|
|
58382be16c | ||
|
|
2edec642fb | ||
|
|
726a08ec2c | ||
|
|
d775ee9e89 | ||
|
|
1c1fcbea51 | ||
|
|
bf89fd7558 | ||
|
|
8247070aae | ||
|
|
241ee1e99d | ||
|
|
a75543c309 | ||
|
|
1c5a3cf6fe | ||
|
|
b2dcac549c | ||
|
|
37b173071e | ||
|
|
041ae7bae7 | ||
|
|
680863fb00 | ||
|
|
8297591853 | ||
|
|
cc3290be8e | ||
|
|
9bfded055a | ||
|
|
2b07e3c2c8 | ||
|
|
eac2e2fb39 | ||
|
|
d843ac6422 | ||
|
|
33a9b7454c | ||
|
|
3dc70ab40a | ||
|
|
ecb5e9cc32 | ||
|
|
9a53d6e209 | ||
|
|
63405a712c | ||
|
|
69c67f96e7 | ||
|
|
d088021902 | ||
|
|
74e3947cb2 | ||
|
|
ca060e406e | ||
|
|
53b496fd00 | ||
|
|
ab60875142 | ||
|
|
3948adf460 | ||
|
|
3c56ec3738 | ||
|
|
661ea6c022 | ||
|
|
3fa864ce52 | ||
|
|
71f312d830 | ||
|
|
f1c095e41d | ||
|
|
bac7179f73 | ||
|
|
9f315207d4 | ||
|
|
08f4d623c7 | ||
|
|
f85297d52f | ||
|
|
e724fb8375 | ||
|
|
54b4a2e9e8 | ||
|
|
94cecc23f5 | ||
|
|
866b539757 | ||
|
|
9132a88963 | ||
|
|
eecd7f7c28 | ||
|
|
ba304b2871 | ||
|
|
0832d3e18c | ||
|
|
3c188f2f9f | ||
|
|
68d2f7bf29 | ||
|
|
ad73fd8abd | ||
|
|
e6a994fd7a | ||
|
|
d324a5c83f | ||
|
|
0aba1595df | ||
|
|
376912d821 | ||
|
|
d3eabc3311 | ||
|
|
d06ea51c7a | ||
|
|
c750defc5f | ||
|
|
130d90ce04 | ||
|
|
55c98ef880 | ||
|
|
6c903abda1 | ||
|
|
28788070b2 | ||
|
|
0fc1ffc4d3 | ||
|
|
8019eaf182 | ||
|
|
225cab676a | ||
|
|
4594bcb23e | ||
|
|
b21e8f8c80 | ||
|
|
8566b08723 | ||
|
|
8452a8d110 | ||
|
|
70f301941b | ||
|
|
d259042542 | ||
|
|
6113e0737b | ||
|
|
b1edb13b3c | ||
|
|
2a21e53422 | ||
|
|
521fce35e4 | ||
|
|
2e23c7e0ae | ||
|
|
68c87c9217 | ||
|
|
4a247f5e94 | ||
|
|
05006e0642 | ||
|
|
d9a8461a2e | ||
|
|
c3d3d947d7 | ||
|
|
e29b86e4dc | ||
|
|
8257eb7aa2 | ||
|
|
1e857b79c1 | ||
|
|
16901482d9 | ||
|
|
aa9f36ee8f | ||
|
|
cf1693e1a0 | ||
|
|
e5cf12cebd | ||
|
|
bcf4b70dc9 | ||
|
|
dc5eb96f50 | ||
|
|
507e86d3b6 | ||
|
|
1900d78122 | ||
|
|
b2522961cd | ||
|
|
499f872641 | ||
|
|
fcf401d20a | ||
|
|
0468ccc34a | ||
|
|
f8ad1acca9 | ||
|
|
36f0ed9ff8 | ||
|
|
ecef32a58e | ||
|
|
9ee947e9b0 | ||
|
|
e533320d92 | ||
|
|
4e293d4b93 | ||
|
|
096a1ba3a0 | ||
|
|
6297ae3428 | ||
|
|
e3b66f7ffe | ||
|
|
da9fb13079 | ||
|
|
b7f830f64e | ||
|
|
90ea73b2ba | ||
|
|
eaa2f07cf3 | ||
|
|
b5ca2cfd21 | ||
|
|
2659204d96 | ||
|
|
6d048ae01d | ||
|
|
d3d96b51ce | ||
|
|
4cd5d79c73 | ||
|
|
2c10e2510b | ||
|
|
8f4b89a193 | ||
|
|
7dac96810f | ||
|
|
10b97fabb4 | ||
|
|
d5abdc6d74 | ||
|
|
edfe06e31e | ||
|
|
d0b2b972e2 | ||
|
|
0c2b6f1a61 | ||
|
|
68793001a2 | ||
|
|
5040636aa2 | ||
|
|
9df3e30bb2 | ||
|
|
38b5807ef7 | ||
|
|
2234ac9703 | ||
|
|
99a37fe01c | ||
|
|
aa5087cc8a | ||
|
|
d5d1a9982f | ||
|
|
ebb225f6c0 | ||
|
|
3a7295c341 | ||
|
|
69d2727106 | ||
|
|
cafdb305a3 | ||
|
|
b05975b97c | ||
|
|
251bb7bd89 | ||
|
|
6f9ded5f20 | ||
|
|
b206cee820 | ||
|
|
759f899620 | ||
|
|
d758a347eb | ||
|
|
0fcf6061c1 | ||
|
|
8b05bd22b5 | ||
|
|
b85e0ab574 | ||
|
|
b43383007a | ||
|
|
d770566aec | ||
|
|
12b9542f72 | ||
|
|
a18e298cdd | ||
|
|
7746d01fc0 | ||
|
|
326525c961 | ||
|
|
355900743d | ||
|
|
818fdc42c9 | ||
|
|
595b153bbf | ||
|
|
cc7145361e | ||
|
|
8db267b21a | ||
|
|
8e26ef4e2e | ||
|
|
67cae68e83 | ||
|
|
468cbad4f3 | ||
|
|
d69a43373e | ||
|
|
155735c828 | ||
|
|
0847f021f1 | ||
|
|
9b565596d5 | ||
|
|
31cf756a7e | ||
|
|
36da830f96 | ||
|
|
5457db269c | ||
|
|
ece4520687 | ||
|
|
1a583e765d | ||
|
|
4364daf54c | ||
|
|
9b9c1e29f1 | ||
|
|
851190dbcc | ||
|
|
992e174bb2 | ||
|
|
ec47e8978f | ||
|
|
a02ad8b52c | ||
|
|
d3903d8602 | ||
|
|
2230850201 | ||
|
|
bb4be0bbf7 | ||
|
|
2fb026074a | ||
|
|
01e43777d2 | ||
|
|
2213ad7bce | ||
|
|
9a318d5170 | ||
|
|
c699f1b487 | ||
|
|
ac5a960581 | ||
|
|
239a77198d | ||
|
|
e5ca0ab784 | ||
|
|
f46a5017c7 | ||
|
|
27910042ea | ||
|
|
d899ea7364 | ||
|
|
7aca72b8fd | ||
|
|
483c10785b | ||
|
|
a7100f238b | ||
|
|
57c5b8c97e | ||
|
|
1c3e7de390 | ||
|
|
96e83f3d37 | ||
|
|
8e68632ed9 | ||
|
|
8de1f7e70f | ||
|
|
bef81eed45 | ||
|
|
181802a76b | ||
|
|
0c012bf62a | ||
|
|
93b6e5a885 | ||
|
|
d6a5fef4e7 | ||
|
|
00584a0787 | ||
|
|
e29ac4f171 | ||
|
|
e37baedddb | ||
|
|
e785904fca | ||
|
|
5c460e26c9 | ||
|
|
a3bd6dd7fb | ||
|
|
c4efda2e0c | ||
|
|
a54b19bf5b | ||
|
|
1115418ce1 | ||
|
|
84e5c0821c | ||
|
|
0c5e702a28 | ||
|
|
a1fddb4ac1 | ||
|
|
fdcbf9de95 | ||
|
|
175e5752fe | ||
|
|
98f4aedbfb | ||
|
|
2f41f43d49 | ||
|
|
3b3e6995c2 | ||
|
|
34e1c43ca7 | ||
|
|
43394bc1bc | ||
|
|
a204263fb2 | ||
|
|
0fec55a659 | ||
|
|
e9b5f3eac7 | ||
|
|
0b59a662df | ||
|
|
304b898ddc | ||
|
|
1fd09d527a | ||
|
|
bd22f00539 | ||
|
|
2f77b9e500 | ||
|
|
ee3b62d671 | ||
|
|
00626b63f7 | ||
|
|
e8b1e7a71c | ||
|
|
d3d92e90e0 | ||
|
|
3e3cf3cd64 | ||
|
|
c2e50a9594 | ||
|
|
5a1d4946fb | ||
|
|
a949776966 | ||
|
|
ac5b6f3097 | ||
|
|
e00d831103 | ||
|
|
8529cb0fca | ||
|
|
7b60c92db9 | ||
|
|
b52cd31309 | ||
|
|
1f3af949a0 | ||
|
|
e4260d3370 | ||
|
|
0cc55f3b87 | ||
|
|
0bb3fc8b94 | ||
|
|
e279cf5cec | ||
|
|
cdaf10a92a | ||
|
|
e85001b2d2 | ||
|
|
eef0335d37 | ||
|
|
931eafff18 | ||
|
|
7627db6c39 | ||
|
|
1984eeeca3 | ||
|
|
03137e15dd | ||
|
|
a17aa031dd | ||
|
|
70dacb5ea6 | ||
|
|
7e52003830 | ||
|
|
342642ec01 | ||
|
|
d8316db20f | ||
|
|
b4e4e3b04d | ||
|
|
45b7f45734 | ||
|
|
4fd0cabe29 | ||
|
|
d09be3a384 | ||
|
|
5ee411fcc6 | ||
|
|
1d92d9ed08 | ||
|
|
1eab3ae773 | ||
|
|
fc1267fe55 | ||
|
|
faed3056dd | ||
|
|
e541a885f5 | ||
|
|
4640ddfba0 | ||
|
|
a667042977 | ||
|
|
ba95f99e03 | ||
|
|
e4bbf55ea5 | ||
|
|
b9b2a19ac5 | ||
|
|
ca4c45fcf2 | ||
|
|
3d66b318ec | ||
|
|
c144b68306 | ||
|
|
119b7b18e6 | ||
|
|
417df65b92 | ||
|
|
a2b568923c | ||
|
|
b5398a4297 | ||
|
|
c960602c62 | ||
|
|
8ef28e27b4 | ||
|
|
d940932d3c | ||
|
|
b2515753c1 | ||
|
|
b1a8f04617 | ||
|
|
ea54397cfc | ||
|
|
7548fceb48 | ||
|
|
cffa7a2b2c | ||
|
|
b27a476507 | ||
|
|
35aa835891 | ||
|
|
8e8c463849 | ||
|
|
6e607f7f67 | ||
|
|
3a4f70dc75 | ||
|
|
5af7e67de7 | ||
|
|
4fea9d81a8 | ||
|
|
72492c267f | ||
|
|
33bfde34b2 | ||
|
|
ea4e7b77f5 | ||
|
|
df80953b5e | ||
|
|
6ce474053e | ||
|
|
e211dd5be2 | ||
|
|
5761e9facf | ||
|
|
24983acf17 | ||
|
|
4972892d9a | ||
|
|
49c2a51980 | ||
|
|
918c3449da | ||
|
|
90711ddd76 | ||
|
|
6d6d62bb77 | ||
|
|
6a7bed0ecf | ||
|
|
6358b1ebee | ||
|
|
a11cc82782 | ||
|
|
1f1227fa10 | ||
|
|
d3b134fe90 | ||
|
|
f6e048b064 | ||
|
|
7d2fb3490e | ||
|
|
d5a24906fa | ||
|
|
c08969b782 | ||
|
|
2cde219317 | ||
|
|
69e257dc8e | ||
|
|
783a7b3868 | ||
|
|
b704126453 | ||
|
|
4623839425 | ||
|
|
5a93a7e4b9 | ||
|
|
5ab4b6d38e | ||
|
|
29403013f5 | ||
|
|
f8cc171e4a | ||
|
|
21cadabd5d | ||
|
|
c36369a83b | ||
|
|
97800434c4 | ||
|
|
d0981934b0 | ||
|
|
68b1a9ee08 | ||
|
|
011f00e5de | ||
|
|
de156ef10a | ||
|
|
b58d08683e | ||
|
|
bf49410f6d | ||
|
|
153293e1c7 | ||
|
|
ea28903761 | ||
|
|
980e847ccb | ||
|
|
2e3125fe8d | ||
|
|
e7a9c96b72 | ||
|
|
aa10c2c5e1 | ||
|
|
b55ca53d1d | ||
|
|
d2d775d687 | ||
|
|
718690030e | ||
|
|
8add226a7c | ||
|
|
58efd9e954 | ||
|
|
6940418955 | ||
|
|
12588655df | ||
|
|
bdff1e1ac3 | ||
|
|
f0a8cabc2c | ||
|
|
1888054627 | ||
|
|
6f3b8fb8e1 | ||
|
|
eff8d52014 | ||
|
|
3b05f447d5 | ||
|
|
326cb15a76 | ||
|
|
bf4d128e49 | ||
|
|
3125f16d99 | ||
|
|
ed326763b7 | ||
|
|
f66b4fa5f1 | ||
|
|
7c60c37f49 | ||
|
|
77b38dff2b | ||
|
|
dc04a63f7c | ||
|
|
cab38d3c84 | ||
|
|
3138e28cdf | ||
|
|
a0d0aec677 | ||
|
|
0b7258d50e | ||
|
|
33bf2117c6 | ||
|
|
437f572c39 | ||
|
|
bd8d93bf92 | ||
|
|
9634c93a3c | ||
|
|
57a997baac | ||
|
|
103207cead | ||
|
|
2526d3dad6 | ||
|
|
f995287a6e | ||
|
|
10cd2e4201 | ||
|
|
b8c1168687 | ||
|
|
3c2b35016a | ||
|
|
021d9b5f44 | ||
|
|
50abcd1061 | ||
|
|
9b7df71da0 | ||
|
|
f80d03210b | ||
|
|
43c3c8d30c | ||
|
|
380879e077 | ||
|
|
bfc604db88 | ||
|
|
06e3498027 | ||
|
|
dfe82ff17e | ||
|
|
03758ad35a | ||
|
|
a1cd1617e4 | ||
|
|
c24a4ea41d | ||
|
|
79e5c642eb | ||
|
|
c4702915a7 | ||
|
|
d22c783a6d | ||
|
|
e8b4e25452 | ||
|
|
c97de9b690 | ||
|
|
d26333dd76 | ||
|
|
1d2055cc89 | ||
|
|
1973cb986c | ||
|
|
d635a9babd | ||
|
|
6036d8efea | ||
|
|
5f51c80022 | ||
|
|
25a66a1722 | ||
|
|
b9bf454237 | ||
|
|
5419135abf | ||
|
|
0fe942adce | ||
|
|
ac91a50ffe | ||
|
|
3cf8fea8e0 | ||
|
|
8e01a275af | ||
|
|
86b9625254 | ||
|
|
0ab5785b7d | ||
|
|
7e2064e264 | ||
|
|
e81a280b87 | ||
|
|
abb37242e8 | ||
|
|
1b637f0870 | ||
|
|
e1564780d6 | ||
|
|
f0b5542c2d | ||
|
|
c27ecc3620 | ||
|
|
557c5d645e | ||
|
|
48a722f826 | ||
|
|
a848275bb9 | ||
|
|
5d7512e026 | ||
|
|
dfed23261a | ||
|
|
e752c433af | ||
|
|
97f006d867 | ||
|
|
2716f4c5df | ||
|
|
21ec72f4c0 | ||
|
|
59022347eb | ||
|
|
2c4952b196 | ||
|
|
ac2e963799 | ||
|
|
c04407f740 | ||
|
|
fe9ac6a2fd | ||
|
|
f0061b976d | ||
|
|
4e669d8932 | ||
|
|
7aece2e143 | ||
|
|
a5cc0a424f | ||
|
|
d99de94c00 | ||
|
|
3f135e8349 | ||
|
|
178525a49b | ||
|
|
4cfb1b1c26 | ||
|
|
4f2fbaaf2a | ||
|
|
8a80289474 | ||
|
|
16fbad92ac | ||
|
|
7bc1a17fac | ||
|
|
251d197fb6 | ||
|
|
e66060e769 | ||
|
|
dcc157261e | ||
|
|
9428eecce4 | ||
|
|
a06d21024c | ||
|
|
6b31a4d470 | ||
|
|
5d63f64411 | ||
|
|
0584eadcf2 | ||
|
|
f7119bc3c7 | ||
|
|
bdfdc3913b | ||
|
|
149444decb | ||
|
|
ce978cb0f5 | ||
|
|
199351c703 | ||
|
|
a7479d33e3 | ||
|
|
41f3955429 | ||
|
|
bfeb852e23 | ||
|
|
72a2c58f1e | ||
|
|
caaa7b6347 | ||
|
|
f26e824247 | ||
|
|
6233ad12ae | ||
|
|
47417276a0 | ||
|
|
9093f9de79 | ||
|
|
a1f2c93cf6 | ||
|
|
18485ffefd | ||
|
|
c20caf8097 | ||
|
|
188c4688ab | ||
|
|
6b44694a12 | ||
|
|
16cd1a90d5 | ||
|
|
58f0121c11 | ||
|
|
abc53f4257 | ||
|
|
2c92750100 | ||
|
|
ee78698e37 | ||
|
|
ce2109ab1b | ||
|
|
638f52a8da | ||
|
|
f013698471 | ||
|
|
6166ecdb7d | ||
|
|
637d4f06a3 | ||
|
|
265a44c517 | ||
|
|
9d8e195ce1 | ||
|
|
6556268056 | ||
|
|
2608080708 | ||
|
|
024ee26705 | ||
|
|
7b5d31efca | ||
|
|
69cf63ed5e | ||
|
|
22e2d1bb54 | ||
|
|
3c37b61f44 | ||
|
|
b0b9764a23 | ||
|
|
ef9f0040e8 | ||
|
|
ca18d2c841 | ||
|
|
4053e31a5e | ||
|
|
c1fc907ecb | ||
|
|
cbbe053cd5 | ||
|
|
d62234ac65 | ||
|
|
892230b153 | ||
|
|
5285ddb954 | ||
|
|
6e49451935 | ||
|
|
1ebd5620de | ||
|
|
798a6b74e9 | ||
|
|
8aa3fd0412 | ||
|
|
aa8068370e | ||
|
|
03060e453c | ||
|
|
21936a8e1a | ||
|
|
4182e3a071 | ||
|
|
92504875bf | ||
|
|
32fff131c8 | ||
|
|
34983471de | ||
|
|
5b39c1803e | ||
|
|
9dd24c9f87 | ||
|
|
1732d2c620 | ||
|
|
06b8fb65a1 | ||
|
|
2259b1b525 | ||
|
|
ac427523b5 | ||
|
|
733a566172 | ||
|
|
c1f0b9ea6f | ||
|
|
6f09011961 | ||
|
|
25294a190a | ||
|
|
0ddc7fd28d | ||
|
|
3b923885de | ||
|
|
48a02e522f | ||
|
|
0704c9682f | ||
|
|
e9b113486b | ||
|
|
677d822a3e | ||
|
|
5adabd32f5 | ||
|
|
00e856701f | ||
|
|
8b551491a9 | ||
|
|
8798ca5a13 | ||
|
|
fbc39ef742 | ||
|
|
4cae93964d | ||
|
|
3288b974c1 | ||
|
|
84248ec9b6 | ||
|
|
e0cc1559d0 | ||
|
|
eac479430a | ||
|
|
e08570058c | ||
|
|
382abeecd3 | ||
|
|
00fb6445b9 | ||
|
|
ac10700427 | ||
|
|
ab260dde0a | ||
|
|
7950f92d8b | ||
|
|
b4ead9d6ec | ||
|
|
1d9c91c0fb | ||
|
|
14f6669314 | ||
|
|
4d266a930a | ||
|
|
4f7597eaa1 | ||
|
|
66530638de | ||
|
|
e95afbf2cc | ||
|
|
8fb43fedf8 | ||
|
|
d6494fa791 | ||
|
|
a0c47e97fb | ||
|
|
5e45006831 | ||
|
|
47e905bcfc | ||
|
|
ab4a872daa | ||
|
|
efe0b6b383 | ||
|
|
8b806e46c1 | ||
|
|
a82e98d176 | ||
|
|
06651f365a | ||
|
|
f851acab4d | ||
|
|
0737cb0cb3 | ||
|
|
00bc631e87 | ||
|
|
c9508d2660 | ||
|
|
b937532505 | ||
|
|
8b5d406a4f | ||
|
|
e0c07b9bcf | ||
|
|
e9a55cf361 | ||
|
|
c0a185394c | ||
|
|
08d45f2751 | ||
|
|
9ae791edd4 | ||
|
|
3b6e9343d4 | ||
|
|
d0397c821f | ||
|
|
8cf31729df | ||
|
|
bcc647fd51 | ||
|
|
3dc91449aa | ||
|
|
0fd4c603d5 | ||
|
|
f8f79c816a | ||
|
|
0db5b2eb9a | ||
|
|
134fefa30e | ||
|
|
80d534e045 | ||
|
|
ab8679e7b9 | ||
|
|
ad1f1b690c | ||
|
|
77779a1ed9 | ||
|
|
1501411037 | ||
|
|
7881d955bd | ||
|
|
524483451f | ||
|
|
5c501f879f | ||
|
|
48a27fbfad | ||
|
|
98c30d1042 | ||
|
|
c045b5df48 | ||
|
|
12031ed09e | ||
|
|
a7c9c2df1a | ||
|
|
94170545ed | ||
|
|
dff6da9a5f | ||
|
|
b158a5682e | ||
|
|
203e871c4a | ||
|
|
1de3b48166 | ||
|
|
7538b4363c | ||
|
|
ee4811bbe7 | ||
|
|
b85c53f476 | ||
|
|
6bafd734d7 | ||
|
|
d3f95000e2 | ||
|
|
859b902ef9 | ||
|
|
614c0a0990 | ||
|
|
6f685a4ab5 | ||
|
|
527c2eaf4a | ||
|
|
352fec539a | ||
|
|
22da8ff4c7 | ||
|
|
ac0655ea64 | ||
|
|
aea2afad29 | ||
|
|
07e2c5998b | ||
|
|
3d837bdd29 | ||
|
|
7b9ddb5033 | ||
|
|
bd26d09564 | ||
|
|
fa7641f715 | ||
|
|
71d1b3b846 | ||
|
|
17e92fc5eb | ||
|
|
2ae8ed5e18 | ||
|
|
0a4945ae39 | ||
|
|
89b4b8ea85 | ||
|
|
7c875187a8 | ||
|
|
a068eb2586 | ||
|
|
aba57e687a | ||
|
|
6a64fe6e1a | ||
|
|
7e7d372338 | ||
|
|
b477db7045 | ||
|
|
11d7b78d80 | ||
|
|
97d481fa65 | ||
|
|
c25e93eb09 | ||
|
|
f1a8c2ea82 | ||
|
|
dc5b5e837f | ||
|
|
2991af79f2 | ||
|
|
f203a971b0 | ||
|
|
76dfaa7d3b | ||
|
|
0037e5969e | ||
|
|
d373702d7b | ||
|
|
be88da7b26 | ||
|
|
7f99095fca | ||
|
|
943dfc2dbf | ||
|
|
4d61b20f39 | ||
|
|
253b50f765 | ||
|
|
ea6a7f1a88 | ||
|
|
32d91379fa | ||
|
|
d4345917da | ||
|
|
f8cba5721e | ||
|
|
d419fd4794 | ||
|
|
64bfb63ba8 | ||
|
|
59ceac650b | ||
|
|
35da310420 | ||
|
|
1cf41426de | ||
|
|
21fb10f7f2 | ||
|
|
0533c0bcc8 | ||
|
|
4ce0c21eb1 | ||
|
|
3b61c3e1ab | ||
|
|
a974e217df | ||
|
|
a0f9d22395 | ||
|
|
555b6c6750 | ||
|
|
55e98bc068 | ||
|
|
3a3adb4723 | ||
|
|
8023b6620a | ||
|
|
0260af9ada | ||
|
|
9ac6dd6e8d | ||
|
|
1acefd8b8c | ||
|
|
ec9af886d5 | ||
|
|
23dd248073 | ||
|
|
c46f85db9c | ||
|
|
1df8285833 | ||
|
|
7d90937d0f | ||
|
|
abf95634db | ||
|
|
55afa81cf1 | ||
|
|
986d67a3d0 | ||
|
|
6127fbe940 | ||
|
|
4f85d5286d | ||
|
|
9dec05def8 | ||
|
|
b34b22c658 | ||
|
|
2c41be106e | ||
|
|
c5f9f460cd | ||
|
|
b95236c170 | ||
|
|
72e3001d43 | ||
|
|
094fadb2ee | ||
|
|
34b3dad252 | ||
|
|
3f1b6be857 | ||
|
|
8bf6935693 | ||
|
|
701c490654 | ||
|
|
c91bd42a77 | ||
|
|
77a90095d9 | ||
|
|
b88030f76e | ||
|
|
1e26e87bc2 | ||
|
|
08ca221410 | ||
|
|
e2594ac843 | ||
|
|
6429d64062 | ||
|
|
4bf9083b23 | ||
|
|
b025c079c5 | ||
|
|
0c5aef8599 | ||
|
|
6eb3c63288 | ||
|
|
4bf094c3ef | ||
|
|
871dc051d7 | ||
|
|
629ede3cbd | ||
|
|
94f6078c9e | ||
|
|
452679e90b | ||
|
|
b71106c9ef | ||
|
|
ac4ddbe23d | ||
|
|
3d67d934c1 | ||
|
|
9179b672f5 | ||
|
|
188a6cf39d | ||
|
|
22d9b128b9 | ||
|
|
f3e3ec0685 | ||
|
|
43cba67531 | ||
|
|
10ba10d792 | ||
|
|
0bdee6ec99 | ||
|
|
832df5a80e | ||
|
|
be09c4052f | ||
|
|
686112e4ee | ||
|
|
77528f6e6a | ||
|
|
ba9bddf277 | ||
|
|
5bbc67bc49 | ||
|
|
2eeb7423bf | ||
|
|
c374a83cfe | ||
|
|
a90073cba2 | ||
|
|
ef65094181 | ||
|
|
74169c3b17 | ||
|
|
698ecbcd53 | ||
|
|
14305a9f12 | ||
|
|
9821c1905b | ||
|
|
92c9544bb3 | ||
|
|
1146e15ea6 | ||
|
|
8bfa7e530c | ||
|
|
2e25fdcf8f | ||
|
|
a68c553d27 | ||
|
|
658a42db80 | ||
|
|
a06a56a490 | ||
|
|
736220c80d | ||
|
|
0d5b938328 | ||
|
|
cc0af372ef | ||
|
|
eaacce7483 | ||
|
|
972dea297b | ||
|
|
bf4dc56cb8 | ||
|
|
9dbeec3a31 | ||
|
|
3b02ffe7a8 | ||
|
|
cf91839838 | ||
|
|
0d07b1aa4a | ||
|
|
56e2b462fb | ||
|
|
b8c75b02a0 | ||
|
|
1871a9a692 | ||
|
|
99b316587e | ||
|
|
fe3d6588bc | ||
|
|
0ffbba0cf5 | ||
|
|
9b0d2ff25f | ||
|
|
82038d3e2d | ||
|
|
4ae6a2b4ef | ||
|
|
a510afe53e | ||
|
|
69aa247470 | ||
|
|
12a18fb34b | ||
|
|
6955233371 | ||
|
|
d8a3a75c0b | ||
|
|
3df65b3d37 | ||
|
|
93057fc3dc | ||
|
|
582867cdb9 | ||
|
|
37b3b5abb9 | ||
|
|
e0b054d2b5 | ||
|
|
7656735103 | ||
|
|
e8fee49dc8 | ||
|
|
30fbd98274 | ||
|
|
915b084af5 | ||
|
|
184c659197 | ||
|
|
0a56dc2ae1 | ||
|
|
64c96c34f4 | ||
|
|
3562e85b5e | ||
|
|
ee4b479b7d | ||
|
|
88de38e694 | ||
|
|
08f47c2f4c | ||
|
|
170978c6f8 | ||
|
|
c8fc123e81 | ||
|
|
abfc2735ba | ||
|
|
9ac1bb3409 | ||
|
|
b8745f6199 | ||
|
|
78135fb62e | ||
|
|
c1f64396d8 | ||
|
|
abef455249 | ||
|
|
2ccc4a766e | ||
|
|
88cb59d177 | ||
|
|
b3e41c957b | ||
|
|
91d3cd1da2 | ||
|
|
721f82a17c | ||
|
|
593a33020f | ||
|
|
3b6c529efb | ||
|
|
82b0272ceb | ||
|
|
c5a31de5a8 | ||
|
|
7f267ff2fb | ||
|
|
5558dffa70 | ||
|
|
114ebb247a | ||
|
|
5a37948ca9 | ||
|
|
aa4868cd9c | ||
|
|
ac201ba689 | ||
|
|
249436a303 | ||
|
|
24f063dd7b | ||
|
|
bd891f9a6d | ||
|
|
a4cf16bb0b | ||
|
|
853ac3560b | ||
|
|
1c8bd8091b | ||
|
|
e0027d951b | ||
|
|
08b44fb2ba | ||
|
|
5fea7ee066 | ||
|
|
8f2a2b40b1 | ||
|
|
e7198073af | ||
|
|
889e191589 | ||
|
|
a66a3fc44e | ||
|
|
fe90c863bf | ||
|
|
752362d2df | ||
|
|
4e11d653a3 | ||
|
|
456a433cd5 | ||
|
|
450fa4dbe9 | ||
|
|
40820c07f2 | ||
|
|
cd98941c5d | ||
|
|
56fe72d900 | ||
|
|
3596c79d3b | ||
|
|
295eeba556 | ||
|
|
29e9da9126 | ||
|
|
aa6812ccd9 | ||
|
|
7be5dd865a | ||
|
|
efcbd81927 | ||
|
|
99ab78d544 | ||
|
|
74abc1ec1d | ||
|
|
71c937c3cb | ||
|
|
65b728eebb | ||
|
|
7c80fe2bf9 | ||
|
|
09f8a633d7 | ||
|
|
834b938185 | ||
|
|
90a0cb60c6 | ||
|
|
ae321d633a | ||
|
|
357d9edbd8 | ||
|
|
a56d5adb77 | ||
|
|
b086c6ace6 | ||
|
|
a37b394139 | ||
|
|
14f9d1b3c6 | ||
|
|
d361619ade | ||
|
|
72231bca5e | ||
|
|
4e51914a04 | ||
|
|
6a74663af4 | ||
|
|
a7911dab64 | ||
|
|
35f307d745 | ||
|
|
0a36ae3c1c | ||
|
|
41405d5fa1 | ||
|
|
58214ccbea | ||
|
|
3504884836 | ||
|
|
210a186c0c | ||
|
|
e88517df07 | ||
|
|
5b2e3ca05a | ||
|
|
92a4e25230 | ||
|
|
0441bbbe72 | ||
|
|
5996fb0edf | ||
|
|
6a4ad0446d | ||
|
|
bf648a586f | ||
|
|
98da2b64e2 | ||
|
|
270a7f4933 | ||
|
|
8a85aea543 | ||
|
|
b2c249a711 | ||
|
|
1da545725a | ||
|
|
ece488cb2a | ||
|
|
26cbc496a7 | ||
|
|
793cd9db91 | ||
|
|
f5c15a445b | ||
|
|
0e9c666981 | ||
|
|
8373a9cffb | ||
|
|
12d03f06b0 | ||
|
|
f5fc52b92f | ||
|
|
04f62e03b8 | ||
|
|
188d865671 | ||
|
|
5d2656550c | ||
|
|
ebc1b3aed2 | ||
|
|
a1d5f97efb | ||
|
|
15791b457a | ||
|
|
18f880530f | ||
|
|
59f43a82a8 | ||
|
|
af3a277e30 | ||
|
|
1416efc6f9 | ||
|
|
481bc00f28 | ||
|
|
34ac6faefc | ||
|
|
7c37d289c0 | ||
|
|
6856ba9972 | ||
|
|
f3942bb647 | ||
|
|
f1f4322db5 | ||
|
|
d15b6ffe67 | ||
|
|
71e88e6f73 | ||
|
|
5448a6d0ba | ||
|
|
8356db94b9 | ||
|
|
ac7b5dba11 | ||
|
|
e2aa29f117 | ||
|
|
f5767e61ef | ||
|
|
cfb37906ca | ||
|
|
1259f09503 | ||
|
|
a11ee472c6 | ||
|
|
2a92f67a9a | ||
|
|
fffd872b20 | ||
|
|
5b648b63ac | ||
|
|
6331210b94 | ||
|
|
25722f6055 | ||
|
|
85070ffda0 | ||
|
|
d6c2a4ba1c | ||
|
|
ac5df9a91d | ||
|
|
15156b4b87 | ||
|
|
c3368450f6 | ||
|
|
1e7b16adb9 | ||
|
|
50ce7f014d | ||
|
|
6ea34b331d | ||
|
|
1614b2ad2d | ||
|
|
371e405eed | ||
|
|
5e11f0b854 | ||
|
|
70b85fad6f | ||
|
|
fe5e5bc4b1 | ||
|
|
4561e52735 | ||
|
|
996404ceed | ||
|
|
854fcdaeae | ||
|
|
bec9870347 | ||
|
|
fc5f6887cb | ||
|
|
098691af9d | ||
|
|
035fdbc54a | ||
|
|
defcc02204 | ||
|
|
67055276ca | ||
|
|
06cc19fc70 | ||
|
|
3e1b778565 | ||
|
|
0ec90e0000 | ||
|
|
c19d2007bd | ||
|
|
46036eb958 | ||
|
|
83c623708f | ||
|
|
de2b7ab2d2 | ||
|
|
b7fb294368 | ||
|
|
dc91929d6e | ||
|
|
ef614751b1 | ||
|
|
45882543b6 | ||
|
|
3c0d89f599 | ||
|
|
a585ffe199 | ||
|
|
90c689a41a | ||
|
|
8927b8374a | ||
|
|
41e2ba7fcf | ||
|
|
8404dd57a7 | ||
|
|
a7e9aaa862 | ||
|
|
c2e4c5d43e | ||
|
|
a252d2ac3a | ||
|
|
3cbb2ac1e2 | ||
|
|
a554423d39 | ||
|
|
5d289dac47 | ||
|
|
16877a8ea3 |
9
.editorconfig
Normal file
9
.editorconfig
Normal file
@ -0,0 +1,9 @@
|
||||
# http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = true
|
||||
39
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
39
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -5,11 +5,18 @@ body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >
|
||||
### ✋ **This is bug tracker, not a support forum**
|
||||
### ⚠️ Please remember: issues are for *bugs*
|
||||
That is, something you believe affects every single user of OpenDTU, not just you. If you're not sure, start with one of the other options below.
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
#### Have a question? 👉 [Start a new discussion](https://github.com/tbnobody/OpenDTU/discussions/new) or [ask in chat](https://discord.gg/WzhxEY62mB).
|
||||
|
||||
If something isn't working right, you have questions or need help, [**get in touch on the Discussions**](https://github.com/tbnobody/OpenDTU/discussions).
|
||||
#### Before opening an issue, please double check:
|
||||
|
||||
Please quickly search existing issues first before submitting a bug.
|
||||
- [Documentation](https://www.opendtu.solar).
|
||||
- [The FAQs](https://www.opendtu.solar/firmware/faq/).
|
||||
- [Existing issues and discussions](https://github.com/tbnobody/OpenDTU/search?q=&type=issues).
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
@ -40,7 +47,8 @@ body:
|
||||
label: Install Method
|
||||
description: How did you install OpenDTU?
|
||||
options:
|
||||
- Pre-Compiled binary from GitHub
|
||||
- Pre-Compiled binary from GitHub releases
|
||||
- Pre-Compiled binary from GitHub actions/pull-request
|
||||
- Self-Compiled
|
||||
validations:
|
||||
required: true
|
||||
@ -52,6 +60,14 @@ body:
|
||||
placeholder: "e.g. 359d513"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: environment
|
||||
attributes:
|
||||
label: What firmware variant (PIO Environment) are you using?
|
||||
description: You can find this in by going to Info -> System
|
||||
placeholder: "generic_esp32s3_usb"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
@ -65,4 +81,17 @@ body:
|
||||
Links? References? Anything that will give us more context about the issue you are encountering!
|
||||
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
|
||||
validations:
|
||||
required: false
|
||||
required: false
|
||||
- type: checkboxes
|
||||
id: required-checks
|
||||
attributes:
|
||||
label: Please confirm the following
|
||||
options:
|
||||
- label: I believe this issue is a bug that affects all users of OpenDTU, not something specific to my installation.
|
||||
required: true
|
||||
- label: I have already searched for relevant existing issues and discussions before opening this report.
|
||||
required: true
|
||||
- label: I have updated the title field above with a concise description.
|
||||
required: true
|
||||
- label: I have double checked that my inverter does not contain a W in the model name (like HMS-xxxW) as they are not supported.
|
||||
required: true
|
||||
|
||||
59
.github/workflows/build.yml
vendored
59
.github/workflows/build.yml
vendored
@ -15,17 +15,17 @@ jobs:
|
||||
name: Gather Environments
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Cache pip
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
|
||||
- uses: actions/setup-python@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.x"
|
||||
|
||||
@ -37,26 +37,26 @@ jobs:
|
||||
- name: Get default environments
|
||||
id: envs
|
||||
run: |
|
||||
echo "environments=$(pio project config --json-output | jq -cr '.[0][1][0][1]')" >> $GITHUB_OUTPUT
|
||||
echo "environments=$(pio project config --json-output | jq -cr '.[1][1][0][1]|split(",")')" >> $GITHUB_OUTPUT
|
||||
|
||||
outputs:
|
||||
environments: ${{ steps.envs.outputs.environments }}
|
||||
|
||||
build:
|
||||
name: Build Enviornments
|
||||
name: Build Environments
|
||||
runs-on: ubuntu-latest
|
||||
needs: get_default_envs
|
||||
strategy:
|
||||
matrix:
|
||||
environment: ${{ fromJSON(needs.get_default_envs.outputs.environments) }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Get tags
|
||||
run: git fetch --force --tags origin
|
||||
|
||||
- name: Cache pip
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
||||
@ -64,33 +64,42 @@ jobs:
|
||||
${{ runner.os }}-pip-
|
||||
|
||||
- name: Cache PlatformIO
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.platformio
|
||||
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.x"
|
||||
|
||||
- name: Install PlatformIO
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install --upgrade platformio
|
||||
pip install --upgrade platformio setuptools
|
||||
|
||||
- name: Enable Corepack
|
||||
run: |
|
||||
cd webapp
|
||||
corepack enable
|
||||
|
||||
- name: Setup Node.js and yarn
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "18"
|
||||
node-version: "22"
|
||||
cache: "yarn"
|
||||
cache-dependency-path: "webapp/yarn.lock"
|
||||
|
||||
- name: Install WebApp dependencies
|
||||
run: yarn --cwd webapp install --frozen-lockfile
|
||||
run: |
|
||||
cd webapp
|
||||
yarn install --frozen-lockfile
|
||||
|
||||
- name: Build WebApp
|
||||
run: yarn --cwd webapp build
|
||||
run: |
|
||||
cd webapp
|
||||
yarn build
|
||||
|
||||
- name: Build firmware
|
||||
run: pio run -e ${{ matrix.environment }}
|
||||
@ -98,17 +107,15 @@ jobs:
|
||||
- name: Rename Firmware
|
||||
run: mv .pio/build/${{ matrix.environment }}/firmware.bin .pio/build/${{ matrix.environment }}/opendtu-${{ matrix.environment }}.bin
|
||||
|
||||
- name: Copy boot_app0.bin
|
||||
run: cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin .pio/build/${{ matrix.environment }}/boot_app0.bin
|
||||
- name: Rename Factory Firmware
|
||||
run: mv .pio/build/${{ matrix.environment }}/firmware.factory.bin .pio/build/${{ matrix.environment }}/opendtu-${{ matrix.environment }}.factory.bin
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: opendtu-${{ matrix.environment }}
|
||||
path: |
|
||||
.pio/build/${{ matrix.environment }}/opendtu-${{ matrix.environment }}.bin
|
||||
.pio/build/${{ matrix.environment }}/partitions.bin
|
||||
.pio/build/${{ matrix.environment }}/bootloader.bin
|
||||
.pio/build/${{ matrix.environment }}/boot_app0.bin
|
||||
.pio/build/${{ matrix.environment }}/opendtu-${{ matrix.environment }}.factory.bin
|
||||
|
||||
release:
|
||||
name: Create Release
|
||||
@ -117,11 +124,11 @@ jobs:
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Build Changelog
|
||||
id: github_release
|
||||
uses: mikepenz/release-changelog-builder-action@v3.7.0
|
||||
uses: mikepenz/release-changelog-builder-action@v4
|
||||
with:
|
||||
failOnError: true
|
||||
commitMode: true
|
||||
@ -129,20 +136,18 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: artifacts/
|
||||
|
||||
- name: Create ZIPs
|
||||
- name: Move all files to the same location
|
||||
run: |
|
||||
ls -R
|
||||
sudo apt install zip
|
||||
cd artifacts
|
||||
for i in */; do zip -r "${i%/}.zip" "$i"; done
|
||||
for i in */; do cp ${i}opendtu-*.bin ./; done
|
||||
|
||||
- name: Create release
|
||||
uses: softprops/action-gh-release@v1
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
body: ${{steps.github_release.outputs.changelog}}
|
||||
draft: False
|
||||
|
||||
@ -18,6 +18,12 @@
|
||||
"fix"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "## 🌎 Web Application",
|
||||
"labels": [
|
||||
"webapp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "## 📚 Documentation",
|
||||
"labels": [
|
||||
|
||||
6
.github/workflows/cpplint.yml
vendored
6
.github/workflows/cpplint.yml
vendored
@ -7,9 +7,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Install dependencies
|
||||
@ -18,4 +18,4 @@ jobs:
|
||||
pip install cpplint
|
||||
- name: Linting
|
||||
run: |
|
||||
cpplint --repository=. --recursive --filter=-runtime/references,-readability/braces,-whitespace,-legal,-build/include ./src ./include ./lib/Hoymiles ./lib/MqttSubscribeParser ./lib/TimeoutHelper ./lib/ResetReason
|
||||
cpplint --repository=. --recursive --filter=-build/c++11,-runtime/references,-readability/braces,-whitespace,-legal,-build/include ./src ./include ./lib/Hoymiles ./lib/MqttSubscribeParser ./lib/TimeoutHelper ./lib/ResetReason
|
||||
|
||||
54
.github/workflows/repo-maintenance.yml
vendored
Normal file
54
.github/workflows/repo-maintenance.yml
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
name: 'Repository Maintenance'
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 4 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
discussions: write
|
||||
|
||||
concurrency:
|
||||
group: lock
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
name: 'Stale'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
days-before-stale: 14
|
||||
days-before-close: 60
|
||||
any-of-labels: 'cant-reproduce,not a bug'
|
||||
stale-issue-label: stale
|
||||
stale-pr-label: stale
|
||||
stale-issue-message: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
|
||||
lock-threads:
|
||||
name: 'Lock Old Threads'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v5
|
||||
with:
|
||||
issue-inactive-days: '30'
|
||||
pr-inactive-days: '30'
|
||||
discussion-inactive-days: '30'
|
||||
log-output: true
|
||||
issue-comment: >
|
||||
This issue has been automatically locked since there
|
||||
has not been any recent activity after it was closed.
|
||||
Please open a new discussion or issue for related concerns.
|
||||
pr-comment: >
|
||||
This pull request has been automatically locked since there
|
||||
has not been any recent activity after it was closed.
|
||||
Please open a new discussion or issue for related concerns.
|
||||
discussion-comment: >
|
||||
This discussion has been automatically locked since there
|
||||
has not been any recent activity after it was closed.
|
||||
Please open a new discussion for related concerns.
|
||||
16
.github/workflows/yarnlint.yml
vendored
16
.github/workflows/yarnlint.yml
vendored
@ -6,17 +6,23 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: webapp
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
- name: Setup Node.js and yarn
|
||||
uses: actions/setup-node@v3
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "18"
|
||||
node-version: "22"
|
||||
cache: "yarn"
|
||||
cache-dependency-path: "webapp/yarn.lock"
|
||||
|
||||
- name: Install WebApp dependencies
|
||||
run: yarn --cwd webapp install --frozen-lockfile
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
- name: Linting
|
||||
run: yarn --cwd webapp lint
|
||||
run: yarn lint
|
||||
|
||||
28
.github/workflows/yarnprettier.yml
vendored
Normal file
28
.github/workflows/yarnprettier.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
name: Yarn Prettier
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: webapp
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
- name: Setup Node.js and yarn
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "22"
|
||||
cache: "yarn"
|
||||
cache-dependency-path: "webapp/yarn.lock"
|
||||
|
||||
- name: Install WebApp dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
- name: Check Formatting
|
||||
run: yarn prettier --check src/
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,5 +5,6 @@
|
||||
.vscode/ipch
|
||||
.vscode/settings.json
|
||||
platformio-device-monitor*.log
|
||||
logs/device-monitor*.log
|
||||
platformio_override.ini
|
||||
.DS_Store
|
||||
|
||||
3
.vscode/extensions.json
vendored
3
.vscode/extensions.json
vendored
@ -2,6 +2,9 @@
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"DavidAnson.vscode-markdownlint",
|
||||
"EditorConfig.EditorConfig",
|
||||
"Vue.volar",
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
|
||||
294
README.md
294
README.md
@ -13,76 +13,23 @@ If you are upgrading from a version before 15.03.2023 you have to upgrade the pa
|
||||
This project was started from [this](https://www.mikrocontroller.net/topic/525778) discussion (Mikrocontroller.net).
|
||||
It was the goal to replace the original Hoymiles DTU (Telemetry Gateway) with their cloud access. With a lot of reverse engineering the Hoymiles protocol was decrypted and analyzed.
|
||||
|
||||
## Screenshots
|
||||
## Documentation
|
||||
|
||||
Several screenshots of the frontend can be found here: [Screenshots](docs/screenshots/README.md)
|
||||
|
||||
## Builds
|
||||
|
||||
Different builds from existing installations can be found here [Builds](docs/builds/README.md)
|
||||
Like to show your own build? Just send me a Pull Request.
|
||||
|
||||
## Currently supported Inverters
|
||||
|
||||
* Hoymiles HM-300
|
||||
* Hoymiles HM-350
|
||||
* Hoymiles HM-400
|
||||
* Hoymiles HM-600
|
||||
* Hoymiles HM-700
|
||||
* Hoymiles HM-800
|
||||
* Hoymiles HM-1000
|
||||
* Hoymiles HM-1200
|
||||
* Hoymiles HM-1500
|
||||
* Solenso SOL-H350
|
||||
* Solenso SOL-H400
|
||||
* Solenso SOL-H800
|
||||
* TSUN TSOL-M350 (Maybe depending on firmware/serial number on the inverter)
|
||||
* TSUN TSOL-M800 (Maybe depending on firmware/serial number on the inverter)
|
||||
* TSUN TSOL-M1600 (Maybe depending on firmware/serial number on the inverter)
|
||||
|
||||
**TSUN compatibility remark:**
|
||||
Compatibility with OpenDTU seems to be related to serial numbers. Current findings indicate that TSUN inverters with a serial number starting with "11" are supported, whereby inverters with a serial number starting with "10" are not.
|
||||
Firmware version seems to play not a significant role and cannot be read from the stickers. For completeness, the following firmware version have been reported to work with OpenDTU:
|
||||
|
||||
* v1.0.8, v1.0.10 TSOL-M800 (DE)
|
||||
* v1.0.12 TSOL-M1600
|
||||
|
||||
## Features for end users
|
||||
|
||||
* Read live data from inverter
|
||||
* Show inverters internal event log
|
||||
* Show inverter information like firmware version, firmware build date, hardware revision and hardware version
|
||||
* Show and set the current inverter limit
|
||||
* Function to turn the inverter off and on
|
||||
* Uses ESP32 microcontroller and NRF24L01+
|
||||
* Multi-Inverter support
|
||||
* MQTT support (with TLS)
|
||||
* Home Assistant MQTT Auto Discovery support
|
||||
* Nice and fancy WebApp with visualization of current data
|
||||
* Firmware upgrade using the web UI
|
||||
* Default source supports up to 10 inverters
|
||||
* Time zone support
|
||||
* Ethernet support
|
||||
* Prometheus API endpoint (/api/prometheus/metrics)
|
||||
* English, german and french web interface
|
||||
* Displays (SSD1306, SH1106, PCD8544)
|
||||
* Dark Theme
|
||||
|
||||
## Features for developers
|
||||
|
||||
* The microcontroller part
|
||||
* Build with Arduino PlatformIO Framework for the ESP32
|
||||
* Uses a fork of [ESPAsyncWebserver](https://github.com/yubox-node-org/ESPAsyncWebServer) and [espMqttClient](https://github.com/bertmelis/espMqttClient)
|
||||
|
||||
* The WebApp part
|
||||
* Build with [Vue.js](https://vuejs.org)
|
||||
* Source is written in TypeScript
|
||||
The documentation can be found [here](https://tbnobody.github.io/OpenDTU-docs/).
|
||||
Please feel free to support and create a PR in [this](https://github.com/tbnobody/OpenDTU-docs) repository to make the documentation even better.
|
||||
|
||||
## Breaking changes
|
||||
|
||||
Generated using: `git log --date=short --pretty=format:"* %h%x09%ad%x09%s" | grep BREAKING`
|
||||
|
||||
```code
|
||||
* 1b637f08 2024-01-30 BREAKING CHANGE: Web API Endpoint /api/livedata/status and /api/prometheus/metrics
|
||||
* e1564780 2024-01-30 BREAKING CHANGE: Web API Endpoint /api/livedata/status and /api/prometheus/metrics
|
||||
* f0b5542c 2024-01-30 BREAKING CHANGE: Web API Endpoint /api/livedata/status and /api/prometheus/metrics
|
||||
* c27ecc36 2024-01-29 BREAKING CHANGE: Web API Endpoint /api/livedata/status
|
||||
* 71d1b3b 2023-11-07 BREAKING CHANGE: Home Assistant Auto Discovery to new naming scheme
|
||||
* 04f62e0 2023-04-20 BREAKING CHANGE: Web API Endpoint /api/eventlog/status no nested serial object
|
||||
* 59f43a8 2023-04-17 BREAKING CHANGE: Web API Endpoint /api/devinfo/status requires GET parameter inv=
|
||||
* 318136d 2023-03-15 BREAKING CHANGE: Updated partition table: Make sure you have a configuration backup and completly reflash the device!
|
||||
* 3b7aef6 2023-02-13 BREAKING CHANGE: Web API!
|
||||
* d4c838a 2023-02-06 BREAKING CHANGE: Prometheus API!
|
||||
@ -91,223 +38,6 @@ Generated using: `git log --date=short --pretty=format:"* %h%x09%ad%x09%s" | gre
|
||||
* 27ed4e3 2022-10-31 BREAKING: Change power factor from percent value to value between 0 and 1
|
||||
```
|
||||
|
||||
## Hardware you need
|
||||
## Currently supported Inverters
|
||||
|
||||
### ESP32 board
|
||||
|
||||
For ease of use, buy a "ESP32 DEVKIT DOIT" or "ESP32 NodeMCU Development Board" with an ESP32-S3 or ESP-WROOM-32 chipset on it.
|
||||
|
||||
Sample Picture:
|
||||
|
||||

|
||||
|
||||
Also supported: Board with Ethernet-Connector and Power-over-Ethernet [Olimex ESP32-POE](https://www.olimex.com/Products/IoT/ESP32/ESP32-POE/open-source-hardware)
|
||||
|
||||
### NRF24L01+ radio board
|
||||
|
||||
The PLUS sign is IMPORTANT! There are different variants available, with antenna on the printed circuit board or external antenna.
|
||||
|
||||
Sample picture:
|
||||
|
||||

|
||||
|
||||
Buy your hardware from a trusted source, at best from a dealer/online shop in your country where you have support and the right to return non-functional hardware.
|
||||
When you want to buy from Amazon, AliExpress, eBay etc., take note that there is a lot of low-quality or fake hardware offered. Read customer comments and ratings carefully!
|
||||
|
||||
A heavily incomplete list of trusted hardware shops in germany is:
|
||||
|
||||
* [AZ-Delivery](https://www.az-delivery.de/)
|
||||
* [Makershop](https://www.makershop.de/)
|
||||
* [Berrybase](https://www.berrybase.de/)
|
||||
|
||||
This list is for your convenience only, the project is not related to any of these shops.
|
||||
|
||||
### Power supply
|
||||
|
||||
Use a power suppy with 5 V and 1 A. The USB cable connected to your PC/Notebook may be powerful enough or may be not.
|
||||
|
||||
## Wiring up
|
||||
|
||||
### Schematic
|
||||
|
||||

|
||||
|
||||
### Symbolic view
|
||||
|
||||

|
||||
|
||||
### Change pin assignment
|
||||
|
||||
Its possible to change all the pins of the NRF24L01+ module, the Display, the LED etc.
|
||||
The recommend way to change the pin assignment is by creating a custom [device profile](docs/DeviceProfiles.md).
|
||||
It is also possible to create a custom environment and compile the source yourself. This can be achieved by copying one of the [env:....] sections from 'platformio.ini' to 'platformio_override.ini' and editing the 'platformio_override.ini' file and add/change one or more of the following lines to the 'build_flags' parameter:
|
||||
|
||||
```makefile
|
||||
-DHOYMILES_PIN_MISO=19
|
||||
-DHOYMILES_PIN_MOSI=23
|
||||
-DHOYMILES_PIN_SCLK=18
|
||||
-DHOYMILES_PIN_IRQ=16
|
||||
-DHOYMILES_PIN_CE=4
|
||||
-DHOYMILES_PIN_CS=5
|
||||
```
|
||||
|
||||
It is recommended to make all changes only in the 'platformio_override.ini', this is your personal copy.
|
||||
|
||||
## Flashing and starting up
|
||||
|
||||
### with Visual Studio Code
|
||||
|
||||
* Install [Visual Studio Code](https://code.visualstudio.com/download) (from now named "vscode")
|
||||
* In Visual Studio Code, install the [PlatformIO Extension](https://marketplace.visualstudio.com/items?itemName=platformio.platformio-ide)
|
||||
* Install git and enable git in vscode - [git download](https://git-scm.com/downloads/) - [Instructions](https://www.jcchouinard.com/install-git-in-vscode/)
|
||||
* Clone this repository (you really have to clone it, don't just download the ZIP file. During the build process the git hash gets embedded into the firmware. If you download the ZIP file a build error will occur): Inside vscode open the command palette by pressing `CTRL` + `SHIFT` + `P`. Enter `git clone`, add the repository-URL `https://github.com/tbnobody/OpenDTU`. Next you have to choose (or create) a target directory.
|
||||
* In vscode, choose File --> Open Folder and select the previously downloaded source code. (You have to select the folder which contains the "platformio.ini" and "platformio_override.ini" file)
|
||||
* Adjust the COM port in the file "platformio_override.ini" for your USB-to-serial-converter. It occurs twice:
|
||||
* upload_port
|
||||
* monitor_port
|
||||
* Select the arrow button in the blue bottom status bar (PlatformIO: Upload) to compile and upload the firmware. During the compilation, all required libraries are downloaded automatically.
|
||||
* Under Linux, if the upload fails with error messages "Could not open /dev/ttyUSB0, the port doesn't exist", you can check via ```ls -la /dev/tty*``` to which group your port belongs to, and then add your user this group via ```sudo adduser <yourusername> dialout``` (if you are using ```arch-linux``` use: ```sudo gpasswd -a <yourusername> uucp```, this method requires a logout/login of the affected user).
|
||||
* There are two videos showing these steps:
|
||||
* [Git Clone and compilation](https://youtu.be/9cA_esv3zeA)
|
||||
* [Full installation and compilation](https://youtu.be/xs6TqHn7QWM)
|
||||
|
||||
### on the commandline with PlatformIO Core
|
||||
|
||||
* Install [PlatformIO Core](https://platformio.org/install/cli)
|
||||
* Clone this repository (you really have to clone it, don't just download the ZIP file. During the build process the git hash gets embedded into the firmware. If you download the ZIP file a build error will occur)
|
||||
* Adjust the COM port in the file "platformio_override.ini". It occurs twice:
|
||||
* upload_port
|
||||
* monitor_port
|
||||
* build: `platformio run -e generic`
|
||||
* upload to esp module: `platformio run -e generic -t upload`
|
||||
* other options:
|
||||
* clean the sources: `platformio run -e generic -t clean`
|
||||
* erase flash: `platformio run -e generic -t erase`
|
||||
|
||||
### using the pre-compiled .bin files
|
||||
|
||||
The pre-compiled files can be found on the [github page](https://github.com/tbnobody/OpenDTU) in the tab "Actions" and the sub menu "OpenDTU Build". Just choose the latest build from the master branch (search for "master" in the blue font text but click on the white header text!). You need to be logged in with your github account to download the files.
|
||||
Use a ESP32 flash tool of your choice (see next chapter) and flash the `.bin` files to the right addresses:
|
||||
|
||||
| Address | File |
|
||||
| ---------| ---------------------- |
|
||||
| 0x1000 | bootloader.bin |
|
||||
| 0x8000 | partitions.bin |
|
||||
| 0xe000 | boot_app0.bin |
|
||||
| 0x10000 | opendtu-*.bin |
|
||||
|
||||
For further updates you can just use the web interface and upload the `opendtu-*.bin` file.
|
||||
|
||||
#### Flash with esptool.py (Linux)
|
||||
|
||||
```bash
|
||||
esptool.py --port /dev/ttyUSB0 --chip esp32 --before default_reset --after hard_reset \
|
||||
write_flash --flash_mode dout --flash_freq 40m --flash_size detect \
|
||||
0x1000 bootloader.bin \
|
||||
0x8000 partitions.bin \
|
||||
0xe000 boot_app0.bin \
|
||||
0x10000 opendtu-generic.bin
|
||||
```
|
||||
|
||||
#### Flash with Espressif Flash Download Tool (Windows)
|
||||
|
||||
[Download link](https://www.espressif.com/en/support/download/other-tools)
|
||||
|
||||
* On startup, select Chip Type -> "ESP32" / WorkMode -> "Develop"
|
||||
* Prepare all settings (see picture). Make sure to uncheck the `DoNotChgBin` option. Otherwise you may get errors like "invalid header".
|
||||
* 
|
||||
* Press "Erase" button on screen. Look into the terminal window, you should see dots appear. Then press the "Boot" button on the ESP32 board. Wait for "FINISH" to see if flashing/erasing is done.
|
||||
* To program, press "Start" on screen, then the "Boot" button.
|
||||
* When flashing is complete (FINISH appears) then press the Reset button on the ESP32 board (or powercycle ) to start the OpenDTU application.
|
||||
|
||||
#### Flash with ESP_Flasher (Windows)
|
||||
|
||||
Users report that [ESP_Flasher](https://github.com/Jason2866/ESP_Flasher/releases/) is suitable for flashing OpenDTU on Windows.
|
||||
|
||||
#### Flash with [ESP_Flasher](https://espressif.github.io/esptool-js/) - web version
|
||||
|
||||
It is also possible to flash it via the web tools which might be more convenient and is platform independent.
|
||||
|
||||
## First configuration
|
||||
|
||||
* After the initial flashing of the microcontroller, an Access Point called "OpenDTU-*" is opened. The default password is "openDTU42".
|
||||
* Use a web browser to open the address [http://192.168.4.1](http://192.168.4.1)
|
||||
* Navigate to Settings --> Network Settings and enter your WiFi credentials. The username to access the config menu is "admin" and the password the same as for accessing the Access Point (default: "openDTU42").
|
||||
* OpenDTU then simultaneously connects to your WiFi AP with these credentials. Navigate to Info --> Network and look into section "Network Interface (Station)" for the IP address received via DHCP.
|
||||
* If your WiFi AP uses an allow-list for MAC-addresses, please be aware that the ESP32 has two different MAC addresses for its AP and client modes, they are also listed at Info --> Network.
|
||||
* When OpenDTU is connected to a configured WiFI AP, the "OpenDTU-*" Access Point is closed after 3 minutes.
|
||||
* OpenDTU needs access to a working NTP server to get the current date & time. Both are sent to the inverter with each request. Default NTP server is pool.ntp.org. If your network has different requirements please change accordingly (Settings --> NTP Settings).
|
||||
* Add your inverter in the inverter settings (Settings --> Inverter Settings)
|
||||
|
||||
## Flashing an Update using "Over The Air" OTA Update
|
||||
|
||||
Once you have your OpenDTU running and connected to WLAN, you can do further updates through the web interface.
|
||||
Navigate to Settings --> Firmware upgrade and press the browse button. Select the firmware file from your local computer.
|
||||
|
||||
You'll find the firmware file (after a successful build process) under `.pio/build/generic/firmware.bin`.
|
||||
|
||||
If you downloaded a precompiled zip archive, unpack it and choose `opendtu-generic.bin`.
|
||||
|
||||
After the successful upload, the OpenDTU immediately restarts into the new firmware.
|
||||
|
||||
## MQTT Topic Documentation
|
||||
|
||||
A documentation of all available MQTT Topics can be found here: [MQTT Documentation](docs/MQTT_Topics.md)
|
||||
|
||||
## Web API Documentation
|
||||
|
||||
A documentation of the Web API can be found here: [Web-API Documentation](docs/Web-API.md)
|
||||
|
||||
## Available cases
|
||||
|
||||
* <https://www.thingiverse.com/thing:5435911>
|
||||
* <https://www.printables.com/model/293003-sol-opendtu-esp32-nrf24l01-case>
|
||||
* <https://www.thingiverse.com/thing:5661780>
|
||||
* <https://www.thingiverse.com/thing:5632374>
|
||||
* <https://www.thingiverse.com/thing:5852233>
|
||||
* <https://www.printables.com/model/377994-opendtu-pcb-box-for-the-wider-board>
|
||||
* <https://www.printables.com/model/376840-esp32-ahoy-opendtu-pcb-housing>
|
||||
|
||||
## Available layouts for printed circuit boards
|
||||
|
||||
* [BreakoutBoard - sample printed circuit board for OpenDTU and Ahoy](https://github.com/dokuhn/openDTU-BreakoutBoard)
|
||||
* [Board for OpenDTU with Display](https://github.com/SteffMUC/openDTU_wDisplay2)
|
||||
* [OpenDTU PCB mit Display](https://github.com/turrican944/OpenDTU-PCB)
|
||||
* [PCB for OpenDTU in Cable Branchbox](https://github.com/plewka/ESP-Solar_OpenDTU)
|
||||
|
||||
## Building
|
||||
|
||||
* Building the WebApp
|
||||
* The WebApp can be build using yarn
|
||||
|
||||
```bash
|
||||
cd webapp
|
||||
yarn install
|
||||
yarn build
|
||||
```
|
||||
|
||||
* The updated output is placed in the 'webapp_dist' directory
|
||||
* It is only necessary to build the webapp when you made changes to it
|
||||
* Building the microcontroller firmware
|
||||
* Visual Studio Code with the PlatformIO Extension is required for building
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
* First: When there is no light on the solar panels, the inverter completely turns off and does not answer to OpenDTU! So if you assembled your OpenDTU in the evening, wait until tomorrow.
|
||||
* When there is no data received from the inverter(s) - try to reduce the distance between the openDTU and the inverter (e.g. move it to the window towards the roof)
|
||||
* Under Settings -> DTU Settings you can increase the transmit power "PA level". Default is "minimum".
|
||||
* The NRF24L01+ needs relatively much current. With bad power supply (and especially bad cables!) a 10 µF capacitor soldered directly to the NRF24L01+ board connector brings more stability (pin 1+2 are the power supply). Note the polarity of the capacitor…
|
||||
* You can try to use an USB power supply with 1 A or more instead of connecting the ESP32 to the computer.
|
||||
* Try a different USB cable. Once again, a stable power source is important. Some USB cables are made of much plastic and very little copper inside.
|
||||
* Double check that you have a radio module NRF24L01+ with a plus sign at the end. NRF24L01 module without the plus are not compatible with this project.
|
||||
* There is no possibility of auto-discovering the inverters. Double check you have entered the serial numbers of the inverters correctly.
|
||||
* OpenDTU needs access to a working NTP server to get the current date & time.
|
||||
* If your problem persists, check the [Issues on Github](https://github.com/tbnobody/OpenDTU/issues). Please inspect not only the open issues, also the closed issues contain useful information.
|
||||
* Another source of information are the [Discussions](https://github.com/tbnobody/OpenDTU/discussions/)
|
||||
* When flashing with VSCode Plattform.IO fails and also with ESPRESSIF tool a demo bin file cannot be flashed to the ESP32 with error message "A fatal error occurred: MD5 of file does not match data in flash!" than un-wire/unconnect ESP32 from the NRF24L01+ board. Try to flash again and rewire afterwards.
|
||||
|
||||
## Related Projects
|
||||
|
||||
* [Ahoy](https://github.com/grindylow/ahoy)
|
||||
* [DTU Simulator](https://github.com/Ziyatoe/DTUsimMI1x00-Hoymiles)
|
||||
* [OpenDTU extended to talk to Victrons MPPT battery chargers (Ve.Direct)](https://github.com/helgeerbe/OpenDTU_VeDirect)
|
||||
A list of all currently supported inverters can be found [here](https://www.opendtu.solar/hardware/inverter_overview/)
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# Copyright (C) 2022 Thomas Basler and others
|
||||
#
|
||||
import pkg_resources
|
||||
|
||||
Import("env")
|
||||
|
||||
required_pkgs = {'dulwich'}
|
||||
installed_pkgs = {pkg.key for pkg in pkg_resources.working_set}
|
||||
missing_pkgs = required_pkgs - installed_pkgs
|
||||
|
||||
if missing_pkgs:
|
||||
env.Execute('"$PYTHONEXE" -m pip install dulwich')
|
||||
|
||||
from dulwich import porcelain
|
||||
|
||||
def get_firmware_specifier_build_flag():
|
||||
try:
|
||||
build_version = porcelain.describe('.') # '.' refers to the repository root dir
|
||||
except:
|
||||
build_version = "g0000000"
|
||||
build_flag = "-D AUTO_GIT_HASH=\\\"" + build_version + "\\\""
|
||||
print ("Firmware Revision: " + build_version)
|
||||
return (build_flag)
|
||||
|
||||
env.Append(
|
||||
BUILD_FLAGS=[get_firmware_specifier_build_flag()]
|
||||
)
|
||||
@ -1,107 +1,3 @@
|
||||
# Device Profiles
|
||||
|
||||
It is possible to change hardware settings like pin assignments or ethernet support using a json file. The json file can be uploaded using the configuration management in the web interface. Just select "Pin Mapping (pin_mapping.json)" in the recovery section.
|
||||
|
||||
When the file is uploaded the ESP performs a reboot. This is required as the pin settings could have changed within the file. By default all the pin assignments are used as compiled into the firmware.
|
||||
|
||||
To change the device profile, navigate to the "Device Manager" and selected the appropriate profile. You can see the current (Active) and the new (Selected) in assignment in the table below the combobox.
|
||||
|
||||
## Structure of the json file
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"name": "Generic NodeMCU 38 pin",
|
||||
"nrf24": {
|
||||
"miso": 19,
|
||||
"mosi": 23,
|
||||
"clk": 18,
|
||||
"irq": 16,
|
||||
"en": 4,
|
||||
"cs": 5
|
||||
},
|
||||
"eth": {
|
||||
"enabled": false,
|
||||
"phy_addr": -1,
|
||||
"power": -1,
|
||||
"mdc": -1,
|
||||
"mdio": -1,
|
||||
"type": -1,
|
||||
"clk_mode": -1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Generic NodeMCU 38 pin with SSD1306",
|
||||
"nrf24": {
|
||||
"miso": 19,
|
||||
"mosi": 23,
|
||||
"clk": 18,
|
||||
"irq": 16,
|
||||
"en": 4,
|
||||
"cs": 5
|
||||
},
|
||||
"eth": {
|
||||
"enabled": false,
|
||||
"phy_addr": -1,
|
||||
"power": -1,
|
||||
"mdc": -1,
|
||||
"mdio": -1,
|
||||
"type": -1,
|
||||
"clk_mode": -1
|
||||
},
|
||||
"display": {
|
||||
"type": 2,
|
||||
"data": 21,
|
||||
"clk": 22
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Olimex ESP32-POE",
|
||||
"nrf24": {
|
||||
"miso": 15,
|
||||
"mosi": 2,
|
||||
"clk": 14,
|
||||
"irq": 13,
|
||||
"en": 16,
|
||||
"cs": 5
|
||||
},
|
||||
"eth": {
|
||||
"enabled": true,
|
||||
"phy_addr": 0,
|
||||
"power": 12,
|
||||
"mdc": 23,
|
||||
"mdio": 18,
|
||||
"type": 0,
|
||||
"clk_mode": 3
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
The json file can contain multiple profiles. Each profile requires a name and different parameters. If one parameter is not set, the default value, as compiled into the firmware is used. The example above shows all the currently supported values. Others may follow. Sample files for some boards can be found [here](DeviceProfiles/). This means you can just flash the generic bin file and upload the json file. Then you select your board and everything works hopyfully as expected.
|
||||
|
||||
## Implemented configuration values
|
||||
|
||||
| Parameter | Data Type | Description |
|
||||
| ------------- | --------- | ----------- |
|
||||
| name | string | Unique name of the profile (max 63 characters) |
|
||||
| nrf24.miso | number | MISO Pin |
|
||||
| nrf24.mosi | number | MOSI Pin |
|
||||
| nrf24.clk | number | Clock Pin |
|
||||
| nrf24.irq | number | Interrupt Pin |
|
||||
| nrf24.en | number | Enable Pin |
|
||||
| nrf24.cs | number | Chip Select Pin |
|
||||
| eth.enabled | boolean | Enable/Disable the ethernet stack |
|
||||
| eth.phy_addr | number | Unique PHY addr |
|
||||
| eth.power | number | Power Pin (if available). Use -1 for not assigned pins. |
|
||||
| eth.mdc | number | Serial Management Interface MDC Pin. Use -1 for not assigned pins. |
|
||||
| eth.mdio | number | Serial Management Interface MDIO Pin. Use -1 for not assigned pins. |
|
||||
| eth.type | number | Possible values:<br>* 0 = ETH_PHY_LAN8720<br>* 1 = ETH_PHY_TLK110<br>* 2 = ETH_PHY_RTL8201<br>* 3 = ETH_PHY_DP83848<br>* 4 = ETH_PHY_DM9051<br>* 5 = ETH_PHY_KSZ8041<br>* 6 = ETH_PHY_KSZ8081 |
|
||||
| eth.clk_mode | number | Possible values:<br>* 0 = ETH_CLOCK_GPIO0_IN<br>* 1 = ETH_CLOCK_GPIO0_OUT<br>* 2 = ETH_CLOCK_GPIO16_OUT<br>* 3 = ETH_CLOCK_GPIO17_OUT |
|
||||
| display.type | number | Specify type of display. Possible values:<br>* 0 = None (default)<br>* 1 = PCD8544 <br>* 2 = SSD1306 <br>* 3 = SH1106 |
|
||||
| display.data | number | Data Pin (e.g. SDA for i2c displays) required for all displays. Use 255 for not assigned pins. |
|
||||
| display.clk | number | Clock Pin (e.g. SCL for i2c displays) required for SSD1306 and SH1106. Use 255 for not assigned pins. |
|
||||
| display.cs | number | Chip Select Pin required for PCD8544. Use 255 for not assigned pins. |
|
||||
| display.reset | number | Reset Pin required for PCD8544, optional for all other displays. Use 255 for not assigned pins. |
|
||||
| led.led0 | number | LED pin for network indication. Blinking = WLAN connected but NTP & MQTT (if enabled) disconnected. On = WLAN, NTP, MQTT connected. Off = Network not connected |
|
||||
| led.led1 | number | LED pin for inverter indication. On = All inverters reachable & producing. Blinking = All inverters reachable but not producing. Off = At least one inverter is not reachable. Only inverters with polling enabled are considered. |
|
||||
This documentation will has been moved and can be found here: <https://tbnobody.github.io/OpenDTU-docs/firmware/device_profiles/>
|
||||
|
||||
76
docs/DeviceProfiles/AhoyDTU-ESP32.json
Normal file
76
docs/DeviceProfiles/AhoyDTU-ESP32.json
Normal file
@ -0,0 +1,76 @@
|
||||
[
|
||||
{
|
||||
"name": "AhoyDTU ESP32 Display LED",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://ahoydtu.de/getting_started/"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 19,
|
||||
"mosi": 23,
|
||||
"clk": 18,
|
||||
"irq": 16,
|
||||
"en": 4,
|
||||
"cs": 5
|
||||
},
|
||||
"led": {
|
||||
"led0": 25,
|
||||
"led1": 26
|
||||
},
|
||||
"display": {
|
||||
"type": 2,
|
||||
"data": 21,
|
||||
"clk": 22
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "AhoyDTU ESP32 Display",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://ahoydtu.de/getting_started/"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 19,
|
||||
"mosi": 23,
|
||||
"clk": 18,
|
||||
"irq": 16,
|
||||
"en": 4,
|
||||
"cs": 5
|
||||
},
|
||||
"display": {
|
||||
"type": 2,
|
||||
"data": 21,
|
||||
"clk": 22
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "AhoyDTU ESP32 LED",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://ahoydtu.de/getting_started/"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 19,
|
||||
"mosi": 23,
|
||||
"clk": 18,
|
||||
"irq": 16,
|
||||
"en": 4,
|
||||
"cs": 5
|
||||
},
|
||||
"led": {
|
||||
"led0": 25,
|
||||
"led1": 26
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "AhoyDTU ESP32",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://ahoydtu.de/getting_started/"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 19,
|
||||
"mosi": 23,
|
||||
"clk": 18,
|
||||
"irq": 16,
|
||||
"en": 4,
|
||||
"cs": 5
|
||||
}
|
||||
}
|
||||
]
|
||||
20
docs/DeviceProfiles/CASmo-DTU.json
Normal file
20
docs/DeviceProfiles/CASmo-DTU.json
Normal file
@ -0,0 +1,20 @@
|
||||
[
|
||||
{
|
||||
"name": "CASmo-DTU",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://casmo.info/product-details/?product=2"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 19,
|
||||
"mosi": 23,
|
||||
"clk": 18,
|
||||
"irq": 16,
|
||||
"en": 4,
|
||||
"cs": 5
|
||||
},
|
||||
"led": {
|
||||
"led0": 25,
|
||||
"led1": 26
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -1,6 +1,12 @@
|
||||
[
|
||||
{
|
||||
"name": "LEDs, Display",
|
||||
"name": "NRF, LEDs, Display",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://shop.blinkyparts.com/de/OpenDTU-NRF-Deine-Auswertung-fuer-deine-Balkonsolaranlage-kompatibel-zu-Hoymiles-HM-Serie-NRF-Modul/blink237542"},
|
||||
{"name": "Manual DE", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_de.pdf"},
|
||||
{"name": "Manual EN", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_en.pdf"},
|
||||
{"name": "Schematic", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/ibom.html"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 19,
|
||||
"mosi": 23,
|
||||
@ -20,7 +26,47 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Only Display",
|
||||
"name": "CMT, LEDs, Display",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://shop.blinkyparts.com/de/OpenDTU-CMT-Deine-Auswertung-fuer-deine-Balkonsolaranlage-kompatibel-zu-Hoymiles-HMS-und-HMT-Serie-CMT-Modul/blink238342"},
|
||||
{"name": "Manual DE", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_de.pdf"},
|
||||
{"name": "Manual EN", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_en.pdf"},
|
||||
{"name": "Schematic", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/ibom.html"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": -1,
|
||||
"mosi": -1,
|
||||
"clk": -1,
|
||||
"irq": -1,
|
||||
"en": -1,
|
||||
"cs": -1
|
||||
},
|
||||
"cmt": {
|
||||
"clk": 18,
|
||||
"cs": 4,
|
||||
"fcs": 5,
|
||||
"sdio": 23,
|
||||
"gpio2": 19,
|
||||
"gpio3": 16
|
||||
},
|
||||
"display": {
|
||||
"type": 3,
|
||||
"data": 21,
|
||||
"clk": 22
|
||||
},
|
||||
"led": {
|
||||
"led0": 25,
|
||||
"led1": 26
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "NRF, Display",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://shop.blinkyparts.com/de/OpenDTU-NRF-Deine-Auswertung-fuer-deine-Balkonsolaranlage-kompatibel-zu-Hoymiles-HM-Serie-NRF-Modul/blink237542"},
|
||||
{"name": "Manual DE", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_de.pdf"},
|
||||
{"name": "Manual EN", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_en.pdf"},
|
||||
{"name": "Schematic", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/ibom.html"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 19,
|
||||
"mosi": 23,
|
||||
@ -36,7 +82,43 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Only LEDs",
|
||||
"name": "CMT, Display",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://shop.blinkyparts.com/de/OpenDTU-CMT-Deine-Auswertung-fuer-deine-Balkonsolaranlage-kompatibel-zu-Hoymiles-HMS-und-HMT-Serie-CMT-Modul/blink238342"},
|
||||
{"name": "Manual DE", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_de.pdf"},
|
||||
{"name": "Manual EN", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_en.pdf"},
|
||||
{"name": "Schematic", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/ibom.html"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": -1,
|
||||
"mosi": -1,
|
||||
"clk": -1,
|
||||
"irq": -1,
|
||||
"en": -1,
|
||||
"cs": -1
|
||||
},
|
||||
"cmt": {
|
||||
"clk": 18,
|
||||
"cs": 4,
|
||||
"fcs": 5,
|
||||
"sdio": 23,
|
||||
"gpio2": 19,
|
||||
"gpio3": 16
|
||||
},
|
||||
"display": {
|
||||
"type": 3,
|
||||
"data": 21,
|
||||
"clk": 22
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "NRF, LEDs",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://shop.blinkyparts.com/de/OpenDTU-NRF-Deine-Auswertung-fuer-deine-Balkonsolaranlage-kompatibel-zu-Hoymiles-HM-Serie-NRF-Modul/blink237542"},
|
||||
{"name": "Manual DE", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_de.pdf"},
|
||||
{"name": "Manual EN", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_en.pdf"},
|
||||
{"name": "Schematic", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/ibom.html"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 19,
|
||||
"mosi": 23,
|
||||
@ -51,7 +133,42 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "No Output",
|
||||
"name": "CMT, LEDs",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://shop.blinkyparts.com/de/OpenDTU-CMT-Deine-Auswertung-fuer-deine-Balkonsolaranlage-kompatibel-zu-Hoymiles-HMS-und-HMT-Serie-CMT-Modul/blink238342"},
|
||||
{"name": "Manual DE", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_de.pdf"},
|
||||
{"name": "Manual EN", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_en.pdf"},
|
||||
{"name": "Schematic", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/ibom.html"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": -1,
|
||||
"mosi": -1,
|
||||
"clk": -1,
|
||||
"irq": -1,
|
||||
"en": -1,
|
||||
"cs": -1
|
||||
},
|
||||
"cmt": {
|
||||
"clk": 18,
|
||||
"cs": 4,
|
||||
"fcs": 5,
|
||||
"sdio": 23,
|
||||
"gpio2": 19,
|
||||
"gpio3": 16
|
||||
},
|
||||
"led": {
|
||||
"led0": 25,
|
||||
"led1": 26
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "NRF",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://shop.blinkyparts.com/de/OpenDTU-NRF-Deine-Auswertung-fuer-deine-Balkonsolaranlage-kompatibel-zu-Hoymiles-HM-Serie-NRF-Modul/blink237542"},
|
||||
{"name": "Manual DE", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_de.pdf"},
|
||||
{"name": "Manual EN", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_en.pdf"},
|
||||
{"name": "Schematic", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/ibom.html"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 19,
|
||||
"mosi": 23,
|
||||
@ -60,5 +177,30 @@
|
||||
"en": 4,
|
||||
"cs": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "CMT",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://shop.blinkyparts.com/de/OpenDTU-CMT-Deine-Auswertung-fuer-deine-Balkonsolaranlage-kompatibel-zu-Hoymiles-HMS-und-HMT-Serie-CMT-Modul/blink238342"},
|
||||
{"name": "Manual DE", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_de.pdf"},
|
||||
{"name": "Manual EN", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/manual/OpenDTU_Breakout_en.pdf"},
|
||||
{"name": "Schematic", "url": "https://binary-kitchen.github.io/SolderingTutorial/OpenDTU_Breakout/ibom.html"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": -1,
|
||||
"mosi": -1,
|
||||
"clk": -1,
|
||||
"irq": -1,
|
||||
"en": -1,
|
||||
"cs": -1
|
||||
},
|
||||
"cmt": {
|
||||
"clk": 18,
|
||||
"cs": 4,
|
||||
"fcs": 5,
|
||||
"sdio": 23,
|
||||
"gpio2": 19,
|
||||
"gpio3": 16
|
||||
}
|
||||
}
|
||||
]
|
||||
25
docs/DeviceProfiles/esp32_stick_poe_a.json
Normal file
25
docs/DeviceProfiles/esp32_stick_poe_a.json
Normal file
@ -0,0 +1,25 @@
|
||||
[
|
||||
{
|
||||
"name": "Esp32-Stick-PoE-A",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://github.com/allexoK/Esp32-Stick-Boards-Docs"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 2,
|
||||
"mosi": 15,
|
||||
"clk": 14,
|
||||
"irq": 34,
|
||||
"en": 12,
|
||||
"cs": 4
|
||||
},
|
||||
"eth": {
|
||||
"enabled": true,
|
||||
"phy_addr": 1,
|
||||
"power": -1,
|
||||
"mdc": 23,
|
||||
"mdio": 18,
|
||||
"type": 0,
|
||||
"clk_mode": 3
|
||||
}
|
||||
}
|
||||
]
|
||||
74
docs/DeviceProfiles/liligo_t-eth-lite_poe.json
Normal file
74
docs/DeviceProfiles/liligo_t-eth-lite_poe.json
Normal file
@ -0,0 +1,74 @@
|
||||
[
|
||||
{
|
||||
"name": "LILYGO T-ETH-Lite-POE CMT",
|
||||
"links": [
|
||||
{"name": "Datasheet", "url": "https://www.lilygo.cc/products/t-eth-lite"}
|
||||
],
|
||||
"eth": {
|
||||
"enabled": true,
|
||||
"phy_addr": 0,
|
||||
"power": 12,
|
||||
"mdc": 23,
|
||||
"mdio": 18,
|
||||
"type": 2,
|
||||
"clk_mode": 0
|
||||
},
|
||||
"cmt": {
|
||||
"clk": 15,
|
||||
"cs": 32,
|
||||
"fcs": 33,
|
||||
"sdio": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "LILYGO T-ETH-Lite-POE NRF24",
|
||||
"links": [
|
||||
{"name": "Datasheet", "url": "https://www.lilygo.cc/products/t-eth-lite"}
|
||||
],
|
||||
"eth": {
|
||||
"enabled": true,
|
||||
"phy_addr": 0,
|
||||
"power": 12,
|
||||
"mdc": 23,
|
||||
"mdio": 18,
|
||||
"type": 2,
|
||||
"clk_mode": 0
|
||||
},
|
||||
"nrf24": {
|
||||
"miso": 34,
|
||||
"mosi": 13,
|
||||
"clk": 14,
|
||||
"irq": 35,
|
||||
"en": 4,
|
||||
"cs": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "LILYGO T-ETH-Lite-POE NRF24 + Display",
|
||||
"links": [
|
||||
{"name": "Datasheet", "url": "https://www.lilygo.cc/products/t-eth-lite"}
|
||||
],
|
||||
"eth": {
|
||||
"enabled": true,
|
||||
"phy_addr": 0,
|
||||
"power": 12,
|
||||
"mdc": 23,
|
||||
"mdio": 18,
|
||||
"type": 2,
|
||||
"clk_mode": 0
|
||||
},
|
||||
"nrf24": {
|
||||
"miso": 34,
|
||||
"mosi": 13,
|
||||
"clk": 14,
|
||||
"irq": 35,
|
||||
"en": 4,
|
||||
"cs": 2
|
||||
},
|
||||
"display": {
|
||||
"type": 3,
|
||||
"data": 32,
|
||||
"clk": 33
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -1,6 +1,9 @@
|
||||
[
|
||||
{
|
||||
"name": "LILYGO TTGO T-Internet-POE",
|
||||
"links": [
|
||||
{"name": "Datasheet", "url": "https://www.lilygo.cc/products/t-internet-poe"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 2,
|
||||
"mosi": 15,
|
||||
@ -18,5 +21,56 @@
|
||||
"type": 0,
|
||||
"clk_mode": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "LILYGO TTGO T-Internet-POE, nrf24 direct solder",
|
||||
"links": [
|
||||
{"name": "Datasheet", "url": "https://www.lilygo.cc/products/t-internet-poe"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 12,
|
||||
"mosi": 4,
|
||||
"clk": 15,
|
||||
"irq": 33,
|
||||
"en": 14,
|
||||
"cs": 2
|
||||
},
|
||||
"eth": {
|
||||
"enabled": true,
|
||||
"phy_addr": 0,
|
||||
"power": -1,
|
||||
"mdc": 23,
|
||||
"mdio": 18,
|
||||
"type": 0,
|
||||
"clk_mode": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "LILYGO TTGO T-Internet-POE, nrf24 direct solder, SSD1306",
|
||||
"links": [
|
||||
{"name": "Datasheet", "url": "https://www.lilygo.cc/products/t-internet-poe"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 12,
|
||||
"mosi": 4,
|
||||
"clk": 15,
|
||||
"irq": 33,
|
||||
"en": 14,
|
||||
"cs": 2
|
||||
},
|
||||
"eth": {
|
||||
"enabled": true,
|
||||
"phy_addr": 0,
|
||||
"power": -1,
|
||||
"mdc": 23,
|
||||
"mdio": 18,
|
||||
"type": 0,
|
||||
"clk_mode": 3
|
||||
},
|
||||
"display": {
|
||||
"type": 2,
|
||||
"data": 16,
|
||||
"clk": 32
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"name": "Generic NodeMCU 32",
|
||||
"name": "NRF24",
|
||||
"nrf24": {
|
||||
"miso": 19,
|
||||
"mosi": 23,
|
||||
@ -10,17 +10,33 @@
|
||||
"cs": 5
|
||||
},
|
||||
"eth": {
|
||||
"enabled": false,
|
||||
"phy_addr": -1,
|
||||
"power": -1,
|
||||
"mdc": -1,
|
||||
"mdio": -1,
|
||||
"type": 0,
|
||||
"clk_mode": 0
|
||||
"enabled": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Generic NodeMCU 32 with SSD1306",
|
||||
"name": "CMT2300A",
|
||||
"nrf24": {
|
||||
"miso": -1,
|
||||
"mosi": -1,
|
||||
"clk": -1,
|
||||
"irq": -1,
|
||||
"en": -1,
|
||||
"cs": -1
|
||||
},
|
||||
"cmt": {
|
||||
"clk": 18,
|
||||
"cs": 4,
|
||||
"fcs": 5,
|
||||
"sdio": 23,
|
||||
"gpio2": 19,
|
||||
"gpio3": 16
|
||||
},
|
||||
"eth": {
|
||||
"enabled": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "NRF24 with SSD1306",
|
||||
"nrf24": {
|
||||
"miso": 19,
|
||||
"mosi": 23,
|
||||
@ -30,13 +46,7 @@
|
||||
"cs": 5
|
||||
},
|
||||
"eth": {
|
||||
"enabled": false,
|
||||
"phy_addr": -1,
|
||||
"power": -1,
|
||||
"mdc": -1,
|
||||
"mdio": -1,
|
||||
"type": 0,
|
||||
"clk_mode": 0
|
||||
"enabled": false
|
||||
},
|
||||
"display": {
|
||||
"type": 2,
|
||||
@ -45,7 +55,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Generic NodeMCU 32 with SH1106",
|
||||
"name": "NRF24 with SH1106",
|
||||
"nrf24": {
|
||||
"miso": 19,
|
||||
"mosi": 23,
|
||||
@ -55,18 +65,131 @@
|
||||
"cs": 5
|
||||
},
|
||||
"eth": {
|
||||
"enabled": false,
|
||||
"phy_addr": -1,
|
||||
"power": -1,
|
||||
"mdc": -1,
|
||||
"mdio": -1,
|
||||
"type": 0,
|
||||
"clk_mode": 0
|
||||
"enabled": false
|
||||
},
|
||||
"display": {
|
||||
"type": 3,
|
||||
"data": 21,
|
||||
"clk": 22
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "NRF24 with SSD1309",
|
||||
"nrf24": {
|
||||
"miso": 19,
|
||||
"mosi": 23,
|
||||
"clk": 18,
|
||||
"irq": 16,
|
||||
"en": 4,
|
||||
"cs": 5
|
||||
},
|
||||
"eth": {
|
||||
"enabled": false
|
||||
},
|
||||
"display": {
|
||||
"type": 4,
|
||||
"data": 21,
|
||||
"clk": 22
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "CMT2300A with SSD1306",
|
||||
"nrf24": {
|
||||
"miso": -1,
|
||||
"mosi": -1,
|
||||
"clk": -1,
|
||||
"irq": -1,
|
||||
"en": -1,
|
||||
"cs": -1
|
||||
},
|
||||
"cmt": {
|
||||
"clk": 18,
|
||||
"cs": 4,
|
||||
"fcs": 5,
|
||||
"sdio": 23,
|
||||
"gpio2": 19,
|
||||
"gpio3": 16
|
||||
},
|
||||
"eth": {
|
||||
"enabled": false
|
||||
},
|
||||
"display": {
|
||||
"type": 2,
|
||||
"data": 21,
|
||||
"clk": 22
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "CMT2300A with SH1106",
|
||||
"nrf24": {
|
||||
"miso": -1,
|
||||
"mosi": -1,
|
||||
"clk": -1,
|
||||
"irq": -1,
|
||||
"en": -1,
|
||||
"cs": -1
|
||||
},
|
||||
"cmt": {
|
||||
"clk": 18,
|
||||
"cs": 4,
|
||||
"fcs": 5,
|
||||
"sdio": 23,
|
||||
"gpio2": 19,
|
||||
"gpio3": 16
|
||||
},
|
||||
"eth": {
|
||||
"enabled": false
|
||||
},
|
||||
"display": {
|
||||
"type": 3,
|
||||
"data": 21,
|
||||
"clk": 22
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "CMT2300A with SSD1309",
|
||||
"nrf24": {
|
||||
"miso": -1,
|
||||
"mosi": -1,
|
||||
"clk": -1,
|
||||
"irq": -1,
|
||||
"en": -1,
|
||||
"cs": -1
|
||||
},
|
||||
"cmt": {
|
||||
"clk": 18,
|
||||
"cs": 4,
|
||||
"fcs": 5,
|
||||
"sdio": 23,
|
||||
"gpio2": 19,
|
||||
"gpio3": 16
|
||||
},
|
||||
"eth": {
|
||||
"enabled": false
|
||||
},
|
||||
"display": {
|
||||
"type": 4,
|
||||
"data": 21,
|
||||
"clk": 22
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "NRF24 + CMT2300A",
|
||||
"nrf24": {
|
||||
"miso": 19,
|
||||
"mosi": 23,
|
||||
"clk": 18,
|
||||
"irq": 16,
|
||||
"en": 4,
|
||||
"cs": 5
|
||||
},
|
||||
"cmt": {
|
||||
"clk": 12,
|
||||
"sdio": 14,
|
||||
"cs": 27,
|
||||
"fcs": 26,
|
||||
"gpio2": -1,
|
||||
"gpio3": -1
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -1,6 +1,9 @@
|
||||
[
|
||||
{
|
||||
"name": "Olimex ESP32-EVB",
|
||||
"links": [
|
||||
{ "name": "Datasheet", "url": "https://www.olimex.com/Products/IoT/ESP32/ESP32-EVB/open-source-hardware" }
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 15,
|
||||
"mosi": 2,
|
||||
|
||||
47
docs/DeviceProfiles/olimex_esp32_gateway.json
Normal file
47
docs/DeviceProfiles/olimex_esp32_gateway.json
Normal file
@ -0,0 +1,47 @@
|
||||
[
|
||||
{
|
||||
"name": "Olimex ESP32-Gateway",
|
||||
"nrf24": {
|
||||
"miso": 14,
|
||||
"mosi": 13,
|
||||
"clk": 12,
|
||||
"irq": 15,
|
||||
"en": 2,
|
||||
"cs": 4
|
||||
},
|
||||
"eth": {
|
||||
"enabled": true,
|
||||
"phy_addr": 0,
|
||||
"power": 12,
|
||||
"mdc": 23,
|
||||
"mdio": 18,
|
||||
"type": 0,
|
||||
"clk_mode": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Olimex ESP32-Gateway with SSH1106",
|
||||
"nrf24": {
|
||||
"miso": 14,
|
||||
"mosi": 13,
|
||||
"clk": 12,
|
||||
"irq": 15,
|
||||
"en": 2,
|
||||
"cs": 4
|
||||
},
|
||||
"eth": {
|
||||
"enabled": true,
|
||||
"phy_addr": 0,
|
||||
"power": 12,
|
||||
"mdc": 23,
|
||||
"mdio": 18,
|
||||
"type": 0,
|
||||
"clk_mode": 3
|
||||
},
|
||||
"display": {
|
||||
"type": 3,
|
||||
"data": 32,
|
||||
"clk": 16
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -1,6 +1,9 @@
|
||||
[
|
||||
{
|
||||
"name": "Olimex ESP32-POE",
|
||||
"links": [
|
||||
{"name": "Datasheet", "url": "https://www.olimex.com/Products/IoT/ESP32/ESP32-POE/open-source-hardware"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 15,
|
||||
"mosi": 2,
|
||||
@ -21,6 +24,9 @@
|
||||
},
|
||||
{
|
||||
"name": "Olimex ESP32-POE with SSD1306",
|
||||
"links": [
|
||||
{"name": "Datasheet", "url": "https://www.olimex.com/Products/IoT/ESP32/ESP32-POE/open-source-hardware"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 15,
|
||||
"mosi": 2,
|
||||
@ -46,6 +52,9 @@
|
||||
},
|
||||
{
|
||||
"name": "Olimex ESP32-POE with SH1106",
|
||||
"links": [
|
||||
{"name": "Datasheet", "url": "https://www.olimex.com/Products/IoT/ESP32/ESP32-POE/open-source-hardware"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 15,
|
||||
"mosi": 2,
|
||||
@ -64,7 +73,35 @@
|
||||
"clk_mode": 3
|
||||
},
|
||||
"display": {
|
||||
"type": 2,
|
||||
"type": 3,
|
||||
"data": 33,
|
||||
"clk": 32
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Olimex ESP32-POE with SSD1309",
|
||||
"links": [
|
||||
{"name": "Datasheet", "url": "https://www.olimex.com/Products/IoT/ESP32/ESP32-POE/open-source-hardware"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 15,
|
||||
"mosi": 2,
|
||||
"clk": 14,
|
||||
"irq": 13,
|
||||
"en": 16,
|
||||
"cs": 5
|
||||
},
|
||||
"eth": {
|
||||
"enabled": true,
|
||||
"phy_addr": 0,
|
||||
"power": 12,
|
||||
"mdc": 23,
|
||||
"mdio": 18,
|
||||
"type": 0,
|
||||
"clk_mode": 3
|
||||
},
|
||||
"display": {
|
||||
"type": 4,
|
||||
"data": 33,
|
||||
"clk": 32
|
||||
}
|
||||
|
||||
325
docs/DeviceProfiles/opendtu_fusion.json
Normal file
325
docs/DeviceProfiles/opendtu_fusion.json
Normal file
@ -0,0 +1,325 @@
|
||||
[
|
||||
{
|
||||
"name": "OpenDTU Fusion v1",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://github.com/markusdd/OpenDTUFusionDocs"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 48,
|
||||
"mosi": 35,
|
||||
"clk": 36,
|
||||
"irq": 47,
|
||||
"en": 38,
|
||||
"cs": 37
|
||||
},
|
||||
"eth": {
|
||||
"enabled": false,
|
||||
"phy_addr": -1,
|
||||
"power": -1,
|
||||
"mdc": -1,
|
||||
"mdio": -1,
|
||||
"type": 0,
|
||||
"clk_mode": 0
|
||||
},
|
||||
"led": {
|
||||
"led0": 17,
|
||||
"led1": 18
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OpenDTU Fusion v1 with SSD1306 Display",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://github.com/markusdd/OpenDTUFusionDocs"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 48,
|
||||
"mosi": 35,
|
||||
"clk": 36,
|
||||
"irq": 47,
|
||||
"en": 38,
|
||||
"cs": 37
|
||||
},
|
||||
"eth": {
|
||||
"enabled": false,
|
||||
"phy_addr": -1,
|
||||
"power": -1,
|
||||
"mdc": -1,
|
||||
"mdio": -1,
|
||||
"type": 0,
|
||||
"clk_mode": 0
|
||||
},
|
||||
"led": {
|
||||
"led0": 17,
|
||||
"led1": 18
|
||||
},
|
||||
"display": {
|
||||
"type": 2,
|
||||
"data": 2,
|
||||
"clk": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OpenDTU Fusion v1 with SH1106 Display",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://github.com/markusdd/OpenDTUFusionDocs"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 48,
|
||||
"mosi": 35,
|
||||
"clk": 36,
|
||||
"irq": 47,
|
||||
"en": 38,
|
||||
"cs": 37
|
||||
},
|
||||
"eth": {
|
||||
"enabled": false,
|
||||
"phy_addr": -1,
|
||||
"power": -1,
|
||||
"mdc": -1,
|
||||
"mdio": -1,
|
||||
"type": 0,
|
||||
"clk_mode": 0
|
||||
},
|
||||
"led": {
|
||||
"led0": 17,
|
||||
"led1": 18
|
||||
},
|
||||
"display": {
|
||||
"type": 3,
|
||||
"data": 2,
|
||||
"clk": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OpenDTU Fusion v2 with CMT2300A and NRF24",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://github.com/markusdd/OpenDTUFusionDocs"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 48,
|
||||
"mosi": 35,
|
||||
"clk": 36,
|
||||
"irq": 47,
|
||||
"en": 38,
|
||||
"cs": 37
|
||||
},
|
||||
"cmt": {
|
||||
"clk": 6,
|
||||
"cs": 4,
|
||||
"fcs": 21,
|
||||
"sdio": 5,
|
||||
"gpio2": 3,
|
||||
"gpio3": 8
|
||||
},
|
||||
"eth": {
|
||||
"enabled": false,
|
||||
"phy_addr": -1,
|
||||
"power": -1,
|
||||
"mdc": -1,
|
||||
"mdio": -1,
|
||||
"type": 0,
|
||||
"clk_mode": 0
|
||||
},
|
||||
"led": {
|
||||
"led0": 17,
|
||||
"led1": 18
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OpenDTU Fusion v2 with CMT2300A, NRF24 and SH1106 Display",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://github.com/markusdd/OpenDTUFusionDocs"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 48,
|
||||
"mosi": 35,
|
||||
"clk": 36,
|
||||
"irq": 47,
|
||||
"en": 38,
|
||||
"cs": 37
|
||||
},
|
||||
"cmt": {
|
||||
"clk": 6,
|
||||
"cs": 4,
|
||||
"fcs": 21,
|
||||
"sdio": 5,
|
||||
"gpio2": 3,
|
||||
"gpio3": 8
|
||||
},
|
||||
"eth": {
|
||||
"enabled": false,
|
||||
"phy_addr": -1,
|
||||
"power": -1,
|
||||
"mdc": -1,
|
||||
"mdio": -1,
|
||||
"type": 0,
|
||||
"clk_mode": 0
|
||||
},
|
||||
"led": {
|
||||
"led0": 17,
|
||||
"led1": 18
|
||||
},
|
||||
"display": {
|
||||
"type": 3,
|
||||
"data": 2,
|
||||
"clk": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OpenDTU Fusion v2 with CMT2300A, NRF24 and SSD1306 Display",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://github.com/markusdd/OpenDTUFusionDocs"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 48,
|
||||
"mosi": 35,
|
||||
"clk": 36,
|
||||
"irq": 47,
|
||||
"en": 38,
|
||||
"cs": 37
|
||||
},
|
||||
"cmt": {
|
||||
"clk": 6,
|
||||
"cs": 4,
|
||||
"fcs": 21,
|
||||
"sdio": 5,
|
||||
"gpio2": 3,
|
||||
"gpio3": 8
|
||||
},
|
||||
"eth": {
|
||||
"enabled": false,
|
||||
"phy_addr": -1,
|
||||
"power": -1,
|
||||
"mdc": -1,
|
||||
"mdio": -1,
|
||||
"type": 0,
|
||||
"clk_mode": 0
|
||||
},
|
||||
"led": {
|
||||
"led0": 17,
|
||||
"led1": 18
|
||||
},
|
||||
"display": {
|
||||
"type": 2,
|
||||
"data": 2,
|
||||
"clk": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OpenDTU Fusion v2 PoE",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://github.com/markusdd/OpenDTUFusionDocs"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 48,
|
||||
"mosi": 35,
|
||||
"clk": 36,
|
||||
"irq": 47,
|
||||
"en": 38,
|
||||
"cs": 37
|
||||
},
|
||||
"cmt": {
|
||||
"clk": 6,
|
||||
"cs": 4,
|
||||
"fcs": 21,
|
||||
"sdio": 5,
|
||||
"gpio2": 3,
|
||||
"gpio3": 8
|
||||
},
|
||||
"w5500": {
|
||||
"mosi": 40,
|
||||
"miso": 41,
|
||||
"sclk": 39,
|
||||
"cs": 42,
|
||||
"int": 44,
|
||||
"rst": 43
|
||||
},
|
||||
"led": {
|
||||
"led0": 17,
|
||||
"led1": 18
|
||||
},
|
||||
"display": {
|
||||
"type": 0,
|
||||
"data": 2,
|
||||
"clk": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OpenDTU Fusion v2 PoE with SH1106 Display",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://github.com/markusdd/OpenDTUFusionDocs"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 48,
|
||||
"mosi": 35,
|
||||
"clk": 36,
|
||||
"irq": 47,
|
||||
"en": 38,
|
||||
"cs": 37
|
||||
},
|
||||
"cmt": {
|
||||
"clk": 6,
|
||||
"cs": 4,
|
||||
"fcs": 21,
|
||||
"sdio": 5,
|
||||
"gpio2": 3,
|
||||
"gpio3": 8
|
||||
},
|
||||
"w5500": {
|
||||
"mosi": 40,
|
||||
"miso": 41,
|
||||
"sclk": 39,
|
||||
"cs": 42,
|
||||
"int": 44,
|
||||
"rst": 43
|
||||
},
|
||||
"led": {
|
||||
"led0": 17,
|
||||
"led1": 18
|
||||
},
|
||||
"display": {
|
||||
"type": 3,
|
||||
"data": 2,
|
||||
"clk": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OpenDTU Fusion v2 PoE with SSD1306 Display",
|
||||
"links": [
|
||||
{"name": "Information", "url": "https://github.com/markusdd/OpenDTUFusionDocs"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 48,
|
||||
"mosi": 35,
|
||||
"clk": 36,
|
||||
"irq": 47,
|
||||
"en": 38,
|
||||
"cs": 37
|
||||
},
|
||||
"cmt": {
|
||||
"clk": 6,
|
||||
"cs": 4,
|
||||
"fcs": 21,
|
||||
"sdio": 5,
|
||||
"gpio2": 3,
|
||||
"gpio3": 8
|
||||
},
|
||||
"w5500": {
|
||||
"mosi": 40,
|
||||
"miso": 41,
|
||||
"sclk": 39,
|
||||
"cs": 42,
|
||||
"int": 44,
|
||||
"rst": 43
|
||||
},
|
||||
"led": {
|
||||
"led0": 17,
|
||||
"led1": 18
|
||||
},
|
||||
"display": {
|
||||
"type": 2,
|
||||
"data": 2,
|
||||
"clk": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
21
docs/DeviceProfiles/wemos-lolin32-oled.json
Normal file
21
docs/DeviceProfiles/wemos-lolin32-oled.json
Normal file
@ -0,0 +1,21 @@
|
||||
[
|
||||
{
|
||||
"name": "Wemos Lolin32 OLED",
|
||||
"nrf24": {
|
||||
"miso": 2,
|
||||
"mosi": 14,
|
||||
"clk": 12,
|
||||
"irq": 0,
|
||||
"en": 15,
|
||||
"cs": 13
|
||||
},
|
||||
"eth": {
|
||||
"enabled": false
|
||||
},
|
||||
"display": {
|
||||
"type": 2,
|
||||
"data": 5,
|
||||
"clk": 4
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -1,6 +1,9 @@
|
||||
[
|
||||
{
|
||||
"name": "WT32-ETH01",
|
||||
"links": [
|
||||
{"name": "Datasheet", "url": "http://www.wireless-tag.com/portfolio/wt32-eth01/"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 4,
|
||||
"mosi": 2,
|
||||
@ -18,5 +21,89 @@
|
||||
"type": 0,
|
||||
"clk_mode": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "WT32-ETH01 with SH1106",
|
||||
"links": [
|
||||
{"name": "Datasheet", "url": "http://www.wireless-tag.com/portfolio/wt32-eth01/"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 4,
|
||||
"mosi": 2,
|
||||
"clk": 32,
|
||||
"irq": 33,
|
||||
"en": 14,
|
||||
"cs": 15
|
||||
},
|
||||
"eth": {
|
||||
"enabled": true,
|
||||
"phy_addr": 1,
|
||||
"power": 16,
|
||||
"mdc": 23,
|
||||
"mdio": 18,
|
||||
"type": 0,
|
||||
"clk_mode": 0
|
||||
},
|
||||
"display": {
|
||||
"type": 3,
|
||||
"data": 5,
|
||||
"clk": 17
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "WT32-ETH01 with SSD1306",
|
||||
"links": [
|
||||
{"name": "Datasheet", "url": "http://www.wireless-tag.com/portfolio/wt32-eth01/"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 4,
|
||||
"mosi": 2,
|
||||
"clk": 32,
|
||||
"irq": 33,
|
||||
"en": 14,
|
||||
"cs": 15
|
||||
},
|
||||
"eth": {
|
||||
"enabled": true,
|
||||
"phy_addr": 1,
|
||||
"power": 16,
|
||||
"mdc": 23,
|
||||
"mdio": 18,
|
||||
"type": 0,
|
||||
"clk_mode": 0
|
||||
},
|
||||
"display": {
|
||||
"type": 2,
|
||||
"data": 5,
|
||||
"clk": 17
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "WT32-ETH01 with SSD1309",
|
||||
"links": [
|
||||
{"name": "Datasheet", "url": "http://www.wireless-tag.com/portfolio/wt32-eth01/"}
|
||||
],
|
||||
"nrf24": {
|
||||
"miso": 4,
|
||||
"mosi": 2,
|
||||
"clk": 32,
|
||||
"irq": 33,
|
||||
"en": 14,
|
||||
"cs": 15
|
||||
},
|
||||
"eth": {
|
||||
"enabled": true,
|
||||
"phy_addr": 1,
|
||||
"power": 16,
|
||||
"mdc": 23,
|
||||
"mdio": 18,
|
||||
"type": 0,
|
||||
"clk_mode": 0
|
||||
},
|
||||
"display": {
|
||||
"type": 4,
|
||||
"data": 5,
|
||||
"clk": 17
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@ -1,20 +1,3 @@
|
||||
# Display integration
|
||||
|
||||
OpenDTU currently supports 3 types of displays (SSD1306, SH1106 and PCD8544). Currently only displays with a resolution of 128x64 pixel are supported. To activate a display you have to specify it's type and pin assignment either in the `platformio_override.ini` or in a device profile. Due to the fact that device profiles work with the pre-compiled binary the following documentation will only cover the device profile method.
|
||||
|
||||
You can either create your own device profile as described [here](DeviceProfiles.md) or use some pre-defined. The pre-defined profiles can be found [here](DeviceProfiles/). You can simply open the json file with a text editor of your choice to view/edit the pin assignment.
|
||||
|
||||
## Uploading Device Profiles
|
||||
|
||||
Use the "Config Management" site to upload (Restore) the json file. Make sure to choose "Pin Mapping (pin_mapping.json)" in the combo box. After you click on restore the ESP will restart. At this point, the profile is not yet active. Please read the next chapter.
|
||||

|
||||
|
||||
## Selecting a Device Profile
|
||||
|
||||
After you uploaded the device profile you can select the profile in the "Device Manager" view. After a click on "Save" the ESP will be restarted and the pin assignment is active. At this point the display should already show something. Please see the next chapter for display settings.
|
||||

|
||||
|
||||
## Display Settings
|
||||
|
||||
Display settings can also be found in the "Device Manager".
|
||||

|
||||
This documentation will has been moved and can be found here: <https://tbnobody.github.io/OpenDTU-docs/hardware/display/>
|
||||
|
||||
@ -1,74 +1,3 @@
|
||||
# MQTT Topics
|
||||
|
||||
The base topic, as configured in the web GUI is prepended to all follwing topics.
|
||||
|
||||
## General topics
|
||||
|
||||
| Topic | R / W | Description | Value / Unit |
|
||||
| --------------------------------------- | ----- | ---------------------------------------------------- | -------------------------- |
|
||||
| dtu/ip | R | IP address of OpenDTU | IP address |
|
||||
| dtu/hostname | R | Current hostname of the dtu (as set in web GUI) | |
|
||||
| dtu/rssi | R | WiFi network quality | db value |
|
||||
| dtu/status | R | Indicates whether OpenDTU network is reachable | online / offline |
|
||||
| dtu/uptime | R | Time in seconds since startup | seconds |
|
||||
|
||||
## Inverter specific topics
|
||||
|
||||
serial will be replaced with the serial number of the inverter.
|
||||
|
||||
| Topic | R / W | Description | Value / Unit |
|
||||
| --------------------------------------- | ----- | ---------------------------------------------------- | -------------------------- |
|
||||
| [serial]/name | R | Name of the inverter as configured in web GUI | |
|
||||
| [serial]/device/bootloaderversion | R | Bootloader version of the inverter | |
|
||||
| [serial]/device/fwbuildversion | R | Firmware version of the inverter | |
|
||||
| [serial]/device/fwbuilddatetime | R | Build date / time of inverter firmware | |
|
||||
| [serial]/device/hwpartnumber | R | Hardware part number of the inverter | |
|
||||
| [serial]/device/hwversion | R | Hardware version of the inverter | |
|
||||
| [serial]/status/reachable | R | Indicates whether the inverter is reachable | 0 or 1 |
|
||||
| [serial]/status/producing | R | Indicates whether the inverter is producing AC power | 0 or 1 |
|
||||
| [serial]/status/last_update | R | Unix timestamp of last inverter statistics udpate | seconds since JAN 01 1970 (UTC) |
|
||||
|
||||
### AC channel / global specific topics
|
||||
|
||||
| Topic | R / W | Description | Value / Unit |
|
||||
| --------------------------------------- | ----- | ---------------------------------------------------- | -------------------------- |
|
||||
| [serial]/0/current | R | AC current in ampere | Ampere (A) |
|
||||
| [serial]/0/efficiency | R | Ratio AC Power over DC Power in percent | % |
|
||||
| [serial]/0/frequency | R | AC frequency in hertz | Hertz (Hz) |
|
||||
| [serial]/0/power | R | AC active power in watts | Watt (W) |
|
||||
| [serial]/0/powerdc | R | DC power in watts | Watt (W) |
|
||||
| [serial]/0/powerfactor | R | Power factor in percent | % |
|
||||
| [serial]/0/reactivepower | R | AC reactive power in VAr | VAr |
|
||||
| [serial]/0/temperature | R | Temperature of inverter in degree celsius | Degree Celsius (°C) |
|
||||
| [serial]/0/voltage | R | AC voltage in volt | Volt (V) |
|
||||
| [serial]/0/yieldday | R | Energy converted to AC per day in watt hours | Watt hours (Wh) |
|
||||
| [serial]/0/yieldtotal | R | Energy converted to AC since reset watt hours | Kilo watt hours (kWh) |
|
||||
|
||||
### DC input channel topics
|
||||
|
||||
[1-4] represents the different inputs. The amount depends on the inverter model.
|
||||
|
||||
| Topic | R / W | Description | Value / Unit |
|
||||
| --------------------------------------- | ----- | ---------------------------------------------------- | -------------------------- |
|
||||
| [serial]/[1-4]/current | R | DC current of specific input in ampere | Ampere (A) |
|
||||
| [serial]/[1-4]/name | R | Name of the DC input channel as configured in web GUI| |
|
||||
| [serial]/[1-4]/irradiation | R | Ratio DC Power over set maximum power (in web GUI) | % |
|
||||
| [serial]/[1-4]/power | R | DC power of specific input in watt | Watt (W) |
|
||||
| [serial]/[1-4]/voltage | R | DC voltage of specific input in volt | Volt (V) |
|
||||
| [serial]/[1-4]/yieldday | R | Energy converted to AC per day on specific input | Watt hours (Wh) |
|
||||
| [serial]/[1-4]/yieldtotal | R | Energy converted to AC since reset on specific input | Kilo watt hours (kWh) |
|
||||
|
||||
### Inverter limit specific topics
|
||||
|
||||
cmd topics are used to set values. Status topics are updated from values set in the inverter.
|
||||
|
||||
| Topic | R / W | Description | Value / Unit |
|
||||
| ----------------------------------------- | ----- | ---------------------------------------------------- | -------------------------- |
|
||||
| [serial]/status/limit_relative | R | Current applied production limit of the inverter | % of total possible output |
|
||||
| [serial]/status/limit_absolute | R | Current applied production limit of the inverter | Watt (W) |
|
||||
| [serial]/cmd/limit_persistent_relative | W | Set the inverter limit as a percentage of total production capability. The value will survive the night without power. The updated value will show up in the web GUI and limit_relative topic immediatly. | % |
|
||||
| [serial]/cmd/limit_persistent_absolute | W | Set the inverter limit as a absolute value. The value will survive the night without power. The updated value will set immediatly within the inverter but show up in the web GUI and limit_relative topic after around 4 minutes. If you are using a already known inverter (known Hardware ID), the updated value will show up within a few seconds. | Watt (W) |
|
||||
| [serial]/cmd/limit_nonpersistent_relative | W | Set the inverter limit as a percentage of total production capability. The value will reset to the last persistent value at night without power. The updated value will show up in the web GUI and limit_relative topic immediatly. The value must be published non-retained, otherwise it will be ignored! | % |
|
||||
| [serial]/cmd/limit_nonpersistent_absolute | W | Set the inverter limit as a absolute value. The value will reset to the last persistent value at night without power. The updated value will set immediatly within the inverter but show up in the web GUI and limit_relative topic after around 4 minutes. If you are using a already known inverter (known Hardware ID), the updated value will show up within a few seconds. The value must be published non-retained, otherwise it will be ignored! | Watt (W) |
|
||||
| [serial]/cmd/power | W | Turn the inverter on (1) or off (0) | 0 or 1 |
|
||||
| [serial]/cmd/restart | W | Restarts the inverters (also resets YieldDay) | 1 |
|
||||
This documentation will has been moved and can be found here: <https://tbnobody.github.io/OpenDTU-docs/firmware/mqtt_topics/>
|
||||
|
||||
@ -1,24 +1,3 @@
|
||||
# Upgrade Partition
|
||||
|
||||
To be able to install further updates you have to update the partition table of the ESP32. Doing so will **erase** all configuration data. Over The Air update using the web interface is **NOT** possible!
|
||||
|
||||
**So make sure you export a backup of your configuration files before continuing.**
|
||||
|
||||
There are several possibilities to update the partition table:
|
||||
|
||||
- Using Visual Studio Code or PlatformIO CLI
|
||||
|
||||
If you have already used Visual Studio Code or the `platformio` command you can use it again to install the latest version. The partition table is upgraded automatically.
|
||||
|
||||
- Any kind of flash interface
|
||||
|
||||
If you like to use any kind of flash interface like `esptool.py`, Espressif Flash Download Tool, ESP_Flasher or esptool-js you have to make sure to upload **ALL** provided .bin files. It is important to enter the correct target addresses.
|
||||
|
||||
| Address | File |
|
||||
| ---------| ---------------------- |
|
||||
| 0x1000 | bootloader.bin |
|
||||
| 0x8000 | partitions.bin |
|
||||
| 0xe000 | boot_app0.bin |
|
||||
| 0x10000 | opendtu-*.bin |
|
||||
|
||||
After upgrading the ESP32 will open the intergrated access point (AP) again. Just connect to it using the default password ("openDTU42"). If you are connected, just visit <http://192.168.4.1> and enter the "Configuration Management". Recover the previously backuped config files.
|
||||
This documentation has been moved and can be found here: <https://tbnobody.github.io/OpenDTU-docs/firmware/howto/upgrade_partition/>
|
||||
|
||||
563
docs/Web-API.md
563
docs/Web-API.md
@ -1,564 +1,3 @@
|
||||
# Web API
|
||||
|
||||
Information in JSON format can be obtained through the web API
|
||||
|
||||
## List of URLs
|
||||
|
||||
may be incomplete
|
||||
|
||||
| GET/POST | Auth required | URL |
|
||||
| -------- | --- | -- |
|
||||
| Get | yes | /api/config/get |
|
||||
| Post | yes | /api/config/delete |
|
||||
| Get | yes | /api/config/list |
|
||||
| Post | yes | /api/config/upload |
|
||||
| Get+Post | yes | /api/device/config |
|
||||
| Get | no | /api/devinfo/status |
|
||||
| Get+Post | yes | /api/dtu/config |
|
||||
| Get | no | /api/eventlog/status?inv=inverter-serialnumber |
|
||||
| Post | yes | /api/firmware/update |
|
||||
| Get | yes | /api/inverter/list |
|
||||
| Post | yes | /api/inverter/add |
|
||||
| Post | yes | /api/inverter/del |
|
||||
| Post | yes | /api/inverter/edit |
|
||||
| Post | yes | /api/limit/config |
|
||||
| Get | no | /api/limit/status |
|
||||
| Get | no | /api/livedata/status |
|
||||
| Post | yes | /api/maintenance/reboot |
|
||||
| Get+Post | yes | /api/mqtt/config |
|
||||
| Get | no | /api/mqtt/status |
|
||||
| Get+Post | yes | /api/network/config |
|
||||
| Get | no | /api/network/status |
|
||||
| Get+Post | yes | /api/ntp/config |
|
||||
| Get | no | /api/ntp/status |
|
||||
| Get+Post | yes | /api/ntp/time |
|
||||
| Get | no | /api/power/status |
|
||||
| Post | yes | /api/power/config |
|
||||
| Get | no | /api/prometheus/metrics |
|
||||
| Get+Post | yes | /api/security/config |
|
||||
| Get | yes | /api/security/authenticate |
|
||||
| Get | no | /api/system/status |
|
||||
|
||||
## Examples of Use
|
||||
|
||||
### Important notes
|
||||
|
||||
- IP addresses and serial numbers in this examples are anonymized. Adjust to your own needs.
|
||||
- The output from curl is without a linefeed at the end, so please be careful when copying the output - do not accidentally add the shell prompt directly after it.
|
||||
- When POSTing config data to OpenDTU, always send all settings back, even if only one setting was changed. Sending single settings is not supported and you will receive a response `{"type":"warning","message":"Values are missing!"}`
|
||||
- When POSTing, always put single quotes around the data part. Do not confuse the single quote `'` with the backtick `` ` ``. You have been warned.
|
||||
- Some API calls have a single URL for GET and POST - e.g. `/api/ntp/config`
|
||||
- Other API calls use e.g. `/api/limit/status` to GET data and a different URL `/api/limit/config` to POST data.
|
||||
- If you want to investigate the web api communication, a good tool is [Postman](https://www.postman.com/)
|
||||
- Settings API require username and password provided with Basic Authentication credentials
|
||||
- If you disable the readonly access to the web API, every endpoint requires authentication
|
||||
|
||||
### Get information
|
||||
|
||||
You can "talk" to the OpenDTU with a command line tool like `curl`. The output is in plain JSON, without carriage return/linefeed and is therefore not very human readable.
|
||||
|
||||
#### Get current livedata
|
||||
|
||||
```bash
|
||||
$ curl http://192.168.10.10/api/livedata/status
|
||||
{"inverters":[{"serial":"11617160xxxx","name":"Meine Solaranlage","data_age":6983,"reachable":false,"producing":false,"limit_relative":0,"limit_absolute":-1,"AC":{"0":{"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"Power DC":{"v":0,"u":"W","d":1},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3},"Frequency":{"v":0,"u":"Hz","d":2},"PowerFactor":{"v":0,"u":"","d":3},"ReactivePower":{"v":0,"u":"var","d":1},"Efficiency":{"v":0,"u":"%","d":3}}},"DC":{"0":{"name":{"u":""},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":3}},"1":{"name":{"u":""},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":3}},"2":{"name":{"u":""},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":3}},"3":{"name":{"u":""},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3}}},"INV":{"0":{"Temperature":{"v":0,"u":"°C","d":1}}},"events":0},{"serial":"11417160xxxx","name":"test","data_age":6983,"reachable":false,"producing":false,"limit_relative":0,"limit_absolute":-1,"AC":{"0":{"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"Power DC":{"v":0,"u":"W","d":1},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3},"Frequency":{"v":0,"u":"Hz","d":2},"PowerFactor":{"v":0,"u":"","d":3},"ReactivePower":{"v":0,"u":"var","d":1},"Efficiency":{"v":0,"u":"%","d":3}}},"DC":{"0":{"name":{"u":"test 1"},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":3}},"1":{"name":{"u":"test 2"},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":3}}},"INV":{"0":{"Temperature":{"v":0,"u":"°C","d":1}}},"events":0}],"total":{"Power":{"v":0,"u":"W","d":1},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":0,"u":"kWh","d":2}},"hints":{"time_sync":false,"radio_problem":false,"default_password":false}}
|
||||
```
|
||||
|
||||
To enhance readability (and filter information) use the JSON command line processor `jq`.
|
||||
|
||||
```bash
|
||||
$ curl --no-progress-meter http://192.168.10.10/api/livedata/status | jq
|
||||
{
|
||||
"inverters": [
|
||||
{
|
||||
"serial": "116171603546",
|
||||
"name": "Meine Solaranlage",
|
||||
"data_age": 7038,
|
||||
"reachable": false,
|
||||
"producing": false,
|
||||
"limit_relative": 0,
|
||||
"limit_absolute": -1,
|
||||
"AC": {
|
||||
"0": {
|
||||
"Power": {
|
||||
"v": 0,
|
||||
"u": "W",
|
||||
"d": 1
|
||||
},
|
||||
"Voltage": {
|
||||
"v": 0,
|
||||
"u": "V",
|
||||
"d": 1
|
||||
},
|
||||
"Current": {
|
||||
"v": 0,
|
||||
"u": "A",
|
||||
"d": 2
|
||||
},
|
||||
"Power DC": {
|
||||
"v": 0,
|
||||
"u": "W",
|
||||
"d": 1
|
||||
},
|
||||
"YieldDay": {
|
||||
"v": 0,
|
||||
"u": "Wh",
|
||||
"d": 0
|
||||
},
|
||||
"YieldTotal": {
|
||||
"v": 0,
|
||||
"u": "kWh",
|
||||
"d": 3
|
||||
},
|
||||
"Frequency": {
|
||||
"v": 0,
|
||||
"u": "Hz",
|
||||
"d": 2
|
||||
},
|
||||
"PowerFactor": {
|
||||
"v": 0,
|
||||
"u": "",
|
||||
"d": 3
|
||||
},
|
||||
"ReactivePower": {
|
||||
"v": 0,
|
||||
"u": "var",
|
||||
"d": 1
|
||||
},
|
||||
"Efficiency": {
|
||||
"v": 0,
|
||||
"u": "%",
|
||||
"d": 3
|
||||
}
|
||||
}
|
||||
},
|
||||
"DC": {
|
||||
"0": {
|
||||
"name": {
|
||||
"u": ""
|
||||
},
|
||||
"Power": {
|
||||
"v": 0,
|
||||
"u": "W",
|
||||
"d": 1
|
||||
},
|
||||
"Voltage": {
|
||||
"v": 0,
|
||||
"u": "V",
|
||||
"d": 1
|
||||
},
|
||||
"Current": {
|
||||
"v": 0,
|
||||
"u": "A",
|
||||
"d": 2
|
||||
},
|
||||
"YieldDay": {
|
||||
"v": 0,
|
||||
"u": "Wh",
|
||||
"d": 0
|
||||
},
|
||||
"YieldTotal": {
|
||||
"v": 0,
|
||||
"u": "kWh",
|
||||
"d": 3
|
||||
},
|
||||
"Irradiation": {
|
||||
"v": 0,
|
||||
"u": "%",
|
||||
"d": 3
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"name": {
|
||||
"u": ""
|
||||
},
|
||||
"Power": {
|
||||
"v": 0,
|
||||
"u": "W",
|
||||
"d": 1
|
||||
},
|
||||
"Voltage": {
|
||||
"v": 0,
|
||||
"u": "V",
|
||||
"d": 1
|
||||
},
|
||||
"Current": {
|
||||
"v": 0,
|
||||
"u": "A",
|
||||
"d": 2
|
||||
},
|
||||
"YieldDay": {
|
||||
"v": 0,
|
||||
"u": "Wh",
|
||||
"d": 0
|
||||
},
|
||||
"YieldTotal": {
|
||||
"v": 0,
|
||||
"u": "kWh",
|
||||
"d": 3
|
||||
},
|
||||
"Irradiation": {
|
||||
"v": 0,
|
||||
"u": "%",
|
||||
"d": 3
|
||||
}
|
||||
},
|
||||
"2": {
|
||||
"name": {
|
||||
"u": ""
|
||||
},
|
||||
"Power": {
|
||||
"v": 0,
|
||||
"u": "W",
|
||||
"d": 1
|
||||
},
|
||||
"Voltage": {
|
||||
"v": 0,
|
||||
"u": "V",
|
||||
"d": 1
|
||||
},
|
||||
"Current": {
|
||||
"v": 0,
|
||||
"u": "A",
|
||||
"d": 2
|
||||
},
|
||||
"YieldDay": {
|
||||
"v": 0,
|
||||
"u": "Wh",
|
||||
"d": 0
|
||||
},
|
||||
"YieldTotal": {
|
||||
"v": 0,
|
||||
"u": "kWh",
|
||||
"d": 3
|
||||
},
|
||||
"Irradiation": {
|
||||
"v": 0,
|
||||
"u": "%",
|
||||
"d": 3
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"name": {
|
||||
"u": ""
|
||||
},
|
||||
"Power": {
|
||||
"v": 0,
|
||||
"u": "W",
|
||||
"d": 1
|
||||
},
|
||||
"Voltage": {
|
||||
"v": 0,
|
||||
"u": "V",
|
||||
"d": 1
|
||||
},
|
||||
"Current": {
|
||||
"v": 0,
|
||||
"u": "A",
|
||||
"d": 2
|
||||
},
|
||||
"YieldDay": {
|
||||
"v": 0,
|
||||
"u": "Wh",
|
||||
"d": 0
|
||||
},
|
||||
"YieldTotal": {
|
||||
"v": 0,
|
||||
"u": "kWh",
|
||||
"d": 3
|
||||
}
|
||||
}
|
||||
},
|
||||
"INV": {
|
||||
"0": {
|
||||
"Temperature": {
|
||||
"v": 0,
|
||||
"u": "°C",
|
||||
"d": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"events": 0
|
||||
},
|
||||
{
|
||||
"serial": "114171603548",
|
||||
"name": "test",
|
||||
"data_age": 7038,
|
||||
"reachable": false,
|
||||
"producing": false,
|
||||
"limit_relative": 0,
|
||||
"limit_absolute": -1,
|
||||
"AC": {
|
||||
"0": {
|
||||
"Power": {
|
||||
"v": 0,
|
||||
"u": "W",
|
||||
"d": 1
|
||||
},
|
||||
"Voltage": {
|
||||
"v": 0,
|
||||
"u": "V",
|
||||
"d": 1
|
||||
},
|
||||
"Current": {
|
||||
"v": 0,
|
||||
"u": "A",
|
||||
"d": 2
|
||||
},
|
||||
"Power DC": {
|
||||
"v": 0,
|
||||
"u": "W",
|
||||
"d": 1
|
||||
},
|
||||
"YieldDay": {
|
||||
"v": 0,
|
||||
"u": "Wh",
|
||||
"d": 0
|
||||
},
|
||||
"YieldTotal": {
|
||||
"v": 0,
|
||||
"u": "kWh",
|
||||
"d": 3
|
||||
},
|
||||
"Frequency": {
|
||||
"v": 0,
|
||||
"u": "Hz",
|
||||
"d": 2
|
||||
},
|
||||
"PowerFactor": {
|
||||
"v": 0,
|
||||
"u": "",
|
||||
"d": 3
|
||||
},
|
||||
"ReactivePower": {
|
||||
"v": 0,
|
||||
"u": "var",
|
||||
"d": 1
|
||||
},
|
||||
"Efficiency": {
|
||||
"v": 0,
|
||||
"u": "%",
|
||||
"d": 3
|
||||
}
|
||||
}
|
||||
},
|
||||
"DC": {
|
||||
"0": {
|
||||
"name": {
|
||||
"u": "test 1"
|
||||
},
|
||||
"Power": {
|
||||
"v": 0,
|
||||
"u": "W",
|
||||
"d": 1
|
||||
},
|
||||
"Voltage": {
|
||||
"v": 0,
|
||||
"u": "V",
|
||||
"d": 1
|
||||
},
|
||||
"Current": {
|
||||
"v": 0,
|
||||
"u": "A",
|
||||
"d": 2
|
||||
},
|
||||
"YieldDay": {
|
||||
"v": 0,
|
||||
"u": "Wh",
|
||||
"d": 0
|
||||
},
|
||||
"YieldTotal": {
|
||||
"v": 0,
|
||||
"u": "kWh",
|
||||
"d": 3
|
||||
},
|
||||
"Irradiation": {
|
||||
"v": 0,
|
||||
"u": "%",
|
||||
"d": 3
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"name": {
|
||||
"u": "test 2"
|
||||
},
|
||||
"Power": {
|
||||
"v": 0,
|
||||
"u": "W",
|
||||
"d": 1
|
||||
},
|
||||
"Voltage": {
|
||||
"v": 0,
|
||||
"u": "V",
|
||||
"d": 1
|
||||
},
|
||||
"Current": {
|
||||
"v": 0,
|
||||
"u": "A",
|
||||
"d": 2
|
||||
},
|
||||
"YieldDay": {
|
||||
"v": 0,
|
||||
"u": "Wh",
|
||||
"d": 0
|
||||
},
|
||||
"YieldTotal": {
|
||||
"v": 0,
|
||||
"u": "kWh",
|
||||
"d": 3
|
||||
},
|
||||
"Irradiation": {
|
||||
"v": 0,
|
||||
"u": "%",
|
||||
"d": 3
|
||||
}
|
||||
}
|
||||
},
|
||||
"INV": {
|
||||
"0": {
|
||||
"Temperature": {
|
||||
"v": 0,
|
||||
"u": "°C",
|
||||
"d": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"events": 0
|
||||
}
|
||||
],
|
||||
"total": {
|
||||
"Power": {
|
||||
"v": 0,
|
||||
"u": "W",
|
||||
"d": 1
|
||||
},
|
||||
"YieldDay": {
|
||||
"v": 0,
|
||||
"u": "Wh",
|
||||
"d": 0
|
||||
},
|
||||
"YieldTotal": {
|
||||
"v": 0,
|
||||
"u": "kWh",
|
||||
"d": 2
|
||||
}
|
||||
},
|
||||
"hints": {
|
||||
"time_sync": false,
|
||||
"radio_problem": false,
|
||||
"default_password": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The eventlog can be fetched with the inverter serial number as parameter:
|
||||
|
||||
```bash
|
||||
$ curl --no-progress-meter http://192.168.10.10/api/eventlog/status?inv=11418186xxxx | jq
|
||||
{
|
||||
"11418186xxxx": {
|
||||
"count": 4,
|
||||
"events": [
|
||||
{
|
||||
"message_id": 1,
|
||||
"message": "Inverter start",
|
||||
"start_time": 28028,
|
||||
"end_time": 28028
|
||||
},
|
||||
{
|
||||
"message_id": 209,
|
||||
"message": "PV-1: No input",
|
||||
"start_time": 28036,
|
||||
"end_time": 0
|
||||
},
|
||||
{
|
||||
"message_id": 2,
|
||||
"message": "DTU command failed",
|
||||
"start_time": 28092,
|
||||
"end_time": 28092
|
||||
},
|
||||
{
|
||||
"message_id": 207,
|
||||
"message": "MPPT-A: Input undervoltage",
|
||||
"start_time": 28336,
|
||||
"end_time": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### combine curl and jq
|
||||
|
||||
`jq` can filter specific fields from json output.
|
||||
|
||||
For example, filter out the current total power:
|
||||
|
||||
```bash
|
||||
$ curl --no-progress-meter http://192.168.10.10/api/livedata/status | jq '.total | .Power.v'
|
||||
140.7999878
|
||||
```
|
||||
|
||||
#### Get information where login is required
|
||||
|
||||
When config data is requested, username and password have to be provided to `curl`
|
||||
Username is always `admin`, the default password is `openDTU42`. The password is used for both the admin login and the Admin-mode Access Point.
|
||||
|
||||
```bash
|
||||
$ curl --u admin:openDTU42 http://192.168.10.10/api/ntp/config
|
||||
{"ntp_server":"pool.ntp.org","ntp_timezone":"CET-1CEST,M3.5.0,M10.5.0/3","ntp_timezone_descr":"Europe/Berlin"}
|
||||
```
|
||||
|
||||
### Post information
|
||||
|
||||
With HTTP POST commands information can be written to the OpenDTU.
|
||||
|
||||
The Web API is designed to allow the web frontend in the web browser to communicate with the OpenDTU software running on the ESP32. It is not designed to be intuitive or user-friendly, so please follow the instructions here.
|
||||
|
||||
#### Example 1: change ntp settings
|
||||
|
||||
If you want to configure the ntp server setting, first fetch the information from the web API:
|
||||
|
||||
```bash
|
||||
$ curl -u "admin:password" http://192.168.10.10/api/ntp/config
|
||||
{"ntp_server":"pool.ntp.org","ntp_timezone":"CET-1CEST,M3.5.0,M10.5.0/3","ntp_timezone_descr":"Europe/Berlin"}
|
||||
```
|
||||
|
||||
Then, second step, send your new settings. Use the text output from curl in the first step, add `data=` and enclose the whole data with single quotes.
|
||||
|
||||
```bash
|
||||
$ curl -u "admin:password" http://192.168.10.10/api/ntp/config -d 'data={"ntp_server":"my.own.ntp.server.home","ntp_timezone":"CET-1CEST,M3.5.0,M10.5.0/3","ntp_timezone_descr":"Europe/Berlin"}'
|
||||
{"type":"success","message":"Settings saved!"}
|
||||
```
|
||||
|
||||
You will receive a json formatted response.
|
||||
|
||||
#### Example 2: change power limit
|
||||
|
||||
In the second example, I want to change the non persistent power limit of an inverter. Again, first fetch current data:
|
||||
|
||||
```bash
|
||||
$ curl http://192.168.10.10/api/limit/status
|
||||
{"11418186xxxx":{"limit_relative":100,"max_power":600,"limit_set_status":"Ok"},"11418180xxxx":{"limit_relative":100,"max_power":800,"limit_set_status":"Ok"}}
|
||||
```
|
||||
|
||||
I see data from two configured inverters.
|
||||
|
||||
Now I set the relative power limit of inverter with serialnumber `11418180xxxx` to 50%.
|
||||
|
||||
```bash
|
||||
$ curl -u "admin:password" http://192.168.10.10/api/limit/config -d 'data={"serial":"11418180xxxx", "limit_type":1, "limit_value":50}'
|
||||
{"type":"success","message":"Settings saved!"}
|
||||
```
|
||||
|
||||
Then I read again the limit status. In the first answer the status is `pending`, some seconds later it changed to `OK`.
|
||||
|
||||
```bash
|
||||
$ curl http://192.168.10.10/api/limit/status
|
||||
{"11418186xxxx":{"limit_relative":100,"max_power":600,"limit_set_status":"Ok"},"11418180xxxx":{"limit_relative":100,"max_power":800,"limit_set_status":"Pending"}}
|
||||
|
||||
...
|
||||
|
||||
$ curl http://192.168.10.10/api/limit/status
|
||||
{"11418186xxxx":{"limit_relative":100,"max_power":600,"limit_set_status":"Ok"},"11418180xxxx":{"limit_relative":50,"max_power":800,"limit_set_status":"Ok"}}
|
||||
```
|
||||
This documentation will has been moved and can be found here: <https://tbnobody.github.io/OpenDTU-docs/firmware/web_api/>
|
||||
|
||||
@ -1,6 +1,15 @@
|
||||
# Builds using different boards
|
||||
|
||||
## ESP32 Dev Board
|
||||
|
||||
### Build by @tbnobody, jan and @marove2000
|
||||
* Used build environment: generic
|
||||
* Case: https://www.printables.com/de/model/441037-opendtu-breakoutboard-case
|
||||
* Soldering Kit: https://shop.blinkyparts.com/en/OpenDTU-Breakoutboard-Your-evaluation-for-your-balcony-solar-system/blink237542
|
||||
* Breakout board: https://github.com/marove2000/openDTU_BreakoutBoard
|
||||

|
||||

|
||||
|
||||
### Build by @Marc--
|
||||
* Used build environment: generic
|
||||
* Case: https://www.thingiverse.com/thing:5435911
|
||||
|
||||
BIN
docs/builds/opendtu_breakoutboard.jpg
Normal file
BIN
docs/builds/opendtu_breakoutboard.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
BIN
docs/builds/thumbnail.jpg
Normal file
BIN
docs/builds/thumbnail.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 168 KiB |
@ -1,10 +1,14 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "PinMapping.h"
|
||||
#include <cstdint>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#define CONFIG_FILENAME "/config.json"
|
||||
#define CONFIG_VERSION 0x00011800 // 0.1.24 // make sure to clean all after change
|
||||
#define CONFIG_VERSION 0x00011d00 // 0.1.29 // make sure to clean all after change
|
||||
|
||||
#define WIFI_MAX_SSID_STRLEN 32
|
||||
#define WIFI_MAX_PASSWORD_STRLEN 64
|
||||
@ -15,6 +19,7 @@
|
||||
#define NTP_MAX_TIMEZONEDESCR_STRLEN 50
|
||||
|
||||
#define MQTT_MAX_HOSTNAME_STRLEN 128
|
||||
#define MQTT_MAX_CLIENTID_STRLEN 64
|
||||
#define MQTT_MAX_USERNAME_STRLEN 64
|
||||
#define MQTT_MAX_PASSWORD_STRLEN 64
|
||||
#define MQTT_MAX_TOPIC_STRLEN 32
|
||||
@ -23,13 +28,12 @@
|
||||
|
||||
#define INV_MAX_NAME_STRLEN 31
|
||||
#define INV_MAX_COUNT 10
|
||||
#define INV_MAX_CHAN_COUNT 4
|
||||
#define INV_MAX_CHAN_COUNT 6
|
||||
|
||||
#define CHAN_MAX_NAME_STRLEN 31
|
||||
|
||||
#define DEV_MAX_MAPPING_NAME_STRLEN 63
|
||||
|
||||
#define JSON_BUFFER_SIZE 12288
|
||||
#define LOCALE_STRLEN 2
|
||||
|
||||
struct CHANNEL_CONFIG_T {
|
||||
uint16_t MaxChannelPower;
|
||||
@ -40,85 +44,153 @@ struct CHANNEL_CONFIG_T {
|
||||
struct INVERTER_CONFIG_T {
|
||||
uint64_t Serial;
|
||||
char Name[INV_MAX_NAME_STRLEN + 1];
|
||||
uint8_t Order;
|
||||
bool Poll_Enable;
|
||||
bool Poll_Enable_Night;
|
||||
bool Command_Enable;
|
||||
bool Command_Enable_Night;
|
||||
uint8_t ReachableThreshold;
|
||||
bool ZeroRuntimeDataIfUnrechable;
|
||||
bool ZeroYieldDayOnMidnight;
|
||||
bool ClearEventlogOnMidnight;
|
||||
bool YieldDayCorrection;
|
||||
CHANNEL_CONFIG_T channel[INV_MAX_CHAN_COUNT];
|
||||
};
|
||||
|
||||
struct CONFIG_T {
|
||||
uint32_t Cfg_Version;
|
||||
uint Cfg_SaveCount;
|
||||
struct {
|
||||
uint32_t Version;
|
||||
uint32_t SaveCount;
|
||||
} Cfg;
|
||||
|
||||
char WiFi_Ssid[WIFI_MAX_SSID_STRLEN + 1];
|
||||
char WiFi_Password[WIFI_MAX_PASSWORD_STRLEN + 1];
|
||||
byte WiFi_Ip[4];
|
||||
byte WiFi_Netmask[4];
|
||||
byte WiFi_Gateway[4];
|
||||
byte WiFi_Dns1[4];
|
||||
byte WiFi_Dns2[4];
|
||||
bool WiFi_Dhcp;
|
||||
char WiFi_Hostname[WIFI_MAX_HOSTNAME_STRLEN + 1];
|
||||
struct {
|
||||
char Ssid[WIFI_MAX_SSID_STRLEN + 1];
|
||||
char Password[WIFI_MAX_PASSWORD_STRLEN + 1];
|
||||
uint8_t Ip[4];
|
||||
uint8_t Netmask[4];
|
||||
uint8_t Gateway[4];
|
||||
uint8_t Dns1[4];
|
||||
uint8_t Dns2[4];
|
||||
bool Dhcp;
|
||||
char Hostname[WIFI_MAX_HOSTNAME_STRLEN + 1];
|
||||
uint32_t ApTimeout;
|
||||
} WiFi;
|
||||
|
||||
char Ntp_Server[NTP_MAX_SERVER_STRLEN + 1];
|
||||
char Ntp_Timezone[NTP_MAX_TIMEZONE_STRLEN + 1];
|
||||
char Ntp_TimezoneDescr[NTP_MAX_TIMEZONEDESCR_STRLEN + 1];
|
||||
double Ntp_Longitude;
|
||||
double Ntp_Latitude;
|
||||
struct {
|
||||
bool Enabled;
|
||||
} Mdns;
|
||||
|
||||
bool Mqtt_Enabled;
|
||||
uint Mqtt_Port;
|
||||
char Mqtt_Username[MQTT_MAX_USERNAME_STRLEN + 1];
|
||||
char Mqtt_Password[MQTT_MAX_PASSWORD_STRLEN + 1];
|
||||
char Mqtt_Topic[MQTT_MAX_TOPIC_STRLEN + 1];
|
||||
bool Mqtt_Retain;
|
||||
char Mqtt_LwtTopic[MQTT_MAX_TOPIC_STRLEN + 1];
|
||||
char Mqtt_LwtValue_Online[MQTT_MAX_LWTVALUE_STRLEN + 1];
|
||||
char Mqtt_LwtValue_Offline[MQTT_MAX_LWTVALUE_STRLEN + 1];
|
||||
uint32_t Mqtt_PublishInterval;
|
||||
struct {
|
||||
char Server[NTP_MAX_SERVER_STRLEN + 1];
|
||||
char Timezone[NTP_MAX_TIMEZONE_STRLEN + 1];
|
||||
char TimezoneDescr[NTP_MAX_TIMEZONEDESCR_STRLEN + 1];
|
||||
double Longitude;
|
||||
double Latitude;
|
||||
uint8_t SunsetType;
|
||||
} Ntp;
|
||||
|
||||
struct {
|
||||
bool Enabled;
|
||||
char Hostname[MQTT_MAX_HOSTNAME_STRLEN + 1];
|
||||
uint32_t Port;
|
||||
char ClientId[MQTT_MAX_CLIENTID_STRLEN + 1];
|
||||
char Username[MQTT_MAX_USERNAME_STRLEN + 1];
|
||||
char Password[MQTT_MAX_PASSWORD_STRLEN + 1];
|
||||
char Topic[MQTT_MAX_TOPIC_STRLEN + 1];
|
||||
bool Retain;
|
||||
uint32_t PublishInterval;
|
||||
bool CleanSession;
|
||||
|
||||
struct {
|
||||
char Topic[MQTT_MAX_TOPIC_STRLEN + 1];
|
||||
char Value_Online[MQTT_MAX_LWTVALUE_STRLEN + 1];
|
||||
char Value_Offline[MQTT_MAX_LWTVALUE_STRLEN + 1];
|
||||
uint8_t Qos;
|
||||
} Lwt;
|
||||
|
||||
struct {
|
||||
bool Enabled;
|
||||
bool Retain;
|
||||
char Topic[MQTT_MAX_TOPIC_STRLEN + 1];
|
||||
bool IndividualPanels;
|
||||
bool Expire;
|
||||
} Hass;
|
||||
|
||||
struct {
|
||||
bool Enabled;
|
||||
char RootCaCert[MQTT_MAX_CERT_STRLEN + 1];
|
||||
bool CertLogin;
|
||||
char ClientCert[MQTT_MAX_CERT_STRLEN + 1];
|
||||
char ClientKey[MQTT_MAX_CERT_STRLEN + 1];
|
||||
} Tls;
|
||||
} Mqtt;
|
||||
|
||||
struct {
|
||||
uint64_t Serial;
|
||||
uint32_t PollInterval;
|
||||
struct {
|
||||
uint8_t PaLevel;
|
||||
} Nrf;
|
||||
struct {
|
||||
int8_t PaLevel;
|
||||
uint32_t Frequency;
|
||||
uint8_t CountryMode;
|
||||
} Cmt;
|
||||
} Dtu;
|
||||
|
||||
struct {
|
||||
char Password[WIFI_MAX_PASSWORD_STRLEN + 1];
|
||||
bool AllowReadonly;
|
||||
} Security;
|
||||
|
||||
struct {
|
||||
bool PowerSafe;
|
||||
bool ScreenSaver;
|
||||
uint8_t Rotation;
|
||||
uint8_t Contrast;
|
||||
char Locale[LOCALE_STRLEN + 1];
|
||||
struct {
|
||||
uint32_t Duration;
|
||||
uint8_t Mode;
|
||||
} Diagram;
|
||||
} Display;
|
||||
|
||||
struct {
|
||||
uint8_t Brightness;
|
||||
} Led_Single[PINMAPPING_LED_COUNT];
|
||||
|
||||
INVERTER_CONFIG_T Inverter[INV_MAX_COUNT];
|
||||
|
||||
uint64_t Dtu_Serial;
|
||||
uint32_t Dtu_PollInterval;
|
||||
uint8_t Dtu_PaLevel;
|
||||
|
||||
bool Mqtt_Hass_Enabled;
|
||||
bool Mqtt_Hass_Retain;
|
||||
char Mqtt_Hass_Topic[MQTT_MAX_TOPIC_STRLEN + 1];
|
||||
bool Mqtt_Hass_IndividualPanels;
|
||||
bool Mqtt_Tls;
|
||||
char Mqtt_RootCaCert[MQTT_MAX_CERT_STRLEN + 1];
|
||||
bool Mqtt_TlsCertLogin;
|
||||
char Mqtt_ClientCert[MQTT_MAX_CERT_STRLEN + 1];
|
||||
char Mqtt_ClientKey[MQTT_MAX_CERT_STRLEN + 1];
|
||||
|
||||
char Mqtt_Hostname[MQTT_MAX_HOSTNAME_STRLEN + 1];
|
||||
|
||||
bool Mqtt_Hass_Expire;
|
||||
|
||||
char Security_Password[WIFI_MAX_PASSWORD_STRLEN + 1];
|
||||
bool Security_AllowReadonly;
|
||||
|
||||
char Dev_PinMapping[DEV_MAX_MAPPING_NAME_STRLEN + 1];
|
||||
|
||||
bool Display_PowerSafe;
|
||||
bool Display_ScreenSaver;
|
||||
uint8_t Display_Rotation;
|
||||
uint8_t Display_Contrast;
|
||||
};
|
||||
|
||||
class ConfigurationClass {
|
||||
public:
|
||||
void init();
|
||||
void init(Scheduler& scheduler);
|
||||
bool read();
|
||||
bool write();
|
||||
void migrate();
|
||||
CONFIG_T& get();
|
||||
CONFIG_T const& get();
|
||||
|
||||
class WriteGuard {
|
||||
public:
|
||||
WriteGuard();
|
||||
CONFIG_T& getConfig();
|
||||
~WriteGuard();
|
||||
|
||||
private:
|
||||
std::unique_lock<std::mutex> _lock;
|
||||
};
|
||||
|
||||
WriteGuard getWriteGuard();
|
||||
|
||||
INVERTER_CONFIG_T* getFreeInverterSlot();
|
||||
INVERTER_CONFIG_T* getInverterConfig(uint64_t serial);
|
||||
INVERTER_CONFIG_T* getInverterConfig(const uint64_t serial);
|
||||
void deleteInverterById(const uint8_t id);
|
||||
|
||||
private:
|
||||
void loop();
|
||||
|
||||
Task _loopTask;
|
||||
};
|
||||
|
||||
extern ConfigurationClass Configuration;
|
||||
extern ConfigurationClass Configuration;
|
||||
|
||||
85
include/Datastore.h
Normal file
85
include/Datastore.h
Normal file
@ -0,0 +1,85 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
#include <mutex>
|
||||
|
||||
class DatastoreClass {
|
||||
public:
|
||||
DatastoreClass();
|
||||
void init(Scheduler& scheduler);
|
||||
|
||||
// Sum of yield total of all enabled inverters, a inverter which is just disabled at night is also included
|
||||
float getTotalAcYieldTotalEnabled();
|
||||
|
||||
// Sum of yield day of all enabled inverters, a inverter which is just disabled at night is also included
|
||||
float getTotalAcYieldDayEnabled();
|
||||
|
||||
// Sum of total AC power of all enabled inverters
|
||||
float getTotalAcPowerEnabled();
|
||||
|
||||
// Sum of total DC power of all enabled inverters
|
||||
float getTotalDcPowerEnabled();
|
||||
|
||||
// Sum of total DC power of all enabled inverters with maxStringPower set
|
||||
float getTotalDcPowerIrradiation();
|
||||
|
||||
// Sum of total installed irradiation of all enabled inverters
|
||||
float getTotalDcIrradiationInstalled();
|
||||
|
||||
// Percentage (1-100) of total irradiation
|
||||
float getTotalDcIrradiation();
|
||||
|
||||
// Amount of relevant digits for yield total
|
||||
uint32_t getTotalAcYieldTotalDigits();
|
||||
|
||||
// Amount of relevant digits for yield total
|
||||
uint32_t getTotalAcYieldDayDigits();
|
||||
|
||||
// Amount of relevant digits for AC power
|
||||
uint32_t getTotalAcPowerDigits();
|
||||
|
||||
// Amount of relevant digits for DC power
|
||||
uint32_t getTotalDcPowerDigits();
|
||||
|
||||
// True, if at least one inverter is reachable
|
||||
bool getIsAtLeastOneReachable();
|
||||
|
||||
// True if at least one inverter is producing
|
||||
bool getIsAtLeastOneProducing();
|
||||
|
||||
// True if at least one inverter is enabled for polling
|
||||
bool getIsAtLeastOnePollEnabled();
|
||||
|
||||
// True if all enabled inverters are producing
|
||||
bool getIsAllEnabledProducing();
|
||||
|
||||
// True if all enabled inverters are reachable
|
||||
bool getIsAllEnabledReachable();
|
||||
|
||||
private:
|
||||
void loop();
|
||||
|
||||
Task _loopTask;
|
||||
|
||||
std::mutex _mutex;
|
||||
|
||||
float _totalAcYieldTotalEnabled = 0;
|
||||
float _totalAcYieldDayEnabled = 0;
|
||||
float _totalAcPowerEnabled = 0;
|
||||
float _totalDcPowerEnabled = 0;
|
||||
float _totalDcPowerIrradiation = 0;
|
||||
float _totalDcIrradiationInstalled = 0;
|
||||
float _totalDcIrradiation = 0;
|
||||
uint32_t _totalAcYieldTotalDigits = 0;
|
||||
uint32_t _totalAcYieldDayDigits = 0;
|
||||
uint32_t _totalAcPowerDigits = 0;
|
||||
uint32_t _totalDcPowerDigits = 0;
|
||||
bool _isAtLeastOneReachable = false;
|
||||
bool _isAtLeastOneProducing = false;
|
||||
bool _isAllEnabledProducing = false;
|
||||
bool _isAllEnabledReachable = false;
|
||||
bool _isAtLeastOnePollEnabled = false;
|
||||
};
|
||||
|
||||
extern DatastoreClass Datastore;
|
||||
@ -1,14 +1,34 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include "Display_Graphic_Diagram.h"
|
||||
#include "defaults.h"
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
#include <U8g2lib.h>
|
||||
|
||||
#define CHART_HEIGHT 20 // chart area hight in pixels
|
||||
#define CHART_WIDTH 47 // chart area width in pixels
|
||||
|
||||
// Left-Upper position of diagram is drawn
|
||||
// (text of Y-axis is display left of that pos)
|
||||
#define CHART_POSX 80
|
||||
#define CHART_POSY 0
|
||||
|
||||
enum DisplayType_t {
|
||||
None,
|
||||
PCD8544,
|
||||
SSD1306,
|
||||
SH1106,
|
||||
SSD1309,
|
||||
ST7567_GM12864I_59N,
|
||||
DisplayType_Max,
|
||||
};
|
||||
|
||||
enum DiagramMode_t {
|
||||
Off,
|
||||
Small,
|
||||
Fullscreen,
|
||||
DisplayMode_Max,
|
||||
};
|
||||
|
||||
class DisplayGraphicClass {
|
||||
@ -16,31 +36,52 @@ public:
|
||||
DisplayGraphicClass();
|
||||
~DisplayGraphicClass();
|
||||
|
||||
void init(DisplayType_t type, uint8_t data, uint8_t clk, uint8_t cs, uint8_t reset);
|
||||
void loop();
|
||||
void setContrast(uint8_t contrast);
|
||||
void setOrientation(uint8_t rotation = DISPLAY_ROTATION);
|
||||
void init(Scheduler& scheduler, const DisplayType_t type, const uint8_t data, const uint8_t clk, const uint8_t cs, const uint8_t reset);
|
||||
void setContrast(const uint8_t contrast);
|
||||
void setStatus(const bool turnOn);
|
||||
void setOrientation(const uint8_t rotation = DISPLAY_ROTATION);
|
||||
void setLocale(const String& locale);
|
||||
void setDiagramMode(DiagramMode_t mode);
|
||||
void setStartupDisplay();
|
||||
|
||||
DisplayGraphicDiagramClass& Diagram();
|
||||
|
||||
bool enablePowerSafe = true;
|
||||
bool enableScreensaver = true;
|
||||
|
||||
private:
|
||||
void printText(const char* text, uint8_t line);
|
||||
void loop();
|
||||
void printText(const char* text, const uint8_t line);
|
||||
void calcLineHeights();
|
||||
void setFont(uint8_t line);
|
||||
void setFont(const uint8_t line);
|
||||
bool isValidDisplay();
|
||||
|
||||
Task _loopTask;
|
||||
|
||||
U8G2* _display;
|
||||
DisplayGraphicDiagramClass _diagram;
|
||||
|
||||
bool _displayTurnedOn;
|
||||
|
||||
DisplayType_t _display_type = DisplayType_t::None;
|
||||
DiagramMode_t _diagram_mode = DiagramMode_t::Off;
|
||||
String _display_language = DISPLAY_LOCALE;
|
||||
uint8_t _mExtra;
|
||||
uint16_t _period = 1000;
|
||||
uint16_t _interval = 60000; // interval at which to power save (milliseconds)
|
||||
uint32_t _lastDisplayUpdate = 0;
|
||||
const uint16_t _period = 1000;
|
||||
const uint16_t _interval = 60000; // interval at which to power save (milliseconds)
|
||||
uint32_t _previousMillis = 0;
|
||||
char _fmtText[32];
|
||||
bool _isLarge = false;
|
||||
uint8_t _lineOffsets[5];
|
||||
|
||||
String _i18n_offline;
|
||||
String _i18n_yield_today_kwh;
|
||||
String _i18n_yield_today_wh;
|
||||
String _i18n_date_format;
|
||||
String _i18n_current_power_kw;
|
||||
String _i18n_current_power_w;
|
||||
String _i18n_yield_total_mwh;
|
||||
String _i18n_yield_total_kwh;
|
||||
};
|
||||
|
||||
extern DisplayGraphicClass Display;
|
||||
extern DisplayGraphicClass Display;
|
||||
|
||||
36
include/Display_Graphic_Diagram.h
Normal file
36
include/Display_Graphic_Diagram.h
Normal file
@ -0,0 +1,36 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
#include <U8g2lib.h>
|
||||
#include <array>
|
||||
|
||||
#define MAX_DATAPOINTS 128
|
||||
|
||||
class DisplayGraphicDiagramClass {
|
||||
public:
|
||||
DisplayGraphicDiagramClass();
|
||||
|
||||
void init(Scheduler& scheduler, U8G2* display);
|
||||
void redraw(uint8_t screenSaverOffsetX, uint8_t xPos, uint8_t yPos, uint8_t width, uint8_t height, bool isFullscreen);
|
||||
|
||||
void updatePeriod();
|
||||
|
||||
private:
|
||||
void averageLoop();
|
||||
void dataPointLoop();
|
||||
|
||||
uint32_t getSecondsPerDot();
|
||||
|
||||
Task _averageTask;
|
||||
Task _dataPointTask;
|
||||
|
||||
U8G2* _display = nullptr;
|
||||
std::array<float, MAX_DATAPOINTS> _graphValues = {};
|
||||
uint8_t _graphValuesCount = 0;
|
||||
|
||||
uint8_t _chartWidth = MAX_DATAPOINTS;
|
||||
|
||||
float _iRunningAverage = 0;
|
||||
uint16_t _iRunningAverageCnt = 0;
|
||||
};
|
||||
35
include/I18n.h
Normal file
35
include/I18n.h
Normal file
@ -0,0 +1,35 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
#include <WString.h>
|
||||
#include <list>
|
||||
|
||||
struct LanguageInfo_t {
|
||||
String code;
|
||||
String name;
|
||||
String filename;
|
||||
};
|
||||
|
||||
class I18nClass {
|
||||
public:
|
||||
I18nClass();
|
||||
void init(Scheduler& scheduler);
|
||||
std::list<LanguageInfo_t> getAvailableLanguages();
|
||||
String getFilenameByLocale(const String& locale) const;
|
||||
void readDisplayStrings(
|
||||
const String& locale,
|
||||
String& date_format,
|
||||
String& offline,
|
||||
String& power_w, String& power_kw,
|
||||
String& yield_today_wh, String& yield_today_kwh,
|
||||
String& yield_total_kwh, String& yield_total_mwh);
|
||||
|
||||
private:
|
||||
void readLangPacks();
|
||||
void readConfig(String file);
|
||||
|
||||
std::list<LanguageInfo_t> _availLanguages;
|
||||
};
|
||||
|
||||
extern I18nClass I18n;
|
||||
@ -1,15 +1,22 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
#include <cstdint>
|
||||
|
||||
#define INVERTER_UPDATE_SETTINGS_INTERVAL 60000l
|
||||
|
||||
class InverterSettingsClass {
|
||||
public:
|
||||
void init();
|
||||
void loop();
|
||||
InverterSettingsClass();
|
||||
void init(Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
uint32_t _lastUpdate = 0;
|
||||
void settingsLoop();
|
||||
void hoyLoop();
|
||||
|
||||
Task _settingsTask;
|
||||
Task _hoyTask;
|
||||
};
|
||||
|
||||
extern InverterSettingsClass InverterSettings;
|
||||
extern InverterSettingsClass InverterSettings;
|
||||
|
||||
@ -2,34 +2,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "PinMapping.h"
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
#include <TimeoutHelper.h>
|
||||
|
||||
#define LEDSINGLE_UPDATE_INTERVAL 2000
|
||||
|
||||
enum eLedFunction {
|
||||
CONNECTED_NETWORK,
|
||||
CONNECTED_MQTT,
|
||||
INV_REACHABLE,
|
||||
INV_PRODUCING,
|
||||
};
|
||||
|
||||
class LedSingleClass {
|
||||
public:
|
||||
LedSingleClass();
|
||||
void init();
|
||||
void loop();
|
||||
void init(Scheduler& scheduler);
|
||||
|
||||
void turnAllOff();
|
||||
void turnAllOn();
|
||||
|
||||
private:
|
||||
void setLoop();
|
||||
void outputLoop();
|
||||
|
||||
void setLed(const uint8_t ledNo, const bool ledState);
|
||||
|
||||
Task _setTask;
|
||||
Task _outputTask;
|
||||
|
||||
enum class LedState_t {
|
||||
On,
|
||||
Off,
|
||||
Blink,
|
||||
};
|
||||
|
||||
LedState_t _ledState[PINMAPPING_LED_COUNT];
|
||||
TimeoutHelper _updateTimeout;
|
||||
LedState_t _ledMode[PINMAPPING_LED_COUNT];
|
||||
LedState_t _allMode;
|
||||
bool _ledStateCurrent[PINMAPPING_LED_COUNT];
|
||||
TimeoutHelper _blinkTimeout;
|
||||
uint8_t _ledActive = 0;
|
||||
};
|
||||
|
||||
extern LedSingleClass LedSingle;
|
||||
@ -1,27 +1,34 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <AsyncWebSocket.h>
|
||||
#include <HardwareSerial.h>
|
||||
#include <Stream.h>
|
||||
|
||||
#define BUFFER_SIZE 500
|
||||
|
||||
class MessageOutputClass : public Print {
|
||||
public:
|
||||
MessageOutputClass();
|
||||
void loop();
|
||||
size_t write(uint8_t c);
|
||||
void register_ws_output(AsyncWebSocket* output);
|
||||
|
||||
private:
|
||||
AsyncWebSocket* _ws = NULL;
|
||||
char _buffer[BUFFER_SIZE];
|
||||
uint16_t _buff_pos = 0;
|
||||
uint32_t _lastSend = 0;
|
||||
bool _forceSend = false;
|
||||
|
||||
SemaphoreHandle_t _lock;
|
||||
};
|
||||
|
||||
extern MessageOutputClass MessageOutput;
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <AsyncWebSocket.h>
|
||||
#include <HardwareSerial.h>
|
||||
#include <Stream.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
#include <mutex>
|
||||
|
||||
#define BUFFER_SIZE 500
|
||||
|
||||
class MessageOutputClass : public Print {
|
||||
public:
|
||||
MessageOutputClass();
|
||||
void init(Scheduler& scheduler);
|
||||
size_t write(uint8_t c) override;
|
||||
size_t write(const uint8_t* buffer, size_t size) override;
|
||||
void register_ws_output(AsyncWebSocket* output);
|
||||
|
||||
private:
|
||||
void loop();
|
||||
|
||||
Task _loopTask;
|
||||
|
||||
AsyncWebSocket* _ws = nullptr;
|
||||
char _buffer[BUFFER_SIZE];
|
||||
uint16_t _buff_pos = 0;
|
||||
uint32_t _lastSend = 0;
|
||||
bool _forceSend = false;
|
||||
|
||||
std::mutex _msgLock;
|
||||
};
|
||||
|
||||
extern MessageOutputClass MessageOutput;
|
||||
|
||||
@ -1,15 +1,18 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
#include <cstdint>
|
||||
|
||||
class MqttHandleDtuClass {
|
||||
public:
|
||||
void init();
|
||||
void loop();
|
||||
MqttHandleDtuClass();
|
||||
void init(Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
uint32_t _lastPublish;
|
||||
void loop();
|
||||
|
||||
Task _loopTask;
|
||||
};
|
||||
|
||||
extern MqttHandleDtuClass MqttHandleDtu;
|
||||
extern MqttHandleDtuClass MqttHandleDtu;
|
||||
|
||||
@ -3,31 +3,45 @@
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <Hoymiles.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
// mqtt discovery device classes
|
||||
enum {
|
||||
enum DeviceClassType {
|
||||
DEVICE_CLS_NONE = 0,
|
||||
DEVICE_CLS_CURRENT,
|
||||
DEVICE_CLS_ENERGY,
|
||||
DEVICE_CLS_PWR,
|
||||
DEVICE_CLS_VOLTAGE,
|
||||
DEVICE_CLS_FREQ,
|
||||
DEVICE_CLS_TEMP,
|
||||
DEVICE_CLS_POWER_FACTOR,
|
||||
DEVICE_CLS_REACTIVE_POWER
|
||||
DEVICE_CLS_REACTIVE_POWER,
|
||||
DEVICE_CLS_CONNECTIVITY,
|
||||
DEVICE_CLS_DURATION,
|
||||
DEVICE_CLS_SIGNAL_STRENGTH,
|
||||
DEVICE_CLS_TEMPERATURE,
|
||||
DEVICE_CLS_RESTART
|
||||
};
|
||||
const char* const deviceClasses[] = { 0, "current", "energy", "power", "voltage", "frequency", "temperature", "power_factor", "reactive_power" };
|
||||
enum {
|
||||
const char* const deviceClass_name[] = { 0, "current", "energy", "power", "voltage", "frequency", "power_factor", "reactive_power", "connectivity", "duration", "signal_strength", "temperature", "restart" };
|
||||
|
||||
enum StateClassType {
|
||||
STATE_CLS_NONE = 0,
|
||||
STATE_CLS_MEASUREMENT,
|
||||
STATE_CLS_TOTAL_INCREASING
|
||||
};
|
||||
const char* const stateClasses[] = { 0, "measurement", "total_increasing" };
|
||||
const char* const stateClass_name[] = { 0, "measurement", "total_increasing" };
|
||||
|
||||
enum CategoryType {
|
||||
CATEGORY_NONE = 0,
|
||||
CATEGORY_CONFIG,
|
||||
CATEGORY_DIAGNOSTIC
|
||||
};
|
||||
const char* const category_name[] = { 0, "config", "diagnostic" };
|
||||
|
||||
|
||||
typedef struct {
|
||||
FieldId_t fieldId; // field id
|
||||
uint8_t deviceClsId; // device class
|
||||
uint8_t stateClsId; // state class
|
||||
DeviceClassType deviceClsId; // device class
|
||||
StateClassType stateClsId; // state class
|
||||
} byteAssign_fieldDeviceClass_t;
|
||||
|
||||
const byteAssign_fieldDeviceClass_t deviceFieldAssignment[] = {
|
||||
@ -40,31 +54,54 @@ const byteAssign_fieldDeviceClass_t deviceFieldAssignment[] = {
|
||||
{ FLD_IAC, DEVICE_CLS_CURRENT, STATE_CLS_MEASUREMENT },
|
||||
{ FLD_PAC, DEVICE_CLS_PWR, STATE_CLS_MEASUREMENT },
|
||||
{ FLD_F, DEVICE_CLS_FREQ, STATE_CLS_MEASUREMENT },
|
||||
{ FLD_T, DEVICE_CLS_TEMP, STATE_CLS_MEASUREMENT },
|
||||
{ FLD_T, DEVICE_CLS_TEMPERATURE, STATE_CLS_MEASUREMENT },
|
||||
{ FLD_PF, DEVICE_CLS_POWER_FACTOR, STATE_CLS_MEASUREMENT },
|
||||
{ FLD_EFF, DEVICE_CLS_NONE, STATE_CLS_NONE },
|
||||
{ FLD_IRR, DEVICE_CLS_NONE, STATE_CLS_NONE },
|
||||
{ FLD_PRA, DEVICE_CLS_REACTIVE_POWER, STATE_CLS_MEASUREMENT }
|
||||
{ FLD_Q, DEVICE_CLS_REACTIVE_POWER, STATE_CLS_MEASUREMENT }
|
||||
};
|
||||
#define DEVICE_CLS_ASSIGN_LIST_LEN (sizeof(deviceFieldAssignment) / sizeof(byteAssign_fieldDeviceClass_t))
|
||||
|
||||
class MqttHandleHassClass {
|
||||
public:
|
||||
void init();
|
||||
void loop();
|
||||
MqttHandleHassClass();
|
||||
void init(Scheduler& scheduler);
|
||||
void publishConfig();
|
||||
void forceUpdate();
|
||||
|
||||
private:
|
||||
void publish(const String& subtopic, const String& payload);
|
||||
void publishField(std::shared_ptr<InverterAbstract> inv, ChannelType_t type, ChannelNum_t channel, byteAssign_fieldDeviceClass_t fieldType, bool clear = false);
|
||||
void publishInverterButton(std::shared_ptr<InverterAbstract> inv, const char* caption, const char* icon, const char* category, const char* deviceClass, const char* subTopic, const char* payload);
|
||||
void publishInverterNumber(std::shared_ptr<InverterAbstract> inv, const char* caption, const char* icon, const char* category, const char* commandTopic, const char* stateTopic, const char* unitOfMeasure, int16_t min = 1, int16_t max = 100);
|
||||
void publishInverterBinarySensor(std::shared_ptr<InverterAbstract> inv, const char* caption, const char* subTopic, const char* payload_on, const char* payload_off);
|
||||
void createDeviceInfo(JsonObject& object, std::shared_ptr<InverterAbstract> inv);
|
||||
void loop();
|
||||
static void publish(const String& subtopic, const String& payload);
|
||||
static void publish(const String& subtopic, const JsonDocument& doc);
|
||||
|
||||
static void addCommonMetadata(JsonDocument& doc, const String& unit_of_measure, const String& icon, const DeviceClassType device_class, const StateClassType state_class, const CategoryType category);
|
||||
|
||||
// Binary Sensor
|
||||
static void publishBinarySensor(JsonDocument& doc, const String& root_device, const String& unique_id_prefix, const String& name, const String& state_topic, const String& payload_on, const String& payload_off, const DeviceClassType device_class, const StateClassType state_class, const CategoryType category);
|
||||
static void publishDtuBinarySensor(const String& name, const String& state_topic, const String& payload_on, const String& payload_off, const DeviceClassType device_class, const StateClassType state_class, const CategoryType category);
|
||||
static void publishInverterBinarySensor(std::shared_ptr<InverterAbstract> inv, const String& name, const String& state_topic, const String& payload_on, const String& payload_off, const DeviceClassType device_class, const StateClassType state_class, const CategoryType category);
|
||||
|
||||
// Sensor
|
||||
static void publishSensor(JsonDocument& doc, const String& root_device, const String& unique_id_prefix, const String& name, const String& state_topic, const String& unit_of_measure, const String& icon, const DeviceClassType device_class, const StateClassType state_class, const CategoryType category);
|
||||
static void publishDtuSensor(const String& name, const String& state_topic, const String& unit_of_measure, const String& icon, const DeviceClassType device_class, const StateClassType state_class, const CategoryType category);
|
||||
static void publishInverterSensor(std::shared_ptr<InverterAbstract> inv, const String& name, const String& state_topic, const String& unit_of_measure, const String& icon, const DeviceClassType device_class, const StateClassType state_class, const CategoryType category);
|
||||
|
||||
static void publishInverterField(std::shared_ptr<InverterAbstract> inv, const ChannelType_t type, const ChannelNum_t channel, const byteAssign_fieldDeviceClass_t fieldType, const bool clear = false);
|
||||
static void publishInverterButton(std::shared_ptr<InverterAbstract> inv, const String& name, const String& state_topic, const String& payload, const String& icon, const DeviceClassType device_class, const StateClassType state_class, const CategoryType category);
|
||||
static void publishInverterNumber(std::shared_ptr<InverterAbstract> inv, const String& name, const String& state_topic, const String& command_topic, const int16_t min, const int16_t max, float step, const String& unit_of_measure, const String& icon, const StateClassType state_class, const CategoryType category);
|
||||
|
||||
static void createInverterInfo(JsonDocument& doc, std::shared_ptr<InverterAbstract> inv);
|
||||
static void createDtuInfo(JsonDocument& doc);
|
||||
|
||||
static void createDeviceInfo(JsonDocument& doc, const String& name, const String& identifiers, const String& configuration_url, const String& manufacturer, const String& model, const String& sw_version, const String& via_device = "");
|
||||
|
||||
static String getDtuUniqueId();
|
||||
static String getDtuUrl();
|
||||
|
||||
Task _loopTask;
|
||||
|
||||
bool _wasConnected = false;
|
||||
bool _updateForced = false;
|
||||
};
|
||||
|
||||
extern MqttHandleHassClass MqttHandleHass;
|
||||
extern MqttHandleHassClass MqttHandleHass;
|
||||
|
||||
@ -3,21 +3,28 @@
|
||||
|
||||
#include "Configuration.h"
|
||||
#include <Hoymiles.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
#include <espMqttClient.h>
|
||||
#include <frozen/map.h>
|
||||
#include <frozen/string.h>
|
||||
|
||||
class MqttHandleInverterClass {
|
||||
public:
|
||||
void init();
|
||||
void loop();
|
||||
MqttHandleInverterClass();
|
||||
void init(Scheduler& scheduler);
|
||||
|
||||
static String getTopic(std::shared_ptr<InverterAbstract> inv, ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId);
|
||||
static String getTopic(std::shared_ptr<InverterAbstract> inv, const ChannelType_t type, const ChannelNum_t channel, const FieldId_t fieldId);
|
||||
|
||||
void subscribeTopics();
|
||||
void unsubscribeTopics();
|
||||
|
||||
private:
|
||||
void publishField(std::shared_ptr<InverterAbstract> inv, ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId);
|
||||
void onMqttMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total);
|
||||
void loop();
|
||||
void publishField(std::shared_ptr<InverterAbstract> inv, const ChannelType_t type, const ChannelNum_t channel, const FieldId_t fieldId);
|
||||
|
||||
uint32_t _lastPublishStats[INV_MAX_COUNT];
|
||||
uint32_t _lastPublish;
|
||||
Task _loopTask;
|
||||
|
||||
uint32_t _lastPublishStats[INV_MAX_COUNT] = { 0 };
|
||||
|
||||
FieldId_t _publishFields[14] = {
|
||||
FLD_UDC,
|
||||
@ -33,8 +40,31 @@ private:
|
||||
FLD_PF,
|
||||
FLD_EFF,
|
||||
FLD_IRR,
|
||||
FLD_PRA
|
||||
FLD_Q
|
||||
};
|
||||
|
||||
enum class Topic : unsigned {
|
||||
LimitPersistentRelative,
|
||||
LimitPersistentAbsolute,
|
||||
LimitNonPersistentRelative,
|
||||
LimitNonPersistentAbsolute,
|
||||
Power,
|
||||
Restart,
|
||||
ResetRfStats,
|
||||
};
|
||||
|
||||
static constexpr frozen::string _cmdtopic = "+/cmd/";
|
||||
static constexpr frozen::map<frozen::string, Topic, 7> _subscriptions = {
|
||||
{ "limit_persistent_relative", Topic::LimitPersistentRelative },
|
||||
{ "limit_persistent_absolute", Topic::LimitPersistentAbsolute },
|
||||
{ "limit_nonpersistent_relative", Topic::LimitNonPersistentRelative },
|
||||
{ "limit_nonpersistent_absolute", Topic::LimitNonPersistentAbsolute },
|
||||
{ "power", Topic::Power },
|
||||
{ "restart", Topic::Restart },
|
||||
{ "reset_rf_stats", Topic::ResetRfStats },
|
||||
};
|
||||
|
||||
void onMqttMessage(Topic t, const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, const size_t len, const size_t index, const size_t total);
|
||||
};
|
||||
|
||||
extern MqttHandleInverterClass MqttHandleInverter;
|
||||
extern MqttHandleInverterClass MqttHandleInverter;
|
||||
|
||||
17
include/MqttHandleInverterTotal.h
Normal file
17
include/MqttHandleInverterTotal.h
Normal file
@ -0,0 +1,17 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class MqttHandleInverterTotalClass {
|
||||
public:
|
||||
MqttHandleInverterTotalClass();
|
||||
void init(Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
void loop();
|
||||
|
||||
Task _loopTask;
|
||||
};
|
||||
|
||||
extern MqttHandleInverterTotalClass MqttHandleInverterTotal;
|
||||
@ -5,6 +5,7 @@
|
||||
#include <MqttSubscribeParser.h>
|
||||
#include <Ticker.h>
|
||||
#include <espMqttClient.h>
|
||||
#include <mutex>
|
||||
|
||||
class MqttSettingsClass {
|
||||
public:
|
||||
@ -13,30 +14,30 @@ public:
|
||||
void performReconnect();
|
||||
bool getConnected();
|
||||
void publish(const String& subtopic, const String& payload);
|
||||
void publishGeneric(const String& topic, const String& payload, bool retain, uint8_t qos = 0);
|
||||
void publishGeneric(const String& topic, const String& payload, const bool retain, const uint8_t qos = 0);
|
||||
|
||||
void subscribe(const String& topic, uint8_t qos, const espMqttClientTypes::OnMessageCallback& cb);
|
||||
void subscribe(const String& topic, const uint8_t qos, const espMqttClientTypes::OnMessageCallback& cb);
|
||||
void unsubscribe(const String& topic);
|
||||
|
||||
String getPrefix();
|
||||
String getPrefix() const;
|
||||
String getClientId() const;
|
||||
|
||||
private:
|
||||
void NetworkEvent(network_event event);
|
||||
|
||||
void onMqttDisconnect(espMqttClientTypes::DisconnectReason reason);
|
||||
void onMqttConnect(bool sessionPresent);
|
||||
void onMqttMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total);
|
||||
void onMqttConnect(const bool sessionPresent);
|
||||
void onMqttMessage(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, const size_t len, const size_t index, const size_t total);
|
||||
|
||||
void performConnect();
|
||||
void performDisconnect();
|
||||
|
||||
void createMqttClientObject();
|
||||
|
||||
MqttClient* mqttClient = nullptr;
|
||||
String clientId;
|
||||
String willTopic;
|
||||
Ticker mqttReconnectTimer;
|
||||
MqttClient* _mqttClient = nullptr;
|
||||
Ticker _mqttReconnectTimer;
|
||||
MqttSubscribeParser _mqttSubscribeParser;
|
||||
std::mutex _clientLock;
|
||||
};
|
||||
|
||||
extern MqttSettingsClass MqttSettings;
|
||||
extern MqttSettingsClass MqttSettings;
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include "W5500.h"
|
||||
#include <DNSServer.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
#include <WiFi.h>
|
||||
#include <vector>
|
||||
|
||||
@ -22,59 +24,67 @@ enum class network_event {
|
||||
NETWORK_EVENT_MAX
|
||||
};
|
||||
|
||||
typedef std::function<void(network_event event)> NetworkEventCb;
|
||||
typedef std::function<void(network_event event)> DtuNetworkEventCb;
|
||||
|
||||
typedef struct NetworkEventCbList {
|
||||
NetworkEventCb cb;
|
||||
typedef struct DtuNetworkEventCbList {
|
||||
DtuNetworkEventCb cb;
|
||||
network_event event;
|
||||
|
||||
NetworkEventCbList()
|
||||
: cb(NULL)
|
||||
DtuNetworkEventCbList()
|
||||
: cb(nullptr)
|
||||
, event(network_event::NETWORK_UNKNOWN)
|
||||
{
|
||||
}
|
||||
} NetworkEventCbList_t;
|
||||
} DtuNetworkEventCbList_t;
|
||||
|
||||
class NetworkSettingsClass {
|
||||
public:
|
||||
NetworkSettingsClass();
|
||||
void init();
|
||||
void loop();
|
||||
void init(Scheduler& scheduler);
|
||||
void applyConfig();
|
||||
void enableAdminMode();
|
||||
String getApName();
|
||||
String getApName() const;
|
||||
|
||||
IPAddress localIP();
|
||||
IPAddress subnetMask();
|
||||
IPAddress gatewayIP();
|
||||
IPAddress dnsIP(uint8_t dns_no = 0);
|
||||
String macAddress();
|
||||
IPAddress localIP() const;
|
||||
IPAddress subnetMask() const;
|
||||
IPAddress gatewayIP() const;
|
||||
IPAddress dnsIP(const uint8_t dns_no = 0) const;
|
||||
String macAddress() const;
|
||||
static String getHostname();
|
||||
bool isConnected();
|
||||
network_mode NetworkMode();
|
||||
bool isConnected() const;
|
||||
network_mode NetworkMode() const;
|
||||
|
||||
bool onEvent(NetworkEventCb cbEvent, network_event event = network_event::NETWORK_EVENT_MAX);
|
||||
void raiseEvent(network_event event);
|
||||
bool onEvent(DtuNetworkEventCb cbEvent, const network_event event = network_event::NETWORK_EVENT_MAX);
|
||||
void raiseEvent(const network_event event);
|
||||
|
||||
private:
|
||||
void loop();
|
||||
void setHostname();
|
||||
void setStaticIp();
|
||||
void handleMDNS();
|
||||
void setupMode();
|
||||
void NetworkEvent(WiFiEvent_t event);
|
||||
bool adminEnabled = true;
|
||||
bool forceDisconnection = false;
|
||||
int adminTimeoutCounter = 0;
|
||||
int connectTimeoutTimer = 0;
|
||||
int connectRedoTimer = 0;
|
||||
uint32_t lastTimerCall = 0;
|
||||
const byte DNS_PORT = 53;
|
||||
IPAddress apIp;
|
||||
IPAddress apNetmask;
|
||||
std::unique_ptr<DNSServer> dnsServer;
|
||||
bool dnsServerStatus = false;
|
||||
void NetworkEvent(const WiFiEvent_t event, WiFiEventInfo_t info);
|
||||
|
||||
Task _loopTask;
|
||||
|
||||
static constexpr byte DNS_PORT = 53;
|
||||
|
||||
bool _adminEnabled = true;
|
||||
bool _forceDisconnection = false;
|
||||
uint32_t _adminTimeoutCounter = 0;
|
||||
uint32_t _adminTimeoutCounterMax = 0;
|
||||
uint32_t _connectTimeoutTimer = 0;
|
||||
uint32_t _connectRedoTimer = 0;
|
||||
uint32_t _lastTimerCall = 0;
|
||||
IPAddress _apIp;
|
||||
IPAddress _apNetmask;
|
||||
std::unique_ptr<DNSServer> _dnsServer;
|
||||
bool _dnsServerStatus = false;
|
||||
network_mode _networkMode = network_mode::Undefined;
|
||||
bool _ethConnected = false;
|
||||
std::vector<NetworkEventCbList_t> _cbEventList;
|
||||
std::vector<DtuNetworkEventCbList_t> _cbEventList;
|
||||
bool _lastMdnsEnabled = false;
|
||||
std::unique_ptr<W5500> _w5500;
|
||||
};
|
||||
|
||||
extern NetworkSettingsClass NetworkSettings;
|
||||
extern NetworkSettingsClass NetworkSettings;
|
||||
|
||||
@ -12,12 +12,29 @@
|
||||
|
||||
struct PinMapping_t {
|
||||
char name[MAPPING_NAME_STRLEN + 1];
|
||||
|
||||
int8_t nrf24_miso;
|
||||
int8_t nrf24_mosi;
|
||||
int8_t nrf24_clk;
|
||||
int8_t nrf24_irq;
|
||||
int8_t nrf24_en;
|
||||
int8_t nrf24_cs;
|
||||
|
||||
int8_t cmt_clk;
|
||||
int8_t cmt_cs;
|
||||
int8_t cmt_fcs;
|
||||
int8_t cmt_gpio2;
|
||||
int8_t cmt_gpio3;
|
||||
int8_t cmt_sdio;
|
||||
|
||||
int8_t w5500_mosi;
|
||||
int8_t w5500_miso;
|
||||
int8_t w5500_sclk;
|
||||
int8_t w5500_cs;
|
||||
int8_t w5500_int;
|
||||
int8_t w5500_rst;
|
||||
|
||||
#if CONFIG_ETH_USE_ESP32_EMAC
|
||||
int8_t eth_phy_addr;
|
||||
bool eth_enabled;
|
||||
int eth_power;
|
||||
@ -25,11 +42,14 @@ struct PinMapping_t {
|
||||
int eth_mdio;
|
||||
eth_phy_type_t eth_type;
|
||||
eth_clock_mode_t eth_clk_mode;
|
||||
#endif
|
||||
|
||||
uint8_t display_type;
|
||||
uint8_t display_data;
|
||||
uint8_t display_clk;
|
||||
uint8_t display_cs;
|
||||
uint8_t display_reset;
|
||||
|
||||
int8_t led[PINMAPPING_LED_COUNT];
|
||||
};
|
||||
|
||||
@ -39,11 +59,19 @@ public:
|
||||
bool init(const String& deviceMapping);
|
||||
PinMapping_t& get();
|
||||
|
||||
bool isValidNrf24Config();
|
||||
bool isValidEthConfig();
|
||||
bool isMappingSelected() const { return _mappingSelected; }
|
||||
|
||||
bool isValidNrf24Config() const;
|
||||
bool isValidCmt2300Config() const;
|
||||
bool isValidW5500Config() const;
|
||||
#if CONFIG_ETH_USE_ESP32_EMAC
|
||||
bool isValidEthConfig() const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
PinMapping_t _pinMapping;
|
||||
|
||||
bool _mappingSelected = false;
|
||||
};
|
||||
|
||||
extern PinMappingClass PinMapping;
|
||||
extern PinMappingClass PinMapping;
|
||||
|
||||
18
include/RestartHelper.h
Normal file
18
include/RestartHelper.h
Normal file
@ -0,0 +1,18 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class RestartHelperClass {
|
||||
public:
|
||||
RestartHelperClass();
|
||||
void init(Scheduler& scheduler);
|
||||
void triggerRestart();
|
||||
|
||||
private:
|
||||
void loop();
|
||||
|
||||
Task _rebootTask;
|
||||
};
|
||||
|
||||
extern RestartHelperClass RestartHelper;
|
||||
6
include/Scheduler.h
Normal file
6
include/Scheduler.h
Normal file
@ -0,0 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
extern Scheduler scheduler;
|
||||
@ -1,30 +1,36 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
#include <atomic>
|
||||
#include <sunset.h>
|
||||
|
||||
#define SUNPOS_UPDATE_INTERVAL 60000l
|
||||
|
||||
class SunPositionClass {
|
||||
public:
|
||||
SunPositionClass();
|
||||
void init();
|
||||
void loop();
|
||||
void init(Scheduler& scheduler);
|
||||
|
||||
bool isDayPeriod();
|
||||
bool sunsetTime(struct tm* info);
|
||||
bool sunriseTime(struct tm* info);
|
||||
bool isDayPeriod() const;
|
||||
bool isSunsetAvailable() const;
|
||||
bool sunsetTime(struct tm* info) const;
|
||||
bool sunriseTime(struct tm* info) const;
|
||||
void setDoRecalc(const bool doRecalc);
|
||||
|
||||
private:
|
||||
void loop();
|
||||
void updateSunData();
|
||||
bool checkRecalcDayChanged() const;
|
||||
bool getSunTime(struct tm* info, const uint32_t offset) const;
|
||||
|
||||
SunSet _sun;
|
||||
bool _isDayPeriod = true;
|
||||
uint _sunriseMinutes = 0;
|
||||
uint _sunsetMinutes = 0;
|
||||
Task _loopTask;
|
||||
|
||||
bool _isSunsetAvailable = true;
|
||||
uint32_t _sunriseMinutes = 0;
|
||||
uint32_t _sunsetMinutes = 0;
|
||||
|
||||
uint32_t _lastUpdate = 0;
|
||||
bool _isValidInfo = false;
|
||||
std::atomic_bool _doRecalc = true;
|
||||
uint32_t _lastSunPositionCalculatedYMD = 0;
|
||||
};
|
||||
|
||||
extern SunPositionClass SunPosition;
|
||||
extern SunPositionClass SunPosition;
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <LittleFS.h>
|
||||
#include <cstdint>
|
||||
|
||||
class Utils {
|
||||
@ -8,4 +10,8 @@ public:
|
||||
static uint32_t getChipId();
|
||||
static uint64_t generateDtuSerial();
|
||||
static int getTimezoneOffset();
|
||||
static bool checkJsonAlloc(const JsonDocument& doc, const char* function, const uint16_t line);
|
||||
static void removeAllFiles();
|
||||
static String generateMd5FromFile(String file);
|
||||
static void skipBom(File& f);
|
||||
};
|
||||
|
||||
29
include/W5500.h
Normal file
29
include/W5500.h
Normal file
@ -0,0 +1,29 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <driver/spi_master.h>
|
||||
#include <esp_eth.h> // required for esp_eth_handle_t
|
||||
#include <esp_netif.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
class W5500 {
|
||||
private:
|
||||
explicit W5500(spi_device_handle_t spi, gpio_num_t pin_int);
|
||||
|
||||
public:
|
||||
W5500(const W5500&) = delete;
|
||||
W5500& operator=(const W5500&) = delete;
|
||||
~W5500();
|
||||
|
||||
static std::unique_ptr<W5500> setup(int8_t pin_mosi, int8_t pin_miso, int8_t pin_sclk, int8_t pin_cs, int8_t pin_int, int8_t pin_rst);
|
||||
String macAddress();
|
||||
|
||||
private:
|
||||
static bool connection_check_spi(spi_device_handle_t spi);
|
||||
static bool connection_check_interrupt(gpio_num_t pin_int);
|
||||
|
||||
esp_eth_handle_t eth_handle;
|
||||
esp_netif_t* eth_netif;
|
||||
};
|
||||
@ -1,12 +1,15 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include "WebApi_config.h"
|
||||
#include "WebApi_device.h"
|
||||
#include "WebApi_devinfo.h"
|
||||
#include "WebApi_dtu.h"
|
||||
#include "WebApi_errors.h"
|
||||
#include "WebApi_eventlog.h"
|
||||
#include "WebApi_file.h"
|
||||
#include "WebApi_firmware.h"
|
||||
#include "WebApi_device.h"
|
||||
#include "WebApi_gridprofile.h"
|
||||
#include "WebApi_i18n.h"
|
||||
#include "WebApi_inverter.h"
|
||||
#include "WebApi_limit.h"
|
||||
#include "WebApi_maintenance.h"
|
||||
@ -20,29 +23,38 @@
|
||||
#include "WebApi_webapp.h"
|
||||
#include "WebApi_ws_console.h"
|
||||
#include "WebApi_ws_live.h"
|
||||
#include <AsyncJson.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiClass {
|
||||
public:
|
||||
WebApiClass();
|
||||
void init();
|
||||
void loop();
|
||||
void init(Scheduler& scheduler);
|
||||
void reload();
|
||||
|
||||
static bool checkCredentials(AsyncWebServerRequest* request);
|
||||
static bool checkCredentialsReadonly(AsyncWebServerRequest* request);
|
||||
|
||||
static void sendTooManyRequests(AsyncWebServerRequest* request);
|
||||
|
||||
static void writeConfig(JsonVariant& retMsg, const WebApiError code = WebApiError::GenericSuccess, const String& message = "Settings saved!");
|
||||
|
||||
static bool parseRequestData(AsyncWebServerRequest* request, AsyncJsonResponse* response, JsonDocument& json_document);
|
||||
static uint64_t parseSerialFromRequest(AsyncWebServerRequest* request, String param_name = "inv");
|
||||
static bool sendJsonResponse(AsyncWebServerRequest* request, AsyncJsonResponse* response, const char* function, const uint16_t line);
|
||||
|
||||
private:
|
||||
AsyncWebServer _server;
|
||||
AsyncEventSource _events;
|
||||
|
||||
WebApiConfigClass _webApiConfig;
|
||||
WebApiDeviceClass _webApiDevice;
|
||||
WebApiDevInfoClass _webApiDevInfo;
|
||||
WebApiDtuClass _webApiDtu;
|
||||
WebApiEventlogClass _webApiEventlog;
|
||||
WebApiFileClass _webApiFile;
|
||||
WebApiFirmwareClass _webApiFirmware;
|
||||
WebApiGridProfileClass _webApiGridprofile;
|
||||
WebApiI18nClass _webApiI18n;
|
||||
WebApiInverterClass _webApiInverter;
|
||||
WebApiLimitClass _webApiLimit;
|
||||
WebApiMaintenanceClass _webApiMaintenance;
|
||||
@ -58,4 +70,4 @@ private:
|
||||
WebApiWsLiveClass _webApiWsLive;
|
||||
};
|
||||
|
||||
extern WebApiClass WebApi;
|
||||
extern WebApiClass WebApi;
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
|
||||
class WebApiConfigClass {
|
||||
public:
|
||||
void init(AsyncWebServer* server);
|
||||
void loop();
|
||||
|
||||
private:
|
||||
void onConfigGet(AsyncWebServerRequest* request);
|
||||
void onConfigDelete(AsyncWebServerRequest* request);
|
||||
void onConfigListGet(AsyncWebServerRequest* request);
|
||||
void onConfigUploadFinish(AsyncWebServerRequest* request);
|
||||
void onConfigUpload(AsyncWebServerRequest* request, String filename, size_t index, uint8_t* data, size_t len, bool final);
|
||||
|
||||
AsyncWebServer* _server;
|
||||
};
|
||||
@ -2,15 +2,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiDeviceClass {
|
||||
public:
|
||||
void init(AsyncWebServer* server);
|
||||
void loop();
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
void onDeviceAdminGet(AsyncWebServerRequest* request);
|
||||
void onDeviceAdminPost(AsyncWebServerRequest* request);
|
||||
|
||||
AsyncWebServer* _server;
|
||||
};
|
||||
};
|
||||
|
||||
@ -2,14 +2,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiDevInfoClass {
|
||||
public:
|
||||
void init(AsyncWebServer* server);
|
||||
void loop();
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
void onDevInfoStatus(AsyncWebServerRequest* request);
|
||||
|
||||
AsyncWebServer* _server;
|
||||
};
|
||||
};
|
||||
|
||||
@ -2,15 +2,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiDtuClass {
|
||||
public:
|
||||
void init(AsyncWebServer* server);
|
||||
void loop();
|
||||
WebApiDtuClass();
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
void onDtuAdminGet(AsyncWebServerRequest* request);
|
||||
void onDtuAdminPost(AsyncWebServerRequest* request);
|
||||
|
||||
AsyncWebServer* _server;
|
||||
};
|
||||
Task _applyDataTask;
|
||||
void applyDataTaskCb();
|
||||
};
|
||||
|
||||
@ -5,18 +5,23 @@ enum WebApiError {
|
||||
GenericBase = 1000,
|
||||
GenericSuccess,
|
||||
GenericNoValueFound,
|
||||
GenericDataTooLarge,
|
||||
GenericDataTooLarge, // not used anymore
|
||||
GenericParseError,
|
||||
GenericValueMissing,
|
||||
GenericWriteFailed,
|
||||
GenericInternalServerError,
|
||||
|
||||
DtuBase = 2000,
|
||||
DtuSerialZero,
|
||||
DtuPollZero,
|
||||
DtuInvalidPowerLevel,
|
||||
DtuInvalidCmtFrequency,
|
||||
DtuInvalidCmtCountry,
|
||||
|
||||
ConfigBase = 3000,
|
||||
ConfigNotDeleted,
|
||||
ConfigSuccess,
|
||||
FileBase = 3000,
|
||||
FileNotDeleted,
|
||||
FileSuccess,
|
||||
FileDeleteSuccess,
|
||||
|
||||
InverterBase = 4000,
|
||||
InverterSerialZero,
|
||||
@ -27,6 +32,8 @@ enum WebApiError {
|
||||
InverterInvalidMaxChannel,
|
||||
InverterChanged,
|
||||
InverterDeleted,
|
||||
InverterOrdered,
|
||||
InverterStatsResetted,
|
||||
|
||||
LimitBase = 5000,
|
||||
LimitSerialZero,
|
||||
@ -54,6 +61,8 @@ enum WebApiError {
|
||||
MqttPublishInterval,
|
||||
MqttHassTopicLength,
|
||||
MqttHassTopicCharacter,
|
||||
MqttLwtQos,
|
||||
MqttClientIdLength,
|
||||
|
||||
NetworkBase = 8000,
|
||||
NetworkIpInvalid,
|
||||
@ -61,6 +70,7 @@ enum WebApiError {
|
||||
NetworkGatewayInvalid,
|
||||
NetworkDns1Invalid,
|
||||
NetworkDns2Invalid,
|
||||
NetworkApTimeoutInvalid,
|
||||
|
||||
NtpBase = 9000,
|
||||
NtpServerLength,
|
||||
@ -84,4 +94,4 @@ enum WebApiError {
|
||||
|
||||
HardwareBase = 12000,
|
||||
HardwarePinMappingLength,
|
||||
};
|
||||
};
|
||||
|
||||
@ -2,14 +2,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiEventlogClass {
|
||||
public:
|
||||
void init(AsyncWebServer* server);
|
||||
void loop();
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
void onEventlogStatus(AsyncWebServerRequest* request);
|
||||
|
||||
AsyncWebServer* _server;
|
||||
};
|
||||
};
|
||||
|
||||
18
include/WebApi_file.h
Normal file
18
include/WebApi_file.h
Normal file
@ -0,0 +1,18 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiFileClass {
|
||||
public:
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
void onFileGet(AsyncWebServerRequest* request);
|
||||
void onFileDelete(AsyncWebServerRequest* request);
|
||||
void onFileDeleteAll(AsyncWebServerRequest* request);
|
||||
void onFileListGet(AsyncWebServerRequest* request);
|
||||
void onFileUploadFinish(AsyncWebServerRequest* request);
|
||||
void onFileUpload(AsyncWebServerRequest* request, String filename, size_t index, uint8_t* data, size_t len, bool final);
|
||||
};
|
||||
@ -2,15 +2,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiFirmwareClass {
|
||||
public:
|
||||
void init(AsyncWebServer* server);
|
||||
void loop();
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
void onFirmwareUpdateFinish(AsyncWebServerRequest* request);
|
||||
void onFirmwareUpdateUpload(AsyncWebServerRequest* request, String filename, size_t index, uint8_t* data, size_t len, bool final);
|
||||
|
||||
AsyncWebServer* _server;
|
||||
};
|
||||
};
|
||||
|
||||
14
include/WebApi_gridprofile.h
Normal file
14
include/WebApi_gridprofile.h
Normal file
@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiGridProfileClass {
|
||||
public:
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
void onGridProfileStatus(AsyncWebServerRequest* request);
|
||||
void onGridProfileRawdata(AsyncWebServerRequest* request);
|
||||
};
|
||||
14
include/WebApi_i18n.h
Normal file
14
include/WebApi_i18n.h
Normal file
@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiI18nClass {
|
||||
public:
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
void onI18nLanguages(AsyncWebServerRequest* request);
|
||||
void onI18nLanguage(AsyncWebServerRequest* request);
|
||||
};
|
||||
@ -2,17 +2,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiInverterClass {
|
||||
public:
|
||||
void init(AsyncWebServer* server);
|
||||
void loop();
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
void onInverterList(AsyncWebServerRequest* request);
|
||||
void onInverterAdd(AsyncWebServerRequest* request);
|
||||
void onInverterEdit(AsyncWebServerRequest* request);
|
||||
void onInverterDelete(AsyncWebServerRequest* request);
|
||||
|
||||
AsyncWebServer* _server;
|
||||
};
|
||||
void onInverterOrder(AsyncWebServerRequest* request);
|
||||
void onInverterStatReset(AsyncWebServerRequest* request);
|
||||
};
|
||||
|
||||
@ -2,15 +2,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiLimitClass {
|
||||
public:
|
||||
void init(AsyncWebServer* server);
|
||||
void loop();
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
void onLimitStatus(AsyncWebServerRequest* request);
|
||||
void onLimitPost(AsyncWebServerRequest* request);
|
||||
|
||||
AsyncWebServer* _server;
|
||||
};
|
||||
};
|
||||
|
||||
@ -2,14 +2,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiMaintenanceClass {
|
||||
public:
|
||||
void init(AsyncWebServer* server);
|
||||
void loop();
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
void onRebootPost(AsyncWebServerRequest* request);
|
||||
|
||||
AsyncWebServer* _server;
|
||||
};
|
||||
};
|
||||
|
||||
@ -2,19 +2,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
|
||||
#define MQTT_JSON_DOC_SIZE 10240
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiMqttClass {
|
||||
public:
|
||||
void init(AsyncWebServer* server);
|
||||
void loop();
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
void onMqttStatus(AsyncWebServerRequest* request);
|
||||
void onMqttAdminGet(AsyncWebServerRequest* request);
|
||||
void onMqttAdminPost(AsyncWebServerRequest* request);
|
||||
String getTlsCertInfo(const char* cert);
|
||||
|
||||
AsyncWebServer* _server;
|
||||
};
|
||||
};
|
||||
|
||||
@ -2,16 +2,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiNetworkClass {
|
||||
public:
|
||||
void init(AsyncWebServer* server);
|
||||
void loop();
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
void onNetworkStatus(AsyncWebServerRequest* request);
|
||||
void onNetworkAdminGet(AsyncWebServerRequest* request);
|
||||
void onNetworkAdminPost(AsyncWebServerRequest* request);
|
||||
|
||||
AsyncWebServer* _server;
|
||||
};
|
||||
};
|
||||
|
||||
@ -2,11 +2,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiNtpClass {
|
||||
public:
|
||||
void init(AsyncWebServer* server);
|
||||
void loop();
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
void onNtpStatus(AsyncWebServerRequest* request);
|
||||
@ -14,6 +14,4 @@ private:
|
||||
void onNtpAdminPost(AsyncWebServerRequest* request);
|
||||
void onNtpTimeGet(AsyncWebServerRequest* request);
|
||||
void onNtpTimePost(AsyncWebServerRequest* request);
|
||||
|
||||
AsyncWebServer* _server;
|
||||
};
|
||||
};
|
||||
|
||||
@ -2,15 +2,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiPowerClass {
|
||||
public:
|
||||
void init(AsyncWebServer* server);
|
||||
void loop();
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
void onPowerStatus(AsyncWebServerRequest* request);
|
||||
void onPowerPost(AsyncWebServerRequest* request);
|
||||
|
||||
AsyncWebServer* _server;
|
||||
};
|
||||
};
|
||||
|
||||
@ -3,43 +3,46 @@
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <Hoymiles.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
#include <map>
|
||||
|
||||
class WebApiPrometheusClass {
|
||||
public:
|
||||
void init(AsyncWebServer* server);
|
||||
void loop();
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
void onPrometheusMetricsGet(AsyncWebServerRequest* request);
|
||||
|
||||
void addField(AsyncResponseStream* stream, String& serial, uint8_t idx, std::shared_ptr<InverterAbstract> inv, ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId, const char* channelName = NULL);
|
||||
void addField(AsyncResponseStream* stream, const String& serial, const uint8_t idx, std::shared_ptr<InverterAbstract> inv, const ChannelType_t type, const ChannelNum_t channel, const FieldId_t fieldId, const char* metricName, const char* channelName = nullptr);
|
||||
|
||||
void addPanelInfo(AsyncResponseStream* stream, String& serial, uint8_t idx, std::shared_ptr<InverterAbstract> inv, ChannelType_t type, ChannelNum_t channel);
|
||||
void addPanelInfo(AsyncResponseStream* stream, const String& serial, const uint8_t idx, std::shared_ptr<InverterAbstract> inv, const ChannelType_t type, const ChannelNum_t channel);
|
||||
|
||||
AsyncWebServer* _server;
|
||||
|
||||
enum {
|
||||
METRIC_TYPE_NONE = 0,
|
||||
METRIC_TYPE_GAUGE,
|
||||
METRIC_TYPE_COUNTER,
|
||||
enum MetricType_t {
|
||||
NONE = 0,
|
||||
GAUGE,
|
||||
COUNTER,
|
||||
};
|
||||
const char* _metricTypes[3] = { 0, "gauge", "counter" };
|
||||
|
||||
std::map<FieldId_t, uint8_t> _fieldMetricAssignment {
|
||||
{ FLD_UDC, METRIC_TYPE_GAUGE },
|
||||
{ FLD_IDC, METRIC_TYPE_GAUGE },
|
||||
{ FLD_PDC, METRIC_TYPE_GAUGE },
|
||||
{ FLD_YD, METRIC_TYPE_COUNTER },
|
||||
{ FLD_YT, METRIC_TYPE_COUNTER },
|
||||
{ FLD_UAC, METRIC_TYPE_GAUGE },
|
||||
{ FLD_IAC, METRIC_TYPE_GAUGE },
|
||||
{ FLD_PAC, METRIC_TYPE_GAUGE },
|
||||
{ FLD_F, METRIC_TYPE_GAUGE },
|
||||
{ FLD_T, METRIC_TYPE_GAUGE },
|
||||
{ FLD_PF, METRIC_TYPE_GAUGE },
|
||||
{ FLD_EFF, METRIC_TYPE_GAUGE },
|
||||
{ FLD_IRR, METRIC_TYPE_GAUGE },
|
||||
{ FLD_PRA, METRIC_TYPE_GAUGE }
|
||||
struct publish_type_t {
|
||||
FieldId_t field;
|
||||
MetricType_t type;
|
||||
};
|
||||
};
|
||||
|
||||
const publish_type_t _publishFields[14] = {
|
||||
{ FLD_PAC, MetricType_t::GAUGE },
|
||||
{ FLD_UAC, MetricType_t::GAUGE },
|
||||
{ FLD_IAC, MetricType_t::GAUGE },
|
||||
{ FLD_PDC, MetricType_t::GAUGE },
|
||||
{ FLD_UDC, MetricType_t::GAUGE },
|
||||
{ FLD_IDC, MetricType_t::GAUGE },
|
||||
{ FLD_YD, MetricType_t::COUNTER },
|
||||
{ FLD_YT, MetricType_t::COUNTER },
|
||||
{ FLD_F, MetricType_t::GAUGE },
|
||||
{ FLD_T, MetricType_t::GAUGE },
|
||||
{ FLD_PF, MetricType_t::GAUGE },
|
||||
{ FLD_Q, MetricType_t::GAUGE },
|
||||
{ FLD_EFF, MetricType_t::GAUGE },
|
||||
{ FLD_IRR, MetricType_t::GAUGE },
|
||||
};
|
||||
};
|
||||
|
||||
@ -2,17 +2,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiSecurityClass {
|
||||
public:
|
||||
void init(AsyncWebServer* server);
|
||||
void loop();
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
void onSecurityGet(AsyncWebServerRequest* request);
|
||||
void onSecurityPost(AsyncWebServerRequest* request);
|
||||
|
||||
void onAuthenticateGet(AsyncWebServerRequest* request);
|
||||
|
||||
AsyncWebServer* _server;
|
||||
};
|
||||
};
|
||||
|
||||
@ -2,14 +2,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiSysstatusClass {
|
||||
public:
|
||||
void init(AsyncWebServer* server);
|
||||
void loop();
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
void onSystemStatus(AsyncWebServerRequest* request);
|
||||
|
||||
AsyncWebServer* _server;
|
||||
};
|
||||
};
|
||||
|
||||
@ -2,12 +2,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiWebappClass {
|
||||
public:
|
||||
void init(AsyncWebServer* server);
|
||||
void loop();
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
|
||||
private:
|
||||
AsyncWebServer* _server;
|
||||
};
|
||||
void responseBinaryDataWithETagCache(AsyncWebServerRequest* request, const String &contentType, const String &contentEncoding, const uint8_t *content, size_t len);
|
||||
};
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
|
||||
class WebApiWsConsoleClass {
|
||||
public:
|
||||
WebApiWsConsoleClass();
|
||||
void init(AsyncWebServer* server);
|
||||
void loop();
|
||||
|
||||
private:
|
||||
void onWebsocketEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len);
|
||||
|
||||
AsyncWebServer* _server;
|
||||
AsyncWebSocket _ws;
|
||||
|
||||
uint32_t _lastWsCleanup = 0;
|
||||
};
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiWsConsoleClass {
|
||||
public:
|
||||
WebApiWsConsoleClass();
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
void reload();
|
||||
|
||||
private:
|
||||
AsyncWebSocket _ws;
|
||||
AsyncAuthenticationMiddleware _simpleDigestAuth;
|
||||
|
||||
Task _wsCleanupTask;
|
||||
void wsCleanupTaskCb();
|
||||
};
|
||||
|
||||
@ -1,28 +1,39 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include "Configuration.h"
|
||||
#include <ArduinoJson.h>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <Hoymiles.h>
|
||||
#include <TaskSchedulerDeclarations.h>
|
||||
|
||||
class WebApiWsLiveClass {
|
||||
public:
|
||||
WebApiWsLiveClass();
|
||||
void init(AsyncWebServer* server);
|
||||
void loop();
|
||||
void init(AsyncWebServer& server, Scheduler& scheduler);
|
||||
void reload();
|
||||
|
||||
private:
|
||||
void generateJsonResponse(JsonVariant& root);
|
||||
void addField(JsonObject& root, uint8_t idx, std::shared_ptr<InverterAbstract> inv, ChannelType_t type, ChannelNum_t channel, FieldId_t fieldId, String topic = "");
|
||||
void addTotalField(JsonObject& root, String name, float value, String unit, uint8_t digits);
|
||||
static void generateInverterCommonJsonResponse(JsonObject& root, std::shared_ptr<InverterAbstract> inv);
|
||||
static void generateInverterChannelJsonResponse(JsonObject& root, std::shared_ptr<InverterAbstract> inv);
|
||||
static void generateCommonJsonResponse(JsonVariant& root);
|
||||
|
||||
static void addField(JsonObject& root, std::shared_ptr<InverterAbstract> inv, const ChannelType_t type, const ChannelNum_t channel, const FieldId_t fieldId, String topic = "");
|
||||
static void addTotalField(JsonObject& root, const String& name, const float value, const String& unit, const uint8_t digits);
|
||||
|
||||
void onLivedataStatus(AsyncWebServerRequest* request);
|
||||
void onWebsocketEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len);
|
||||
|
||||
AsyncWebServer* _server;
|
||||
AsyncWebSocket _ws;
|
||||
AsyncAuthenticationMiddleware _simpleDigestAuth;
|
||||
|
||||
uint32_t _lastWsPublish = 0;
|
||||
uint32_t _lastInvUpdateCheck = 0;
|
||||
uint32_t _lastWsCleanup = 0;
|
||||
uint32_t _newestInverterTimestamp = 0;
|
||||
};
|
||||
uint32_t _lastPublishStats[INV_MAX_COUNT] = { 0 };
|
||||
|
||||
std::mutex _mutex;
|
||||
|
||||
Task _wsCleanupTask;
|
||||
void wsCleanupTaskCb();
|
||||
|
||||
Task _sendDataTask;
|
||||
void sendDataTaskCb();
|
||||
};
|
||||
|
||||
9
include/__compiled_constants.h
Normal file
9
include/__compiled_constants.h
Normal file
@ -0,0 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
// The referenced values are generated by pio-scripts/auto_firmware_version.py
|
||||
|
||||
|
||||
extern const char *__COMPILED_GIT_HASH__;
|
||||
extern const char *__COMPILED_GIT_BRANCH__;
|
||||
// extern const char *__COMPILED_DATE_TIME_UTC_STR__;
|
||||
@ -9,26 +9,30 @@
|
||||
|
||||
#define ACCESS_POINT_NAME "OpenDTU-"
|
||||
#define ACCESS_POINT_PASSWORD "openDTU42"
|
||||
#define ACCESS_POINT_TIMEOUT 3
|
||||
#define AUTH_USERNAME "admin"
|
||||
#define SECURITY_ALLOW_READONLY true
|
||||
|
||||
#define ADMIN_TIMEOUT 180
|
||||
#define WIFI_RECONNECT_TIMEOUT 15
|
||||
#define WIFI_RECONNECT_TIMEOUT 30
|
||||
#define WIFI_RECONNECT_REDO_TIMEOUT 600
|
||||
|
||||
#define WIFI_SSID ""
|
||||
#define WIFI_PASSWORD ""
|
||||
#define WIFI_DHCP true
|
||||
|
||||
#define NTP_SERVER "pool.ntp.org"
|
||||
#define MDNS_ENABLED false
|
||||
|
||||
#define NTP_SERVER_OLD "pool.ntp.org"
|
||||
#define NTP_SERVER "opendtu.pool.ntp.org"
|
||||
#define NTP_TIMEZONE "CET-1CEST,M3.5.0,M10.5.0/3"
|
||||
#define NTP_TIMEZONEDESCR "Europe/Berlin"
|
||||
#define NTP_LONGITUDE 10.4515f
|
||||
#define NTP_LATITUDE 51.1657f
|
||||
#define NTP_SUNSETTYPE 1U
|
||||
|
||||
#define MQTT_ENABLED false
|
||||
#define MQTT_HOST ""
|
||||
#define MQTT_PORT 1883
|
||||
#define MQTT_PORT 1883U
|
||||
#define MQTT_USER ""
|
||||
#define MQTT_PASSWORD ""
|
||||
#define MQTT_TOPIC "solar/"
|
||||
@ -72,11 +76,16 @@
|
||||
#define MQTT_LWT_TOPIC "dtu/status"
|
||||
#define MQTT_LWT_ONLINE "online"
|
||||
#define MQTT_LWT_OFFLINE "offline"
|
||||
#define MQTT_PUBLISH_INTERVAL 5
|
||||
#define MQTT_LWT_QOS 2U
|
||||
#define MQTT_PUBLISH_INTERVAL 5U
|
||||
#define MQTT_CLEAN_SESSION true
|
||||
|
||||
#define DTU_SERIAL 0x99978563412
|
||||
#define DTU_POLL_INTERVAL 5
|
||||
#define DTU_PA_LEVEL 0
|
||||
#define DTU_SERIAL 0x99978563412U
|
||||
#define DTU_POLL_INTERVAL 5U
|
||||
#define DTU_NRF_PA_LEVEL 0U
|
||||
#define DTU_CMT_PA_LEVEL 0
|
||||
#define DTU_CMT_FREQUENCY 865000000U
|
||||
#define DTU_CMT_COUNTRY_MODE 0U
|
||||
|
||||
#define MQTT_HASS_ENABLED false
|
||||
#define MQTT_HASS_EXPIRE true
|
||||
@ -88,5 +97,16 @@
|
||||
|
||||
#define DISPLAY_POWERSAFE true
|
||||
#define DISPLAY_SCREENSAVER true
|
||||
#define DISPLAY_ROTATION 2
|
||||
#define DISPLAY_CONTRAST 60
|
||||
#define DISPLAY_ROTATION 2U
|
||||
#define DISPLAY_CONTRAST 60U
|
||||
#define DISPLAY_LOCALE "en"
|
||||
#define DISPLAY_DIAGRAM_DURATION (10UL * 60UL * 60UL)
|
||||
#define DISPLAY_DIAGRAM_MODE 1U
|
||||
|
||||
#define REACHABLE_THRESHOLD 2U
|
||||
|
||||
#define LED_BRIGHTNESS 100U
|
||||
|
||||
#define MAX_INVERTER_LIMIT 2250
|
||||
|
||||
#define LANG_PACK_SUFFIX ".lang.json"
|
||||
|
||||
9
lang/README.md
Normal file
9
lang/README.md
Normal file
@ -0,0 +1,9 @@
|
||||
# Language Packs
|
||||
|
||||
This folder contains language packs for OpenDTU which can be uploaded to the
|
||||
device using the "Config Management" function.
|
||||
Select "Language Pack" in the restore section, select a `.json` file containing
|
||||
your language and press "Restore". Afterwards all language selection drop down
|
||||
menues contain the new language.
|
||||
|
||||
Create a pull to request to share your own language pack (or corrections) with the community.
|
||||
696
lang/es.lang.json
Normal file
696
lang/es.lang.json
Normal file
@ -0,0 +1,696 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Español",
|
||||
"code": "es"
|
||||
},
|
||||
"display": {
|
||||
"date_format": "%d/%m/%Y %H:%M",
|
||||
"offline": "Apagado",
|
||||
"power_w": "%.0f W",
|
||||
"power_kw": "%.1f kW",
|
||||
"yield_today_wh": "Hoy: %4.0f Wh",
|
||||
"yield_today_kwh": "Hoy: %.1f kWh",
|
||||
"yield_total_kwh": "Total: %.1f kWh",
|
||||
"yield_total_mwh": "Total: %.0f kWh"
|
||||
},
|
||||
"webapp": {
|
||||
"menu": {
|
||||
"LiveView": "Vista en directo",
|
||||
"Settings": "Ajustes",
|
||||
"NetworkSettings": "Ajustes de Red",
|
||||
"NTPSettings": "Ajustes NTP",
|
||||
"MQTTSettings": "Ajustes MQTT",
|
||||
"InverterSettings": "Ajustes Inversor",
|
||||
"SecuritySettings": "Ajustes Seguridad",
|
||||
"DTUSettings": "Ajustes DTU",
|
||||
"DeviceManager": "Administrador Dispositivos",
|
||||
"ConfigManagement": "Gestión configuración",
|
||||
"FirmwareUpgrade": "Actualización Firmware",
|
||||
"DeviceReboot": "Reinicio Dispositivo",
|
||||
"Info": "Info",
|
||||
"System": "Sistema",
|
||||
"Network": "Red",
|
||||
"NTP": "NTP",
|
||||
"MQTT": "MQTT",
|
||||
"Console": "Consola",
|
||||
"About": "Acerca",
|
||||
"Logout": "Logout",
|
||||
"Login": "Login"
|
||||
},
|
||||
"base": {
|
||||
"Loading": "Cargando...",
|
||||
"Reload": "Recargar",
|
||||
"Cancel": "Cancelar",
|
||||
"Save": "Guardar",
|
||||
"Refreshing": "Refrescando",
|
||||
"Pull": "Tira hacia abajo para refrescar",
|
||||
"Release": "Soltar para refrescar",
|
||||
"Close": "Cerrar",
|
||||
"Yes": "Yes",
|
||||
"No": "No"
|
||||
},
|
||||
"wait": {
|
||||
"NotReady": "OpenDTU is not yet ready",
|
||||
"PleaseWait": "Please wait. You will be automatically redirected to the home page."
|
||||
},
|
||||
"Error": {
|
||||
"Oops": "Oops!"
|
||||
},
|
||||
"localeswitcher": {
|
||||
"Dark": "Oscuro",
|
||||
"Light": "Claro",
|
||||
"Auto": "Automático"
|
||||
},
|
||||
"apiresponse": {
|
||||
"1001": "¡Opciones guardadas!",
|
||||
"1002": "No se encontraron valores",
|
||||
"1003": "Datos demasiado grandes",
|
||||
"1004": "Fallo al procesar los datos",
|
||||
"1005": "Faltan valores",
|
||||
"1006": "Fallo en la escritura",
|
||||
"2001": "¡El número de serie no puede ser cero!",
|
||||
"2002": "Intervalo de Poll interval debe ser mayor que cero!",
|
||||
"2003": "Configuración de potencia incorrecta!",
|
||||
"2004": "La frecuencia debe estar entre {min} y {max} kHz y debe ser un múltiplo de 250 kHz!",
|
||||
"2005": "Modelo desconocido! Por favor, informe el \"Modelo de pieza de hardware\" y el modelo (por ejemplo, HM-350) como un problema en <a href=\"https://github.com/tbnobody/OpenDTU/issues\" target=\"_blank\">aquí</a>.",
|
||||
"3001": "No se eliminó nada",
|
||||
"3002": "Configuración borrada. Reinicio en curso...",
|
||||
"4001": "@:apiresponse.2001",
|
||||
"4002": "El nombre debe tener entre 1 y {max} caracteres de longitud!",
|
||||
"4003": "Solo se admiten {max} inversores!",
|
||||
"4004": "Inversor creado!",
|
||||
"4005": "ID no válido especificado",
|
||||
"4006": "Cantidad de canales máxima incorrecta dada!",
|
||||
"4007": "Inversor modificado!",
|
||||
"4008": "Inversor eliminado!",
|
||||
"4009": "Orden de inversores guardado!",
|
||||
"5001": "@:apiresponse.2001",
|
||||
"5002": "Límite debe estar entre 1 y {max}!",
|
||||
"5003": "Tipo incorrecto especificado!",
|
||||
"5004": "Inversor incorrecto especificado!",
|
||||
"6001": "Reinicio desencadenado!",
|
||||
"6002": "Reinicio cancelado!",
|
||||
"7001": "¡El servidor MQTT debe tener entre 1 y {max} caracteres de longitud!",
|
||||
"7002": "¡El nombre de usuario debe no tener más de {max} caracteres!",
|
||||
"7003": "¡La contraseña debe no tener más de {max} caracteres!",
|
||||
"7004": "¡El tema debe tener entre 1 y {max} caracteres de longitud!",
|
||||
"7005": "¡El tema no debe contener caracteres de espacio!",
|
||||
"7006": "¡El tema debe terminar con barra inclinada (/)!",
|
||||
"7007": "¡El puerto debe ser un número entre 1 y 65535!",
|
||||
"7008": "¡El certificado debe tener entre 1 y {max} caracteres de longitud!",
|
||||
"7009": "¡El tema LWT debe tener entre 1 y {max} caracteres de longitud!",
|
||||
"7010": "¡El tema LWT no debe contener caracteres de espacio!",
|
||||
"7011": "¡El valor LWT en línea debe tener entre 1 y {max} caracteres de longitud!",
|
||||
"7012": "¡El valor LWT fuera de línea debe tener entre 1 y {max} caracteres de longitud!",
|
||||
"7013": "¡El intervalo de publicación debe ser un número entre {min} y {max}!",
|
||||
"7014": "¡El tema Hass debe tener entre 1 y {max} caracteres de longitud!",
|
||||
"7015": "¡El tema Hass no debe contener caracteres de espacio!",
|
||||
"7016": "¡La QoS LWT no debe ser mayor que {max}!",
|
||||
"7017": "Client ID must not longer then {max} characters!",
|
||||
"8001": "¡La dirección IP no es válida!",
|
||||
"8002": "¡La máscara de red no es válida!",
|
||||
"8003": "¡El gateway no es válido!",
|
||||
"8004": "¡La dirección IP del servidor DNS 1 no es válida!",
|
||||
"8005": "¡La dirección IP del servidor DNS 2 no es válida!",
|
||||
"8006": "¡El valor de tiempo de espera del punto de acceso administrativo es inválido!",
|
||||
"9001": "¡El servidor NTP debe tener entre 1 y {max} caracteres de longitud!",
|
||||
"9002": "¡La zona horaria debe tener entre 1 y {max} caracteres de longitud!",
|
||||
"9003": "¡La descripción de la zona horaria debe tener entre 1 y {max} caracteres de longitud!",
|
||||
"9004": "¡El año debe ser un número entre {min} y {max}!",
|
||||
"9005": "¡El mes debe ser un número entre {min} y {max}!",
|
||||
"9006": "¡El día debe ser un número entre {min} y {max}!",
|
||||
"9007": "¡La hora debe ser un número entre {min} y {max}!",
|
||||
"9008": "¡Los minutos deben ser un número entre {min} y {max}!",
|
||||
"9009": "¡Los segundos deben ser un número entre {min} y {max}!",
|
||||
"9010": "¡Hora actualizada!",
|
||||
"10001": "¡La contraseña debe tener entre 8 y {max} caracteres de longitud!",
|
||||
"10002": "¡Autenticación exitosa!",
|
||||
"11001": "¡@:apiresponse.2001",
|
||||
"11002": "¡@:apiresponse:5004",
|
||||
"12001": "¡El perfil debe tener entre 1 y {max} caracteres de longitud!"
|
||||
},
|
||||
"home": {
|
||||
"LiveData": "Datos en Vivo",
|
||||
"SerialNumber": "Número de Serie: ",
|
||||
"CurrentLimit": "Límite de Corriente: ",
|
||||
"DataAge": "Edad de los Datos: ",
|
||||
"Seconds": "{val} segundos",
|
||||
"ShowSetInverterLimit": "Ver / Establecer Límite del Inversor",
|
||||
"TurnOnOff": "Encender/Apagar el Inversor",
|
||||
"ShowInverterInfo": "Ver Información del Inversor",
|
||||
"ShowEventlog": "Ver Registro de Eventos",
|
||||
"UnreadMessages": "mensajes sin leer",
|
||||
"Loading": "@:base.Cargando",
|
||||
"EventLog": "Registro de Eventos",
|
||||
"InverterInfo": "Información del Inversor",
|
||||
"LimitSettings": "Configuración de Límites",
|
||||
"LastLimitSetStatus": "Último Estado de Configuración del Límite:",
|
||||
"SetLimit": "Establecer Límite:",
|
||||
"Relative": "Relativo (%)",
|
||||
"Absolute": "Absoluto (W)",
|
||||
"LimitHint": "<b>Consejo:</b> Si establece el límite como un valor absoluto, la visualización del valor actual solo se actualizará después de ~4 minutos.",
|
||||
"SetPersistent": "Establecer Límite Permanente",
|
||||
"SetNonPersistent": "Establecer Límite No Permanente",
|
||||
"PowerSettings": "Configuración de Energía",
|
||||
"LastPowerSetStatus": "Último Estado de Configuración de Energía:",
|
||||
"TurnOn": "Encender",
|
||||
"TurnOff": "Apagar",
|
||||
"Restart": "Reiniciar",
|
||||
"Failure": "Fallo",
|
||||
"Pending": "Pendiente",
|
||||
"Ok": "Aceptar",
|
||||
"Unknown": "Desconocido",
|
||||
"ShowGridProfile": "Ver Perfil de la Red",
|
||||
"GridProfile": "Perfil de la Red",
|
||||
"LoadingInverter": "Waiting for data... (can take up to 10 seconds)",
|
||||
"RadioStats": "Radio Statistics",
|
||||
"TxRequest": "TX Request Count",
|
||||
"RxSuccess": "RX Success",
|
||||
"RxFailNothing": "RX Fail: Receive Nothing",
|
||||
"RxFailPartial": "RX Fail: Receive Partial",
|
||||
"RxFailCorrupt": "RX Fail: Receive Corrupt",
|
||||
"TxReRequest": "TX Re-Request Fragment",
|
||||
"StatsReset": "Reset Statistics",
|
||||
"StatsResetting": "Resetting...",
|
||||
"Rssi": "RSSI of last received packet",
|
||||
"RssiHint": "HM inverters only support RSSI values < -64 dBm and > -64 dBm. In this case, -80 dbm and -30 dbm is shown.",
|
||||
"dBm": "{dbm} dBm"
|
||||
},
|
||||
"eventlog": {
|
||||
"Start": "Iniciar",
|
||||
"Stop": "Parar",
|
||||
"Id": "ID",
|
||||
"Message": "Mensaje"
|
||||
},
|
||||
"devinfo": {
|
||||
"NoInfo": "Sin información disponible",
|
||||
"NoInfoLong": "No se ha recibido ningún dato válido del inversor hasta ahora. Todavía estamos intentando...",
|
||||
"UnknownModel": "¡Modelo desconocido! Por favor, informe el \"Número de parte de hardware\" y el modelo (por ejemplo, HM-350) como un problema <a href=\"https://github.com/tbnobody/OpenDTU/issues\" target=\"_blank\">aquí</a>.",
|
||||
"Serial": "Número de serie",
|
||||
"ProdYear": "Año de producción",
|
||||
"ProdWeek": "Semana de producción",
|
||||
"Model": "Modelo",
|
||||
"DetectedMaxPower": "Potencia máxima detectada",
|
||||
"BootloaderVersion": "Versión del cargador de arranque",
|
||||
"FirmwareVersion": "Versión del firmware",
|
||||
"FirmwareBuildDate": "Fecha de construcción del firmware",
|
||||
"HardwarePartNumber": "Número de parte de hardware",
|
||||
"HardwareVersion": "Versión de hardware",
|
||||
"SupportsPowerDistributionLogic": "'Power Distribution Logic' supported",
|
||||
"Yes": "@:base.Yes",
|
||||
"No": "@:base.No"
|
||||
},
|
||||
"gridprofile": {
|
||||
"NoInfo": "@:devinfo.NoInfo",
|
||||
"NoInfoLong": "@:devinfo.NoInfoLong",
|
||||
"Name": "Nombre",
|
||||
"Version": "Versión",
|
||||
"Enabled": "@:wifistationinfo.Enabled",
|
||||
"Disabled": "@:wifistationinfo.Disabled",
|
||||
"GridprofileSupport": "Apoyar el desarrollo",
|
||||
"GridprofileSupportLong": "Por favor, consulte <a href=\"https://github.com/tbnobody/OpenDTU/wiki/Grid-Profile-Parser\" target=\"_blank\">aquí</a> para obtener más información."
|
||||
},
|
||||
"systeminfo": {
|
||||
"SystemInfo": "Información del sistema",
|
||||
"VersionError": "Error al obtener información de la versión",
|
||||
"VersionNew": "¡Nueva versión disponible! ¡Mostrar cambios!",
|
||||
"VersionOk": "¡Actualizado!"
|
||||
},
|
||||
"firmwareinfo": {
|
||||
"FirmwareInformation": "Información del firmware",
|
||||
"Hostname": "Hostname",
|
||||
"SdkVersion": "Versión del SDK",
|
||||
"ConfigVersion": "Versión de la configuración",
|
||||
"FirmwareVersion": "Versión del firmware / Hash de Git",
|
||||
"PioEnv": "Entorno PIO",
|
||||
"FirmwareVersionHint": "Haga clic aquí para mostrar información sobre su versión actual",
|
||||
"FirmwareUpdate": "Actualización de firmware",
|
||||
"FirmwareUpdateHint": "Haga clic aquí para ver las diferencias entre su versión y la última versión",
|
||||
"FrmwareUpdateAllow": "Al activar la comprobación de actualización, se envía una solicitud a GitHub.com cada vez que se llama a la página para recuperar la versión actualmente disponible. Si no está de acuerdo con esto, deje esta función desactivada.",
|
||||
"ResetReason0": "Razón de reinicio CPU 0",
|
||||
"ResetReason1": "Razón de reinicio CPU 1",
|
||||
"ConfigSaveCount": "Contador de guardado de configuración",
|
||||
"Uptime": "Tiempo de actividad",
|
||||
"UptimeValue": "0 días {time} | 1 día {time} | {count} días {time}"
|
||||
},
|
||||
"hardwareinfo": {
|
||||
"HardwareInformation": "Información del hardware",
|
||||
"ChipModel": "Modelo de chip",
|
||||
"ChipRevision": "Revisión de chip",
|
||||
"ChipCores": "Núcleos del chip",
|
||||
"CpuFrequency": "Frecuencia de la CPU",
|
||||
"Mhz": "MHz",
|
||||
"CpuTemperature": "CPU Temperature",
|
||||
"FlashSize": "Flash Memory Size"
|
||||
},
|
||||
"memoryinfo": {
|
||||
"MemoryInformation": "Información de la memoria",
|
||||
"Type": "Tipo",
|
||||
"Usage": "Uso",
|
||||
"Free": "Libre",
|
||||
"Used": "Usado",
|
||||
"Size": "Tamaño",
|
||||
"Heap": "Montón",
|
||||
"PsRam": "PSRAM",
|
||||
"LittleFs": "LittleFs",
|
||||
"Sketch": "Boceto"
|
||||
},
|
||||
"heapdetails": {
|
||||
"HeapDetails": "Detalles del montón",
|
||||
"TotalFree": "Total libre",
|
||||
"LargestFreeBlock": "Bloque libre contiguo más grande",
|
||||
"MaxUsage": "Uso máximo desde el inicio",
|
||||
"Fragmentation": "Nivel de fragmentación"
|
||||
},
|
||||
"taskdetails": {
|
||||
"TaskDetails": "Task Details",
|
||||
"Name": "Name",
|
||||
"StackFree": "Stack Free",
|
||||
"Priority": "Priority",
|
||||
"Task_idle0": "Idle (CPU Core 0)",
|
||||
"Task_idle1": "Idle (CPU Core 1)",
|
||||
"Task_wifi": "Wi-Fi",
|
||||
"Task_tit": "TCP/IP",
|
||||
"Task_looptask": "Arduino Main Loop",
|
||||
"Task_asynctcp": "Async TCP",
|
||||
"Task_mqttclient": "MQTT Client",
|
||||
"Task_huaweican0": "AC Charger CAN",
|
||||
"Task_pmsdm": "PowerMeter (SDM)",
|
||||
"Task_pmhttpjson": "PowerMeter (HTTP+JSON)",
|
||||
"Task_pmsml": "PowerMeter (Serial SML)",
|
||||
"Task_pmhttpsml": "PowerMeter (HTTP+SML)"
|
||||
},
|
||||
"radioinfo": {
|
||||
"RadioInformation": "Información de la radio",
|
||||
"Status": "Estado de {module}",
|
||||
"ChipStatus": "Estado del chip de {module}",
|
||||
"ChipType": "Tipo de chip de {module}",
|
||||
"Connected": "conectado",
|
||||
"NotConnected": "no conectado",
|
||||
"Configured": "configurado",
|
||||
"NotConfigured": "no configurado",
|
||||
"Unknown": "Desconocido"
|
||||
},
|
||||
"networkinfo": {
|
||||
"NetworkInformation": "Información de la red"
|
||||
},
|
||||
"wifistationinfo": {
|
||||
"WifiStationInfo": "Información de WiFi (Estación)",
|
||||
"Status": "Estado",
|
||||
"Enabled": "habilitado",
|
||||
"Disabled": "deshabilitado",
|
||||
"Ssid": "SSID",
|
||||
"Bssid": "BSSID",
|
||||
"Quality": "Calidad",
|
||||
"Rssi": "RSSI"
|
||||
},
|
||||
"wifiapinfo": {
|
||||
"WifiApInfo": "Información de WiFi (Punto de acceso)",
|
||||
"Status": "@:wifistationinfo.Status",
|
||||
"Enabled": "@:wifistationinfo.Enabled",
|
||||
"Disabled": "@:wifistationinfo.Disabled",
|
||||
"Ssid": "@:wifistationinfo.Ssid",
|
||||
"Stations": "# Estaciones"
|
||||
},
|
||||
"interfacenetworkinfo": {
|
||||
"NetworkInterface": "Interfaz de red ({iface})",
|
||||
"Hostname": "@:firmwareinfo.Hostname",
|
||||
"IpAddress": "Dirección IP",
|
||||
"Netmask": "Máscara de red",
|
||||
"DefaultGateway": "Puerta de enlace predeterminada",
|
||||
"Dns": "DNS {num}",
|
||||
"MacAddress": "Dirección MAC"
|
||||
},
|
||||
"interfaceapinfo": {
|
||||
"NetworkInterface": "Interfaz de red (Punto de acceso)",
|
||||
"IpAddress": "@:interfacenetworkinfo.IpAddress",
|
||||
"MacAddress": "@:interfacenetworkinfo.MacAddress"
|
||||
},
|
||||
"ntpinfo": {
|
||||
"NtpInformation": "Información de NTP",
|
||||
"ConfigurationSummary": "Resumen de configuración",
|
||||
"Server": "Servidor",
|
||||
"Timezone": "Zona horaria",
|
||||
"TimezoneDescription": "Descripción de la zona horaria",
|
||||
"CurrentTime": "Hora actual",
|
||||
"Status": "Estado",
|
||||
"Synced": "sincronizado",
|
||||
"NotSynced": "no sincronizado",
|
||||
"LocalTime": "Hora local",
|
||||
"Sunrise": "Amanecer",
|
||||
"Sunset": "Atardecer",
|
||||
"NotAvailable": "No disponible",
|
||||
"Mode": "Modo",
|
||||
"Day": "Día",
|
||||
"Night": "Noche"
|
||||
},
|
||||
"mqttinfo": {
|
||||
"MqttInformation": "Información de MQTT",
|
||||
"ConfigurationSummary": "@:ntpinfo.ConfigurationSummary",
|
||||
"Status": "@:ntpinfo.Status",
|
||||
"Enabled": "Habilitado",
|
||||
"Disabled": "Deshabilitado",
|
||||
"Server": "@:ntpinfo.Server",
|
||||
"Port": "Puerto",
|
||||
"ClientId": "Client ID",
|
||||
"Username": "Nombre de usuario",
|
||||
"BaseTopic": "Tema base",
|
||||
"PublishInterval": "Intervalo de publicación",
|
||||
"Seconds": "{sec} segundos",
|
||||
"CleanSession": "Bandera CleanSession",
|
||||
"Retain": "Retener",
|
||||
"Tls": "TLS",
|
||||
"RootCertifcateInfo": "Información del certificado raíz de CA",
|
||||
"TlsCertLogin": "Iniciar sesión con certificado TLS",
|
||||
"ClientCertifcateInfo": "Información del Certificado del Cliente",
|
||||
"HassSummary": "Resumen de la Configuración de Descubrimiento Automático MQTT de Home Assistant",
|
||||
"Expire": "Expirar",
|
||||
"IndividualPanels": "Paneles Individuales",
|
||||
"RuntimeSummary": "Resumen de Tiempo de Ejecución",
|
||||
"ConnectionStatus": "Estado de Conexión",
|
||||
"Connected": "conectado",
|
||||
"Disconnected": "desconectado"
|
||||
},
|
||||
"console": {
|
||||
"Console": "Consola",
|
||||
"VirtualDebugConsole": "Consola de Depuración Virtual",
|
||||
"EnableAutoScroll": "Habilitar Desplazamiento Automático",
|
||||
"ClearConsole": "Limpiar Consola",
|
||||
"CopyToClipboard": "Copiar al Portapapeles"
|
||||
},
|
||||
"inverterchannelinfo": {
|
||||
"String": "Cadena {num}",
|
||||
"Phase": "Fase {num}",
|
||||
"General": "General"
|
||||
},
|
||||
"invertertotalinfo": {
|
||||
"TotalYieldTotal": "Total de Rendimiento Acumulado",
|
||||
"TotalYieldDay": "Total de Rendimiento del Día",
|
||||
"TotalPower": "Potencia Total"
|
||||
},
|
||||
"inverterchannelproperty": {
|
||||
"Power": "Potencia",
|
||||
"Voltage": "Voltaje",
|
||||
"Current": "Corriente",
|
||||
"Power DC": "Potencia DC",
|
||||
"YieldDay": "Rendimiento del Día",
|
||||
"YieldTotal": "Rendimiento Total",
|
||||
"Frequency": "Frecuencia",
|
||||
"Temperature": "Temperatura",
|
||||
"PowerFactor": "Factor de Potencia",
|
||||
"ReactivePower": "Potencia Reactiva",
|
||||
"Efficiency": "Eficiencia",
|
||||
"Irradiation": "Irradiación"
|
||||
},
|
||||
"maintenancereboot": {
|
||||
"DeviceReboot": "Reinicio del Dispositivo",
|
||||
"PerformReboot": "Realizar Reinicio",
|
||||
"Reboot": "¡Reiniciar!",
|
||||
"Cancel": "@:base.Cancel",
|
||||
"RebootOpenDTU": "Reiniciar OpenDTU",
|
||||
"RebootQuestion": "¿Realmente desea reiniciar el dispositivo?",
|
||||
"RebootHint": "<b>Nota:</b> Normalmente no es necesario realizar un reinicio manual. OpenDTU realiza cualquier reinicio necesario (por ejemplo, después de una actualización de firmware) automáticamente. También se adoptan configuraciones sin reiniciar. Si necesita reiniciar debido a un error, considere informarlo en <a href=\"https://github.com/tbnobody/OpenDTU/issues\" class=\"alert-link\" target=\"_blank\">https://github.com/tbnobody/OpenDTU/issues</a>."
|
||||
},
|
||||
"dtuadmin": {
|
||||
"DtuSettings": "Configuración de DTU",
|
||||
"DtuConfiguration": "Configuración de DTU",
|
||||
"Serial": "Serial",
|
||||
"SerialHint": "Tanto el inversor como el DTU tienen un número de serie. El número de serie del DTU se genera aleatoriamente en el primer inicio y generalmente no es necesario cambiarlo.",
|
||||
"PollInterval": "Intervalo de Sondeo",
|
||||
"Seconds": "Segundos",
|
||||
"NrfPaLevel": "Potencia de Transmisión NRF24",
|
||||
"CmtPaLevel": "Potencia de Transmisión CMT2300A",
|
||||
"NrfPaLevelHint": "Utilizado para inversores HM. Asegúrese de que su fuente de alimentación sea lo suficientemente estable antes de aumentar la potencia de transmisión.",
|
||||
"CmtPaLevelHint": "Utilizado para inversores HMS/HMT. Asegúrese de que su fuente de alimentación sea lo suficientemente estable antes de aumentar la potencia de transmisión.",
|
||||
"CmtCountry": "Región/País CMT2300A",
|
||||
"CmtCountryHint": "Cada país tiene asignaciones de frecuencia diferentes.",
|
||||
"country_0": "Europa ({min}MHz - {max}MHz)",
|
||||
"country_1": "América del Norte ({min}MHz - {max}MHz)",
|
||||
"country_2": "Brasil ({min}MHz - {max}MHz)",
|
||||
"CmtFrequency": "Frecuencia CMT2300A",
|
||||
"CmtFrequencyHint": "¡Asegúrese de utilizar solo frecuencias permitidas en el país respectivo! Después de un cambio de frecuencia, puede tardar hasta 15 minutos en establecer una conexión.",
|
||||
"CmtFrequencyWarning": "La frecuencia seleccionada está fuera del rango permitido en su región/país seleccionado. Asegúrese de que esta selección no infrinja ninguna regulación local.",
|
||||
"MHz": "{mhz} MHz",
|
||||
"dBm": "{dbm} dBm",
|
||||
"Min": "Mínimo ({db} dBm)",
|
||||
"Low": "Bajo ({db} dBm)",
|
||||
"High": "Alto ({db} dBm)",
|
||||
"Max": "Máximo ({db} dBm)"
|
||||
},
|
||||
"securityadmin": {
|
||||
"SecuritySettings": "Configuración de Seguridad",
|
||||
"AdminPassword": "Contraseña de Administrador",
|
||||
"Password": "Contraseña",
|
||||
"RepeatPassword": "Repetir Contraseña",
|
||||
"PasswordHint": "<b>Consejo:</b> La contraseña de administrador se utiliza para acceder a esta interfaz web (usuario 'admin'), pero también para conectarse al dispositivo cuando está en modo AP. Debe tener 8 a 64 caracteres.",
|
||||
"Permissions": "Permisos",
|
||||
"ReadOnly": "Permitir acceso de solo lectura a la interfaz web sin contraseña"
|
||||
},
|
||||
"ntpadmin": {
|
||||
"NtpSettings": "Configuración de NTP",
|
||||
"NtpConfiguration": "Configuración de NTP",
|
||||
"TimeServer": "Servidor de Tiempo",
|
||||
"TimeServerHint": "El valor predeterminado es adecuado siempre que OpenDTU tenga acceso directo a Internet.",
|
||||
"Timezone": "Zona Horaria",
|
||||
"TimezoneConfig": "Configuración de Zona Horaria",
|
||||
"LocationConfiguration": "Configuración de Ubicación",
|
||||
"Longitude": "Longitud",
|
||||
"Latitude": "Latitud",
|
||||
"SunSetType": "Tipo de Atardecer",
|
||||
"SunSetTypeHint": "Afecta al cálculo día/noche. Puede tardar hasta un minuto en aplicarse el nuevo tipo.",
|
||||
"OFFICIAL": "Amanecer estándar (90.8°)",
|
||||
"NAUTICAL": "Amanecer náutico (102°)",
|
||||
"CIVIL": "Amanecer civil (96°)",
|
||||
"ASTONOMICAL": "Amanecer astronómico (108°)",
|
||||
"ManualTimeSynchronization": "Sincronización Manual del Tiempo",
|
||||
"CurrentOpenDtuTime": "Hora Actual de OpenDTU",
|
||||
"CurrentLocalTime": "Hora Local Actual",
|
||||
"SynchronizeTime": "Sincronizar Tiempo",
|
||||
"SynchronizeTimeHint": "<b>Consejo:</b> Puede utilizar la sincronización manual del tiempo para establecer la hora actual de OpenDTU si no hay un servidor NTP disponible. Pero tenga en cuenta que en caso de un ciclo de energía, se perderá la hora. Además, tenga en cuenta que la precisión del tiempo se verá gravemente afectada, ya que no se puede resincronizar regularmente y el microcontrolador ESP32 no tiene un reloj en tiempo real."
|
||||
},
|
||||
"networkadmin": {
|
||||
"NetworkSettings": "Configuración de Red",
|
||||
"WifiConfiguration": "Configuración de WiFi",
|
||||
"WifiSsid": "SSID de WiFi",
|
||||
"WifiPassword": "Contraseña de WiFi",
|
||||
"Hostname": "Nombre de Host",
|
||||
"HostnameHint": "<b>Consejo:</b> El texto <span class=\"font-monospace\">%06X</span> se remplazará con los últimos 6 dígitos del ChipID de ESP en formato hexadecimal.",
|
||||
"EnableDhcp": "Habilitar DHCP",
|
||||
"StaticIpConfiguration": "Configuración de IP Estática",
|
||||
"IpAddress": "Dirección IP",
|
||||
"Netmask": "Máscara de Red",
|
||||
"DefaultGateway": "Puerta de Enlace Predeterminada",
|
||||
"Dns": "Servidor DNS {num}",
|
||||
"AdminAp": "Configuración de WiFi (Punto de Acceso de Administrador)",
|
||||
"ApTimeout": "Tiempo de espera del Punto de Acceso",
|
||||
"ApTimeoutHint": "Tiempo que se mantiene abierto el Punto de Acceso. Un valor de 0 significa infinito.",
|
||||
"Minutes": "minutos",
|
||||
"EnableMdns": "Habilitar mDNS",
|
||||
"MdnsSettings": "Configuración de mDNS"
|
||||
},
|
||||
"mqttadmin": {
|
||||
"MqttSettings": "Configuración de MQTT",
|
||||
"MqttConfiguration": "Configuración de MQTT",
|
||||
"EnableMqtt": "Habilitar MQTT",
|
||||
"EnableHass": "Habilitar Descubrimiento Automático MQTT de Home Assistant",
|
||||
"MqttBrokerParameter": "Parámetros del Broker MQTT",
|
||||
"Hostname": "Nombre de Host",
|
||||
"HostnameHint": "Nombre de host o dirección IP",
|
||||
"Port": "Puerto",
|
||||
"ClientId": "Client ID",
|
||||
"Username": "Nombre de Usuario",
|
||||
"UsernameHint": "Nombre de usuario, dejar vacío para conexión anónima",
|
||||
"Password": "Contraseña",
|
||||
"PasswordHint": "Contraseña, dejar vacío para conexión anónima",
|
||||
"BaseTopic": "Tema Base",
|
||||
"BaseTopicHint": "Tema base, se antepondrá a todos los temas publicados (por ejemplo, inverter/)",
|
||||
"PublishInterval": "Intervalo de Publicación",
|
||||
"Seconds": "segundos",
|
||||
"CleanSession": "Habilitar Bandera CleanSession",
|
||||
"EnableRetain": "Habilitar Bandera Retain",
|
||||
"EnableTls": "Habilitar TLS",
|
||||
"RootCa": "Certificado Raíz CA (predeterminado Letsencrypt)",
|
||||
"TlsCertLoginEnable": "Habilitar Inicio de Sesión con Certificado TLS",
|
||||
"ClientCert": "Certificado del Cliente TLS",
|
||||
"ClientKey": "Clave del Cliente TLS",
|
||||
"LwtParameters": "Parámetros de LWT",
|
||||
"LwtTopic": "Tema de LWT",
|
||||
"LwtTopicHint": "Tema de LWT, se añadirá al tema base",
|
||||
"LwtOnline": "Mensaje de LWT en línea",
|
||||
"LwtOnlineHint": "Mensaje que se publicará en el tema de LWT cuando esté en línea",
|
||||
"LwtOffline": "Mensaje de LWT fuera de línea",
|
||||
"LwtOfflineHint": "Mensaje que se publicará en el tema de LWT cuando esté fuera de línea",
|
||||
"LwtQos": "QoS (Calidad de Servicio)",
|
||||
"QOS0": "0 (Como máximo una vez)",
|
||||
"QOS1": "1 (Al menos una vez)",
|
||||
"QOS2": "2 (Exactamente una vez)",
|
||||
"HassParameters": "Parámetros de Descubrimiento Automático MQTT de Home Assistant",
|
||||
"HassPrefixTopic": "Tema de Prefijo",
|
||||
"HassPrefixTopicHint": "El prefijo para el tema de descubrimiento",
|
||||
"HassRetain": "Habilitar Bandera Retain",
|
||||
"HassExpire": "Habilitar Expiración",
|
||||
"HassIndividual": "Paneles Individuales"
|
||||
},
|
||||
"inverteradmin": {
|
||||
"InverterSettings": "Configuración del Inversor",
|
||||
"AddInverter": "Agregar un nuevo Inversor",
|
||||
"Serial": "Serial",
|
||||
"Name": "Nombre",
|
||||
"Add": "Agregar",
|
||||
"AddHint": "<b>Consejo:</b> Puede configurar parámetros adicionales después de haber creado el inversor. Use el ícono de lápiz en la lista de inversores.",
|
||||
"InverterList": "Lista de Inversores",
|
||||
"Status": "Estado",
|
||||
"Send": "Enviar",
|
||||
"Receive": "Recibir",
|
||||
"StatusHint": "<b>Consejo:</b> El inversor se alimenta con su entrada de CC. Si no hay sol, el inversor está apagado. Aún se pueden enviar solicitudes.",
|
||||
"Type": "Tipo",
|
||||
"Action": "Acción",
|
||||
"SaveOrder": "Guardar orden",
|
||||
"DeleteInverter": "Eliminar inversor",
|
||||
"EditInverter": "Editar inversor",
|
||||
"General": "General",
|
||||
"String": "Cadena",
|
||||
"Advanced": "Avanzado",
|
||||
"InverterSerial": "Serial del Inversor:",
|
||||
"InverterName": "Nombre del Inversor:",
|
||||
"InverterNameHint": "Aquí puede especificar un nombre personalizado para su inversor.",
|
||||
"InverterStatus": "Recibir / Enviar",
|
||||
"PollEnable": "Sondear datos del inversor",
|
||||
"PollEnableNight": "Sondear datos del inversor por la noche",
|
||||
"CommandEnable": "Enviar comandos",
|
||||
"CommandEnableNight": "Enviar comandos por la noche",
|
||||
"StringName": "Nombre de cadena {num}:",
|
||||
"StringNameHint": "Aquí puede especificar un nombre personalizado para el puerto respectivo de su inversor.",
|
||||
"StringMaxPower": "Potencia máxima de cadena {num}:",
|
||||
"StringMaxPowerHint": "Ingrese la potencia máxima de los paneles solares conectados.",
|
||||
"StringYtOffset": "Compensación total de rendimiento de cadena {num}:",
|
||||
"StringYtOffsetHint": "Esta compensación se aplica al valor total de rendimiento leído del inversor. Esto se puede usar para ajustar el rendimiento total del inversor a cero si se utiliza un inversor usado. Pero aún puede intentar sondear datos.",
|
||||
"InverterHint": "*) Ingrese W<sub>p</sub> del canal para calcular la irradiación.",
|
||||
"ReachableThreshold": "Umbral de Alcanzabilidad",
|
||||
"ReachableThresholdHint": "Define cuántas solicitudes se permiten fallar hasta que el inversor se considere no alcanzable.",
|
||||
"ZeroRuntime": "Datos de tiempo cero",
|
||||
"ZeroRuntimeHint": "Datos de tiempo cero (sin datos de rendimiento) si el inversor se vuelve inalcanzable.",
|
||||
"ZeroDay": "Rendimiento diario cero a medianoche",
|
||||
"ZeroDayHint": "Esto solo funciona si el inversor es inalcanzable. Si se leen datos del inversor, se usarán sus valores. (El reinicio solo ocurre en el ciclo de energía)",
|
||||
"ClearEventlog": "Clear Eventlog at midnight",
|
||||
"Cancel": "@:base.Cancel",
|
||||
"Save": "@:base.Save",
|
||||
"DeleteMsg": "¿Está seguro de que desea eliminar el inversor \"{name}\" con número de serie {serial}?",
|
||||
"Delete": "Eliminar",
|
||||
"YieldDayCorrection": "Corrección de Rendimiento Diario",
|
||||
"YieldDayCorrectionHint": "Sumar el rendimiento diario incluso si el inversor se reinicia. El valor se restablecerá a medianoche"
|
||||
},
|
||||
"fileadmin": {
|
||||
"ConfigManagement": "Gestión de Configuración",
|
||||
"BackupHeader": "Copia de seguridad: Copia de Seguridad del Archivo de Configuración",
|
||||
"BackupConfig": "Copia de seguridad del archivo de configuración",
|
||||
"Backup": "Copia de seguridad",
|
||||
"Restore": "Restaurar",
|
||||
"NoFileSelected": "Ningún archivo seleccionado",
|
||||
"RestoreHeader": "Restaurar: Restaurar el Archivo de Configuración",
|
||||
"Back": "Atrás",
|
||||
"UploadSuccess": "Carga Exitosa",
|
||||
"RestoreHint": "<b>Nota:</b> Esta operación reemplaza el archivo de configuración con la configuración restaurada y reinicia OpenDTU para aplicar todas las configuraciones.",
|
||||
"ResetHeader": "Inicializar: Realizar Restablecimiento de Fábrica",
|
||||
"FactoryResetButton": "Restaurar Configuraciones Predeterminadas de Fábrica",
|
||||
"ResetHint": "<b>Nota:</b> Haga clic en Restaurar Configuraciones Predeterminadas de Fábrica para restaurar e inicializar las configuraciones predeterminadas de fábrica y reiniciar.",
|
||||
"FactoryReset": "Restablecimiento de Fábrica",
|
||||
"ResetMsg": "¿Está seguro de que desea eliminar la configuración actual y restablecer todas las configuraciones a sus valores predeterminados de fábrica?",
|
||||
"ResetConfirm": "Restablecimiento de Fábrica",
|
||||
"Cancel": "@:base.Cancel",
|
||||
"InvalidJson": "JSON file is formatted incorrectly.",
|
||||
"InvalidJsonContent": "JSON file has the wrong content."
|
||||
},
|
||||
"login": {
|
||||
"Login": "Iniciar Sesión",
|
||||
"SystemLogin": "Inicio de Sesión en el Sistema",
|
||||
"Username": "Nombre de Usuario",
|
||||
"UsernameRequired": "Se requiere el nombre de usuario",
|
||||
"Password": "Contraseña",
|
||||
"PasswordRequired": "Se requiere la contraseña",
|
||||
"LoginButton": "Iniciar Sesión"
|
||||
},
|
||||
"firmwareupgrade": {
|
||||
"FirmwareUpgrade": "Actualización de Firmware",
|
||||
"Loading": "@:base.Loading",
|
||||
"OtaError": "Error OTA",
|
||||
"Back": "Atrás",
|
||||
"Retry": "Reintentar",
|
||||
"OtaStatus": "Estado OTA",
|
||||
"OtaSuccess": "La carga de firmware fue exitosa. El dispositivo se reinició automáticamente. Cuando el dispositivo vuelva a ser accesible, la interfaz se recargará automáticamente.",
|
||||
"FirmwareUpload": "Carga de Firmware",
|
||||
"UploadProgress": "Progreso de Carga"
|
||||
},
|
||||
"about": {
|
||||
"AboutOpendtu": "Acerca de OpenDTU",
|
||||
"Documentation": "Documentation",
|
||||
"DocumentationBody": "The firmware and hardware documentation can be found here: <a href=\"https://www.opendtu.solar\" target=\"_blank\">https://www.opendtu.solar</a>",
|
||||
"ProjectOrigin": "Origen del Proyecto",
|
||||
"ProjectOriginBody1": "Este proyecto se inició a partir de <a href=\"https://www.mikrocontroller.net/topic/525778\" target=\"_blank\">esta discusión. (Mikrocontroller.net)</a>",
|
||||
"ProjectOriginBody2": "El protocolo de Hoymiles fue descifrado mediante los esfuerzos voluntarios de muchos participantes. OpenDTU, entre otros, se desarrolló basado en este trabajo. El proyecto está bajo una Licencia de Código Abierto (<a href=\"https://www.gnu.de/documents/gpl-2.0.de.html\" target=\"_blank\">Licencia Pública General de GNU versión 2</a>).",
|
||||
"ProjectOriginBody3": "El software se desarrolló según nuestro mejor conocimiento y creencia. Sin embargo, no se acepta ninguna responsabilidad por un mal funcionamiento o pérdida de garantía del inversor.",
|
||||
"ProjectOriginBody4": "OpenDTU está disponible de forma gratuita. Si pagaste dinero por el software, probablemente te estafaron.",
|
||||
"NewsUpdates": "Noticias y Actualizaciones",
|
||||
"NewsUpdatesBody": "Las nuevas actualizaciones se pueden encontrar en Github: <a href=\"https://github.com/tbnobody/OpenDTU\" target=\"_blank\">https://github.com/tbnobody/OpenDTU</a>",
|
||||
"ErrorReporting": "Reporte de Errores",
|
||||
"ErrorReportingBody": "Por favor, informa problemas utilizando la función proporcionada por <a href=\"https://github.com/tbnobody/OpenDTU/issues\" target=\"_blank\">Github</a>",
|
||||
"Discussion": "Discusión",
|
||||
"DiscussionBody": "Discute con nosotros en <a href=\"https://discord.gg/WzhxEY62mB\" target=\"_blank\">Discord</a> o <a href=\"https://github.com/tbnobody/OpenDTU/discussions\" target=\"_blank\">Github</a>"
|
||||
},
|
||||
"hints": {
|
||||
"RadioProblem": "No se pudo conectar a un módulo de radio configurado. Por favor, verifica la conexión.",
|
||||
"TimeSync": "El reloj aún no ha sido sincronizado. Sin un reloj correctamente ajustado, no se realizan solicitudes al inversor. Esto es normal poco después del inicio. Sin embargo, después de un tiempo de ejecución más largo (>1 minuto), indica que el servidor NTP no es accesible.",
|
||||
"TimeSyncLink": "Por favor, verifica la configuración de tu hora.",
|
||||
"DefaultPassword": "Estás utilizando la contraseña predeterminada para la interfaz web y el punto de acceso de emergencia. Esto potencialmente es inseguro.",
|
||||
"DefaultPasswordLink": "Por favor, cambia la contraseña.",
|
||||
"PinMappingIssue": "You are using a generic firmware image, but have not yet uploaded a file with device profiles (<code>pin_mapping.json</code>) or have not selected a profile defined there. Please refer to the <a href=\"https://opendtu.solar/firmware/device_profiles/\" target=\"_blank\" class=\"alert-link\">documentation</a> for details."
|
||||
},
|
||||
"deviceadmin": {
|
||||
"DeviceManager": "Administrador de Dispositivos",
|
||||
"ParseError": "Error de análisis en 'pin_mapping.json': {error}",
|
||||
"PinAssignment": "Configuración de Conexión",
|
||||
"SelectedProfile": "Perfil Seleccionado",
|
||||
"DefaultProfile": "(Configuraciones predeterminadas)",
|
||||
"ProfileHint": "Tu dispositivo puede dejar de responder si seleccionas un perfil incompatible. En este caso, debes realizar una eliminación a través de la interfaz serial.",
|
||||
"Display": "Pantalla",
|
||||
"PowerSafe": "Habilitar Ahorro de Energía",
|
||||
"PowerSafeHint": "Apaga la pantalla si no hay un inversor produciendo.",
|
||||
"Screensaver": "Habilitar Protector de Pantalla",
|
||||
"ScreensaverHint": "Mueve la pantalla un poco en cada actualización para evitar el quemado. (Útil especialmente para pantallas OLED)",
|
||||
"DiagramMode": "Modo de Diagrama",
|
||||
"off": "Apagar",
|
||||
"small": "Pequeño",
|
||||
"fullscreen": "Pantalla Completa",
|
||||
"DiagramDuration": "Duración del Diagrama",
|
||||
"DiagramDurationHint": "El período de tiempo que se muestra en el diagrama.",
|
||||
"Seconds": "Segundos",
|
||||
"Contrast": "Contraste ({contrast})",
|
||||
"Rotation": "Rotación",
|
||||
"rot0": "Sin rotación",
|
||||
"rot90": "Rotación de 90 grados",
|
||||
"rot180": "Rotación de 180 grados",
|
||||
"rot270": "Rotación de 270 grados",
|
||||
"DisplayLanguage": "Idioma de la Pantalla",
|
||||
"en": "Inglés",
|
||||
"de": "Alemán",
|
||||
"fr": "Francés",
|
||||
"Leds": "LEDs",
|
||||
"EqualBrightness": "Brillo Equitativo",
|
||||
"LedBrightness": "Brillo del LED {led} ({brightness})"
|
||||
},
|
||||
"pininfo": {
|
||||
"Category": "Categoría",
|
||||
"Name": "Nombre",
|
||||
"Number": "Número",
|
||||
"ValueSelected": "Seleccionado",
|
||||
"ValueActive": "Activo"
|
||||
},
|
||||
"inputserial": {
|
||||
"format_hoymiles": "Hoymiles serial number format",
|
||||
"format_converted": "Already converted serial number",
|
||||
"format_herf_valid": "E-Star HERF format (will be saved converted): {serial}",
|
||||
"format_herf_invalid": "E-Star HERF format: Invalid checksum",
|
||||
"format_unknown": "Unknown format"
|
||||
}
|
||||
}
|
||||
}
|
||||
696
lang/it.lang.json
Normal file
696
lang/it.lang.json
Normal file
@ -0,0 +1,696 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Italiano",
|
||||
"code": "it"
|
||||
},
|
||||
"display": {
|
||||
"date_format": "%d/%m/%Y %H:%M",
|
||||
"offline": "Offline",
|
||||
"power_w": "%.0f W",
|
||||
"power_kw": "%.1f kW",
|
||||
"yield_today_wh": "oggi: %4.0f Wh",
|
||||
"yield_today_kwh": "oggi: %.1f kWh",
|
||||
"yield_total_kwh": "totale: %.1f kWh",
|
||||
"yield_total_mwh": "totale: %.0f kWh"
|
||||
},
|
||||
"webapp": {
|
||||
"menu": {
|
||||
"LiveView": "Dati in tempo reale",
|
||||
"Settings": "Impostazioni",
|
||||
"NetworkSettings": "Impostazioni di rete",
|
||||
"NTPSettings": "Impostazioni NTP",
|
||||
"MQTTSettings": "Impostazioni MQTT",
|
||||
"InverterSettings": "Impostazioni Inverter",
|
||||
"SecuritySettings": "Impostazioni di Sicurezza",
|
||||
"DTUSettings": "Impostazioni DTU",
|
||||
"DeviceManager": "Gestione Dispositivi",
|
||||
"ConfigManagement": "Gestione Configurazione",
|
||||
"FirmwareUpgrade": "Aggiornamento Firmware",
|
||||
"DeviceReboot": "Riavvio DTU",
|
||||
"Info": "Info",
|
||||
"System": "Sistema",
|
||||
"Network": "Rete",
|
||||
"NTP": "NTP",
|
||||
"MQTT": "MQTT",
|
||||
"Console": "Console",
|
||||
"About": "Informazioni DTU",
|
||||
"Logout": "Esci",
|
||||
"Login": "Login"
|
||||
},
|
||||
"base": {
|
||||
"Loading": "Caricamento...",
|
||||
"Reload": "Ricarica",
|
||||
"Cancel": "Cancella",
|
||||
"Save": "Salva",
|
||||
"Refreshing": "Aggiorna",
|
||||
"Pull": "Trascina in basso per aggiornare",
|
||||
"Release": "Rilascia per aggiornare",
|
||||
"Close": "Chiudi",
|
||||
"Yes": "Yes",
|
||||
"No": "No"
|
||||
},
|
||||
"wait": {
|
||||
"NotReady": "OpenDTU is not yet ready",
|
||||
"PleaseWait": "Please wait. You will be automatically redirected to the home page."
|
||||
},
|
||||
"Error": {
|
||||
"Oops": "Oops!"
|
||||
},
|
||||
"localeswitcher": {
|
||||
"Dark": "Scuro",
|
||||
"Light": "Chiaro",
|
||||
"Auto": "Automatico"
|
||||
},
|
||||
"apiresponse": {
|
||||
"1001": "Settings saved!",
|
||||
"1002": "No values found!",
|
||||
"1003": "Data too large!",
|
||||
"1004": "Failed to parse data!",
|
||||
"1005": "Values are missing!",
|
||||
"1006": "Write failed!",
|
||||
"2001": "Serial cannot be zero!",
|
||||
"2002": "Poll interval must be greater zero!",
|
||||
"2003": "Invalid power level setting!",
|
||||
"2004": "The frequency must be set between {min} and {max} kHz and must be a multiple of 250kHz!",
|
||||
"2005": "Invalid country selection!",
|
||||
"3001": "Not deleted anything!",
|
||||
"3002": "Configuration resettet. Rebooting now...",
|
||||
"4001": "@:apiresponse.2001",
|
||||
"4002": "Name must between 1 and {max} characters long!",
|
||||
"4003": "Only {max} inverters are supported!",
|
||||
"4004": "Inverter created!",
|
||||
"4005": "Invalid ID specified!",
|
||||
"4006": "Invalid amount of max channel setting given!",
|
||||
"4007": "Inverter changed!",
|
||||
"4008": "Inverter deleted!",
|
||||
"4009": "Inverter order saved!",
|
||||
"5001": "@:apiresponse.2001",
|
||||
"5002": "Limit must between 1 and {max}!",
|
||||
"5003": "Invalid type specified!",
|
||||
"5004": "Invalid inverter specified!",
|
||||
"6001": "Reboot triggered!",
|
||||
"6002": "Reboot cancled!",
|
||||
"7001": "MQTT Server must between 1 and {max} characters long!",
|
||||
"7002": "Username must not longer then {max} characters!",
|
||||
"7003": "Password must not longer then {max} characters!",
|
||||
"7004": "Topic must not longer then {max} characters!",
|
||||
"7005": "Topic must not contain space characters!",
|
||||
"7006": "Topic must end with slash (/)!",
|
||||
"7007": "Port must be a number between 1 and 65535!",
|
||||
"7008": "Certificate must not longer then {max} characters!",
|
||||
"7009": "LWT topic must not longer then {max} characters!",
|
||||
"7010": "LWT topic must not contain space characters!",
|
||||
"7011": "LWT online value must not longer then {max} characters!",
|
||||
"7012": "LWT offline value must not longer then {max} characters!",
|
||||
"7013": "Publish interval must be a number between {min} and {max}!",
|
||||
"7014": "Hass topic must not longer then {max} characters!",
|
||||
"7015": "Hass topic must not contain space characters!",
|
||||
"7016": "LWT QOS must not greater then {max}!",
|
||||
"7017": "Client ID must not longer then {max} characters!",
|
||||
"8001": "IP address is invalid!",
|
||||
"8002": "Netmask is invalid!",
|
||||
"8003": "Gateway is invalid!",
|
||||
"8004": "DNS Server IP 1 is invalid!",
|
||||
"8005": "DNS Server IP 2 is invalid!",
|
||||
"8006": "Administrative AccessPoint Timeout value is invalid",
|
||||
"9001": "NTP Server must between 1 and {max} characters long!",
|
||||
"9002": "Timezone must between 1 and {max} characters long!",
|
||||
"9003": "Timezone description must between 1 and {max} characters long!",
|
||||
"9004": "Year must be a number between {min} and {max}!",
|
||||
"9005": "Month must be a number between {min} and {max}!",
|
||||
"9006": "Day must be a number between {min} and {max}!",
|
||||
"9007": "Hour must be a number between {min} and {max}!",
|
||||
"9008": "Minute must be a number between {min} and {max}!",
|
||||
"9009": "Second must be a number between {min} and {max}!",
|
||||
"9010": "Time updated!",
|
||||
"10001": "Password must between 8 and {max} characters long!",
|
||||
"10002": "Authentication successful!",
|
||||
"11001": "@:apiresponse.2001",
|
||||
"11002": "@:apiresponse:5004",
|
||||
"12001": "Profil must between 1 and {max} characters long!"
|
||||
},
|
||||
"home": {
|
||||
"LiveData": "Dati in tempo reale",
|
||||
"SerialNumber": "Numero seriale: ",
|
||||
"CurrentLimit": "Limite attuale: ",
|
||||
"DataAge": "Aggiornamento Dati: ",
|
||||
"Seconds": "{val} secondi",
|
||||
"ShowSetInverterLimit": "Mostra / Imposta Limite di Potenza",
|
||||
"TurnOnOff": "Accendi/Spegni Inverter",
|
||||
"ShowInverterInfo": "Mostra info Inverter",
|
||||
"ShowEventlog": "Mostra Log Eventi",
|
||||
"UnreadMessages": "msg non letti",
|
||||
"Loading": "@:base.Loading",
|
||||
"EventLog": "Log Eventi",
|
||||
"InverterInfo": "Info Inverter",
|
||||
"LimitSettings": "Impostazioni Limite Potenza",
|
||||
"LastLimitSetStatus": "Stato ultimo limite impostato:",
|
||||
"SetLimit": "Imposta Limite a:",
|
||||
"Relative": "Percentuale (%)",
|
||||
"Absolute": "Assoluto (W)",
|
||||
"LimitHint": "<b>Nota:</b> Se imposti il limite assoluto, il valore sul display sarà aggiornato dopo circa 4 minuti.",
|
||||
"SetPersistent": "Imposta Limite in Modo Persistente",
|
||||
"SetNonPersistent": "Imposta Limite Temporaneamente",
|
||||
"PowerSettings": "Impostazioni Potenza",
|
||||
"LastPowerSetStatus": "Ultimo Stato dell'Inverter:",
|
||||
"TurnOn": "Accendi Inverter",
|
||||
"TurnOff": "Spegni Inverter",
|
||||
"Restart": "Riavvia Inverter",
|
||||
"Failure": "Fallito",
|
||||
"Pending": "In Attesa",
|
||||
"Ok": "Ok",
|
||||
"Unknown": "Sconosciuto",
|
||||
"ShowGridProfile": "Mostra Settaggi Inverter",
|
||||
"GridProfile": "Settaggi Inverter",
|
||||
"LoadingInverter": "In attesa dei dati... (puo' richiedere fino a 10 secondi)",
|
||||
"RadioStats": "Radio Statistics",
|
||||
"TxRequest": "TX Request Count",
|
||||
"RxSuccess": "RX Success",
|
||||
"RxFailNothing": "RX Fail: Receive Nothing",
|
||||
"RxFailPartial": "RX Fail: Receive Partial",
|
||||
"RxFailCorrupt": "RX Fail: Receive Corrupt",
|
||||
"TxReRequest": "TX Re-Request Fragment",
|
||||
"StatsReset": "Reset Statistics",
|
||||
"StatsResetting": "Resetting...",
|
||||
"Rssi": "RSSI of last received packet",
|
||||
"RssiHint": "HM inverters only support RSSI values < -64 dBm and > -64 dBm. In this case, -80 dbm and -30 dbm is shown.",
|
||||
"dBm": "{dbm} dBm"
|
||||
},
|
||||
"eventlog": {
|
||||
"Start": "Inizio",
|
||||
"Stop": "Fine",
|
||||
"Id": "ID",
|
||||
"Message": "Messaggio"
|
||||
},
|
||||
"devinfo": {
|
||||
"NoInfo": "Informazioni non disponibili",
|
||||
"NoInfoLong": "Ancora nessuna informazione dall'inverter. Sto riprovando...",
|
||||
"UnknownModel": "Modello sconosciuto! Per favore fornisci \"Hardware Part Number\" ed il modello (esempio HM-350) in una Issue su <a href=\"https://github.com/tbnobody/OpenDTU/issues\" target=\"_blank\">GitHub</a>.",
|
||||
"Serial": "Seriale",
|
||||
"ProdYear": "Produzione Annua",
|
||||
"ProdWeek": "Produzione Settimanale",
|
||||
"Model": "Modello",
|
||||
"DetectedMaxPower": "Rilevata potenza massima",
|
||||
"BootloaderVersion": "Versione Bootloader",
|
||||
"FirmwareVersion": "Versione Firmware",
|
||||
"FirmwareBuildDate": "Data Firmware",
|
||||
"HardwarePartNumber": "Hardware Part Number",
|
||||
"HardwareVersion": "Hardware Version",
|
||||
"SupportsPowerDistributionLogic": "'Power Distribution Logic' supported",
|
||||
"Yes": "@:base.Yes",
|
||||
"No": "@:base.No"
|
||||
},
|
||||
"gridprofile": {
|
||||
"NoInfo": "@:devinfo.NoInfo",
|
||||
"NoInfoLong": "@:devinfo.NoInfoLong",
|
||||
"Name": "Nome",
|
||||
"Version": "Versione",
|
||||
"Enabled": "@:wifistationinfo.Enabled",
|
||||
"Disabled": "@:wifistationinfo.Disabled",
|
||||
"GridprofileSupport": "Supporto sviluppatori",
|
||||
"GridprofileSupportLong": "Clicca <a href=\"https://github.com/tbnobody/OpenDTU/wiki/Grid-Profile-Parser\" target=\"_blank\">qui</a> per ulteriori informazioni."
|
||||
},
|
||||
"systeminfo": {
|
||||
"SystemInfo": "Info Sistema",
|
||||
"VersionError": "Errore ricezione della versione",
|
||||
"VersionNew": "Nuova versione disponibile! Mostra aggiornamenti!",
|
||||
"VersionOk": "Già aggiornato!"
|
||||
},
|
||||
"firmwareinfo": {
|
||||
"FirmwareInformation": "Info Firmware",
|
||||
"Hostname": "Hostname",
|
||||
"SdkVersion": "SDK Version",
|
||||
"ConfigVersion": "Config Version",
|
||||
"FirmwareVersion": "Firmware Version / Git Hash",
|
||||
"PioEnv": "PIO Environment",
|
||||
"FirmwareVersionHint": "Click here to show information about your current version",
|
||||
"FirmwareUpdate": "Firmware Update",
|
||||
"FirmwareUpdateHint": "Click here to view the changes between your version and the latest version",
|
||||
"FrmwareUpdateAllow": "By activating the update check, a request is sent to GitHub.com each time the page is called up to retrieve the currently available version. If you do not agree with this, leave this function deactivated.",
|
||||
"ResetReason0": "Reset Reason CPU 0",
|
||||
"ResetReason1": "Reset Reason CPU 1",
|
||||
"ConfigSaveCount": "Config save count",
|
||||
"Uptime": "Uptime",
|
||||
"UptimeValue": "0 days {time} | 1 day {time} | {count} days {time}"
|
||||
},
|
||||
"hardwareinfo": {
|
||||
"HardwareInformation": "Info Hardware",
|
||||
"ChipModel": "Chip Model",
|
||||
"ChipRevision": "Chip Revision",
|
||||
"ChipCores": "Chip Cores",
|
||||
"CpuFrequency": "CPU Frequency",
|
||||
"Mhz": "MHz",
|
||||
"CpuTemperature": "CPU Temperature",
|
||||
"FlashSize": "Flash Memory Size"
|
||||
},
|
||||
"memoryinfo": {
|
||||
"MemoryInformation": "Info Memoria",
|
||||
"Type": "Tipo",
|
||||
"Usage": "Uso",
|
||||
"Free": "Libera",
|
||||
"Used": "Usata",
|
||||
"Size": "Dimensione",
|
||||
"Heap": "Heap",
|
||||
"PsRam": "PSRAM",
|
||||
"LittleFs": "LittleFs",
|
||||
"Sketch": "Sketch"
|
||||
},
|
||||
"heapdetails": {
|
||||
"HeapDetails": "Dettagli memoria Heap",
|
||||
"TotalFree": "Libera totale",
|
||||
"LargestFreeBlock": "Blocco contiguo libero più grande",
|
||||
"MaxUsage": "Massima utilizzata dall'avvio",
|
||||
"Fragmentation": "Livello frammentazione"
|
||||
},
|
||||
"taskdetails": {
|
||||
"TaskDetails": "Task Details",
|
||||
"Name": "Name",
|
||||
"StackFree": "Stack Free",
|
||||
"Priority": "Priority",
|
||||
"Task_idle0": "Idle (CPU Core 0)",
|
||||
"Task_idle1": "Idle (CPU Core 1)",
|
||||
"Task_wifi": "Wi-Fi",
|
||||
"Task_tit": "TCP/IP",
|
||||
"Task_looptask": "Arduino Main Loop",
|
||||
"Task_asynctcp": "Async TCP",
|
||||
"Task_mqttclient": "MQTT Client",
|
||||
"Task_huaweican0": "AC Charger CAN",
|
||||
"Task_pmsdm": "PowerMeter (SDM)",
|
||||
"Task_pmhttpjson": "PowerMeter (HTTP+JSON)",
|
||||
"Task_pmsml": "PowerMeter (Serial SML)",
|
||||
"Task_pmhttpsml": "PowerMeter (HTTP+SML)"
|
||||
},
|
||||
"radioinfo": {
|
||||
"RadioInformation": "Info Transceiver Radio",
|
||||
"Status": "{module} Stato",
|
||||
"ChipStatus": "{module} Chip Stato",
|
||||
"ChipType": "{module} Chip Tipo",
|
||||
"Connected": "connesso",
|
||||
"NotConnected": "non connesso",
|
||||
"Configured": "configurato",
|
||||
"NotConfigured": "no configurato",
|
||||
"Unknown": "Sconosciuto"
|
||||
},
|
||||
"networkinfo": {
|
||||
"NetworkInformation": "Informazioni Rete"
|
||||
},
|
||||
"wifistationinfo": {
|
||||
"WifiStationInfo": "Info WiFi (Station)",
|
||||
"Status": "Stato",
|
||||
"Enabled": "abilitato",
|
||||
"Disabled": "disabilitato",
|
||||
"Ssid": "SSID",
|
||||
"Bssid": "BSSID",
|
||||
"Quality": "Qualità",
|
||||
"Rssi": "RSSI"
|
||||
},
|
||||
"wifiapinfo": {
|
||||
"WifiApInfo": "Info WiFi (Access Point)",
|
||||
"Status": "@:wifistationinfo.Status",
|
||||
"Enabled": "@:wifistationinfo.Enabled",
|
||||
"Disabled": "@:wifistationinfo.Disabled",
|
||||
"Ssid": "@:wifistationinfo.Ssid",
|
||||
"Stations": "Numero Stazioni"
|
||||
},
|
||||
"interfacenetworkinfo": {
|
||||
"NetworkInterface": "Interfaccia di Rete ({iface})",
|
||||
"Hostname": "@:firmwareinfo.Hostname",
|
||||
"IpAddress": "Indirizzo IP",
|
||||
"Netmask": "Netmask",
|
||||
"DefaultGateway": "Gateway",
|
||||
"Dns": "DNS {num}",
|
||||
"MacAddress": "Indirizzo MAC"
|
||||
},
|
||||
"interfaceapinfo": {
|
||||
"NetworkInterface": "Interfaccia di Rete (Access Point)",
|
||||
"IpAddress": "@:interfacenetworkinfo.IpAddress",
|
||||
"MacAddress": "@:interfacenetworkinfo.MacAddress"
|
||||
},
|
||||
"ntpinfo": {
|
||||
"NtpInformation": "Informazioni NTP",
|
||||
"ConfigurationSummary": "Riepilogo Configurazione",
|
||||
"Server": "Server",
|
||||
"Timezone": "Timezone",
|
||||
"TimezoneDescription": "Descrizione Timezone",
|
||||
"CurrentTime": "Data/Ora attuale",
|
||||
"Status": "Stato",
|
||||
"Synced": "sincronizzata",
|
||||
"NotSynced": "non sincronizzata",
|
||||
"LocalTime": "Ora Locale",
|
||||
"Sunrise": "Alba",
|
||||
"Sunset": "Tramonto",
|
||||
"NotAvailable": "Non Disponibile",
|
||||
"Mode": "Modalità",
|
||||
"Day": "Giorno",
|
||||
"Night": "Notte"
|
||||
},
|
||||
"mqttinfo": {
|
||||
"MqttInformation": "Informazioni MQTT",
|
||||
"ConfigurationSummary": "@:ntpinfo.ConfigurationSummary",
|
||||
"Status": "@:ntpinfo.Status",
|
||||
"Enabled": "Abilitato",
|
||||
"Disabled": "Disabilitato",
|
||||
"Server": "@:ntpinfo.Server",
|
||||
"Port": "Porta",
|
||||
"ClientId": "Client ID",
|
||||
"Username": "Username",
|
||||
"BaseTopic": "Topic Base",
|
||||
"PublishInterval": "Intervallo Publish",
|
||||
"Seconds": "{sec} secondi",
|
||||
"CleanSession": "CleanSession",
|
||||
"Retain": "Retain",
|
||||
"Tls": "TLS",
|
||||
"RootCertifcateInfo": "Info Certificato Root CA",
|
||||
"TlsCertLogin": "Entra con Certificato TLS",
|
||||
"ClientCertifcateInfo": "Info Certificato Client",
|
||||
"HassSummary": "Riepilogo Configurazione Home Assistant MQTT Auto Discovery",
|
||||
"Expire": "Scade",
|
||||
"IndividualPanels": "Pannello Individuale",
|
||||
"RuntimeSummary": "Riepilogo Runtime",
|
||||
"ConnectionStatus": "Stato Connessione",
|
||||
"Connected": "connesso",
|
||||
"Disconnected": "disconnesso"
|
||||
},
|
||||
"console": {
|
||||
"Console": "Console",
|
||||
"VirtualDebugConsole": "Virtual Debug Console",
|
||||
"EnableAutoScroll": "Abilita AutoScroll",
|
||||
"ClearConsole": "Pulisci Console",
|
||||
"CopyToClipboard": "Copia nella clipboard"
|
||||
},
|
||||
"inverterchannelinfo": {
|
||||
"String": "Stringa {num}",
|
||||
"Phase": "Fase {num}",
|
||||
"General": "Generale"
|
||||
},
|
||||
"invertertotalinfo": {
|
||||
"TotalYieldTotal": "Totale Energia",
|
||||
"TotalYieldDay": "Energia Giornaliera",
|
||||
"TotalPower": "Potenza Totale"
|
||||
},
|
||||
"inverterchannelproperty": {
|
||||
"Power": "Potenza",
|
||||
"Voltage": "Tensione",
|
||||
"Current": "Corrente",
|
||||
"Power DC": "PotenzaDC",
|
||||
"YieldDay": "EnergiaOggi",
|
||||
"YieldTotal": "EnergiaTotale",
|
||||
"Frequency": "Frequenza",
|
||||
"Temperature": "Temperatura",
|
||||
"PowerFactor": "FattorePotenza",
|
||||
"ReactivePower": "PotenzaReattiva",
|
||||
"Efficiency": "Efficienza",
|
||||
"Irradiation": "Irragiamento"
|
||||
},
|
||||
"maintenancereboot": {
|
||||
"DeviceReboot": "Riavvio DTU",
|
||||
"PerformReboot": "Fai il riavvio",
|
||||
"Reboot": "Riavvio!",
|
||||
"Cancel": "@:base.Cancel",
|
||||
"RebootOpenDTU": "Riavvio OpenDTU",
|
||||
"RebootQuestion": "Vuoi veramente riavvia il DTU?",
|
||||
"RebootHint": "<b>Nota:</b> Normalmente non serve riavviare OpenDTU, in quanto esegue automaticamente il ravvio quando necessario (ad esempio dopo aggiornamento firmware). Modifiche alla configurazione vengono apprese subito, senza richiedere riavvio. Se devi riavviare a causa di un errore, ti preghiamo di segnalarcelo cliccando su <a href=\"https://github.com/tbnobody/OpenDTU/issues\" class=\"alert-link\" target=\"_blank\">https://github.com/tbnobody/OpenDTU/issues</a>."
|
||||
},
|
||||
"dtuadmin": {
|
||||
"DtuSettings": "Impostazioni DTU",
|
||||
"DtuConfiguration": "Configurazione DTU",
|
||||
"Serial": "Seriale",
|
||||
"SerialHint": "Sia il DTU che l'inverter hanno un numero seriale. Il numero seriale del DTU è generato casualmente al primo avvio e normalmente non serve modificarlo.",
|
||||
"PollInterval": "Intervallo Interrogazione",
|
||||
"Seconds": "Secondi",
|
||||
"NrfPaLevel": "Potenza Trasmettitore NRF24",
|
||||
"CmtPaLevel": "Potenza Trasmettitore CMT2300A",
|
||||
"NrfPaLevelHint": "Usato per inverter HM. Considera che aumentando la potenza aumentano il consumo di corrente.",
|
||||
"CmtPaLevelHint": "Usato per inverter HMS/HMT. Considera che aumentando la potenza aumentano il consumo di corrente.",
|
||||
"CmtCountry": "CMT2300A Zona/Paese",
|
||||
"CmtCountryHint": "Ogni zona ha una differente allocazione di frequenze utilizzabili.",
|
||||
"country_0": "Europa ({min}MHz - {max}MHz)",
|
||||
"country_1": "Nord America ({min}MHz - {max}MHz)",
|
||||
"country_2": "Brasile ({min}MHz - {max}MHz)",
|
||||
"CmtFrequency": "Frequenza CMT2300A",
|
||||
"CmtFrequencyHint": "Fai attenzione ad usare solo frequenze ammesse nel tuo Paese! Dopo la modifica frequenza, servono fino a 15 minuti affinché la connessione si ristabilisca.",
|
||||
"CmtFrequencyWarning": "La frequenza selezionata è fuori dal range selezionato dal tuo Paese. Verifica che la frequenza selezionata non violi le normative del tuo Paese.",
|
||||
"MHz": "{mhz} MHz",
|
||||
"dBm": "{dbm} dBm",
|
||||
"Min": "Minima ({db} dBm)",
|
||||
"Low": "Bassa ({db} dBm)",
|
||||
"High": "Alta ({db} dBm)",
|
||||
"Max": "Massima ({db} dBm)"
|
||||
},
|
||||
"securityadmin": {
|
||||
"SecuritySettings": "Impostazioni di Sicurezza",
|
||||
"AdminPassword": "Password Admin",
|
||||
"Password": "Password",
|
||||
"RepeatPassword": "Ripeti Password",
|
||||
"PasswordHint": "<b>Nota:</b> La password di amministrazione viene utilizzata non solo per accedere a questa interfaccia web (con user 'admin'), ma anche per connettersi al dispositivo in modalità AP. Deve avere da 8 a 64 caratteri.",
|
||||
"Permissions": "Permessi",
|
||||
"ReadOnly": "Permetti accessi web in sola lettura senza richiedere la password"
|
||||
},
|
||||
"ntpadmin": {
|
||||
"NtpSettings": "Impostazioni NTP (Data / Ora)",
|
||||
"NtpConfiguration": "Configurazione NTP",
|
||||
"TimeServer": "Server NTP",
|
||||
"TimeServerHint": "Puoi lasciare il valore di default, nel caso in cui OpenDTU abbia accesso ad internet.",
|
||||
"Timezone": "Timezone",
|
||||
"TimezoneConfig": "Timezone Config",
|
||||
"LocationConfiguration": "Configurazione Posizione",
|
||||
"Longitude": "Longitudine",
|
||||
"Latitude": "Latitudine",
|
||||
"SunSetType": "Tipo di Alba",
|
||||
"SunSetTypeHint": "Influenza il calcolo dell'ora di Alba/Tramonto. Dopo la conferma, è richiesto fino ad un minuto perché la modifica venga applicata.",
|
||||
"OFFICIAL": "Standard dawn (90.8°)",
|
||||
"NAUTICAL": "Nautical dawn (102°)",
|
||||
"CIVIL": "Civil dawn (96°)",
|
||||
"ASTONOMICAL": "Astronomical dawn (108°)",
|
||||
"ManualTimeSynchronization": "Sincronizzazione Manuale Data/Ora",
|
||||
"CurrentOpenDtuTime": "Ora OpenDTU attuale",
|
||||
"CurrentLocalTime": "Ora Locale attuale",
|
||||
"SynchronizeTime": "Sincronizza Data/Ora",
|
||||
"SynchronizeTimeHint": "<b>Nota:</b> Puoi usare la sincronizzazione manuale per impostare Data/Ora nel caso che non sia disponibile un server NTP. In questo caso la data/ora viene persa in caso di mancata alimentazione. Inoltre, con la sincronizzazione manuale ci sarà una progressiva deriva della Data/Ora in quanto l'ESP32 non ha un Real Time Clock interno."
|
||||
},
|
||||
"networkadmin": {
|
||||
"NetworkSettings": "Impostazioni di Rete",
|
||||
"WifiConfiguration": "Configurazione WiFi",
|
||||
"WifiSsid": "WiFi SSID",
|
||||
"WifiPassword": "WiFi Password",
|
||||
"Hostname": "Hostname",
|
||||
"HostnameHint": "<b>Nota:</b> Il testo <span class=\"font-monospace\">%06X</span> sarà rimpiazzato con le ultime 6 cifre del ChipID dell'ESP32 in formato esadecimale.",
|
||||
"EnableDhcp": "Abilita DHCP",
|
||||
"StaticIpConfiguration": "Configurazione IP Statico",
|
||||
"IpAddress": "Indirizzo IP",
|
||||
"Netmask": "Netmask",
|
||||
"DefaultGateway": "Default Gateway",
|
||||
"Dns": "DNS Server {num}",
|
||||
"AdminAp": "Configurazione WiFi (Admin AccessPoint)",
|
||||
"ApTimeout": "Timeout AccessPoint",
|
||||
"ApTimeoutHint": "Tempo in cui la modalità AccessPoint rimarrà attiva. 0=per sempre.",
|
||||
"Minutes": "minuti",
|
||||
"EnableMdns": "Abilita mDNS",
|
||||
"MdnsSettings": "Configurazione mDNS"
|
||||
},
|
||||
"mqttadmin": {
|
||||
"MqttSettings": "Impostazioni MQTT",
|
||||
"MqttConfiguration": "Configurazione MQTT",
|
||||
"EnableMqtt": "Abilita MQTT",
|
||||
"EnableHass": "Abilita Home Assistant MQTT Auto Discovery",
|
||||
"MqttBrokerParameter": "Parametri Broker MQTT",
|
||||
"Hostname": "Hostname",
|
||||
"HostnameHint": "Hostname o Indirizzo IP",
|
||||
"Port": "Porta",
|
||||
"ClientId": "Client ID",
|
||||
"Username": "Username",
|
||||
"UsernameHint": "Username, lascia vuoto per connessione anonima",
|
||||
"Password": "Password",
|
||||
"PasswordHint": "Password, lascia vuota per connessione anonima",
|
||||
"BaseTopic": "Topic Base",
|
||||
"BaseTopicHint": "Topic Base, prefisso da aggiungere (ad esempio inverter/)",
|
||||
"PublishInterval": "Intervallo pubblicazione",
|
||||
"Seconds": "secondi",
|
||||
"CleanSession": "Abilita CleanSession",
|
||||
"EnableRetain": "Abilita Retain",
|
||||
"EnableTls": "Abilita TLS",
|
||||
"RootCa": "CA-Root-Certificate (default Letsencrypt)",
|
||||
"TlsCertLoginEnable": "Abilita Login con certificato TLS",
|
||||
"ClientCert": "TLS Client-Certificate",
|
||||
"ClientKey": "TLS Client-Key",
|
||||
"LwtParameters": "Parametri LWT",
|
||||
"LwtTopic": "Topic LWT",
|
||||
"LwtTopicHint": "Topic LWT, da aggiungere al Topic Base",
|
||||
"LwtOnline": "Messaggio 'Online0 LWT",
|
||||
"LwtOnlineHint": "Messaggio pubblicato quando online",
|
||||
"LwtOffline": "Messaggio 'Offline' LWT",
|
||||
"LwtOfflineHint": "Messaggio che sarà pubblicato quando offline",
|
||||
"LwtQos": "QoS (Quality of Service)",
|
||||
"QOS0": "0 (Al massimo una volta)",
|
||||
"QOS1": "1 (Almeno una volta)",
|
||||
"QOS2": "2 (Esattamente una volta)",
|
||||
"HassParameters": "Parametri Home Assistant MQTT Auto Discovery",
|
||||
"HassPrefixTopic": "Prefisso Topic",
|
||||
"HassPrefixTopicHint": "Prefisso per Topic autodiscovery",
|
||||
"HassRetain": "Abilita Retain",
|
||||
"HassExpire": "Abilita Scadenza",
|
||||
"HassIndividual": "Pannelli Individuale"
|
||||
},
|
||||
"inverteradmin": {
|
||||
"InverterSettings": "Impostazioni Inverter",
|
||||
"AddInverter": "Aggiungi nuovo Inverter",
|
||||
"Serial": "Seriale",
|
||||
"Name": "Nome",
|
||||
"Add": "Aggiungi",
|
||||
"AddHint": "<b>Nota:</b> Potrai aggiungere ulteriori parametri dopo aver creato l'inverter, cliccando sull'icona 'Matita' nella lista inverter.",
|
||||
"InverterList": "Lista Inverter",
|
||||
"Status": "Stato",
|
||||
"Send": "Invia",
|
||||
"Receive": "Riceve",
|
||||
"StatusHint": "<b>Nota:</b> L'inverter viene alimentato dal fotovoltaico. Durante la notte, l'inverter risulterà spento. Le richieste potranno comunque essere trasmesse.",
|
||||
"Type": "Tipo",
|
||||
"Action": "Azione",
|
||||
"SaveOrder": "Salva ordine",
|
||||
"DeleteInverter": "Rimuovi inverter",
|
||||
"EditInverter": "Modifica inverter",
|
||||
"General": "Generale",
|
||||
"String": "Stringa",
|
||||
"Advanced": "Avanzate",
|
||||
"InverterSerial": "Seriale Inverter:",
|
||||
"InverterName": "Nome Inverter:",
|
||||
"InverterNameHint": "Puoi specificare un nome qualsiasi da assegnare all'inverter.",
|
||||
"InverterStatus": "Riceve / Invia",
|
||||
"PollEnable": "Interroga inverter",
|
||||
"PollEnableNight": "Interroga inverter di notte",
|
||||
"CommandEnable": "Invia comandi",
|
||||
"CommandEnableNight": "Invia comandi di notte",
|
||||
"StringName": "Nome stringa {num}:",
|
||||
"StringNameHint": "Qui puoi specificare un nome qualsiasi per la porta dell'inverter o per il pannello fotovoltaico collegato.",
|
||||
"StringMaxPower": "Massima potenza stringa {num}:",
|
||||
"StringMaxPowerHint": "Inserisci la potenza massima associata ai panelli fotovoltaici collegati a questa stringa.",
|
||||
"StringYtOffset": "Offset Energia totale per la stringa {num}:",
|
||||
"StringYtOffsetHint": "Questo offset viene utilizzato per azzerare il contatore qualora venga usato un inverter usato.",
|
||||
"InverterHint": "*) Inserisci la potenza W<sub>p</sub> dei pannelli fotovoltaici collegati alla stringa: servirà per calcolare l'irragiamento.",
|
||||
"ReachableThreshold": "Reachable Threshold",
|
||||
"ReachableThresholdHint": "Definisce il numero di richieste fallite prima che l'inverter sia considerato irraggiungibile.",
|
||||
"ZeroRuntime": "Azzera dati in tempo reale",
|
||||
"ZeroRuntimeHint": "Azzera i dati in tempo reale (tranne l'Energia) se l'inverter diventa irraggiunbile.",
|
||||
"ZeroDay": "Azzera dati energia alla mezzanotte",
|
||||
"ZeroDayHint": "Questo vale se l'inverter risulta irraggiungibile. Se l'inverter risponde anche di notte, verranno mostrati i suoi valori. (Il Reset si verifica al riavvio)",
|
||||
"ClearEventlog": "Clear Eventlog at midnight",
|
||||
"Cancel": "@:base.Cancel",
|
||||
"Save": "@:base.Save",
|
||||
"DeleteMsg": "Sicuro di voler rimuovere l'inverter \"{name}\" con numero seriale {serial}?",
|
||||
"Delete": "Rimuovi",
|
||||
"YieldDayCorrection": "Correzione energia giornaliera",
|
||||
"YieldDayCorrectionHint": "Aggiungi questo valore all'energia giornaliera se l'inverter è stato riavviato. Questo valore sarò resettato a mezzanotte"
|
||||
},
|
||||
"fileadmin": {
|
||||
"ConfigManagement": "Configurazione Gestione",
|
||||
"BackupHeader": "Backup: Configurazione File Backup",
|
||||
"BackupConfig": "Esegui il backup del file",
|
||||
"Backup": "Backup",
|
||||
"Restore": "Ripristina",
|
||||
"NoFileSelected": "Nessun file selezionato",
|
||||
"RestoreHeader": "Ripristina: Ripristina File Configurazione",
|
||||
"Back": "Indietro",
|
||||
"UploadSuccess": "Invio File con successo",
|
||||
"RestoreHint": "<b>Nota:</b> questa operazione rimpiazza la configurazione con quella contenuta nel file, e poi riavvia automaticamente OpenDTU per applicare la nuova configurazione.",
|
||||
"ResetHeader": "Inizializza: Esegui il Factory Reset",
|
||||
"FactoryResetButton": "Ripristina Configurazione Factory-Default",
|
||||
"ResetHint": "<b>Nota:</b> Clicca 'Ripristina Configurazione Factory-Default' per stabilire le impostazioni di fabbrica e riavviare automaticamente OpenDTU.",
|
||||
"FactoryReset": "Factory Reset",
|
||||
"ResetMsg": "Sei sicuro di voler cancellare la configurazione attuale e applicare la configurazione di fabbrica?",
|
||||
"ResetConfirm": "Factory Reset!",
|
||||
"Cancel": "@:base.Cancel",
|
||||
"InvalidJson": "JSON file is formatted incorrectly.",
|
||||
"InvalidJsonContent": "JSON file has the wrong content."
|
||||
},
|
||||
"login": {
|
||||
"Login": "Login",
|
||||
"SystemLogin": "System Login",
|
||||
"Username": "Username",
|
||||
"UsernameRequired": "Inserisci Username",
|
||||
"Password": "Password",
|
||||
"PasswordRequired": "Inserisci Password",
|
||||
"LoginButton": "Login"
|
||||
},
|
||||
"firmwareupgrade": {
|
||||
"FirmwareUpgrade": "Aggiornamento Firmware",
|
||||
"Loading": "@:base.Loading",
|
||||
"OtaError": "Errore aggiornamento OTA",
|
||||
"Back": "Indietro",
|
||||
"Retry": "Riprova",
|
||||
"OtaStatus": "Stato OTA",
|
||||
"OtaSuccess": "Aggiornamento firmware eseguito con successo. Il dispositivo si riavvierà automaticamente. Quando sarà nuovamente disponibile, l'interfacca sarà ricaricata automaticamente.",
|
||||
"FirmwareUpload": "Invia Firmware",
|
||||
"UploadProgress": "Upload in corso"
|
||||
},
|
||||
"about": {
|
||||
"AboutOpendtu": "About OpenDTU",
|
||||
"Documentation": "Documentazione",
|
||||
"DocumentationBody": "La documentazione firmware e hardware sono disponibili qui: <a href=\"https://www.opendtu.solar\" target=\"_blank\">https://www.opendtu.solar</a>",
|
||||
"ProjectOrigin": "Origine Progetto",
|
||||
"ProjectOriginBody1": "Questo progetto è partito da <a href=\"https://www.mikrocontroller.net/topic/525778\" target=\"_blank\">questa discussione. (Mikrocontroller.net)</a>",
|
||||
"ProjectOriginBody2": "Il protocollo Hoymiles è stato decriptato grazie al contributo volontario di molti programmatori. OpenDTU, fra gli altri, è stato sviluppato grazie a questo lavoro. Il progetto è distribuito con Licenza Open Source (<a href=\"https://www.gnu.de/documents/gpl-2.0.de.html\" target=\"_blank\">GNU General Public License version 2</a>).",
|
||||
"ProjectOriginBody3": "Il software è stato sviluppato con le nostre migliori conoscenze e convinzioni. Tuttavia, non si assume alcuna responsabilità per malfunzionamenti o perdita di garanzia dell'inverter.",
|
||||
"ProjectOriginBody4": "OpenDTU è disponibile gratuitamente. Se hai pagato per questo software, probabilmente sei stato truffato.",
|
||||
"NewsUpdates": "Novità e Aggiornamenti",
|
||||
"NewsUpdatesBody": "Nuovi aggiornamenti sono disponibili su Github: <a href=\"https://github.com/tbnobody/OpenDTU\" target=\"_blank\">https://github.com/tbnobody/OpenDTU</a>",
|
||||
"ErrorReporting": "Segnalazione Errori",
|
||||
"ErrorReportingBody": "Per favore segnala eventuali problemi utilizzando le funzionalità della piattaforma <a href=\"https://github.com/tbnobody/OpenDTU/issues\" target=\"_blank\">Github</a>",
|
||||
"Discussion": "Discussioni",
|
||||
"DiscussionBody": "Puoi avviare una discussione con noi su <a href=\"https://discord.gg/WzhxEY62mB\" target=\"_blank\">Discord</a> o <a href=\"https://github.com/tbnobody/OpenDTU/discussions\" target=\"_blank\">Github</a>"
|
||||
},
|
||||
"hints": {
|
||||
"RadioProblem": "Non è possibile dialogare con il modulo radio selezionato. Controlla i collegamenti alla radio.",
|
||||
"TimeSync": "La Data/Ora non sono state sincronizzate, ed in tal caso non è possibile eseguire richieste all'inverter. Questa condizione è normale appena avviato, tuttavia dopo un po' (>1 minuto), questa situazione potrebbe indicare un problema di accesso al server NTP.",
|
||||
"TimeSyncLink": "Controlla le impostazioni Data/Ora.",
|
||||
"DefaultPassword": "Stai usando la password di default per accedere all'interfaccia web e per la modalità Access Point di emergenza. Questo può portare ad un rischio di sicurezza.",
|
||||
"DefaultPasswordLink": "Per favore cambia la password.",
|
||||
"PinMappingIssue": "You are using a generic firmware image, but have not yet uploaded a file with device profiles (<code>pin_mapping.json</code>) or have not selected a profile defined there. Please refer to the <a href=\"https://opendtu.solar/firmware/device_profiles/\" target=\"_blank\" class=\"alert-link\">documentation</a> for details."
|
||||
},
|
||||
"deviceadmin": {
|
||||
"DeviceManager": "Device-Manager",
|
||||
"ParseError": "Parse error in 'pin_mapping.json': {error}",
|
||||
"PinAssignment": "Impostazioni Connessione",
|
||||
"SelectedProfile": "Profilo selezionato",
|
||||
"DefaultProfile": "(Impostazioni di Default)",
|
||||
"ProfileHint": "Il tuo dispositivo potrebbe smettere di rispondere selezionando un profilo incompatibile. In questo caso, dovrai eseguire una cancellazione collegandoti all'interfaccia seriale.",
|
||||
"Display": "Display",
|
||||
"PowerSafe": "Abilita Risparmio Energetico",
|
||||
"PowerSafeHint": "Spegni il display se l'inverter non produce.",
|
||||
"Screensaver": "Abilita Screensaver",
|
||||
"ScreensaverHint": "Muove il testo nel display per prevenire danneggiamento pixel. (Utile in caso di display OLED)",
|
||||
"DiagramMode": "Modalità grafica",
|
||||
"off": "Off",
|
||||
"small": "Small",
|
||||
"fullscreen": "Fullscreen",
|
||||
"DiagramDuration": "Durata grafico",
|
||||
"DiagramDurationHint": "Periodo che viene mostrato nel grafico.",
|
||||
"Seconds": "Secondi",
|
||||
"Contrast": "Contrasto ({contrast})",
|
||||
"Rotation": "Rotazione",
|
||||
"rot0": "Nessuna rotazione",
|
||||
"rot90": "Rotazione 90 gradi",
|
||||
"rot180": "Rotazione 180 gradi",
|
||||
"rot270": "Rotazione 270 gradi",
|
||||
"DisplayLanguage": "Linuga Display",
|
||||
"en": "English",
|
||||
"de": "German",
|
||||
"fr": "French",
|
||||
"Leds": "LEDs",
|
||||
"EqualBrightness": "Equalizza luminosità",
|
||||
"LedBrightness": "LED {led}, Luminosità ({brightness})"
|
||||
},
|
||||
"pininfo": {
|
||||
"Category": "Categoria",
|
||||
"Name": "Nome",
|
||||
"Number": "Numero",
|
||||
"ValueSelected": "Selezionato",
|
||||
"ValueActive": "Attivo"
|
||||
},
|
||||
"inputserial": {
|
||||
"format_hoymiles": "Hoymiles serial number format",
|
||||
"format_converted": "Already converted serial number",
|
||||
"format_herf_valid": "E-Star HERF format (will be saved converted): {serial}",
|
||||
"format_herf_invalid": "E-Star HERF format: Invalid checksum",
|
||||
"format_unknown": "Unknown format"
|
||||
}
|
||||
}
|
||||
}
|
||||
778
lib/CMT2300a/cmt2300a.c
Normal file
778
lib/CMT2300a/cmt2300a.c
Normal file
@ -0,0 +1,778 @@
|
||||
/*
|
||||
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
|
||||
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
|
||||
* CONSEQUENTLY, CMOSTEK SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
|
||||
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
|
||||
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* Copyright (C) CMOSTEK SZ.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file cmt2300a.c
|
||||
* @brief CMT2300A transceiver RF chip driver
|
||||
*
|
||||
* @version 1.3
|
||||
* @date Jul 17 2017
|
||||
* @author CMOSTEK R@D
|
||||
*/
|
||||
|
||||
#include "cmt2300a.h"
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_SoftReset
|
||||
* @desc Soft reset.
|
||||
* *********************************************************/
|
||||
void CMT2300A_SoftReset(void)
|
||||
{
|
||||
CMT2300A_WriteReg(0x7F, 0xFF);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_GetChipStatus
|
||||
* @desc Get the chip status.
|
||||
* @return
|
||||
* CMT2300A_STA_PUP
|
||||
* CMT2300A_STA_SLEEP
|
||||
* CMT2300A_STA_STBY
|
||||
* CMT2300A_STA_RFS
|
||||
* CMT2300A_STA_TFS
|
||||
* CMT2300A_STA_RX
|
||||
* CMT2300A_STA_TX
|
||||
* CMT2300A_STA_EEPROM
|
||||
* CMT2300A_STA_ERROR
|
||||
* CMT2300A_STA_CAL
|
||||
* *********************************************************/
|
||||
uint8_t CMT2300A_GetChipStatus(void)
|
||||
{
|
||||
return CMT2300A_ReadReg(CMT2300A_CUS_MODE_STA) & CMT2300A_MASK_CHIP_MODE_STA;
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_AutoSwitchStatus
|
||||
* @desc Auto switch the chip status, and 10 ms as timeout.
|
||||
* @param nGoCmd: the chip next status
|
||||
* @return TRUE or FALSE
|
||||
* *********************************************************/
|
||||
bool CMT2300A_AutoSwitchStatus(uint8_t nGoCmd)
|
||||
{
|
||||
#ifdef ENABLE_AUTO_SWITCH_CHIP_STATUS
|
||||
uint32_t nBegTick = CMT2300A_GetTickCount();
|
||||
uint8_t nWaitStatus = 0;
|
||||
|
||||
switch (nGoCmd) {
|
||||
case CMT2300A_GO_SLEEP:
|
||||
nWaitStatus = CMT2300A_STA_SLEEP;
|
||||
break;
|
||||
case CMT2300A_GO_STBY:
|
||||
nWaitStatus = CMT2300A_STA_STBY;
|
||||
break;
|
||||
case CMT2300A_GO_TFS:
|
||||
nWaitStatus = CMT2300A_STA_TFS;
|
||||
break;
|
||||
case CMT2300A_GO_TX:
|
||||
nWaitStatus = CMT2300A_STA_TX;
|
||||
break;
|
||||
case CMT2300A_GO_RFS:
|
||||
nWaitStatus = CMT2300A_STA_RFS;
|
||||
break;
|
||||
case CMT2300A_GO_RX:
|
||||
nWaitStatus = CMT2300A_STA_RX;
|
||||
break;
|
||||
}
|
||||
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_MODE_CTL, nGoCmd);
|
||||
|
||||
while (CMT2300A_GetTickCount() - nBegTick < 10) {
|
||||
CMT2300A_DelayUs(100);
|
||||
|
||||
if (nWaitStatus == CMT2300A_GetChipStatus())
|
||||
return true;
|
||||
|
||||
if (CMT2300A_GO_TX == nGoCmd) {
|
||||
CMT2300A_DelayUs(100);
|
||||
|
||||
if (CMT2300A_MASK_TX_DONE_FLG & CMT2300A_ReadReg(CMT2300A_CUS_INT_CLR1))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (CMT2300A_GO_RX == nGoCmd) {
|
||||
CMT2300A_DelayUs(100);
|
||||
|
||||
if (CMT2300A_MASK_PKT_OK_FLG & CMT2300A_ReadReg(CMT2300A_CUS_INT_FLAG))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
#else
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_MODE_CTL, nGoCmd);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_GoSleep
|
||||
* @desc Entry SLEEP mode.
|
||||
* @return TRUE or FALSE
|
||||
* *********************************************************/
|
||||
bool CMT2300A_GoSleep(void)
|
||||
{
|
||||
return CMT2300A_AutoSwitchStatus(CMT2300A_GO_SLEEP);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_GoStby
|
||||
* @desc Entry Sleep mode.
|
||||
* @return TRUE or FALSE
|
||||
* *********************************************************/
|
||||
bool CMT2300A_GoStby(void)
|
||||
{
|
||||
return CMT2300A_AutoSwitchStatus(CMT2300A_GO_STBY);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_GoTFS
|
||||
* @desc Entry TFS mode.
|
||||
* @return TRUE or FALSE
|
||||
* *********************************************************/
|
||||
bool CMT2300A_GoTFS(void)
|
||||
{
|
||||
return CMT2300A_AutoSwitchStatus(CMT2300A_GO_TFS);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_GoRFS
|
||||
* @desc Entry RFS mode.
|
||||
* @return TRUE or FALSE
|
||||
* *********************************************************/
|
||||
bool CMT2300A_GoRFS(void)
|
||||
{
|
||||
return CMT2300A_AutoSwitchStatus(CMT2300A_GO_RFS);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_GoTx
|
||||
* @desc Entry Tx mode.
|
||||
* @return TRUE or FALSE
|
||||
* *********************************************************/
|
||||
bool CMT2300A_GoTx(void)
|
||||
{
|
||||
return CMT2300A_AutoSwitchStatus(CMT2300A_GO_TX);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_GoRx
|
||||
* @desc Entry Rx mode.
|
||||
* @return TRUE or FALSE
|
||||
* *********************************************************/
|
||||
bool CMT2300A_GoRx(void)
|
||||
{
|
||||
return CMT2300A_AutoSwitchStatus(CMT2300A_GO_RX);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_ConfigGpio
|
||||
* @desc Config GPIO pins mode.
|
||||
* @param nGpioSel: GPIO1_SEL | GPIO2_SEL | GPIO3_SEL | GPIO4_SEL
|
||||
* GPIO1_SEL:
|
||||
* CMT2300A_GPIO1_SEL_DOUT/DIN
|
||||
* CMT2300A_GPIO1_SEL_INT1
|
||||
* CMT2300A_GPIO1_SEL_INT2
|
||||
* CMT2300A_GPIO1_SEL_DCLK
|
||||
*
|
||||
* GPIO2_SEL:
|
||||
* CMT2300A_GPIO2_SEL_INT1
|
||||
* CMT2300A_GPIO2_SEL_INT2
|
||||
* CMT2300A_GPIO2_SEL_DOUT/DIN
|
||||
* CMT2300A_GPIO2_SEL_DCLK
|
||||
*
|
||||
* GPIO3_SEL:
|
||||
* CMT2300A_GPIO3_SEL_CLKO
|
||||
* CMT2300A_GPIO3_SEL_DOUT/DIN
|
||||
* CMT2300A_GPIO3_SEL_INT2
|
||||
* CMT2300A_GPIO3_SEL_DCLK
|
||||
*
|
||||
* GPIO4_SEL:
|
||||
* CMT2300A_GPIO4_SEL_RSTIN
|
||||
* CMT2300A_GPIO4_SEL_INT1
|
||||
* CMT2300A_GPIO4_SEL_DOUT
|
||||
* CMT2300A_GPIO4_SEL_DCLK
|
||||
* *********************************************************/
|
||||
void CMT2300A_ConfigGpio(uint8_t nGpioSel)
|
||||
{
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_IO_SEL, nGpioSel);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_ConfigInterrupt
|
||||
* @desc Config interrupt on INT1 and INT2.
|
||||
* @param nInt1Sel, nInt2Sel
|
||||
* CMT2300A_INT_SEL_RX_ACTIVE
|
||||
* CMT2300A_INT_SEL_TX_ACTIVE
|
||||
* CMT2300A_INT_SEL_RSSI_VLD
|
||||
* CMT2300A_INT_SEL_PREAM_OK
|
||||
* CMT2300A_INT_SEL_SYNC_OK
|
||||
* CMT2300A_INT_SEL_NODE_OK
|
||||
* CMT2300A_INT_SEL_CRC_OK
|
||||
* CMT2300A_INT_SEL_PKT_OK
|
||||
* CMT2300A_INT_SEL_SL_TMO
|
||||
* CMT2300A_INT_SEL_RX_TMO
|
||||
* CMT2300A_INT_SEL_TX_DONE
|
||||
* CMT2300A_INT_SEL_RX_FIFO_NMTY
|
||||
* CMT2300A_INT_SEL_RX_FIFO_TH
|
||||
* CMT2300A_INT_SEL_RX_FIFO_FULL
|
||||
* CMT2300A_INT_SEL_RX_FIFO_WBYTE
|
||||
* CMT2300A_INT_SEL_RX_FIFO_OVF
|
||||
* CMT2300A_INT_SEL_TX_FIFO_NMTY
|
||||
* CMT2300A_INT_SEL_TX_FIFO_TH
|
||||
* CMT2300A_INT_SEL_TX_FIFO_FULL
|
||||
* CMT2300A_INT_SEL_STATE_IS_STBY
|
||||
* CMT2300A_INT_SEL_STATE_IS_FS
|
||||
* CMT2300A_INT_SEL_STATE_IS_RX
|
||||
* CMT2300A_INT_SEL_STATE_IS_TX
|
||||
* CMT2300A_INT_SEL_LED
|
||||
* CMT2300A_INT_SEL_TRX_ACTIVE
|
||||
* CMT2300A_INT_SEL_PKT_DONE
|
||||
* *********************************************************/
|
||||
void CMT2300A_ConfigInterrupt(uint8_t nInt1Sel, uint8_t nInt2Sel)
|
||||
{
|
||||
nInt1Sel &= CMT2300A_MASK_INT1_SEL;
|
||||
nInt1Sel |= (~CMT2300A_MASK_INT1_SEL) & CMT2300A_ReadReg(CMT2300A_CUS_INT1_CTL);
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_INT1_CTL, nInt1Sel);
|
||||
|
||||
nInt2Sel &= CMT2300A_MASK_INT2_SEL;
|
||||
nInt2Sel |= (~CMT2300A_MASK_INT2_SEL) & CMT2300A_ReadReg(CMT2300A_CUS_INT2_CTL);
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_INT2_CTL, nInt2Sel);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_SetInterruptPolar
|
||||
* @desc Set the polarity of the interrupt.
|
||||
* @param bEnable(TRUE): active-high (default)
|
||||
* bEnable(FALSE): active-low
|
||||
* *********************************************************/
|
||||
void CMT2300A_SetInterruptPolar(bool bActiveHigh)
|
||||
{
|
||||
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_INT1_CTL);
|
||||
|
||||
if (bActiveHigh)
|
||||
tmp &= ~CMT2300A_MASK_INT_POLAR;
|
||||
else
|
||||
tmp |= CMT2300A_MASK_INT_POLAR;
|
||||
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_INT1_CTL, tmp);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_SetFifoThreshold
|
||||
* @desc Set FIFO threshold.
|
||||
* @param nFifoThreshold
|
||||
* *********************************************************/
|
||||
void CMT2300A_SetFifoThreshold(uint8_t nFifoThreshold)
|
||||
{
|
||||
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_PKT29);
|
||||
|
||||
tmp &= ~CMT2300A_MASK_FIFO_TH;
|
||||
tmp |= nFifoThreshold & CMT2300A_MASK_FIFO_TH;
|
||||
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_PKT29, tmp);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_EnableAntennaSwitch
|
||||
* @desc Enable antenna switch, output TX_ACTIVE/RX_ACTIVE
|
||||
* via GPIO1/GPIO2.
|
||||
* @param nMode
|
||||
* 0: RF_SWT1_EN=1, RF_SWT2_EN=0
|
||||
* GPIO1: RX_ACTIVE, GPIO2: TX_ACTIVE
|
||||
* 1: RF_SWT1_EN=0, RF_SWT2_EN=1
|
||||
* GPIO1: RX_ACTIVE, GPIO2: ~RX_ACTIVE
|
||||
* *********************************************************/
|
||||
void CMT2300A_EnableAntennaSwitch(uint8_t nMode)
|
||||
{
|
||||
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_INT1_CTL);
|
||||
|
||||
if (0 == nMode) {
|
||||
tmp |= CMT2300A_MASK_RF_SWT1_EN;
|
||||
tmp &= ~CMT2300A_MASK_RF_SWT2_EN;
|
||||
} else if (1 == nMode) {
|
||||
tmp &= ~CMT2300A_MASK_RF_SWT1_EN;
|
||||
tmp |= CMT2300A_MASK_RF_SWT2_EN;
|
||||
}
|
||||
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_INT1_CTL, tmp);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_EnableInterrupt
|
||||
* @desc Enable interrupt.
|
||||
* @param nEnable
|
||||
* CMT2300A_MASK_SL_TMO_EN |
|
||||
* CMT2300A_MASK_RX_TMO_EN |
|
||||
* CMT2300A_MASK_TX_DONE_EN |
|
||||
* CMT2300A_MASK_PREAM_OK_EN |
|
||||
* CMT2300A_MASK_SYNC_OK_EN |
|
||||
* CMT2300A_MASK_NODE_OK_EN |
|
||||
* CMT2300A_MASK_CRC_OK_EN |
|
||||
* CMT2300A_MASK_PKT_DONE_EN
|
||||
* *********************************************************/
|
||||
void CMT2300A_EnableInterrupt(uint8_t nEnable)
|
||||
{
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_INT_EN, nEnable);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_EnableRxFifoAutoClear
|
||||
* @desc Auto clear Rx FIFO before entry Rx mode.
|
||||
* @param bEnable(TRUE): Enable it(default)
|
||||
* bEnable(FALSE): Disable it
|
||||
* *********************************************************/
|
||||
void CMT2300A_EnableRxFifoAutoClear(bool bEnable)
|
||||
{
|
||||
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_FIFO_CTL);
|
||||
|
||||
if (bEnable)
|
||||
tmp &= ~CMT2300A_MASK_FIFO_AUTO_CLR_DIS;
|
||||
else
|
||||
tmp |= CMT2300A_MASK_FIFO_AUTO_CLR_DIS;
|
||||
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_FIFO_CTL, tmp);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_EnableFifoMerge
|
||||
* @desc Enable FIFO merge.
|
||||
* @param bEnable(TRUE): use a single 64-byte FIFO for either Tx or Rx
|
||||
* bEnable(FALSE): use a 32-byte FIFO for Tx and another 32-byte FIFO for Rx(default)
|
||||
* *********************************************************/
|
||||
void CMT2300A_EnableFifoMerge(bool bEnable)
|
||||
{
|
||||
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_FIFO_CTL);
|
||||
|
||||
if (bEnable)
|
||||
tmp |= CMT2300A_MASK_FIFO_MERGE_EN;
|
||||
else
|
||||
tmp &= ~CMT2300A_MASK_FIFO_MERGE_EN;
|
||||
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_FIFO_CTL, tmp);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_EnableReadFifo
|
||||
* @desc Enable SPI to read the FIFO.
|
||||
* *********************************************************/
|
||||
void CMT2300A_EnableReadFifo(void)
|
||||
{
|
||||
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_FIFO_CTL);
|
||||
tmp &= ~CMT2300A_MASK_SPI_FIFO_RD_WR_SEL;
|
||||
tmp &= ~CMT2300A_MASK_FIFO_RX_TX_SEL;
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_FIFO_CTL, tmp);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_EnableWriteFifo
|
||||
* @desc Enable SPI to write the FIFO.
|
||||
* *********************************************************/
|
||||
void CMT2300A_EnableWriteFifo(void)
|
||||
{
|
||||
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_FIFO_CTL);
|
||||
tmp |= CMT2300A_MASK_SPI_FIFO_RD_WR_SEL;
|
||||
tmp |= CMT2300A_MASK_FIFO_RX_TX_SEL;
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_FIFO_CTL, tmp);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_RestoreFifo
|
||||
* @desc Restore the FIFO.
|
||||
* *********************************************************/
|
||||
void CMT2300A_RestoreFifo(void)
|
||||
{
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_FIFO_CLR, CMT2300A_MASK_FIFO_RESTORE);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_ClearFifo
|
||||
* @desc Clear the Tx FIFO.
|
||||
* @return FIFO flags
|
||||
* CMT2300A_MASK_RX_FIFO_FULL_FLG |
|
||||
* CMT2300A_MASK_RX_FIFO_NMTY_FLG |
|
||||
* CMT2300A_MASK_RX_FIFO_TH_FLG |
|
||||
* CMT2300A_MASK_RX_FIFO_OVF_FLG |
|
||||
* CMT2300A_MASK_TX_FIFO_FULL_FLG |
|
||||
* CMT2300A_MASK_TX_FIFO_NMTY_FLG |
|
||||
* CMT2300A_MASK_TX_FIFO_TH_FLG
|
||||
* *********************************************************/
|
||||
uint8_t CMT2300A_ClearTxFifo(void)
|
||||
{
|
||||
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_FIFO_FLAG);
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_FIFO_CLR, CMT2300A_MASK_FIFO_CLR_TX);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_ClearFifo
|
||||
* @desc Clear the Rx FIFO.
|
||||
* @return FIFO flags
|
||||
* CMT2300A_MASK_RX_FIFO_FULL_FLG |
|
||||
* CMT2300A_MASK_RX_FIFO_NMTY_FLG |
|
||||
* CMT2300A_MASK_RX_FIFO_TH_FLG |
|
||||
* CMT2300A_MASK_RX_FIFO_OVF_FLG |
|
||||
* CMT2300A_MASK_TX_FIFO_FULL_FLG |
|
||||
* CMT2300A_MASK_TX_FIFO_NMTY_FLG |
|
||||
* CMT2300A_MASK_TX_FIFO_TH_FLG
|
||||
* *********************************************************/
|
||||
uint8_t CMT2300A_ClearRxFifo(void)
|
||||
{
|
||||
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_FIFO_FLAG);
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_FIFO_CLR, CMT2300A_MASK_FIFO_CLR_RX);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_ClearInterruptFlags
|
||||
* @desc Clear all interrupt flags.
|
||||
* @return Some interrupt flags
|
||||
* CMT2300A_MASK_SL_TMO_EN |
|
||||
* CMT2300A_MASK_RX_TMO_EN |
|
||||
* CMT2300A_MASK_TX_DONE_EN |
|
||||
* CMT2300A_MASK_PREAM_OK_FLG |
|
||||
* CMT2300A_MASK_SYNC_OK_FLG |
|
||||
* CMT2300A_MASK_NODE_OK_FLG |
|
||||
* CMT2300A_MASK_CRC_OK_FLG |
|
||||
* CMT2300A_MASK_PKT_OK_FLG
|
||||
* *********************************************************/
|
||||
uint8_t CMT2300A_ClearInterruptFlags(void)
|
||||
{
|
||||
uint8_t nFlag1, nFlag2;
|
||||
uint8_t nClr1 = 0;
|
||||
uint8_t nClr2 = 0;
|
||||
uint8_t nRet = 0;
|
||||
uint8_t nIntPolar;
|
||||
|
||||
nIntPolar = CMT2300A_ReadReg(CMT2300A_CUS_INT1_CTL);
|
||||
nIntPolar = (nIntPolar & CMT2300A_MASK_INT_POLAR) ? 1 : 0;
|
||||
|
||||
nFlag1 = CMT2300A_ReadReg(CMT2300A_CUS_INT_FLAG);
|
||||
nFlag2 = CMT2300A_ReadReg(CMT2300A_CUS_INT_CLR1);
|
||||
|
||||
if (nIntPolar) {
|
||||
/* Interrupt flag active-low */
|
||||
nFlag1 = ~nFlag1;
|
||||
nFlag2 = ~nFlag2;
|
||||
}
|
||||
|
||||
if (CMT2300A_MASK_LBD_FLG & nFlag1) {
|
||||
nClr2 |= CMT2300A_MASK_LBD_CLR; /* Clear LBD_FLG */
|
||||
}
|
||||
|
||||
if (CMT2300A_MASK_COL_ERR_FLG & nFlag1) {
|
||||
nClr2 |= CMT2300A_MASK_PKT_DONE_CLR; /* Clear COL_ERR_FLG by PKT_DONE_CLR */
|
||||
}
|
||||
|
||||
if (CMT2300A_MASK_PKT_ERR_FLG & nFlag1) {
|
||||
nClr2 |= CMT2300A_MASK_PKT_DONE_CLR; /* Clear PKT_ERR_FLG by PKT_DONE_CLR */
|
||||
}
|
||||
|
||||
if (CMT2300A_MASK_PREAM_OK_FLG & nFlag1) {
|
||||
nClr2 |= CMT2300A_MASK_PREAM_OK_CLR; /* Clear PREAM_OK_FLG */
|
||||
nRet |= CMT2300A_MASK_PREAM_OK_FLG; /* Return PREAM_OK_FLG */
|
||||
}
|
||||
|
||||
if (CMT2300A_MASK_SYNC_OK_FLG & nFlag1) {
|
||||
nClr2 |= CMT2300A_MASK_SYNC_OK_CLR; /* Clear SYNC_OK_FLG */
|
||||
nRet |= CMT2300A_MASK_SYNC_OK_FLG; /* Return SYNC_OK_FLG */
|
||||
}
|
||||
|
||||
if (CMT2300A_MASK_NODE_OK_FLG & nFlag1) {
|
||||
nClr2 |= CMT2300A_MASK_NODE_OK_CLR; /* Clear NODE_OK_FLG */
|
||||
nRet |= CMT2300A_MASK_NODE_OK_FLG; /* Return NODE_OK_FLG */
|
||||
}
|
||||
|
||||
if (CMT2300A_MASK_CRC_OK_FLG & nFlag1) {
|
||||
nClr2 |= CMT2300A_MASK_CRC_OK_CLR; /* Clear CRC_OK_FLG */
|
||||
nRet |= CMT2300A_MASK_CRC_OK_FLG; /* Return CRC_OK_FLG */
|
||||
}
|
||||
|
||||
if (CMT2300A_MASK_PKT_OK_FLG & nFlag1) {
|
||||
nClr2 |= CMT2300A_MASK_PKT_DONE_CLR; /* Clear PKT_OK_FLG */
|
||||
nRet |= CMT2300A_MASK_PKT_OK_FLG; /* Return PKT_OK_FLG */
|
||||
}
|
||||
|
||||
if (CMT2300A_MASK_SL_TMO_FLG & nFlag2) {
|
||||
nClr1 |= CMT2300A_MASK_SL_TMO_CLR; /* Clear SL_TMO_FLG */
|
||||
nRet |= CMT2300A_MASK_SL_TMO_EN; /* Return SL_TMO_FLG by SL_TMO_EN */
|
||||
}
|
||||
|
||||
if (CMT2300A_MASK_RX_TMO_FLG & nFlag2) {
|
||||
nClr1 |= CMT2300A_MASK_RX_TMO_CLR; /* Clear RX_TMO_FLG */
|
||||
nRet |= CMT2300A_MASK_RX_TMO_EN; /* Return RX_TMO_FLG by RX_TMO_EN */
|
||||
}
|
||||
|
||||
if (CMT2300A_MASK_TX_DONE_FLG & nFlag2) {
|
||||
nClr1 |= CMT2300A_MASK_TX_DONE_CLR; /* Clear TX_DONE_FLG */
|
||||
nRet |= CMT2300A_MASK_TX_DONE_EN; /* Return TX_DONE_FLG by TX_DONE_EN */
|
||||
}
|
||||
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_INT_CLR1, nClr1);
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_INT_CLR2, nClr2);
|
||||
|
||||
if (nIntPolar) {
|
||||
/* Interrupt flag active-low */
|
||||
nRet = ~nRet;
|
||||
}
|
||||
|
||||
return nRet;
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_ConfigTxDin
|
||||
* @desc Used to select whether to use GPIO1 or GPIO2 or GPIO3
|
||||
* as DIN in the direct mode. It only takes effect when
|
||||
* call CMT2300A_EnableTxDin(TRUE) in the direct mode.
|
||||
* @param nDinSel
|
||||
* CMT2300A_TX_DIN_SEL_GPIO1
|
||||
* CMT2300A_TX_DIN_SEL_GPIO2
|
||||
* CMT2300A_TX_DIN_SEL_GPIO3
|
||||
* *********************************************************/
|
||||
void CMT2300A_ConfigTxDin(uint8_t nDinSel)
|
||||
{
|
||||
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_FIFO_CTL);
|
||||
tmp &= ~CMT2300A_MASK_TX_DIN_SEL;
|
||||
tmp |= nDinSel;
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_FIFO_CTL, tmp);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_EnableTxDin
|
||||
* @desc Used to change GPIO1/GPIO2/GPIO3 between DOUT and DIN.
|
||||
* @param bEnable(TRUE): used as DIN
|
||||
* bEnable(FALSE): used as DOUT(default)
|
||||
* *********************************************************/
|
||||
void CMT2300A_EnableTxDin(bool bEnable)
|
||||
{
|
||||
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_FIFO_CTL);
|
||||
|
||||
if (bEnable)
|
||||
tmp |= CMT2300A_MASK_TX_DIN_EN;
|
||||
else
|
||||
tmp &= ~CMT2300A_MASK_TX_DIN_EN;
|
||||
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_FIFO_CTL, tmp);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_EnableTxDinInvert
|
||||
* @desc Used to invert DIN data in direct mode.
|
||||
* @param bEnable(TRUE): invert DIN
|
||||
* bEnable(FALSE): not invert DIN(default)
|
||||
* *********************************************************/
|
||||
void CMT2300A_EnableTxDinInvert(bool bEnable)
|
||||
{
|
||||
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_INT2_CTL);
|
||||
|
||||
if (bEnable)
|
||||
tmp |= CMT2300A_MASK_TX_DIN_INV;
|
||||
else
|
||||
tmp &= ~CMT2300A_MASK_TX_DIN_INV;
|
||||
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_INT2_CTL, tmp);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_IsExist
|
||||
* @desc Chip indentify.
|
||||
* @return TRUE: chip is exist, FALSE: chip not found
|
||||
* *********************************************************/
|
||||
bool CMT2300A_IsExist(void)
|
||||
{
|
||||
uint8_t back, dat;
|
||||
|
||||
back = CMT2300A_ReadReg(CMT2300A_CUS_PKT17);
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_PKT17, 0xAA);
|
||||
|
||||
dat = CMT2300A_ReadReg(CMT2300A_CUS_PKT17);
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_PKT17, back);
|
||||
|
||||
if (0xAA == dat)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_GetRssiCode
|
||||
* @desc Get RSSI code.
|
||||
* @return RSSI code
|
||||
* *********************************************************/
|
||||
uint8_t CMT2300A_GetRssiCode(void)
|
||||
{
|
||||
return CMT2300A_ReadReg(CMT2300A_CUS_RSSI_CODE);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_GetRssiDBm
|
||||
* @desc Get RSSI dBm.
|
||||
* @return dBm
|
||||
* *********************************************************/
|
||||
int CMT2300A_GetRssiDBm(void)
|
||||
{
|
||||
return (int)CMT2300A_ReadReg(CMT2300A_CUS_RSSI_DBM) - 128;
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_SetFrequencyChannel
|
||||
* @desc This defines up to 255 frequency channel
|
||||
* for fast frequency hopping operation.
|
||||
* @param nChann: the frequency channel
|
||||
* *********************************************************/
|
||||
void CMT2300A_SetFrequencyChannel(const uint8_t nChann)
|
||||
{
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_FREQ_CHNL, nChann);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_SetFrequencyStep
|
||||
* @desc This defines the frequency channel step size
|
||||
* for fast frequency hopping operation.
|
||||
* One step size is 2.5 kHz.
|
||||
* @param nOffset: the frequency step
|
||||
* *********************************************************/
|
||||
void CMT2300A_SetFrequencyStep(uint8_t nOffset)
|
||||
{
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_FREQ_OFS, nOffset);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_SetPayloadLength
|
||||
* @desc Set payload length.
|
||||
* @param nLength
|
||||
* *********************************************************/
|
||||
void CMT2300A_SetPayloadLength(uint16_t nLength)
|
||||
{
|
||||
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_PKT14);
|
||||
|
||||
tmp &= ~CMT2300A_MASK_PAYLOAD_LENG_10_8;
|
||||
tmp |= (nLength >> 4) & CMT2300A_MASK_PAYLOAD_LENG_10_8;
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_PKT14, tmp);
|
||||
|
||||
tmp = nLength & CMT2300A_MASK_PAYLOAD_LENG_7_0;
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_PKT15, tmp);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_EnableLfosc
|
||||
* @desc If you need use sleep timer, you should enable LFOSC.
|
||||
* @param bEnable(TRUE): Enable it(default)
|
||||
* bEnable(FALSE): Disable it
|
||||
* *********************************************************/
|
||||
void CMT2300A_EnableLfosc(bool bEnable)
|
||||
{
|
||||
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_SYS2);
|
||||
|
||||
if (bEnable) {
|
||||
tmp |= CMT2300A_MASK_LFOSC_RECAL_EN;
|
||||
tmp |= CMT2300A_MASK_LFOSC_CAL1_EN;
|
||||
tmp |= CMT2300A_MASK_LFOSC_CAL2_EN;
|
||||
} else {
|
||||
tmp &= ~CMT2300A_MASK_LFOSC_RECAL_EN;
|
||||
tmp &= ~CMT2300A_MASK_LFOSC_CAL1_EN;
|
||||
tmp &= ~CMT2300A_MASK_LFOSC_CAL2_EN;
|
||||
}
|
||||
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_SYS2, tmp);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_EnableLfoscOutput
|
||||
* @desc LFOSC clock is output via GPIO3.
|
||||
* @param bEnable(TRUE): Enable it
|
||||
* bEnable(FALSE): Disable it(default)
|
||||
* *********************************************************/
|
||||
void CMT2300A_EnableLfoscOutput(bool bEnable)
|
||||
{
|
||||
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_INT2_CTL);
|
||||
|
||||
if (bEnable)
|
||||
tmp |= CMT2300A_MASK_LFOSC_OUT_EN;
|
||||
else
|
||||
tmp &= ~CMT2300A_MASK_LFOSC_OUT_EN;
|
||||
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_INT2_CTL, tmp);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_EnableAfc
|
||||
* @desc AFC enable or disanble.
|
||||
* @param bEnable(TRUE): Enable it
|
||||
* bEnable(FALSE): Disable it(default)
|
||||
* *********************************************************/
|
||||
void CMT2300A_EnableAfc(bool bEnable)
|
||||
{
|
||||
uint8_t tmp = CMT2300A_ReadReg(CMT2300A_CUS_FSK5);
|
||||
|
||||
if (bEnable)
|
||||
tmp |= 0x10;
|
||||
else
|
||||
tmp &= ~0x10;
|
||||
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_FSK5, tmp);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_SetAfcOvfTh
|
||||
* @desc This is optional, only needed when using Rx fast frequency hopping.
|
||||
* @param afcOvfTh: AFC_OVF_TH see AN142 and AN197 for details.
|
||||
* *********************************************************/
|
||||
void CMT2300A_SetAfcOvfTh(uint8_t afcOvfTh)
|
||||
{
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_FSK4, afcOvfTh);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_Init
|
||||
* @desc Initialize chip status.
|
||||
* *********************************************************/
|
||||
bool CMT2300A_Init(void)
|
||||
{
|
||||
uint8_t tmp;
|
||||
|
||||
CMT2300A_SoftReset();
|
||||
CMT2300A_DelayMs(20);
|
||||
|
||||
if (!CMT2300A_GoStby())
|
||||
return false; // CMT2300A not switched to standby mode!
|
||||
|
||||
if (!CMT2300A_IsExist())
|
||||
return false; // CMT2300A not found!
|
||||
|
||||
tmp = CMT2300A_ReadReg(CMT2300A_CUS_MODE_STA);
|
||||
tmp |= CMT2300A_MASK_CFG_RETAIN; /* Enable CFG_RETAIN */
|
||||
tmp &= ~CMT2300A_MASK_RSTN_IN_EN; /* Disable RSTN_IN */
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_MODE_STA, tmp);
|
||||
|
||||
tmp = CMT2300A_ReadReg(CMT2300A_CUS_EN_CTL);
|
||||
tmp |= CMT2300A_MASK_LOCKING_EN; /* Enable LOCKING_EN */
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_EN_CTL, tmp);
|
||||
|
||||
CMT2300A_EnableLfosc(false); /* Disable LFOSC */
|
||||
|
||||
CMT2300A_ClearInterruptFlags();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_ConfigRegBank
|
||||
* @desc Config one register bank.
|
||||
* *********************************************************/
|
||||
bool CMT2300A_ConfigRegBank(uint8_t base_addr, const uint8_t bank[], uint8_t len)
|
||||
{
|
||||
uint8_t i;
|
||||
for (i = 0; i < len; i++)
|
||||
CMT2300A_WriteReg(i + base_addr, bank[i]);
|
||||
|
||||
return true;
|
||||
}
|
||||
96
lib/CMT2300a/cmt2300a.h
Normal file
96
lib/CMT2300a/cmt2300a.h
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
|
||||
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
|
||||
* CONSEQUENTLY, CMOSTEK SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
|
||||
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
|
||||
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* Copyright (C) CMOSTEK SZ.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file cmt2300a.h
|
||||
* @brief CMT2300A transceiver RF chip driver
|
||||
*
|
||||
* @version 1.3
|
||||
* @date Jul 17 2017
|
||||
* @author CMOSTEK R@D
|
||||
*/
|
||||
|
||||
#ifndef __CMT2300A_H
|
||||
#define __CMT2300A_H
|
||||
|
||||
#include "cmt2300a_defs.h"
|
||||
#include "cmt2300a_hal.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ENABLE_AUTO_SWITCH_CHIP_STATUS /* Enable the auto switch chip status */
|
||||
|
||||
/* ************************************************************************
|
||||
The following are for chip status controls.
|
||||
* ************************************************************************ */
|
||||
void CMT2300A_SoftReset(void);
|
||||
uint8_t CMT2300A_GetChipStatus(void);
|
||||
bool CMT2300A_AutoSwitchStatus(uint8_t nGoCmd);
|
||||
bool CMT2300A_GoSleep(void);
|
||||
bool CMT2300A_GoStby(void);
|
||||
bool CMT2300A_GoTFS(void);
|
||||
bool CMT2300A_GoRFS(void);
|
||||
bool CMT2300A_GoTx(void);
|
||||
bool CMT2300A_GoRx(void);
|
||||
|
||||
/* ************************************************************************
|
||||
* The following are for chip interrupts, GPIO, FIFO operations.
|
||||
* ************************************************************************ */
|
||||
void CMT2300A_ConfigGpio(uint8_t nGpioSel);
|
||||
void CMT2300A_ConfigInterrupt(uint8_t nInt1Sel, uint8_t nInt2Sel);
|
||||
void CMT2300A_SetInterruptPolar(bool bActiveHigh);
|
||||
void CMT2300A_SetFifoThreshold(uint8_t nFifoThreshold);
|
||||
void CMT2300A_EnableAntennaSwitch(uint8_t nMode);
|
||||
void CMT2300A_EnableInterrupt(uint8_t nEnable);
|
||||
void CMT2300A_EnableRxFifoAutoClear(bool bEnable);
|
||||
void CMT2300A_EnableFifoMerge(bool bEnable);
|
||||
void CMT2300A_EnableReadFifo(void);
|
||||
void CMT2300A_EnableWriteFifo(void);
|
||||
void CMT2300A_RestoreFifo(void);
|
||||
uint8_t CMT2300A_ClearTxFifo(void);
|
||||
uint8_t CMT2300A_ClearRxFifo(void);
|
||||
uint8_t CMT2300A_ClearInterruptFlags(void);
|
||||
|
||||
/* ************************************************************************
|
||||
* The following are for Tx DIN operations in direct mode.
|
||||
* ************************************************************************ */
|
||||
void CMT2300A_ConfigTxDin(uint8_t nDinSel);
|
||||
void CMT2300A_EnableTxDin(bool bEnable);
|
||||
void CMT2300A_EnableTxDinInvert(bool bEnable);
|
||||
|
||||
/* ************************************************************************
|
||||
* The following are general operations.
|
||||
* ************************************************************************ */
|
||||
bool CMT2300A_IsExist(void);
|
||||
uint8_t CMT2300A_GetRssiCode(void);
|
||||
int CMT2300A_GetRssiDBm(void);
|
||||
void CMT2300A_SetFrequencyChannel(const uint8_t nChann);
|
||||
void CMT2300A_SetFrequencyStep(uint8_t nOffset);
|
||||
void CMT2300A_SetPayloadLength(uint16_t nLength);
|
||||
void CMT2300A_EnableLfosc(bool bEnable);
|
||||
void CMT2300A_EnableLfoscOutput(bool bEnable);
|
||||
void CMT2300A_EnableAfc(bool bEnable);
|
||||
void CMT2300A_SetAfcOvfTh(uint8_t afcOvfTh);
|
||||
|
||||
/* ************************************************************************
|
||||
* The following are for chip initializes.
|
||||
* ************************************************************************ */
|
||||
bool CMT2300A_Init(void);
|
||||
bool CMT2300A_ConfigRegBank(uint8_t base_addr, const uint8_t bank[], uint8_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
606
lib/CMT2300a/cmt2300a_defs.h
Normal file
606
lib/CMT2300a/cmt2300a_defs.h
Normal file
@ -0,0 +1,606 @@
|
||||
/*
|
||||
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
|
||||
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
|
||||
* CONSEQUENTLY, CMOSTEK SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
|
||||
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
|
||||
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* Copyright (C) CMOSTEK SZ.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file cmt2300a_defs.h
|
||||
* @brief CMT2300A registers defines
|
||||
*
|
||||
* @version 1.2
|
||||
* @date Jul 17 2017
|
||||
* @author CMOSTEK R@D
|
||||
*/
|
||||
|
||||
#ifndef __CMT2300A_DEFS_H
|
||||
#define __CMT2300A_DEFS_H
|
||||
|
||||
/* ---------- CMT bank defines ---------- */
|
||||
#define CMT2300A_CMT_BANK_ADDR 0x00
|
||||
#define CMT2300A_CMT_BANK_SIZE 12
|
||||
#define CMT2300A_CUS_CMT1 0x00
|
||||
#define CMT2300A_CUS_CMT2 0x01
|
||||
#define CMT2300A_CUS_CMT3 0x02
|
||||
#define CMT2300A_CUS_CMT4 0x03
|
||||
#define CMT2300A_CUS_CMT5 0x04
|
||||
#define CMT2300A_CUS_CMT6 0x05
|
||||
#define CMT2300A_CUS_CMT7 0x06
|
||||
#define CMT2300A_CUS_CMT8 0x07
|
||||
#define CMT2300A_CUS_CMT9 0x08
|
||||
#define CMT2300A_CUS_CMT10 0x09
|
||||
#define CMT2300A_CUS_CMT11 0x0A
|
||||
#define CMT2300A_CUS_RSSI 0x0B
|
||||
|
||||
/* ---------- System bank defines ---------- */
|
||||
#define CMT2300A_SYSTEM_BANK_ADDR 0x0C
|
||||
#define CMT2300A_SYSTEM_BANK_SIZE 12
|
||||
#define CMT2300A_CUS_SYS1 0x0C
|
||||
#define CMT2300A_CUS_SYS2 0x0D
|
||||
#define CMT2300A_CUS_SYS3 0x0E
|
||||
#define CMT2300A_CUS_SYS4 0x0F
|
||||
#define CMT2300A_CUS_SYS5 0x10
|
||||
#define CMT2300A_CUS_SYS6 0x11
|
||||
#define CMT2300A_CUS_SYS7 0x12
|
||||
#define CMT2300A_CUS_SYS8 0x13
|
||||
#define CMT2300A_CUS_SYS9 0x14
|
||||
#define CMT2300A_CUS_SYS10 0x15
|
||||
#define CMT2300A_CUS_SYS11 0x16
|
||||
#define CMT2300A_CUS_SYS12 0x17
|
||||
|
||||
/* ---------- Frequency bank defines ---------- */
|
||||
#define CMT2300A_FREQUENCY_BANK_ADDR 0x18
|
||||
#define CMT2300A_FREQUENCY_BANK_SIZE 8
|
||||
#define CMT2300A_CUS_RF1 0x18
|
||||
#define CMT2300A_CUS_RF2 0x19
|
||||
#define CMT2300A_CUS_RF3 0x1A
|
||||
#define CMT2300A_CUS_RF4 0x1B
|
||||
#define CMT2300A_CUS_RF5 0x1C
|
||||
#define CMT2300A_CUS_RF6 0x1D
|
||||
#define CMT2300A_CUS_RF7 0x1E
|
||||
#define CMT2300A_CUS_RF8 0x1F
|
||||
|
||||
/* ---------- Data rate bank defines ---------- */
|
||||
#define CMT2300A_DATA_RATE_BANK_ADDR 0x20
|
||||
#define CMT2300A_DATA_RATE_BANK_SIZE 24
|
||||
#define CMT2300A_CUS_RF9 0x20
|
||||
#define CMT2300A_CUS_RF10 0x21
|
||||
#define CMT2300A_CUS_RF11 0x22
|
||||
#define CMT2300A_CUS_RF12 0x23
|
||||
#define CMT2300A_CUS_FSK1 0x24
|
||||
#define CMT2300A_CUS_FSK2 0x25
|
||||
#define CMT2300A_CUS_FSK3 0x26
|
||||
#define CMT2300A_CUS_FSK4 0x27
|
||||
#define CMT2300A_CUS_FSK5 0x28
|
||||
#define CMT2300A_CUS_FSK6 0x29
|
||||
#define CMT2300A_CUS_FSK7 0x2A
|
||||
#define CMT2300A_CUS_CDR1 0x2B
|
||||
#define CMT2300A_CUS_CDR2 0x2C
|
||||
#define CMT2300A_CUS_CDR3 0x2D
|
||||
#define CMT2300A_CUS_CDR4 0x2E
|
||||
#define CMT2300A_CUS_AGC1 0x2F
|
||||
#define CMT2300A_CUS_AGC2 0x30
|
||||
#define CMT2300A_CUS_AGC3 0x31
|
||||
#define CMT2300A_CUS_AGC4 0x32
|
||||
#define CMT2300A_CUS_OOK1 0x33
|
||||
#define CMT2300A_CUS_OOK2 0x34
|
||||
#define CMT2300A_CUS_OOK3 0x35
|
||||
#define CMT2300A_CUS_OOK4 0x36
|
||||
#define CMT2300A_CUS_OOK5 0x37
|
||||
|
||||
/* ---------- Baseband bank defines ---------- */
|
||||
#define CMT2300A_BASEBAND_BANK_ADDR 0x38
|
||||
#define CMT2300A_BASEBAND_BANK_SIZE 29
|
||||
#define CMT2300A_CUS_PKT1 0x38
|
||||
#define CMT2300A_CUS_PKT2 0x39
|
||||
#define CMT2300A_CUS_PKT3 0x3A
|
||||
#define CMT2300A_CUS_PKT4 0x3B
|
||||
#define CMT2300A_CUS_PKT5 0x3C
|
||||
#define CMT2300A_CUS_PKT6 0x3D
|
||||
#define CMT2300A_CUS_PKT7 0x3E
|
||||
#define CMT2300A_CUS_PKT8 0x3F
|
||||
#define CMT2300A_CUS_PKT9 0x40
|
||||
#define CMT2300A_CUS_PKT10 0x41
|
||||
#define CMT2300A_CUS_PKT11 0x42
|
||||
#define CMT2300A_CUS_PKT12 0x43
|
||||
#define CMT2300A_CUS_PKT13 0x44
|
||||
#define CMT2300A_CUS_PKT14 0x45
|
||||
#define CMT2300A_CUS_PKT15 0x46
|
||||
#define CMT2300A_CUS_PKT16 0x47
|
||||
#define CMT2300A_CUS_PKT17 0x48
|
||||
#define CMT2300A_CUS_PKT18 0x49
|
||||
#define CMT2300A_CUS_PKT19 0x4A
|
||||
#define CMT2300A_CUS_PKT20 0x4B
|
||||
#define CMT2300A_CUS_PKT21 0x4C
|
||||
#define CMT2300A_CUS_PKT22 0x4D
|
||||
#define CMT2300A_CUS_PKT23 0x4E
|
||||
#define CMT2300A_CUS_PKT24 0x4F
|
||||
#define CMT2300A_CUS_PKT25 0x50
|
||||
#define CMT2300A_CUS_PKT26 0x51
|
||||
#define CMT2300A_CUS_PKT27 0x52
|
||||
#define CMT2300A_CUS_PKT28 0x53
|
||||
#define CMT2300A_CUS_PKT29 0x54
|
||||
|
||||
/* ---------- Tx bank defines ---------- */
|
||||
#define CMT2300A_TX_BANK_ADDR 0x55
|
||||
#define CMT2300A_TX_BANK_SIZE 11
|
||||
#define CMT2300A_CUS_TX1 0x55
|
||||
#define CMT2300A_CUS_TX2 0x56
|
||||
#define CMT2300A_CUS_TX3 0x57
|
||||
#define CMT2300A_CUS_TX4 0x58
|
||||
#define CMT2300A_CUS_TX5 0x59
|
||||
#define CMT2300A_CUS_TX6 0x5A
|
||||
#define CMT2300A_CUS_TX7 0x5B
|
||||
#define CMT2300A_CUS_TX8 0x5C
|
||||
#define CMT2300A_CUS_TX9 0x5D
|
||||
#define CMT2300A_CUS_TX10 0x5E
|
||||
#define CMT2300A_CUS_LBD 0x5F
|
||||
|
||||
/* ---------- Control1 bank defines ---------- */
|
||||
#define CMT2300A_CONTROL1_BANK_ADDR 0x60
|
||||
#define CMT2300A_CONTROL1_BANK_SIZE 11
|
||||
#define CMT2300A_CUS_MODE_CTL 0x60
|
||||
#define CMT2300A_CUS_MODE_STA 0x61
|
||||
#define CMT2300A_CUS_EN_CTL 0x62
|
||||
#define CMT2300A_CUS_FREQ_CHNL 0x63
|
||||
#define CMT2300A_CUS_FREQ_OFS 0x64
|
||||
#define CMT2300A_CUS_IO_SEL 0x65
|
||||
#define CMT2300A_CUS_INT1_CTL 0x66
|
||||
#define CMT2300A_CUS_INT2_CTL 0x67
|
||||
#define CMT2300A_CUS_INT_EN 0x68
|
||||
#define CMT2300A_CUS_FIFO_CTL 0x69
|
||||
#define CMT2300A_CUS_INT_CLR1 0x6A
|
||||
|
||||
/* ---------- Control2 bank defines ---------- */
|
||||
#define CMT2300A_CONTROL2_BANK_ADDR 0x6B
|
||||
#define CMT2300A_CONTROL2_BANK_SIZE 7
|
||||
#define CMT2300A_CUS_INT_CLR2 0x6B
|
||||
#define CMT2300A_CUS_FIFO_CLR 0x6C
|
||||
#define CMT2300A_CUS_INT_FLAG 0x6D
|
||||
#define CMT2300A_CUS_FIFO_FLAG 0x6E
|
||||
#define CMT2300A_CUS_RSSI_CODE 0x6F
|
||||
#define CMT2300A_CUS_RSSI_DBM 0x70
|
||||
#define CMT2300A_CUS_LBD_RESULT 0x71
|
||||
|
||||
/* ********** CMT2300A_CUS_CMT2 registers ********** */
|
||||
#define CMT2300A_MASK_PRODUCT_ID 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_CMT5 registers ********** */
|
||||
#define CMT2300A_MASK_LMT_CODE 0xC0
|
||||
|
||||
/* ********** CMT2300A_CUS_CMT9 registers ********** */
|
||||
#define CMT2300A_MASK_RSSI_OFFSET_SIGN 0x80
|
||||
#define CMT2300A_MASK_DIG_CLKDIV 0x1F
|
||||
|
||||
/* ********** CMT2300A_CUS_RSSI registers ********** */
|
||||
#define CMT2300A_MASK_RSSI_OFFSET 0xF8
|
||||
#define CMT2300A_MASK_RSSI_SLOPE 0x07
|
||||
|
||||
/* ********** CMT2300A_CUS_SYS1 registers ********** */
|
||||
#define CMT2300A_MASK_LMT_VTR 0xC0
|
||||
#define CMT2300A_MASK_MIXER_BIAS 0x30
|
||||
#define CMT2300A_MASK_LNA_MODE 0x0C
|
||||
#define CMT2300A_MASK_LNA_BIAS 0x03
|
||||
|
||||
/* ********** CMT2300A_CUS_SYS2 registers ********** */
|
||||
#define CMT2300A_MASK_LFOSC_RECAL_EN 0x80
|
||||
#define CMT2300A_MASK_LFOSC_CAL1_EN 0x40
|
||||
#define CMT2300A_MASK_LFOSC_CAL2_EN 0x20
|
||||
#define CMT2300A_MASK_RX_TIMER_EN 0x10
|
||||
#define CMT2300A_MASK_SLEEP_TIMER_EN 0x08
|
||||
#define CMT2300A_MASK_TX_DC_EN 0x04
|
||||
#define CMT2300A_MASK_RX_DC_EN 0x02
|
||||
#define CMT2300A_MASK_DC_PAUSE 0x01
|
||||
|
||||
/* ********** CMT2300A_CUS_SYS3 registers ********** */
|
||||
#define CMT2300A_MASK_SLEEP_BYPASS_EN 0x80
|
||||
#define CMT2300A_MASK_XTAL_STB_TIME 0x70
|
||||
#define CMT2300A_MASK_TX_EXIT_STATE 0x0C
|
||||
#define CMT2300A_MASK_RX_EXIT_STATE 0x03
|
||||
|
||||
/* ********** CMT2300A_CUS_SYS4 registers ********** */
|
||||
#define CMT2300A_MASK_SLEEP_TIMER_M_7_0 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_SYS5 registers ********** */
|
||||
#define CMT2300A_MASK_SLEEP_TIMER_M_10_8 0x70
|
||||
#define CMT2300A_MASK_SLEEP_TIMER_R 0x0F
|
||||
|
||||
/* ********** CMT2300A_CUS_SYS6 registers ********** */
|
||||
#define CMT2300A_MASK_RX_TIMER_T1_M_7_0 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_SYS7 registers ********** */
|
||||
#define CMT2300A_MASK_RX_TIMER_T1_M_10_8 0x70
|
||||
#define CMT2300A_MASK_RX_TIMER_T1_R 0x0F
|
||||
|
||||
/* ********** CMT2300A_CUS_SYS8 registers ********** */
|
||||
#define CMT2300A_MASK_RX_TIMER_T2_M_7_0 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_SYS9 registers ********** */
|
||||
#define CMT2300A_MASK_RX_TIMER_T2_M_10_8 0x70
|
||||
#define CMT2300A_MASK_RX_TIMER_T2_R 0x0F
|
||||
|
||||
/* ********** CMT2300A_CUS_SYS10 registers ********** */
|
||||
#define CMT2300A_MASK_COL_DET_EN 0x80
|
||||
#define CMT2300A_MASK_COL_OFS_SEL 0x40
|
||||
#define CMT2300A_MASK_RX_AUTO_EXIT_DIS 0x20
|
||||
#define CMT2300A_MASK_DOUT_MUTE 0x10
|
||||
#define CMT2300A_MASK_RX_EXTEND_MODE 0x0F
|
||||
|
||||
/* ********** CMT2300A_CUS_SYS11 registers ********** */
|
||||
#define CMT2300A_MASK_PJD_TH_SEL 0x80
|
||||
#define CMT2300A_MASK_CCA_INT_SEL 0x60
|
||||
#define CMT2300A_MASK_RSSI_DET_SEL 0x18
|
||||
#define CMT2300A_MASK_RSSI_AVG_MODE 0x07
|
||||
|
||||
/* ********** CMT2300A_CUS_SYS12 registers ********** */
|
||||
#define CMT2300A_MASK_PJD_WIN_SEL 0xC0
|
||||
#define CMT2300A_MASK_CLKOUT_EN 0x20
|
||||
#define CMT2300A_MASK_CLKOUT_DIV 0x1F
|
||||
|
||||
/* ********** CMT2300A_CUS_RF1 registers ********** */
|
||||
#define CMT2300A_MASK_FREQ_RX_N 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_RF2 registers ********** */
|
||||
#define CMT2300A_MASK_FREQ_RX_K_7_0 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_RF3 registers ********** */
|
||||
#define CMT2300A_MASK_FREQ_RX_K_15_8 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_RF4 registers ********** */
|
||||
#define CMT2300A_MASK_FREQ_PALDO_SEL 0x80
|
||||
#define CMT2300A_MASK_FREQ_DIVX_CODE 0x70
|
||||
#define CMT2300A_MASK_FREQ_RX_K_19_16 0x0F
|
||||
|
||||
/* ********** CMT2300A_CUS_RF5 registers ********** */
|
||||
#define CMT2300A_MASK_FREQ_TX_N 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_RF6 registers ********** */
|
||||
#define CMT2300A_MASK_FREQ_TX_K_7_0 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_RF7 registers ********** */
|
||||
#define CMT2300A_MASK_FREQ_TX_K_15_8 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_RF8 registers ********** */
|
||||
#define CMT2300A_MASK_FSK_SWT 0x80
|
||||
#define CMT2300A_MASK_FREQ_VCO_BANK 0x70
|
||||
#define CMT2300A_MASK_FREQ_TX_K_19_16 0x0F
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT1 registers ********** */
|
||||
#define CMT2300A_MASK_RX_PREAM_SIZE 0xF8
|
||||
#define CMT2300A_MASK_PREAM_LENG_UNIT 0x04
|
||||
#define CMT2300A_MASK_DATA_MODE 0x03
|
||||
/* CMT2300A_MASK_PREAM_LENG_UNIT options */
|
||||
#define CMT2300A_PREAM_LENG_UNIT_8_BITS 0x00
|
||||
#define CMT2300A_PREAM_LENG_UNIT_4_BITS 0x04
|
||||
/* CMT2300A_MASK_DATA_MODE options */
|
||||
#define CMT2300A_DATA_MODE_DIRECT 0x00
|
||||
#define CMT2300A_DATA_MODE_PACKET 0x02
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT2 registers ********** */
|
||||
#define CMT2300A_MASK_TX_PREAM_SIZE_7_0 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT3 registers ********** */
|
||||
#define CMT2300A_MASK_TX_PREAM_SIZE_15_8 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT4 registers ********** */
|
||||
#define CMT2300A_MASK_PREAM_VALUE 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT5 registers ********** */
|
||||
#define CMT2300A_MASK_SYNC_TOL 0x70
|
||||
#define CMT2300A_MASK_SYNC_SIZE 0x0E
|
||||
#define CMT2300A_MASK_SYNC_MAN_EN 0x01
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT6 registers ********** */
|
||||
#define CMT2300A_MASK_SYNC_VALUE_7_0 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT7 registers ********** */
|
||||
#define CMT2300A_MASK_SYNC_VALUE_15_8 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT8 registers ********** */
|
||||
#define CMT2300A_MASK_SYNC_VALUE_23_16 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT9 registers ********** */
|
||||
#define CMT2300A_MASK_SYNC_VALUE_31_24 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT10 registers ********** */
|
||||
#define CMT2300A_MASK_SYNC_VALUE_39_32 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT11 registers ********** */
|
||||
#define CMT2300A_MASK_SYNC_VALUE_47_40 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT12 registers ********** */
|
||||
#define CMT2300A_MASK_SYNC_VALUE_55_48 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT13 registers ********** */
|
||||
#define CMT2300A_MASK_SYNC_VALUE_63_56 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT14 registers ********** */
|
||||
#define CMT2300A_MASK_PAYLOAD_LENG_10_8 0x70
|
||||
#define CMT2300A_MASK_AUTO_ACK_EN 0x08
|
||||
#define CMT2300A_MASK_NODE_LENG_POS_SEL 0x04
|
||||
#define CMT2300A_MASK_PAYLOAD_BIT_ORDER 0x02
|
||||
#define CMT2300A_MASK_PKT_TYPE 0x01
|
||||
/* CMT2300A_MASK_NODE_LENG_POS_SEL options */
|
||||
#define CMT2300A_NODE_LENG_FIRST_NODE 0x00
|
||||
#define CMT2300A_NODE_LENG_FIRST_LENGTH 0x04
|
||||
/* CMT2300A_MASK_PAYLOAD_BIT_ORDER options */
|
||||
#define CMT2300A_PAYLOAD_BIT_ORDER_MSB 0x00
|
||||
#define CMT2300A_PAYLOAD_BIT_ORDER_LSB 0x02
|
||||
/* CMT2300A_MASK_PKT_TYPE options */
|
||||
#define CMT2300A_PKT_TYPE_FIXED 0x00
|
||||
#define CMT2300A_PKT_TYPE_VARIABLE 0x01
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT15 registers ********** */
|
||||
#define CMT2300A_MASK_PAYLOAD_LENG_7_0 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT16 registers ********** */
|
||||
#define CMT2300A_MASK_NODE_FREE_EN 0x20
|
||||
#define CMT2300A_MASK_NODE_ERR_MASK 0x10
|
||||
#define CMT2300A_MASK_NODE_SIZE 0x0C
|
||||
#define CMT2300A_MASK_NODE_DET_MODE 0x03
|
||||
/* CMT2300A_MASK_NODE_DET_MODE options */
|
||||
#define CMT2300A_NODE_DET_NODE 0x00
|
||||
#define CMT2300A_NODE_DET_VALUE 0x01
|
||||
#define CMT2300A_NODE_DET_VALUE_0 0x02
|
||||
#define CMT2300A_NODE_DET_VALUE_0_1 0x03
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT17 registers ********** */
|
||||
#define CMT2300A_MASK_NODE_VALUE_7_0 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT18 registers ********** */
|
||||
#define CMT2300A_MASK_NODE_VALUE_15_8 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT19 registers ********** */
|
||||
#define CMT2300A_MASK_NODE_VALUE_23_16 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT20 registers ********** */
|
||||
#define CMT2300A_MASK_NODE_VALUE_31_24 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT21 registers ********** */
|
||||
#define CMT2300A_MASK_FEC_TYPE 0x80
|
||||
#define CMT2300A_MASK_FEC_EN 0x40
|
||||
#define CMT2300A_MASK_CRC_BYTE_SWAP 0x20
|
||||
#define CMT2300A_MASK_CRC_BIT_INV 0x10
|
||||
#define CMT2300A_MASK_CRC_RANGE 0x08
|
||||
#define CMT2300A_MASK_CRC_TYPE 0x06
|
||||
#define CMT2300A_MASK_CRC_EN 0x01
|
||||
/* CMT2300A_MASK_CRC_BYTE_SWAP options */
|
||||
#define CMT2300A_CRC_ORDER_HBYTE 0x00
|
||||
#define CMT2300A_CRC_ORDER_LBYTE 0x20
|
||||
/* CMT2300A_MASK_CRC_RANGE options */
|
||||
#define CMT2300A_CRC_RANGE_PAYLOAD 0x00
|
||||
#define CMT2300A_CRC_RANGE_DATA 0x08
|
||||
/* CMT2300A_MASK_CRC_TYPE options */
|
||||
#define CMT2300A_CRC_TYPE_CCITT16 0x00
|
||||
#define CMT2300A_CRC_TYPE_IBM16 0x02
|
||||
#define CMT2300A_CRC_TYPE_ITuint16_t 0x04
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT22 registers ********** */
|
||||
#define CMT2300A_MASK_CRC_SEED_7_0 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT23 registers ********** */
|
||||
#define CMT2300A_MASK_CRC_SEED_15_8 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT24 registers ********** */
|
||||
#define CMT2300A_MASK_CRC_BIT_ORDER 0x80
|
||||
#define CMT2300A_MASK_WHITEN_SEED_8_8 0x40
|
||||
#define CMT2300A_MASK_WHITEN_SEED_TYPE 0x20
|
||||
#define CMT2300A_MASK_WHITEN_TYPE 0x18
|
||||
#define CMT2300A_MASK_WHITEN_EN 0x04
|
||||
#define CMT2300A_MASK_MANCH_TYPE 0x02
|
||||
#define CMT2300A_MASK_MANCH_EN 0x01
|
||||
/* CMT2300A_MASK_CRC_BIT_ORDER options */
|
||||
#define CMT2300A_CRC_BIT_ORDER_MSB 0x00
|
||||
#define CMT2300A_CRC_BIT_ORDER_LSB 0x80
|
||||
/* CMT2300A_MASK_WHITEN_SEED_TYPE options */
|
||||
#define CMT2300A_WHITEN_SEED_TYPE_1 0x00
|
||||
#define CMT2300A_WHITEN_SEED_TYPE_2 0x20
|
||||
/* CMT2300A_MASK_WHITEN_TYPE options */
|
||||
#define CMT2300A_WHITEN_TYPE_PN9_CCITT 0x00
|
||||
#define CMT2300A_WHITEN_TYPE_PN9_IBM 0x08
|
||||
#define CMT2300A_WHITEN_TYPE_PN7 0x10
|
||||
/* CMT2300A_MASK_MANCH_TYPE options */
|
||||
#define CMT2300A_MANCH_TYPE_ONE_01 0x00
|
||||
#define CMT2300A_MANCH_TYPE_ONE_10 0x02
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT25 registers ********** */
|
||||
#define CMT2300A_MASK_WHITEN_SEED_7_0 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT26 registers ********** */
|
||||
#define CMT2300A_MASK_TX_PREFIX_TYPE 0x03
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT27 registers ********** */
|
||||
#define CMT2300A_MASK_TX_PKT_NUM 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT28 registers ********** */
|
||||
#define CMT2300A_MASK_TX_PKT_GAP 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_PKT29 registers ********** */
|
||||
#define CMT2300A_MASK_FIFO_AUTO_RES_EN 0x80
|
||||
#define CMT2300A_MASK_FIFO_TH 0x7F
|
||||
|
||||
/* ********** CMT2300A_CUS_MODE_CTL registers ********** */
|
||||
#define CMT2300A_MASK_CHIP_MODE_SWT 0xFF
|
||||
/* CMT2300A_MASK_CHIP_MODE_SWT options */
|
||||
#define CMT2300A_GO_EEPROM 0x01
|
||||
#define CMT2300A_GO_STBY 0x02
|
||||
#define CMT2300A_GO_RFS 0x04
|
||||
#define CMT2300A_GO_RX 0x08
|
||||
#define CMT2300A_GO_SLEEP 0x10
|
||||
#define CMT2300A_GO_TFS 0x20
|
||||
#define CMT2300A_GO_TX 0x40
|
||||
#define CMT2300A_GO_SWITCH 0x80
|
||||
|
||||
/* ********** CMT2300A_CUS_MODE_STA registers ********** */
|
||||
#define CMT2300A_MASK_RSTN_IN_EN 0x20
|
||||
#define CMT2300A_MASK_CFG_RETAIN 0x10
|
||||
#define CMT2300A_MASK_CHIP_MODE_STA 0x0F
|
||||
/* CMT2300A_MASK_CHIP_MODE_STA options */
|
||||
#define CMT2300A_STA_IDLE 0x00
|
||||
#define CMT2300A_STA_SLEEP 0x01
|
||||
#define CMT2300A_STA_STBY 0x02
|
||||
#define CMT2300A_STA_RFS 0x03
|
||||
#define CMT2300A_STA_TFS 0x04
|
||||
#define CMT2300A_STA_RX 0x05
|
||||
#define CMT2300A_STA_TX 0x06
|
||||
#define CMT2300A_STA_EEPROM 0x07
|
||||
#define CMT2300A_STA_ERROR 0x08
|
||||
#define CMT2300A_STA_CAL 0x09
|
||||
|
||||
/* ********** CMT2300A_CUS_EN_CTL registers ********** */
|
||||
#define CMT2300A_MASK_LOCKING_EN 0x20
|
||||
|
||||
/* ********** CMT2300A_CUS_FREQ_CHNL registers ********** */
|
||||
#define CMT2300A_MASK_FH_CHANNEL 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_FREQ_OFS registers ********** */
|
||||
#define CMT2300A_MASK_FH_OFFSET 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_IO_SEL registers ********** */
|
||||
#define CMT2300A_MASK_GPIO4_SEL 0xC0
|
||||
#define CMT2300A_MASK_GPIO3_SEL 0x30
|
||||
#define CMT2300A_MASK_GPIO2_SEL 0x0C
|
||||
#define CMT2300A_MASK_GPIO1_SEL 0x03
|
||||
/* CMT2300A_MASK_GPIO4_SEL options */
|
||||
#define CMT2300A_GPIO4_SEL_RSTIN 0x00
|
||||
#define CMT2300A_GPIO4_SEL_INT1 0x40
|
||||
#define CMT2300A_GPIO4_SEL_DOUT 0x80
|
||||
#define CMT2300A_GPIO4_SEL_DCLK 0xC0
|
||||
/* CMT2300A_MASK_GPIO3_SEL options */
|
||||
#define CMT2300A_GPIO3_SEL_CLKO 0x00
|
||||
#define CMT2300A_GPIO3_SEL_DOUT 0x10
|
||||
#define CMT2300A_GPIO3_SEL_DIN 0x10
|
||||
#define CMT2300A_GPIO3_SEL_INT2 0x20
|
||||
#define CMT2300A_GPIO3_SEL_DCLK 0x30
|
||||
/* CMT2300A_MASK_GPIO2_SEL options */
|
||||
#define CMT2300A_GPIO2_SEL_INT1 0x00
|
||||
#define CMT2300A_GPIO2_SEL_INT2 0x04
|
||||
#define CMT2300A_GPIO2_SEL_DOUT 0x08
|
||||
#define CMT2300A_GPIO2_SEL_DIN 0x08
|
||||
#define CMT2300A_GPIO2_SEL_DCLK 0x0C
|
||||
/* CMT2300A_MASK_GPIO1_SEL options */
|
||||
#define CMT2300A_GPIO1_SEL_DOUT 0x00
|
||||
#define CMT2300A_GPIO1_SEL_DIN 0x00
|
||||
#define CMT2300A_GPIO1_SEL_INT1 0x01
|
||||
#define CMT2300A_GPIO1_SEL_INT2 0x02
|
||||
#define CMT2300A_GPIO1_SEL_DCLK 0x03
|
||||
|
||||
/* ********** CMT2300A_CUS_INT1_CTL registers ********** */
|
||||
#define CMT2300A_MASK_RF_SWT1_EN 0x80
|
||||
#define CMT2300A_MASK_RF_SWT2_EN 0x40
|
||||
#define CMT2300A_MASK_INT_POLAR 0x20
|
||||
#define CMT2300A_MASK_INT1_SEL 0x1F
|
||||
/* CMT2300A_MASK_INT_POLAR options */
|
||||
#define CMT2300A_INT_POLAR_SEL_0 0x00
|
||||
#define CMT2300A_INT_POLAR_SEL_1 0x20
|
||||
/* CMT2300A_MASK_INT1_SEL options */
|
||||
#define CMT2300A_INT_SEL_RX_ACTIVE 0x00
|
||||
#define CMT2300A_INT_SEL_TX_ACTIVE 0x01
|
||||
#define CMT2300A_INT_SEL_RSSI_VLD 0x02
|
||||
#define CMT2300A_INT_SEL_PREAM_OK 0x03
|
||||
#define CMT2300A_INT_SEL_SYNC_OK 0x04
|
||||
#define CMT2300A_INT_SEL_NODE_OK 0x05
|
||||
#define CMT2300A_INT_SEL_CRC_OK 0x06
|
||||
#define CMT2300A_INT_SEL_PKT_OK 0x07
|
||||
#define CMT2300A_INT_SEL_SL_TMO 0x08
|
||||
#define CMT2300A_INT_SEL_RX_TMO 0x09
|
||||
#define CMT2300A_INT_SEL_TX_DONE 0x0A
|
||||
#define CMT2300A_INT_SEL_RX_FIFO_NMTY 0x0B
|
||||
#define CMT2300A_INT_SEL_RX_FIFO_TH 0x0C
|
||||
#define CMT2300A_INT_SEL_RX_FIFO_FULL 0x0D
|
||||
#define CMT2300A_INT_SEL_RX_FIFO_WBYTE 0x0E
|
||||
#define CMT2300A_INT_SEL_RX_FIFO_OVF 0x0F
|
||||
#define CMT2300A_INT_SEL_TX_FIFO_NMTY 0x10
|
||||
#define CMT2300A_INT_SEL_TX_FIFO_TH 0x11
|
||||
#define CMT2300A_INT_SEL_TX_FIFO_FULL 0x12
|
||||
#define CMT2300A_INT_SEL_STATE_IS_STBY 0x13
|
||||
#define CMT2300A_INT_SEL_STATE_IS_FS 0x14
|
||||
#define CMT2300A_INT_SEL_STATE_IS_RX 0x15
|
||||
#define CMT2300A_INT_SEL_STATE_IS_TX 0x16
|
||||
#define CMT2300A_INT_SEL_LED 0x17
|
||||
#define CMT2300A_INT_SEL_TRX_ACTIVE 0x18
|
||||
#define CMT2300A_INT_SEL_PKT_DONE 0x19
|
||||
|
||||
/* ********** CMT2300A_CUS_INT2_CTL registers ********** */
|
||||
#define CMT2300A_MASK_LFOSC_OUT_EN 0x40
|
||||
#define CMT2300A_MASK_TX_DIN_INV 0x20
|
||||
#define CMT2300A_MASK_INT2_SEL 0x1F
|
||||
|
||||
/* ********** CMT2300A_CUS_INT_EN registers ********** */
|
||||
#define CMT2300A_MASK_SL_TMO_EN 0x80
|
||||
#define CMT2300A_MASK_RX_TMO_EN 0x40
|
||||
#define CMT2300A_MASK_TX_DONE_EN 0x20
|
||||
#define CMT2300A_MASK_PREAM_OK_EN 0x10
|
||||
#define CMT2300A_MASK_SYNC_OK_EN 0x08
|
||||
#define CMT2300A_MASK_NODE_OK_EN 0x04
|
||||
#define CMT2300A_MASK_CRC_OK_EN 0x02
|
||||
#define CMT2300A_MASK_PKT_DONE_EN 0x01
|
||||
|
||||
/* ********** CMT2300A_CUS_FIFO_CTL registers ********** */
|
||||
#define CMT2300A_MASK_TX_DIN_EN 0x80
|
||||
#define CMT2300A_MASK_TX_DIN_SEL 0x60
|
||||
#define CMT2300A_MASK_FIFO_AUTO_CLR_DIS 0x10
|
||||
#define CMT2300A_MASK_FIFO_TX_RD_EN 0x08
|
||||
#define CMT2300A_MASK_FIFO_RX_TX_SEL 0x04
|
||||
#define CMT2300A_MASK_FIFO_MERGE_EN 0x02
|
||||
#define CMT2300A_MASK_SPI_FIFO_RD_WR_SEL 0x01
|
||||
/* CMT2300A_MASK_TX_DIN_SEL options */
|
||||
#define CMT2300A_TX_DIN_SEL_GPIO1 0x00
|
||||
#define CMT2300A_TX_DIN_SEL_GPIO2 0x20
|
||||
#define CMT2300A_TX_DIN_SEL_GPIO3 0x40
|
||||
|
||||
/* ********** CMT2300A_CUS_INT_CLR1 registers ********** */
|
||||
#define CMT2300A_MASK_SL_TMO_FLG 0x20
|
||||
#define CMT2300A_MASK_RX_TMO_FLG 0x10
|
||||
#define CMT2300A_MASK_TX_DONE_FLG 0x08
|
||||
#define CMT2300A_MASK_TX_DONE_CLR 0x04
|
||||
#define CMT2300A_MASK_SL_TMO_CLR 0x02
|
||||
#define CMT2300A_MASK_RX_TMO_CLR 0x01
|
||||
|
||||
/* ********** CMT2300A_CUS_INT_CLR2 registers ********** */
|
||||
#define CMT2300A_MASK_LBD_CLR 0x20
|
||||
#define CMT2300A_MASK_PREAM_OK_CLR 0x10
|
||||
#define CMT2300A_MASK_SYNC_OK_CLR 0x08
|
||||
#define CMT2300A_MASK_NODE_OK_CLR 0x04
|
||||
#define CMT2300A_MASK_CRC_OK_CLR 0x02
|
||||
#define CMT2300A_MASK_PKT_DONE_CLR 0x01
|
||||
|
||||
/* ********** CMT2300A_CUS_FIFO_CLR registers ********** */
|
||||
#define CMT2300A_MASK_FIFO_RESTORE 0x04
|
||||
#define CMT2300A_MASK_FIFO_CLR_RX 0x02
|
||||
#define CMT2300A_MASK_FIFO_CLR_TX 0x01
|
||||
|
||||
/* ********** CMT2300A_CUS_INT_FLAG registers ********** */
|
||||
#define CMT2300A_MASK_LBD_FLG 0x80
|
||||
#define CMT2300A_MASK_COL_ERR_FLG 0x40
|
||||
#define CMT2300A_MASK_PKT_ERR_FLG 0x20
|
||||
#define CMT2300A_MASK_PREAM_OK_FLG 0x10
|
||||
#define CMT2300A_MASK_SYNC_OK_FLG 0x08
|
||||
#define CMT2300A_MASK_NODE_OK_FLG 0x04
|
||||
#define CMT2300A_MASK_CRC_OK_FLG 0x02
|
||||
#define CMT2300A_MASK_PKT_OK_FLG 0x01
|
||||
|
||||
/* ********** CMT2300A_CUS_FIFO_FLAG registers ********** */
|
||||
#define CMT2300A_MASK_RX_FIFO_FULL_FLG 0x40
|
||||
#define CMT2300A_MASK_RX_FIFO_NMTY_FLG 0x20
|
||||
#define CMT2300A_MASK_RX_FIFO_TH_FLG 0x10
|
||||
#define CMT2300A_MASK_RX_FIFO_OVF_FLG 0x08
|
||||
#define CMT2300A_MASK_TX_FIFO_FULL_FLG 0x04
|
||||
#define CMT2300A_MASK_TX_FIFO_NMTY_FLG 0x02
|
||||
#define CMT2300A_MASK_TX_FIFO_TH_FLG 0x01
|
||||
|
||||
/* ********** CMT2300A_CUS_RSSI_CODE registers ********** */
|
||||
#define CMT2300A_MASK_RSSI_CODE 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_RSSI_DBM registers ********** */
|
||||
#define CMT2300A_MASK_RSSI_DBM 0xFF
|
||||
|
||||
/* ********** CMT2300A_CUS_LBD_RESULT registers ********** */
|
||||
#define CMT2300A_MASK_LBD_RESULT 0xFF
|
||||
|
||||
#endif
|
||||
76
lib/CMT2300a/cmt2300a_hal.c
Normal file
76
lib/CMT2300a/cmt2300a_hal.c
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
|
||||
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
|
||||
* CONSEQUENTLY, CMOSTEK SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
|
||||
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
|
||||
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* Copyright (C) CMOSTEK SZ.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file cmt2300a_hal.c
|
||||
* @brief CMT2300A hardware abstraction layer
|
||||
*
|
||||
* @version 1.2
|
||||
* @date Jul 17 2017
|
||||
* @author CMOSTEK R@D
|
||||
*/
|
||||
|
||||
#include "cmt2300a_hal.h"
|
||||
#include "cmt_spi3.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_InitSpi
|
||||
* @desc Initializes the CMT2300A SPI interface.
|
||||
* *********************************************************/
|
||||
void CMT2300A_InitSpi(const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const uint32_t spi_speed)
|
||||
{
|
||||
cmt_spi3_init(pin_sdio, pin_clk, pin_cs, pin_fcs, spi_speed);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_ReadReg
|
||||
* @desc Read the CMT2300A register at the specified address.
|
||||
* @param addr: register address
|
||||
* @return Register value
|
||||
* *********************************************************/
|
||||
uint8_t CMT2300A_ReadReg(const uint8_t addr)
|
||||
{
|
||||
return cmt_spi3_read(addr);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_WriteReg
|
||||
* @desc Write the CMT2300A register at the specified address.
|
||||
* @param addr: register address
|
||||
* dat: register value
|
||||
* *********************************************************/
|
||||
void CMT2300A_WriteReg(const uint8_t addr, const uint8_t dat)
|
||||
{
|
||||
cmt_spi3_write(addr, dat);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_ReadFifo
|
||||
* @desc Reads the contents of the CMT2300A FIFO.
|
||||
* @param buf: buffer where to copy the FIFO read data
|
||||
* len: number of bytes to be read from the FIFO
|
||||
* *********************************************************/
|
||||
void CMT2300A_ReadFifo(uint8_t buf[], const uint16_t len)
|
||||
{
|
||||
cmt_spi3_read_fifo(buf, len);
|
||||
}
|
||||
|
||||
/*! ********************************************************
|
||||
* @name CMT2300A_WriteFifo
|
||||
* @desc Writes the buffer contents to the CMT2300A FIFO.
|
||||
* @param buf: buffer containing data to be put on the FIFO
|
||||
* len: number of bytes to be written to the FIFO
|
||||
* *********************************************************/
|
||||
void CMT2300A_WriteFifo(const uint8_t buf[], const uint16_t len)
|
||||
{
|
||||
cmt_spi3_write_fifo(buf, len);
|
||||
}
|
||||
51
lib/CMT2300a/cmt2300a_hal.h
Normal file
51
lib/CMT2300a/cmt2300a_hal.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND
|
||||
* (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
|
||||
* CONSEQUENTLY, CMOSTEK SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
|
||||
* OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
|
||||
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* Copyright (C) CMOSTEK SZ.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file cmt2300a_hal.h
|
||||
* @brief CMT2300A hardware abstraction layer
|
||||
*
|
||||
* @version 1.2
|
||||
* @date Jul 17 2017
|
||||
* @author CMOSTEK R@D
|
||||
*/
|
||||
|
||||
#ifndef __CMT2300A_HAL_H
|
||||
#define __CMT2300A_HAL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ************************************************************************
|
||||
* The following need to be modified by user
|
||||
* ************************************************************************ */
|
||||
#define CMT2300A_DelayMs(ms) delay(ms)
|
||||
#define CMT2300A_DelayUs(us) delayMicroseconds(us)
|
||||
#define CMT2300A_GetTickCount() millis()
|
||||
/* ************************************************************************ */
|
||||
|
||||
void CMT2300A_InitSpi(const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const uint32_t spi_speed);
|
||||
|
||||
uint8_t CMT2300A_ReadReg(const uint8_t addr);
|
||||
void CMT2300A_WriteReg(const uint8_t addr, const uint8_t dat);
|
||||
|
||||
void CMT2300A_ReadFifo(uint8_t buf[], const uint16_t len);
|
||||
void CMT2300A_WriteFifo(const uint8_t buf[], const uint16_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
214
lib/CMT2300a/cmt2300a_params_860.h
Normal file
214
lib/CMT2300a/cmt2300a_params_860.h
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
;---------------------------------------
|
||||
; CMT2300A Configuration File
|
||||
; Generated by CMOSTEK RFPDK 1.46
|
||||
; 2023.03.17 23:16
|
||||
;---------------------------------------
|
||||
; Mode = Advanced
|
||||
; Part Number = CMT2300A
|
||||
; Frequency = 860.000 MHz
|
||||
; Xtal Frequency = 26.0000 MHz
|
||||
; Demodulation = GFSK
|
||||
; AGC = On
|
||||
; Data Rate = 20.0 kbps
|
||||
; Deviation = 20.0 kHz
|
||||
; Tx Xtal Tol. = 20 ppm
|
||||
; Rx Xtal Tol. = 20 ppm
|
||||
; TRx Matching Network Type = 20 dBm
|
||||
; Tx Power = +13 dBm
|
||||
; Gaussian BT = 0.5
|
||||
; Bandwidth = Auto-Select kHz
|
||||
; CDR Type = Counting
|
||||
; CDR DR Range = NA
|
||||
; AFC = On
|
||||
; AFC Method = Auto-Select
|
||||
; Data Representation = 0:F-low 1:F-high
|
||||
; Rx Duty-Cycle = Off
|
||||
; Tx Duty-Cycle = Off
|
||||
; Sleep Timer = Off
|
||||
; Sleep Time = NA
|
||||
; Rx Timer = Off
|
||||
; Rx Time T1 = NA
|
||||
; Rx Time T2 = NA
|
||||
; Rx Exit State = STBY
|
||||
; Tx Exit State = STBY
|
||||
; SLP Mode = Disable
|
||||
; RSSI Valid Source = PJD
|
||||
; PJD Window = 8 Jumps
|
||||
; LFOSC Calibration = On
|
||||
; Xtal Stable Time = 155 us
|
||||
; RSSI Compare TH = NA
|
||||
; Data Mode = Packet
|
||||
; Whitening = Disable
|
||||
; Whiten Type = NA
|
||||
; Whiten Seed Type = NA
|
||||
; Whiten Seed = NA
|
||||
; Manchester = Disable
|
||||
; Manchester Type = NA
|
||||
; FEC = Enable
|
||||
; FEC Type = x^3+x^2+1
|
||||
; Tx Prefix Type = 0
|
||||
; Tx Packet Number = 1
|
||||
; Tx Packet Gap = 32
|
||||
; Packet Type = Variable Length
|
||||
; Node-Length Position = First Node, then Length
|
||||
; Payload Bit Order = Start from msb
|
||||
; Preamble Rx Size = 2
|
||||
; Preamble Tx Size = 30
|
||||
; Preamble Value = 170
|
||||
; Preamble Unit = 8-bit
|
||||
; Sync Size = 4-byte
|
||||
; Sync Value = 1296587336
|
||||
; Sync Tolerance = None
|
||||
; Sync Manchester = Disable
|
||||
; Node ID Size = NA
|
||||
; Node ID Value = NA
|
||||
; Node ID Mode = None
|
||||
; Node ID Err Mask = Disable
|
||||
; Node ID Free = Disable
|
||||
; Payload Length = 32
|
||||
; CRC Options = IBM-16
|
||||
; CRC Seed = 0 crc_seed
|
||||
; CRC Range = Entire Payload
|
||||
; CRC Swap = Start from MSB
|
||||
; CRC Bit Invert = Normal
|
||||
; CRC Bit Order = Start from bit 15
|
||||
; Dout Mute = Off
|
||||
; Dout Adjust Mode = Disable
|
||||
; Dout Adjust Percentage = NA
|
||||
; Collision Detect = Off
|
||||
; Collision Detect Offset = NA
|
||||
; RSSI Detect Mode = At PREAM_OK
|
||||
; RSSI Filter Setting = 32-tap
|
||||
; RF Performance = High
|
||||
; LBD Threshold = 2.4 V
|
||||
; RSSI Offset = 0
|
||||
; RSSI Offset Sign = 0
|
||||
*/
|
||||
#ifndef __CMT2300A_PARAMS_860_H
|
||||
#define __CMT2300A_PARAMS_860_H
|
||||
|
||||
#include "cmt2300a_defs.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/* [CMT Bank] with RSSI offset of +- 0 (and Tx power double bit not set) */
|
||||
static uint8_t g_cmt2300aCmtBank_860[CMT2300A_CMT_BANK_SIZE] = {
|
||||
0x00,
|
||||
0x66,
|
||||
0xEC,
|
||||
0x1C,
|
||||
0x70,
|
||||
0x80,
|
||||
0x14,
|
||||
0x08,
|
||||
0x11,
|
||||
0x02,
|
||||
0x02,
|
||||
0x00,
|
||||
};
|
||||
|
||||
/* [System Bank] */
|
||||
static uint8_t g_cmt2300aSystemBank_860[CMT2300A_SYSTEM_BANK_SIZE] = {
|
||||
0xAE,
|
||||
0xE0,
|
||||
0x35,
|
||||
0x00,
|
||||
0x00,
|
||||
0xF4,
|
||||
0x10,
|
||||
0xE2,
|
||||
0x42,
|
||||
0x20,
|
||||
0x0C,
|
||||
0x81,
|
||||
};
|
||||
|
||||
/* [Frequency Bank] 860 MHz */
|
||||
static uint8_t g_cmt2300aFrequencyBank_860[CMT2300A_FREQUENCY_BANK_SIZE] = {
|
||||
0x42,
|
||||
0x32,
|
||||
0xCF,
|
||||
0x82,
|
||||
0x42,
|
||||
0x27,
|
||||
0x76,
|
||||
0x12,
|
||||
};
|
||||
|
||||
/* [Data Rate Bank] */
|
||||
static uint8_t g_cmt2300aDataRateBank_860[CMT2300A_DATA_RATE_BANK_SIZE] = {
|
||||
0xA6,
|
||||
0xC9,
|
||||
0x20,
|
||||
0x20,
|
||||
0xD2,
|
||||
0x35,
|
||||
0x0C,
|
||||
0x0A,
|
||||
0x9F,
|
||||
0x4B,
|
||||
0x29,
|
||||
0x29,
|
||||
0xC0,
|
||||
0x14,
|
||||
0x05,
|
||||
0x53,
|
||||
0x10,
|
||||
0x00,
|
||||
0xB4,
|
||||
0x00,
|
||||
0x00,
|
||||
0x01,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
/* [Baseband Bank] - EU */
|
||||
static uint8_t g_cmt2300aBasebandBank_860[CMT2300A_BASEBAND_BANK_SIZE] = {
|
||||
0x12,
|
||||
0x1E,
|
||||
0x00,
|
||||
0xAA,
|
||||
0x06,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x48,
|
||||
0x5A,
|
||||
0x48,
|
||||
0x4D,
|
||||
0x01,
|
||||
0x1F,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0xC3,
|
||||
0x00,
|
||||
0x00,
|
||||
0x60,
|
||||
0xFF,
|
||||
0x00,
|
||||
0x00,
|
||||
0x1F,
|
||||
0x10,
|
||||
};
|
||||
|
||||
/* [Tx Bank] 13 dBm */
|
||||
static uint8_t g_cmt2300aTxBank_860[CMT2300A_TX_BANK_SIZE] = {
|
||||
0x70,
|
||||
0x4D,
|
||||
0x06,
|
||||
0x00,
|
||||
0x07,
|
||||
0x50,
|
||||
0x00,
|
||||
0x53,
|
||||
0x09,
|
||||
0x3F,
|
||||
0x7F,
|
||||
};
|
||||
|
||||
#endif
|
||||
214
lib/CMT2300a/cmt2300a_params_900.h
Normal file
214
lib/CMT2300a/cmt2300a_params_900.h
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
;---------------------------------------
|
||||
; CMT2300A Configuration File
|
||||
; Generated by CMOSTEK RFPDK 1.46
|
||||
; 2023.03.17 23:16
|
||||
;---------------------------------------
|
||||
; Mode = Advanced
|
||||
; Part Number = CMT2300A
|
||||
; Frequency = 900.000 MHz
|
||||
; Xtal Frequency = 26.0000 MHz
|
||||
; Demodulation = GFSK
|
||||
; AGC = On
|
||||
; Data Rate = 20.0 kbps
|
||||
; Deviation = 20.0 kHz
|
||||
; Tx Xtal Tol. = 20 ppm
|
||||
; Rx Xtal Tol. = 20 ppm
|
||||
; TRx Matching Network Type = 20 dBm
|
||||
; Tx Power = +13 dBm
|
||||
; Gaussian BT = 0.5
|
||||
; Bandwidth = Auto-Select kHz
|
||||
; CDR Type = Counting
|
||||
; CDR DR Range = NA
|
||||
; AFC = On
|
||||
; AFC Method = Auto-Select
|
||||
; Data Representation = 0:F-low 1:F-high
|
||||
; Rx Duty-Cycle = Off
|
||||
; Tx Duty-Cycle = Off
|
||||
; Sleep Timer = Off
|
||||
; Sleep Time = NA
|
||||
; Rx Timer = Off
|
||||
; Rx Time T1 = NA
|
||||
; Rx Time T2 = NA
|
||||
; Rx Exit State = STBY
|
||||
; Tx Exit State = STBY
|
||||
; SLP Mode = Disable
|
||||
; RSSI Valid Source = PJD
|
||||
; PJD Window = 8 Jumps
|
||||
; LFOSC Calibration = On
|
||||
; Xtal Stable Time = 155 us
|
||||
; RSSI Compare TH = NA
|
||||
; Data Mode = Packet
|
||||
; Whitening = Disable
|
||||
; Whiten Type = NA
|
||||
; Whiten Seed Type = NA
|
||||
; Whiten Seed = NA
|
||||
; Manchester = Disable
|
||||
; Manchester Type = NA
|
||||
; FEC = Enable
|
||||
; FEC Type = x^3+x^2+1
|
||||
; Tx Prefix Type = 0
|
||||
; Tx Packet Number = 1
|
||||
; Tx Packet Gap = 32
|
||||
; Packet Type = Variable Length
|
||||
; Node-Length Position = First Node, then Length
|
||||
; Payload Bit Order = Start from msb
|
||||
; Preamble Rx Size = 2
|
||||
; Preamble Tx Size = 30
|
||||
; Preamble Value = 170
|
||||
; Preamble Unit = 8-bit
|
||||
; Sync Size = 4-byte
|
||||
; Sync Value = 1296587336
|
||||
; Sync Tolerance = None
|
||||
; Sync Manchester = Disable
|
||||
; Node ID Size = NA
|
||||
; Node ID Value = NA
|
||||
; Node ID Mode = None
|
||||
; Node ID Err Mask = Disable
|
||||
; Node ID Free = Disable
|
||||
; Payload Length = 32
|
||||
; CRC Options = IBM-16
|
||||
; CRC Seed = 0 crc_seed
|
||||
; CRC Range = Entire Payload
|
||||
; CRC Swap = Start from MSB
|
||||
; CRC Bit Invert = Normal
|
||||
; CRC Bit Order = Start from bit 15
|
||||
; Dout Mute = Off
|
||||
; Dout Adjust Mode = Disable
|
||||
; Dout Adjust Percentage = NA
|
||||
; Collision Detect = Off
|
||||
; Collision Detect Offset = NA
|
||||
; RSSI Detect Mode = At PREAM_OK
|
||||
; RSSI Filter Setting = 32-tap
|
||||
; RF Performance = High
|
||||
; LBD Threshold = 2.4 V
|
||||
; RSSI Offset = 0
|
||||
; RSSI Offset Sign = 0
|
||||
*/
|
||||
#ifndef __CMT2300A_PARAMS_900_H
|
||||
#define __CMT2300A_PARAMS_900_H
|
||||
|
||||
#include "cmt2300a_defs.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/* [CMT Bank] with RSSI offset of +- 0 (and Tx power double bit not set) */
|
||||
static uint8_t g_cmt2300aCmtBank_900[CMT2300A_CMT_BANK_SIZE] = {
|
||||
0x00,
|
||||
0x66,
|
||||
0xEC,
|
||||
0x1C,
|
||||
0x70,
|
||||
0x80,
|
||||
0x14,
|
||||
0x08,
|
||||
0x11,
|
||||
0x02,
|
||||
0x02,
|
||||
0x00,
|
||||
};
|
||||
|
||||
/* [System Bank] */
|
||||
static uint8_t g_cmt2300aSystemBank_900[CMT2300A_SYSTEM_BANK_SIZE] = {
|
||||
0xAE,
|
||||
0xE0,
|
||||
0x35,
|
||||
0x00,
|
||||
0x00,
|
||||
0xF4,
|
||||
0x10,
|
||||
0xE2,
|
||||
0x42,
|
||||
0x20,
|
||||
0x0C,
|
||||
0x81,
|
||||
};
|
||||
|
||||
/* [Frequency Bank] 900 MHz */
|
||||
static uint8_t g_cmt2300aFrequencyBank_900[CMT2300A_FREQUENCY_BANK_SIZE] = {
|
||||
0x45,
|
||||
0x46,
|
||||
0x0A,
|
||||
0x84,
|
||||
0x45,
|
||||
0x3B,
|
||||
0xB1,
|
||||
0x13,
|
||||
};
|
||||
|
||||
/* [Data Rate Bank] */
|
||||
static uint8_t g_cmt2300aDataRateBank_900[CMT2300A_DATA_RATE_BANK_SIZE] = {
|
||||
0xA6,
|
||||
0xC9,
|
||||
0x20,
|
||||
0x20,
|
||||
0xD2,
|
||||
0x35,
|
||||
0x0C,
|
||||
0x0B,
|
||||
0x9F,
|
||||
0x4B,
|
||||
0x29,
|
||||
0x29,
|
||||
0xC0,
|
||||
0x14,
|
||||
0x05,
|
||||
0x53,
|
||||
0x10,
|
||||
0x00,
|
||||
0xB4,
|
||||
0x00,
|
||||
0x00,
|
||||
0x01,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
/* [Baseband Bank] - EU */
|
||||
static uint8_t g_cmt2300aBasebandBank_900[CMT2300A_BASEBAND_BANK_SIZE] = {
|
||||
0x12,
|
||||
0x1E,
|
||||
0x00,
|
||||
0xAA,
|
||||
0x06,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x48,
|
||||
0x5A,
|
||||
0x48,
|
||||
0x4D,
|
||||
0x01,
|
||||
0x1F,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0xC3,
|
||||
0x00,
|
||||
0x00,
|
||||
0x60,
|
||||
0xFF,
|
||||
0x00,
|
||||
0x00,
|
||||
0x1F,
|
||||
0x10,
|
||||
};
|
||||
|
||||
/* [Tx Bank] 13 dBm */
|
||||
static uint8_t g_cmt2300aTxBank_900[CMT2300A_TX_BANK_SIZE] = {
|
||||
0x70,
|
||||
0x4D,
|
||||
0x06,
|
||||
0x00,
|
||||
0x07,
|
||||
0x50,
|
||||
0x00,
|
||||
0x53,
|
||||
0x09,
|
||||
0x3F,
|
||||
0x7F,
|
||||
};
|
||||
|
||||
#endif
|
||||
330
lib/CMT2300a/cmt2300wrapper.cpp
Normal file
330
lib/CMT2300a/cmt2300wrapper.cpp
Normal file
@ -0,0 +1,330 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) 2023-2024 Thomas Basler and others
|
||||
*/
|
||||
#include "cmt2300wrapper.h"
|
||||
#include "cmt2300a.h"
|
||||
#include "cmt2300a_params_860.h"
|
||||
#include "cmt2300a_params_900.h"
|
||||
|
||||
CMT2300A::CMT2300A(const uint8_t pin_sdio, const uint8_t pin_clk, const uint8_t pin_cs, const uint8_t pin_fcs, const uint32_t spi_speed)
|
||||
{
|
||||
_pin_sdio = pin_sdio;
|
||||
_pin_clk = pin_clk;
|
||||
_pin_cs = pin_cs;
|
||||
_pin_fcs = pin_fcs;
|
||||
_spi_speed = spi_speed;
|
||||
}
|
||||
|
||||
bool CMT2300A::begin(void)
|
||||
{
|
||||
return _init_pins() && _init_radio();
|
||||
}
|
||||
|
||||
bool CMT2300A::isChipConnected()
|
||||
{
|
||||
return CMT2300A_IsExist();
|
||||
}
|
||||
|
||||
bool CMT2300A::startListening(void)
|
||||
{
|
||||
CMT2300A_GoStby();
|
||||
CMT2300A_ClearInterruptFlags();
|
||||
|
||||
/* Must clear FIFO after enable SPI to read or write the FIFO */
|
||||
CMT2300A_EnableReadFifo();
|
||||
CMT2300A_ClearRxFifo();
|
||||
|
||||
if (!CMT2300A_GoRx()) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool CMT2300A::stopListening(void)
|
||||
{
|
||||
CMT2300A_ClearInterruptFlags();
|
||||
return CMT2300A_GoSleep();
|
||||
}
|
||||
|
||||
bool CMT2300A::available(void)
|
||||
{
|
||||
return (
|
||||
CMT2300A_MASK_PREAM_OK_FLG |
|
||||
CMT2300A_MASK_SYNC_OK_FLG |
|
||||
CMT2300A_MASK_CRC_OK_FLG |
|
||||
CMT2300A_MASK_PKT_OK_FLG
|
||||
) & CMT2300A_ReadReg(CMT2300A_CUS_INT_FLAG);
|
||||
}
|
||||
|
||||
void CMT2300A::read(void* buf, const uint8_t len)
|
||||
{
|
||||
// Fetch the payload
|
||||
CMT2300A_ReadFifo(static_cast<uint8_t*>(buf), len);
|
||||
|
||||
CMT2300A_ClearInterruptFlags();
|
||||
}
|
||||
|
||||
bool CMT2300A::write(const uint8_t* buf, const uint8_t len)
|
||||
{
|
||||
CMT2300A_GoStby();
|
||||
CMT2300A_ClearInterruptFlags();
|
||||
|
||||
/* Must clear FIFO after enable SPI to read or write the FIFO */
|
||||
CMT2300A_EnableWriteFifo();
|
||||
CMT2300A_ClearTxFifo();
|
||||
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_PKT15, len); // set Tx length
|
||||
/* The length need be smaller than 32 */
|
||||
CMT2300A_WriteFifo(buf, len);
|
||||
|
||||
if (!(CMT2300A_ReadReg(CMT2300A_CUS_FIFO_FLAG) & CMT2300A_MASK_TX_FIFO_NMTY_FLG)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CMT2300A_GoTx()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t timer = millis();
|
||||
|
||||
while (!(CMT2300A_MASK_TX_DONE_FLG & CMT2300A_ReadReg(CMT2300A_CUS_INT_CLR1))) {
|
||||
if (millis() - timer > 95) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
CMT2300A_ClearInterruptFlags();
|
||||
CMT2300A_GoSleep();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMT2300A::setChannel(const uint8_t channel)
|
||||
{
|
||||
CMT2300A_SetFrequencyChannel(channel);
|
||||
}
|
||||
|
||||
uint8_t CMT2300A::getChannel(void)
|
||||
{
|
||||
return CMT2300A_ReadReg(CMT2300A_CUS_FREQ_CHNL);
|
||||
}
|
||||
|
||||
uint8_t CMT2300A::getDynamicPayloadSize(void)
|
||||
{
|
||||
uint8_t result;
|
||||
CMT2300A_ReadFifo(&result, 1); // first byte in FiFo is length
|
||||
return result;
|
||||
}
|
||||
|
||||
int CMT2300A::getRssiDBm()
|
||||
{
|
||||
return CMT2300A_GetRssiDBm();
|
||||
}
|
||||
|
||||
bool CMT2300A::setPALevel(const int8_t level)
|
||||
{
|
||||
uint16_t Tx_dBm_word;
|
||||
switch (level) {
|
||||
// for TRx Matching Network Type: 20 dBm
|
||||
case -10:
|
||||
Tx_dBm_word = 0x0501;
|
||||
break;
|
||||
case -9:
|
||||
Tx_dBm_word = 0x0601;
|
||||
break;
|
||||
case -8:
|
||||
Tx_dBm_word = 0x0701;
|
||||
break;
|
||||
case -7:
|
||||
Tx_dBm_word = 0x0801;
|
||||
break;
|
||||
case -6:
|
||||
Tx_dBm_word = 0x0901;
|
||||
break;
|
||||
case -5:
|
||||
Tx_dBm_word = 0x0A01;
|
||||
break;
|
||||
case -4:
|
||||
Tx_dBm_word = 0x0B01;
|
||||
break;
|
||||
case -3:
|
||||
Tx_dBm_word = 0x0C01;
|
||||
break;
|
||||
case -2:
|
||||
Tx_dBm_word = 0x0D01;
|
||||
break;
|
||||
case -1:
|
||||
Tx_dBm_word = 0x0E01;
|
||||
break;
|
||||
case 0:
|
||||
Tx_dBm_word = 0x1002;
|
||||
break;
|
||||
case 1:
|
||||
Tx_dBm_word = 0x1302;
|
||||
break;
|
||||
case 2:
|
||||
Tx_dBm_word = 0x1602;
|
||||
break;
|
||||
case 3:
|
||||
Tx_dBm_word = 0x1902;
|
||||
break;
|
||||
case 4:
|
||||
Tx_dBm_word = 0x1C02;
|
||||
break;
|
||||
case 5:
|
||||
Tx_dBm_word = 0x1F03;
|
||||
break;
|
||||
case 6:
|
||||
Tx_dBm_word = 0x2403;
|
||||
break;
|
||||
case 7:
|
||||
Tx_dBm_word = 0x2804;
|
||||
break;
|
||||
case 8:
|
||||
Tx_dBm_word = 0x2D04;
|
||||
break;
|
||||
case 9:
|
||||
Tx_dBm_word = 0x3305;
|
||||
break;
|
||||
case 10:
|
||||
Tx_dBm_word = 0x3906;
|
||||
break;
|
||||
case 11:
|
||||
Tx_dBm_word = 0x4107;
|
||||
break;
|
||||
case 12:
|
||||
Tx_dBm_word = 0x4908;
|
||||
break;
|
||||
case 13:
|
||||
Tx_dBm_word = 0x5309;
|
||||
break;
|
||||
case 14:
|
||||
Tx_dBm_word = 0x5E0B;
|
||||
break;
|
||||
case 15:
|
||||
Tx_dBm_word = 0x6C0C;
|
||||
break;
|
||||
case 16:
|
||||
Tx_dBm_word = 0x7D0C;
|
||||
break;
|
||||
// the following values require the double bit:
|
||||
case 17:
|
||||
Tx_dBm_word = 0x4A0C;
|
||||
break;
|
||||
case 18:
|
||||
Tx_dBm_word = 0x580F;
|
||||
break;
|
||||
case 19:
|
||||
Tx_dBm_word = 0x6B12;
|
||||
break;
|
||||
case 20:
|
||||
Tx_dBm_word = 0x8A18;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (level > 16) { // set bit for double Tx value
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_CMT4, CMT2300A_ReadReg(CMT2300A_CUS_CMT4) | 0x01); // set bit0
|
||||
} else {
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_CMT4, CMT2300A_ReadReg(CMT2300A_CUS_CMT4) & 0xFE); // reset bit0
|
||||
}
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_TX8, Tx_dBm_word >> 8);
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_TX9, Tx_dBm_word & 0xFF);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMT2300A::rxFifoAvailable()
|
||||
{
|
||||
return (
|
||||
CMT2300A_MASK_PKT_OK_FLG
|
||||
) & CMT2300A_ReadReg(CMT2300A_CUS_INT_FLAG);
|
||||
}
|
||||
|
||||
uint32_t CMT2300A::getBaseFrequency() const
|
||||
{
|
||||
return getBaseFrequency(_frequencyBand);
|
||||
}
|
||||
|
||||
FrequencyBand_t CMT2300A::getFrequencyBand() const
|
||||
{
|
||||
return _frequencyBand;
|
||||
}
|
||||
|
||||
void CMT2300A::setFrequencyBand(const FrequencyBand_t mode)
|
||||
{
|
||||
_frequencyBand = mode;
|
||||
_init_radio();
|
||||
}
|
||||
|
||||
void CMT2300A::flush_rx(void)
|
||||
{
|
||||
CMT2300A_ClearRxFifo();
|
||||
}
|
||||
|
||||
bool CMT2300A::_init_pins()
|
||||
{
|
||||
CMT2300A_InitSpi(_pin_sdio, _pin_clk, _pin_cs, _pin_fcs, _spi_speed);
|
||||
|
||||
return true; // assuming pins are connected properly
|
||||
}
|
||||
|
||||
bool CMT2300A::_init_radio()
|
||||
{
|
||||
if (!CMT2300A_Init()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* config registers */
|
||||
switch (_frequencyBand) {
|
||||
case FrequencyBand_t::BAND_900:
|
||||
CMT2300A_ConfigRegBank(CMT2300A_CMT_BANK_ADDR, g_cmt2300aCmtBank_900, CMT2300A_CMT_BANK_SIZE);
|
||||
CMT2300A_ConfigRegBank(CMT2300A_SYSTEM_BANK_ADDR, g_cmt2300aSystemBank_900, CMT2300A_SYSTEM_BANK_SIZE);
|
||||
CMT2300A_ConfigRegBank(CMT2300A_FREQUENCY_BANK_ADDR, g_cmt2300aFrequencyBank_900, CMT2300A_FREQUENCY_BANK_SIZE);
|
||||
CMT2300A_ConfigRegBank(CMT2300A_DATA_RATE_BANK_ADDR, g_cmt2300aDataRateBank_900, CMT2300A_DATA_RATE_BANK_SIZE);
|
||||
CMT2300A_ConfigRegBank(CMT2300A_BASEBAND_BANK_ADDR, g_cmt2300aBasebandBank_900, CMT2300A_BASEBAND_BANK_SIZE);
|
||||
CMT2300A_ConfigRegBank(CMT2300A_TX_BANK_ADDR, g_cmt2300aTxBank_900, CMT2300A_TX_BANK_SIZE);
|
||||
break;
|
||||
default:
|
||||
CMT2300A_ConfigRegBank(CMT2300A_CMT_BANK_ADDR, g_cmt2300aCmtBank_860, CMT2300A_CMT_BANK_SIZE);
|
||||
CMT2300A_ConfigRegBank(CMT2300A_SYSTEM_BANK_ADDR, g_cmt2300aSystemBank_860, CMT2300A_SYSTEM_BANK_SIZE);
|
||||
CMT2300A_ConfigRegBank(CMT2300A_FREQUENCY_BANK_ADDR, g_cmt2300aFrequencyBank_860, CMT2300A_FREQUENCY_BANK_SIZE);
|
||||
CMT2300A_ConfigRegBank(CMT2300A_DATA_RATE_BANK_ADDR, g_cmt2300aDataRateBank_860, CMT2300A_DATA_RATE_BANK_SIZE);
|
||||
CMT2300A_ConfigRegBank(CMT2300A_BASEBAND_BANK_ADDR, g_cmt2300aBasebandBank_860, CMT2300A_BASEBAND_BANK_SIZE);
|
||||
CMT2300A_ConfigRegBank(CMT2300A_TX_BANK_ADDR, g_cmt2300aTxBank_860, CMT2300A_TX_BANK_SIZE);
|
||||
break;
|
||||
}
|
||||
|
||||
// xosc_aac_code[2:0] = 2
|
||||
uint8_t tmp;
|
||||
tmp = (~0x07) & CMT2300A_ReadReg(CMT2300A_CUS_CMT10);
|
||||
CMT2300A_WriteReg(CMT2300A_CUS_CMT10, tmp | 0x02);
|
||||
|
||||
/* Config GPIOs */
|
||||
CMT2300A_ConfigGpio(
|
||||
CMT2300A_GPIO2_SEL_INT1 | CMT2300A_GPIO3_SEL_INT2);
|
||||
|
||||
/* Config interrupt */
|
||||
CMT2300A_ConfigInterrupt(
|
||||
CMT2300A_INT_SEL_TX_DONE, /* Config INT1 */
|
||||
CMT2300A_INT_SEL_PKT_OK /* Config INT2 */
|
||||
);
|
||||
|
||||
/* Enable interrupt */
|
||||
CMT2300A_EnableInterrupt(
|
||||
CMT2300A_MASK_TX_DONE_EN | CMT2300A_MASK_PREAM_OK_EN | CMT2300A_MASK_SYNC_OK_EN | CMT2300A_MASK_CRC_OK_EN | CMT2300A_MASK_PKT_DONE_EN);
|
||||
|
||||
CMT2300A_SetFrequencyStep(FH_OFFSET); // set FH_OFFSET (frequency = base freq + 2.5kHz*FH_OFFSET*FH_CHANNEL)
|
||||
|
||||
/* Use a single 64-byte FIFO for either Tx or Rx */
|
||||
CMT2300A_EnableFifoMerge(true);
|
||||
|
||||
/* Go to sleep for configuration to take effect */
|
||||
if (!CMT2300A_GoSleep()) {
|
||||
return false; // CMT2300A not switched to sleep mode!
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
138
lib/CMT2300a/cmt2300wrapper.h
Normal file
138
lib/CMT2300a/cmt2300wrapper.h
Normal file
@ -0,0 +1,138 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define CMT2300A_ONE_STEP_SIZE 2500 // frequency channel step size for fast frequency hopping operation: One step size is 2.5 kHz.
|
||||
#define FH_OFFSET 100 // value * CMT2300A_ONE_STEP_SIZE = channel frequency offset
|
||||
#define CMT_SPI_SPEED 4000000 // 4 MHz
|
||||
|
||||
#define CMT_BASE_FREQ_900 900000000
|
||||
#define CMT_BASE_FREQ_860 860000000
|
||||
|
||||
enum FrequencyBand_t {
|
||||
BAND_860,
|
||||
BAND_900,
|
||||
FrequencyBand_Max,
|
||||
};
|
||||
|
||||
class CMT2300A {
|
||||
public:
|
||||
CMT2300A(const uint8_t pin_sdio, const uint8_t pin_clk, const uint8_t pin_cs, const uint8_t pin_fcs, const uint32_t _spi_speed = CMT_SPI_SPEED);
|
||||
|
||||
bool begin(void);
|
||||
|
||||
/**
|
||||
* Checks if the chip is connected to the SPI bus
|
||||
*/
|
||||
bool isChipConnected();
|
||||
|
||||
bool startListening(void);
|
||||
|
||||
bool stopListening(void);
|
||||
|
||||
/**
|
||||
* Check whether there are bytes available to be read
|
||||
* @code
|
||||
* if(radio.available()){
|
||||
* radio.read(&data,sizeof(data));
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @see available(uint8_t*)
|
||||
*
|
||||
* @return True if there is a payload available, false if none is
|
||||
*/
|
||||
bool available(void);
|
||||
|
||||
/**
|
||||
* Read payload data from the RX FIFO buffer(s).
|
||||
*
|
||||
* The length of data read is usually the next available payload's length
|
||||
* @see
|
||||
* - getDynamicPayloadSize()
|
||||
*
|
||||
* @note I specifically chose `void*` as a data type to make it easier
|
||||
* for beginners to use. No casting needed.
|
||||
*
|
||||
* @param buf Pointer to a buffer where the data should be written
|
||||
* @param len Maximum number of bytes to read into the buffer. This
|
||||
* value should match the length of the object referenced using the
|
||||
* `buf` parameter. The absolute maximum number of bytes that can be read
|
||||
* in one call is 32 (for dynamic payload lengths) or whatever number was
|
||||
* previously passed to setPayloadSize() (for static payload lengths).
|
||||
*/
|
||||
void read(void* buf, const uint8_t len);
|
||||
|
||||
bool write(const uint8_t* buf, const uint8_t len);
|
||||
|
||||
/**
|
||||
* Set RF communication channel. The frequency used by a channel is
|
||||
* @param channel Which RF channel to communicate on, 0-254
|
||||
*/
|
||||
void setChannel(const uint8_t channel);
|
||||
|
||||
/**
|
||||
* Get RF communication channel
|
||||
* @return The currently configured RF Channel
|
||||
*/
|
||||
uint8_t getChannel(void);
|
||||
|
||||
/**
|
||||
* Get Dynamic Payload Size
|
||||
*
|
||||
* For dynamic payloads, this pulls the size of the payload off
|
||||
* the chip
|
||||
*
|
||||
* @return Payload length of last-received dynamic payload
|
||||
*/
|
||||
uint8_t getDynamicPayloadSize(void);
|
||||
|
||||
int getRssiDBm();
|
||||
|
||||
bool setPALevel(const int8_t level);
|
||||
|
||||
bool rxFifoAvailable();
|
||||
|
||||
uint32_t getBaseFrequency() const;
|
||||
static constexpr uint32_t getBaseFrequency(FrequencyBand_t band)
|
||||
{
|
||||
switch (band) {
|
||||
case FrequencyBand_t::BAND_900:
|
||||
return CMT_BASE_FREQ_900;
|
||||
break;
|
||||
default:
|
||||
return CMT_BASE_FREQ_860;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FrequencyBand_t getFrequencyBand() const;
|
||||
void setFrequencyBand(const FrequencyBand_t mode);
|
||||
|
||||
/**
|
||||
* Empty the RX (receive) FIFO buffers.
|
||||
*/
|
||||
void flush_rx(void);
|
||||
|
||||
private:
|
||||
/**
|
||||
* initialize the GPIO pins
|
||||
*/
|
||||
bool _init_pins();
|
||||
|
||||
/**
|
||||
* initialize radio.
|
||||
* @warning This function assumes the SPI bus object's begin() method has been
|
||||
* previously called.
|
||||
*/
|
||||
bool _init_radio();
|
||||
|
||||
int8_t _pin_sdio;
|
||||
int8_t _pin_clk;
|
||||
int8_t _pin_cs;
|
||||
int8_t _pin_fcs;
|
||||
uint32_t _spi_speed;
|
||||
|
||||
FrequencyBand_t _frequencyBand = FrequencyBand_t::BAND_860;
|
||||
};
|
||||
155
lib/CMT2300a/cmt_spi3.cpp
Normal file
155
lib/CMT2300a/cmt_spi3.cpp
Normal file
@ -0,0 +1,155 @@
|
||||
#include "cmt_spi3.h"
|
||||
#include <Arduino.h>
|
||||
#include <driver/spi_master.h>
|
||||
#include <SpiManager.h>
|
||||
|
||||
SemaphoreHandle_t paramLock = NULL;
|
||||
#define SPI_PARAM_LOCK() \
|
||||
do { \
|
||||
} while (xSemaphoreTake(paramLock, portMAX_DELAY) != pdPASS)
|
||||
#define SPI_PARAM_UNLOCK() xSemaphoreGive(paramLock)
|
||||
|
||||
static void IRAM_ATTR pre_cb(spi_transaction_t *trans) {
|
||||
gpio_set_level(*reinterpret_cast<gpio_num_t*>(trans->user), 0);
|
||||
}
|
||||
|
||||
static void IRAM_ATTR post_cb(spi_transaction_t *trans) {
|
||||
gpio_set_level(*reinterpret_cast<gpio_num_t*>(trans->user), 1);
|
||||
}
|
||||
|
||||
spi_device_handle_t spi;
|
||||
gpio_num_t cs_reg, cs_fifo;
|
||||
|
||||
void cmt_spi3_init(const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const int32_t spi_speed)
|
||||
{
|
||||
paramLock = xSemaphoreCreateMutex();
|
||||
|
||||
auto bus_config = std::make_shared<SpiBusConfig>(
|
||||
static_cast<gpio_num_t>(pin_sdio),
|
||||
GPIO_NUM_NC,
|
||||
static_cast<gpio_num_t>(pin_clk)
|
||||
);
|
||||
|
||||
spi_device_interface_config_t device_config {
|
||||
.command_bits = 0, // set by transactions individually
|
||||
.address_bits = 0, // set by transactions individually
|
||||
.dummy_bits = 0,
|
||||
.mode = 0, // SPI mode 0
|
||||
.duty_cycle_pos = 0,
|
||||
.cs_ena_pretrans = 2, // only 1 pre and post cycle would be required for register access
|
||||
.cs_ena_posttrans = static_cast<uint8_t>(2 * spi_speed / 1000000), // >2 us
|
||||
.clock_speed_hz = spi_speed,
|
||||
.input_delay_ns = 0,
|
||||
.spics_io_num = -1, // CS handled by callbacks
|
||||
.flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_3WIRE,
|
||||
.queue_size = 1,
|
||||
.pre_cb = pre_cb,
|
||||
.post_cb = post_cb,
|
||||
};
|
||||
|
||||
spi = SpiManagerInst.alloc_device("", bus_config, device_config);
|
||||
if (!spi)
|
||||
ESP_ERROR_CHECK(ESP_FAIL);
|
||||
|
||||
cs_reg = static_cast<gpio_num_t>(pin_cs);
|
||||
ESP_ERROR_CHECK(gpio_reset_pin(cs_reg));
|
||||
ESP_ERROR_CHECK(gpio_set_level(cs_reg, 1));
|
||||
ESP_ERROR_CHECK(gpio_set_direction(cs_reg, GPIO_MODE_OUTPUT));
|
||||
|
||||
cs_fifo = static_cast<gpio_num_t>(pin_fcs);
|
||||
ESP_ERROR_CHECK(gpio_reset_pin(cs_fifo));
|
||||
ESP_ERROR_CHECK(gpio_set_level(cs_fifo, 1));
|
||||
ESP_ERROR_CHECK(gpio_set_direction(cs_fifo, GPIO_MODE_OUTPUT));
|
||||
}
|
||||
|
||||
void cmt_spi3_write(const uint8_t addr, const uint8_t data)
|
||||
{
|
||||
spi_transaction_ext_t trans {
|
||||
.base {
|
||||
.flags = SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR,
|
||||
.cmd = 0,
|
||||
.addr = addr,
|
||||
.length = 8,
|
||||
.rxlength = 0,
|
||||
.user = &cs_reg, // CS for register access
|
||||
.tx_buffer = &data,
|
||||
.rx_buffer = nullptr,
|
||||
},
|
||||
.command_bits = 1,
|
||||
.address_bits = 7,
|
||||
.dummy_bits = 0,
|
||||
};
|
||||
SPI_PARAM_LOCK();
|
||||
ESP_ERROR_CHECK(spi_device_polling_transmit(spi, reinterpret_cast<spi_transaction_t*>(&trans)));
|
||||
SPI_PARAM_UNLOCK();
|
||||
}
|
||||
|
||||
uint8_t cmt_spi3_read(const uint8_t addr)
|
||||
{
|
||||
uint8_t data;
|
||||
spi_transaction_ext_t trans {
|
||||
.base {
|
||||
.flags = SPI_TRANS_VARIABLE_CMD | SPI_TRANS_VARIABLE_ADDR,
|
||||
.cmd = 1,
|
||||
.addr = addr,
|
||||
.length = 0,
|
||||
.rxlength = 8,
|
||||
.user = &cs_reg, // CS for register access
|
||||
.tx_buffer = nullptr,
|
||||
.rx_buffer = &data,
|
||||
},
|
||||
.command_bits = 1,
|
||||
.address_bits = 7,
|
||||
.dummy_bits = 0,
|
||||
};
|
||||
SPI_PARAM_LOCK();
|
||||
ESP_ERROR_CHECK(spi_device_polling_transmit(spi, reinterpret_cast<spi_transaction_t*>(&trans)));
|
||||
SPI_PARAM_UNLOCK();
|
||||
return data;
|
||||
}
|
||||
|
||||
void cmt_spi3_write_fifo(const uint8_t* buf, const uint16_t len)
|
||||
{
|
||||
spi_transaction_t trans {
|
||||
.flags = 0,
|
||||
.cmd = 0,
|
||||
.addr = 0,
|
||||
.length = 8,
|
||||
.rxlength = 0,
|
||||
.user = &cs_fifo, // CS for FIFO access
|
||||
.tx_buffer = nullptr,
|
||||
.rx_buffer = nullptr,
|
||||
};
|
||||
|
||||
SPI_PARAM_LOCK();
|
||||
spi_device_acquire_bus(spi, portMAX_DELAY);
|
||||
for (uint8_t i = 0; i < len; i++) {
|
||||
trans.tx_buffer = buf + i;
|
||||
ESP_ERROR_CHECK(spi_device_polling_transmit(spi, &trans));
|
||||
}
|
||||
spi_device_release_bus(spi);
|
||||
SPI_PARAM_UNLOCK();
|
||||
}
|
||||
|
||||
void cmt_spi3_read_fifo(uint8_t* buf, const uint16_t len)
|
||||
{
|
||||
spi_transaction_t trans {
|
||||
.flags = 0,
|
||||
.cmd = 0,
|
||||
.addr = 0,
|
||||
.length = 0,
|
||||
.rxlength = 8,
|
||||
.user = &cs_fifo, // CS for FIFO access
|
||||
.tx_buffer = nullptr,
|
||||
.rx_buffer = nullptr,
|
||||
};
|
||||
|
||||
SPI_PARAM_LOCK();
|
||||
spi_device_acquire_bus(spi, portMAX_DELAY);
|
||||
for (uint8_t i = 0; i < len; i++) {
|
||||
trans.rx_buffer = buf + i;
|
||||
ESP_ERROR_CHECK(spi_device_polling_transmit(spi, &trans));
|
||||
}
|
||||
spi_device_release_bus(spi);
|
||||
SPI_PARAM_UNLOCK();
|
||||
}
|
||||
22
lib/CMT2300a/cmt_spi3.h
Normal file
22
lib/CMT2300a/cmt_spi3.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef __CMT_SPI3_H
|
||||
#define __CMT_SPI3_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void cmt_spi3_init(const int8_t pin_sdio, const int8_t pin_clk, const int8_t pin_cs, const int8_t pin_fcs, const int32_t spi_speed);
|
||||
|
||||
void cmt_spi3_write(const uint8_t addr, const uint8_t dat);
|
||||
uint8_t cmt_spi3_read(const uint8_t addr);
|
||||
|
||||
void cmt_spi3_write_fifo(const uint8_t* p_buf, const uint16_t len);
|
||||
void cmt_spi3_read_fifo(uint8_t* p_buf, const uint16_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
57
lib/CpuTemperature/src/CpuTemperature.cpp
Normal file
57
lib/CpuTemperature/src/CpuTemperature.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) 2024 Thomas Basler and others
|
||||
*/
|
||||
|
||||
#include "CpuTemperature.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||
// there is no official API available on the original ESP32
|
||||
extern "C" {
|
||||
uint8_t temprature_sens_read();
|
||||
}
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
#include "driver/temp_sensor.h"
|
||||
#endif
|
||||
|
||||
CpuTemperatureClass CpuTemperature;
|
||||
|
||||
float CpuTemperatureClass::read()
|
||||
{
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
// Disabling temperature reading for ESP32-S2 models as it might lead to WDT resets.
|
||||
// See: https://github.com/espressif/esp-idf/issues/8088
|
||||
return NAN;
|
||||
#endif
|
||||
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
|
||||
float temperature = NAN;
|
||||
bool success = false;
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||
uint8_t raw = temprature_sens_read();
|
||||
ESP_LOGV(TAG, "Raw temperature value: %d", raw);
|
||||
temperature = (raw - 32) / 1.8f;
|
||||
success = (raw != 128);
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
temp_sensor_config_t tsens = TSENS_CONFIG_DEFAULT();
|
||||
temp_sensor_set_config(tsens);
|
||||
temp_sensor_start();
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32S3) && (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 4, 3))
|
||||
#error \
|
||||
"ESP32-S3 internal temperature sensor requires ESP IDF V4.4.3 or higher. See https://github.com/esphome/issues/issues/4271"
|
||||
#endif
|
||||
esp_err_t result = temp_sensor_read_celsius(&temperature);
|
||||
temp_sensor_stop();
|
||||
success = (result == ESP_OK);
|
||||
#endif
|
||||
|
||||
if (success && std::isfinite(temperature)) {
|
||||
return temperature;
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Ignoring invalid temperature (success=%d, value=%.1f)", success, temperature);
|
||||
return NAN;
|
||||
}
|
||||
}
|
||||
14
lib/CpuTemperature/src/CpuTemperature.h
Normal file
14
lib/CpuTemperature/src/CpuTemperature.h
Normal file
@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
|
||||
class CpuTemperatureClass {
|
||||
public:
|
||||
float read();
|
||||
|
||||
private:
|
||||
std::mutex _mutex;
|
||||
};
|
||||
|
||||
extern CpuTemperatureClass CpuTemperature;
|
||||
3
lib/Frozen/AUTHORS
Normal file
3
lib/Frozen/AUTHORS
Normal file
@ -0,0 +1,3 @@
|
||||
serge-sans-paille <sguelton@quarkslab.com>
|
||||
Jérôme Dumesnil <jerome.dumesnil@gmail.com>
|
||||
Chris Beck <chbeck@tesla.com>
|
||||
202
lib/Frozen/LICENSE
Normal file
202
lib/Frozen/LICENSE
Normal file
@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2017 Quarkslab
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
245
lib/Frozen/README.rst
Normal file
245
lib/Frozen/README.rst
Normal file
@ -0,0 +1,245 @@
|
||||
Frozen
|
||||
######
|
||||
|
||||
.. image:: https://travis-ci.org/serge-sans-paille/frozen.svg?branch=master
|
||||
:target: https://travis-ci.org/serge-sans-paille/frozen
|
||||
|
||||
Header-only library that provides 0 cost initialization for immutable containers, fixed-size containers, and various algorithms.
|
||||
|
||||
Frozen provides:
|
||||
|
||||
- immutable (a.k.a. frozen), ``constexpr``-compatible versions of ``std::set``,
|
||||
``std::unordered_set``, ``std::map`` and ``std::unordered_map``.
|
||||
|
||||
- fixed-capacity, ``constinit``-compatible versions of ``std::map`` and
|
||||
``std::unordered_map`` with immutable, compile-time selected keys mapped
|
||||
to mutable values.
|
||||
|
||||
- 0-cost initialization version of ``std::search`` for frozen needles using
|
||||
Boyer-Moore or Knuth-Morris-Pratt algorithms.
|
||||
|
||||
|
||||
The ``unordered_*`` containers are guaranteed *perfect* (a.k.a. no hash
|
||||
collision) and the extra storage is linear with respect to the number of keys.
|
||||
|
||||
Once initialized, the container keys cannot be updated, and in exchange, lookups
|
||||
are faster. And initialization is free when ``constexpr`` or ``constinit`` is
|
||||
used :-).
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Just copy the ``include/frozen`` directory somewhere and points to it using the ``-I`` flag. Alternatively, using CMake:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
> mkdir build
|
||||
> cd build
|
||||
> cmake -D CMAKE_BUILD_TYPE=Release ..
|
||||
> make install
|
||||
|
||||
|
||||
Installation via CMake populates configuration files into the ``/usr/local/share``
|
||||
directory which can be consumed by CMake's ``find_package`` instrinsic function.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
A C++ compiler that supports C++14. Clang version 5 is a good pick, GCC version
|
||||
6 lags behind in terms of ``constexpr`` compilation time (At least on my
|
||||
setup), but compiles correctly. Visual Studio 2017 also works correctly!
|
||||
|
||||
Note that gcc 5 isn't supported. (Here's an `old compat branch`_ where a small amount of stuff was ported.)
|
||||
|
||||
.. _old compat branch: https://github.com/cbeck88/frozen/tree/gcc5-support
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Compiled with ``-std=c++14`` flag:
|
||||
|
||||
.. code:: C++
|
||||
|
||||
#include <frozen/set.h>
|
||||
|
||||
constexpr frozen::set<int, 4> some_ints = {1,2,3,5};
|
||||
|
||||
constexpr bool letitgo = some_ints.count(8);
|
||||
|
||||
extern int n;
|
||||
bool letitgoooooo = some_ints.count(n);
|
||||
|
||||
|
||||
As the constructor and some methods are ``constexpr``, it's also possible to write weird stuff like:
|
||||
|
||||
.. code:: C++
|
||||
|
||||
#include <frozen/set.h>
|
||||
|
||||
template<std::size_t N>
|
||||
std::enable_if_t< frozen::set<int, 3>{{1,11,111}}.count(N), int> foo();
|
||||
|
||||
String support is built-in:
|
||||
|
||||
.. code:: C++
|
||||
|
||||
#include <frozen/unordered_map.h>
|
||||
#include <frozen/string.h>
|
||||
|
||||
constexpr frozen::unordered_map<frozen::string, int, 2> olaf = {
|
||||
{"19", 19},
|
||||
{"31", 31},
|
||||
};
|
||||
constexpr auto val = olaf.at("19");
|
||||
|
||||
The associative containers have different functionality with and without ``constexpr``.
|
||||
With ``constexpr``, frozen maps have immutable keys and values. Without ``constexpr``, the
|
||||
values can be updated in runtime (the keys, however, remain immutable):
|
||||
|
||||
.. code:: C++
|
||||
|
||||
|
||||
#include <frozen/unordered_map.h>
|
||||
#include <frozen/string.h>
|
||||
|
||||
static constinit frozen::unordered_map<frozen::string, frozen::string, 2> voice = {
|
||||
{"Anna", "???"},
|
||||
{"Elsa", "???"}
|
||||
};
|
||||
|
||||
int main() {
|
||||
voice.at("Anna") = "Kristen";
|
||||
voice.at("Elsa") = "Idina";
|
||||
}
|
||||
|
||||
You may also prefer a slightly more DRY initialization syntax:
|
||||
|
||||
.. code:: C++
|
||||
|
||||
#include <frozen/set.h>
|
||||
|
||||
constexpr auto some_ints = frozen::make_set<int>({1,2,3,5});
|
||||
|
||||
There are similar ``make_X`` functions for all frozen containers.
|
||||
|
||||
Exception Handling
|
||||
------------------
|
||||
|
||||
For compatibility with STL's API, Frozen may eventually throw exceptions, as in
|
||||
``frozen::map::at``. If you build your code without exception support, or
|
||||
define the ``FROZEN_NO_EXCEPTIONS`` macro variable, they will be turned into an
|
||||
``std::abort``.
|
||||
|
||||
Extending
|
||||
---------
|
||||
|
||||
Just like the regular C++14 container, you can specialize the hash function,
|
||||
the key equality comparator for ``unordered_*`` containers, and the comparison
|
||||
functions for the ordered version.
|
||||
|
||||
It's also possible to specialize the ``frozen::elsa`` structure used for
|
||||
hashing. Note that unlike `std::hash`, the hasher also takes a seed in addition
|
||||
to the value being hashed.
|
||||
|
||||
.. code:: C++
|
||||
|
||||
template <class T> struct elsa {
|
||||
// in case of collisions, different seeds are tried
|
||||
constexpr std::size_t operator()(T const &value, std::size_t seed) const;
|
||||
};
|
||||
|
||||
Ideally, the hash function should have nice statistical properties like *pairwise-independence*:
|
||||
|
||||
If ``x`` and ``y`` are different values, the chance that ``elsa<T>{}(x, seed) == elsa<T>{}(y, seed)``
|
||||
should be very low for a random value of ``seed``.
|
||||
|
||||
Note that frozen always ultimately produces a perfect hash function, and you will always have ``O(1)``
|
||||
lookup with frozen. It's just that if the input hasher performs poorly, the search will take longer and
|
||||
your project will take longer to compile.
|
||||
|
||||
Troubleshooting
|
||||
---------------
|
||||
|
||||
If you hit a message like this:
|
||||
|
||||
.. code:: none
|
||||
|
||||
[...]
|
||||
note: constexpr evaluation hit maximum step limit; possible infinite loop?
|
||||
|
||||
Then either you've got a very big container and you should increase Clang's
|
||||
thresholds, using ``-fconstexpr-steps=1000000000`` for instance, or the hash
|
||||
functions used by frozen do not suit your data, and you should change them, as
|
||||
in the following:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
struct olaf {
|
||||
constexpr std::size_t operator()(frozen::string const &value, std::size_t seed) const { return seed ^ value[0];}
|
||||
};
|
||||
|
||||
constexpr frozen::unordered_set<frozen::string, 2, olaf/*custom hash*/> hans = { "a", "b" };
|
||||
|
||||
Tests and Benchmarks
|
||||
--------------------
|
||||
|
||||
Using hand-written Makefiles crafted with love and care:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
> # running tests
|
||||
> make -C tests check
|
||||
> # running benchmarks
|
||||
> make -C benchmarks GOOGLE_BENCHMARK_PREFIX=<GOOGLE-BENCHMARK_INSTALL_DIR>
|
||||
|
||||
Using CMake to generate a static configuration build system:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
> mkdir build
|
||||
> cd build
|
||||
> cmake -D CMAKE_BUILD_TYPE=Release \
|
||||
-D frozen.benchmark=ON \
|
||||
-G <"Unix Makefiles" or "Ninja"> ..
|
||||
> # building the tests and benchmarks...
|
||||
> make # ... with make
|
||||
> ninja # ... with ninja
|
||||
> cmake --build . # ... with cmake
|
||||
> # running the tests...
|
||||
> make test # ... with make
|
||||
> ninja test # ... with ninja
|
||||
> cmake --build . --target test # ... with cmake
|
||||
> ctest # ... with ctest
|
||||
> # running the benchmarks...
|
||||
> make benchmark # ... with make
|
||||
> ninja benchmark # ... with ninja
|
||||
> cmake --build . --target benchmark # ... with cmake
|
||||
|
||||
Using CMake to generate an IDE build system with test and benchmark targets
|
||||
|
||||
.. code:: sh
|
||||
|
||||
> mkdir build
|
||||
> cd build
|
||||
> cmake -D frozen.benchmark=ON -G <"Xcode" or "Visual Studio 15 2017"> ..
|
||||
> # using cmake to drive the IDE build, test, and benchmark
|
||||
> cmake --build . --config Release
|
||||
> cmake --build . --target test
|
||||
> cmake --build . --target benchmark
|
||||
|
||||
|
||||
Credits
|
||||
-------
|
||||
|
||||
The perfect hashing is strongly inspired by the blog post `Throw away the keys:
|
||||
Easy, Minimal Perfect Hashing <http://stevehanov.ca/blog/index.php?id=119>`_.
|
||||
|
||||
Thanks a lot to Jérôme Dumesnil for his high-quality reviews, and to Chris Beck
|
||||
for his contributions on perfect hashing.
|
||||
|
||||
Contact
|
||||
-------
|
||||
|
||||
Serge sans Paille ``<serge.guelton@telecom-bretagne.eu>``
|
||||
|
||||
12
lib/Frozen/frozen/CMakeLists.txt
Normal file
12
lib/Frozen/frozen/CMakeLists.txt
Normal file
@ -0,0 +1,12 @@
|
||||
target_sources(frozen-headers INTERFACE
|
||||
"${prefix}/frozen/algorithm.h"
|
||||
"${prefix}/frozen/map.h"
|
||||
"${prefix}/frozen/random.h"
|
||||
"${prefix}/frozen/set.h"
|
||||
"${prefix}/frozen/string.h"
|
||||
"${prefix}/frozen/unordered_map.h"
|
||||
"${prefix}/frozen/unordered_set.h"
|
||||
"${prefix}/frozen/bits/algorithms.h"
|
||||
"${prefix}/frozen/bits/basic_types.h"
|
||||
"${prefix}/frozen/bits/elsa.h"
|
||||
"${prefix}/frozen/bits/pmh.h")
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user