This commit is contained in:
Milos Kozak 2023-09-11 10:54:19 +02:00
commit 23428f5dbc
321 changed files with 4395 additions and 2262 deletions

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<circle fill="#555555" cx="12" cy="12" r="12"/>
<path fill="#B7B7B7" d="M16.407,2.131c0.068-0.14,0.269-0.181,0.449-0.093l0,0c0.18,0.088,0.271,0.272,0.203,0.412l-4.738,9.696
c-0.068,0.14-0.269,0.181-0.449,0.093l0,0c-0.18-0.088-0.271-0.272-0.203-0.412L16.407,2.131z"/>
<path fill="#B7B7B7" d="M18.097,9.416c0.147-0.052,0.325,0.076,0.399,0.285l0,0c0.074,0.209,0.014,0.42-0.132,0.472l-6.224,2.193
c-0.147,0.052-0.325-0.076-0.399-0.285l0,0c-0.074-0.209-0.014-0.42,0.132-0.472L18.097,9.416z"/>
<g>
<circle fill="#FFFFFF" cx="3.813" cy="12" r="2.414"/>
<circle fill="#FFFFFF" cx="20.188" cy="12" r="2.414"/>
<circle fill="#FFFFFF" cx="12" cy="20.188" r="2.414"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<circle fill="#555555" cx="12" cy="12" r="12"/>
</g>
<g>
<g>
<path fill="#84C441" d="M7.346,15.22c0.621,0,1.211,0.202,1.707,0.584l0.401-0.519c-0.611-0.472-1.34-0.721-2.108-0.721
c-1.903,0-3.451,1.546-3.455,3.448H3.359l0.86,1.49l0.86-1.49H4.547C4.551,16.472,5.805,15.22,7.346,15.22z"/>
</g>
<g>
<path fill="#84C441" d="M11.333,18.024l-0.86-1.49l-0.86,1.49h0.532c-0.003,1.541-1.257,2.794-2.798,2.794
c-0.621,0-1.211-0.202-1.707-0.584l-0.401,0.519c0.611,0.472,1.34,0.721,2.108,0.721c1.903,0,3.452-1.547,3.454-3.45H11.333z"/>
</g>
</g>
<g>
<path fill="#84C441" d="M19.268,20.276c0.907-0.978,2.043-2.145,2.834-2.662h0.001l-0.001,0l0.001,0h-0.001
c-0.791-0.517-1.927-1.684-2.834-2.662l-0.913,0.664c0,0,0.706,0.791,1.367,1.471h-7.581v1.055h7.582
c-0.661,0.68-1.367,1.471-1.367,1.471L19.268,20.276z"/>
</g>
<g>
<path fill="#F99D1C" d="M2.62,12.053l0.687,0.217c-0.105,0.383-0.281,0.668-0.525,0.852c-0.245,0.186-0.556,0.28-0.932,0.28
c-0.466,0-0.849-0.159-1.148-0.478c-0.3-0.318-0.45-0.754-0.45-1.306c0-0.583,0.151-1.036,0.453-1.36
c0.301-0.322,0.698-0.484,1.189-0.484c0.429,0,0.777,0.127,1.046,0.38c0.159,0.15,0.279,0.366,0.359,0.646l-0.701,0.167
c-0.042-0.181-0.128-0.325-0.26-0.43c-0.132-0.105-0.291-0.158-0.48-0.158c-0.26,0-0.471,0.092-0.633,0.28
c-0.162,0.186-0.243,0.489-0.243,0.906c0,0.444,0.08,0.76,0.239,0.947c0.159,0.189,0.367,0.282,0.622,0.282
c0.188,0,0.35-0.059,0.485-0.18C2.464,12.498,2.561,12.31,2.62,12.053z"/>
<path fill="#F99D1C" d="M4.412,11.577l-0.61-0.11c0.069-0.245,0.187-0.428,0.354-0.546c0.168-0.118,0.416-0.177,0.746-0.177
c0.3,0,0.523,0.036,0.67,0.107c0.146,0.072,0.25,0.162,0.31,0.271c0.06,0.109,0.089,0.309,0.089,0.601l-0.007,0.786
c0,0.223,0.011,0.388,0.032,0.493c0.022,0.107,0.062,0.221,0.121,0.341H5.453c-0.018-0.045-0.039-0.11-0.065-0.199
c-0.011-0.04-0.019-0.065-0.024-0.078c-0.115,0.112-0.238,0.195-0.368,0.252C4.865,13.372,4.726,13.4,4.578,13.4
c-0.262,0-0.468-0.072-0.619-0.213c-0.151-0.143-0.226-0.321-0.226-0.538c0-0.144,0.034-0.272,0.103-0.384
C3.904,12.152,4,12.066,4.124,12.006c0.124-0.059,0.302-0.112,0.535-0.157c0.315-0.059,0.532-0.114,0.653-0.164v-0.068
c0-0.128-0.032-0.221-0.096-0.276c-0.064-0.055-0.184-0.082-0.361-0.082c-0.119,0-0.213,0.023-0.28,0.071
C4.508,11.377,4.454,11.459,4.412,11.577z M5.312,12.123c-0.086,0.028-0.223,0.063-0.41,0.103c-0.186,0.04-0.308,0.078-0.366,0.117
c-0.087,0.063-0.132,0.141-0.132,0.238c0,0.094,0.035,0.175,0.105,0.244c0.071,0.068,0.16,0.103,0.268,0.103
c0.121,0,0.237-0.04,0.347-0.119c0.082-0.062,0.135-0.135,0.16-0.223c0.017-0.056,0.026-0.167,0.026-0.327V12.123z"/>
<path fill="#F99D1C" d="M7.278,13.342H6.606v-2.541h0.625v0.361c0.107-0.171,0.203-0.282,0.288-0.336
c0.085-0.055,0.182-0.082,0.291-0.082c0.153,0,0.3,0.042,0.442,0.127l-0.208,0.587c-0.114-0.074-0.219-0.11-0.316-0.11
c-0.094,0-0.174,0.026-0.239,0.077c-0.065,0.053-0.117,0.146-0.154,0.281c-0.037,0.136-0.056,0.42-0.056,0.852V13.342z"/>
<path fill="#F99D1C" d="M8.512,13.342V9.835h0.672v1.263c0.207-0.236,0.453-0.354,0.737-0.354c0.309,0,0.566,0.113,0.768,0.336
c0.203,0.225,0.304,0.546,0.304,0.965c0,0.434-0.103,0.768-0.31,1.003c-0.207,0.234-0.457,0.352-0.752,0.352
c-0.145,0-0.288-0.037-0.429-0.109c-0.141-0.073-0.263-0.18-0.365-0.322v0.374H8.512z M9.18,12.018
c0,0.263,0.041,0.457,0.125,0.583c0.116,0.178,0.271,0.268,0.464,0.268c0.148,0,0.275-0.063,0.379-0.19
c0.105-0.127,0.157-0.326,0.157-0.6c0-0.29-0.053-0.499-0.158-0.628c-0.105-0.128-0.239-0.193-0.404-0.193
c-0.161,0-0.295,0.063-0.402,0.187C9.233,11.572,9.18,11.762,9.18,12.018z"/>
<path fill="#F99D1C" d="M11.297,12.617l0.675-0.103c0.029,0.131,0.087,0.23,0.175,0.298c0.087,0.068,0.211,0.101,0.368,0.101
c0.174,0,0.304-0.031,0.392-0.095c0.059-0.045,0.089-0.104,0.089-0.18c0-0.051-0.016-0.094-0.048-0.127
c-0.033-0.031-0.108-0.06-0.225-0.089c-0.542-0.119-0.886-0.229-1.031-0.327c-0.201-0.137-0.302-0.327-0.302-0.571
c0-0.221,0.087-0.406,0.261-0.556c0.174-0.149,0.444-0.225,0.809-0.225c0.348,0,0.606,0.056,0.775,0.171
c0.169,0.113,0.285,0.28,0.349,0.502l-0.634,0.117c-0.027-0.099-0.078-0.175-0.154-0.227c-0.076-0.053-0.184-0.078-0.324-0.078
c-0.177,0-0.304,0.024-0.381,0.073c-0.051,0.036-0.076,0.081-0.076,0.137c0,0.048,0.022,0.089,0.067,0.122
c0.061,0.045,0.27,0.108,0.628,0.189c0.358,0.081,0.608,0.181,0.75,0.299c0.14,0.119,0.211,0.286,0.211,0.499
c0,0.234-0.098,0.434-0.292,0.601c-0.194,0.168-0.482,0.252-0.863,0.252c-0.346,0-0.62-0.071-0.822-0.211
C11.491,13.048,11.359,12.858,11.297,12.617z"/>
</g>
<g>
<path fill="#40C7F4" d="M15.147,13.375V9.802h0.721v3.572H15.147z"/>
<path fill="#40C7F4" d="M16.409,11.611c0-0.364,0.054-0.67,0.163-0.917c0.081-0.182,0.192-0.345,0.332-0.49
c0.14-0.144,0.294-0.251,0.462-0.32c0.222-0.094,0.48-0.141,0.77-0.141c0.526,0,0.948,0.163,1.263,0.489
c0.316,0.327,0.475,0.781,0.475,1.363c0,0.577-0.157,1.028-0.471,1.353s-0.732,0.489-1.258,0.489c-0.531,0-0.953-0.162-1.267-0.486
C16.566,12.626,16.409,12.18,16.409,11.611z M17.152,11.586c0,0.405,0.094,0.711,0.28,0.921c0.187,0.208,0.425,0.313,0.713,0.313
c0.286,0,0.523-0.103,0.707-0.31c0.184-0.208,0.276-0.518,0.276-0.932c0-0.409-0.089-0.715-0.269-0.917
c-0.179-0.201-0.417-0.302-0.714-0.302c-0.298,0-0.537,0.102-0.719,0.306C17.243,10.868,17.152,11.176,17.152,11.586z"/>
<path fill="#40C7F4" d="M20.44,9.802h1.427c0.284,0,0.494,0.012,0.633,0.035c0.139,0.024,0.263,0.073,0.373,0.148
s0.201,0.174,0.275,0.298c0.073,0.124,0.11,0.264,0.11,0.418c0,0.167-0.046,0.32-0.136,0.46s-0.212,0.245-0.366,0.314
c0.217,0.064,0.384,0.171,0.502,0.324c0.116,0.153,0.175,0.332,0.175,0.539c0,0.162-0.038,0.32-0.114,0.473
c-0.076,0.154-0.179,0.277-0.31,0.369c-0.131,0.092-0.292,0.148-0.483,0.169c-0.12,0.013-0.411,0.022-0.871,0.025H20.44V9.802z
M21.161,10.397v0.826h0.473c0.28,0,0.455-0.005,0.523-0.013c0.124-0.014,0.221-0.058,0.292-0.128
c0.071-0.071,0.106-0.163,0.106-0.279c0-0.111-0.03-0.2-0.092-0.269c-0.061-0.069-0.152-0.111-0.272-0.126
c-0.071-0.008-0.277-0.012-0.616-0.012H21.161z M21.161,11.818v0.956h0.668c0.259,0,0.424-0.008,0.494-0.022
c0.107-0.02,0.195-0.067,0.262-0.143c0.068-0.076,0.102-0.177,0.102-0.303c0-0.107-0.026-0.199-0.078-0.273
s-0.127-0.129-0.225-0.163c-0.099-0.034-0.313-0.051-0.641-0.051H21.161z"/>
</g>
<g>
<path fill="#DEDDDD" d="M8.21,8.513H7.142V4.488c-0.39,0.365-0.85,0.635-1.38,0.81V4.329C6.041,4.238,6.344,4.065,6.67,3.81
s0.551-0.552,0.673-0.891H8.21V8.513z"/>
<path fill="#DEDDDD" d="M11.9,8.513V7.392H9.619V6.457l2.418-3.538h0.896v3.535h0.692v0.939h-0.692v1.121H11.9z M11.9,6.453V4.549
l-1.281,1.904H11.9z"/>
<path fill="#DEDDDD" d="M16.228,8.513V7.392h-2.28V6.457l2.417-3.538h0.897v3.535h0.692v0.939h-0.692v1.121H16.228z M16.228,6.453
V4.549l-1.281,1.904H16.228z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7 KiB

81
_docs/icons/ic_graph.svg Normal file
View file

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<circle fill="#555555" cx="12" cy="12" r="12"/>
<path fill="#C8C8C8" d="M23.216,7.763v8.474c0.029-0.078,0.058-0.156,0.086-0.235V7.998C23.274,7.919,23.245,7.841,23.216,7.763z"/>
<rect x="16.993" y="1.86" fill="#C8C8C8" width="0.428" height="17.214"/>
<path fill="#C8C8C8" d="M23.045,16.696c0.163-0.382,0.305-0.774,0.428-1.175V8.479c-0.123-0.401-0.265-0.793-0.428-1.175V16.696z"/>
<path fill="#C8C8C8" d="M23.045,16.696c0.163-0.382,0.305-0.774,0.428-1.175V8.479c-0.123-0.401-0.265-0.793-0.428-1.175V16.696z"/>
<path fill="#C8C8C8" d="M4.889,2.35v16.725h0.429V2.033C5.17,2.132,5.032,2.244,4.889,2.35z"/>
<rect x="10.942" y="1.86" fill="#C8C8C8" width="0.427" height="17.214"/>
<g>
<path fill="#D1D2D3" d="M4.491,20.319c0-0.222,0.023-0.399,0.069-0.534s0.114-0.239,0.203-0.313c0.09-0.073,0.204-0.109,0.34-0.109
c0.101,0,0.189,0.021,0.265,0.061c0.076,0.04,0.139,0.099,0.188,0.175c0.05,0.076,0.088,0.169,0.117,0.278s0.042,0.257,0.042,0.442
c0,0.22-0.023,0.396-0.068,0.531c-0.046,0.135-0.113,0.239-0.203,0.313c-0.09,0.073-0.204,0.11-0.341,0.11
c-0.181,0-0.323-0.065-0.426-0.194C4.553,20.925,4.491,20.671,4.491,20.319z M4.728,20.319c0,0.308,0.036,0.512,0.108,0.613
c0.072,0.102,0.161,0.152,0.267,0.152s0.195-0.051,0.267-0.153c0.072-0.102,0.108-0.306,0.108-0.612
c0-0.308-0.036-0.513-0.108-0.614c-0.072-0.101-0.162-0.151-0.269-0.151c-0.106,0-0.19,0.044-0.254,0.134
C4.768,19.802,4.728,20.012,4.728,20.319z"/>
<path fill="#D1D2D3" d="M10.791,21.242h-0.2v-1.464c-0.048,0.053-0.111,0.105-0.189,0.158s-0.148,0.092-0.21,0.118v-0.222
c0.112-0.061,0.209-0.134,0.293-0.22c0.084-0.086,0.143-0.169,0.178-0.25h0.129V21.242z"/>
<path fill="#D1D2D3" d="M11.886,21.242h-0.2v-1.464c-0.048,0.053-0.111,0.105-0.189,0.158s-0.148,0.092-0.21,0.118v-0.222
c0.112-0.061,0.209-0.134,0.293-0.22c0.084-0.086,0.143-0.169,0.178-0.25h0.129V21.242z"/>
<path fill="#D1D2D3" d="M16.768,21.242h-0.199v-1.464c-0.048,0.053-0.111,0.105-0.189,0.158s-0.148,0.092-0.21,0.118v-0.222
c0.111-0.061,0.209-0.134,0.293-0.22c0.083-0.086,0.143-0.169,0.178-0.25h0.128V21.242z"/>
<path fill="#D1D2D3" d="M18.331,21.021v0.221h-1.076c-0.001-0.056,0.007-0.108,0.023-0.159c0.027-0.085,0.071-0.168,0.132-0.249
c0.061-0.082,0.147-0.177,0.262-0.283c0.177-0.167,0.296-0.3,0.358-0.396c0.063-0.098,0.094-0.189,0.094-0.276
c0-0.092-0.028-0.168-0.085-0.23s-0.131-0.094-0.222-0.094c-0.097,0-0.174,0.033-0.231,0.1s-0.087,0.158-0.088,0.275l-0.205-0.024
c0.015-0.176,0.067-0.311,0.159-0.402c0.092-0.093,0.215-0.139,0.369-0.139c0.156,0,0.28,0.05,0.371,0.149s0.137,0.223,0.137,0.37
c0,0.075-0.014,0.148-0.04,0.221s-0.071,0.148-0.133,0.229s-0.164,0.189-0.308,0.329c-0.12,0.116-0.197,0.194-0.231,0.235
c-0.034,0.042-0.063,0.083-0.084,0.125H18.331z"/>
</g>
<path fill="#3954A3" d="M1.54,6.129v1.763H0.978v2.146H0.174c-0.037,0.227-0.08,0.452-0.104,0.684h1.591V8.576h0.563V5.058
C1.978,5.403,1.749,5.759,1.54,6.129z"/>
<path fill="#3954A3" d="M10,6.951H7.134v8.574H5.752v-3.9H4.38V3.519L3.467,3.568C3.265,3.772,3.074,3.987,2.887,4.205h0.809v8.104
h1.373v3.898h2.749V7.635h1.499v9.243h8.115v-0.682H10V6.951z"/>
<path fill="#D52028" d="M0.465,15.277h23.071c0.064-0.225,0.124-0.451,0.175-0.682H0.289C0.34,14.826,0.401,15.052,0.465,15.277z"/>
<path fill="#F5EB11" d="M0.737,7.892C0.654,8.118,0.571,8.344,0.502,8.576h22.995c-0.069-0.232-0.152-0.458-0.234-0.684H0.737z"/>
<path fill="#DFE335" d="M23.968,11.371l-1.383-0.288c-0.938-0.192-1.678-0.345-2.543-0.761l-0.394-0.185
c-0.285-0.131-0.58-0.267-0.83-0.415c-0.089-0.052-0.187-0.129-0.322-0.236c-0.352-0.275-0.751-0.588-1.258-0.595l-0.3-0.003
L16.926,9.77l0.301,0.005c0.207,0.003,0.49,0.224,0.743,0.421c0.14,0.109,0.271,0.211,0.399,0.287c0.28,0.165,0.6,0.313,0.911,0.457
l0.379,0.177c0.964,0.465,1.816,0.64,2.803,0.842l1.524,0.32C23.988,12.185,24,12.094,24,12C24,11.788,23.979,11.581,23.968,11.371z
"/>
<path fill="#3496CE" d="M23.803,9.889c-0.053-0.296-0.119-0.586-0.193-0.874c-1.782,0.162-3.987,0.269-6.071-0.141l-0.295-0.058
l-0.168,0.867l0.294,0.057C19.59,10.178,21.938,10.061,23.803,9.889z"/>
<path fill="#56C5CD" d="M21.556,13.262c-0.179-0.132-0.353-0.28-0.537-0.436c-0.412-0.351-0.84-0.714-1.268-0.882l-0.351-0.366
c-0.732-0.757-1.56-1.615-1.713-2.413l-0.058-0.3l-0.996,0.096l0.058,0.301c0.203,1.054,1.138,2.021,1.963,2.876l0.398,0.408
l0.138,0.09c0.416,0.185,0.795,0.508,1.163,0.82c0.19,0.161,0.386,0.327,0.583,0.472c0.778,0.574,1.588,1.017,2.347,1.408
l0.21,0.113c0.088-0.293,0.164-0.591,0.229-0.892C23.011,14.191,22.261,13.781,21.556,13.262z"/>
<g>
<ellipse fill="#EC9F23" cx="3.673" cy="15.784" rx="0.921" ry="0.848"/>
</g>
<g>
<ellipse fill="#29ABE2" cx="5.104" cy="16.549" rx="0.921" ry="0.848"/>
</g>
<path fill="#7FC242" d="M13.364,9.36c-0.486,0.284-1.095,0.35-1.74,0.419c-0.736,0.079-1.497,0.161-2.087,0.594
c-0.313,0.229-0.605,0.458-0.893,0.684C8.078,11.5,7.543,11.918,6.897,12.31c-0.169,0.103-0.306,0.27-0.438,0.432
c-0.162,0.198-0.315,0.387-0.501,0.433c-0.297,0.076-0.883-0.014-1.354-0.083c-0.232-0.034-0.446-0.066-0.608-0.078
c-1.145-0.082-2.571-0.188-3.874-0.053c-0.028,0.003-0.046,0.009-0.073,0.012c0.008,0.094,0.008,0.19,0.017,0.283
c0.031-0.004,0.052-0.011,0.084-0.014c1.277-0.129,2.69-0.027,3.824,0.055c0.157,0.011,0.364,0.042,0.587,0.075
c0.522,0.077,1.114,0.164,1.464,0.078c0.277-0.069,0.468-0.303,0.652-0.529c0.123-0.149,0.238-0.291,0.366-0.368
c0.66-0.401,1.201-0.824,1.773-1.273c0.286-0.223,0.576-0.45,0.886-0.678c0.529-0.388,1.251-0.466,1.95-0.541
c0.646-0.069,1.314-0.141,1.853-0.456c1.377-0.805,2.205-0.816,3.847-0.448l0.063-0.276C15.694,8.494,14.823,8.509,13.364,9.36z"/>
<path fill="#DD9D27" d="M22.332,7.527c0.141-0.082,0.281-0.169,0.422-0.263c0.076-0.05,0.126-0.105,0.196-0.158
C22.826,6.83,22.7,6.555,22.557,6.29c-0.097,0.081-0.18,0.163-0.291,0.237c-0.124,0.082-0.249,0.159-0.374,0.232
c-0.47,0.275-0.959,0.501-1.391,0.7c-0.444,0.204-0.902,0.415-1.365,0.686C18.943,8.258,18.749,8.381,18.63,8.5
c-0.348-0.051-0.776,0.083-1.174,0.207c-0.13,0.041-0.251,0.078-0.328,0.091l-0.296,0.049l0.144,0.872l0.297-0.049
c0.12-0.021,0.28-0.068,0.47-0.127c0.435-0.135,0.71-0.181,0.854-0.127l0.247-0.013l0.103-0.076
c0.211-0.157,0.424-0.294,0.635-0.418c0.427-0.25,0.871-0.455,1.318-0.661C21.34,8.045,21.838,7.816,22.332,7.527z"/>
<path fill="#7FC242" d="M15.44,8.422c-0.822,0-1.537,0.221-2.466,0.764c-0.432,0.252-1.011,0.314-1.625,0.38
c-0.774,0.083-1.575,0.169-2.229,0.65c-0.307,0.225-0.593,0.449-0.9,0.689c-0.557,0.437-1.083,0.849-1.717,1.233
c-0.212,0.128-0.366,0.317-0.517,0.501c-0.111,0.137-0.25,0.307-0.342,0.329c-0.034,0.009-0.101,0.02-0.221,0.02
c-0.269,0-0.634-0.053-1.05-0.114c-0.226-0.033-0.434-0.063-0.663-0.08c-0.744-0.053-1.586-0.114-2.446-0.114
c-0.445,0-0.834,0.021-1.226,0.057c0.018,0.295,0.045,0.586,0.084,0.875c0.349-0.029,0.719-0.048,1.139-0.048
c0.851,0,1.69,0.061,2.455,0.115c0.145,0.011,0.332,0.039,0.579,0.075C4.66,13.81,5.075,13.87,5.423,13.87
c0.17,0,0.313-0.014,0.438-0.044c0.375-0.094,0.608-0.38,0.813-0.633c0.101-0.122,0.204-0.249,0.287-0.299
c0.679-0.412,1.235-0.848,1.828-1.313c0.275-0.215,0.555-0.433,0.853-0.653c0.463-0.339,1.144-0.413,1.805-0.484
c0.677-0.073,1.376-0.147,1.972-0.495c0.778-0.455,1.367-0.64,2.033-0.64c0.412,0,0.89,0.067,1.597,0.226L17.341,9.6l0.194-0.861
l-0.293-0.066C16.46,8.497,15.921,8.422,15.44,8.422z"/>
</svg>

After

Width:  |  Height:  |  Size: 7.5 KiB

View file

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<circle fill="#555555" cx="12" cy="12" r="12"/>
<g>
<path fill="#212121" d="M20.398,4.993c0,0.917-0.743,1.66-1.66,1.66H5.288c-0.917,0-1.66-0.743-1.66-1.66l0,0
c0-0.917,0.743-1.66,1.66-1.66h13.451C19.655,3.333,20.398,4.076,20.398,4.993L20.398,4.993z"/>
<circle fill="#80C564" cx="5.5" cy="4.993" r="1.354"/>
<path fill="#FFFFFF" d="M14.875,4.625c0,0.368-0.298,0.667-0.667,0.667H8.521c-0.368,0-0.667-0.298-0.667-0.667l0,0
c0-0.368,0.298-0.667,0.667-0.667h5.688C14.577,3.958,14.875,4.257,14.875,4.625L14.875,4.625z"/>
</g>
<g>
<path fill="#212121" d="M23.034,10.49c0,1.45-1.175,2.625-2.625,2.625H3.617c-1.45,0-2.625-1.175-2.625-2.625l0,0
c0-1.45,1.175-2.625,2.625-2.625h16.792C21.859,7.865,23.034,9.04,23.034,10.49L23.034,10.49z"/>
<circle fill="#FBAD18" cx="3.646" cy="10.49" r="1.854"/>
<path fill="#FFFFFF" d="M15.75,10.146c0,0.472-0.382,0.854-0.854,0.854h-7.25c-0.472,0-0.854-0.382-0.854-0.854l0,0
c0-0.472,0.382-0.854,0.854-0.854h7.25C15.368,9.292,15.75,9.674,15.75,10.146L15.75,10.146z"/>
</g>
<g>
<path fill="#212121" d="M21.784,16.271c0,1.254-1.017,2.271-2.271,2.271h-15c-1.254,0-2.271-1.017-2.271-2.271l0,0
C2.242,15.017,3.259,14,4.513,14h15C20.767,14,21.784,15.017,21.784,16.271L21.784,16.271z"/>
<circle fill="#78CEDB" cx="4.547" cy="16.271" r="1.604"/>
<path fill="#FFFFFF" d="M16.292,15.938c0,0.38-0.308,0.688-0.687,0.688H7.979c-0.38,0-0.688-0.308-0.688-0.688l0,0
c0-0.38,0.308-0.688,0.688-0.688h7.625C15.984,15.25,16.292,15.558,16.292,15.938L16.292,15.938z"/>
</g>
<g>
<path fill="#212121" d="M17.388,20.375H6.638c-0.771,0-1.396,0.625-1.396,1.396c0,0.053,0.01,0.104,0.016,0.155
c0.735,0.5,1.532,0.912,2.371,1.241h8.743c0.85-0.333,1.656-0.753,2.399-1.262c0.004-0.045,0.014-0.088,0.014-0.134
C18.784,21,18.159,20.375,17.388,20.375z"/>
<path fill="#B38FC2" d="M6.714,20.75c-0.587,0-1.063,0.476-1.063,1.063c0,0.144,0.03,0.281,0.082,0.407
c0.37,0.227,0.753,0.435,1.148,0.622c0.504-0.083,0.895-0.501,0.895-1.029C7.776,21.226,7.3,20.75,6.714,20.75z"/>
<path fill="#FFFFFF" d="M15.167,21.667c0,0.276-0.224,0.5-0.5,0.5H9.25c-0.276,0-0.5-0.224-0.5-0.5l0,0c0-0.276,0.224-0.5,0.5-0.5
h5.417C14.943,21.167,15.167,21.391,15.167,21.667L15.167,21.667z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

31
_docs/icons/ic_others.svg Normal file
View file

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<circle fill="#555555" cx="12" cy="12" r="12"/>
<g>
<path fill="#FFFFFF" d="M17.925,8.906c0.579,0.002,1.029,0.462,1.022,1.044c-0.007,0.563-0.465,1.012-1.032,1.012
c-0.572-0.001-1.033-0.471-1.025-1.045C16.897,9.359,17.363,8.905,17.925,8.906z"/>
<path fill="#FFFFFF" d="M18.847,17.539c-0.15-0.085-0.266,0.009-0.357,0.122c-0.145,0.182-0.274,0.379-0.426,0.555
c-0.259,0.3-0.511,0.614-0.884,0.785c-0.127,0.058-0.276,0.105-0.393,0.008c-0.106-0.087-0.054-0.225-0.033-0.343
c0.105-0.566,0.349-1.084,0.563-1.612c0.458-1.129,0.887-2.269,1.196-3.45c0.216-0.829-0.06-1.479-0.736-1.752
c-0.32-0.129-0.655-0.188-0.991-0.114c-0.873,0.191-1.635,0.591-2.235,1.268c-0.374,0.373-0.705,0.78-0.959,1.244
c-0.043,0.079-0.101,0.178-0.002,0.258c0.092,0.075,0.199,0.055,0.291-0.004c0.064-0.041,0.123-0.097,0.168-0.158
c0.36-0.479,0.791-0.887,1.246-1.273l0,0c0.163-0.056,0.328-0.221,0.499-0.051c0.17,0.169,0.166,0.388,0.095,0.606
c-0.011,0.033-0.025,0.064-0.038,0.096c-0.602,1.527-1.205,3.053-1.807,4.58c-0.182,0.462-0.304,0.938-0.274,1.44
c0.033,0.563,0.333,0.888,0.892,0.972c0.396,0.06,0.774-0.027,1.147-0.145c1.099-0.347,1.903-1.097,2.632-1.944
c0.186-0.215,0.346-0.454,0.454-0.721C18.949,17.78,19.007,17.631,18.847,17.539z"/>
</g>
<path fill="#EE2725" d="M14.17,7.47c0-0.483-0.121-0.962-0.352-1.386c-0.223-0.41-0.546-0.763-0.933-1.023
c-0.396-0.266-0.856-0.431-1.331-0.477c-0.519-0.05-1.048,0.04-1.519,0.263c-0.46,0.217-0.859,0.556-1.148,0.974
c-0.067,0.096-0.128,0.197-0.182,0.3c-0.237-0.45-0.592-0.834-1.022-1.105C7.24,4.737,6.725,4.583,6.202,4.571
C5.717,4.56,5.232,4.672,4.801,4.896C4.387,5.111,4.027,5.427,3.76,5.81C3.487,6.2,3.313,6.656,3.258,7.128
C3.224,7.417,3.233,7.711,3.286,7.996c0.049,0.267,0.14,0.518,0.247,0.767c0.189,0.439,0.422,0.858,0.683,1.258
c0.289,0.443,0.613,0.864,0.959,1.263c0.38,0.439,0.788,0.853,1.215,1.246c0.463,0.426,0.948,0.827,1.45,1.207
c0.264,0.2,0.533,0.394,0.807,0.581c0.017,0.011,0.033,0.023,0.05,0.034c0.012,0.008,0.014,0.002,0.025-0.006
c0.008-0.006,0.017-0.011,0.025-0.017c0.036-0.025,0.072-0.05,0.108-0.075c0.069-0.048,0.137-0.096,0.205-0.144
c0.135-0.096,0.268-0.193,0.401-0.292c0.507-0.378,0.998-0.778,1.466-1.203c0.432-0.393,0.846-0.806,1.232-1.245
c0.352-0.4,0.682-0.82,0.977-1.264c0.267-0.4,0.506-0.82,0.702-1.26c0.086-0.194,0.168-0.391,0.226-0.595
C14.134,7.998,14.17,7.734,14.17,7.47z"/>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<path fill="#010101" d="M12,0C5.6,0,0,5.6,0,12s5.6,12,12,12s12-5.6,12-12S18.4,0,12,0"/>
<path fill="#FFFFFF" d="M7.89,19.226c-0.286,0-0.56-0.09-0.793-0.259c-0.419-0.304-0.625-0.811-0.537-1.321l0.666-3.878
l-2.818-2.746c-0.371-0.36-0.502-0.891-0.342-1.383C4.222,9.153,4.65,8.793,5.154,8.72l3.894-0.566l1.742-3.528
c0.212-0.432,0.676-0.701,1.21-0.701s0.997,0.269,1.21,0.701l1.742,3.528l3.893,0.566c0.513,0.074,0.931,0.426,1.09,0.918
c0.158,0.482,0.024,1.026-0.341,1.383l-2.817,2.746l0.665,3.878c0.087,0.502-0.123,1.021-0.536,1.321
c-0.231,0.168-0.505,0.258-0.79,0.258l0,0c-0.218,0-0.437-0.054-0.632-0.155L12,17.238l-3.482,1.83
C8.324,19.171,8.106,19.226,7.89,19.226z M16.033,17.758l-0.72-4.485l3.236-3.154l-4.489-0.701l-2-4.053l-0.026-0.007
c-0.015,0-0.025,0.005-0.026,0.007l-2.001,4.053l-4.474,0.65l3.221,3.206L7.99,17.727l4.044-2.07L16.033,17.758z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

19
_docs/icons/ic_status.svg Normal file
View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<circle fill="#FFFFFF" cx="12" cy="12" r="12"/>
<g>
<path d="M13.348,3.699c0.745,0.002,1.326,0.595,1.317,1.344c-0.009,0.725-0.599,1.304-1.329,1.303C12.6,6.346,12.005,5.74,12.015,5
C12.025,4.282,12.624,3.697,13.348,3.699z"/>
<path d="M14.535,14.818c-0.193-0.11-0.343,0.011-0.459,0.157c-0.187,0.235-0.352,0.488-0.549,0.714
c-0.334,0.386-0.658,0.79-1.138,1.011c-0.163,0.075-0.355,0.135-0.506,0.01c-0.136-0.112-0.07-0.29-0.042-0.442
c0.135-0.729,0.45-1.396,0.726-2.076c0.59-1.454,1.143-2.922,1.54-4.443c0.279-1.068-0.077-1.905-0.948-2.256
c-0.412-0.166-0.844-0.242-1.276-0.147c-1.124,0.247-2.105,0.761-2.879,1.633c-0.482,0.48-0.907,1.004-1.235,1.602
c-0.056,0.102-0.13,0.229-0.003,0.332c0.119,0.096,0.257,0.071,0.374-0.005c0.082-0.053,0.158-0.126,0.217-0.204
c0.463-0.617,1.019-1.143,1.605-1.639l0,0c0.21-0.072,0.422-0.285,0.642-0.066c0.219,0.218,0.214,0.5,0.123,0.781
c-0.014,0.042-0.033,0.083-0.049,0.124c-0.776,1.966-1.553,3.932-2.327,5.899c-0.235,0.596-0.391,1.208-0.353,1.855
c0.043,0.726,0.429,1.143,1.149,1.252c0.51,0.077,0.997-0.035,1.477-0.187c1.416-0.446,2.451-1.413,3.39-2.503
c0.239-0.277,0.446-0.585,0.585-0.928C14.666,15.127,14.742,14.935,14.535,14.818z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -9,13 +9,18 @@ import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.database.entities.EffectiveProfileSwitch
import info.nightscout.database.entities.embedments.InsulinConfiguration
import info.nightscout.implementation.profile.ProfileStoreObject
import info.nightscout.implementation.profile.ProfileUtilImpl
import info.nightscout.implementation.utils.DecimalFormatterImpl
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.profile.ProfileStore
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.rx.bus.RxBus
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
@ -41,6 +46,8 @@ open class TestBaseWithProfile : TestBase() {
@Mock lateinit var sp: SP
lateinit var dateUtil: DateUtil
lateinit var profileUtil: ProfileUtil
lateinit var decimalFormatter: DecimalFormatter
lateinit var hardLimits: HardLimits
val rxBus = RxBus(aapsSchedulers, aapsLogger)
@ -76,9 +83,12 @@ open class TestBaseWithProfile : TestBase() {
"{\"time\":\"2:00\",\"value\":\"3.4\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4.5\"}]," +
"\"target_high\":[{\"time\":\"00:00\",\"value\":\"7\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}"
dateUtil = Mockito.spy(DateUtil(context))
decimalFormatter = DecimalFormatterImpl(rh)
profileUtil = ProfileUtilImpl(sp, decimalFormatter)
testPumpPlugin = TestPumpPlugin(profileInjector)
Mockito.`when`(dateUtil.now()).thenReturn(now)
Mockito.`when`(activePlugin.activePump).thenReturn(testPumpPlugin)
Mockito.`when`(sp.getString(info.nightscout.core.utils.R.string.key_units, GlucoseUnit.MGDL.asText)).thenReturn(GlucoseUnit.MGDL.asText)
hardLimits = HardLimitsMock(sp, rh)
validProfile = ProfileSealed.Pure(pureProfileFromJson(JSONObject(validProfileJSON), dateUtil)!!)
effectiveProfileSwitch = EffectiveProfileSwitch(

View file

@ -0,0 +1,17 @@
package info.nightscout.interfaces
@Suppress("SpellCheckingInspection")
enum class GlucoseUnit(val asText: String) {
// This is Nightscout's representation
MGDL("mg/dl"),
MMOL("mmol");
companion object {
const val MMOLL_TO_MGDL = 18.0 // 18.0182;
const val MGDL_TO_MMOLL = 1 / MMOLL_TO_MGDL
fun fromText(name: String) = values().firstOrNull { it.asText == name } ?: MGDL
}
}

View file

@ -0,0 +1,21 @@
package info.nightscout.interfaces.utils
import java.text.DecimalFormat
/**
* Format double values to strings
*/
interface DecimalFormatter {
fun to0Decimal(value: Double): String
fun to0Decimal(value: Double, unit: String): String
fun to1Decimal(value: Double): String
fun to1Decimal(value: Double, unit: String): String
fun to2Decimal(value: Double): String
fun to2Decimal(value: Double, unit: String): String
fun to3Decimal(value: Double): String
fun to3Decimal(value: Double, unit: String): String
fun toPumpSupportedBolus(value: Double, bolusStep: Double): String
fun toPumpSupportedBolusWithUnits(value: Double, bolusStep: Double): String
fun pumpSupportedBolusFormat(bolusStep: Double): DecimalFormat
}

View file

@ -50,11 +50,7 @@ enum class ResFileMap(val fileName: String) {
ARROW_FLAT("ArrowFlat"),
ARROW_FORTY_FIVE_DOWN("Arrow45Down"),
ARROW_SINGLE_DOWN("ArrowSingleDown"),
ARROW_DOUBLE_DOWN("ArrowDoubleDown"),
FONT1("Font1"),
FONT2("Font2"),
FONT3("Font3"),
FONT4("Font4");
ARROW_DOUBLE_DOWN("ArrowDoubleDown");
companion object {
@ -67,7 +63,8 @@ enum class ResFormat(val extension: String) {
SVG("svg"),
JPG("jpg"),
PNG("png"),
TTF("ttf");
TTF("ttf"),
OTF("otf");
companion object {
@ -106,9 +103,9 @@ data class ResData(val value: ByteArray, val format: ResFormat) {
fun toTypeface(): Typeface? {
try {
return when (format) {
ResFormat.TTF -> {
ResFormat.TTF, ResFormat.OTF -> {
// Workaround with temporary File, Typeface.createFromFileDescriptor(null, value, 0, value.size) more simple not available
File.createTempFile("temp", ".ttf").let { tempFile ->
File.createTempFile("temp", format.extension).let { tempFile ->
FileOutputStream(tempFile).let { fileOutputStream ->
fileOutputStream.write(value)
fileOutputStream.close()
@ -134,7 +131,7 @@ data class ResData(val value: ByteArray, val format: ResFormat) {
}
}
typealias CwfResDataMap = MutableMap<ResFileMap, ResData>
typealias CwfResDataMap = MutableMap<String, ResData>
typealias CwfMetadataMap = MutableMap<CwfMetadataKey, String>
@Serializable
@ -206,71 +203,60 @@ enum class ViewKeys(val key: String, @StringRes val comment: Int) {
COVER_PLATE("cover_plate", R.string.cwf_comment_cover_plate),
HOUR_HAND("hour_hand", R.string.cwf_comment_hour_hand),
MINUTE_HAND("minute_hand", R.string.cwf_comment_minute_hand),
SECOND_HAND("second_hand", R.string.cwf_comment_second_hand);
SECOND_HAND("second_hand", R.string.cwf_comment_second_hand)
}
enum class JsonKeys(val key: String, val viewType: ViewType, @StringRes val comment: Int?) {
METADATA("metadata", ViewType.NONE, null),
ENABLESECOND("enableSecond", ViewType.NONE, null),
HIGHCOLOR("highColor", ViewType.NONE, null),
MIDCOLOR("midColor", ViewType.NONE, null),
LOWCOLOR("lowColor", ViewType.NONE, null),
LOWBATCOLOR("lowBatColor", ViewType.NONE, null),
CARBCOLOR("carbColor", ViewType.NONE, null),
BASALBACKGROUNDCOLOR("basalBackgroundColor", ViewType.NONE, null),
BASALCENTERCOLOR("basalCenterColor", ViewType.NONE, null),
GRIDCOLOR("gridColor", ViewType.NONE, null),
POINTSIZE("pointSize", ViewType.NONE, null),
WIDTH("width", ViewType.ALLVIEWS, null),
HEIGHT("height", ViewType.ALLVIEWS, null),
TOPMARGIN("topmargin", ViewType.ALLVIEWS, null),
LEFTMARGIN("leftmargin", ViewType.ALLVIEWS, null),
ROTATION("rotation", ViewType.TEXTVIEW, null),
VISIBILITY("visibility", ViewType.ALLVIEWS, null),
TEXTSIZE("textsize", ViewType.TEXTVIEW, null),
TEXTVALUE("textvalue", ViewType.TEXTVIEW, null),
GRAVITY("gravity", ViewType.TEXTVIEW, null),
FONT("font", ViewType.TEXTVIEW, null),
FONTSTYLE("fontStyle", ViewType.TEXTVIEW, null),
FONTCOLOR("fontColor", ViewType.TEXTVIEW, null),
COLOR("color", ViewType.IMAGEVIEW, null),
ALLCAPS("allCaps", ViewType.TEXTVIEW, null),
DAYNAMEFORMAT("dayNameFormat", ViewType.NONE, null),
MONTHFORMAT("monthFormat", ViewType.NONE, null)
enum class JsonKeys(val key: String) {
METADATA("metadata"),
ENABLESECOND("enableSecond"),
HIGHCOLOR("highColor"),
MIDCOLOR("midColor"),
LOWCOLOR("lowColor"),
LOWBATCOLOR("lowBatColor"),
CARBCOLOR("carbColor"),
BASALBACKGROUNDCOLOR("basalBackgroundColor"),
BASALCENTERCOLOR("basalCenterColor"),
GRIDCOLOR("gridColor"),
POINTSIZE("pointSize"),
WIDTH("width"),
HEIGHT("height"),
TOPMARGIN("topmargin"),
LEFTMARGIN("leftmargin"),
ROTATION("rotation"),
VISIBILITY("visibility"),
TEXTSIZE("textsize"),
TEXTVALUE("textvalue"),
GRAVITY("gravity"),
FONT("font"),
FONTSTYLE("fontStyle"),
FONTCOLOR("fontColor"),
COLOR("color"),
ALLCAPS("allCaps"),
DAYNAMEFORMAT("dayNameFormat"),
MONTHFORMAT("monthFormat")
}
enum class JsonKeyValues(val key: String, val jsonKey: JsonKeys) {
GONE("gone", JsonKeys.VISIBILITY),
VISIBLE("visible", JsonKeys.VISIBILITY),
INVISIBLE("invisible", JsonKeys.VISIBILITY),
CENTER("center", JsonKeys.GRAVITY),
LEFT("left", JsonKeys.GRAVITY),
RIGHT("right", JsonKeys.GRAVITY),
SANS_SERIF("sans_serif", JsonKeys.FONT),
DEFAULT("default", JsonKeys.FONT),
DEFAULT_BOLD("default_bold", JsonKeys.FONT),
MONOSPACE("monospace", JsonKeys.FONT),
SERIF("serif", JsonKeys.FONT),
ROBOTO_CONDENSED_BOLD("roboto_condensed_bold", JsonKeys.FONT),
ROBOTO_CONDENSED_LIGHT("roboto_condensed_light", JsonKeys.FONT),
ROBOTO_CONDENSED_REGULAR("roboto_condensed_regular", JsonKeys.FONT),
ROBOTO_SLAB_LIGHT("roboto_slab_light", JsonKeys.FONT),
NORMAL("normal", JsonKeys.FONTSTYLE),
BOLD("bold", JsonKeys.FONTSTYLE),
BOLD_ITALIC("bold_italic", JsonKeys.FONTSTYLE),
ITALIC("italic", JsonKeys.FONTSTYLE),
BGCOLOR("bgColor", JsonKeys.COLOR),
FONT1("font1", JsonKeys.FONTCOLOR),
FONT2("font2", JsonKeys.FONTCOLOR),
FONT3("font3", JsonKeys.FONTCOLOR),
FONT4("font4", JsonKeys.FONTCOLOR)
}
enum class ViewType(@StringRes val comment: Int?) {
NONE(null),
TEXTVIEW(null),
IMAGEVIEW(null),
ALLVIEWS(null)
enum class JsonKeyValues(val key: String) {
GONE("gone"),
VISIBLE("visible"),
INVISIBLE("invisible"),
CENTER("center"),
LEFT("left"),
RIGHT("right"),
SANS_SERIF("sans_serif"),
DEFAULT("default"),
DEFAULT_BOLD("default_bold"),
MONOSPACE("monospace"),
SERIF("serif"),
ROBOTO_CONDENSED_BOLD("roboto_condensed_bold"),
ROBOTO_CONDENSED_LIGHT("roboto_condensed_light"),
ROBOTO_CONDENSED_REGULAR("roboto_condensed_regular"),
ROBOTO_SLAB_LIGHT("roboto_slab_light"),
NORMAL("normal"),
BOLD("bold"),
BOLD_ITALIC("bold_italic"),
ITALIC("italic"),
BGCOLOR("bgColor")
}
class ZipWatchfaceFormat {
@ -309,14 +295,15 @@ class ZipWatchfaceFormat {
val cwfResFileMap = ResFileMap.fromFileName(entryName)
val drawableFormat = ResFormat.fromFileName(entryName)
if (cwfResFileMap != ResFileMap.UNKNOWN && drawableFormat != ResFormat.UNKNOWN) {
resDatas[cwfResFileMap] = ResData(byteArrayOutputStream.toByteArray(), drawableFormat)
}
resDatas[cwfResFileMap.fileName] = ResData(byteArrayOutputStream.toByteArray(), drawableFormat)
} else if (drawableFormat != ResFormat.UNKNOWN)
resDatas[entryName.substringBeforeLast(".")] = ResData(byteArrayOutputStream.toByteArray(), drawableFormat)
}
zipEntry = zipInputStream.nextEntry
}
// Valid CWF file must contains a valid json file with a name within metadata and a custom watchface image
return if (metadata.containsKey(CwfMetadataKey.CWF_NAME) && resDatas.containsKey(ResFileMap.CUSTOM_WATCHFACE))
return if (metadata.containsKey(CwfMetadataKey.CWF_NAME) && resDatas.containsKey(ResFileMap.CUSTOM_WATCHFACE.fileName))
CwfData(json.toString(4), metadata, resDatas)
else
null
@ -338,7 +325,7 @@ class ZipWatchfaceFormat {
zipOutputStream.closeEntry()
for (resData in customWatchface.resDatas) {
val fileEntry = ZipEntry("${resData.key.fileName}.${resData.value.format.extension}")
val fileEntry = ZipEntry("${resData.key}.${resData.value.format.extension}")
zipOutputStream.putNextEntry(fileEntry)
zipOutputStream.write(resData.value.value)
zipOutputStream.closeEntry()
@ -362,5 +349,4 @@ class ZipWatchfaceFormat {
return metadata
}
}
}

View file

@ -0,0 +1,146 @@
package info.nightscout.shared.interfaces
import info.nightscout.interfaces.GlucoseUnit
interface ProfileUtil {
/**
* Units selected in [info.nightscout.shared.sharedPreferences.SP]
*
* @return GlucoseUnit for UI
*/
val units: GlucoseUnit
/**
* Convert value from mg/dl to selected units
*
* @param valueInMgdl glucose value in mgdl
* @param targetUnits target units
* @return value in target units
*/
fun fromMgdlToUnits(valueInMgdl: Double, targetUnits: GlucoseUnit = units): Double
/**
* Convert value from mmol/l to selected units
*
* @param value glucose value in mmol/l
* @param targetUnits target units
* @return value in target units
*/
fun fromMmolToUnits(value: Double, targetUnits: GlucoseUnit = units): Double
/**
* Convert to currently used units
*
* @param anyBg glycemia
* @return value in mg/dl or mmol/l
*/
fun valueInCurrentUnitsDetect(anyBg: Double): Double
/**
* Detect units of [anyBg] and return string in currently used units.
* Values >= 39 are expected to be in mmol/l, below in mg/dl.
*
* @param anyBg value either in mmol/l or mg/dl
* @return formatted string in current units
*/
fun stringInCurrentUnitsDetect(anyBg: Double): String
/**
* Value based on [targetUnits] parameter as a formatted string
*
* @param valueInMgdl known value in mg/dl
* @param targetUnits wanted units
* @return formatted one of the values based on [targetUnits] parameter
*/
fun fromMgdlToStringInUnits(valueInMgdl: Double?, targetUnits: GlucoseUnit = units): String
/**
* Pick from values based on [targetUnits] parameter as a formatted string with +/- sign
*
* @param valueInMgdl known value in mg/dl
* @param targetUnits wanted units
* @return formatted one of the values based on [targetUnits] parameter
*/
fun fromMgdlToSignedStringInUnits(valueInMgdl: Double, targetUnits: GlucoseUnit = units): String
/**
* Test if value is in mg/dl.
*
* @param anyBg glycemia
* @return true if value < 39
*/
fun isMgdl(anyBg: Double): Boolean
/**
* Test if value is in mmol/l
*
* @param anyBg glycemia
* @return true if value >= 39
*/
fun isMmol(anyBg: Double): Boolean
/**
* Detect units of [anyBg]
*
* @param anyBg glycemia
* @return [GlucoseUnit.MMOL] if value >= 39 otherwise [GlucoseUnit.MGDL]
*/
fun unitsDetect(anyBg: Double): GlucoseUnit
/**
* Convert to selected units
*
* @param anyBg glycemia
* @param targetUnits target units
* @return value in mg/dl or mmol/l
*/
fun valueInUnitsDetect(anyBg: Double, targetUnits: GlucoseUnit): Double
/**
* Detect units of [anyBg] and return string in [targetUnits]
* Values >= 39 are expected to be in mmol/l, below in mg/dl.
*
* @param anyBg value either in mmol/l or mg/dl
* @return formatted string
*/
fun stringInUnitsDetect(anyBg: Double, targetUnits: GlucoseUnit): String
/**
* Detect units and convert value to mg/dl
* Values >= 39 are expected to be in mmol/l, below in mg/dl.
*
* @param anyBg in any units
* @return value in mg/dl
*/
fun convertToMgdlDetect(anyBg: Double): Double
/**
* Convert value to mg/dl
*
* @param value value in [sourceUnits]
* @return value in mg/dl
*/
fun convertToMgdl(value: Double, sourceUnits: GlucoseUnit): Double
/**
* Convert value to mmol/l
*
* @param value value in [sourceUnits]
* @return value in mmol/l
*/
fun convertToMmol(value: Double, sourceUnits: GlucoseUnit): Double
/**
* Create properly formatted string of range "low - high".
* Targets are stored in mg/dl but profile vary
*
* @param low low range value
* @param high high range value
* @param sourceUnits units of source values
* @param targetUnits target units for formatting
* @return formatted range string
*/
//
fun toTargetRangeString(low: Double, high: Double, sourceUnits: GlucoseUnit, targetUnits: GlucoseUnit = units): String
}

View file

@ -1,6 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- DateUtil-->
<string name="minago">%1$d λ πριν</string>
<string name="minago_long">%1$d λεπτά πριν</string>
<string name="hoursago">%1$.1f ω πριν</string>
<string name="days_ago">%1$.1f ημέρες πριν</string>
<string name="days_ago_round">%1$.0f ημέρες πριν</string>
<string name="in_days">σε %1$.0f ημέρες</string>
<string name="in_days_round">σε %1$.0f ημέρες</string>
<string name="shorthour">h</string>
<string name="days">ημέρες</string>
<string name="hours">ώρες</string>
@ -15,10 +22,72 @@
<string name="unit_days">ημέρες</string>
<string name="unit_weeks">εβδομάδες</string>
<string name="shortminute">m</string>
<string name="shortday">ημ</string>
<string name="later_today">Αργότερα σήμερα</string>
<string name="tomorrow">Αύριο</string>
<string name="today">Σήμερα</string>
<string name="yesterday">Χθες</string>
<!-- Rx -->
<string name="connecting_for">Σύνδεση για %1$d δευτερόλεπτα</string>
<string name="handshaking">Δημιουργία σύνδεσης</string>
<string name="connected">Συνδέθηκε</string>
<string name="disconnecting">Αποσυνδέεται</string>
<string name="waiting_for_disconnection">Αναμονή για αποσύνδεση</string>
<!-- Custom Watchface -->
<string name="metadata_label_watchface_created_at">Δημιουργήθηκε: %1$s</string>
<string name="metadata_label_watchface_author">Συντάκτης: %1$s</string>
<string name="metadata_label_watchface_name">Όνομα: %1$s</string>
<string name="metadata_wear_import_filename">Όνομα αρχείου: %1$s</string>
<string name="metadata_label_plugin_version">Έκδοση πρόσθετου: %1$s</string>
<string name="metadata_label_watchface_name_version">Όνομα: %1$s (%2$s)</string>
<string name="metadata_label_watchface_infos">Πληροφορίες: %1$s</string>
<string name="pref_show_iob">Εμφάνιση IOB</string>
<string name="pref_show_detailed_iob">Εμφάνιση λεπτομερούς IOB</string>
<string name="pref_show_cob">Εμφάνιση COB</string>
<string name="pref_show_delta">Εμφάνιση Διαφοράς</string>
<string name="pref_show_detailed_delta">Εμφάνιση λεπτομερούς Διαφοράς</string>
<string name="pref_show_avgdelta">Εμφάνιση Μέσης Διαφοράς</string>
<string name="pref_show_phone_battery">Εμφάνιση Μπαταρίας Τηλεφώνου</string>
<string name="pref_show_rig_battery">Εμφάνιση Μπαταρίας Rig</string>
<string name="pref_show_basal_rate">Εμφάνιση Βασικού Ρυθμού</string>
<string name="pref_show_loop_status">Εμφάνιση Κατάστασης Κυκλώματος</string>
<string name="pref_show_bg">Εμφάνιση γλυκόζης αίματος</string>
<string name="pref_show_bgi">Εμφάνιση BGI</string>
<string name="pref_show_direction_arrow">Εμφάνιση Βέλους Κατεύθυνσης</string>
<string name="pref_show_ago">Εμφάνιση Πριν</string>
<string name="default_custom_watchface_comment">Προεπιλεγμένη πρόσοψη ρολογιού, μπορείτε να κάνετε κλικ στο κουμπί ΕΞΑΓΩΓΗ ΠΡΟΣΟΨΗΣ για να δημιουργήσετε ένα πρότυπο</string>
<string name="wear_default_watchface">Προεπιλεγμένη πρόσοψη ρολογιού</string>
<string name="cwf_comment_background">Εικόνα φόντου</string>
<string name="cwf_comment_chart">Γραφήματα (BG, βασικός, γραμμές πρόβλεψης...)</string>
<string name="cwf_comment_cover_chart">Εικόνα μπροστά από το γράφημα και πίσω από τα πεδία κειμένου</string>
<string name="cwf_comment_freetext1">Ελεύθερο κείμενο 1</string>
<string name="cwf_comment_freetext2">Ελεύθερο κείμενο 2</string>
<string name="cwf_comment_freetext3">Ελεύθερο κείμενο 3</string>
<string name="cwf_comment_freetext4">Ελεύθερο κείμενο 4</string>
<string name="cwf_comment_iob1">Ετικέτα IOB ή Άθροισμα IOB εάν είναι λεπτομερές</string>
<string name="cwf_comment_iob2">Άθροισμα IOB ή (Bolus_IOB|Basal_IOB) εάν είναι λεπτομερές</string>
<string name="cwf_comment_cob1">Ετικέτα COB</string>
<string name="cwf_comment_cob2">Τιμή COB</string>
<string name="cwf_comment_delta">Βραχυπρόθεσμη διαφορά BG</string>
<string name="cwf_comment_avg_delta">Μέση διαφορά BG (15λεπτά)</string>
<string name="cwf_comment_uploader_battery">Μπαταρία τηλεφώνου (%)</string>
<string name="cwf_comment_rig_battery">Μπαταρία συνολικού κυκλώματος (%)</string>
<string name="cwf_comment_basalRate">Βασικός Ρυθμός</string>
<string name="cwf_comment_bgi">Τιμή BGI</string>
<string name="cwf_comment_time">Ώρα (ΩΩ:ΛΛ ή ΩΩ:ΜΜ:ΣΣ)</string>
<string name="cwf_comment_hour">Ώρα (HH)</string>
<string name="cwf_comment_minute">Λεπτό (MM)</string>
<string name="cwf_comment_second">Δευτερόλεπτο (SS)</string>
<string name="cwf_comment_timePeriod">ΠΜ ή ΜΜ</string>
<string name="cwf_comment_day_name">Όνομα της ημέρας της εβδομάδας</string>
<string name="cwf_comment_day">Ημέρα (DD)</string>
<string name="cwf_comment_month">Όνομα μήνα (σύντομο)</string>
<string name="cwf_comment_loop">Κατάσταση κυκλώματος και πριν</string>
<string name="cwf_comment_direction">Βέλος κατεύθυνσης</string>
<string name="cwf_comment_timestamp">Λεπτά πριν από την τελευταία λήψη BG</string>
<string name="cwf_comment_sgv">Τιμή γλυκόζης αίματος</string>
<string name="cwf_comment_cover_plate">Εικόνα εξωφύλλου μπροστά από το κείμενο (κλήσεις...)</string>
<string name="cwf_comment_hour_hand">Εικόνα ώρας χεριού (Αναλογικό ρολόι)</string>
<string name="cwf_comment_minute_hand">Εικόνα λεπτού χεριού (Αναλογικό ρολόι)</string>
<string name="cwf_comment_second_hand">Εικόνα δευτερολέπτου χεριού (Αναλογικό ρολόι)</string>
</resources>

View file

@ -40,6 +40,7 @@
<string name="metadata_wear_import_filename">Nombre del archivo: %1$s</string>
<string name="metadata_label_plugin_version">Versión del plugin: %1$s</string>
<string name="metadata_label_watchface_name_version">Nombre: %1$s (%2$s)</string>
<string name="metadata_label_watchface_infos">Info: %1$s</string>
<string name="pref_show_iob">Mostrar IOB</string>
<string name="pref_show_detailed_iob">Mostrar IOB detallada</string>
<string name="pref_show_cob">Mostrar COB</string>

View file

@ -40,6 +40,7 @@
<string name="metadata_wear_import_filename">Nom du fichier : %1$s</string>
<string name="metadata_label_plugin_version">Version du plugin : %1$s</string>
<string name="metadata_label_watchface_name_version">Nom : %1$s (%2$s)</string>
<string name="metadata_label_watchface_infos">Infos : %1$s</string>
<string name="pref_show_iob">Afficher IA</string>
<string name="pref_show_detailed_iob">Afficher IA détaillée</string>
<string name="pref_show_cob">Afficher GA</string>

View file

@ -40,6 +40,7 @@
<string name="metadata_wear_import_filename">Bestandsnaam: %1$s</string>
<string name="metadata_label_plugin_version">Plugin versie: %1$s</string>
<string name="metadata_label_watchface_name_version">Naam: %1$s (%2$s)</string>
<string name="metadata_label_watchface_infos">Info: %1$s</string>
<string name="pref_show_iob">Toon IOB</string>
<string name="pref_show_detailed_iob">Toon gedetailleerde IOB</string>
<string name="pref_show_cob">Toon COB</string>

View file

@ -40,6 +40,7 @@
<string name="metadata_wear_import_filename">Nome do arquivo: %1$s</string>
<string name="metadata_label_plugin_version">Versão do plugin: %1$s</string>
<string name="metadata_label_watchface_name_version">Nome: %1$s (%2$s)</string>
<string name="metadata_label_watchface_infos">Informações: %1$s</string>
<string name="pref_show_iob">Mostrar IA</string>
<string name="pref_show_detailed_iob">Mostrar detalhes da IA</string>
<string name="pref_show_cob">Mostrar CA</string>

View file

@ -34,4 +34,5 @@
<string name="disconnecting">разъединение</string>
<string name="waiting_for_disconnection">Ожидание разъединения</string>
<!-- Custom Watchface -->
<string name="pref_show_delta">Отображать дельту</string>
</resources>

View file

@ -9,6 +9,7 @@ import info.nightscout.implementation.overview.OverviewDataImpl
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.DefaultValueHelper
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus
@ -33,7 +34,8 @@ class HistoryBrowserData @Inject constructor(
profileFunction: ProfileFunction,
repository: AppRepository,
fabricPrivacy: FabricPrivacy,
calculationWorkflow: CalculationWorkflow
calculationWorkflow: CalculationWorkflow,
decimalFormatter: DecimalFormatter
) {
var iobCobCalculator: IobCobCalculatorPlugin
@ -50,7 +52,8 @@ class HistoryBrowserData @Inject constructor(
activePlugin,
defaultValueHelper,
profileFunction,
repository
repository,
decimalFormatter
)
iobCobCalculator =
IobCobCalculatorPlugin(
@ -66,7 +69,8 @@ class HistoryBrowserData @Inject constructor(
dateUtil,
repository,
overviewData,
calculationWorkflow
calculationWorkflow,
decimalFormatter
)
}
}

View file

@ -20,7 +20,6 @@ import info.nightscout.androidaps.R
import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin
import info.nightscout.androidaps.danaRv2.DanaRv2Plugin
import info.nightscout.androidaps.danar.DanaRPlugin
import info.nightscout.plugins.sync.openhumans.OpenHumansUploaderPlugin
import info.nightscout.androidaps.plugins.pump.eopatch.EopatchPumpPlugin
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin
@ -32,8 +31,6 @@ import info.nightscout.insulin.InsulinOrefFreePeakPlugin
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.nsclient.NSSettingsStatus
import info.nightscout.interfaces.plugin.PluginBase
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.protection.PasswordCheck
import info.nightscout.interfaces.protection.ProtectionCheck.ProtectionType.BIOMETRIC
import info.nightscout.interfaces.protection.ProtectionCheck.ProtectionType.CUSTOM_PASSWORD
@ -49,6 +46,7 @@ import info.nightscout.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.plugins.general.wear.WearPlugin
import info.nightscout.plugins.sync.nsclient.NSClientPlugin
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
import info.nightscout.plugins.sync.openhumans.OpenHumansUploaderPlugin
import info.nightscout.plugins.sync.tidepool.TidepoolPlugin
import info.nightscout.plugins.sync.xdrip.XdripPlugin
import info.nightscout.pump.combo.ComboPlugin
@ -63,6 +61,7 @@ import info.nightscout.sensitivity.SensitivityAAPSPlugin
import info.nightscout.sensitivity.SensitivityOref1Plugin
import info.nightscout.sensitivity.SensitivityWeightedAveragePlugin
import info.nightscout.shared.SafeParse
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.source.AidexPlugin
@ -83,7 +82,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
@Inject lateinit var rxBus: RxBus
@Inject lateinit var rh: ResourceHelper
@Inject lateinit var sp: SP
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var profileUtil: ProfileUtil
@Inject lateinit var pluginStore: PluginStore
@Inject lateinit var config: Config
@ -326,7 +325,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
rh.gs(info.nightscout.core.utils.R.string.key_low_mark)
)
if (unitDependent.toList().contains(pref.key) && pref is EditTextPreference) {
val converted = Profile.toCurrentUnits(profileFunction, SafeParse.stringToDouble(pref.text))
val converted = profileUtil.valueInCurrentUnitsDetect(SafeParse.stringToDouble(pref.text))
pref.summary = converted.toString()
}
}

View file

@ -17,22 +17,44 @@
<string name="nav_about">Σχετικά με</string>
<string name="smscommunicator_missingphonestatepermission">Λείπει η άδεια κατάστασης τηλεφώνου</string>
<string name="ns_alarm_options">Επιλογές συναγερμού</string>
<string name="ns_alarms">Δημιουργία ειδοποιήσεων από συναγερμούς του NS</string>
<string name="ns_announcements">Δημιουργία ειδοποιήσεων από ανακοινώσεις NS</string>
<string name="ns_alarm_stale_data_value_label">Οριακή τιμή για παλιά δεδομένα [min]</string>
<string name="ns_alarm_urgent_stale_data_value_label">Επείγουσα οριακή τιμή για παλιά δεδομένα [min]</string>
<string name="sensitivity_warning">Ενεργοποιώντας το autosense θυμηθείτε να εισάγετε όλους τους υδατάνθρακες. Διαφορετικά, οι αποκλίσεις των υδατανθράκων θα εντοπιστούν λανθασμένα ως αλλαγή ευαισθησίας!!</string>
<string name="notloadedplugins">Δεν έχουν φορτωθεί όλα τα προφίλ!</string>
<string name="valuesnotstored">Οι τιμές δεν αποθηκεύτηκαν!</string>
<string name="invalid">ΜΗ ΕΓΚΥΡΟ</string>
<string name="gradually_increase_notification_volume">Σταδιακή αύξηση της έντασης για συναγερμούς και ειδοποιήσεις</string>
<string name="localalertsettings_title">Τοπικές Ειδοποιήσεις</string>
<string name="enable_missed_bg_readings_alert">Προειδοποίηση αν δεν ληφθούν δεδομένα μετρήσεων BG</string>
<string name="enable_pump_unreachable_alert">Προειδοποίηση αν η αντλία δεν είναι διαθέσιμη</string>
<string name="pump_unreachable_threshold">Όριο για μη διαθεσιμότητα της αντλίας [λεπτά]</string>
<string name="enable_carbs_req_alert">Ειδοποίηση εάν απαιτούνται υδατάνθρακες</string>
<string name="open_navigation">Άνοιγμα μενού πλοήγησης</string>
<string name="close_navigation">Κλείσιμο μενού πλοήγησης</string>
<string name="remove_items">Αφαίρεση αντικειμένου</string>
<string name="sort_items">Ταξινόμηση στοιχείων</string>
<string name="error_adding_treatment_title">Ελλιπή δεδομένα θεραπείας</string>
<string name="error_adding_treatment_message">Μια θεραπεία (ινσουλίνη: %1$.2f, υδατάνθρακες: %2$d, στο: %3$s) δεν μπορεί να προστεθεί στις θεραπείες. Παρακαλούμε ελέγξτε και προσθέστε χειροκίνητα μια εγγραφή ανάλογα με την περίπτωση.</string>
<string name="generated_ecarbs_note">eCarbs: %1$d g (%2$d h), καθυστέρηση: %3$d m</string>
<string name="profile_total">== ∑ %1$s U</string>
<string name="unitsnosemicolon">Μονάδες</string>
<string name="show_removed">Εμφάνιση αφαιρεμένων</string>
<string name="clearqueueconfirm">Εκκαθάριση ουράς? Όλα τα δεδομένα στην ουρά θα χαθούν!</string>
<string name="chartmenu">Μενού διαγράμματος</string>
<string name="authorizationfailed">Η εξουσιοδότηση απέτυχε</string>
<string name="copytolocalprofile_invalid">Αδυναμία δημιουργίας προφίλ. Το προφίλ δεν είναι έγκυρο.</string>
<string name="clear_filter">Κατάργηση φίλτρου</string>
<string name="cannula">Υποδόριος καθετήρας</string>
<string name="email_address">Διεύθυνση E-mail</string>
<string name="remove_bg_readings">Αφαίρεση αναγνώσεων γλυκόζης αίματος BG</string>
<string name="identification_not_set">Η ταυτοποίηση δεν έχει οριστεί στη λειτουργία προγραμματισμού</string>
<string name="a11y_dialog">διάλογος</string>
<!-- WEAR OS-->
<string name="wear_unknown_action_string">Άγνωστη εντολή ενέργειας:</string>
<string name="remove_selected_items">Αφαίρεση επιλεγμένων στοιχείων</string>
<string name="count_selected">Επιλέχθηκε %1$d</string>
<string name="sort_label">Ταξινόμηση</string>
<string name="search">Αναζήτηση</string>
</resources>

View file

@ -33,6 +33,8 @@
<string name="enable_carbs_req_alert">Alertează dacă sunt necesari carbohidrați</string>
<string name="open_navigation">Afișare navigație</string>
<string name="close_navigation">Închidere navigație</string>
<string name="remove_items">Elimină obiecte</string>
<string name="sort_items">Sortează obiecte</string>
<string name="error_adding_treatment_title">Date incomplete despre tratament</string>
<string name="error_adding_treatment_message">Un tratament (insulină: %1$.2f, carbohidrați: %2$d, la: %3$s) nu a putut fi înregistrat. Reverificați și apoi adăugați manual înregistrarea corectă.</string>
<string name="generated_ecarbs_note">eCarbohidrați: %1$d g (%2$d h), întârziere: %3$d m</string>
@ -46,7 +48,13 @@
<string name="clear_filter">Șterge filtru</string>
<string name="cannula">Canula</string>
<string name="email_address">Adresă de e-mail</string>
<string name="remove_bg_readings">Eliminați valorile glicemiei</string>
<string name="identification_not_set">Identificarea nu este setată în modul dezvoltator</string>
<string name="a11y_dialog">dialog</string>
<!-- WEAR OS-->
<string name="wear_unknown_action_string">Comandă de acțiune necunoscută:</string>
<string name="remove_selected_items">Șterge obiectele selectate</string>
<string name="count_selected">%1$d selectat(e)</string>
<string name="sort_label">Sortează</string>
<string name="search">Caută</string>
</resources>

View file

@ -1,5 +1,6 @@
package info.nightscout.plugins.constraints
import com.google.common.truth.Truth.assertThat
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.danar.DanaRPlugin
@ -39,10 +40,10 @@ import info.nightscout.pump.combo.ruffyscripter.RuffyScripter
import info.nightscout.pump.dana.DanaPump
import info.nightscout.pump.dana.R
import info.nightscout.pump.dana.database.DanaHistoryDatabase
import info.nightscout.pump.danars.DanaRSPlugin
import info.nightscout.pump.virtual.VirtualPumpPlugin
import info.nightscout.sharedtests.TestBaseWithProfile
import info.nightscout.source.GlimpPlugin
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.Mock
@ -78,7 +79,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
private lateinit var objectivesPlugin: ObjectivesPlugin
private lateinit var comboPlugin: ComboPlugin
private lateinit var danaRPlugin: DanaRPlugin
private lateinit var danaRSPlugin: info.nightscout.pump.danars.DanaRSPlugin
private lateinit var danaRSPlugin: DanaRSPlugin
private lateinit var insightPlugin: LocalInsightPlugin
private lateinit var openAPSSMBPlugin: OpenAPSSMBPlugin
private lateinit var openAPSAMAPlugin: OpenAPSAMAPlugin
@ -135,36 +136,21 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
//SafetyPlugin
constraintChecker = ConstraintsImpl(activePlugin)
val glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger = aapsLogger, iobCobCalculator = iobCobCalculator, dateUtil = dateUtil)
val glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculator, dateUtil, decimalFormatter)
insightDbHelper = InsightDbHelper(insightDatabaseDao)
danaPump = DanaPump(aapsLogger, sp, dateUtil, instantiator)
danaPump = DanaPump(aapsLogger, sp, dateUtil, instantiator, decimalFormatter)
objectivesPlugin = ObjectivesPlugin(injector, aapsLogger, rh, activePlugin, sp, config)
comboPlugin = ComboPlugin(injector, aapsLogger, rxBus, rh, profileFunction, sp, commandQueue, pumpSync, dateUtil, ruffyScripter, uiInteraction)
danaRPlugin = DanaRPlugin(
injector, aapsLogger, aapsSchedulers, rxBus, context, rh, constraintChecker, activePlugin, sp, commandQueue, danaPump, dateUtil, fabricPrivacy, pumpSync,
uiInteraction, danaHistoryDatabase
uiInteraction, danaHistoryDatabase, decimalFormatter
)
danaRSPlugin =
info.nightscout.pump.danars.DanaRSPlugin(
injector,
aapsLogger,
aapsSchedulers,
rxBus,
context,
rh,
constraintChecker,
profileFunction,
sp,
commandQueue,
danaPump,
pumpSync,
detailedBolusInfoStorage,
temporaryBasalStorage,
fabricPrivacy,
dateUtil,
uiInteraction,
danaHistoryDatabase
DanaRSPlugin(
injector, aapsLogger, aapsSchedulers, rxBus, context, rh, constraintChecker, profileFunction,
sp, commandQueue, danaPump, pumpSync, detailedBolusInfoStorage, temporaryBasalStorage,
fabricPrivacy, dateUtil, uiInteraction, danaHistoryDatabase, decimalFormatter
)
insightPlugin = LocalInsightPlugin(injector, aapsLogger, rxBus, rh, sp, commandQueue, profileFunction, context, config, dateUtil, insightDbHelper, pumpSync, insightDatabase)
openAPSSMBPlugin =
@ -228,18 +214,8 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
)
safetyPlugin =
SafetyPlugin(
injector,
aapsLogger,
rh,
sp,
rxBus,
constraintChecker,
activePlugin,
hardLimits,
ConfigImpl(fileListProvider),
iobCobCalculator,
dateUtil,
uiInteraction
injector, aapsLogger, rh, sp, constraintChecker, activePlugin, hardLimits,
ConfigImpl(fileListProvider), iobCobCalculator, dateUtil, uiInteraction, decimalFormatter
)
val constraintsPluginsList = ArrayList<PluginBase>()
constraintsPluginsList.add(safetyPlugin)
@ -261,9 +237,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
comboPlugin.setPluginEnabled(PluginType.PUMP, true)
comboPlugin.setValidBasalRateProfileSelectedOnPump(false)
val c = constraintChecker.isLoopInvocationAllowed()
Assertions.assertEquals(true, c.reasonList.size == 2) // Combo & Objectives
Assertions.assertEquals(true, c.mostLimitedReasonList.size == 2) // Combo & Objectives
Assertions.assertEquals(java.lang.Boolean.FALSE, c.value())
assertThat(c.reasonList).hasSize(2) // Combo & Objectives
assertThat(c.mostLimitedReasonList).hasSize(2) // Combo & Objectives
assertThat(c.value()).isFalse()
}
// Safety & Objectives
@ -274,13 +250,13 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
objectivesPlugin.objectives[Objectives.MAXIOB_ZERO_CL_OBJECTIVE].startedOn = 0
var c: Constraint<Boolean> = constraintChecker.isClosedLoopAllowed()
aapsLogger.debug("Reason list: " + c.reasonList.toString())
// Assertions.assertTrue(c.reasonList[0].toString().contains("Closed loop is disabled")) // Safety & Objectives
Assertions.assertEquals(false, c.value())
// assertThat(c.reasonList[0].toString()).contains("Closed loop is disabled") // Safety & Objectives
assertThat(c.value()).isFalse()
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.OPEN.name)
c = constraintChecker.isClosedLoopAllowed()
Assertions.assertTrue(c.reasonList[0].contains("Closed loop mode disabled in preferences")) // Safety & Objectives
// Assertions.assertEquals(3, c.reasonList.size) // 2x Safety & Objectives
Assertions.assertEquals(false, c.value())
assertThat(c.reasonList[0]).contains("Closed loop mode disabled in preferences") // Safety & Objectives
// assertThat(c.reasonList).hasThat(3) // 2x Safety & Objectives
assertThat(c.value()).isFalse()
}
// Safety & Objectives
@ -290,9 +266,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
objectivesPlugin.objectives[Objectives.AUTOSENS_OBJECTIVE].startedOn = 0
`when`(sp.getBoolean(info.nightscout.plugins.aps.R.string.key_openapsama_use_autosens, false)).thenReturn(false)
val c = constraintChecker.isAutosensModeEnabled()
Assertions.assertEquals(true, c.reasonList.size == 2) // Safety & Objectives
Assertions.assertEquals(true, c.mostLimitedReasonList.size == 2) // Safety & Objectives
Assertions.assertEquals(java.lang.Boolean.FALSE, c.value())
assertThat(c.reasonList).hasSize(2) // Safety & Objectives
assertThat(c.mostLimitedReasonList).hasSize(2) // Safety & Objectives
assertThat( c.value()).isFalse()
}
// Safety
@ -300,9 +276,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
fun isAdvancedFilteringEnabledTest() {
`when`(activePlugin.activeBgSource).thenReturn(glimpPlugin)
val c = constraintChecker.isAdvancedFilteringEnabled()
Assertions.assertEquals(true, c.reasonList.size == 1) // Safety
Assertions.assertEquals(true, c.mostLimitedReasonList.size == 1) // Safety
Assertions.assertEquals(false, c.value())
assertThat(c.reasonList).hasSize(1) // Safety
assertThat(c.mostLimitedReasonList).hasSize(1) // Safety
assertThat( c.value()).isFalse()
}
// SMB should limit
@ -310,7 +286,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
fun isSuperBolusEnabledTest() {
openAPSSMBPlugin.setPluginEnabled(PluginType.APS, true)
val c = constraintChecker.isSuperBolusEnabled()
Assertions.assertEquals(java.lang.Boolean.FALSE, c.value()) // SMB should limit
assertThat( c.value()).isFalse() // SMB should limit
}
// Safety & Objectives
@ -322,9 +298,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.OPEN.name)
// `when`(constraintChecker.isClosedLoopAllowed()).thenReturn(Constraint(true))
val c = constraintChecker.isSMBModeEnabled()
Assertions.assertEquals(true, c.reasonList.size == 3) // 2x Safety & Objectives
Assertions.assertEquals(true, c.mostLimitedReasonList.size == 3) // 2x Safety & Objectives
Assertions.assertEquals(false, c.value())
assertThat(c.reasonList).hasSize(3) // 2x Safety & Objectives
assertThat(c.mostLimitedReasonList).hasSize(3) // 2x Safety & Objectives
assertThat( c.value()).isFalse()
}
// applyBasalConstraints tests
@ -350,9 +326,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
// Apply all limits
val d = constraintChecker.getMaxBasalAllowed(validProfile)
Assertions.assertEquals(0.8, d.value(), 0.01)
Assertions.assertEquals(3, d.reasonList.size)
Assertions.assertEquals("DanaR: Limiting max basal rate to 0.80 U/h because of pump limit", d.getMostLimitedReasons(aapsLogger))
assertThat( d.value()).isWithin( 0.01).of(0.8)
assertThat(d.reasonList).hasSize(3)
assertThat(d.getMostLimitedReasons(aapsLogger)).isEqualTo("DanaR: Limiting max basal rate to 0.80 U/h because of pump limit")
}
@Test
@ -377,9 +353,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
// Apply all limits
val i = constraintChecker.getMaxBasalPercentAllowed(validProfile)
Assertions.assertEquals(200, i.value())
Assertions.assertEquals(6, i.reasonList.size)
Assertions.assertEquals("Safety: Limiting max percent rate to 200% because of pump limit", i.getMostLimitedReasons(aapsLogger))
assertThat(i.value()).isEqualTo(200)
assertThat(i.reasonList).hasSize(6)
assertThat(i.getMostLimitedReasons(aapsLogger)).isEqualTo("Safety: Limiting max percent rate to 200% because of pump limit")
}
// applyBolusConstraints tests
@ -404,9 +380,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
// Apply all limits
val d = constraintChecker.getMaxBolusAllowed()
Assertions.assertEquals(3.0, d.value(), 0.01)
Assertions.assertEquals(4, d.reasonList.size) // 2x Safety & RS & R
Assertions.assertEquals("Safety: Limiting bolus to 3.0 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
assertThat( d.value()).isWithin( 0.01).of(3.0)
assertThat(d.reasonList).hasSize(4) // 2x Safety & RS & R
assertThat(d.getMostLimitedReasons(aapsLogger)).isEqualTo("Safety: Limiting bolus to 3.0 U because of max value in preferences")
}
// applyCarbsConstraints tests
@ -417,9 +393,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
// Apply all limits
val i = constraintChecker.getMaxCarbsAllowed()
Assertions.assertEquals(48, i.value())
Assertions.assertEquals(true, i.reasonList.size == 1)
Assertions.assertEquals("Safety: Limiting carbs to 48 g because of max value in preferences", i.getMostLimitedReasons(aapsLogger))
assertThat(i.value()).isEqualTo(48)
assertThat(i.reasonList).hasSize(1)
assertThat(i.getMostLimitedReasons(aapsLogger)).isEqualTo("Safety: Limiting carbs to 48 g because of max value in preferences")
}
// applyMaxIOBConstraints tests
@ -434,9 +410,9 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
// Apply all limits
val d = constraintChecker.getMaxIOBAllowed()
Assertions.assertEquals(1.5, d.value(), 0.01)
Assertions.assertEquals(2, d.reasonList.size)
Assertions.assertEquals("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
assertThat( d.value()).isWithin( 0.01).of(1.5)
assertThat(d.reasonList).hasSize(2)
assertThat(d.getMostLimitedReasons(aapsLogger)).isEqualTo("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences")
}
@Test
@ -450,8 +426,8 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
// Apply all limits
val d = constraintChecker.getMaxIOBAllowed()
Assertions.assertEquals(3.0, d.value(), 0.01)
Assertions.assertEquals(2, d.reasonList.size)
Assertions.assertEquals("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
assertThat( d.value()).isWithin( 0.01).of(3.0)
assertThat(d.reasonList).hasSize(2)
assertThat(d.getMostLimitedReasons(aapsLogger)).isEqualTo("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences")
}
}

View file

@ -1,5 +1,6 @@
package info.nightscout.plugins.safety
import com.google.common.truth.Truth.assertThat
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.database.impl.AppRepository
@ -21,7 +22,6 @@ import info.nightscout.plugins.constraints.safety.SafetyPlugin
import info.nightscout.pump.virtual.VirtualPumpPlugin
import info.nightscout.sharedtests.TestBaseWithProfile
import info.nightscout.source.GlimpPlugin
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.Mock
@ -72,7 +72,7 @@ class SafetyPluginTest : TestBaseWithProfile() {
`when`(activePlugin.activePump).thenReturn(virtualPumpPlugin)
`when`(virtualPumpPlugin.pumpDescription).thenReturn(pumpDescription)
`when`(config.APS).thenReturn(true)
safetyPlugin = SafetyPlugin(injector, aapsLogger, rh, sp, rxBus, constraintChecker, activePlugin, hardLimits, config, iobCobCalculator, dateUtil, uiInteraction)
safetyPlugin = SafetyPlugin(injector, aapsLogger, rh, sp, constraintChecker, activePlugin, hardLimits, config, iobCobCalculator, dateUtil, uiInteraction, decimalFormatter)
openAPSAMAPlugin = OpenAPSAMAPlugin(
injector, aapsLogger, rxBus, constraintChecker, rh, profileFunction, context, activePlugin, iobCobCalculator, hardLimits, profiler, fabricPrivacy,
dateUtil, repository, glucoseStatusProvider, sp
@ -88,8 +88,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
pumpDescription.isTempBasalCapable = false
var c = Constraint(true)
c = safetyPlugin.isLoopInvocationAllowed(c)
Assertions.assertEquals("Safety: Pump is not temp basal capable", c.getReasons(aapsLogger))
Assertions.assertEquals(false, c.value())
assertThat(c.getReasons(aapsLogger)).isEqualTo("Safety: Pump is not temp basal capable")
assertThat(c.value()).isFalse()
}
@Test
@ -98,8 +98,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
`when`(config.isEngineeringModeOrRelease()).thenReturn(false)
var c = Constraint(true)
c = safetyPlugin.isClosedLoopAllowed(c)
Assertions.assertTrue(c.getReasons(aapsLogger).contains("Running dev version. Closed loop is disabled."))
Assertions.assertEquals(false, c.value())
assertThat(c.getReasons(aapsLogger)).contains("Running dev version. Closed loop is disabled.")
assertThat(c.value()).isFalse()
}
@Test
@ -107,8 +107,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
`when`(sp.getString(info.nightscout.core.utils.R.string.key_aps_mode, ApsMode.OPEN.name)).thenReturn(ApsMode.OPEN.name)
var c = Constraint(true)
c = safetyPlugin.isClosedLoopAllowed(c)
Assertions.assertTrue(c.getReasons(aapsLogger).contains("Closed loop mode disabled in preferences"))
Assertions.assertEquals(false, c.value())
assertThat(c.getReasons(aapsLogger)).contains("Closed loop mode disabled in preferences")
assertThat(c.value()).isFalse()
}
@Test
@ -117,8 +117,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
`when`(constraintChecker.isClosedLoopAllowed(anyObject())).thenReturn(Constraint(true))
var c = Constraint(true)
c = openAPSSMBPlugin.isSMBModeEnabled(c)
Assertions.assertTrue(c.getReasons(aapsLogger).contains("SMB disabled in preferences"))
Assertions.assertEquals(false, c.value())
assertThat(c.getReasons(aapsLogger)).contains("SMB disabled in preferences")
assertThat(c.value()).isFalse()
}
@Test
@ -127,8 +127,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
`when`(constraintChecker.isClosedLoopAllowed(anyObject())).thenReturn(Constraint(false))
var c = Constraint(true)
c = safetyPlugin.isSMBModeEnabled(c)
Assertions.assertTrue(c.getReasons(aapsLogger).contains("SMB not allowed in open loop mode"))
Assertions.assertEquals(false, c.value())
assertThat(c.getReasons(aapsLogger)).contains("SMB not allowed in open loop mode")
assertThat(c.value()).isFalse()
}
@Test
@ -136,8 +136,8 @@ class SafetyPluginTest : TestBaseWithProfile() {
`when`(activePlugin.activeBgSource).thenReturn(glimpPlugin)
var c = Constraint(true)
c = safetyPlugin.isAdvancedFilteringEnabled(c)
Assertions.assertEquals("Safety: SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering", c.getReasons(aapsLogger))
Assertions.assertEquals(false, c.value())
assertThat(c.getReasons(aapsLogger)).isEqualTo("Safety: SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering")
assertThat(c.value()).isFalse()
}
@Test
@ -148,13 +148,12 @@ class SafetyPluginTest : TestBaseWithProfile() {
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
val c = Constraint(Constants.REALLYHIGHBASALRATE)
safetyPlugin.applyBasalConstraints(c, validProfile)
Assertions.assertEquals(2.0, c.value(), 0.01)
Assertions.assertEquals(
assertThat(c.value()).isWithin(0.01).of(2.0)
assertThat(c.getReasons(aapsLogger)).isEqualTo(
"""
Safety: Limiting max basal rate to 2.00 U/h because of hard limit
""".trimIndent(), c.getReasons(aapsLogger)
)
Assertions.assertEquals("Safety: Limiting max basal rate to 2.00 U/h because of hard limit", c.getMostLimitedReasons(aapsLogger))
""".trimIndent())
assertThat(c.getMostLimitedReasons(aapsLogger)).isEqualTo("Safety: Limiting max basal rate to 2.00 U/h because of hard limit")
}
@Test
@ -162,8 +161,9 @@ class SafetyPluginTest : TestBaseWithProfile() {
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
val d = Constraint(-0.5)
safetyPlugin.applyBasalConstraints(d, validProfile)
Assertions.assertEquals(0.0, d.value(), 0.01)
Assertions.assertEquals("Safety: Limiting max basal rate to 0.00 U/h because of it must be positive value", d.getReasons(aapsLogger))
assertThat(d.value()).isWithin(0.01).of(0.0)
assertThat(d.getReasons(aapsLogger)).isEqualTo(
"Safety: Limiting max basal rate to 0.00 U/h because of it must be positive value")
}
@Test
@ -175,16 +175,17 @@ class SafetyPluginTest : TestBaseWithProfile() {
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
val i = Constraint(Constants.REALLYHIGHPERCENTBASALRATE)
safetyPlugin.applyBasalPercentConstraints(i, validProfile)
Assertions.assertEquals(200, i.value())
Assertions.assertEquals(
assertThat(i.value()).isEqualTo(200)
assertThat(i.getReasons(aapsLogger)).isEqualTo(
"""
Safety: Percent rate 1111111% recalculated to 11111.11 U/h with current basal 1.00 U/h
Safety: Limiting max basal rate to 2.00 U/h because of hard limit
Safety: Limiting max percent rate to 200% because of pump limit
Safety: Limiting max basal rate to 500.00 U/h because of pump limit
""".trimIndent(), i.getReasons(aapsLogger)
""".trimIndent()
)
Assertions.assertEquals("Safety: Limiting max percent rate to 200% because of pump limit", i.getMostLimitedReasons(aapsLogger))
assertThat(i.getMostLimitedReasons(aapsLogger)).isEqualTo(
"Safety: Limiting max percent rate to 200% because of pump limit")
}
@Test
@ -197,15 +198,14 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
openAPSSMBPlugin.setPluginEnabled(PluginType.APS, true)
val i = Constraint(Constants.REALLYHIGHBASALRATE)
openAPSSMBPlugin.applyBasalConstraints(i, validProfile)
Assertions.assertEquals(1.0, i.value(), 0.01)
Assertions.assertEquals(
assertThat(i.value()).isWithin(0.01).of(1.0)
assertThat(i.getReasons(aapsLogger)).isEqualTo(
"""
OpenAPSSMB: Limiting max basal rate to 1.00 U/h because of max value in preferences
OpenAPSSMB: Limiting max basal rate to 4.00 U/h because of max basal multiplier
OpenAPSSMB: Limiting max basal rate to 3.00 U/h because of max daily basal multiplier
""".trimIndent(), i.getReasons(aapsLogger)
)
Assertions.assertEquals("OpenAPSSMB: Limiting max basal rate to 1.00 U/h because of max value in preferences", i.getMostLimitedReasons(aapsLogger))
""".trimIndent())
assertThat(i.getMostLimitedReasons(aapsLogger)).isEqualTo("OpenAPSSMB: Limiting max basal rate to 1.00 U/h because of max value in preferences")
}
@Test
@ -213,15 +213,14 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
val i = Constraint(-22)
safetyPlugin.applyBasalPercentConstraints(i, validProfile)
Assertions.assertEquals(0, i.value())
Assertions.assertEquals(
assertThat(i.value()).isEqualTo(0)
assertThat(i.getReasons(aapsLogger)).isEqualTo(
"""
Safety: Percent rate -22% recalculated to -0.22 U/h with current basal 1.00 U/h
Safety: Limiting max basal rate to 0.00 U/h because of it must be positive value
Safety: Limiting max percent rate to 0% because of pump limit
""".trimIndent(), i.getReasons(aapsLogger)
)
Assertions.assertEquals("Safety: Limiting max percent rate to 0% because of pump limit", i.getMostLimitedReasons(aapsLogger))
""".trimIndent())
assertThat(i.getMostLimitedReasons(aapsLogger)).isEqualTo("Safety: Limiting max percent rate to 0% because of pump limit")
}
@Test
@ -230,14 +229,13 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
var d = Constraint(Constants.REALLYHIGHBOLUS)
d = safetyPlugin.applyBolusConstraints(d)
Assertions.assertEquals(3.0, d.value(), 0.01)
Assertions.assertEquals(
assertThat(d.value()).isWithin(0.01).of(3.0)
assertThat(d.getReasons(aapsLogger)).isEqualTo(
"""
Safety: Limiting bolus to 3.0 U because of max value in preferences
Safety: Limiting bolus to 5.0 U because of hard limit
""".trimIndent(), d.getReasons(aapsLogger)
)
Assertions.assertEquals("Safety: Limiting bolus to 3.0 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
""".trimIndent())
assertThat(d.getMostLimitedReasons(aapsLogger)).isEqualTo("Safety: Limiting bolus to 3.0 U because of max value in preferences")
}
@Test
@ -246,9 +244,9 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
`when`(sp.getString(info.nightscout.core.utils.R.string.key_age, "")).thenReturn("child")
var d = Constraint(-22.0)
d = safetyPlugin.applyBolusConstraints(d)
Assertions.assertEquals(0.0, d.value(), 0.01)
Assertions.assertEquals("Safety: Limiting bolus to 0.0 U because of it must be positive value", d.getReasons(aapsLogger))
Assertions.assertEquals("Safety: Limiting bolus to 0.0 U because of it must be positive value", d.getMostLimitedReasons(aapsLogger))
assertThat(d.value()).isWithin(0.01).of(0.0)
assertThat(d.getReasons(aapsLogger)).isEqualTo("Safety: Limiting bolus to 0.0 U because of it must be positive value")
assertThat(d.getMostLimitedReasons(aapsLogger)).isEqualTo("Safety: Limiting bolus to 0.0 U because of it must be positive value")
}
@Test
@ -259,13 +257,13 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
// Negative carbs not allowed
var i = Constraint(-22)
safetyPlugin.applyCarbsConstraints(i)
Assertions.assertEquals(0, i.value())
Assertions.assertEquals("Safety: Limiting carbs to 0 g because of it must be positive value", i.getReasons(aapsLogger))
assertThat(i.value()).isEqualTo(0)
assertThat(i.getReasons(aapsLogger)).isEqualTo("Safety: Limiting carbs to 0 g because of it must be positive value")
// Apply all limits
i = safetyPlugin.applyCarbsConstraints(Constraint(Constants.REALLYHIGHCARBS))
Assertions.assertEquals(48, i.value())
Assertions.assertEquals("Safety: Limiting carbs to 48 g because of max value in preferences", i.getReasons(aapsLogger))
assertThat(i.value()).isEqualTo(48)
assertThat(i.getReasons(aapsLogger)).isEqualTo("Safety: Limiting carbs to 48 g because of max value in preferences")
}
@Test
@ -282,22 +280,22 @@ Safety: Limiting max basal rate to 500.00 U/h because of pump limit
// Apply all limits
var d = Constraint(Constants.REALLYHIGHIOB)
d = safetyPlugin.applyMaxIOBConstraints(d)
Assertions.assertEquals(HardLimits.MAX_IOB_LGS, d.value(), 0.01)
Assertions.assertEquals("Safety: Limiting IOB to 0.0 U because of Low Glucose Suspend", d.getReasons(aapsLogger))
Assertions.assertEquals("Safety: Limiting IOB to 0.0 U because of Low Glucose Suspend", d.getMostLimitedReasons(aapsLogger))
assertThat(d.value()).isWithin(0.01).of(HardLimits.MAX_IOB_LGS)
assertThat(d.getReasons(aapsLogger)).isEqualTo("Safety: Limiting IOB to 0.0 U because of Low Glucose Suspend")
assertThat(d.getMostLimitedReasons(aapsLogger)).isEqualTo("Safety: Limiting IOB to 0.0 U because of Low Glucose Suspend")
// Apply all limits
d = Constraint(Constants.REALLYHIGHIOB)
val a = openAPSAMAPlugin.applyMaxIOBConstraints(d)
Assertions.assertEquals(1.5, a.value(), 0.01)
Assertions.assertEquals("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences\nOpenAPSAMA: Limiting IOB to 7.0 U because of hard limit", d.getReasons(aapsLogger))
Assertions.assertEquals("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
assertThat(a.value()).isWithin(0.01).of(1.5)
assertThat(d.getReasons(aapsLogger)).isEqualTo("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences\nOpenAPSAMA: Limiting IOB to 7.0 U because of hard limit")
assertThat(d.getMostLimitedReasons(aapsLogger)).isEqualTo("OpenAPSAMA: Limiting IOB to 1.5 U because of max value in preferences")
// Apply all limits
d = Constraint(Constants.REALLYHIGHIOB)
val s = openAPSSMBPlugin.applyMaxIOBConstraints(d)
Assertions.assertEquals(3.0, s.value(), 0.01)
Assertions.assertEquals("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences\nOpenAPSSMB: Limiting IOB to 22.0 U because of hard limit", d.getReasons(aapsLogger))
Assertions.assertEquals("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences", d.getMostLimitedReasons(aapsLogger))
assertThat(s.value()).isWithin(0.01).of(3.0)
assertThat(d.getReasons(aapsLogger)).isEqualTo("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences\nOpenAPSSMB: Limiting IOB to 22.0 U because of hard limit")
assertThat(d.getMostLimitedReasons(aapsLogger)).isEqualTo("OpenAPSSMB: Limiting IOB to 3.0 U because of max value in preferences")
}
}

View file

@ -159,15 +159,15 @@ class PumpEnactResultTest : TestBaseWithProfile() {
@Test fun toHtmlTest() {
var per: PumpEnactResult = PumpEnactResult(injector).enacted(true).bolusDelivered(10.0).comment("AAA")
Assertions.assertEquals("<b>Success</b>: false<br><b>Enacted</b>: true<br><b>Comment</b>: AAA<br><b>SMB</b>: 10.0 U", per.toHtml(rh))
Assertions.assertEquals("<b>Success</b>: false<br><b>Enacted</b>: true<br><b>Comment</b>: AAA<br><b>SMB</b>: 10.0 U", per.toHtml(rh, decimalFormatter))
per = PumpEnactResult(injector).enacted(true).isTempCancel(true).comment("AAA")
Assertions.assertEquals("<b>Success</b>: false<br><b>Enacted</b>: true<br><b>Comment</b>: AAA<br>Cancel temp basal", per.toHtml(rh))
Assertions.assertEquals("<b>Success</b>: false<br><b>Enacted</b>: true<br><b>Comment</b>: AAA<br>Cancel temp basal", per.toHtml(rh, decimalFormatter))
per = PumpEnactResult(injector).enacted(true).isPercent(true).percent(90).duration(20).comment("AAA")
Assertions.assertEquals("<b>Success</b>: false<br><b>Enacted</b>: true<br><b>Comment</b>: AAA<br><b>Duration</b>: 20 min<br><b>Percent</b>: 90%", per.toHtml(rh))
Assertions.assertEquals("<b>Success</b>: false<br><b>Enacted</b>: true<br><b>Comment</b>: AAA<br><b>Duration</b>: 20 min<br><b>Percent</b>: 90%", per.toHtml(rh, decimalFormatter))
per = PumpEnactResult(injector).enacted(true).isPercent(false).absolute(1.0).duration(30).comment("AAA")
Assertions.assertEquals("<b>Success</b>: false<br><b>Enacted</b>: true<br><b>Comment</b>: AAA<br><b>Duration</b>: 30 min<br><b>Absolute</b>: 1.00 U/h", per.toHtml(rh))
Assertions.assertEquals("<b>Success</b>: false<br><b>Enacted</b>: true<br><b>Comment</b>: AAA<br><b>Duration</b>: 30 min<br><b>Absolute</b>: 1.00 U/h", per.toHtml(rh, decimalFormatter))
per = PumpEnactResult(injector).enacted(false).comment("AAA")
Assertions.assertEquals("<b>Success</b>: false<br><b>Comment</b>: AAA", per.toHtml(rh))
Assertions.assertEquals("<b>Success</b>: false<br><b>Comment</b>: AAA", per.toHtml(rh, decimalFormatter))
}
@Test fun jsonTest() {

View file

@ -12,7 +12,8 @@ class BolusDataPoint(
val data: Bolus,
private val rh: ResourceHelper,
private val activePlugin: ActivePlugin,
private val defaultValueHelper: DefaultValueHelper
private val defaultValueHelper: DefaultValueHelper,
private val decimalFormatter: DecimalFormatter
) : DataPointWithLabelInterface {
private var yValue = 0.0
@ -20,7 +21,7 @@ class BolusDataPoint(
override fun getX(): Double = data.timestamp.toDouble()
override fun getY(): Double = if (data.type == Bolus.Type.SMB) defaultValueHelper.determineLowLine() else yValue
override val label
get() = DecimalFormatter.toPumpSupportedBolus(data.amount, activePlugin.activePump, rh)
get() = decimalFormatter.toPumpSupportedBolus(data.amount, activePlugin.activePump.pumpDescription.bolusStep)
override val duration = 0L
override val size = 2f
override val paintStyle: Paint.Style = Paint.Style.FILL // not used

View file

@ -8,7 +8,8 @@ import info.nightscout.shared.interfaces.ResourceHelper
class ExtendedBolusDataPoint(
val data: ExtendedBolus,
private val rh: ResourceHelper
private val rh: ResourceHelper,
private val decimalFormatter: DecimalFormatter
) : DataPointWithLabelInterface {
private var yValue = 0.0
@ -28,5 +29,5 @@ class ExtendedBolusDataPoint(
yValue = y
}
private fun ExtendedBolus.toStringTotal(): String = "${DecimalFormatter.to2Decimal(amount)}U ( ${DecimalFormatter.to2Decimal(rate)} U/h )"
private fun ExtendedBolus.toStringTotal(): String = "${decimalFormatter.to2Decimal(amount)}U ( ${decimalFormatter.to2Decimal(rate)} U/h )"
}

View file

@ -5,24 +5,23 @@ import android.graphics.Paint
import info.nightscout.database.entities.GlucoseValue
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
class GlucoseValueDataPoint(
val data: GlucoseValue,
private val profileFunction: ProfileFunction,
private val rh: ResourceHelper
private val profileUtil: ProfileUtil,
private val rh: ResourceHelper,
) : DataPointWithLabelInterface {
private fun valueToUnits(units: GlucoseUnit): Double =
if (units == GlucoseUnit.MGDL) data.value else data.value * Constants.MGDL_TO_MMOLL
override fun getX(): Double = data.timestamp.toDouble()
override fun getY(): Double = valueToUnits(profileFunction.getUnits())
override fun getY(): Double = valueToUnits(profileUtil.units)
override fun setY(y: Double) {}
override val label: String = Profile.toCurrentUnitsString(profileFunction, data.value)
override val label: String = profileUtil.fromMgdlToStringInUnits(data.value)
override val duration = 0L
override val shape get() = if (isPrediction) PointsWithLabelGraphSeries.Shape.PREDICTION else PointsWithLabelGraphSeries.Shape.BG
override val size = if (isPrediction) 1f else 0.6f

View file

@ -5,14 +5,13 @@ import android.graphics.Paint
import info.nightscout.database.entities.TherapyEvent
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.Translator
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
class TherapyEventDataPoint(
val data: TherapyEvent,
private val rh: ResourceHelper,
private val profileFunction: ProfileFunction,
private val profileUtil: ProfileUtil,
private val translator: Translator
) : DataPointWithLabelInterface {
@ -21,20 +20,13 @@ class TherapyEventDataPoint(
override fun getX(): Double = data.timestamp.toDouble()
override fun getY(): Double {
val units = profileFunction.getUnits()
if (data.type == TherapyEvent.Type.NS_MBG) return Profile.fromMgdlToUnits(data.glucose!!, units)
if (data.type == TherapyEvent.Type.NS_MBG) return profileUtil.fromMgdlToUnits(data.glucose!!)
if (data.glucose != null && data.glucose != 0.0) {
var mmol = 0.0
var mgdl = 0.0
if (data.glucoseUnit == TherapyEvent.GlucoseUnit.MGDL) {
mgdl = data.glucose!!
mmol = data.glucose!! * Constants.MGDL_TO_MMOLL
val mgdl: Double = when (data.glucoseUnit) {
TherapyEvent.GlucoseUnit.MGDL -> data.glucose!!
TherapyEvent.GlucoseUnit.MMOL -> data.glucose!! * Constants.MMOLL_TO_MGDL
}
if (data.glucoseUnit == TherapyEvent.GlucoseUnit.MMOL) {
mmol = data.glucose!!
mgdl = data.glucose!! * Constants.MMOLL_TO_MGDL
}
return Profile.toUnits(mgdl, mmol, units)
return profileUtil.fromMgdlToUnits(mgdl)
}
return yValue
}

View file

@ -1,2 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>
<resources>
<string name="format_carbs">%1$d g</string>
</resources>

View file

@ -1,12 +0,0 @@
package info.nightscout.interfaces
enum class GlucoseUnit(val asText: String) {
MGDL(Constants.MGDL),
MMOL(Constants.MMOL);
companion object {
fun fromText(name: String) = values().firstOrNull { it.asText == name } ?: MGDL
}
}

View file

@ -1,10 +1,8 @@
package info.nightscout.interfaces.profile
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.pump.Pump
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.interfaces.utils.Round
import info.nightscout.rx.bus.RxBus
@ -133,62 +131,4 @@ interface Profile {
return result
}
}
companion object {
/*
* Units conversion
*/
fun fromMgdlToUnits(value: Double, units: GlucoseUnit): Double =
if (units == GlucoseUnit.MGDL) value else value * Constants.MGDL_TO_MMOLL
fun fromMmolToUnits(value: Double, units: GlucoseUnit): Double =
if (units == GlucoseUnit.MMOL) value else value * Constants.MMOLL_TO_MGDL
fun toUnits(valueInMgdl: Double, valueInMmol: Double, units: GlucoseUnit): Double =
if (units == GlucoseUnit.MGDL) valueInMgdl else valueInMmol
fun toUnitsString(valueInMgdl: Double, valueInMmol: Double, units: GlucoseUnit): String =
if (units == GlucoseUnit.MGDL) DecimalFormatter.to0Decimal(valueInMgdl) else DecimalFormatter.to1Decimal(valueInMmol)
fun toSignedUnitsString(valueInMgdl: Double, valueInMmol: Double, units: GlucoseUnit): String =
if (units == GlucoseUnit.MGDL) (if (valueInMgdl > 0) "+" else "") + DecimalFormatter.to0Decimal(valueInMgdl)
else (if (valueInMmol > 0) "+" else "") + DecimalFormatter.to1Decimal(valueInMmol)
fun isMgdl(anyBg: Double) = anyBg >= 39
fun isMmol(anyBg: Double) = anyBg < 39
fun unit(anyBg: Double) = if (isMgdl(anyBg)) GlucoseUnit.MGDL else GlucoseUnit.MMOL
fun toCurrentUnits(profileFunction: ProfileFunction, anyBg: Double): Double =
if (isMmol(anyBg)) fromMmolToUnits(anyBg, profileFunction.getUnits())
else fromMgdlToUnits(anyBg, profileFunction.getUnits())
fun toCurrentUnits(units: GlucoseUnit, anyBg: Double): Double =
if (isMmol(anyBg)) fromMmolToUnits(anyBg, units)
else fromMgdlToUnits(anyBg, units)
fun toCurrentUnitsString(profileFunction: ProfileFunction, anyBg: Double): String =
if (isMmol(anyBg)) toUnitsString(anyBg * Constants.MMOLL_TO_MGDL, anyBg, profileFunction.getUnits())
else toUnitsString(anyBg, anyBg * Constants.MGDL_TO_MMOLL, profileFunction.getUnits())
fun toMgdl(value: Double): Double =
if (isMgdl(value)) value else value * Constants.MMOLL_TO_MGDL
fun toMgdl(value: Double, units: GlucoseUnit): Double =
if (units == GlucoseUnit.MGDL) value else value * Constants.MMOLL_TO_MGDL
fun toMmol(value: Double, units: GlucoseUnit): Double =
if (units == GlucoseUnit.MGDL) value * Constants.MGDL_TO_MMOLL else value
// targets are stored in mg/dl but profile vary
fun toTargetRangeString(low: Double, high: Double, sourceUnits: GlucoseUnit, units: GlucoseUnit): String {
val lowMgdl = toMgdl(low, sourceUnits)
val highMgdl = toMgdl(high, sourceUnits)
val lowMmol = toMmol(low, sourceUnits)
val highMmol = toMmol(high, sourceUnits)
return if (low == high) toUnitsString(lowMgdl, lowMmol, units)
else toUnitsString(lowMgdl, lowMmol, units) + " - " + toUnitsString(highMgdl, highMmol, units)
}
}
}

View file

@ -91,10 +91,10 @@ interface PumpSync {
if (isAbsolute) rate
else profile.getBasal(time) * rate / 100
fun toStringFull(dateUtil: DateUtil): String {
fun toStringFull(dateUtil: DateUtil, decimalFormatter: DecimalFormatter): String {
return when {
isAbsolute -> {
DecimalFormatter.to2Decimal(rate) + "U/h @" +
decimalFormatter.to2Decimal(rate) + "U/h @" +
dateUtil.timeString(timestamp) +
" " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + durationInMinutes + "'"
}
@ -130,10 +130,12 @@ interface PumpSync {
val plannedRemainingMinutes: Long
get() = max(T.msecs(end - System.currentTimeMillis()).mins(), 0L)
private fun getPassedDurationToTimeInMinutes(time: Long): Int =
((min(time, end) - timestamp) / 60.0 / 1000).roundToInt()
fun toStringFull(dateUtil: DateUtil): String =
"E " + DecimalFormatter.to2Decimal(rate) + "U/h @" +
fun toStringFull(dateUtil: DateUtil, decimalFormatter: DecimalFormatter): String =
"E " + decimalFormatter.to2Decimal(rate) + "U/h @" +
dateUtil.timeString(timestamp) +
" " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + T.msecs(duration).mins() + "min"
}

View file

@ -3,14 +3,14 @@ package info.nightscout.interfaces.stats
import android.content.Context
import android.widget.TableRow
import android.widget.TextView
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.interfaces.ProfileUtil
interface DexcomTIR {
fun calculateSD(): Double
fun toHbA1cView(context: Context): TextView
fun toSDView(context: Context, profileFunction: ProfileFunction): TextView
fun toRangeHeaderView(context: Context, profileFunction: ProfileFunction): TextView
fun toSDView(context: Context, profileUtil: ProfileUtil): TextView
fun toRangeHeaderView(context: Context, profileUtil: ProfileUtil): TextView
fun toTableRowHeader(context: Context): TableRow
fun toTableRow(context: Context): TableRow
}

View file

@ -1,29 +0,0 @@
package info.nightscout.interfaces.utils
import info.nightscout.interfaces.R
import info.nightscout.interfaces.pump.Pump
import info.nightscout.shared.interfaces.ResourceHelper
import java.text.DecimalFormat
object DecimalFormatter {
private val format0dec = DecimalFormat("0")
private val format1dec = DecimalFormat("0.0")
private val format2dec = DecimalFormat("0.00")
private val format3dec = DecimalFormat("0.000")
fun to0Decimal(value: Double): String = format0dec.format(value)
fun to0Decimal(value: Double, unit: String): String = format0dec.format(value) + unit
fun to1Decimal(value: Double): String = format1dec.format(value)
fun to1Decimal(value: Double, unit: String): String = format1dec.format(value) + unit
fun to2Decimal(value: Double): String = format2dec.format(value)
fun to2Decimal(value: Double, unit: String): String = format2dec.format(value) + unit
fun to3Decimal(value: Double): String = format3dec.format(value)
fun to3Decimal(value: Double, unit: String): String = format3dec.format(value) + unit
fun toPumpSupportedBolus(value: Double, pump: Pump): String = if (pump.pumpDescription.bolusStep <= 0.051) to2Decimal(value) else to1Decimal(value)
fun toPumpSupportedBolus(value: Double, pump: Pump, rh: ResourceHelper): String =
if (pump.pumpDescription.bolusStep <= 0.051) rh.gs(R.string.format_insulin_units, value)
else rh.gs(R.string.format_insulin_units1, value)
fun pumpSupportedBolusFormat(pump: Pump): DecimalFormat = if (pump.pumpDescription.bolusStep <= 0.051) DecimalFormat("0.00") else DecimalFormat("0.0")
}

View file

@ -1,9 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Maintenance -->
<string name="metadata_label_format">Μορφή αρχείου</string>
<string name="metadata_label_created_at">Δημιουργήθηκε στις</string>
<string name="metadata_label_aaps_version">Έκδοση AAPS</string>
<string name="metadata_label_aaps_flavour">Δημιουργία Παραλλαγής</string>
<string name="metadata_label_device_name">Εξαγωγή ονόματος συσκευής ασθενούς </string>
<string name="metadata_label_device_model">Εξαγωγή μοντέλου συσκευής</string>
<string name="metadata_label_encryption">Κρυπτογράφηση αρχείων</string>
<string name="metadata_format_new">Νέα κρυπτογραφημένη μορφή</string>
<string name="metadata_format_debug">Νέα μορφή εντοπισμού σφαλμάτων (μη κρυπτογραφημένη)</string>
<string name="metadata_format_other">Άγνωστη μορφή εξαγωγής</string>
<!-- PumpType-->
<string name="def_extended_note">* Υποστηρίζονται μόνο διακριτές τιμές και όχι εύρος τιμών για βασικό/bolus στην εικονική αντλία.</string>
<!-- PumpPluginBase -->
<string name="pump_driver_changed" comment="26 characters max for translation">Ο οδηγός της αντλίας άλλαξε.</string>
<!-- DecimalFormatter-->
<string name="format_insulin_units1">%1$.1f U</string>
<string name="format_insulin_units">%1$.2f U</string>

View file

@ -23,12 +23,12 @@ fun ExtendedBolus.isInProgress(dateUtil: DateUtil): Boolean =
val ExtendedBolus.plannedRemainingMinutes: Int
get() = max(round((end - System.currentTimeMillis()) / 1000.0 / 60).toInt(), 0)
fun ExtendedBolus.toStringFull(dateUtil: DateUtil): String =
"E " + DecimalFormatter.to2Decimal(rate) + "U/h @" + dateUtil.timeString(timestamp) +
fun ExtendedBolus.toStringFull(dateUtil: DateUtil, decimalFormatter: DecimalFormatter): String =
"E " + decimalFormatter.to2Decimal(rate) + "U/h @" + dateUtil.timeString(timestamp) +
" " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + T.msecs(duration).mins() + "min"
fun ExtendedBolus.toStringMedium(dateUtil: DateUtil): String =
DecimalFormatter.to2Decimal(rate) + "U/h " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + T.msecs(duration).mins() + "'"
fun ExtendedBolus.toStringMedium(dateUtil: DateUtil, decimalFormatter: DecimalFormatter): String =
decimalFormatter.to2Decimal(rate) + "U/h " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + T.msecs(duration).mins() + "'"
fun ExtendedBolus.getPassedDurationToTimeInMinutes(time: Long): Int =
((min(time, end) - timestamp) / 60.0 / 1000).roundToInt()

View file

@ -5,14 +5,9 @@ import info.nightscout.database.entities.GlucoseValue
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.iob.InMemoryGlucoseValue
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.shared.utils.DateUtil
import org.json.JSONObject
fun GlucoseValue.valueToUnitsString(units: GlucoseUnit): String =
if (units == GlucoseUnit.MGDL) DecimalFormatter.to0Decimal(value)
else DecimalFormatter.to1Decimal(value * Constants.MGDL_TO_MMOLL)
fun GlucoseValue.toJson(isAdd: Boolean, dateUtil: DateUtil): JSONObject =
JSONObject()
.put("device", sourceSensor.text)
@ -28,10 +23,6 @@ fun InMemoryGlucoseValue.valueToUnits(units: GlucoseUnit): Double =
if (units == GlucoseUnit.MGDL) recalculated
else recalculated * Constants.MGDL_TO_MMOLL
fun InMemoryGlucoseValue.valueToUnitsString(units: GlucoseUnit): String =
if (units == GlucoseUnit.MGDL) DecimalFormatter.to0Decimal(recalculated)
else DecimalFormatter.to1Decimal(recalculated * Constants.MGDL_TO_MMOLL)
fun GlucoseValue.TrendArrow.directionToIcon(): Int =
when (this) {
GlucoseValue.TrendArrow.TRIPLE_DOWN -> R.drawable.ic_invalid

View file

@ -12,10 +12,10 @@ import info.nightscout.shared.utils.T
import org.json.JSONObject
import java.util.TimeZone
fun ProfileSwitch.getCustomizedName(): String {
fun ProfileSwitch.getCustomizedName(decimalFormatter: DecimalFormatter): String {
var name: String = profileName
if (Constants.LOCAL_PROFILE == name) {
name = DecimalFormatter.to2Decimal(ProfileSealed.PS(this).percentageBasalSum()) + "U "
name = decimalFormatter.to2Decimal(ProfileSealed.PS(this).percentageBasalSum()) + "U "
}
if (timeshift != 0L || percentage != 100) {
name += "($percentage%"

View file

@ -34,16 +34,16 @@ private fun TemporaryBasal.netExtendedRate(profile: Profile) = rate - profile.ge
val TemporaryBasal.durationInMinutes
get() = T.msecs(duration).mins()
fun TemporaryBasal.toStringFull(profile: Profile, dateUtil: DateUtil): String {
fun TemporaryBasal.toStringFull(profile: Profile, dateUtil: DateUtil, decimalFormatter: DecimalFormatter): String {
return when {
type == TemporaryBasal.Type.FAKE_EXTENDED -> {
DecimalFormatter.to2Decimal(rate) + "U/h (" + DecimalFormatter.to2Decimal(netExtendedRate(profile)) + "E) @" +
decimalFormatter.to2Decimal(rate) + "U/h (" + decimalFormatter.to2Decimal(netExtendedRate(profile)) + "E) @" +
dateUtil.timeString(timestamp) +
" " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + durationInMinutes + "'"
}
isAbsolute -> {
DecimalFormatter.to2Decimal(rate) + "U/h @" +
decimalFormatter.to2Decimal(rate) + "U/h @" +
dateUtil.timeString(timestamp) +
" " + getPassedDurationToTimeInMinutes(dateUtil.now()) + "/" + durationInMinutes + "'"
}
@ -56,9 +56,9 @@ fun TemporaryBasal.toStringFull(profile: Profile, dateUtil: DateUtil): String {
}
}
fun TemporaryBasal.toStringShort(): String =
if (isAbsolute || type == TemporaryBasal.Type.FAKE_EXTENDED) DecimalFormatter.to2Decimal(rate) + "U/h"
else "${DecimalFormatter.to0Decimal(rate)}%"
fun TemporaryBasal.toStringShort(decimalFormatter: DecimalFormatter): String =
if (isAbsolute || type == TemporaryBasal.Type.FAKE_EXTENDED) decimalFormatter.to2Decimal(rate) + "U/h"
else "${decimalFormatter.to0Decimal(rate)}%"
fun TemporaryBasal.iobCalc(time: Long, profile: Profile, insulinInterface: Insulin): IobTotal {
if (!isValid) return IobTotal(time)

View file

@ -3,23 +3,23 @@ package info.nightscout.core.extensions
import info.nightscout.database.entities.TemporaryTarget
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import java.util.concurrent.TimeUnit
fun TemporaryTarget.lowValueToUnitsToString(units: GlucoseUnit): String =
if (units == GlucoseUnit.MGDL) DecimalFormatter.to0Decimal(this.lowTarget)
else DecimalFormatter.to1Decimal(this.lowTarget * Constants.MGDL_TO_MMOLL)
fun TemporaryTarget.lowValueToUnitsToString(units: GlucoseUnit, decimalFormatter: DecimalFormatter): String =
if (units == GlucoseUnit.MGDL) decimalFormatter.to0Decimal(this.lowTarget)
else decimalFormatter.to1Decimal(this.lowTarget * Constants.MGDL_TO_MMOLL)
fun TemporaryTarget.highValueToUnitsToString(units: GlucoseUnit): String =
if (units == GlucoseUnit.MGDL) DecimalFormatter.to0Decimal(this.highTarget)
else DecimalFormatter.to1Decimal(this.highTarget * Constants.MGDL_TO_MMOLL)
fun TemporaryTarget.highValueToUnitsToString(units: GlucoseUnit, decimalFormatter: DecimalFormatter): String =
if (units == GlucoseUnit.MGDL) decimalFormatter.to0Decimal(this.highTarget)
else decimalFormatter.to1Decimal(this.highTarget * Constants.MGDL_TO_MMOLL)
fun TemporaryTarget.target(): Double =
(this.lowTarget + this.highTarget) / 2
fun TemporaryTarget.friendlyDescription(units: GlucoseUnit, rh: ResourceHelper): String =
Profile.toTargetRangeString(lowTarget, highTarget, GlucoseUnit.MGDL, units) +
fun TemporaryTarget.friendlyDescription(units: GlucoseUnit, rh: ResourceHelper, profileUtil: ProfileUtil): String =
profileUtil.toTargetRangeString(lowTarget, highTarget, GlucoseUnit.MGDL, units) +
units.asText +
"@" + rh.gs(info.nightscout.core.ui.R.string.format_mins, TimeUnit.MILLISECONDS.toMinutes(duration)) + "(" + reason.text + ")"

View file

@ -4,20 +4,20 @@ import info.nightscout.interfaces.iob.CobInfo
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.shared.interfaces.ResourceHelper
fun CobInfo.generateCOBString(): String {
fun CobInfo.generateCOBString(decimalFormatter: DecimalFormatter): String {
var cobStringResult = "--g"
displayCob?.let { displayCob ->
cobStringResult = DecimalFormatter.to0Decimal(displayCob)
cobStringResult = decimalFormatter.to0Decimal(displayCob)
if (futureCarbs > 0)
cobStringResult += "(${DecimalFormatter.to0Decimal(futureCarbs)})"
cobStringResult += "(${decimalFormatter.to0Decimal(futureCarbs)})"
cobStringResult += "g"
}
return cobStringResult
}
fun CobInfo.displayText(rh: ResourceHelper): String? =
fun CobInfo.displayText(rh: ResourceHelper, decimalFormatter: DecimalFormatter): String? =
displayCob?.let { displayCob ->
var cobText = rh.gs(info.nightscout.core.ui.R.string.format_carbs, displayCob.toInt())
if (futureCarbs > 0) cobText += "(" + DecimalFormatter.to0Decimal(futureCarbs) + ")"
if (futureCarbs > 0) cobText += "(" + decimalFormatter.to0Decimal(futureCarbs) + ")"
cobText
}

View file

@ -4,11 +4,11 @@ import info.nightscout.interfaces.iob.GlucoseStatus
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.Round
fun GlucoseStatus.log(): String = "Glucose: " + DecimalFormatter.to0Decimal(glucose) + " mg/dl " +
"Noise: " + DecimalFormatter.to0Decimal(noise) + " " +
"Delta: " + DecimalFormatter.to0Decimal(delta) + " mg/dl" +
"Short avg. delta: " + " " + DecimalFormatter.to2Decimal(shortAvgDelta) + " mg/dl " +
"Long avg. delta: " + DecimalFormatter.to2Decimal(longAvgDelta) + " mg/dl"
fun GlucoseStatus.log(decimalFormatter: DecimalFormatter): String = "Glucose: " + decimalFormatter.to0Decimal(glucose) + " mg/dl " +
"Noise: " + decimalFormatter.to0Decimal(noise) + " " +
"Delta: " + decimalFormatter.to0Decimal(delta) + " mg/dl" +
"Short avg. delta: " + " " + decimalFormatter.to2Decimal(shortAvgDelta) + " mg/dl " +
"Long avg. delta: " + decimalFormatter.to2Decimal(longAvgDelta) + " mg/dl"
fun GlucoseStatus.asRounded() = copy(
glucose = Round.roundTo(glucose, 0.1),

View file

@ -156,14 +156,20 @@ sealed class ProfileSealed(
break
}
for (isf in isfBlocks)
if (!hardLimits.isInRange(Profile.toMgdl(isf.amount * 100.0 / percentage, units), HardLimits.MIN_ISF, HardLimits.MAX_ISF)) {
if (!hardLimits.isInRange(toMgdl(isf.amount * 100.0 / percentage, units), HardLimits.MIN_ISF, HardLimits.MAX_ISF)) {
validityCheck.isValid = false
validityCheck.reasons.add(rh.gs(info.nightscout.core.ui.R.string.value_out_of_hard_limits, rh.gs(info.nightscout.core.ui.R.string.profile_sensitivity_value), isf.amount * 100.0 / percentage))
validityCheck.reasons.add(
rh.gs(
info.nightscout.core.ui.R.string.value_out_of_hard_limits,
rh.gs(info.nightscout.core.ui.R.string.profile_sensitivity_value),
isf.amount * 100.0 / percentage
)
)
break
}
for (target in targetBlocks) {
if (!hardLimits.isInRange(
Profile.toMgdl(target.lowTarget, units),
toMgdl(target.lowTarget, units),
HardLimits.VERY_HARD_LIMIT_MIN_BG[0],
HardLimits.VERY_HARD_LIMIT_MIN_BG[1]
)
@ -173,7 +179,7 @@ sealed class ProfileSealed(
break
}
if (!hardLimits.isInRange(
Profile.toMgdl(target.highTarget, units),
toMgdl(target.highTarget, units),
HardLimits.VERY_HARD_LIMIT_MAX_BG[0],
HardLimits.VERY_HARD_LIMIT_MAX_BG[1]
)
@ -227,23 +233,25 @@ sealed class ProfileSealed(
override fun getBasal(timestamp: Long): Double = basalBlocks.blockValueBySeconds(MidnightUtils.secondsFromMidnight(timestamp), percentage / 100.0, timeshift)
override fun getIc(): Double = icBlocks.blockValueBySeconds(MidnightUtils.secondsFromMidnight(), 100.0 / percentage, timeshift)
override fun getIc(timestamp: Long): Double = icBlocks.blockValueBySeconds(MidnightUtils.secondsFromMidnight(timestamp), 100.0 / percentage, timeshift)
override fun getIsfMgdl(): Double = Profile.toMgdl(isfBlocks.blockValueBySeconds(MidnightUtils.secondsFromMidnight(), 100.0 / percentage, timeshift), units)
override fun getIsfMgdl(timestamp: Long): Double = Profile.toMgdl(isfBlocks.blockValueBySeconds(MidnightUtils.secondsFromMidnight(timestamp), 100.0 / percentage, timeshift), units)
override fun getTargetMgdl(): Double = Profile.toMgdl(targetBlocks.targetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(), timeshift), units)
override fun getTargetLowMgdl(): Double = Profile.toMgdl(targetBlocks.lowTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(), timeshift), units)
override fun getTargetLowMgdl(timestamp: Long): Double = Profile.toMgdl(targetBlocks.lowTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(timestamp), timeshift), units)
override fun getTargetHighMgdl(): Double = Profile.toMgdl(targetBlocks.highTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(), timeshift), units)
override fun getTargetHighMgdl(timestamp: Long): Double = Profile.toMgdl(targetBlocks.highTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(timestamp), timeshift), units)
override fun getIsfMgdl(): Double = toMgdl(isfBlocks.blockValueBySeconds(MidnightUtils.secondsFromMidnight(), 100.0 / percentage, timeshift), units)
override fun getIsfMgdl(timestamp: Long): Double = toMgdl(isfBlocks.blockValueBySeconds(MidnightUtils.secondsFromMidnight(timestamp), 100.0 / percentage, timeshift), units)
override fun getTargetMgdl(): Double = toMgdl(targetBlocks.targetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(), timeshift), units)
override fun getTargetLowMgdl(): Double = toMgdl(targetBlocks.lowTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(), timeshift), units)
override fun getTargetLowMgdl(timestamp: Long): Double = toMgdl(targetBlocks.lowTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(timestamp), timeshift), units)
override fun getTargetHighMgdl(): Double = toMgdl(targetBlocks.highTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(), timeshift), units)
override fun getTargetHighMgdl(timestamp: Long): Double = toMgdl(targetBlocks.highTargetBlockValueBySeconds(MidnightUtils.secondsFromMidnight(timestamp), timeshift), units)
override fun getBasalTimeFromMidnight(timeAsSeconds: Int): Double = basalBlocks.blockValueBySeconds(timeAsSeconds, percentage / 100.0, timeshift)
override fun getIcTimeFromMidnight(timeAsSeconds: Int): Double = icBlocks.blockValueBySeconds(timeAsSeconds, 100.0 / percentage, timeshift)
fun getIsfTimeFromMidnight(timeAsSeconds: Int): Double = isfBlocks.blockValueBySeconds(timeAsSeconds, 100.0 / percentage, timeshift)
override fun getIsfMgdlTimeFromMidnight(timeAsSeconds: Int): Double = Profile.toMgdl(isfBlocks.blockValueBySeconds(timeAsSeconds, 100.0 / percentage, timeshift), units)
override fun getTargetLowMgdlTimeFromMidnight(timeAsSeconds: Int): Double = Profile.toMgdl(targetBlocks.lowTargetBlockValueBySeconds(timeAsSeconds, timeshift), units)
override fun getIsfMgdlTimeFromMidnight(timeAsSeconds: Int): Double = toMgdl(isfBlocks.blockValueBySeconds(timeAsSeconds, 100.0 / percentage, timeshift), units)
override fun getTargetLowMgdlTimeFromMidnight(timeAsSeconds: Int): Double = toMgdl(targetBlocks.lowTargetBlockValueBySeconds(timeAsSeconds, timeshift), units)
private fun getTargetLowTimeFromMidnight(timeAsSeconds: Int): Double = targetBlocks.lowTargetBlockValueBySeconds(timeAsSeconds, timeshift)
private fun getTargetHighTimeFromMidnight(timeAsSeconds: Int): Double = targetBlocks.highTargetBlockValueBySeconds(timeAsSeconds, timeshift)
override fun getTargetHighMgdlTimeFromMidnight(timeAsSeconds: Int): Double = Profile.toMgdl(targetBlocks.highTargetBlockValueBySeconds(timeAsSeconds, timeshift), units)
override fun getTargetHighMgdlTimeFromMidnight(timeAsSeconds: Int): Double = toMgdl(targetBlocks.highTargetBlockValueBySeconds(timeAsSeconds, timeshift), units)
override fun getIcList(rh: ResourceHelper, dateUtil: DateUtil): String =
getValuesList(icBlocks, 100.0 / percentage, DecimalFormat("0.0"), rh.gs(info.nightscout.core.ui.R.string.profile_carbs_per_unit), dateUtil)
override fun getIcList(rh: ResourceHelper, dateUtil: DateUtil): String = getValuesList(icBlocks, 100.0 / percentage, DecimalFormat("0.0"), rh.gs(info.nightscout.core.ui.R.string.profile_carbs_per_unit), dateUtil)
override fun getIsfList(rh: ResourceHelper, dateUtil: DateUtil): String =
getValuesList(isfBlocks, 100.0 / percentage, DecimalFormat("0.0"), units.asText + rh.gs(info.nightscout.core.ui.R.string.profile_per_unit), dateUtil)
@ -355,7 +363,7 @@ sealed class ProfileSealed(
val ret = Array(shifted.size) { ProfileValue(0, 0.0) }
var elapsed = 0
for (index in shifted.indices) {
ret[index] = ProfileValue(elapsed, Profile.toMgdl(shifted[index].amount, units))
ret[index] = ProfileValue(elapsed, toMgdl(shifted[index].amount, units))
elapsed += T.msecs(shifted[index].duration).secs().toInt()
}
return ret
@ -377,7 +385,7 @@ sealed class ProfileSealed(
val ret = Array(shifted.size) { ProfileValue(0, 0.0) }
var elapsed = 0
for (index in shifted.indices) {
ret[index] = ProfileValue(elapsed, Profile.toMgdl((shifted[index].lowTarget + shifted[index].highTarget) / 2.0, units))
ret[index] = ProfileValue(elapsed, toMgdl((shifted[index].lowTarget + shifted[index].highTarget) / 2.0, units))
elapsed += T.msecs(shifted[index].duration).secs().toInt()
}
return ret
@ -414,4 +422,6 @@ sealed class ProfileSealed(
fun isInProgress(dateUtil: DateUtil): Boolean =
dateUtil.now() in timestamp..timestamp + (duration ?: 0L)
private fun toMgdl(value: Double, units: GlucoseUnit): Double =
if (units == GlucoseUnit.MGDL) value else value * GlucoseUnit.MMOLL_TO_MGDL
}

View file

@ -4,7 +4,7 @@ import info.nightscout.interfaces.pump.PumpEnactResult
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.shared.interfaces.ResourceHelper
fun PumpEnactResult.toHtml(rh: ResourceHelper): String {
fun PumpEnactResult.toHtml(rh: ResourceHelper, decimalFormatter: DecimalFormatter): String {
var ret = "<b>" + rh.gs(info.nightscout.core.ui.R.string.success) + "</b>: " + success
if (queued) {
ret = rh.gs(info.nightscout.core.ui.R.string.waitingforpumpresult)
@ -33,7 +33,7 @@ fun PumpEnactResult.toHtml(rh: ResourceHelper): String {
ret += "<br><b>" + rh.gs(info.nightscout.core.ui.R.string.enacted) + "</b>: " + enacted
if (comment.isNotEmpty()) ret += "<br><b>" + rh.gs(info.nightscout.core.ui.R.string.comment) + "</b>: " + comment
ret += "<br><b>" + rh.gs(info.nightscout.core.ui.R.string.duration) + "</b>: " + duration + " min"
ret += "<br><b>" + rh.gs(info.nightscout.core.ui.R.string.absolute) + "</b>: " + DecimalFormatter.to2Decimal(absolute) + " U/h"
ret += "<br><b>" + rh.gs(info.nightscout.core.ui.R.string.absolute) + "</b>: " + decimalFormatter.to2Decimal(absolute) + " U/h"
}
}
} else {

View file

@ -35,12 +35,14 @@ import info.nightscout.interfaces.pump.defs.PumpDescription
import info.nightscout.interfaces.queue.Callback
import info.nightscout.interfaces.queue.CommandQueue
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.HtmlHelper
import info.nightscout.interfaces.utils.Round
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventRefreshOverview
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
@ -60,6 +62,7 @@ class BolusWizard @Inject constructor(
@Inject lateinit var rxBus: RxBus
@Inject lateinit var sp: SP
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var profileUtil: ProfileUtil
@Inject lateinit var constraintChecker: Constraints
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var commandQueue: CommandQueue
@ -72,7 +75,7 @@ class BolusWizard @Inject constructor(
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
@Inject lateinit var uiInteraction: UiInteraction
@Inject lateinit var persistenceLayer: PersistenceLayer
@Inject lateinit var decimalFormatter: DecimalFormatter
var timeStamp: Long
@ -81,7 +84,6 @@ class BolusWizard @Inject constructor(
timeStamp = dateUtil.now()
}
// Intermediate
var sens = 0.0
private set
@ -197,12 +199,12 @@ class BolusWizard @Inject constructor(
this.totalPercentage = totalPercentage
// Insulin from BG
sens = Profile.fromMgdlToUnits(profile.getIsfMgdl(), profileFunction.getUnits())
targetBGLow = Profile.fromMgdlToUnits(profile.getTargetLowMgdl(), profileFunction.getUnits())
targetBGHigh = Profile.fromMgdlToUnits(profile.getTargetHighMgdl(), profileFunction.getUnits())
sens = profileUtil.fromMgdlToUnits(profile.getIsfMgdl())
targetBGLow = profileUtil.fromMgdlToUnits(profile.getTargetLowMgdl())
targetBGHigh = profileUtil.fromMgdlToUnits(profile.getTargetHighMgdl())
if (useTT && tempTarget != null) {
targetBGLow = Profile.fromMgdlToUnits(tempTarget.lowTarget, profileFunction.getUnits())
targetBGHigh = Profile.fromMgdlToUnits(tempTarget.highTarget, profileFunction.getUnits())
targetBGLow = profileUtil.fromMgdlToUnits(tempTarget.lowTarget)
targetBGHigh = profileUtil.fromMgdlToUnits(tempTarget.highTarget)
}
if (useBg && bg > 0) {
bgDiff = when {
@ -218,7 +220,7 @@ class BolusWizard @Inject constructor(
glucoseStatus?.let {
if (useTrend) {
trend = it.shortAvgDelta
insulinFromTrend = Profile.fromMgdlToUnits(trend, profileFunction.getUnits()) * 3 / sens
insulinFromTrend = profileUtil.fromMgdlToUnits(trend) * 3 / sens
}
}
@ -281,19 +283,19 @@ class BolusWizard @Inject constructor(
val unit = profileFunction.getUnits()
return BolusCalculatorResult(
timestamp = dateUtil.now(),
targetBGLow = Profile.toMgdl(targetBGLow, unit),
targetBGHigh = Profile.toMgdl(targetBGHigh, unit),
isf = Profile.toMgdl(sens, unit),
targetBGLow = profileUtil.convertToMgdl(targetBGLow, unit),
targetBGHigh = profileUtil.convertToMgdl(targetBGHigh, unit),
isf = profileUtil.convertToMgdl(sens, unit),
ic = ic,
bolusIOB = insulinFromBolusIOB,
wasBolusIOBUsed = includeBolusIOB,
basalIOB = insulinFromBasalIOB,
wasBasalIOBUsed = includeBasalIOB,
glucoseValue = Profile.toMgdl(bg, unit),
glucoseValue = profileUtil.convertToMgdl(bg, unit),
wasGlucoseUsed = useBg && bg > 0,
glucoseDifference = bgDiff,
glucoseInsulin = insulinFromBG,
glucoseTrend = Profile.fromMgdlToUnits(trend, unit),
glucoseTrend = profileUtil.fromMgdlToUnits(trend, unit),
wasTrendUsed = useTrend,
trendInsulin = insulinFromTrend,
cob = cob,
@ -318,8 +320,10 @@ class BolusWizard @Inject constructor(
val actions: LinkedList<String> = LinkedList()
if (insulinAfterConstraints > 0) {
val pct = if (percentageCorrection != 100) " ($percentageCorrection%)" else ""
actions.add(rh.gs(info.nightscout.core.ui.R.string.bolus) + ": " + rh.gs(info.nightscout.interfaces.R.string.format_insulin_units, insulinAfterConstraints).formatColor
(context, rh, info.nightscout.core.ui.R.attr.bolusColor) + pct)
actions.add(
rh.gs(info.nightscout.core.ui.R.string.bolus) + ": " + rh.gs(info.nightscout.interfaces.R.string.format_insulin_units, insulinAfterConstraints).formatColor
(context, rh, info.nightscout.core.ui.R.attr.bolusColor) + pct
)
}
if (carbs > 0 && !advisor) {
var timeShift = ""
@ -328,19 +332,30 @@ class BolusWizard @Inject constructor(
} else if (carbTime < 0) {
timeShift += " (" + rh.gs(info.nightscout.core.ui.R.string.mins, carbTime) + ")"
}
actions.add(rh.gs(info.nightscout.core.ui.R.string.carbs) + ": " + rh.gs(info.nightscout.core.ui.R.string.format_carbs, carbs).formatColor(context, rh, info.nightscout.core.ui.R.attr.carbsColor) + timeShift)
actions.add(
rh.gs(info.nightscout.core.ui.R.string.carbs) + ": " + rh.gs(info.nightscout.core.ui.R.string.format_carbs, carbs)
.formatColor(context, rh, info.nightscout.core.ui.R.attr.carbsColor) + timeShift
)
}
if (insulinFromCOB > 0) {
actions.add(
rh.gs(info.nightscout.core.ui.R.string.cobvsiob) + ": " + rh.gs(info.nightscout.core.ui.R.string.formatsignedinsulinunits, insulinFromBolusIOB + insulinFromBasalIOB + insulinFromCOB + insulinFromBG).formatColor(context, rh, info.nightscout.core.ui.R.attr
.cobAlertColor)
rh.gs(info.nightscout.core.ui.R.string.cobvsiob) + ": " + rh.gs(
info.nightscout.core.ui.R.string.formatsignedinsulinunits,
insulinFromBolusIOB + insulinFromBasalIOB + insulinFromCOB + insulinFromBG
).formatColor(
context, rh, info.nightscout.core.ui.R.attr
.cobAlertColor
)
)
val absorptionRate = iobCobCalculator.ads.slowAbsorptionPercentage(60)
if (absorptionRate > .25)
actions.add(rh.gs(info.nightscout.core.ui.R.string.slowabsorptiondetected, rh.gac(context, info.nightscout.core.ui.R.attr.cobAlertColor), (absorptionRate * 100).toInt()))
}
if (abs(insulinAfterConstraints - calculatedTotalInsulin) > activePlugin.activePump.pumpDescription.pumpType.determineCorrectBolusStepSize(insulinAfterConstraints))
actions.add(rh.gs(info.nightscout.core.ui.R.string.bolus_constraint_applied_warn, calculatedTotalInsulin, insulinAfterConstraints).formatColor(context, rh, info.nightscout.core.ui.R.attr.warningColor))
actions.add(
rh.gs(info.nightscout.core.ui.R.string.bolus_constraint_applied_warn, calculatedTotalInsulin, insulinAfterConstraints)
.formatColor(context, rh, info.nightscout.core.ui.R.attr.warningColor)
)
if (config.NSCLIENT && insulinAfterConstraints > 0)
actions.add(rh.gs(info.nightscout.core.ui.R.string.bolus_recorded_only).formatColor(context, rh, info.nightscout.core.ui.R.attr.warningColor))
if (useAlarm && !advisor && carbs > 0 && carbTime > 0)
@ -362,7 +377,7 @@ class BolusWizard @Inject constructor(
automation.removeAutomationEventBolusReminder()
if (carbs > 0.0)
automation.removeAutomationEventEatReminder()
if (sp.getBoolean(info.nightscout.core.ui.R.string.key_usebolusadvisor, false) && Profile.toMgdl(bg, profile.units) > 180 && carbs > 0 && carbTime >= 0)
if (sp.getBoolean(info.nightscout.core.ui.R.string.key_usebolusadvisor, false) && profileUtil.convertToMgdl(bg, profile.units) > 180 && carbs > 0 && carbTime >= 0)
OKDialog.showYesNoCancel(ctx, rh.gs(info.nightscout.core.ui.R.string.bolus_advisor), rh.gs(info.nightscout.core.ui.R.string.bolus_advisor_message),
{ bolusAdvisorProcessing(ctx) },
{ commonProcessing(ctx) }
@ -382,7 +397,7 @@ class BolusWizard @Inject constructor(
insulin = insulinAfterConstraints
carbs = 0.0
context = ctx
mgdlGlucose = Profile.toMgdl(bg, profile.units)
mgdlGlucose = profileUtil.convertToMgdl(bg, profile.units)
glucoseType = DetailedBolusInfo.MeterType.MANUAL
carbTime = 0
bolusCalculatorResult = createBolusCalculatorResult()
@ -412,8 +427,12 @@ class BolusWizard @Inject constructor(
var message = rh.gs(info.nightscout.core.ui.R.string.wizard_explain_calc, ic, sens)
message += "\n" + rh.gs(info.nightscout.core.ui.R.string.wizard_explain_carbs, insulinFromCarbs)
if (useTT && tempTarget != null) {
val tt = if (tempTarget?.lowTarget == tempTarget?.highTarget) tempTarget?.lowValueToUnitsToString(profile.units)
else rh.gs(info.nightscout.core.ui.R.string.wizard_explain_tt_to, tempTarget?.lowValueToUnitsToString(profile.units), tempTarget?.highValueToUnitsToString(profile.units))
val tt = if (tempTarget?.lowTarget == tempTarget?.highTarget) tempTarget?.lowValueToUnitsToString(profile.units, decimalFormatter)
else rh.gs(
info.nightscout.core.ui.R.string.wizard_explain_tt_to,
tempTarget?.lowValueToUnitsToString(profile.units, decimalFormatter),
tempTarget?.highValueToUnitsToString(profile.units, decimalFormatter)
)
message += "\n" + rh.gs(info.nightscout.core.ui.R.string.wizard_explain_tt, tt)
}
if (useCob) message += "\n" + rh.gs(info.nightscout.core.ui.R.string.wizard_explain_cob, cob, insulinFromCOB)
@ -464,15 +483,15 @@ class BolusWizard @Inject constructor(
insulin = insulinAfterConstraints
carbs = this@BolusWizard.carbs.toDouble()
context = ctx
mgdlGlucose = Profile.toMgdl(bg, profile.units)
mgdlGlucose = profileUtil.convertToMgdl(bg, profile.units)
glucoseType = DetailedBolusInfo.MeterType.MANUAL
carbsTimestamp = dateUtil.now() + T.mins(this@BolusWizard.carbTime.toLong()).msecs()
bolusCalculatorResult = createBolusCalculatorResult()
notes = this@BolusWizard.notes
if (insulin > 0 || carbs > 0) {
val action = when {
insulinAfterConstraints.equals(0.0) -> Action.CARBS
carbs.equals(0.0) -> Action.BOLUS
insulinAfterConstraints == 0.0 -> Action.CARBS
carbs == 0.0 -> Action.BOLUS
else -> Action.TREATMENT
}
uel.log(action, if (quickWizard) Sources.QuickWizard else Sources.WizardDialog,

View file

@ -1,7 +1,7 @@
package info.nightscout.core.data
import com.google.common.truth.Truth.assertThat
import info.nightscout.interfaces.iob.Iob
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
class IobTest {
@ -10,23 +10,23 @@ class IobTest {
val a = Iob().iobContrib(1.0).activityContrib(2.0)
val b = Iob().iobContrib(3.0).activityContrib(4.0)
a.plus(b)
Assertions.assertEquals(4.0, a.iobContrib, 0.01)
Assertions.assertEquals(6.0, a.activityContrib, 0.01)
assertThat(a.iobContrib).isWithin(0.01).of(4.0)
assertThat(a.activityContrib).isWithin(0.01).of(6.0)
}
@Test fun equalTest() {
val a1 = Iob().iobContrib(1.0).activityContrib(2.0)
val a2 = Iob().iobContrib(1.0).activityContrib(2.0)
val b = Iob().iobContrib(3.0).activityContrib(4.0)
Assertions.assertTrue(a1 == a2)
Assertions.assertFalse(a1 == b)
@Suppress("SENSELESS_COMPARISON")
Assertions.assertFalse(a1 == null)
Assertions.assertFalse(a1 == Any())
assertThat(a1).isEqualTo(a1)
assertThat(a1).isEqualTo(a2)
assertThat(a1).isNotEqualTo(b)
assertThat(a1).isNotNull()
assertThat(a1).isNotEqualTo(Any())
}
@Test fun hashCodeTest() {
val a = Iob().iobContrib(1.0).activityContrib(2.0)
Assertions.assertNotEquals(0, a.hashCode().toLong())
assertThat(a.hashCode().toLong()).isNotEqualTo(0L)
}
}

View file

@ -5,9 +5,7 @@ import dagger.android.AndroidInjector
import info.nightscout.core.extensions.pureProfileFromJson
import info.nightscout.core.profile.ProfileSealed
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.rx.TestAapsSchedulers
import info.nightscout.rx.bus.RxBus
@ -115,18 +113,6 @@ class ProfileTest : TestBase() {
Assertions.assertEquals("00:00 5,0 - 5,0 mmol", p.getTargetList(rh, dateUtil).replace(".", ","))
Assertions.assertEquals(100, p.percentage)
Assertions.assertEquals(0, p.timeshift)
Assertions.assertEquals(0.1, Profile.toMgdl(0.1, GlucoseUnit.MGDL), 0.01)
Assertions.assertEquals(18.0, Profile.toMgdl(1.0, GlucoseUnit.MMOL), 0.01)
Assertions.assertEquals(1.0, Profile.toMmol(18.0, GlucoseUnit.MGDL), 0.01)
Assertions.assertEquals(18.0, Profile.toMmol(18.0, GlucoseUnit.MMOL), 0.01)
Assertions.assertEquals(18.0, Profile.fromMgdlToUnits(18.0, GlucoseUnit.MGDL), 0.01)
Assertions.assertEquals(1.0, Profile.fromMgdlToUnits(18.0, GlucoseUnit.MMOL), 0.01)
Assertions.assertEquals(18.0, Profile.toUnits(18.0, 1.0, GlucoseUnit.MGDL), 0.01)
Assertions.assertEquals(1.0, Profile.toUnits(18.0, 1.0, GlucoseUnit.MMOL), 0.01)
Assertions.assertEquals("18", Profile.toUnitsString(18.0, 1.0, GlucoseUnit.MGDL))
Assertions.assertEquals("1,0", Profile.toUnitsString(18.0, 1.0, GlucoseUnit.MMOL).replace(".", ","))
Assertions.assertEquals("5 - 6", Profile.toTargetRangeString(5.0, 6.0, GlucoseUnit.MGDL, GlucoseUnit.MGDL))
Assertions.assertEquals("4", Profile.toTargetRangeString(4.0, 4.0, GlucoseUnit.MGDL, GlucoseUnit.MGDL))
//Test basal profile below limit
p = ProfileSealed.Pure(pureProfileFromJson(JSONObject(belowLimitValidProfile), dateUtil)!!)

View file

@ -1,9 +1,7 @@
package info.nightscout.core.utils
import com.google.common.truth.TruthJUnit.assume
import info.nightscout.sharedtests.TestBase
import org.hamcrest.CoreMatchers.containsString
import org.hamcrest.CoreMatchers.not
import org.junit.Assume.assumeThat
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
@ -11,9 +9,10 @@ import org.junit.jupiter.api.Test
// https://stackoverflow.com/questions/47708951/can-aes-256-work-on-android-devices-with-api-level-26
// Java prior to Oracle Java 8u161 does not have policy for 256 bit AES - but Android support it
// when test is run in Vanilla JVM without policy - Invalid key size exception is thrown
fun assumeAES256isSupported(cryptoUtil: CryptoUtil) {
private fun assumeAES256isSupported(cryptoUtil: CryptoUtil) {
cryptoUtil.lastException?.message?.let { exceptionMessage ->
assumeThat("Upgrade your testing environment Java (OpenJDK or Java 8u161) and JAVA_HOME - AES 256 is supported by Android so this exception should not happen!", exceptionMessage, not(containsString("key size")))
assume().withMessage("Upgrade your testing environment Java (OpenJDK or Java 8u161) and JAVA_HOME - AES 256 is supported by Android so this exception should not happen!")
.that(exceptionMessage).doesNotContain("key size")
}
}
@ -26,7 +25,8 @@ class CryptoUtilTest : TestBase() {
fun testFixedSaltCrypto() {
val salt = byteArrayOf(
-33, -29, 16, -19, 99, -111, -3, 2, 116, 106, 47, 38, -54, 11, -77, 28,
111, -15, -65, -110, 4, -32, -29, -70, -95, -88, -53, 19, 87, -103, 123, -15)
111, -15, -65, -110, 4, -32, -29, -70, -95, -88, -53, 19, 87, -103, 123, -15
)
val password = "thisIsFixedPassword"
val payload = "FIXED-PAYLOAD"
@ -83,10 +83,30 @@ class CryptoUtilTest : TestBase() {
Assertions.assertTrue(cryptoUtil.checkPassword("givenSecret", cryptoUtil.hashPassword("givenSecret")))
Assertions.assertFalse(cryptoUtil.checkPassword("givenSecret", cryptoUtil.hashPassword("otherSecret")))
Assertions.assertTrue(cryptoUtil.checkPassword("givenHashToCheck", "hmac:7fe5f9c7b4b97c5d32d5cfad9d07473543a9938dc07af48a46dbbb49f4f68c12:a0c7cee14312bbe31b51359a67f0d2dfdf46813f319180269796f1f617a64be1"))
Assertions.assertFalse(cryptoUtil.checkPassword("givenMashToCheck", "hmac:7fe5f9c7b4b97c5d32d5cfad9d07473543a9938dc07af48a46dbbb49f4f68c12:a0c7cee14312bbe31b51359a67f0d2dfdf46813f319180269796f1f617a64be1"))
Assertions.assertFalse(cryptoUtil.checkPassword("givenHashToCheck", "hmac:0fe5f9c7b4b97c5d32d5cfad9d07473543a9938dc07af48a46dbbb49f4f68c12:a0c7cee14312bbe31b51359a67f0d2dfdf46813f319180269796f1f617a64be1"))
Assertions.assertFalse(cryptoUtil.checkPassword("givenHashToCheck", "hmac:7fe5f9c7b4b97c5d32d5cfad9d07473543a9938dc07af48a46dbbb49f4f68c12:b0c7cee14312bbe31b51359a67f0d2dfdf46813f319180269796f1f617a64be1"))
Assertions.assertTrue(
cryptoUtil.checkPassword(
"givenHashToCheck",
"hmac:7fe5f9c7b4b97c5d32d5cfad9d07473543a9938dc07af48a46dbbb49f4f68c12:a0c7cee14312bbe31b51359a67f0d2dfdf46813f319180269796f1f617a64be1"
)
)
Assertions.assertFalse(
cryptoUtil.checkPassword(
"givenMashToCheck",
"hmac:7fe5f9c7b4b97c5d32d5cfad9d07473543a9938dc07af48a46dbbb49f4f68c12:a0c7cee14312bbe31b51359a67f0d2dfdf46813f319180269796f1f617a64be1"
)
)
Assertions.assertFalse(
cryptoUtil.checkPassword(
"givenHashToCheck",
"hmac:0fe5f9c7b4b97c5d32d5cfad9d07473543a9938dc07af48a46dbbb49f4f68c12:a0c7cee14312bbe31b51359a67f0d2dfdf46813f319180269796f1f617a64be1"
)
)
Assertions.assertFalse(
cryptoUtil.checkPassword(
"givenHashToCheck",
"hmac:7fe5f9c7b4b97c5d32d5cfad9d07473543a9938dc07af48a46dbbb49f4f68c12:b0c7cee14312bbe31b51359a67f0d2dfdf46813f319180269796f1f617a64be1"
)
)
}
}

View file

@ -1,21 +1,44 @@
package info.nightscout.core.utils
import android.content.Context
import com.google.common.truth.Truth.assertThat
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import info.nightscout.sharedtests.TestBase
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.AfterAll
import org.mockito.Mock
import org.mockito.Mockito.`when`
import java.util.Date
import java.util.SimpleTimeZone
import java.util.TimeZone
class DateUtilTest : TestBase() {
@Mock lateinit var context: Context
@Mock lateinit var rh: ResourceHelper
companion object {
private lateinit var savedTimeZone: TimeZone
@BeforeAll
@JvmStatic
fun setDefaultTimezoneUtc() {
savedTimeZone = TimeZone.getDefault()
TimeZone.setDefault(SimpleTimeZone(0, "UTC"))
}
@AfterAll
@JvmStatic
fun restoreDefaultTimezone() {
TimeZone.setDefault(savedTimeZone)
}
}
@Test
fun fromISODateStringTest() {
Assertions.assertEquals(1511124634417L, DateUtil(context).fromISODateString("2017-11-19T22:50:34.417+0200"))
@ -40,7 +63,7 @@ class DateUtilTest : TestBase() {
}
@Test fun dateStringTest() {
Assertions.assertTrue(DateUtil(context).dateString(1513902750000L).contains("22"))
assertThat(DateUtil(context).dateString(1513902750000L)).contains("22")
}
@Test fun timeStringTest() {
@ -48,15 +71,15 @@ class DateUtilTest : TestBase() {
}
@Test fun dateAndTimeStringTest() {
Assertions.assertTrue(DateUtil(context).dateAndTimeString(1513902750000L).contains("22"))
Assertions.assertTrue(DateUtil(context).dateAndTimeString(1513902750000L).contains("32"))
assertThat(DateUtil(context).dateAndTimeString(1513902750000L)).contains("22")
assertThat(DateUtil(context).dateAndTimeString(1513902750000L)).contains("32")
}
@Test fun dateAndTimeRangeStringTest() {
Assertions.assertTrue(DateUtil(context).dateAndTimeRangeString(1513902750000L, 1513902750000L).contains("22"))
Assertions.assertTrue(DateUtil(context).dateAndTimeRangeString(1513902750000L, 1513902750000L).contains("32"))
Assertions.assertTrue(DateUtil(context).dateAndTimeRangeString(1513902750000L, 1513902750000L).contains("22"))
Assertions.assertTrue(DateUtil(context).dateAndTimeRangeString(1513902750000L, 1513902750000L).contains("32"))
assertThat(DateUtil(context).dateAndTimeRangeString(1513902750000L, 1513902750000L)).contains("22")
assertThat(DateUtil(context).dateAndTimeRangeString(1513902750000L, 1513902750000L)).contains("32")
assertThat(DateUtil(context).dateAndTimeRangeString(1513902750000L, 1513902750000L)).contains("22")
assertThat(DateUtil(context).dateAndTimeRangeString(1513902750000L, 1513902750000L)).contains("32")
}
/*

View file

@ -1,28 +0,0 @@
package info.nightscout.core.utils
import info.nightscout.interfaces.utils.DecimalFormatter
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
class DecimalFormatterTest {
@Test fun to0DecimalTest() {
Assertions.assertEquals("1", DecimalFormatter.to0Decimal(1.33).replace(",", "."))
Assertions.assertEquals("1U", DecimalFormatter.to0Decimal(1.33, "U").replace(",", "."))
}
@Test fun to1DecimalTest() {
Assertions.assertEquals("1.3", DecimalFormatter.to1Decimal(1.33).replace(",", "."))
Assertions.assertEquals("1.3U", DecimalFormatter.to1Decimal(1.33, "U").replace(",", "."))
}
@Test fun to2DecimalTest() {
Assertions.assertEquals("1.33", DecimalFormatter.to2Decimal(1.3333).replace(",", "."))
Assertions.assertEquals("1.33U", DecimalFormatter.to2Decimal(1.3333, "U").replace(",", "."))
}
@Test fun to3DecimalTest() {
Assertions.assertEquals("1.333", DecimalFormatter.to3Decimal(1.3333).replace(",", "."))
Assertions.assertEquals("1.333U", DecimalFormatter.to3Decimal(1.3333, "U").replace(",", "."))
}
}

View file

@ -1,7 +1,7 @@
package info.nightscout.core.utils
import com.google.common.truth.Truth.assertThat
import info.nightscout.interfaces.utils.MidnightTime
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import java.util.Calendar
@ -10,40 +10,40 @@ class MidnightTimeTest {
@Test fun calc() {
// We get real midnight
val now = System.currentTimeMillis()
Assertions.assertTrue(now >= MidnightTime.calc())
assertThat(MidnightTime.calc()).isAtMost(now)
val c = Calendar.getInstance()
c.timeInMillis = MidnightTime.calc()
Assertions.assertEquals(c[Calendar.HOUR_OF_DAY].toLong(), 0)
Assertions.assertEquals(c[Calendar.MINUTE].toLong(), 0)
Assertions.assertEquals(c[Calendar.SECOND].toLong(), 0)
Assertions.assertEquals(c[Calendar.MILLISECOND].toLong(), 0)
assertThat(c[Calendar.HOUR_OF_DAY].toLong()).isEqualTo(0L)
assertThat(c[Calendar.MINUTE].toLong()).isEqualTo(0L)
assertThat(c[Calendar.SECOND].toLong()).isEqualTo(0L)
assertThat(c[Calendar.MILLISECOND].toLong()).isEqualTo(0L)
}
@Test fun calc_time() {
// We get real midnight
val now = System.currentTimeMillis()
val midnight = MidnightTime.calc(now)
Assertions.assertTrue(now >= midnight)
assertThat(midnight).isAtMost(now)
val c = Calendar.getInstance()
c.timeInMillis = MidnightTime.calc(now)
Assertions.assertEquals(c[Calendar.HOUR_OF_DAY].toLong(), 0)
Assertions.assertEquals(c[Calendar.MINUTE].toLong(), 0)
Assertions.assertEquals(c[Calendar.SECOND].toLong(), 0)
Assertions.assertEquals(c[Calendar.MILLISECOND].toLong(), 0)
assertThat(c[Calendar.HOUR_OF_DAY].toLong()).isEqualTo(0L)
assertThat(c[Calendar.MINUTE].toLong()).isEqualTo(0L)
assertThat(c[Calendar.SECOND].toLong()).isEqualTo(0L)
assertThat(c[Calendar.MILLISECOND].toLong()).isEqualTo(0L)
// Assure we get the same time from cache
Assertions.assertEquals(midnight, MidnightTime.calc(now))
assertThat(midnight).isEqualTo(MidnightTime.calc(now))
}
@Test fun resetCache() {
val now = System.currentTimeMillis()
MidnightTime.calc(now)
MidnightTime.resetCache()
Assertions.assertEquals(0, MidnightTime.times.size().toLong())
assertThat(MidnightTime.times.size().toLong()).isEqualTo(0L)
}
@Test fun log() {
val now = System.currentTimeMillis()
MidnightTime.calc(now)
Assertions.assertTrue(MidnightTime.log().startsWith("Hits:"))
assertThat(MidnightTime.log()).startsWith("Hits:")
}
}

View file

@ -1,7 +1,7 @@
package info.nightscout.core.utils
import com.google.common.truth.Truth.assertThat
import info.nightscout.shared.utils.T
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import kotlin.math.abs
@ -9,33 +9,33 @@ import kotlin.math.abs
class TTest {
@Test fun toUnits() {
Assertions.assertEquals(1, T.msecs(1000).secs())
Assertions.assertEquals(1, T.secs(60).mins())
Assertions.assertEquals(1, T.mins(60).hours())
Assertions.assertEquals(1, T.hours(24).days())
Assertions.assertEquals(24, T.days(1).hours())
Assertions.assertEquals(60000, T.mins(1).msecs())
assertThat(T.msecs(1000).secs()).isEqualTo(1)
assertThat(T.secs(60).mins()).isEqualTo(1)
assertThat(T.mins(60).hours()).isEqualTo(1)
assertThat(T.hours(24).days()).isEqualTo(1)
assertThat(T.days(1).hours()).isEqualTo(24)
assertThat(T.mins(1).msecs()).isEqualTo(60000)
}
@Test fun now() {
Assertions.assertTrue(abs(T.now().msecs() - System.currentTimeMillis()) < 5000)
assertThat(abs(T.now().msecs() - System.currentTimeMillis())).isLessThan(5_000L)
}
@Test fun additions() {
val nowMsecs = System.currentTimeMillis()
val now = T.msecs(nowMsecs)
Assertions.assertEquals(now.plus(T.secs(5)).msecs(), nowMsecs + 5 * 1000)
Assertions.assertEquals(now.plus(T.mins(5)).msecs(), nowMsecs + 5 * 60 * 1000)
Assertions.assertEquals(now.plus(T.hours(5)).msecs(), nowMsecs + 5 * 60 * 60 * 1000)
Assertions.assertEquals(now.plus(T.days(5)).msecs(), nowMsecs + 5 * 24 * 60 * 60 * 1000)
assertThat(nowMsecs + 5 * 1000).isEqualTo(now.plus(T.secs(5)).msecs())
assertThat(nowMsecs + 5 * 60 * 1000).isEqualTo(now.plus(T.mins(5)).msecs())
assertThat(nowMsecs + 5 * 60 * 60 * 1000).isEqualTo(now.plus(T.hours(5)).msecs())
assertThat(nowMsecs + 5 * 24 * 60 * 60 * 1000).isEqualTo(now.plus(T.days(5)).msecs())
}
@Test fun subtractions() {
val nowMsecs = System.currentTimeMillis()
val now = T.msecs(nowMsecs)
Assertions.assertEquals(now.minus(T.secs(5)).msecs(), nowMsecs - 5 * 1000)
Assertions.assertEquals(now.minus(T.mins(5)).msecs(), nowMsecs - 5 * 60 * 1000)
Assertions.assertEquals(now.minus(T.hours(5)).msecs(), nowMsecs - 5 * 60 * 60 * 1000)
Assertions.assertEquals(now.minus(T.days(5)).msecs(), nowMsecs - 5 * 24 * 60 * 60 * 1000)
assertThat(nowMsecs - 5 * 1000).isEqualTo(now.minus(T.secs(5)).msecs())
assertThat(nowMsecs - 5 * 60 * 1000).isEqualTo(now.minus(T.mins(5)).msecs())
assertThat(nowMsecs - 5 * 60 * 60 * 1000).isEqualTo(now.minus(T.hours(5)).msecs())
assertThat(nowMsecs - 5 * 24 * 60 * 60 * 1000).isEqualTo(now.minus(T.days(5)).msecs())
}
}

View file

@ -8,7 +8,6 @@ dependencies {
testImplementation "joda-time:joda-time:$jodatime_version"
testImplementation 'com.google.truth:truth:1.1.5'
testImplementation "org.skyscreamer:jsonassert:1.5.0"
testImplementation "org.hamcrest:hamcrest-all:1.3"
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation "androidx.test.ext:junit-ktx:$androidx_junit_version"

View file

@ -1,2 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>
<resources>
<string name="biometric_title">Απαιτείται πιστοποίηση</string>
<string name="biometric_description">Τοποθετήστε το δάχτυλό σας στον αναγνώστη δακτυλικών αποτυπωμάτων για να επαληθεύσετε την ταυτότητά σας</string>
<string name="settings_protection">Προστασία ρυθμίσεων</string>
<string name="application_protection">Προστασία εφαρμογής</string>
<string name="bolus_protection">Προστασία Bolus</string>
<string name="settings_password">Κωδικός πρόσβασης στις ρυθμίσεις</string>
<string name="settings_pin">PIN Ρυθμίσεων</string>
<string name="application_password">Κωδικός πρόσβασης Εφαρμογής</string>
<string name="application_pin">PIN Εφαρμογής</string>
<string name="bolus_password">Κωδικός πρόσβασης για Bolus</string>
<string name="bolus_pin">Bolus PIN</string>
<string name="protection_timeout_title">Διατήρηση κωδικού πρόσβασης και PIN [s]</string>
<string name="protection_timeout_summary">Χρόνος πριν ο κωδικός πρόσβασης ή το PIN πρέπει να εισαχθεί</string>
<string name="biometric">Βιομετρικά</string>
<string name="custom_password">Προσαρμοσμένος κωδικός</string>
<string name="custom_pin">Προσαρμοσμένο PIN</string>
<string name="noprotection">Καμία προστασία</string>
<string name="unsecure_fallback_biometric">Μη Ασφαλής Επανάκληση</string>
<string name="unsecure_fallback_descriotion_biometric">Για να είναι αποτελεσματική, η βιομετρική προστασία, χρειάζεται να οριστεί ένας κωδικός master για δυνατότητα επανάκλησης.\n\nΠαρακαλώ ρυθμίστε ένα κωδικό master!</string>
<string name="password_set">Ο κωδικός ορίστηκε!</string>
<string name="pin_set">Το PIN ορίστηκε!</string>
<string name="password_not_set">Ο κωδικός δεν ορίστηκε</string>
<string name="pin_not_set">Το PIN δεν ορίστηκε</string>
<string name="password_not_changed">Ο κωδικός δεν άλλαξε</string>
<string name="pin_not_changed">Το PIN δεν άλλαξε</string>
<string name="pin_cleared">Το PIN διαγράφηκε!</string>
<string name="password_hint">Εισάγετε τον κωδικό εδώ</string>
<string name="pin_hint">Εισάγετε το PIN εδώ</string>
</resources>

View file

@ -2,8 +2,10 @@
<resources>
<!-- General-->
<string name="refresh">Ανανέωση</string>
<string name="error">Σφάλμα</string>
<string name="profile_set_ok">Το Βασικό προφίλ στην αντλία ενημερώθηκε</string>
<string name="invalid_input">Μη έγκυρα δεδομένα</string>
<string name="bolus_delivering">Έγχυση %1$.2f U</string>
<string name="constraint_applied">Εφαρμόστηκαν Περιορισμοί!</string>
<string name="tempbasals_iobtotal_label_string">Συνολική IOB:</string>
<string name="tt_label">TT</string>
@ -12,6 +14,7 @@
<string name="pump_base_basal_rate">%1$.2f U/h</string>
<string name="pump_not_initialized_profile_not_set">Η αντλία δεν έχει ρυθμιστεί, δεν ορίστηκε προφίλ!</string>
<string name="failed_update_basal_profile">Αποτυχία αναβάθμισης βασικού προφίλ</string>
<string name="bolus_delivered_successfully">Δόση Bolus %1$.2f U χορηγήθηκε επιτυχώς</string>
<string name="no_valid_basal_rate">Διαβάζεται από την αντλία μη έγκυρος βασικός ρυθμός</string>
<string name="limiting_iob">Περιορίζεται η IOB σε %1$.1f U λόγω %2$s</string>
<string name="loop_disabled">ΤΟ ΚΥΚΛΩΜΑ ΑΠΕΝΕΡΓΟΠΟΙΗΘΗΚΕ ΑΠΟ ΠΕΡΙΟΡΙΣΜΟΥΣ</string>
@ -29,27 +32,38 @@
<string name="patient_name_default" comment="This is default patient display name, when user does not provide real one">Χρήστης</string>
<string name="result">Αποτέλεσμα</string>
<string name="settings">Ρυθμίσεις</string>
<string name="statuslights">Ενδείξεις κατάστασης</string>
<string name="do_ns_upload_title">Ανέβασμα δεδομένων BG στο NS</string>
<string name="configbuilder_insulin">Ινσουλίνη</string>
<string name="value_unavailable_short">n/a</string>
<string name="master_password">Κύριος κωδικός</string>
<string name="ue_export_to_csv">Εξαγωγή καταχωρήσεων χρήστη σε Excel (csv)</string>
<string name="confirm">Επιβεβαίωση</string>
<string name="pump">Αντλία</string>
<string name="missed_bg_readings">Χαμένες μετρήσεις BG</string>
<string name="treatments_iob_label_string">IOB:</string>
<string name="mute5min">Σίγαση για 5 λεπτά</string>
<string name="mute">Σίγαση</string>
<string name="success">Επιτυχία</string>
<string name="advanced_settings_title">Ρυθμίσεις για Προχωρημένους</string>
<string name="extendedbolusdeliveryerror">Σφάλμα έγχυσης εκτεταμένου bolus</string>
<string name="aps_mode_title">Λειτουργία APS</string>
<string name="extended_bolus">Εκτεταμένο bolus</string>
<string name="paused">Παύση</string>
<string name="tdd_total">TDD σύνολο</string>
<string name="goingtodeliver">Πρόκειται να εγχυθούν %1$.2f μονάδες</string>
<string name="waitingforpump">Αναμονή για αντλία</string>
<string name="androidaps_start">Το AAPS ξεκίνησε</string>
<string name="formatsignedinsulinunits">%1$+.2f U</string>
<string name="format_carbs">%1$d g</string>
<string name="format_hours">%1$.2f h</string>
<string name="format_mins">%1$d λεπτά</string>
<string name="objectives">Βήματα</string>
<string name="please_wait">Περιμένετε…</string>
<string name="stop">Stop</string>
<string name="carbs">Υδατάνθρακες</string>
<string name="invalid_profile">Μη έγκυρο προφίλ!</string>
<string name="no_profile_set">ΔΕΝ ΟΡΙΣΤΗΚΕ ΠΡΟΦΙΛ</string>
<string name="active"><![CDATA[<Ενεργή>]]></string>
<string name="date">Ημερομηνία</string>
<string name="units_label">Μονάδες</string>
@ -58,8 +72,13 @@
<string name="isf_label">ISF</string>
<string name="basal_label">Βασικός Ρυθμός</string>
<string name="target_label">Στόχος</string>
<string name="dia_long_label">Διάρκεια Δράσης Ινσουλίνης</string>
<string name="ic_long_label">Αναλογία Ινσουλίνης προς Υδατάνθρακες</string>
<string name="isf_long_label">Συντελεστής Ευαισθησίας στην Ινσουλίνης</string>
<string name="basal_long_label">Βασικός Ρυθμός</string>
<string name="target_long_label">Στόχος Γλυκόζης Αίματος</string>
<string name="shortgram">g</string>
<string name="shortpercent">%</string>
<string name="bluetooth">Bluetooth</string>
<string name="btwatchdog_title">BT Watchdog</string>
<string name="btwatchdog_summary">Απενεργοποιεί το bluetooth του τηλεφώνου για ένα δευτερόλεπτο αν δεν είναι δυνατή η σύνδεση με την αντλία. Αυτό μπορεί να βοηθήσει σε ορισμένα τηλέφωνα όπου το bluetooth παγώνει.</string>
@ -84,41 +103,78 @@
<string name="name_short">Όνομα:</string>
<string name="time">Χρόνος</string>
<string name="ns_wifi_ssids">WiFi SSID</string>
<string name="loading">Φόρτωση…</string>
<string name="notes_label">Σημειώσεις</string>
<string name="remove_button">Διαγραφή</string>
<string name="add_new">Προσθήκη νέου</string>
<string name="addnew_above">Προσθήκη νέου πάνω</string>
<string name="wrong_pump_data">Τα δεδομένα προέρχονται από διαφορετική αντλία. Αλλάξτε τον οδηγό της αντλίας για να επαναφέρετε την κατάσταση της αντλίας.</string>
<string name="bg_label">BG</string>
<string name="calibration">Καλιμπράρισμα</string>
<string name="alarminxmin">Εκτέλεση συναγερμού σε %1$d λεπτά</string>
<string name="treatmentdeliveryerror">Το Bolus ανέφερε ένα σφάλμα. Ελέγξτε χειροκίνητα την ποσότητα που έχει πραγματικά χορηγηθεί</string>
<string name="bolus_reminder">Υπενθύμιση Bolus</string>
<string name="duration_label">Διάρκεια</string>
<string name="shortgramm">g</string>
<string name="pumpsuspended">Η αντλία είναι σε παύση</string>
<string name="notconfigured">Δεν έχει ρυθμιστεί</string>
<string name="loopsuspended">Κύκλωμα σε αναστολή</string>
<string name="trend_arrow">Βέλος τάσης</string>
<string name="a11y_autosens_label">Auto sens</string>
<string name="required">req</string>
<string name="a11y_arrow_double_down">ταχεία πτώση</string>
<string name="a11y_arrow_single_down">πτώση</string>
<string name="a11y_arrow_forty_five_down">αργή πτώση</string>
<string name="a11y_arrow_flat">σταθερό</string>
<string name="a11y_arrow_forty_five_up">αργή αύξηση</string>
<string name="a11y_arrow_single_up">αύξηση</string>
<string name="a11y_arrow_double_up">ταχεία αύξηση</string>
<string name="a11y_arrow_none">κανένα</string>
<string name="a11y_arrow_unknown">άγνωστο</string>
<string name="a11y_high">υψηλό</string>
<string name="a11y_inrange">εντός στόχου</string>
<string name="a11y_low">χαμηλό</string>
<string name="average">Μέση</string>
<string name="tir">TIR</string>
<string name="none"><![CDATA[<κενό>]]></string>
<string name="remove_label">ΜΕΤΑΚΙΝΗΣΗ</string>
<string name="activate_profile">Ενεργοποίηση προφίλ</string>
<string name="reset">επαναφορά</string>
<string name="profileswitch_ismissing">Η αλλαγή προφίλ λείπει. Αλλάξτε το προφίλ ή πατήστε \"Ενεργοποίηση Προφίλ\" στο Τοπικό Προφίλ.</string>
<string name="profile">Προφίλ</string>
<string name="select_for_removal">Επιλέξτε για αφαίρεση</string>
<string name="confirm_remove_multiple_items">Είστε βέβαιοι ότι θέλετε να καταργήσετε %1$d στοιχεία</string>
<string name="overview_treatment_label">Θεραπεία</string>
<string name="copytolocalprofile">Δημιουργία νέου προφίλ από αυτό το προφίλ;</string>
<string name="wear_wizard_settings">Ρυθμίσεις Γρήγορου Οδηγού</string>
<string name="bg_trend_label">Γραφική 15min</string>
<string name="treatments_wizard_cob_label">COB</string>
<string name="bolus_iob_label">Bolus IOB</string>
<string name="treatments_wizard_basaliob_label">Βασική ΙΟΒ</string>
<string name="invalid">ΜΗ ΕΓΚΥΡΟ</string>
<string name="login">Σύνδεση</string>
<string name="prime_fill">Πλήρωση/Γέμισμα</string>
<string name="overview_insulin_label">Ινσουλίνη</string>
<string name="stoptemptarget">Λήξη προσ. στόχου</string>
<string name="closedloop">Κλειστό Κύκλωμα</string>
<string name="openloop">Ανοιχτό Κύκλωμα</string>
<string name="lowglucosesuspend">Αναστολή Χαμηλής Γλυκόζης</string>
<string name="dia">DIA</string>
<string name="ic_short">IC</string>
<string name="isf_short">ISF</string>
<string name="canceling_tbr_failed">Απέτυχε η Ακύρωση Προσωρινού Ρυθμού</string>
<string name="canceling_eb_failed">Η ακύρωση της εκτεταμένης δόσης bolus απέτυχε</string>
<string name="virtualpump_uploadstatus_title">Φόρτωση κατάστασης αντλίας στο NS ή στο Tidepool</string>
<string name="suspendloop_label">Απενεργοποιημένο/Αναστολή κυκλώματος</string>
<string name="iob_label">Ενεργή Ινσουλίνη (IOB)</string>
<!-- Protection-->
<string name="wrongpassword">Λάθος κωδικός</string>
<string name="wrongpin">Λάθος PIN</string>
<string name="passwords_dont_match">Οι κωδικοί δεν ταιριάζουν</string>
<string name="pin_dont_match">Τα PINs δεν ταιριάζουν</string>
<!-- Profile-->
<string name="basalprofilenotaligned">Οι τιμές του βασικού ρυθμού δεν αντιστοιχούν σε ώρες: %1$s</string>
<string name="minimalbasalvaluereplaced">Η τιμή του βασικού αντικαταστάθηκε από την ελάχιστη υποστηριζόμενη τιμή: %1$s</string>
<string name="maximumbasalvaluereplaced">Η τιμή του βασικού αντικαταστάθηκε από την μέγιστη υποστηριζόμενη τιμή: %1$s</string>
<string name="profile_per_unit">/U</string>
<string name="profile_ins_units_per_hour">U/h</string>
@ -126,6 +182,7 @@
<!-- ProfileFunction-->
<string name="startprofile">Έναρξη προφίλ %1$d%% για %2$d λεπτά</string>
<!-- APSResult-->
<string name="cancel_temp">Ακύρωση προσωρινού βασικού ρυθμού</string>
<string name="let_temp_basal_run">Αφήστε τον προσωρινό ρυθμό ενεργό</string>
<string name="rate">Τιμή</string>
<string name="duration">Διάρκεια</string>
@ -134,14 +191,25 @@
<!-- ProfileSwitch-->
<string name="zerovalueinprofile">Μη έγκυρο προφίλ: %1$s</string>
<!-- Temptarget-->
<string name="mins">%1$d λεπτά</string>
<!-- Translator-->
<string name="careportal">Φροντίδα</string>
<string name="careportal_bgcheck">Έλεγχος BG</string>
<string name="careportal_mbg">Χειροκίνητη εισαγωγή γλυκόζης αίματος ή βαθμονόμηση</string>
<string name="careportal_announcement">Ανακοίνωση</string>
<string name="careportal_note">Σημείωση</string>
<string name="careportal_question">Ερώτηση</string>
<string name="careportal_exercise">Άσκηση</string>
<string name="careportal_announcement_message">Ανακοίνωση : %1$s</string>
<string name="careportal_note_message">Σημείωση: %1$s</string>
<string name="careportal_question_message">Ερώτηση : %1$s</string>
<string name="careportal_exercise_message">Άσκηση : %1$s</string>
<string name="careportal_pump_site_change">Αλλαγή σημείου αντλίας</string>
<string name="cgm_sensor_insert">Εισαγωγή Αισθητήρα CGM</string>
<string name="careportal_cgmsensorstart">Έναρξη Αισθητήρα CGM</string>
<string name="careportal_cgm_sensor_stop">Διακοπή Αισθητήρα CGM</string>
<string name="careportal_dad_alert">Ειδοποίηση D.A.D.</string>
<string name="careportal_insulin_cartridge_change">Αλλαγή Αμπούλας Ινσουλίνης</string>
<string name="careportal_profileswitch">Αλλαγή Προφίλ</string>
<string name="careportal_snackbolus">Bolus για σνακ</string>
<string name="careportal_mealbolus">Bolus Γεύματος</string>
@ -151,6 +219,10 @@
<string name="careportal_tempbasalend">Τέλος Προσ Ρυθμού</string>
<string name="careportal_carbscorrection">Διόρθωση Υδατανθράκων</string>
<string name="careportal_openapsoffline">OpenAPS εκτός σύνδεσης</string>
<string name="pump_battery_change">Αλλαγή Μπαταρίας Αντλίας</string>
<string name="temporary_target">Προσωρινός στόχος</string>
<string name="careportal_temporarytargetvalue">Τιμή Προσωρινού στόχου</string>
<string name="careportal_temporarytargetcancel">Ακύρωση προσωρινού στόχου</string>
<string name="boluswizard">Οδηγός Bolus</string>
<string name="glucosetype_finger">Δάκτυλο</string>
<string name="glucosetype_sensor">Αισθητήρας</string>
@ -163,6 +235,8 @@
<string name="automation">Αυτοματισμός</string>
<string name="custom">Προσαρμογή</string>
<string name="loop">Κύκλωμα</string>
<string name="ns">NS</string>
<string name="record">Εγγραφή</string>
<!-- Command-->
<string name="connectiontimedout">Ο χρόνος σύνδεσης έληξε</string>
<!-- PumpEnactResult-->
@ -173,7 +247,9 @@
<string name="waitingforpumpresult">Περιμένετε για αποτέλεσμα</string>
<string name="smb_shortname">SMB</string>
<!-- CarbsReq-->
<string name="carbsreq">%1$d g επιπλέον υδατάνθρακες απαιτούνται μέσα σε %2$d λεπτά</string>
<!-- TDDStatsActivity-->
<string name="cumulative_tdd">Άθροισμα TDD</string>
<string name="expweight">Εκθετικά Σταθμισμένο TDD</string>
<string name="basalrate">Βασικός Ρυθμός</string>
<string name="bolus">Bolus</string>
@ -182,35 +258,236 @@
<string name="amount_days"># Ημέρες</string>
<string name="weight">Βάρος</string>
<string name="warning_Message">Πιθανώς ανακριβής όταν χρησιμοποιείτε bolus για πλήρωση/γέμισμα!</string>
<string name="olddata_Message">Παλιά δεδομένα, παρακαλώ πατήστε \"ΕΠΑΝΑΦΟΡΤΩΣΗ\"</string>
<string name="tbb">Συνολικός Βασικός Ρυθμός</string>
<string name="tbb2">TBB * 2</string>
<!-- Ntp-->
<string name="timedetection">Ανίχνευση χρόνου</string>
<!-- User Entry -->
<string name="uel_bolus">BOLUS</string>
<string name="uel_bolus_calculator">ΥΠΟΛΟΓΙΣΤΗΣ BOLUS</string>
<string name="uel_bolus_advisor">ΣΥΜΒΟΥΛΟΣ BOLUS</string>
<string name="uel_extended_bolus">ΕΚΤΕΤΑΜΕΝΟ BOLUS</string>
<string name="uel_superbolus_tbr">SUPERBOLUS TBR</string>
<string name="uel_carbs">ΥΔΑΤΑΝΘΡΑΚΕΣ</string>
<string name="uel_extended_carbs">ΕΚΤΕΤΑΜΕΝΟΙ ΥΔΑΤΑΝΘΡΑΚΕΣ</string>
<string name="uel_temp_basal">ΠΡΟΣΩΡΙΝΟΣ ΒΑΣΙΚΟΣ</string>
<string name="uel_tt">ΠΡΟΣΩΡΙΝΟΣ ΣΤΟΧΟΣ</string>
<string name="uel_new_profile">ΝΕΟ ΠΡΟΦΙΛ</string>
<string name="uel_clone_profile">ΚΛΩΝΟΠΟΙΗΣΗ ΠΡΟΦΙΛ</string>
<string name="uel_store_profile">ΑΠΟΘΗΚΕΥΣΗ ΠΡΟΦΙΛ</string>
<string name="uel_profile_switch">ΕΝΑΛΛΑΓΗ ΠΡΟΦΙΛ</string>
<string name="uel_profile_switch_cloned">ΚΛΩΝΟΠΟΙΗΣΗ ΕΝΑΛΛΑΓΗΣ ΠΡΟΦΙΛ</string>
<string name="uel_closed_loop_mode">ΛΕΙΤΟΥΡΓΙΑ ΚΛΕΙΣΤΟΥ ΚΥΚΛΩΜΑΤΟΣ</string>
<string name="uel_lgs_loop_mode">ΛΕΙΤΟΥΡΓΙΑ ΚΥΚΛΩΜΑΤΟΣ LGS</string>
<string name="uel_open_loop_mode">ΛΕΙΤΟΥΡΓΙΑ ΑΝΟΙΚΤΟΥ ΚΥΚΛΩΜΑΤΟΣ</string>
<string name="uel_loop_disabled">ΑΠΕΝΕΡΓΟΠΟΙΗΣΗ ΚΥΚΛΩΜΑΤΟΣ</string>
<string name="uel_loop_enabled">ΕΝΕΡΓΟΠΟΙΗΣΗ ΚΥΚΛΩΜΑΤΟΣ</string>
<string name="uel_reconnect">ΕΝΑΝΑΣΥΝΔΕΣΗ</string>
<string name="uel_disconnect">ΑΠΟΣΥΝΔΕΣΗ</string>
<string name="uel_resume">ΕΠΑΝΑΦΟΡΑ</string>
<string name="uel_suspend">ΑΝΑΣΤΟΛΗ</string>
<string name="uel_hw_pump_allowed">ΑΝΤΛΙΑ HW ΕΠΙΤΡΕΠΕΤΑΙ</string>
<string name="uel_clear_pairing_keys">ΚΑΘΑΡΙΣΜΟΣ ΚΛΕΙΔΙΩΝ ΖΕΥΓΟΠΟΙΗΣΗΣ</string>
<string name="uel_accepts_temp_basal">ΑΠΟΔΟΧΗ ΠΡΟΣΩΡΙΝΟΥ ΒΑΣΙΚΟΥ</string>
<string name="uel_cancel_temp_basal">ΑΚΥΡΩΣΗ ΠΡΟΣΩΡΙΝΟΥ ΒΑΣΙΚΟΥ</string>
<string name="uel_cancel_bolus">ΑΚΥΡΩΣΗ BOLUS</string>
<string name="uel_cancel_extended_bolus">ΑΚΥΡΩΣΗ ΕΚΤΕΤΑΜΕΝΟΥ BOLUS</string>
<string name="uel_cancel_tt">ΑΚΥΡΩΣΗ ΠΡΟΣΩΡΙΝΟΥ ΣΤΟΧΟΥ</string>
<string name="uel_careportal">CAREPORTAL</string>
<string name="uel_site_change">ΑΛΛΑΓΗ ΣΗΜΕΙΟΥ</string>
<string name="uel_reservoir_change">ΑΛΛΑΓΗ ΔΕΞΑΜΕΝΗΣ</string>
<string name="uel_calibration">ΒΑΘΜΟΝΟΜΗΣΗ</string>
<string name="uel_prime_bolus">ΠΡΩΤΕΥΟΝ BOLUS</string>
<string name="uel_treatment">ΘΕΡΑΠΕΙΑ</string>
<string name="uel_careportal_ns_refresh">ΑΝΑΝΕΩΣΗ CAREPORTAL NS</string>
<string name="uel_profile_switch_ns_refresh">ΑΝΑΝΕΩΣΗ ΑΛΛΑΓΗΣ ΠΡΟΦΙΛ NS</string>
<string name="uel_treatments_ns_refresh">ΑΝΑΝΕΩΣΗ ΘΕΡΑΠΕΙΩΝ NS</string>
<string name="uel_tt_ns_refresh">ΑΝΑΝΕΩΣΗ ΠΡΟΣΩΡΙΝΟΥ ΣΤΟΧΟΥ NS</string>
<string name="uel_automation_removed">ΑΥΤΟΜΑΤΙΣΜΟΣ ΑΦΑΙΡΕΘΗΚΕ</string>
<string name="uel_bg_removed">ΜΕΤΡΗΣΗ ΓΛΥΚΟΖΗΣ ΑΙΜΑΤΟΣ ΑΦΑΙΡΕΘΗΚΕ</string>
<string name="uel_careportal_removed">CAREPORTAL ΑΦΑΙΡΕΘΗΚΕ</string>
<string name="uel_bolus_removed">BOLUS ΑΦΑΙΡΕΘΗΚΕ</string>
<string name="uel_carbs_removed">ΥΔΑΤΑΝΘΡΑΚΕΣ ΑΦΑΙΡΕΘΗΚΑΝ</string>
<string name="uel_temp_basal_removed">ΠΡΟΣΩΡΙΝΟΣ ΒΑΣΙΚΟΣ ΑΦΑΙΡΕΘΗΚΕ</string>
<string name="uel_extended_bolus_removed">ΕΚΤΕΤΑΜΕΝΟ BOLUS ΑΦΑΙΡΕΘΗΚΕ</string>
<string name="uel_food">ΤΡΟΦΗ</string>
<string name="uel_food_removed">ΑΦΑΙΡΕΣΗ ΤΡΟΦΗΣ</string>
<string name="uel_profile_removed">ΑΦΑΙΡΕΣΗ ΠΡΟΦΙΛ</string>
<string name="uel_profile_switch_removed">ΑΦΑΙΡΕΣΗ ΑΛΛΑΓΗΣ ΠΡΟΦΙΛ</string>
<string name="uel_restart_events_removed">ΑΦΑΙΡΕΣΗ ΕΠΑΝΕΝΑΡΞΗΣ ΓΕΓΟΝΟΤΩΝ</string>
<string name="uel_treatment_removed">ΑΦΑΙΡΕΣΗ ΘΕΡΑΠΕΙΩΝ</string>
<string name="uel_tt_removed">ΠΡΟΣΩΡΙΝΟΣ ΒΑΣΙΚΟΣ ΑΦΑΙΡΕΘΗΚΕ</string>
<string name="uel_ns_paused">ΠΑΥΣΗ NS</string>
<string name="uel_ns_resume">ΑΠΟΚΑΤΑΣΤΑΣΗ NS</string>
<string name="uel_ns_queue_cleared">ΕΚΚΑΘΑΡΙΣΗ ΟΥΡΑΣ NS</string>
<string name="uel_ns_settings_copied">ΑΝΤΙΓΡΑΦΗ ΡΥΘΜΙΣΕΩΝ NS</string>
<string name="uel_error_dialog_ok">ΠΑΡΑΘΥΡΟ ΣΦΑΛΜΑΤΟΣ ΟΚ</string>
<string name="uel_error_dialog_mute">ΠΑΡΑΘΥΡΟ ΣΦΑΛΜΑΤΟΣ ΣΙΓΑΣΗ </string>
<string name="uel_error_dialog_mute_5min">ΠΑΡΑΘΥΡΟ ΣΦΑΛΜΑΤΟΣ ΣΙΓΑΣΗ 5ΛΕΠΤΑ</string>
<string name="uel_objective_started">ΕΝΑΡΞΗ ΣΤΟΧΟΥ</string>
<string name="uel_objectives_skipped">ΠΑΡΑΛΗΨΗ ΣΤΟΧΟΥ</string>
<string name="uel_stat_reset">ΕΠΑΝΑΦΟΡΑ ΣΤΑΤΙΣΤΙΚΩΝ</string>
<string name="uel_delete_logs">ΔΙΑΓΡΑΦΗ ΚΑΤΑΓΡΑΦΩΝ</string>
<string name="uel_delete_future_treatments">ΔΙΑΓΡΑΦΗ ΜΕΛΛΟΝΤΙΚΩΝ ΘΕΡΑΠΕΙΩΝ</string>
<string name="delete_future_treatments">Διαγραφή μελλοντικών θεραπειών</string>
<string name="uel_export_settings">ΕΞΑΓΩΓΗ ΡΥΘΜΙΣΕΩΝ</string>
<string name="uel_import_settings">ΕΙΣΑΓΩΓΗ ΡΥΘΜΙΣΕΩΝ</string>
<string name="uel_reset_databases">ΕΠΑΝΑΦΟΡΑ ΒΑΣΕΩΝ ΔΕΔΟΜΕΝΩΝ</string>
<string name="uel_cleanup_databases">ΕΚΚΑΘΑΡΙΣΗ ΒΑΣΕΩΝ ΔΕΔΟΜΕΝΩΝ</string>
<string name="uel_export_databases">ΕΞΑΓΩΓΗ ΒΑΣΕΩΝ ΔΕΔΟΜΕΝΩΝ</string>
<string name="uel_import_databases">ΕΙΣΑΓΩΓΗ ΒΑΣΕΩΝ ΔΕΔΟΜΕΝΩΝ</string>
<string name="uel_otp_export">ΕΞΑΓΩΓΗ OTP</string>
<string name="uel_otp_reset">ΕΠΑΝΑΦΟΡΑ OTP</string>
<string name="uel_stop_sms">ΔΙΑΚΟΠΗ SMS</string>
<string name="uel_export_csv">ΕΞΑΓΩΓΗ ΕΓΓΡΑΦΩΝ ΧΡΗΣΤΗ</string>
<string name="uel_start_aaps">ΕΝΑΡΞΗ AAPS</string>
<string name="uel_exit_aaps">ΕΞΟΔΟΣ ΑΠΟ AAPS</string>
<string name="uel_plugin_enabled">ΕΝΕΡΓΟΠΟΙΗΣΗ ΠΡΟΣΘΕΤΟΥ</string>
<string name="uel_plugin_disabled">ΑΠΕΝΕΡΓΟΠΟΙΗΣΗ ΠΡΟΣΘΕΤΟΥ</string>
<string name="uel_unknown">ΑΓΝΩΣΤΟ</string>
<string name="ue_string">Συμβολοσειρά</string>
<string name="ue_source">Πηγή</string>
<string name="ue_utc_offset">Μετατόπιση UTC</string>
<string name="ue_action">Ενέργεια</string>
<string name="ue_timestamp">Χρονοσήμανση</string>
<string name="ue_none">Χωρίς Μονάδα</string>
<string name="uel_loop_change">ΤΟ ΚΥΚΛΩΜΑ ΑΛΛΑΞΕ</string>
<string name="uel_loop_removed">ΤΟ ΚΥΚΛΩΜΑ ΑΦΑΙΡΕΘΗΚΕ</string>
<string name="uel_other">ΑΛΛΟ</string>
<!-- HardLimits -->
<string name="profile_low_target">Χαμηλός στόχος προφίλ</string>
<string name="profile_high_target">Υψηλός στόχος προφίλ</string>
<string name="temp_target_low_target">Κάτω τιμή προσωρινού στόχου</string>
<string name="temp_target_high_target">Πάνω τιμή προσωρινού στόχου</string>
<string name="temp_target_value">Τιμή προσωρινού στόχου</string>
<string name="profile_dia">Τιμή DIA του προφίλ</string>
<string name="profile_sensitivity_value">Τιμή ευαισθησίας προφίλ</string>
<string name="profile_max_daily_basal_value">Μέγιστη τιμή βασικού ρυθμού προφίλ</string>
<string name="current_basal_value">Τρέχουσα τιμή βασικού</string>
<string name="profile_carbs_ratio_value">Τιμή αναλογίας υδατανθράκων προφίλ</string>
<string name="valuelimitedto">Το %1$.2f περιορίζεται σε %2$.2f</string>
<string name="valueoutofrange">» Το%1$s« είναι εκτός ορίων</string>
<string name="value_out_of_hard_limits">Η τιμή »%1$s« %2$.2f είναι εκτός ορίων</string>
<string name="basal_value">Τιμή Βασικού ρυθμού</string>
<!-- Command Queue + readStatus reasons -->
<string name="bolus_u_min">BOLUS %1$.2f U</string>
<string name="carbs_g">ΥΔΑΤΑΝΘΡΑΚΕΣ %1$d g</string>
<string name="extended_bolus_u_min">ΕΚΤΕΤΑΜΕΝΟ BOLUS %1$.2f U %2$d λεπτά</string>
<string name="load_events">ΦΟΡΤΩΣΗ ΓΕΓΟΝΟΤΩΝ</string>
<string name="clear_alarms">ΕΚΚΑΘΑΡΙΣΗ ΣΥΝΑΓΕΡΜΩΝ</string>
<string name="deactivate">ΑΠΕΝΕΡΓΟΠΟΙΗΣΗ</string>
<string name="update_time">ΧΡΟΝΟΣ ΕΝΗΜΕΡΩΣΗΣ</string>
<string name="load_history">ΦΟΡΤΩΣΗ ΙΣΤΟΡΙΚΟΥ %1$d</string>
<string name="load_tdds">ΦΟΡΤΩΣΗ ΤΩΝ TDD</string>
<string name="set_profile">ΟΡΙΣΜΟΣ ΠΡΟΦΙΛ</string>
<string name="set_user_settings">ΟΡΙΣΜΟΣ ΡΥΘΜΙΣΕΩΝ ΧΡΗΣΤΗ</string>
<string name="smb_bolus_u">SMB BOLUS %1$.2f U</string>
<string name="start_pump">ΕΝΑΡΞΗ ΑΝΤΛΙΑΣ</string>
<string name="stop_pump">ΔΙΑΚΟΠΗ ΑΝΤΛΙΑΣ</string>
<string name="temp_basal_absolute">ΠΡΟΣΩΡΙΝΟΣ ΒΑΣΙΚΟΣ ΡΥΘΜΟΣ %1$.2f U/h %2$d λεπτά</string>
<string name="temp_basal_percent">ΠΡΟΣΩΡΙΝΟΣ ΒΑΣΙΚΟΣ ΡΥΘΜΟΣ %1$d%% %2$d λεπτά</string>
<string name="insight_set_tbr_over_notification">ΟΡΙΣΜΟΣ INSIGHT TBR ΜΕΣΩ ΕΙΔΟΠΟΙΗΣΗΣ</string>
<string name="read_status" comment="10 characters max for READSTATUS translation">ΑΝΑΓΝΩΣΗ ΚΑΤΑΣΤΑΣΗΣ %1$s</string>
<string name="keepalive_status_outdated" comment="26 characters max for translation">KeepAlive. Κατάσταση ξεπερασμένη.</string>
<string name="keepalive_basal_outdated" comment="26 characters max for translation">KeepAlive. Βασικός ρυθμός πεπερασμένος.</string>
<string name="sms" comment="26 characters max for translation">SMS</string>
<string name="formatPercent">%1$.0f%%</string>
<string name="basal">Βασικός Ρυθμός</string>
<string name="basalpct">Βασικός Ρυθμός %</string>
<string name="a11y_file">αρχείο</string>
<string name="a11y_user">χρήστης</string>
<!-- Autotune -->
<string name="autotune">Autotune</string>
<string name="autotune_description">Βοήθεια για πιθανές προσαρμογές του προφίλ (ISF, αναλογία υδατανθράκων και βασικοί ρυθμοί)</string>
<string name="autotune_shortname">AT</string>
<string name="autotune_settings">Ρυθμίσεις Autotune</string>
<string name="autotune_auto_title">Αυτοματισμός Εναλλαγής Προφίλ</string>
<string name="autotune_auto_summary">Αν ενεργοποιηθεί, το Autotune θα ενημερώνει αυτόματα και θα αλλάζει το προεπιλεγμένο Προφίλ μετά τον υπολογισμό από έναν κανόνα αυτοματισμού.</string>
<string name="autotune_categorize_uam_as_basal_title">Κατηγοριοποίηση του UAM ως βασικού</string>
<string name="autotune_categorize_uam_as_basal_summary">Ενεργοποιήστε μόνο αν έχετε εισαγάγει αξιόπιστα όλους τους υδατάνθρακες που καταναλώνονται, με αυτή την επιλογή ξαφνικές αυξήσεις που εμφανίζονται θα χρησιμοποιηθούν από το Autotune για να προτείνουν αλλαγές στο βασικό ρυθμό.</string>
<string name="autotune_tune_insulin_curve_title">Συντονισμός καμπύλης ινσουλίνης</string>
<string name="autotune_tune_insulin_curve_summary">Ενεργοποιήστε μόνο αν χρησιμοποιείτε free peak. Αυτή η επιλογή θα συντονίσει τις διάρκειες των peak και DIA</string>
<string name="autotune_default_tune_days_title">Αριθμός ημερών δεδομένων</string>
<string name="autotune_circadian_ic_isf_title">Εφαρμόστε το μέσο αποτέλεσμα σε κιρκαδικό IC/ISF</string>
<string name="autotune_circadian_ic_isf_summary">Το Autotune δεν θα συντονίσει τις κιρκαδικές παραλλαγές, αυτή η επιλογή ισχύει μόνο για του μέσο συντονισμό του IC και ISF στο κιρκαδικό προφίλ εισόδου σας</string>
<string name="autotune_additional_log_title">Συμπερίληψη περισσότερων πληροφοριών καταγραφής για τον εντοπισμό σφαλμάτων</string>
<string name="autotune_additional_log_summary">Ενεργοποιήστε μόνο αν ζητηθεί από τον προγραματιστή η αποστολή περισσότερων πληροφοριών καταγραφής για να βοηθήσει στην αποσφαλμάτωση του προσθέτου Autotune</string>
<string name="autotune_default_tune_days_summary">Προεπιλεγμένος αριθμός ημερών δεδομένων προς επεξεργασία από το Autotune (έως 30)</string>
<string name="autotune_tunedprofile_name">Συντονισμένο</string>
<string name="autotune_profile">Προφίλ :</string>
<string name="autotune_tune_days">Ημέρες συντονισμού:</string>
<string name="autotune_last_run">Τελευταίος Υπολογισμός :</string>
<string name="autotune_warning">Προειδοποίηση :</string>
<string name="autotune_select_profile">Επιλέξτε προφίλ για συντονισμό</string>
<string name="autotune_ic_warning">Το επιλεγμένο προφίλ έχει τιμές IC %1$d. Το Autotune θα χρησιμοποιήσει %2$.2f g/U</string>
<string name="autotune_isf_warning">Το επιλεγμένο προφίλ έχει τιμές ISF %1$d. Το Autotune θα χρησιμοποιήσει %2$.1f %3$s/U</string>
<string name="autotune_error">Σφάλμα στα εισαχθέντα δεδομένα, προσπαθήστε να εκτελέσετε ξανά το autotune ή μειώστε τον αριθμό των ημερών</string>
<string name="autotune_error_more_days">Σφάλμα στα εισαχθέντα δεδομένα , αυξήστε τον αριθμό των ημερών</string>
<string name="autotune_warning_during_run">Ο υπολογισμός Autotune ξεκίνησε, παρακαλώ να είστε υπομονετικοί</string>
<string name="autotune_warning_after_run">Ελέγξτε προσεκτικά τα αποτελέσματα πριν τα χρησιμοποιήσετε!</string>
<string name="autotune_partial_result">Ημέρα μερικού αποτελέσματος %1$d / %2$d ρυθμίστηκε</string>
<string name="autotune_result">Αποτέλεσμα: %1$s</string>
<string name="autotune_param">Παράμετρος</string>
<string name="autotune_percent">%</string>
<string name="autotune_missing">Χαμένες</string>
<string name="autotune_profile_name">Προφίλ Autotune %1$s</string>
<string name="autotune_run">Εκτέλεση Autotune</string>
<string name="autotune_check_input_profile_button">Έλεγχος προφίλ εισόδου</string>
<string name="autotune_compare_profile">Σύγκριση προφίλ</string>
<string name="autotune_copy_localprofile_button">Αντιγραφή στο τοπικό προφίλ</string>
<string name="autotune_update_input_profile_button">Ενημέρωση προφίλ εισόδου</string>
<string name="autotune_revert_input_profile_button">Επαναφορά προφίλ εισόδου</string>
<string name="autotune_copy_local_profile_message">Δημιουργία ενός νέου τοπικού προφίλ από αυτό το Προφίλ Autotune;</string>
<string name="autotune_update_local_profile_message">Ενημέρωση του προφίλ %1$s με το Προφίλ Autotune;</string>
<string name="autotune_revert_local_profile_message">Επαναφορά προφίλ %1$s με Προφίλ Εισαγωγής;</string>
<string name="autotune_profile_invalid">Μη έγκυρο προφίλ</string>
<string name="autotune_run_without_autoswitch">Το Autotune έτρεξε χωρίς αλλαγή προφίλ</string>
<string name="autotune_run_with_autoswitch">Το Autotune έτρεξε έγινε αυτόματη αλλαγή προφίλ</string>
<string name="autotune_run_with_error">Σφάλμα κατά την τελευταία εκτέλεση του Autotune</string>
<string name="autotune_run_cancelled">Εντοπίστηκε μια άλλη εκτέλεση του Autotune, η εκτέλεση ακυρώθηκε</string>
<!-- Alerts -->
<string name="raise_notifications_as_android_notifications">Χρησιμοποιήστε ειδοποιήσεις συστήματος για ειδοποιήσεις και συναγερμούς</string>
<string name="urgent_alarm">Συναγερμός έκτακτης ανάγκης</string>
<string name="info">Πληροφορίες</string>
<!-- BolusWizard -->
<string name="bolus_advisor">Σύμβουλος Bolus</string>
<string name="bolus_advisor_message">Έχετε υπεργλυκαιμία. Αντί να φάτε τώρα συνιστάτε να περιμένετε μια καλύτερη γλυκαιμία. Θέλετε να κάνετε ένα διορθωτικό bolus τώρα και να γίνει υπενθύμιση όταν έρθει η ώρα να φάτε; Σε αυτή την περίπτωση δε θα καταγραφούν καθόλου υδατάνθρακες και θα πρέπει να χρησιμοποιήσετε τον οδηγό ξανά μετά την υπενθύμιση.</string>
<string name="cobvsiob">COB vs IOB (ενεργοί υδατάνθρακες vs ενεργή ινσουλίνη)</string>
<string name="slowabsorptiondetected"><![CDATA[<font color=\'%1$s\'>!!!!! Μικρή απορρόφηση υδατανθράκων ανιχνεύτηκε: %2$d%% της ώρας. Τσεκάρετε τους υπολογισμούς σας. COB μπορεί να υπερεκτιμήθηκε και να δόθηκε περισσότερη ινσουλίνη!!!!!</font>]]></string>
<string name="partialboluswizard">Χορήγηση του αποτελέσματος αυτού του μέρους του υπολογισμού bolus [%]</string>
<string name="partialboluswizard_reset_time">Χρονικό όριο παλιάς γλυκαιμίας [min]</string>
<string name="bolus_constraint_applied_warn">Ορίστηκε περιορισμός Bolus: %1$.2f U σε %2$.2f U</string>
<string name="bolus_recorded_only">Το Bolus μόνο θα καταγραφεί (δε θα χορηγηθεί από την αντλία)</string>
<string name="advisoralarm">Εκτέλεση συναγερμού όταν έρθει η ώρα να φάτε</string>
<string name="no_action_selected">Δεν έχει επιλεγεί καμία ενέργεια, δεν υπάρχει τίποτα να κάνει</string>
<string name="wizard_no_actual_bg">Δεν υπάρχει πρόσφατή γλυκόζη αίματος για να γίνει υπολογισμός!</string>
<string name="wizard_no_active_profile">Δεν ορίστηκε ενεργό προφίλ!</string>
<string name="wizard_no_cob">Άγνωστο COB! Λείπει Η ανάγνωση γλυκόζης αίματος ή έγινε πρόσφατα επανεκκίνηση της εφαρμογής;</string>
<string name="wizard_carbs_constraint">Παραβίαση περιορισμού υδατανθράκων!</string>
<string name="wizard_explain_calc">Υπολογισμός (IC: %1$.1f, ISF: %2$.1f)</string>
<string name="wizard_explain_carbs">Υδατάνθρακες: %1$.2fU</string>
<string name="wizard_explain_cob">COB: %1$.0fg %2$.2fU</string>
<string name="wizard_explain_bg">BG: %1$.2fU</string>
<string name="wizard_explain_iob">IOB: %1$.2fU</string>
<string name="wizard_explain_superbolus">Superbolus: %1$.2fU</string>
<string name="wizard_explain_trend">Τάση 15\': %1$.2fU</string>
<string name="wizard_explain_percent">Ποσοστό: %1$.2fU x %2$d%% ≈ %3$.2fU</string>
<string name="wizard_constraint_bolus_size">Παραβίαση περιορισμού ινσουλίνης!\nΔεν μπορούν να χορηγηθούν %1$.2fU</string>
<string name="wizard_explain_tt">Προσωρινός Στόχος: %1$s</string>
<string name="wizard_explain_tt_to">%1$s σε %2$s</string>
<string name="wizard_pump_not_available">Δεν υπάρχει διαθέσιμη αντλία!</string>
<string name="quickwizard">Γρήγορος Οδηγός</string>
<!-- Preferences-->
<string name="child">Παιδί</string>
<string name="teenage">Έφηβος</string>
<string name="adult">Ενήλικας</string>
<string name="resistant_adult">Ενήλικας με ανοχή στην ινσουλίνη</string>
<string name="pregnant">Κύηση</string>
<string name="patient_age_summary">Παρακαλώ επιλέξτε τύπο ασθενούς για να ορισθούν τα όρια ασφαλείας</string>
<string name="max_bolus_title">Μέγιστο επιτρεπτό bolus[U]</string>
<string name="max_carbs_title">Μέγιστο επιτρεπτό υδατανθράκων [g]</string>
<string name="patient_type">Τύπος ασθενή</string>
<!-- Protection-->
<string name="unlock_settings">Ξεκλείδωμα ρυθμίσεων</string>
<!-- Pumps -->
@ -224,14 +501,23 @@
<string name="serial_number">Serial number</string>
<string name="disconnected">Αποσυνδέθηκε</string>
<string name="connecting">Συνδέεται</string>
<string name="clicked_connect_to_pump" comment="26 characters max for translation">Πατήθηκε σύνδεση στην αντλία</string>
<string name="reservoir_value">%1$.0f / %2$d U</string>
<string name="daily_units">Μονάδες ανά ημέρα </string>
<string name="pump_icon">Εικονίδιο αντλίας</string>
<string name="view_profile">Δείτε το προφίλ</string>
<string name="pump_history">Ιστορικό αντλίας</string>
<string name="stats">Στατιστικά</string>
<string name="pump_driver_change" comment="26 characters max for translation">Αλλαγή οδηγού αντλίας.</string>
<string name="device_changed" comment="26 characters max for translation">Η συσκευή άλλαξε</string>
<string name="bolus_ok" comment="26 characters max for translation">Bolus OK</string>
<string name="temp_basal_delivery_error">Σφάλμα παράδοσης Προσ Ρυθμού</string>
<string name="not_set_short">Μη ορισμένο</string>
<string name="pump_busy">Αντλία απασχολημένη</string>
<string name="connection_error">Λάθος σύνδεσης αντλίας</string>
<string name="reading_pump_history">Ανάγνωση ιστορικού αντλίας</string>
<string name="password_cleared">Ο κωδικός εκκαθαρίστηκε!</string>
<string name="pairing">Σύζευξη</string>
<string name="initializing">Παραμετροποίηση...</string>
<!-- Constraints-->
<string name="limitingbasalratio">Ο μέγιστος βασικός ρυθμός περιορίζεται σε %1$.2f U/h λόγω ότι %2$s</string>
@ -242,6 +528,7 @@
<!-- Locale -->
<!-- Dialogs-->
<string name="confirmation">Επιβεβαίωση</string>
<string name="message">Μήνυμα</string>
<string name="ok">ΟΚ</string>
<string name="cancel">Ακύρωση</string>
<string name="dismiss">ΑΠΟΡΡΙΨΗ</string>
@ -251,12 +538,20 @@
<!-- TwoMessagesDialog -->
<string name="password_preferences_decrypt_prompt">Θα σας ζητηθεί ο βασικός κωδικός πρόσβασης, ο οποίος είναι απαραίτητος για την αποκωδικοποίηση των εισαγώμενων προτιμήσεων.</string>
<!-- NumberPicker -->
<string name="a11y_min_button_description">μείωση %1$s κατά %2$s</string>
<string name="a11y_plus_button_description">αύξηση %1$s κατά %2$s</string>
<string name="you_are_on_allowed_limit">Συμπληρώθηκε το επιτρεπόμενο όριο</string>
<string name="format_hour_minute">%1$dh %2$dm</string>
<!-- datetime layout -->
<string name="event_time_label">Ώρα Συμβάντος</string>
<!-- BluetoothDevicePreference -->
<string name="need_connect_permission">Η εφαρμογή χρειάζεται άδεια Bluetooth</string>
<!-- Combo-->
<string name="user_request" comment="26 characters max for translation">Αίτημα χρήστη</string>
<string name="pump_paired" comment="26 characters max for translation">Αντλία σε ζεύξη</string>
<!-- BlePreCheck-->
<string name="ble_not_supported">Χαμηλή ενέργεια Bluetooth δεν υποστηρίζεται.</string>
<string name="ble_not_supported_or_not_paired">Το Bluetooth Low Energy δεν υποστηρίζεται ή η συσκευή δεν είναι συνδεδεμένη.</string>
<string name="ble_not_enabled">Bluetooth μη ενεργοποιημένο.</string>
<string name="location_not_found_title">Τοποθεσία μη ενεργοποιημένη</string>
<string name="location_not_found_message">Για την εύρεση Bluetooth σε νεότερες συσκευές, η τοποθεσία πρέπει να είναι ενεργοποιημένη. Το AAPS δεν παρακολουθεί την τοποθεσία σας και μπορεί να απενεργοποιηθεί μετά την επιτυχή σύζευξη.</string>
@ -265,6 +560,9 @@
<!-- SmsCommunicator -->
<string name="smscommunicator_missingsmspermission">Απουσία δικαιωμάτων SMS</string>
<!-- About -->
<string name="cta_dont_kill_my_app_info">Μην σκοτώσεις την εφαρμογή μου;</string>
<string name="fabric_upload_disabled">Η μεταφόρτωση των αρχείων καταγραφής σφαλμάτων απενεργοποιήθηκε!</string>
<string name="about_link_urls">\n\nΤεκμηρίωση:\nhttps://wiki.aaps.app\n\nFacebook:\nhttps://www.facebook.com/groups/AndroidAPSUsers</string>
<plurals name="days">
<item quantity="one">%1$d ημέρες</item>
<item quantity="other">%1$d ημέρες</item>
@ -278,4 +576,7 @@
<item quantity="other">%1$d λεπτά</item>
</plurals>
<!-- Maintenance-->
<string name="cleanup_db_confirm">Θέλετε να καθαρίσετε τη βάση δεδομένων;\nΑυτή η ενέργεια θα αφαιρέσει την παρακολούθηση των αλλαγών και ιστορικά δεδομένα παλαιότερα από 3 μήνες.</string>
<string name="cleanup_db_confirm_sync">Θέλετε να εκκαθαρίσετε τη βάση δεδομένων;\nΑυτή η ενέργεια θα αφαιρέσει την παρακολούθηση των αλλαγών και ιστορικά δεδομένα παλαιότερα από 3 μήνες.\nΚάνοντας αυτό θα επιταχυνθεί δραματικά ο πλήρης συγχρονισμός.</string>
<string name="cleared_entries">Έγινε εκκαθάριση των καταχωρήσεων</string>
</resources>

View file

@ -139,7 +139,7 @@
<string name="none"><![CDATA[<nenhum>]]></string>
<string name="remove_label">REMOVER</string>
<string name="activate_profile">Ativar perfil</string>
<string name="reset">repor</string>
<string name="reset">redefinir</string>
<string name="profileswitch_ismissing">TrocaPerfil em falta. Por favor faça uma troca de perfil ou pressione \"Ativar Perfil\" em PerfilLocal.</string>
<string name="profile">Perfil</string>
<string name="select_for_removal">Selecione para remover</string>

View file

@ -6,15 +6,26 @@
<string name="application_protection">Protecție aplicație</string>
<string name="bolus_protection">Protecție bolus</string>
<string name="settings_password">Parolă setări</string>
<string name="settings_pin">Setări PIN</string>
<string name="application_password">Parolă aplicație</string>
<string name="application_pin">PIN Aplicație</string>
<string name="bolus_password">Parolă bolus</string>
<string name="bolus_pin">PIN Bolus</string>
<string name="protection_timeout_title">Reținerea parolei și a PIN-ului [s]</string>
<string name="protection_timeout_summary">Timpul până la introducerea parolei sau a PIN-ului</string>
<string name="biometric">Biometric</string>
<string name="custom_password">Parolă personalizată</string>
<string name="custom_pin">PIN particularizat</string>
<string name="noprotection">Fără protecţie</string>
<string name="unsecure_fallback_biometric">Trecere la modul nesecurizat biometric</string>
<string name="unsecure_fallback_descriotion_biometric">Pentru a fi eficientă, protecţia biometrică are nevoie de o parolă principală pentru regresie.\n\nVă rugăm să setaţi o parolă principală!</string>
<string name="password_set">Parola a fost setată!</string>
<string name="pin_set">PIN setat!</string>
<string name="password_not_set">Parola nu a fost setată</string>
<string name="pin_not_set">Cod PIN nesetat</string>
<string name="password_not_changed">Parola nu a fost modificată</string>
<string name="pin_not_changed">PIN nemodificat</string>
<string name="pin_cleared">PIN șters!</string>
<string name="password_hint">Introduceți parola aici</string>
<string name="pin_hint">Introduceți codul PIN aici</string>
</resources>

View file

@ -14,6 +14,7 @@
<string name="pump_base_basal_rate">%1$.2f U/h</string>
<string name="pump_not_initialized_profile_not_set">Pompa nu este inițializată, profilul nu este setat!</string>
<string name="failed_update_basal_profile">Actualizarea profilului bazalei a eșuat</string>
<string name="bolus_delivered_successfully">Bolusul de %1$.2fU a fost livrat cu succes</string>
<string name="no_valid_basal_rate">Nu s-a citit o rată bazală validă din pompă</string>
<string name="limiting_iob">Se limitează IOB la %1$.1f U datorită %2$s</string>
<string name="loop_disabled">BUCLĂ DEZACTIVATĂ DATORITĂ CONSTRÂNGERILOR</string>
@ -44,12 +45,15 @@
<string name="mute5min">Dezactivează pentru 5 minute</string>
<string name="mute">Liniște</string>
<string name="success">Succes</string>
<string name="advanced_settings_title">Setări avansate</string>
<string name="extendedbolusdeliveryerror">Eroare de livrare a bolusului extins</string>
<string name="aps_mode_title">Mod APS</string>
<string name="extended_bolus">Bolus extins</string>
<string name="paused">Suspendat</string>
<string name="tdd_total">Total TDD</string>
<string name="goingtodeliver">Se vor livra %1$.2fU</string>
<string name="waitingforpump">Se așteaptă pompa</string>
<string name="androidaps_start">AAPS pornit</string>
<string name="formatsignedinsulinunits">%1$+.2f U</string>
<string name="format_carbs">%1$d g</string>
<string name="format_hours">%1$.2f h</string>
@ -58,6 +62,8 @@
<string name="please_wait">Așteptați…</string>
<string name="stop">Stop</string>
<string name="carbs">Carbohidrați</string>
<string name="invalid_profile">Profil invalid!</string>
<string name="no_profile_set">NICIUN PROFIL SETAT</string>
<string name="active"><![CDATA[<Activ>]]></string>
<string name="date">Data</string>
<string name="units_label">Unități</string>
@ -66,7 +72,11 @@
<string name="isf_label">ISF</string>
<string name="basal_label">Bazală</string>
<string name="target_label">Țintă</string>
<string name="dia_long_label">Durata de Acțiune a Insulinei (DIA)</string>
<string name="ic_long_label">Rația insulină pt. carbohidraţi (IC sau ICR)</string>
<string name="isf_long_label">Factorul de sensibilitate la insulină (ISF)</string>
<string name="basal_long_label">Rată bazală</string>
<string name="target_long_label">Glicemie țintă</string>
<string name="shortgram">g</string>
<string name="shortpercent">%</string>
<string name="bluetooth">Bluetooth</string>
@ -96,6 +106,8 @@
<string name="loading">Se încarcă…</string>
<string name="notes_label">Note</string>
<string name="remove_button">Șterge</string>
<string name="add_new">Adăugare nouă</string>
<string name="addnew_above">Adăugare nouă deasupra</string>
<string name="wrong_pump_data">Datele vin de la o pompa diferita. Schimba driver-ul de pompa pentru a reseta starea pompei.</string>
<string name="bg_label">Gl</string>
<string name="calibration">Calibrare</string>
@ -108,10 +120,19 @@
<string name="notconfigured">Nu este configurat</string>
<string name="loopsuspended">Buclă suspendată</string>
<string name="trend_arrow">Săgeată tendinţă</string>
<string name="a11y_autosens_label">Auto sens</string>
<string name="required">req</string>
<string name="a11y_arrow_double_down">în scădere rapidă</string>
<string name="a11y_arrow_single_down">în scădere</string>
<string name="a11y_arrow_forty_five_down">în scădere lentă</string>
<string name="a11y_arrow_flat">stabilă</string>
<string name="a11y_arrow_forty_five_up">în creștere lentă</string>
<string name="a11y_arrow_single_up">în creștere</string>
<string name="a11y_arrow_double_up">în creștere rapidă</string>
<string name="a11y_arrow_none">nimic</string>
<string name="a11y_arrow_unknown">necunoscută</string>
<string name="a11y_high">hiper</string>
<string name="a11y_inrange">în țintă</string>
<string name="a11y_low">hipo</string>
<string name="average">Medie</string>
<string name="tir">Timp în țintă</string>
@ -121,6 +142,7 @@
<string name="reset">resetare</string>
<string name="profileswitch_ismissing">Lipsă SchimbareProfil. Efectuați o schimbare de profil sau apăsați \"Activare profil\" în ProfilulLocal.</string>
<string name="profile">Profil</string>
<string name="select_for_removal">Selectează pentru ștergere</string>
<string name="confirm_remove_multiple_items">Sigur vrei să elimini %1$d element(e)</string>
<string name="overview_treatment_label">Tratament</string>
<string name="copytolocalprofile">Creați un profil nou din acest profil?</string>
@ -131,6 +153,7 @@
<string name="treatments_wizard_basaliob_label">IOB bazală</string>
<string name="invalid">INVALID</string>
<string name="login">Autentificare</string>
<string name="prime_fill">Amorsare/Umplere</string>
<string name="overview_insulin_label">Insulină</string>
<string name="stoptemptarget">Oprește o țintă temporară</string>
<string name="closedloop">Buclă închisă</string>
@ -139,13 +162,19 @@
<string name="dia">DIA</string>
<string name="ic_short">IC</string>
<string name="isf_short">ISF</string>
<string name="canceling_tbr_failed">Anularea ratei bazale temporare a eșuat</string>
<string name="canceling_eb_failed">Anularea bolusului extins a eșuat</string>
<string name="virtualpump_uploadstatus_title">Trimitere status către NS sau Tidepool</string>
<string name="suspendloop_label">Buclă dezactivată/suspendată</string>
<string name="iob_label">Insulină activă (IOB)</string>
<!-- Protection-->
<string name="wrongpassword">Parola greșită</string>
<string name="wrongpin">PIN greșit</string>
<string name="passwords_dont_match">Parolele nu corespund</string>
<string name="pin_dont_match">PIN-urile nu se potrivesc</string>
<!-- Profile-->
<string name="basalprofilenotaligned">Valori bazale nesincronizate cu ora: %1$s</string>
<string name="minimalbasalvaluereplaced">Valoarea bazalei a fost înlocuită cu valoarea minimă posibilă: %1$s</string>
<string name="maximumbasalvaluereplaced">Valoarea bazalei a fost înlocuită cu valoarea maximă posibilă: %1$s</string>
<string name="profile_per_unit">/U</string>
<string name="profile_ins_units_per_hour">U/h</string>
@ -153,6 +182,7 @@
<!-- ProfileFunction-->
<string name="startprofile">Utilizează profilul %1$d%% pentru %2$d min</string>
<!-- APSResult-->
<string name="cancel_temp">Anulare rată bazală temporară</string>
<string name="let_temp_basal_run">Lasă să funcționeze bazala temporară</string>
<string name="rate">Rată</string>
<string name="duration">Durată</string>
@ -174,9 +204,12 @@
<string name="careportal_note_message">Notă: %1$s</string>
<string name="careportal_question_message">Întrebare : %1$s</string>
<string name="careportal_exercise_message">Exercițiu fizic: %1$s</string>
<string name="careportal_pump_site_change">Schimbare canulă/loc infuzie</string>
<string name="cgm_sensor_insert">Inserare senzor</string>
<string name="careportal_cgmsensorstart">Start senzor</string>
<string name="careportal_cgm_sensor_stop">Stop senzor CGM</string>
<string name="careportal_dad_alert">Alertă D.A.D.</string>
<string name="careportal_insulin_cartridge_change">Schimbare cartuș insulină</string>
<string name="careportal_profileswitch">Schimbare de profil</string>
<string name="careportal_snackbolus">Bolus Gustare</string>
<string name="careportal_mealbolus">Bolus Masă</string>
@ -186,6 +219,8 @@
<string name="careportal_tempbasalend">Sfârșit bazală temporară</string>
<string name="careportal_carbscorrection">Corecție de carbohidrați</string>
<string name="careportal_openapsoffline">OpenAPS Offline</string>
<string name="pump_battery_change">Schimbare baterie pompă</string>
<string name="temporary_target">Ţintă temporară</string>
<string name="careportal_temporarytargetvalue">Valoare țintă temporară</string>
<string name="careportal_temporarytargetcancel">Oprire ţintă temporară</string>
<string name="boluswizard">Asistent bolusare</string>
@ -212,7 +247,9 @@
<string name="waitingforpumpresult">Se așteaptă rezultatul</string>
<string name="smb_shortname">SMB</string>
<!-- CarbsReq-->
<string name="carbsreq">%1$d g carbohidrați suplimentari necesari în %2$d minute</string>
<!-- TDDStatsActivity-->
<string name="cumulative_tdd">TDD cumulată</string>
<string name="expweight">TDD estimat exponențial</string>
<string name="basalrate">Bazală</string>
<string name="bolus">Bolus</string>
@ -221,6 +258,7 @@
<string name="amount_days"># Zile</string>
<string name="weight">Greutate</string>
<string name="warning_Message">Posibil fără acuratețe bună dacă folosiți bolus de insulină pentru amorsare/umplere!</string>
<string name="olddata_Message">Date vechi, te rog apasă \"REÎNCĂRCARE\"</string>
<string name="tbb">Total bazală implicită</string>
<string name="tbb2">TBB * 2</string>
<!-- Ntp-->
@ -293,9 +331,11 @@
<string name="uel_stat_reset">RESET STATISTICI</string>
<string name="uel_delete_logs">STERGERE JURNAL</string>
<string name="uel_delete_future_treatments">STERGERE TRATAMENTE VIITOARE</string>
<string name="delete_future_treatments">Șterge tratamentele viitoare</string>
<string name="uel_export_settings">EXPORT SETARI</string>
<string name="uel_import_settings">IMPORT SETARI</string>
<string name="uel_reset_databases">RESETARE BAZE DE DATE</string>
<string name="uel_cleanup_databases">CURĂȚĂ BAZELE DE DATE</string>
<string name="uel_export_databases">EXPORT BAZE DE DATE</string>
<string name="uel_import_databases">IMPORT BAZE DE DATE</string>
<string name="uel_otp_export">EXPORT OTP</string>
@ -336,6 +376,9 @@
<string name="carbs_g">CARB %1$d g</string>
<string name="extended_bolus_u_min">BOLUS EXTINS %1$.2f U %2$d min</string>
<string name="load_events">ÎNCARCA EVENIMENTE</string>
<string name="clear_alarms">ȘTERGE ALARMELE</string>
<string name="deactivate">DEZACTIVEAZĂ</string>
<string name="update_time">ACTUALIZEAZĂ ORA</string>
<string name="load_history">ÎNCARCA ISTORICUL %1$d</string>
<string name="load_tdds">ÎNCARCA TDD-uri</string>
<string name="set_profile">SETARE PROFIL</string>
@ -353,25 +396,99 @@
<string name="formatPercent">%1$.0f%%</string>
<string name="basal">Rate bazale</string>
<string name="basalpct">Bazală %</string>
<string name="a11y_file">fişier</string>
<string name="a11y_user">utilizator</string>
<!-- Autotune -->
<string name="autotune">Autotune</string>
<string name="autotune_description">Ajutor în scopul potențialelor ajustări ale profilului (ISF, IC și ratele bazale)</string>
<string name="autotune_shortname">AT</string>
<string name="autotune_settings">Setări Autotune</string>
<string name="autotune_auto_title">Automatizare schimbare profil</string>
<string name="autotune_auto_summary">Dacă este activată, Autotune va actualiza automat profilul și va comuta la profilul nou în baza unui calcul făcut cu regula de automatizare.</string>
<string name="autotune_categorize_uam_as_basal_title">Clasifică UAM ca bazală</string>
<string name="autotune_categorize_uam_as_basal_summary">Activează numai dacă ai introdus valori corecte de carbohidrați consumați. Cu această opțiune, creșterile bruște detectate de Autotune vor fi utilizate pentru a recomanda schimbări de rată bazală.</string>
<string name="autotune_tune_insulin_curve_title">Ajustați curba insulinei</string>
<string name="autotune_tune_insulin_curve_summary">Activați doar dacă folosiți vârf liber. Această opțiune va regla durata vârfului și a DIA</string>
<string name="autotune_default_tune_days_title">Număr de zile de date</string>
<string name="autotune_circadian_ic_isf_title">Aplică rezultatul mediu în circadian IC/ISF</string>
<string name="autotune_circadian_ic_isf_summary">Autotune nu va corecta variațiile circadiene. Această opțiune aplică o reglare medie a IC și ISF la profilul circadian înregistrat</string>
<string name="autotune_additional_log_title">Include mai multe informaţii de jurnal pentru depanare</string>
<string name="autotune_additional_log_summary">Activați numai dacă se solicită de către dezvoltator pentru a trimite mai multe informații în jurnal pentru a ajuta la depanarea pluginului Autotune</string>
<string name="autotune_default_tune_days_summary">Numărul implicit de zile de date pentru a fi procesate automat (până la 30)</string>
<string name="autotune_tunedprofile_name">Ajustat</string>
<string name="autotune_profile">Profil :</string>
<string name="autotune_tune_days">Zilele de reglare:</string>
<string name="autotune_last_run">Ultima executare :</string>
<string name="autotune_warning">Atenție :</string>
<string name="autotune_select_profile">Selectați profilul pentru reglare</string>
<string name="autotune_ic_warning">Profilul selectat are %1$d valori IC. Autotune va utiliza %2$.2f g/U</string>
<string name="autotune_isf_warning">Profilul selectat are %1$d valori ISF. Autotune va folosi %2$.1f %3$s/U</string>
<string name="autotune_error">Eroare în datele introduse, încercați să rulați din nou automat sau să reduceți numărul de zile</string>
<string name="autotune_error_more_days">Eroare în datele de introducere, mărește numărul de zile</string>
<string name="autotune_warning_during_run">Calcularea automată a început, vă rugăm să aveți răbdare</string>
<string name="autotune_warning_after_run">Verificați cu atenție rezultatele înainte de a le utiliza!</string>
<string name="autotune_partial_result">Rezultatul parțial din ziua %1$d / %2$d ajustat</string>
<string name="autotune_result">Rezultat: %1$s</string>
<string name="autotune_param">Param</string>
<string name="autotune_percent">%</string>
<string name="autotune_missing">Lipsă</string>
<string name="autotune_profile_name">Autotune profilul %1$s</string>
<string name="autotune_run">Rulează Autotune</string>
<string name="autotune_check_input_profile_button">Verificați profilul de intrare</string>
<string name="autotune_compare_profile">Compară profilurile</string>
<string name="autotune_copy_localprofile_button">Copiați în profilul local</string>
<string name="autotune_update_input_profile_button">Actualizați profilul de intrare</string>
<string name="autotune_revert_input_profile_button">Reveniţi la profilul de intrare</string>
<string name="autotune_copy_local_profile_message">Creați un profil local nou din acest profil Autotune?</string>
<string name="autotune_update_local_profile_message">Actualizați profilul %1$s cu Profil Autotune?</string>
<string name="autotune_revert_local_profile_message">Reveniți la profilul %1$s cu profilul de intrare?</string>
<string name="autotune_profile_invalid">Profil invalid</string>
<string name="autotune_run_without_autoswitch">Autotune a rulat fără schimbarea profilului</string>
<string name="autotune_run_with_autoswitch">Autotune a rulat și profilul a fost automat schimbat</string>
<string name="autotune_run_with_error">Eroare în timpul ultimei rulări Autotune</string>
<string name="autotune_run_cancelled">O altă rulare Autotune este detectată, rularea este anulată</string>
<!-- Alerts -->
<string name="raise_notifications_as_android_notifications">Se folosesc notificările sistemului pentru alerte și notificări</string>
<string name="urgent_alarm">Alarmă urgentă</string>
<string name="info">INFO</string>
<!-- BolusWizard -->
<string name="bolus_advisor">Consilier bolus</string>
<string name="bolus_advisor_message">Ai glicemia crescută. În loc să mănânci acum, este recomandat să aştepţi o glicemie mai bună. Vrei să faci un bolus de corecție acum și să îți reamintesc când este timpul să mănânci? În acest caz, niciun carbohidrat nu va fi înregistrat și trebuie să utilizezi din nou calculatorul de vbolus când îți voi reaminti.</string>
<string name="cobvsiob">COB vs IOB</string>
<string name="slowabsorptiondetected"><![CDATA[<font color=\'%1$s\'>!!!!! A fost detectată o absorbție lentă a carbohidraților: %2$d%% din timp. Reverificați calculele. COB poate fi supraestimat, astfel că este posibilă administrarea de mai multă insulină !!!!!</font>]]></string>
<string name="partialboluswizard">Livrați doar partea aceasta din rezultatul sugerat de wizard [%]</string>
<string name="partialboluswizard_reset_time">Prag de timp pentru vechimea glicemiei [min]</string>
<string name="bolus_constraint_applied_warn">Este aplicatâ limitarea bolusului %1$.2f U la %2$.2f U</string>
<string name="bolus_recorded_only">Bolusul va fi doar consemnat (nu va fi livrat de pompă)</string>
<string name="advisoralarm">Rulează alarma când este timpul să mănânci</string>
<string name="no_action_selected">Nicio acțiune selectată, nu se va întâmpla nimic</string>
<string name="wizard_no_actual_bg">Nicio glicemie recentă pe care să se bazeze calculul!</string>
<string name="wizard_no_active_profile">Niciun profil activ stabilit!</string>
<string name="wizard_no_cob">COB necunoscut! Lipsesc datele de glicemie sau aplicația a fost repornită de curând?</string>
<string name="wizard_carbs_constraint">Limite carbohidrați încălcate!</string>
<string name="wizard_explain_calc">Calc (IC: %1$.1f, ISF: %2$.1f)</string>
<string name="wizard_explain_carbs">Carbohidrați: %1$.2fU</string>
<string name="wizard_explain_cob">COB: %1$.0fg %2$.2fU</string>
<string name="wizard_explain_bg">Glicemie: %1$.2fU</string>
<string name="wizard_explain_iob">IOB: %1$.2fU</string>
<string name="wizard_explain_superbolus">Superbolus: %1$.2fU</string>
<string name="wizard_explain_trend">Tendința la 15\': %1$.2fU</string>
<string name="wizard_explain_percent">Procentaj: %1$.2fU x %2$d%% ≈ %3$.2fU</string>
<string name="wizard_constraint_bolus_size">Încălcare constrângere insulină!\nNu se pot livra %1$.2fU</string>
<string name="wizard_explain_tt">BazalaT.: %1$s</string>
<string name="wizard_explain_tt_to">Între %1$s și %2$s</string>
<string name="wizard_pump_not_available">Nicio pompă disponibilă!</string>
<string name="quickwizard">Asistent Rapid</string>
<!-- Preferences-->
<string name="child">Copil</string>
<string name="teenage">Adolescent</string>
<string name="adult">Adult</string>
<string name="resistant_adult">Adult cu rezistență la insulină</string>
<string name="pregnant">Sarcină</string>
<string name="patient_age_summary">Te rog confirmă tipul de pacient pentru a stabili limitele de siguranță</string>
<string name="max_bolus_title">Bolus maxim admis [U]</string>
<string name="max_carbs_title">Carbohidrați admiși maxim [g]</string>
<string name="patient_type">Tip de pacient</string>
<!-- Protection-->
<string name="unlock_settings">Deblochează setările</string>
<!-- Pumps -->
@ -422,6 +539,9 @@
<!-- TwoMessagesDialog -->
<string name="password_preferences_decrypt_prompt">Vi se va solicita parola principală, care este necesară pentru a decripta setările importate.</string>
<!-- NumberPicker -->
<string name="a11y_min_button_description">scădere %1$s cu %2$s</string>
<string name="a11y_plus_button_description">creștere %1$s cu %2$s</string>
<string name="you_are_on_allowed_limit">S-a atins limita permisă</string>
<string name="format_hour_minute">%1$dh %2$dm</string>
<!-- datetime layout -->
<string name="event_time_label">Ora evenimentului</string>
@ -441,6 +561,9 @@
<!-- SmsCommunicator -->
<string name="smscommunicator_missingsmspermission">Lipsesc permisiunile de SMS</string>
<!-- About -->
<string name="cta_dont_kill_my_app_info">Nu-mi opri aplicația?</string>
<string name="fabric_upload_disabled">Încărcarea jurnalelor de erori este dezactivata!</string>
<string name="about_link_urls">\n\nDocumentation:\nhttps://wiki.aaps.app\n\nFacebook:\nhttps://www.facebook.com/groups/AndroidAPSUsers</string>
<plurals name="days">
<item quantity="one">%1$d zi</item>
<item quantity="few">%1$d zile</item>
@ -457,4 +580,7 @@
<item quantity="other">%1$d minute</item>
</plurals>
<!-- Maintenance-->
<string name="cleanup_db_confirm">Doriți să curățați baza de date?\nAceasta va elimina schimbările înregistrate și datele istorice mai vechi de 3 luni.</string>
<string name="cleanup_db_confirm_sync">Doriți să curățați baza de date?\nAceasta va elimina schimbările înregistrate și datele istorice mai vechi de 3 luni.\nFăcând acest lucru, veți accelera foarte mult sincronizarea completă.</string>
<string name="cleared_entries">Înregistrări șterse</string>
</resources>

View file

@ -376,6 +376,9 @@
<string name="carbs_g">УГЛ %1$d г</string>
<string name="extended_bolus_u_min">Пролонгированный болюс %1$.2f ед %2$d мин</string>
<string name="load_events">ЗАГРУЗИТЬ СОБЫТИЯ</string>
<string name="clear_alarms">ОЧИСТИТЬ ОПОВЕЩЕНИЯ</string>
<string name="deactivate">ДЕАКТИВИРОВАТЬ</string>
<string name="update_time">ВРЕМЯ ОБНОВЛЕНИЯ</string>
<string name="load_history">ЗАГРУЗИТЬ ИСТОРИЮ %1$d</string>
<string name="load_tdds">ЗАГРУЗИТЬ СУТ ДОЗЫ</string>
<string name="set_profile">ЗАДАТЬ ПРОФИЛЬ</string>
@ -421,6 +424,7 @@
<string name="autotune_ic_warning">Выбранный профиль имеет %1$d значений IC. Автоматически будет использоваться %2$.2f г/ед</string>
<string name="autotune_isf_warning">Выбранный профиль имеет %1$d значений ISF. Автоматически будет использоваться %2$.1f%3$s/ед</string>
<string name="autotune_error">Ошибка ввода данных, попробуйте запустить снова autotune или уменьшить количество дней</string>
<string name="autotune_error_more_days">Ошибка в данных, увеличьте количество дней</string>
<string name="autotune_warning_during_run">Идет настройка автоматизации, ждите</string>
<string name="autotune_warning_after_run">Перед использованием внимательно проверьте результаты!</string>
<string name="autotune_partial_result">Частичный результат дня %1$d / %2$d с отладкой</string>

View file

@ -1,2 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>
<resources>
<string name="count_selected">Επιλέχθηκε %1$d</string>
<string name="remove_items">Αφαίρεση Στοιχείων</string>
<string name="sort_items">Ταξινόμηση Στοιχείων</string>
<string name="remove_selected_items">Αφαίρεση Επιλεγμένων Στοιχείων</string>
<string name="sort_label">Ταξινόμηση</string>
</resources>

View file

@ -17,6 +17,5 @@ android {
dependencies {
implementation project(':app-wear-shared:shared')
implementation project(':core:interfaces')
api "com.google.android.material:material:$material_version"
}

View file

@ -34,8 +34,7 @@ import info.nightscout.core.validators.validators.PinStrengthValidator
import info.nightscout.core.validators.validators.RegexpValidator
import info.nightscout.core.validators.validators.Validator
import info.nightscout.core.validators.validators.WebUrlValidator
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.interfaces.ProfileUtil
import javax.inject.Inject
@Suppress("SpellCheckingInspection")
@ -61,7 +60,7 @@ class DefaultEditTextValidator : EditTextValidator {
private var floatminNumber = 0f
private var floatmaxNumber = 0f
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var profileUtil: ProfileUtil
@Suppress("unused")
constructor(editTextView: EditText, context: Context) {
@ -98,7 +97,6 @@ class DefaultEditTextValidator : EditTextValidator {
}
private fun setEditText(editText: EditText) {
//editTextView?.removeTextChangedListener(textWatcher)
editTextView = editText
editText.addTextChangedListener(getTextWatcher())
}
@ -110,7 +108,9 @@ class DefaultEditTextValidator : EditTextValidator {
testValidity()
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { /* not needed */
}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
if (!TextUtils.isEmpty(s) && isErrorShown) {
try {
@ -156,9 +156,12 @@ class DefaultEditTextValidator : EditTextValidator {
EditTextValidator.TEST_PERSONNAME -> PersonNameValidator(if (TextUtils.isEmpty(testErrorString)) context.getString(R.string.error_notvalid_personname) else testErrorString)
EditTextValidator.TEST_PERSONFULLNAME -> PersonFullNameValidator(if (TextUtils.isEmpty(testErrorString)) context.getString(R.string.error_notvalid_personfullname) else testErrorString)
EditTextValidator.TEST_MIN_LENGTH -> MinDigitLengthValidator(if (TextUtils.isEmpty(testErrorString)) context.getString(R.string.error_not_a_minimum_length) else testErrorString, minLength)
EditTextValidator.TEST_BG_RANGE -> BgRangeValidator(if (TextUtils.isEmpty(testErrorString)) context.getString(R.string.error_only_numeric_digits_range_allowed,
Profile.fromMgdlToUnits(minMgdl.toDouble(), profileFunction.getUnits()).toString(), Profile.fromMgdlToUnits(maxMgdl.toDouble(), profileFunction.getUnits()).toString()) else
testErrorString, minMgdl, maxMgdl, profileFunction)
EditTextValidator.TEST_BG_RANGE -> BgRangeValidator(
if (TextUtils.isEmpty(testErrorString)) context.getString(
R.string.error_only_numeric_digits_range_allowed,
profileUtil.fromMgdlToUnits(minMgdl.toDouble()).toString(), profileUtil.fromMgdlToUnits(maxMgdl.toDouble()).toString()
) else testErrorString, minMgdl, maxMgdl, profileUtil
)
EditTextValidator.TEST_CUSTOM -> {
// must specify the fully qualified class name & an error message

View file

@ -5,9 +5,8 @@ import android.util.AttributeSet
import androidx.preference.EditTextPreference
import androidx.preference.PreferenceViewHolder
import dagger.android.HasAndroidInjector
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.SafeParse
import info.nightscout.shared.interfaces.ProfileUtil
import javax.inject.Inject
class ValidatingEditTextPreference(ctx: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : EditTextPreference(ctx, attrs, defStyleAttr, defStyleRes) {
@ -15,7 +14,7 @@ class ValidatingEditTextPreference(ctx: Context, attrs: AttributeSet, defStyleAt
private val validatorParameters: DefaultEditTextValidator.Parameters = obtainValidatorParameters(attrs)
private var validator: DefaultEditTextValidator? = null
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var profileUtil: ProfileUtil
init {
(ctx.applicationContext as HasAndroidInjector).androidInjector().inject(this)
@ -75,14 +74,14 @@ class ValidatingEditTextPreference(ctx: Context, attrs: AttributeSet, defStyleAt
override fun onSetInitialValue(defaultValue: Any?) {
text =
if (validatorParameters.testType == EditTextValidator.TEST_BG_RANGE)
Profile.fromMgdlToUnits(SafeParse.stringToDouble(getPersistedString(defaultValue as String?)), profileFunction.getUnits()).toString()
profileUtil.fromMgdlToUnits(SafeParse.stringToDouble(getPersistedString(defaultValue as String?)), profileUtil.units).toString()
else
getPersistedString(defaultValue as String?)
}
override fun persistString(value: String?): Boolean =
when (validatorParameters.testType) {
EditTextValidator.TEST_BG_RANGE -> super.persistString(Profile.toMgdl(SafeParse.stringToDouble(value, 0.0), profileFunction.getUnits()).toString())
EditTextValidator.TEST_BG_RANGE -> super.persistString(profileUtil.convertToMgdl(SafeParse.stringToDouble(value, 0.0), profileUtil.units).toString())
EditTextValidator.TEST_FLOAT_NUMERIC_RANGE -> super.persistString(SafeParse.stringToDouble(value, 0.0).toString())
else -> super.persistString(value)
}

View file

@ -1,15 +1,14 @@
package info.nightscout.core.validators.validators
import android.widget.EditText
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.interfaces.ProfileUtil
class BgRangeValidator(_customErrorMessage: String?, private val min: Int, private val max: Int, private val profileFunction: ProfileFunction) : Validator(_customErrorMessage) {
class BgRangeValidator(customErrorMessage: String?, private val min: Int, private val max: Int, private val profileUtil: ProfileUtil) : Validator(customErrorMessage) {
override fun isValid(editText: EditText): Boolean {
return try {
val value = editText.text.toString().toDouble()
value in Profile.fromMgdlToUnits(min.toDouble(), profileFunction.getUnits())..Profile.fromMgdlToUnits(max.toDouble(), profileFunction.getUnits())
value in profileUtil.fromMgdlToUnits(min.toDouble())..profileUtil.fromMgdlToUnits(max.toDouble())
} catch (e: NumberFormatException) {
false
}

View file

@ -2,6 +2,23 @@
<resources>
<string name="error_only_numeric_digits_allowed">Μόνο αριθμητικά ψηφία επιτρέπονται.</string>
<string name="error_only_numeric_digits_range_allowed">Μόνο αριθμητικά ψηφία μέσα στο εύρος %1$s - %2$s επιτρέπονται. </string>
<string name="error_this_field_cannot_contain_special_character">Αυτό το πεδίο δεν μπορεί να περιέχει ειδικούς χαρακτήρες</string>
<string name="error_only_standard_letters_are_allowed">Επιτρέπονται μόνο τυπικά γράμματα</string>
<string name="error_field_must_not_be_empty">Το πεδίο αυτό δεν πρέπει να είναι κενό</string>
<string name="error_email_address_not_valid">Μη έγκυρη διεύθυνση ηλεκτρονικού ταχυδρομείου</string>
<string name="error_creditcard_number_not_valid">Μη έγκυρος αριθμός πιστωτικής κάρτας</string>
<string name="error_phone_not_valid">Μη έγκυρος αριθμός τηλεφώνου</string>
<string name="error_domain_not_valid">Μη έγκυρο όνομα τομέα</string>
<string name="error_ip_not_valid">Μη έγκυρη διεύθυνση IP</string>
<string name="error_url_not_valid">Μη έγκυρη διεύθυνση Web</string>
<string name="error_notvalid_personname">Μη έγκυρο όνομα ή επώνυμο.</string>
<string name="error_notvalid_personfullname">Μη έγκυρο πλήρες όνομα.</string>
<string name="error_date_not_valid">Μη έγκυρη μορφοποίηση</string>
<string name="error_mustbe4digitnumber">Πρέπει να περιέχει 4 ψηφία</string>
<string name="error_mustbe6digitnumber">Πρέπει να περιέχει 6 ψηφία</string>
<string name="error_mustbe12hexadidits">Πρέπει να είναι 12 χαρακτήρες από τους ABCDEF0123456789</string>
<string name="error_mustbe8hexadidits">Πρέπει να είναι 8 χαρακτήρες από τους ABCDEF0123456789</string>
<string name="error_mustbe4hexadidits">Πρέπει να είναι 4 χαρακτήρες από τους ABCDEF0123456789</string>
<string name="error_not_a_minimum_length">Μη ελάχιστο μήκος</string>
<string name="error_pin_not_valid">Το Pin πρέπει να είναι 3 έως 6 ψηφία, όχι ίδια μεταξύ τους ή σε σειρά</string>
</resources>

View file

@ -4,8 +4,7 @@ import info.nightscout.annotations.OpenForTesting
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.DefaultValueHelper
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.sharedPreferences.SP
import javax.inject.Inject
import javax.inject.Singleton
@ -14,7 +13,7 @@ import javax.inject.Singleton
@Singleton
class DefaultValueHelperImpl @Inject constructor(
private val sp: SP,
private val profileFunction: ProfileFunction
private val profileUtil: ProfileUtil
) : DefaultValueHelper {
/**
@ -53,9 +52,9 @@ class DefaultValueHelperImpl @Inject constructor(
* @return
*/
override fun determineEatingSoonTT(): Double {
val units = profileFunction.getUnits()
val units = profileUtil.units
var value = sp.getDouble(info.nightscout.core.utils.R.string.key_eatingsoon_target, getDefaultEatingSoonTT(units))
value = Profile.toCurrentUnits(profileFunction, value)
value = profileUtil.valueInCurrentUnitsDetect(value)
return if (value > 0) value else getDefaultEatingSoonTT(units)
}
@ -70,9 +69,9 @@ class DefaultValueHelperImpl @Inject constructor(
* @return
*/
override fun determineActivityTT(): Double {
val units = profileFunction.getUnits()
val units = profileUtil.units
var value = sp.getDouble(info.nightscout.core.utils.R.string.key_activity_target, getDefaultActivityTT(units))
value = Profile.toCurrentUnits(profileFunction, value)
value = profileUtil.valueInCurrentUnitsDetect(value)
return if (value > 0) value else getDefaultActivityTT(units)
}
@ -87,9 +86,9 @@ class DefaultValueHelperImpl @Inject constructor(
* @return
*/
override fun determineHypoTT(): Double {
val units = profileFunction.getUnits()
val units = profileUtil.units
var value = sp.getDouble(info.nightscout.core.utils.R.string.key_hypo_target, getDefaultHypoTT(units))
value = Profile.toCurrentUnits(profileFunction, value)
value = profileUtil.valueInCurrentUnitsDetect(value)
return if (value > 0) value else getDefaultHypoTT(units)
}
@ -104,14 +103,14 @@ class DefaultValueHelperImpl @Inject constructor(
override fun determineHighLine(): Double {
var highLineSetting = sp.getDouble(info.nightscout.core.utils.R.string.key_high_mark, bgTargetHigh)
if (highLineSetting < 1) highLineSetting = Constants.HIGH_MARK
highLineSetting = Profile.toCurrentUnits(profileFunction, highLineSetting)
highLineSetting = profileUtil.valueInCurrentUnitsDetect(highLineSetting)
return highLineSetting
}
override fun determineLowLine(): Double {
var lowLineSetting = sp.getDouble(info.nightscout.core.utils.R.string.key_low_mark, bgTargetLow)
if (lowLineSetting < 1) lowLineSetting = Constants.LOW_MARK
lowLineSetting = Profile.toCurrentUnits(profileFunction, lowLineSetting)
lowLineSetting = profileUtil.valueInCurrentUnitsDetect(lowLineSetting)
return lowLineSetting
}
}

View file

@ -18,6 +18,7 @@ import info.nightscout.implementation.overview.OverviewDataImpl
import info.nightscout.implementation.plugin.PluginStore
import info.nightscout.implementation.profile.ProfileFunctionImpl
import info.nightscout.implementation.profile.ProfileStoreObject
import info.nightscout.implementation.profile.ProfileUtilImpl
import info.nightscout.implementation.profiling.ProfilerImpl
import info.nightscout.implementation.protection.PasswordCheckImpl
import info.nightscout.implementation.protection.ProtectionCheckImpl
@ -36,6 +37,7 @@ import info.nightscout.implementation.stats.TddCalculatorImpl
import info.nightscout.implementation.stats.TirCalculatorImpl
import info.nightscout.implementation.storage.FileStorage
import info.nightscout.implementation.userEntry.UserEntryPresentationHelperImpl
import info.nightscout.implementation.utils.DecimalFormatterImpl
import info.nightscout.interfaces.LocalAlertUtils
import info.nightscout.interfaces.NotificationHolder
import info.nightscout.interfaces.Translator
@ -62,8 +64,10 @@ import info.nightscout.interfaces.stats.TirCalculator
import info.nightscout.interfaces.storage.Storage
import info.nightscout.interfaces.ui.IconsProvider
import info.nightscout.interfaces.userEntry.UserEntryPresentationHelper
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.HardLimits
import info.nightscout.interfaces.utils.TrendCalculator
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
@Module(
@ -81,6 +85,7 @@ abstract class ImplementationModule {
@Module
interface Bindings {
@Binds fun bindPersistenceLayer(persistenceLayerImpl: PersistenceLayerImpl): PersistenceLayer
@Binds fun bindActivePlugin(pluginStore: PluginStore): ActivePlugin
@Binds fun bindOverviewData(overviewData: OverviewDataImpl): OverviewData
@ -108,9 +113,11 @@ abstract class ImplementationModule {
@Binds fun bindNotificationHolderInterface(notificationHolder: NotificationHolderImpl): NotificationHolder
@Binds fun bindCommandQueue(commandQueue: CommandQueueImplementation): CommandQueue
@Binds fun bindsProfileFunction(profileFunctionImpl: ProfileFunctionImpl): ProfileFunction
@Binds fun bindsProfileUtil(profileUtilImpl: ProfileUtilImpl): ProfileUtil
@Binds fun bindsStorage(fileStorage: FileStorage): Storage
@Binds fun bindsReceiverStatusStore(receiverStatusStoreImpl: ReceiverStatusStoreImpl): ReceiverStatusStore
@Binds fun bindsUserEntryPresentationHelper(userEntryPresentationHelperImpl: UserEntryPresentationHelperImpl): UserEntryPresentationHelper
@Binds fun bindsGlucoseStatusProvider(glucoseStatusProviderImpl: GlucoseStatusProviderImpl): GlucoseStatusProvider
@Binds fun bindsDecimalFormatter(decimalFormatterImpl: DecimalFormatterImpl): DecimalFormatter
}
}

View file

@ -7,6 +7,7 @@ import info.nightscout.core.iob.log
import info.nightscout.interfaces.iob.GlucoseStatus
import info.nightscout.interfaces.iob.GlucoseStatusProvider
import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.utils.DateUtil
@ -18,7 +19,8 @@ import kotlin.math.roundToLong
class GlucoseStatusProviderImpl @Inject constructor(
private val aapsLogger: AAPSLogger,
private val iobCobCalculator: IobCobCalculator,
private val dateUtil: DateUtil
private val dateUtil: DateUtil,
private val decimalFormatter: DecimalFormatter
) : GlucoseStatusProvider {
override val glucoseStatusData: GlucoseStatus?
@ -100,7 +102,7 @@ class GlucoseStatusProviderImpl @Inject constructor(
shortAvgDelta = shortAverageDelta,
delta = delta,
longAvgDelta = average(longDeltas),
).also { aapsLogger.debug(LTag.GLUCOSE, it.log()) }.asRounded()
).also { aapsLogger.debug(LTag.GLUCOSE, it.log(decimalFormatter)) }.asRounded()
}
/* Real BG (previous) version

View file

@ -34,6 +34,7 @@ import info.nightscout.interfaces.iob.IobTotal
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.DefaultValueHelper
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
@ -52,7 +53,8 @@ class OverviewDataImpl @Inject constructor(
private val activePlugin: ActivePlugin,
private val defaultValueHelper: DefaultValueHelper,
private val profileFunction: ProfileFunction,
private val repository: AppRepository
private val repository: AppRepository,
private val decimalFormatter: DecimalFormatter
) : OverviewData {
override var rangeToDisplay = 6 // for graph
@ -182,7 +184,7 @@ class OverviewDataImpl @Inject constructor(
profileFunction.getProfile()?.let { profile ->
var temporaryBasal = iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now())
if (temporaryBasal?.isInProgress == false) temporaryBasal = null
temporaryBasal?.let { "T:" + it.toStringShort() }
temporaryBasal?.let { "T:" + it.toStringShort(decimalFormatter) }
?: rh.gs(info.nightscout.core.ui.R.string.pump_base_basal_rate, profile.getBasal())
} ?: rh.gs(info.nightscout.core.ui.R.string.value_unavailable_short)
@ -190,7 +192,7 @@ class OverviewDataImpl @Inject constructor(
profileFunction.getProfile()?.let { profile ->
iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now())?.let { temporaryBasal ->
"${rh.gs(info.nightscout.core.ui.R.string.base_basal_rate_label)}: ${rh.gs(info.nightscout.core.ui.R.string.pump_base_basal_rate, profile.getBasal())}" +
"\n" + rh.gs(info.nightscout.core.ui.R.string.tempbasal_label) + ": " + temporaryBasal.toStringFull(profile, dateUtil)
"\n" + rh.gs(info.nightscout.core.ui.R.string.tempbasal_label) + ": " + temporaryBasal.toStringFull(profile, dateUtil, decimalFormatter)
}
?: "${rh.gs(info.nightscout.core.ui.R.string.base_basal_rate_label)}: ${rh.gs(info.nightscout.core.ui.R.string.pump_base_basal_rate, profile.getBasal())}"
} ?: rh.gs(info.nightscout.core.ui.R.string.value_unavailable_short)
@ -227,7 +229,7 @@ class OverviewDataImpl @Inject constructor(
} ?: ""
override fun extendedBolusDialogText(iobCobCalculator: IobCobCalculator): String =
iobCobCalculator.getExtendedBolus(dateUtil.now())?.toStringFull(dateUtil) ?: ""
iobCobCalculator.getExtendedBolus(dateUtil.now())?.toStringFull(dateUtil, decimalFormatter) ?: ""
/*
* IOB, COB

View file

@ -0,0 +1,72 @@
package info.nightscout.implementation.profile
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.sharedPreferences.SP
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class ProfileUtilImpl @Inject constructor(
private val sp: SP,
private val decimalFormatter: DecimalFormatter
) : ProfileUtil {
override val units: GlucoseUnit
get() =
if (sp.getString(info.nightscout.core.utils.R.string.key_units, GlucoseUnit.MGDL.asText) == GlucoseUnit.MGDL.asText) GlucoseUnit.MGDL
else GlucoseUnit.MMOL
override fun fromMgdlToUnits(valueInMgdl: Double, targetUnits: GlucoseUnit): Double =
if (targetUnits == GlucoseUnit.MGDL) valueInMgdl else valueInMgdl * GlucoseUnit.MGDL_TO_MMOLL
override fun fromMmolToUnits(value: Double, targetUnits: GlucoseUnit): Double =
if (targetUnits == GlucoseUnit.MMOL) value else value * GlucoseUnit.MMOLL_TO_MGDL
override fun valueInCurrentUnitsDetect(anyBg: Double): Double =
if (isMmol(anyBg)) fromMmolToUnits(anyBg, units)
else fromMgdlToUnits(anyBg, units)
override fun stringInCurrentUnitsDetect(anyBg: Double): String =
if (isMmol(anyBg)) toUnitsString(anyBg * GlucoseUnit.MMOLL_TO_MGDL, units)
else toUnitsString(anyBg, units)
override fun fromMgdlToStringInUnits(valueInMgdl: Double?, targetUnits: GlucoseUnit): String =
valueInMgdl?.let { toUnitsString(valueInMgdl, targetUnits) } ?: ""
override fun fromMgdlToSignedStringInUnits(valueInMgdl: Double, targetUnits: GlucoseUnit): String =
if (targetUnits == GlucoseUnit.MGDL) (if (valueInMgdl > 0) "+" else "") + decimalFormatter.to0Decimal(valueInMgdl)
else (if (valueInMgdl > 0) "+" else "") + decimalFormatter.to1Decimal(valueInMgdl * GlucoseUnit.MGDL_TO_MMOLL)
override fun isMgdl(anyBg: Double) = anyBg >= 39
override fun isMmol(anyBg: Double) = anyBg < 39
override fun unitsDetect(anyBg: Double) = if (isMgdl(anyBg)) GlucoseUnit.MGDL else GlucoseUnit.MMOL
override fun valueInUnitsDetect(anyBg: Double, targetUnits: GlucoseUnit): Double =
if (isMmol(anyBg)) fromMmolToUnits(anyBg, targetUnits)
else fromMgdlToUnits(anyBg, targetUnits)
override fun stringInUnitsDetect(anyBg: Double, targetUnits: GlucoseUnit): String =
if (isMmol(anyBg)) toUnitsString(anyBg * GlucoseUnit.MMOLL_TO_MGDL, targetUnits)
else toUnitsString(anyBg, targetUnits)
override fun convertToMgdlDetect(anyBg: Double): Double =
if (isMgdl(anyBg)) anyBg else anyBg * GlucoseUnit.MMOLL_TO_MGDL
override fun convertToMgdl(value: Double, sourceUnits: GlucoseUnit): Double =
if (sourceUnits == GlucoseUnit.MGDL) value else value * GlucoseUnit.MMOLL_TO_MGDL
override fun convertToMmol(value: Double, sourceUnits: GlucoseUnit): Double =
if (sourceUnits == GlucoseUnit.MGDL) value * GlucoseUnit.MGDL_TO_MMOLL else value
override fun toTargetRangeString(low: Double, high: Double, sourceUnits: GlucoseUnit, targetUnits: GlucoseUnit): String {
val lowMgdl = convertToMgdl(low, sourceUnits)
val highMgdl = convertToMgdl(high, sourceUnits)
return if (low == high) toUnitsString(lowMgdl, targetUnits)
else toUnitsString(lowMgdl, targetUnits) + " - " + toUnitsString(highMgdl, targetUnits)
}
private fun toUnitsString(valueInMgdl: Double, targetUnits: GlucoseUnit): String =
if (targetUnits == GlucoseUnit.MGDL) decimalFormatter.to0Decimal(valueInMgdl) else decimalFormatter.to1Decimal(valueInMgdl * GlucoseUnit.MGDL_TO_MMOLL)
}

View file

@ -57,6 +57,7 @@ import info.nightscout.interfaces.queue.Command.CommandType
import info.nightscout.interfaces.queue.CommandQueue
import info.nightscout.interfaces.queue.CustomCommand
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.HtmlHelper
import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus
@ -95,7 +96,8 @@ class CommandQueueImplementation @Inject constructor(
private val fabricPrivacy: FabricPrivacy,
private val androidPermission: AndroidPermission,
private val uiInteraction: UiInteraction,
private val persistenceLayer: PersistenceLayer
private val persistenceLayer: PersistenceLayer,
private val decimalFormatter: DecimalFormatter
) : CommandQueue {
private val disposable = CompositeDisposable()
@ -132,7 +134,7 @@ class CommandQueueImplementation @Inject constructor(
targetBlocks = nonCustomized.targetBlocks,
glucoseUnit = if (it.glucoseUnit == ProfileSwitch.GlucoseUnit.MGDL) EffectiveProfileSwitch.GlucoseUnit.MGDL else EffectiveProfileSwitch.GlucoseUnit.MMOL,
originalProfileName = it.profileName,
originalCustomizedName = it.getCustomizedName(),
originalCustomizedName = it.getCustomizedName(decimalFormatter),
originalTimeshift = it.timeshift,
originalPercentage = it.percentage,
originalDuration = it.duration,
@ -234,7 +236,7 @@ class CommandQueueImplementation @Inject constructor(
val tempCommandQueue = CommandQueueImplementation(
injector, aapsLogger, rxBus, aapsSchedulers, rh,
constraintChecker, profileFunction, activePlugin, context, sp,
config, dateUtil, repository, fabricPrivacy, androidPermission, uiInteraction, persistenceLayer
config, dateUtil, repository, fabricPrivacy, androidPermission, uiInteraction, persistenceLayer, decimalFormatter
)
tempCommandQueue.readStatus(reason, callback)
tempCommandQueue.disposable.clear()

View file

@ -5,10 +5,10 @@ import android.content.Context
import android.view.ViewGroup
import android.widget.TableLayout
import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.stats.DexcomTIR
import info.nightscout.interfaces.stats.DexcomTirCalculator
import info.nightscout.interfaces.utils.MidnightTime
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import javax.inject.Inject
@ -16,7 +16,7 @@ import javax.inject.Singleton
@Singleton
class DexcomTirCalculatorImpl @Inject constructor(
private val profileFunction: ProfileFunction,
private val profileUtil: ProfileUtil,
private val dateUtil: DateUtil,
private val repository: AppRepository
) : DexcomTirCalculator {
@ -38,10 +38,10 @@ class DexcomTirCalculatorImpl @Inject constructor(
TableLayout(context).also { layout ->
val tir = calculate()
layout.layoutParams = TableLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f)
layout.addView(tir.toRangeHeaderView(context, profileFunction))
layout.addView(tir.toRangeHeaderView(context, profileUtil))
layout.addView(tir.toTableRowHeader(context))
layout.addView(tir.toTableRow(context))
layout.addView(tir.toSDView(context, profileFunction))
layout.addView(tir.toSDView(context, profileUtil))
layout.addView(tir.toHbA1cView(context))
}
}

View file

@ -8,9 +8,8 @@ import android.widget.TableRow
import android.widget.TextView
import info.nightscout.implementation.R
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.stats.DexcomTIR
import info.nightscout.shared.interfaces.ProfileUtil
import java.util.Calendar
import kotlin.math.pow
import kotlin.math.roundToInt
@ -86,42 +85,42 @@ class DexcomTirImpl : DexcomTIR {
}
@SuppressLint("SetTextI18n")
override fun toSDView(context: Context, profileFunction: ProfileFunction): TextView =
override fun toSDView(context: Context, profileUtil: ProfileUtil): TextView =
TextView(context).apply {
val sd = calculateSD()
text = "\n" + context.getString(R.string.std_deviation, Profile.toUnitsString(sd, sd * Constants.MGDL_TO_MMOLL, profileFunction.getUnits()))
text = "\n" + context.getString(R.string.std_deviation, profileUtil.fromMgdlToStringInUnits(sd))
setTypeface(typeface, Typeface.NORMAL)
gravity = Gravity.CENTER_HORIZONTAL
}
override fun toRangeHeaderView(context: Context, profileFunction: ProfileFunction): TextView =
override fun toRangeHeaderView(context: Context, profileUtil: ProfileUtil): TextView =
TextView(context).apply {
text = StringBuilder()
.append(context.getString(R.string.detailed_14_days))
.append("\n")
.append(context.getString(R.string.day_tir))
.append(" (")
.append(Profile.toUnitsString(0.0, 0.0, profileFunction.getUnits()))
.append(profileUtil.fromMgdlToStringInUnits(0.0))
.append("-")
.append(Profile.toCurrentUnitsString(profileFunction, veryLowTirMgdl))
.append(profileUtil.stringInCurrentUnitsDetect(veryLowTirMgdl))
.append("-")
.append(Profile.toCurrentUnitsString(profileFunction, lowTirMgdl))
.append(profileUtil.stringInCurrentUnitsDetect(lowTirMgdl))
.append("-")
.append(Profile.toCurrentUnitsString(profileFunction, highTirMgdl))
.append(profileUtil.stringInCurrentUnitsDetect(highTirMgdl))
.append("-")
.append(Profile.toCurrentUnitsString(profileFunction, veryHighTirMgdl))
.append(profileUtil.stringInCurrentUnitsDetect(veryHighTirMgdl))
.append("-∞)\n")
.append(context.getString(R.string.night_tir))
.append(" (")
.append(Profile.toUnitsString(0.0, 0.0, profileFunction.getUnits()))
.append(profileUtil.fromMgdlToStringInUnits(0.0))
.append("-")
.append(Profile.toCurrentUnitsString(profileFunction, veryLowTirMgdl))
.append(profileUtil.stringInCurrentUnitsDetect(veryLowTirMgdl))
.append("-")
.append(Profile.toCurrentUnitsString(profileFunction, lowTirMgdl))
.append(profileUtil.stringInCurrentUnitsDetect(lowTirMgdl))
.append("-")
.append(Profile.toCurrentUnitsString(profileFunction, highNightTirMgdl))
.append(profileUtil.stringInCurrentUnitsDetect(highNightTirMgdl))
.append("-")
.append(Profile.toCurrentUnitsString(profileFunction, veryHighTirMgdl))
.append(profileUtil.stringInCurrentUnitsDetect(veryHighTirMgdl))
.append("-∞)\n")
.toString()
setTypeface(typeface, Typeface.BOLD)

View file

@ -10,11 +10,10 @@ import android.widget.TableLayout
import android.widget.TextView
import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.stats.TIR
import info.nightscout.interfaces.stats.TirCalculator
import info.nightscout.interfaces.utils.MidnightTime
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
@ -24,7 +23,7 @@ import javax.inject.Singleton
@Singleton
class TirCalculatorImpl @Inject constructor(
private val rh: ResourceHelper,
private val profileFunction: ProfileFunction,
private val profileUtil: ProfileUtil,
private val dateUtil: DateUtil,
private val repository: AppRepository
) : TirCalculator {
@ -88,7 +87,7 @@ class TirCalculatorImpl @Inject constructor(
layout.layoutParams = TableLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f)
layout.addView(
TextView(context).apply {
text = rh.gs(info.nightscout.core.ui.R.string.tir) + " (" + Profile.toCurrentUnitsString(profileFunction, lowTirMgdl) + "-" + Profile.toCurrentUnitsString(profileFunction, highTirMgdl) + ")"
text = rh.gs(info.nightscout.core.ui.R.string.tir) + " (" + profileUtil.stringInCurrentUnitsDetect(lowTirMgdl) + "-" + profileUtil.stringInCurrentUnitsDetect(highTirMgdl) + ")"
setTypeface(typeface, Typeface.BOLD)
gravity = Gravity.CENTER_HORIZONTAL
setTextAppearance(android.R.style.TextAppearance_Material_Medium)
@ -97,7 +96,7 @@ class TirCalculatorImpl @Inject constructor(
for (i in 0 until tir7.size()) layout.addView(tir7.valueAt(i).toTableRow(context, rh, dateUtil))
layout.addView(
TextView(context).apply {
text = rh.gs(info.nightscout.core.ui.R.string.average) + " (" + Profile.toCurrentUnitsString(profileFunction, lowTirMgdl) + "-" + Profile.toCurrentUnitsString(profileFunction, highTirMgdl) + ")"
text = rh.gs(info.nightscout.core.ui.R.string.average) + " (" + profileUtil.stringInCurrentUnitsDetect(lowTirMgdl) + "-" + profileUtil.stringInCurrentUnitsDetect(highTirMgdl) + ")"
setTypeface(typeface, Typeface.BOLD)
gravity = Gravity.CENTER_HORIZONTAL
setTextAppearance(android.R.style.TextAppearance_Material_Medium)
@ -106,7 +105,7 @@ class TirCalculatorImpl @Inject constructor(
layout.addView(averageTir30.toTableRow(context, rh, tir30.size()))
layout.addView(
TextView(context).apply {
text = rh.gs(info.nightscout.core.ui.R.string.average) + " (" + Profile.toCurrentUnitsString(profileFunction, lowTitMgdl) + "-" + Profile.toCurrentUnitsString(profileFunction, highTitMgdl) + ")"
text = rh.gs(info.nightscout.core.ui.R.string.average) + " (" + profileUtil.stringInCurrentUnitsDetect(lowTitMgdl) + "-" + profileUtil.stringInCurrentUnitsDetect(highTitMgdl) + ")"
setTypeface(typeface, Typeface.BOLD)
gravity = Gravity.CENTER_HORIZONTAL
setTextAppearance(android.R.style.TextAppearance_Material_Medium)

View file

@ -11,11 +11,10 @@ import info.nightscout.database.entities.ValueWithUnit
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.Translator
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.userEntry.UserEntryPresentationHelper
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.HtmlHelper
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.utils.DateUtil
import javax.inject.Inject
@ -23,9 +22,10 @@ import javax.inject.Inject
@Reusable
class UserEntryPresentationHelperImpl @Inject constructor(
private val translator: Translator,
private val profileFunction: ProfileFunction,
private val profileUtil: ProfileUtil,
private val rh: ResourceHelper,
private val dateUtil: DateUtil
private val dateUtil: DateUtil,
private val decimalFormatter: DecimalFormatter
) : UserEntryPresentationHelper {
override fun colorId(colorGroup: ColorGroup): Int = when (colorGroup) {
@ -126,8 +126,8 @@ class UserEntryPresentationHelperImpl @Inject constructor(
is ValueWithUnit.Hour -> "${valueWithUnit.value}${translator.translate(valueWithUnit)}"
is ValueWithUnit.Minute -> "${valueWithUnit.value}${translator.translate(valueWithUnit)}"
is ValueWithUnit.Percent -> "${valueWithUnit.value}${translator.translate(valueWithUnit)}"
is ValueWithUnit.Insulin -> DecimalFormatter.to2Decimal(valueWithUnit.value) + translator.translate(valueWithUnit)
is ValueWithUnit.UnitPerHour -> DecimalFormatter.to2Decimal(valueWithUnit.value) + translator.translate(valueWithUnit)
is ValueWithUnit.Insulin -> decimalFormatter.to2Decimal(valueWithUnit.value) + translator.translate(valueWithUnit)
is ValueWithUnit.UnitPerHour -> decimalFormatter.to2Decimal(valueWithUnit.value) + translator.translate(valueWithUnit)
is ValueWithUnit.SimpleInt -> valueWithUnit.value.toString()
is ValueWithUnit.SimpleString -> valueWithUnit.value
is ValueWithUnit.TherapyEventMeterType -> translator.translate(valueWithUnit.value)
@ -137,13 +137,13 @@ class UserEntryPresentationHelperImpl @Inject constructor(
is ValueWithUnit.Timestamp -> dateUtil.dateAndTimeAndSecondsString(valueWithUnit.value)
is ValueWithUnit.Mgdl -> {
if (profileFunction.getUnits() == GlucoseUnit.MGDL) DecimalFormatter.to0Decimal(valueWithUnit.value) + rh.gs(info.nightscout.core.ui.R.string.mgdl)
else DecimalFormatter.to1Decimal(valueWithUnit.value * Constants.MGDL_TO_MMOLL) + rh.gs(info.nightscout.core.ui.R.string.mmol)
if (profileUtil.units == GlucoseUnit.MGDL) decimalFormatter.to0Decimal(valueWithUnit.value) + rh.gs(info.nightscout.core.ui.R.string.mgdl)
else decimalFormatter.to1Decimal(valueWithUnit.value * Constants.MGDL_TO_MMOLL) + rh.gs(info.nightscout.core.ui.R.string.mmol)
}
is ValueWithUnit.Mmoll -> {
if (profileFunction.getUnits() == GlucoseUnit.MMOL) DecimalFormatter.to1Decimal(valueWithUnit.value) + rh.gs(info.nightscout.core.ui.R.string.mmol)
else DecimalFormatter.to0Decimal(valueWithUnit.value * Constants.MMOLL_TO_MGDL) + rh.gs(info.nightscout.core.ui.R.string.mgdl)
if (profileUtil.units == GlucoseUnit.MMOL) decimalFormatter.to1Decimal(valueWithUnit.value) + rh.gs(info.nightscout.core.ui.R.string.mmol)
else decimalFormatter.to0Decimal(valueWithUnit.value * Constants.MMOLL_TO_MGDL) + rh.gs(info.nightscout.core.ui.R.string.mgdl)
}
ValueWithUnit.UNKNOWN -> ""
@ -165,7 +165,7 @@ class UserEntryPresentationHelperImpl @Inject constructor(
csvString(info.nightscout.core.ui.R.string.careportal_note),
csvString(info.nightscout.core.ui.R.string.ue_string),
csvString(info.nightscout.core.ui.R.string.event_time_label),
csvString(if (profileFunction.getUnits() == GlucoseUnit.MGDL) info.nightscout.core.ui.R.string.mgdl else info.nightscout.core.ui.R.string.mmol),
csvString(if (profileUtil.units == GlucoseUnit.MGDL) info.nightscout.core.ui.R.string.mgdl else info.nightscout.core.ui.R.string.mmol),
csvString(info.nightscout.core.ui.R.string.shortgram),
csvString(info.nightscout.core.ui.R.string.insulin_unit_shortname),
csvString(info.nightscout.core.ui.R.string.profile_ins_units_per_hour),
@ -201,8 +201,8 @@ class UserEntryPresentationHelperImpl @Inject constructor(
is ValueWithUnit.Hour -> hour = valueWithUnit.value.toString()
is ValueWithUnit.Minute -> minute = valueWithUnit.value.toString()
is ValueWithUnit.Percent -> percent = valueWithUnit.value.toString()
is ValueWithUnit.Insulin -> insulin = DecimalFormatter.to2Decimal(valueWithUnit.value)
is ValueWithUnit.UnitPerHour -> unitPerHour = DecimalFormatter.to2Decimal(valueWithUnit.value)
is ValueWithUnit.Insulin -> insulin = decimalFormatter.to2Decimal(valueWithUnit.value)
is ValueWithUnit.UnitPerHour -> unitPerHour = decimalFormatter.to2Decimal(valueWithUnit.value)
is ValueWithUnit.SimpleInt -> noUnit = noUnit.addWithSeparator(valueWithUnit.value)
is ValueWithUnit.SimpleString -> simpleString = simpleString.addWithSeparator(valueWithUnit.value)
is ValueWithUnit.TherapyEventMeterType -> therapyEvent = therapyEvent.addWithSeparator(translator.translate(valueWithUnit.value))
@ -212,10 +212,10 @@ class UserEntryPresentationHelperImpl @Inject constructor(
is ValueWithUnit.Timestamp -> timestamp = dateUtil.dateAndTimeAndSecondsString(valueWithUnit.value)
is ValueWithUnit.Mgdl ->
bg = Profile.toUnitsString(valueWithUnit.value, valueWithUnit.value * Constants.MGDL_TO_MMOLL, profileFunction.getUnits())
bg = profileUtil.fromMgdlToStringInUnits(valueWithUnit.value)
is ValueWithUnit.Mmoll ->
bg = Profile.toUnitsString(valueWithUnit.value * Constants.MMOLL_TO_MGDL, valueWithUnit.value, profileFunction.getUnits())
bg = profileUtil.fromMgdlToStringInUnits(valueWithUnit.value * Constants.MMOLL_TO_MGDL)
ValueWithUnit.UNKNOWN -> Unit
}

View file

@ -0,0 +1,33 @@
package info.nightscout.implementation.utils
import info.nightscout.interfaces.R
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.shared.interfaces.ResourceHelper
import java.text.DecimalFormat
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class DecimalFormatterImpl @Inject constructor(
private val rh: ResourceHelper
) : DecimalFormatter {
private val format0dec = DecimalFormat("0")
private val format1dec = DecimalFormat("0.0")
private val format2dec = DecimalFormat("0.00")
private val format3dec = DecimalFormat("0.000")
override fun to0Decimal(value: Double): String = format0dec.format(value)
override fun to0Decimal(value: Double, unit: String): String = format0dec.format(value) + unit
override fun to1Decimal(value: Double): String = format1dec.format(value)
override fun to1Decimal(value: Double, unit: String): String = format1dec.format(value) + unit
override fun to2Decimal(value: Double): String = format2dec.format(value)
override fun to2Decimal(value: Double, unit: String): String = format2dec.format(value) + unit
override fun to3Decimal(value: Double): String = format3dec.format(value)
override fun to3Decimal(value: Double, unit: String): String = format3dec.format(value) + unit
override fun toPumpSupportedBolus(value: Double, bolusStep: Double): String = if (bolusStep <= 0.051) to2Decimal(value) else to1Decimal(value)
override fun toPumpSupportedBolusWithUnits(value: Double, bolusStep: Double): String =
if (bolusStep <= 0.051) rh.gs(R.string.format_insulin_units, value) else rh.gs(R.string.format_insulin_units1, value)
override fun pumpSupportedBolusFormat(bolusStep: Double): DecimalFormat = if (bolusStep <= 0.051) DecimalFormat("0.00") else DecimalFormat("0.0")
}

View file

@ -4,9 +4,21 @@
<string name="executing_right_now">Se execută comanda chiar acum</string>
<string name="basal_value_below_minimum">Valoarea bazalei este sub minimul permis. Profilul nu este setat!</string>
<string name="permission">Permisiune</string>
<string name="need_whitelisting">%1$s necesită excluderea din lista de optimizare a bateriei pentru o funcționare corespunzătoare</string>
<string name="need_location_permission">Aplicația are nevoie sa acceseze locația pentru scanare Bluetooth și identificare WiFi</string>
<string name="need_storage_permission">Aplicația are nevoie de permisiunea de a accesa unitatea de stocare pentru a scrie fișierele registru și pentru a exporta setările</string>
<!-- Stats -->
<string name="veryLow" comment="below 3.1">Foarte scăzută</string>
<string name="low" comment="3.1-3.9">Hipo</string>
<string name="high" comment="10.0-13.9">Hiper</string>
<string name="veryHigh" comment="above 13.9">Foarte mare</string>
<string name="below" comment="below &quot;in range&quot;">Sub</string>
<string name="in_range">În țintă</string>
<string name="above" comment="above &quot;in range&quot;">Mai sus</string>
<string name="hba1c">HbA1c: </string>
<string name="std_deviation">DST: %1$s</string>
<string name="detailed_14_days">Detaliere 14 zile</string>
<string name="day_tir">TIR ziua</string>
<string name="night_tir">TIR noapte</string>
<string name="carbs_short" comment="max 6 characters">Carbohidrați</string>
</resources>

View file

@ -7,9 +7,8 @@ import info.nightscout.interfaces.aps.AutosensDataStore
import info.nightscout.interfaces.iob.GlucoseStatus
import info.nightscout.interfaces.iob.InMemoryGlucoseValue
import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import info.nightscout.sharedtests.TestBase
import info.nightscout.sharedtests.TestBaseWithProfile
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
@ -19,9 +18,8 @@ import org.mockito.Mockito
/**
* Created by mike on 26.03.2018.
*/
class GlucoseStatusTest : TestBase() {
class GlucoseStatusTest : TestBaseWithProfile() {
@Mock lateinit var dateUtil: DateUtil
@Mock lateinit var iobCobCalculatorPlugin: IobCobCalculator
@Mock lateinit var autosensDataStore: AutosensDataStore
@ -32,7 +30,7 @@ class GlucoseStatusTest : TestBase() {
@Test fun toStringShouldBeOverloaded() {
val glucoseStatus = GlucoseStatus(glucose = 0.0, noise = 0.0, delta = 0.0, shortAvgDelta = 0.0, longAvgDelta = 0.0, date = 0)
Assertions.assertEquals(true, glucoseStatus.log().contains("Delta"))
Assertions.assertEquals(true, glucoseStatus.log(decimalFormatter).contains("Delta"))
}
@Test fun roundTest() {
@ -42,7 +40,7 @@ class GlucoseStatusTest : TestBase() {
@Test fun calculateValidGlucoseStatus() {
Mockito.`when`(autosensDataStore.getBucketedDataTableCopy()).thenReturn(generateValidBgData())
val glucoseStatus = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
val glucoseStatus = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil, decimalFormatter).glucoseStatusData!!
Assertions.assertEquals(214.0, glucoseStatus.glucose, 0.001)
Assertions.assertEquals(-2.0, glucoseStatus.delta, 0.001)
Assertions.assertEquals(-2.5, glucoseStatus.shortAvgDelta, 0.001) // -2 -2.5 -3 deltas are relative to current value
@ -73,7 +71,7 @@ class GlucoseStatusTest : TestBase() {
@Test fun oneRecordShouldProduceZeroDeltas() {
Mockito.`when`(autosensDataStore.getBucketedDataTableCopy()).thenReturn(generateOneCurrentRecordBgData())
val glucoseStatus: GlucoseStatus = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData!!
val glucoseStatus: GlucoseStatus = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil, decimalFormatter).glucoseStatusData!!
Assertions.assertEquals(214.0, glucoseStatus.glucose, 0.001)
Assertions.assertEquals(0.0, glucoseStatus.delta, 0.001)
Assertions.assertEquals(0.0, glucoseStatus.shortAvgDelta, 0.001) // -2 -2.5 -3 deltas are relative to current value
@ -83,19 +81,19 @@ class GlucoseStatusTest : TestBase() {
@Test fun insufficientDataShouldReturnNull() {
Mockito.`when`(autosensDataStore.getBucketedDataTableCopy()).thenReturn(generateInsufficientBgData())
val glucoseStatus: GlucoseStatus? = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData
val glucoseStatus: GlucoseStatus? = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil, decimalFormatter).glucoseStatusData
Assertions.assertEquals(null, glucoseStatus)
}
@Test fun oldDataShouldReturnNull() {
Mockito.`when`(autosensDataStore.getBucketedDataTableCopy()).thenReturn(generateOldBgData())
val glucoseStatus: GlucoseStatus? = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil).glucoseStatusData
val glucoseStatus: GlucoseStatus? = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil, decimalFormatter).glucoseStatusData
Assertions.assertEquals(null, glucoseStatus)
}
@Test fun returnOldDataIfAllowed() {
Mockito.`when`(autosensDataStore.getBucketedDataTableCopy()).thenReturn(generateOldBgData())
val glucoseStatus: GlucoseStatus? = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil).getGlucoseStatusData(true)
val glucoseStatus: GlucoseStatus? = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculatorPlugin, dateUtil, decimalFormatter).getGlucoseStatusData(true)
Assertions.assertNotEquals(null, glucoseStatus)
}

View file

@ -6,14 +6,9 @@ import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.aps.AutosensDataStore
import info.nightscout.interfaces.iob.InMemoryGlucoseValue
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.DefaultValueHelper
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import info.nightscout.sharedtests.TestBase
import info.nightscout.sharedtests.TestBaseWithProfile
import io.reactivex.rxjava3.core.Single
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
@ -21,14 +16,9 @@ import org.junit.jupiter.api.Test
import org.mockito.Mock
import org.mockito.Mockito
class OverviewDataImplTest : TestBase() {
class OverviewDataImplTest : TestBaseWithProfile() {
@Mock lateinit var rh: ResourceHelper
@Mock lateinit var dateUtil: DateUtil
@Mock lateinit var sp: SP
@Mock lateinit var activePlugin: ActivePlugin
@Mock lateinit var defaultValueHelper: DefaultValueHelper
@Mock lateinit var profileFunction: ProfileFunction
@Mock lateinit var repository: AppRepository
@Mock lateinit var autosensDataStore: AutosensDataStore
@ -40,7 +30,7 @@ class OverviewDataImplTest : TestBase() {
@BeforeEach
fun setup() {
sut = OverviewDataImpl(aapsLogger, rh, dateUtil, sp, activePlugin, defaultValueHelper, profileFunction, repository)
sut = OverviewDataImpl(aapsLogger, rh, dateUtil, sp, activePlugin, defaultValueHelper, profileFunction, repository, decimalFormatter)
Mockito.`when`(defaultValueHelper.determineLowLine()).thenReturn(80.0)
Mockito.`when`(defaultValueHelper.determineHighLine()).thenReturn(180.0)
Mockito.`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)

View file

@ -0,0 +1,47 @@
package info.nightscout.implementation.profile
import info.nightscout.database.entities.GlucoseValue
import info.nightscout.implementation.utils.DecimalFormatterImpl
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.sharedtests.TestBase
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.Mock
class ProfileUtilImplTest : TestBase() {
@Mock lateinit var rh: ResourceHelper
@Mock lateinit var sp: SP
private val glucoseValue =
GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = 1514766900000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT)
private lateinit var sut: ProfileUtilImpl
@BeforeEach
fun setup() {
val decimalFormatter = DecimalFormatterImpl(rh)
sut = ProfileUtilImpl(sp, decimalFormatter)
}
@Test
fun toUnitsString() {
Assertions.assertEquals("100", sut.fromMgdlToStringInUnits(glucoseValue.value, GlucoseUnit.MGDL))
Assertions.assertEquals("5.6", sut.fromMgdlToStringInUnits(glucoseValue.value, GlucoseUnit.MMOL))
Assertions.assertEquals(0.1, sut.convertToMgdl(0.1, GlucoseUnit.MGDL), 0.01)
Assertions.assertEquals(18.0, sut.convertToMgdl(1.0, GlucoseUnit.MMOL), 0.01)
Assertions.assertEquals(1.0, sut.convertToMmol(18.0, GlucoseUnit.MGDL), 0.01)
Assertions.assertEquals(18.0, sut.convertToMmol(18.0, GlucoseUnit.MMOL), 0.01)
Assertions.assertEquals(18.0, sut.fromMgdlToUnits(18.0, GlucoseUnit.MGDL), 0.01)
Assertions.assertEquals(1.0, sut.fromMgdlToUnits(18.0, GlucoseUnit.MMOL), 0.01)
Assertions.assertEquals(18.0, sut.fromMgdlToUnits(18.0, GlucoseUnit.MGDL), 0.01)
Assertions.assertEquals(1.0, sut.fromMgdlToUnits(18.0, GlucoseUnit.MMOL), 0.01)
Assertions.assertEquals("18", sut.fromMgdlToStringInUnits(18.0, GlucoseUnit.MGDL))
Assertions.assertEquals("1.0", sut.fromMgdlToStringInUnits(18.0, GlucoseUnit.MMOL).replace(",", "."))
Assertions.assertEquals("5 - 6", sut.toTargetRangeString(5.0, 6.0, GlucoseUnit.MGDL, GlucoseUnit.MGDL))
Assertions.assertEquals("4", sut.toTargetRangeString(4.0, 4.0, GlucoseUnit.MGDL, GlucoseUnit.MGDL))
}
}

View file

@ -28,6 +28,7 @@ import info.nightscout.interfaces.queue.Callback
import info.nightscout.interfaces.queue.Command
import info.nightscout.interfaces.queue.CustomCommand
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger
@ -73,11 +74,12 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
fabricPrivacy: FabricPrivacy,
androidPermission: AndroidPermission,
uiInteraction: UiInteraction,
persistenceLayer: PersistenceLayer
persistenceLayer: PersistenceLayer,
decimalFormatter: DecimalFormatter
) : CommandQueueImplementation(
injector, aapsLogger, rxBus, aapsSchedulers, rh, constraintChecker, profileFunction,
activePlugin, context, sp, config, dateUtil, repository, fabricPrivacy,
androidPermission, uiInteraction, persistenceLayer
androidPermission, uiInteraction, persistenceLayer, decimalFormatter
) {
override fun notifyAboutNewCommand(): Boolean = true
@ -120,7 +122,7 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
injector, aapsLogger, rxBus, aapsSchedulers, rh,
constraintChecker, profileFunction, activePlugin, context, sp,
config, dateUtil, repository,
fabricPrivacy, androidPermission, uiInteraction, persistenceLayer
fabricPrivacy, androidPermission, uiInteraction, persistenceLayer, decimalFormatter
)
testPumpPlugin = TestPumpPlugin(injector)
@ -157,7 +159,7 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
val commandQueue = CommandQueueImplementation(
injector, aapsLogger, rxBus, aapsSchedulers, rh,
constraintChecker, profileFunction, activePlugin, context, sp,
config, dateUtil, repository, fabricPrivacy, androidPermission, uiInteraction, persistenceLayer
config, dateUtil, repository, fabricPrivacy, androidPermission, uiInteraction, persistenceLayer, decimalFormatter
)
val handler = mock(Handler::class.java)
`when`(handler.post(anyObject())).thenAnswer { invocation: InvocationOnMock ->

View file

@ -55,7 +55,7 @@ class QueueThreadTest : TestBaseWithProfile() {
commandQueue = CommandQueueImplementation(
injector, aapsLogger, rxBus, aapsSchedulers, rh, constraintChecker,
profileFunction, activePlugin, context, sp,
config, dateUtil, repository, fabricPrivacy, androidPermission, uiInteraction, persistenceLayer
config, dateUtil, repository, fabricPrivacy, androidPermission, uiInteraction, persistenceLayer, decimalFormatter
)
val pumpDescription = PumpDescription()

View file

@ -0,0 +1,41 @@
package info.nightscout.implementation.utils
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.sharedtests.TestBase
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.Mock
class DecimalFormatterTest : TestBase() {
@Mock lateinit var rh: ResourceHelper
private lateinit var sut: DecimalFormatter
@BeforeEach
fun setup() {
sut = DecimalFormatterImpl(rh)
}
@Test fun to0DecimalTest() {
Assertions.assertEquals("1", sut.to0Decimal(1.33).replace(",", "."))
Assertions.assertEquals("1U", sut.to0Decimal(1.33, "U").replace(",", "."))
}
@Test fun to1DecimalTest() {
Assertions.assertEquals("1.3", sut.to1Decimal(1.33).replace(",", "."))
Assertions.assertEquals("1.3U", sut.to1Decimal(1.33, "U").replace(",", "."))
}
@Test fun to2DecimalTest() {
Assertions.assertEquals("1.33", sut.to2Decimal(1.3333).replace(",", "."))
Assertions.assertEquals("1.33U", sut.to2Decimal(1.3333, "U").replace(",", "."))
}
@Test fun to3DecimalTest() {
Assertions.assertEquals("1.333", sut.to3Decimal(1.3333).replace(",", "."))
Assertions.assertEquals("1.333U", sut.to3Decimal(1.3333, "U").replace(",", "."))
}
}

View file

@ -1,10 +1,10 @@
package info.nightscout.implementation.wizard
import com.google.common.truth.Truth.assertThat
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.core.wizard.BolusWizard
import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.aps.AutosensDataStore
import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.constraints.Constraint
@ -15,7 +15,6 @@ import info.nightscout.interfaces.pump.defs.PumpDescription
import info.nightscout.interfaces.queue.CommandQueue
import info.nightscout.rx.bus.RxBus
import info.nightscout.sharedtests.TestBaseWithProfile
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.mockito.Mock
import org.mockito.Mockito
@ -43,7 +42,8 @@ class BolusWizardTest : TestBaseWithProfile() {
it.loop = loop
it.dateUtil = dateUtil
it.iobCobCalculator = iobCobCalculator
it.glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger = aapsLogger, iobCobCalculator = iobCobCalculator, dateUtil = dateUtil)
it.glucoseStatusProvider = GlucoseStatusProviderImpl(aapsLogger, iobCobCalculator, dateUtil, decimalFormatter)
it.profileUtil = profileUtil
}
}
}
@ -56,7 +56,6 @@ class BolusWizardTest : TestBaseWithProfile() {
Mockito.`when`(profile.getIsfMgdl()).thenReturn(insulinSensitivityFactor)
Mockito.`when`(profile.getIc()).thenReturn(insulinToCarbRatio)
Mockito.`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
Mockito.`when`(iobCobCalculator.calculateIobFromBolus()).thenReturn(IobTotal(System.currentTimeMillis()))
Mockito.`when`(iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended()).thenReturn(IobTotal(System.currentTimeMillis()))
testPumpPlugin.pumpDescription = PumpDescription().also {
@ -114,7 +113,7 @@ class BolusWizardTest : TestBaseWithProfile() {
useAlarm = false
)
val bolusForBg54 = bw.calculatedTotalInsulin
Assertions.assertEquals(bolusForBg42, bolusForBg54, 0.01)
assertThat(bolusForBg54).isWithin( 0.01).of(bolusForBg42)
}
@Test
@ -160,7 +159,7 @@ class BolusWizardTest : TestBaseWithProfile() {
useAlarm = false
)
val bolusForBgInRange = bw.calculatedTotalInsulin
Assertions.assertTrue(bolusForHighBg > bolusForBgInRange)
assertThat(bolusForHighBg).isGreaterThan(bolusForBgInRange)
}
@Test
@ -206,6 +205,6 @@ class BolusWizardTest : TestBaseWithProfile() {
useAlarm = false
)
val bolusForBgInRange = bw.calculatedTotalInsulin
Assertions.assertTrue(bolusForLowBg < bolusForBgInRange)
assertThat(bolusForLowBg).isLessThan(bolusForBgInRange)
}
}

View file

@ -47,6 +47,7 @@ public class LocalInsightFragment extends DaggerFragment implements View.OnClick
@Inject FabricPrivacy fabricPrivacy;
@Inject DateUtil dateUtil;
@Inject AapsSchedulers aapsSchedulers;
@Inject DecimalFormatter decimalFormatter;
private final CompositeDisposable disposable = new CompositeDisposable();
@ -289,7 +290,7 @@ public class LocalInsightFragment extends DaggerFragment implements View.OnClick
if (cartridgeStatus == null) return;
String status;
if (cartridgeStatus.isInserted())
status = DecimalFormatter.INSTANCE.to2Decimal(cartridgeStatus.getRemainingAmount()) + "U";
status = decimalFormatter.to2Decimal(cartridgeStatus.getRemainingAmount()) + "U";
else status = rh.gs(R.string.not_inserted);
statusItems.add(getStatusItem(rh.gs(info.nightscout.core.ui.R.string.reservoir_label), status));
}
@ -297,16 +298,16 @@ public class LocalInsightFragment extends DaggerFragment implements View.OnClick
private void getTDDItems(List<View> statusItems) {
if (localInsightPlugin.getTotalDailyDose() == null) return;
TotalDailyDose tdd = localInsightPlugin.getTotalDailyDose();
statusItems.add(getStatusItem(rh.gs(R.string.tdd_bolus), DecimalFormatter.INSTANCE.to2Decimal(tdd.getBolus())));
statusItems.add(getStatusItem(rh.gs(R.string.tdd_basal), DecimalFormatter.INSTANCE.to2Decimal(tdd.getBasal())));
statusItems.add(getStatusItem(rh.gs(info.nightscout.core.ui.R.string.tdd_total), DecimalFormatter.INSTANCE.to2Decimal(tdd.getBolusAndBasal())));
statusItems.add(getStatusItem(rh.gs(R.string.tdd_bolus), decimalFormatter.to2Decimal(tdd.getBolus())));
statusItems.add(getStatusItem(rh.gs(R.string.tdd_basal), decimalFormatter.to2Decimal(tdd.getBasal())));
statusItems.add(getStatusItem(rh.gs(info.nightscout.core.ui.R.string.tdd_total), decimalFormatter.to2Decimal(tdd.getBolusAndBasal())));
}
private void getBaseBasalRateItem(List<View> statusItems) {
if (localInsightPlugin.getActiveBasalRate() == null) return;
ActiveBasalRate activeBasalRate = localInsightPlugin.getActiveBasalRate();
statusItems.add(getStatusItem(rh.gs(info.nightscout.core.ui.R.string.base_basal_rate_label),
DecimalFormatter.INSTANCE.to2Decimal(activeBasalRate.getActiveBasalRate()) + " U/h (" + activeBasalRate.getActiveBasalProfileName() + ")"));
decimalFormatter.to2Decimal(activeBasalRate.getActiveBasalRate()) + " U/h (" + activeBasalRate.getActiveBasalProfileName() + ")"));
}
private void getTBRItem(List<View> statusItems) {

View file

@ -19,14 +19,20 @@
<string name="tbr_formatter">%1$d%% για %2$d / %3$d λεπτά</string>
<string name="multiwave_bolus">Συνδυαστικό bolus</string>
<string name="eb_formatter">%1$.2f / %2$.2f U για %3$d λεπτά</string>
<string name="insight_last_bolus">Τελευταία Δόση Bolus</string>
<string name="searching_for_devices">Αναζήτηση συσκευών…</string>
<string name="pairing_completed">Σύζευξη ολοκληρώθηκε</string>
<string name="code_compare">Ταιριάζουν οι εμφανιζόμενοι κωδικοί με αυτούς της αντλίας;</string>
<string name="insight_pairing">Σύζευξη Insight</string>
<string name="insight_local">Accu-Chek Insight</string>
<string name="insight_alert_formatter">%1$s: %2$s</string>
<string name="tube_changed">Σωληνάκι αλλάχθηκε</string>
<string name="tube_changed">Σωληνάκι αλλάχτηκε</string>
<string name="insightpump_shortname">Sight</string>
<string name="insight_alert_notification_channel">Ειδοποιήσεις Αντλίας Insight</string>
<string name="disable_vibration">Απενεργοποίηση δονήσεων κατά τη χειροκίνητη δόση bolus</string>
<string name="disable_vibration_summary">Για Δόση bolus και εκτεταμένη Δόση bolus (διαθέσιμο μόνο με firmware 3.x)</string>
<string name="disable_vibration_auto">Απενεργοποίηση δονήσεων κατά την αυτόματη δόση bolus</string>
<string name="disable_vibration_auto_summary">Για SMB(SuperMicroBolus) και προσωρινό βασικό ρυθμό με προσομοίωση TBR (διατίθεται μόνο με firmware Insight 3.x)</string>
<string name="timeout_during_handshake">Τέλος χρόνου κατά τη διάρκεια handshake - επαναφορά bluetooth</string>
<string name="pump_stopped">Η αντλία σταμάτησε</string>
<string name="pump_started">Η αντλία ξεκίνησε</string>
@ -35,8 +41,9 @@
<string name="short_status_extended">Εκτεταμένο: %1$.2f / %2$.2f U για %3$d λεπτά</string>
<string name="short_status_multiwave">Συνδυαστικό: %1$.2f / %2$.2f U για %3$d λεπτά</string>
<string name="short_status_tdd">TDD: %1$.2f</string>
<string name="short_status_reservoir">Υπόλοιπο μονάδων:%1$.2fU</string>
<string name="short_status_battery">Μπατ.:%1$d%%</string>
<string name="release_software_version">Απελευθέρωση έκδοση λογισμικού</string>
<string name="release_software_version">Έκδοση λογισμικού</string>
<string name="ui_processor_software_version">Έκδοση λογισμικού επεξεργαστή UI</string>
<string name="pc_processor_software_version">Έκδοση λογισμικού επεξεργαστή PC</string>
<string name="md_tel_processor_software_version">Έκδοση λογισμικού επεξεργαστή MD tel</string>
@ -59,4 +66,5 @@
<string name="min_recovery_duration">Ελάχ. διάρκεια αποκατάστασης [s]</string>
<string name="pump_alert">Συναγερμός αντλίας</string>
<string name="pairing_information">Πληροφορίεςσύζευξης</string>
<string name="insight_refresh_button" comment="26 characters max for translation">Κουμπί Ανανέωσης Insight</string>
</resources>

View file

@ -41,6 +41,7 @@ open class APSResultObject @Inject constructor(val injector: HasAndroidInjector)
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var rh: ResourceHelper
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var decimalFormatter: DecimalFormatter
override var date: Long = 0
override var reason: String = ""
@ -67,7 +68,7 @@ open class APSResultObject @Inject constructor(val injector: HasAndroidInjector)
}
override val carbsRequiredText: String
get() = rh.gs(info.nightscout.core.ui.R.string.carbsreq, carbsReq, carbsReqWithin)
get() = rh.gs(R.string.carbsreq, carbsReq, carbsReqWithin)
override fun toString(): String {
val pump = activePlugin.activePump
@ -75,18 +76,18 @@ open class APSResultObject @Inject constructor(val injector: HasAndroidInjector)
// rate
var ret: String = if (rate == 0.0 && duration == 0) "${rh.gs(info.nightscout.core.ui.R.string.cancel_temp)} "
else if (rate == -1.0) "${rh.gs(info.nightscout.core.ui.R.string.let_temp_basal_run)}\n"
else if (usePercent) "${rh.gs(info.nightscout.core.ui.R.string.rate)}: ${DecimalFormatter.to2Decimal(percent.toDouble())}% (${DecimalFormatter.to2Decimal(percent * pump.baseBasalRate / 100.0)} U/h) " +
"${rh.gs(info.nightscout.core.ui.R.string.duration)}: ${DecimalFormatter.to2Decimal(duration.toDouble())} min "
else "${rh.gs(info.nightscout.core.ui.R.string.rate)}: ${DecimalFormatter.to2Decimal(rate)} U/h (${DecimalFormatter.to2Decimal(rate / pump.baseBasalRate * 100)}%) " +
"${rh.gs(info.nightscout.core.ui.R.string.duration)}: ${DecimalFormatter.to2Decimal(duration.toDouble())} min "
else if (usePercent) "${rh.gs(info.nightscout.core.ui.R.string.rate)}: ${decimalFormatter.to2Decimal(percent.toDouble())}% (${decimalFormatter.to2Decimal(percent * pump.baseBasalRate / 100.0)} U/h) " +
"${rh.gs(info.nightscout.core.ui.R.string.duration)}: ${decimalFormatter.to2Decimal(duration.toDouble())} min "
else "${rh.gs(info.nightscout.core.ui.R.string.rate)}: ${decimalFormatter.to2Decimal(rate)} U/h (${decimalFormatter.to2Decimal(rate / pump.baseBasalRate * 100)}%) " +
"${rh.gs(info.nightscout.core.ui.R.string.duration)}: ${decimalFormatter.to2Decimal(duration.toDouble())} min "
// smb
if (smb != 0.0) ret += "SMB: ${DecimalFormatter.toPumpSupportedBolus(smb, activePlugin.activePump, rh)} "
if (smb != 0.0) ret += "SMB: ${decimalFormatter.toPumpSupportedBolus(smb, activePlugin.activePump.pumpDescription.bolusStep)} "
if (isCarbsRequired) {
ret += "$carbsRequiredText "
}
// reason
ret += rh.gs(info.nightscout.core.ui.R.string.reason) + ": " + reason
ret += rh.gs(R.string.reason) + ": " + reason
return ret
}
return if (isCarbsRequired) {
@ -99,24 +100,26 @@ open class APSResultObject @Inject constructor(val injector: HasAndroidInjector)
if (isChangeRequested) {
// rate
var ret: String =
if (rate == 0.0 && duration == 0) rh.gs(info.nightscout.core.ui.R.string.cancel_temp) + "<br>" else if (rate == -1.0) rh.gs(info.nightscout.core.ui.R.string.let_temp_basal_run) + "<br>" else if (usePercent) "<b>" + rh.gs(info.nightscout.core.ui.R.string.rate) + "</b>: " + DecimalFormatter.to2Decimal(
if (rate == 0.0 && duration == 0) rh.gs(info.nightscout.core.ui.R.string.cancel_temp) + "<br>" else if (rate == -1.0) rh.gs(info.nightscout.core.ui.R.string.let_temp_basal_run) + "<br>" else if (usePercent) "<b>" + rh.gs(
info.nightscout.core.ui.R.string.rate
) + "</b>: " + decimalFormatter.to2Decimal(
percent.toDouble()
) + "% " +
"(" + DecimalFormatter.to2Decimal(percent * pump.baseBasalRate / 100.0) + " U/h)<br>" +
"<b>" + rh.gs(info.nightscout.core.ui.R.string.duration) + "</b>: " + DecimalFormatter.to2Decimal(duration.toDouble()) + " min<br>" else "<b>" + rh.gs(info.nightscout.core.ui.R.string.rate) + "</b>: " + DecimalFormatter.to2Decimal(
"(" + decimalFormatter.to2Decimal(percent * pump.baseBasalRate / 100.0) + " U/h)<br>" +
"<b>" + rh.gs(info.nightscout.core.ui.R.string.duration) + "</b>: " + decimalFormatter.to2Decimal(duration.toDouble()) + " min<br>" else "<b>" + rh.gs(info.nightscout.core.ui.R.string.rate) + "</b>: " + decimalFormatter.to2Decimal(
rate
) + " U/h " +
"(" + DecimalFormatter.to2Decimal(rate / pump.baseBasalRate * 100.0) + "%) <br>" +
"<b>" + rh.gs(info.nightscout.core.ui.R.string.duration) + "</b>: " + DecimalFormatter.to2Decimal(duration.toDouble()) + " min<br>"
"(" + decimalFormatter.to2Decimal(rate / pump.baseBasalRate * 100.0) + "%) <br>" +
"<b>" + rh.gs(info.nightscout.core.ui.R.string.duration) + "</b>: " + decimalFormatter.to2Decimal(duration.toDouble()) + " min<br>"
// smb
if (smb != 0.0) ret += "<b>" + "SMB" + "</b>: " + DecimalFormatter.toPumpSupportedBolus(smb, activePlugin.activePump, rh) + "<br>"
if (smb != 0.0) ret += "<b>" + "SMB" + "</b>: " + decimalFormatter.toPumpSupportedBolus(smb, activePlugin.activePump.pumpDescription.bolusStep) + "<br>"
if (isCarbsRequired) {
ret += "$carbsRequiredText<br>"
}
// reason
ret += "<b>" + rh.gs(info.nightscout.core.ui.R.string.reason) + "</b>: " + reason.replace("<", "&lt;").replace(">", "&gt;")
ret += "<b>" + rh.gs(R.string.reason) + "</b>: " + reason.replace("<", "&lt;").replace(">", "&gt;")
return HtmlHelper.fromHtml(ret)
}
return if (isCarbsRequired) {

View file

@ -17,6 +17,7 @@ import info.nightscout.core.pump.toHtml
import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.constraints.Constraint
import info.nightscout.interfaces.utils.DecimalFormatter
import info.nightscout.interfaces.utils.HtmlHelper
import info.nightscout.plugins.aps.R
import info.nightscout.plugins.aps.databinding.LoopFragmentBinding
@ -42,6 +43,7 @@ class LoopFragment : DaggerFragment(), MenuProvider {
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var loop: Loop
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var decimalFormatter: DecimalFormatter
@Suppress("PrivatePropertyName")
private val ID_MENU_RUN = 501
@ -64,7 +66,11 @@ class LoopFragment : DaggerFragment(), MenuProvider {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.swipeRefresh.setColorSchemeColors(rh.gac(context, android.R.attr.colorPrimaryDark), rh.gac(context, android.R.attr.colorPrimary), rh.gac(context,com.google.android.material.R.attr.colorSecondary))
binding.swipeRefresh.setColorSchemeColors(
rh.gac(context, android.R.attr.colorPrimaryDark),
rh.gac(context, android.R.attr.colorPrimary),
rh.gac(context, com.google.android.material.R.attr.colorSecondary)
)
binding.swipeRefresh.setOnRefreshListener {
binding.lastrun.text = rh.gs(R.string.executing)
handler.post {
@ -137,9 +143,9 @@ class LoopFragment : DaggerFragment(), MenuProvider {
binding.tbrrequestTime.text = dateUtil.dateAndTimeAndSecondsString(it.lastTBRRequest)
binding.tbrexecutionTime.text = dateUtil.dateAndTimeAndSecondsString(it.lastTBREnact)
binding.tbrsetbypump.text = it.tbrSetByPump?.let { tbrSetByPump -> HtmlHelper.fromHtml(tbrSetByPump.toHtml(rh)) }
binding.tbrsetbypump.text = it.tbrSetByPump?.let { tbrSetByPump -> HtmlHelper.fromHtml(tbrSetByPump.toHtml(rh, decimalFormatter)) }
?: ""
binding.smbsetbypump.text = it.smbSetByPump?.let { smbSetByPump -> HtmlHelper.fromHtml(smbSetByPump.toHtml(rh)) }
binding.smbsetbypump.text = it.smbSetByPump?.let { smbSetByPump -> HtmlHelper.fromHtml(smbSetByPump.toHtml(rh, decimalFormatter)) }
?: ""
var constraints =

View file

@ -22,6 +22,7 @@ import info.nightscout.plugins.aps.utils.ScriptReader
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.SafeParse
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.sharedPreferences.SP
import org.json.JSONArray
import org.json.JSONException
@ -48,6 +49,7 @@ class DetermineBasalAdapterSMBDynamicISFJS internal constructor(private val scri
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var iobCobCalculator: IobCobCalculator
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var profileUtil: ProfileUtil
private var profile = JSONObject()
private var mGlucoseStatus = JSONObject()
@ -202,7 +204,7 @@ class DetermineBasalAdapterSMBDynamicISFJS internal constructor(private val scri
this.profile.put("sens", profile.getIsfMgdl())
this.profile.put("max_daily_safety_multiplier", sp.getInt(R.string.key_openapsama_max_daily_safety_multiplier, 3))
this.profile.put("current_basal_safety_multiplier", sp.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4.0))
this.profile.put("lgsThreshold", Profile.toMgdl(sp.getDouble(R.string.key_lgs_threshold, 65.0)))
this.profile.put("lgsThreshold", profileUtil.convertToMgdlDetect(sp.getDouble(R.string.key_lgs_threshold, 65.0)))
//mProfile.put("high_temptarget_raises_sensitivity", SP.getBoolean(R.string.key_high_temptarget_raises_sensitivity, SMBDefaults.high_temptarget_raises_sensitivity));
this.profile.put("high_temptarget_raises_sensitivity", sp.getBoolean(info.nightscout.core.utils.R.string.key_high_temptarget_raises_sensitivity, SMBDefaults.high_temptarget_raises_sensitivity))

View file

@ -30,7 +30,6 @@ import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.Instantiator
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.profile.ProfileStore
import info.nightscout.interfaces.ui.UiInteraction
@ -47,6 +46,7 @@ import info.nightscout.rx.events.EventLocalProfileChanged
import info.nightscout.shared.SafeParse
import info.nightscout.shared.extensions.runOnUiThread
import info.nightscout.shared.extensions.toVisibility
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
@ -59,6 +59,7 @@ import javax.inject.Inject
class AutotuneFragment : DaggerFragment() {
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var profileUtil: ProfileUtil
@Inject lateinit var autotunePlugin: AutotunePlugin
@Inject lateinit var autotuneFS: AutotuneFS
@Inject lateinit var sp: SP
@ -389,7 +390,7 @@ class AutotuneFragment : DaggerFragment() {
nl = "\n"
}
if (profile.isfSize > 1) {
warning += nl + rh.gs(info.nightscout.core.ui.R.string.autotune_isf_warning, profile.isfSize, Profile.fromMgdlToUnits(profile.isf, profileFunction.getUnits()), profileFunction.getUnits().asText)
warning += nl + rh.gs(info.nightscout.core.ui.R.string.autotune_isf_warning, profile.isfSize, profileUtil.fromMgdlToUnits(profile.isf), profileFunction.getUnits().asText)
}
}
}

View file

@ -12,7 +12,6 @@ import info.nightscout.interfaces.insulin.Insulin
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.Instantiator
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.profile.ProfileStore
import info.nightscout.interfaces.profile.PureProfile
import info.nightscout.interfaces.utils.Round
@ -20,6 +19,7 @@ import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.SafeParse
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
@ -36,7 +36,7 @@ class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector:
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var sp: SP
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var profileUtil: ProfileUtil
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var config: Config
@Inject lateinit var rxBus: RxBus
@ -81,7 +81,7 @@ class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector:
fun isf(circadian: Boolean = false): JSONArray {
if (circadian)
return jsonArray(pumpProfile.isfBlocks, avgISF / pumpProfileAvgISF)
return jsonArray(Profile.fromMgdlToUnits(isf, profile.units))
return jsonArray(profileUtil.fromMgdlToUnits(isf, profile.units))
}
fun getProfile(circadian: Boolean = false): PureProfile {
@ -162,7 +162,7 @@ class ATProfile(profile: Profile, var localInsulin: LocalInsulin, val injector:
json.put("sens", jsonArray(pumpProfile.isfBlocks, avgISF / pumpProfileAvgISF))
json.put("carbratio", jsonArray(pumpProfile.icBlocks, avgIC / pumpProfileAvgIC))
} else {
json.put("sens", jsonArray(Profile.fromMgdlToUnits(isf, profile.units)))
json.put("sens", jsonArray(profileUtil.fromMgdlToUnits(isf, profile.units)))
json.put("carbratio", jsonArray(ic))
}
json.put("basal", jsonArray(basal))

View file

@ -1,10 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="dynisf_adjust_sensitivity">Ρύθμιση ευαισθησίας και γλυκόζης αίματος</string>
<string name="DynISFAdjust_title" formatted="false">DynamicISF Συντελεστής Προσαρμογής %</string>
<string name="DynISFAdjust_summary" formatted="false">Συντελεστής Προσαρμογής για το DynamicISF. Ρυθμίστε περισσότερο από 100% για πιο επιθετικές διορθωτικές δόσεις και λιγότερο από 100% για λιγότερο επιθετικές διορθώσεις.</string>
<string name="high_temptarget_raises_sensitivity_title">Ο υψηλός προσωρινός στόχος ανεβάζει την ευαισθησία</string>
<string name="high_temptarget_raises_sensitivity_summary"><![CDATA[Αύξηση ευαισθησίας για προσωρινό στόχο > = 100]]></string>
<string name="low_temptarget_lowers_sensitivity_title">Ο χαμηλός προσωρινός στόχος μειώνει την ευαισθησία</string>
<string name="low_temptarget_lowers_sensitivity_summary"><![CDATA[Χαμηλότερη ευαισθησία για προσωρινό στόχο < 100]]></string>
<string name="openapssmb">OpenAPS SMB</string>
<string name="openaps_smb_dynamic_isf">Δυναμική ISF</string>
<string name="smb_interval_summary">Πόσο συχνά τα SMBs θα χορηγούνται σε λεπτά</string>
<string name="resistance_lowers_target_title">Η αντίσταση στην ινσουλίνη μειώνει τον στόχο</string>
<string name="resistance_lowers_target_summary">Όταν ανιχνευθεί αντίσταση, μειώστε το στόχο γλυκόζης</string>
<string name="sensitivity_raises_target_title">Η ευαισθησία αυξάνει τον στόχο</string>
<string name="sensitivity_raises_target_summary">Όταν ανιχνευθεί ευαισθησία, αυξήστε το στόχο γλυκόζης</string>
<string name="openapsma_disabled">Προσθήκη απενεργοποιημένη</string>
<string name="openapsma_no_glucose_data">Μη διαθέσιμα δεδομένα γλυκόζης</string>
<string name="openaps_no_as_data">Μη διαθέσιμα δεδομένα autosens</string>
@ -60,7 +69,14 @@
<string name="enable_smb_with_temp_target">Ενεργοποίηση SMB με προσωρινούς στόχους</string>
<string name="enable_smb_with_temp_target_summary">Ενεργοποίηση του SMB όταν υπάρχει ενεργός προσωρινός στόχος (τρώω σύντομα, άσκηση)</string>
<string name="enable_smb_with_high_temp_target">Ενεργοποίηση SMB με υψηλούς προσωρινούς στόχους</string>
<string name="enable_smb_with_high_temp_target_summary">Ενεργοποίηση SMB όταν υπάρχει ενεργός υψηλός προσωρινός στόχος (άσκηση, πάνω από 100 mg/dl ή 5.5 mmol/l)</string>
<string name="smb_max_minutes_summary">Τα μέγιστα λεπτά του βασικού ρυθμού που περιορίζουν το SMB να</string>
<string name="uam_smb_max_minutes">Μέγιστη διάρκεια UAM SMB (λεπτά)</string>
<string name="uam_smb_max_minutes_summary">Μέγιστα λεπτά βασικού ρυθμού που περιορίζουν το SMB για UAM</string>
<string name="carbs_req_threshold">Ελάχιστοι Υδατάνθρακες που Απαιτούνται Για Πρόταση</string>
<string name="carbs_req_threshold_summary">Ελάχιστα γραμμάρια υδατανθράκων για την εμφάνιση μιας ειδοποίησης πρότασης υδατανθράκων. Δε θα εμφανιστούν ειδοποιήσεις για προτάσεις υδατανθράκων κάτω από αυτόν τον αριθμό.</string>
<string name="lgs_threshold_summary">Η τιμή BG κάτω από την οποία αναστέλλεται η ινσουλίνη. Η προεπιλεγμένη τιμή χρησιμοποιεί τυποποιημένο μοντέλο στόχου. Ο χρήστης μπορεί να ορίσει τιμή μεταξύ 60mg/dl (3. mmol/l) και 100mg/dl (5.5mmol/l). Τιμές κάτω των 65/3.6 έχουν ως αποτέλεσμα τη χρήση προκαθορισμένου μοντέλου</string>
<string name="lgs_threshold_title">Η τιμή BG κάτω από την οποία γίνεται αναστολή λόγω χαμηλής γλυκόζης</string>
<string name="increasing_max_basal">Αυξείστε την μέγιστη βασική τιμή, επειδή η ρύθμιση είναι χαμηλότερη από τη μέγιστη βασική στο προφίλ σας</string>
<string name="max_basal_multiplier">πολλαπλασιαστής μέγιστου βασικού</string>
<string name="max_daily_basal_multiplier">πολλαπλασιαστής ημερήσιου μέγιστου βασικού</string>
@ -72,10 +88,30 @@
<string name="maxvalueinpreferences">μέγιστη τιμή στις Επιλογές</string>
<string name="hardlimit">σταθερό όριο</string>
<!-- Autotune -->
<string name="insulin_peak">Κορυφή</string>
<!-- Loop -->
<string name="run_now">Εκτέλεση τώρα</string>
<string name="smb_frequency_exceeded">Ένα bolus παραδόθηκε μέσα στα τελευταία 3 λεπτά, παράκαμψη SMB</string>
<string name="pump_not_initialized">Η αντλία δεν αρχικοποιήθηκε!</string>
<string name="loop_shortname">ΚΥΚΛΩΜΑ</string>
<string name="description_loop">Ενεργοποιήστε ή απενεργοποιήστε την εφαρμογή που ενεργοποιεί το κύκλωμα.</string>
<string name="no_aps_selected">ΔΕΝ ΕΠΙΛΕΧΘΗΚΕ APS Ή ΔΕΝ ΕΓΙΝΕ ΠΑΡΟΧΗ ΑΠΟΤΕΛΕΣΜΑΤΟΣ</string>
<string name="ignore5m">Παράβλεψη για 5 λεπτά</string>
<string name="ignore15m">Παράβλεψη για 15 λεπτά</string>
<string name="ignore30m">Παράβλεψη για 30 λεπτά</string>
<string name="carbs_suggestion">Προτεινόμενοι Υδατάνθρακες</string>
<string name="open_loop_new_suggestion">Νέα διαθέσιμη πρόταση</string>
<string name="basal_set_correctly">Ο βασικός ρυθμός ορίστηκε σωστά</string>
<string name="last_run_label">Τελευταία εκτέλεση</string>
<string name="loop_aps_label">APS</string>
<string name="request_label">Αίτημα</string>
<string name="loop_constraints_processed_label">Μετά από επεξεργασμένους περιορισμούς</string>
<string name="loop_tbr_request_time_label">Χρόνος αιτήματος προσωρινού βασικού</string>
<string name="loop_tbr_execution_time_label">Χρόνος εκτέλεσης προσωρινού βασικού</string>
<string name="loop_tbr_set_by_pump_label">Προσωρινός ρυθμός καθορισμένος από την αντλία</string>
<string name="loop_smb_request_time_label">Χρόνος αιτήματος SMB</string>
<string name="loop_smb_execution_time_label">Χρόνος εκτέλεσης SMB</string>
<string name="loop_smb_set_by_pump_label">SMB καθορισμένο από την αντλία</string>
<string name="loop_open_mode_min_change">Ελάχιστο αίτημα για αλλαγή [%]</string>
<string name="loop_open_mode_min_change_summary" formatted="false">Το Ανοιχτό κύκλωμα θα εμφανίσει νέο μήνυμα αλλαγής μόνο αν η αλλαγή είναι μεγαλύτερη από αυτήν την τιμή σε %. Προεπιλεγμένη τιμή 20%</string>
</resources>

View file

@ -9,7 +9,7 @@
<string name="low_temptarget_lowers_sensitivity_summary"><![CDATA[Baixar sensibilidade para alvostemp < 100]]></string>
<string name="openapssmb">SMB OpenAPS</string>
<string name="openaps_smb_dynamic_isf">FSI Dinâmico</string>
<string name="smb_interval_summary">Com que frequência em min os SMBs serão dados</string>
<string name="smb_interval_summary">Com que frequência em minutos os SMBs serão aplicados</string>
<string name="resistance_lowers_target_title">Resistência reduz alvo</string>
<string name="resistance_lowers_target_summary">Quando a resistência for detectada, diminui o alvo de glicose</string>
<string name="sensitivity_raises_target_title">Sensibilidade aumenta o alvo</string>
@ -39,42 +39,42 @@
<string name="openapsma_autosensdata_label">Dados Autosens</string>
<string name="openapsma_script_debug_data_label">Script debug</string>
<string name="openapsama_use_autosens">Usar função Autosens</string>
<string name="openapsma_max_basal_title">Max U/h em que uma Basal temporária pode ser definida</string>
<string name="openapsma_max_basal_summary">Este valor é chamado max basal no contexto do OpenAPS</string>
<string name="openapsma_max_basal_title">Máximo em U/h em que uma basal temporária pode ser definida</string>
<string name="openapsma_max_basal_summary">O valor definido será o máximo de unidades de basal por hora que o aaps poderá chegar</string>
<string name="openapsma_max_iob_title">Basal Máxima IOB que OpenAPS pode dar [U]</string>
<string name="openapsma_max_iob_summary">Este valor é denominado Max IOB em contexto OpenAPS \nEste é o valor máximo de insulina em [U] que APS pode dar de uma vez.</string>
<string name="openapsma_max_iob_summary">Este valor é chamado Max IOB em contexto OpenAPS \nEste é o valor máximo de insulina em [U] que aaps pode deixar ativo de uma vez.</string>
<string name="openapsama_autosens_adjust_targets_summary">Valor padrão: true\nÉ usado para permitir que autosens possa ajustar os valores alvo de glucose no sangue (BG), além de ISF e basais.</string>
<string name="openapsama_autosens_adjust_targets">Autosens também ajusta os alvos</string>
<string name="openapsama_min_5m_carb_impact_summary">Valor padrão: 3.0 para assitência avançada de refeições (AAR) ou 8.0 para super micro bolus (SMB). Esta é a configuração padrão para o calculo de quanto varia a cada 5 min a glicemia (BG) devido à absorção de carboidratos. O padrão é 3mg/dl/5min. Isso afeta a rapidez com que decaem os carboidratos ativos (CA) e quanta absorção de carboidrato será considerada no cálculo da previsão de glicemia futura, tornando possível notar que glicemia está baixando mais do que o esperado ou não subindo como esperado.</string>
<string name="openapsama_max_daily_safety_multiplier_summary">Valor padrão: 3 Por segurança é o valor limite estabelecido por OpenAPS. O que faz é limitar a basal a x3 a basal mázima. Se necessário modificar este valor, por favor ter em conta que os dados apontam para que os limites de segurança sejam - 3 x max diario ou 4x valor atual (qual seja menor) como valores máximos.</string>
<string name="openapsama_current_basal_safety_multiplier_summary">Valor padrão: 4 Esta é a outra parte dos valores limites de segurança - 3 x max diário ou 4x valor actual - do OpenAPS. Isto define que não importa o valor da basal máxima definido na bomba, o valor máximo da basal temporária não pode ser maior que 4 x o valor da basal definida na bomba. O objetivo é evitar que sejam determinadas basais temporárias muito elevadas antes que se perceba como o algoritmo funciona. 4x é um valor que a maior parte das pessoas nunca necessitará de alterar pois o mais provável é necessitar de alterar outras definições para não necessitar de \"ultrapassar\" este limite de segurança.</string>
<string name="openapsama_min_5m_carb_impact_summary">Valor padrão: 3.0 para assitência avançada de refeições (AAR) ou 8.0 para super micro bolus (SMB). Esta é uma configuração para o impacto de absorção de carboidratos por 5 minutos. O padrão é uma expectativa de 3 mg/dl/5min. Isso afeta a velocidade com que os CA são decaídos e a quantidade de absorção de carboidratos assumida ao calcular a glicemia futura prevista, quando a glicemia está caindo mais do que o esperado ou não está subindo tanto quanto o esperado.</string>
<string name="openapsama_max_daily_safety_multiplier_summary">Valor padrão: 3 Esta é uma chave de segurança OpenAPS. O que isso faz é limitar seus basais para serem 3x (neste caso) sua maior taxa basal. Provavelmente você não precisará alterar isso, mas você deve estar ciente de que é o que se discute sobre \"3x máximo diário; 4x atual\" para chaves de segurança.</string>
<string name="openapsama_current_basal_safety_multiplier_summary">Valor padrão: 4 Esta é a outra metade da chave OpenAPS de segurança, e a outra metade de \"3x diário máximo; 4x atual\" das tampas de segurança. Isso significa que o seu basal, independentemente do nível máximo de basal definido na bomba, não pode ser maior do que este número vezes o nível atual do seu basal. Isso é para evitar que as pessoas entrem em território perigoso, definindo basais excessivamente altos antes de entender como funciona o algoritmo. Novamente, o padrão é 4x; a maioria das pessoas nunca precisará ajustar isso e, em vez disso, precisará ajustar outras configurações se sentirem que estão \"batendo\" nessa tampa de segurança.</string>
<string name="openapsama_bolus_snooze_dia_divisor_summary">Valor padrão: 2\nBolus Snooze (pausa após bolus) é executado depois de realizar um bolus por refeição Desta maneira o algoritmo não irá contrariar com temporárias baixas logo depois da refeição. O valor padrão é 2; Então uma duração de ação da insulina (DIA) de 5h significa que o Bolus Snooze irá ser gradualmente reduzido ao longo de 2,5 horas = 5/2 = DIA/Valor padrão.</string>
<string name="openapsama_link_to_preference_json_doc_txt">Atenção!\n Normalmente não é necessário modificar os valores abaixo. Por favor PRESSIONE AQUI e LEIA o texto para garantir que ENTENDE as consequências antes de alterar qualquer um destes valores.</string>
<string name="always_use_short_avg">Usar sempre delta médio curto em vez de delta simples</string>
<string name="always_use_short_avg_summary">Útil quando há ruído nos dados das fontes sem filtro como o xDrip.</string>
<string name="openapsama_max_daily_safety_multiplier">Multiplicador máx. diário de segurança</string>
<string name="openapsama_current_basal_safety_multiplier">Multiplicador actual de segurança basal</string>
<string name="openapssmb_max_iob_title">Máximo total de IOB OpenAPS não pode superar [U]</string>
<string name="openapssmb_max_iob_title">Máximo total de insulina ativa no OpenAPS não pode superar [U]</string>
<string name="openapssmb_max_iob_summary">Este valor é chamado de Max IOB em contexto de OpenAPS\nOpenAPS não adicionará mais insulina se o IOB atual for maior que este valor</string>
<string name="enable_uam">Ativar UAM</string>
<string name="enable_uam">Ativar refeição não anunciada</string>
<string name="enable_smb">Ativar SMB</string>
<string name="enable_smb_summary">Use Super Micro Boluses em vez de basal temp para uma ação mais rápida</string>
<string name="enable_uam_summary">Detecção de refeições não Introduzidas</string>
<string name="enable_smb_always">SMB sempre activado</string>
<string name="enable_smb_summary">Usar Super Micro Bolus (SMB) em vez de basal temporária para resposta mais rápida</string>
<string name="enable_uam_summary">Detecção de refeições não anunciadas</string>
<string name="enable_smb_always">SMB sempre ativo</string>
<string name="enable_smb_always_summary">SMB sempre activo independentemente dos bolus. Possível apenas quando o medidor tive um bom filtro de dados como o G5</string>
<string name="enable_smb_after_carbs">Ativar SMB após carbos</string>
<string name="enable_smb_after_carbs">Ativar SMB após refeição</string>
<string name="enable_smb_after_carbs_summary">SMB activo por 6h após carbs, mesmo com 0 COB. Possível apenas quando o medidor tive um bom filtro de dados como o G5</string>
<string name="enable_smb_with_cob">Ativar SMB com COB</string>
<string name="enable_smb_with_cob_summary">Ativar SMB quando houver COB ativo.</string>
<string name="enable_smb_with_cob_summary">Ativar SMB quando houver carboidratos ativos.</string>
<string name="enable_smb_with_temp_target">SMB activo com valores alvo temporários</string>
<string name="enable_smb_with_temp_target_summary">SMB activo quando há valor alvo temporário activo (exercício, etc)</string>
<string name="enable_smb_with_high_temp_target">SMB activo com alvos temporários elevados</string>
<string name="enable_smb_with_high_temp_target_summary">Ativar SMB quando tiver um alvo temporário alto ativo (exercício, acima de 100 mg/dl ou 5,5 mmol/l)</string>
<string name="smb_max_minutes_summary">Limite de minutos de basal para SMB</string>
<string name="uam_smb_max_minutes">UAM SMB máx minutos</string>
<string name="uam_smb_max_minutes_summary">Max minutos de basal para limitar SMB para UAM</string>
<string name="carbs_req_threshold">Limite mínimo de carboidratos necessários para sugerir</string>
<string name="carbs_req_threshold_summary">Mínimo de gramas de carboidratos requeridos para exibir uma alerta de sugestão de carboidratos. Sugestões de carboidratos abaixo deste número não ativarão uma notificação.</string>
<string name="uam_smb_max_minutes_summary">Máximo de minutos de basal para usar o SMB em RNA</string>
<string name="carbs_req_threshold">Qual o mínimo de carboidratos necessários para correção para gerar um alerta</string>
<string name="carbs_req_threshold_summary">Gramas mínimas de carboidratos para exibir um alerta de sugestão de carboidratos. Sugestões de carboidratos abaixo deste número não acionarão uma notificação.</string>
<string name="lgs_threshold_summary">Valor a partir do qual a insulina é suspensa. O valor padrão usa como base o alvo padrão. O usuário pode definir o valor entre 60mg/dl (3.3mmol/l) e 100mg/dl(5.5 mmol/l). Valores abaixo de 65/3.6 resulta em uso do modelo padrão.</string>
<string name="lgs_threshold_title">Nível de glicose (BG) está abaixo do ponto em que ocorre a suspensão causada por hipoglicemia.</string>
<string name="increasing_max_basal">Aumentar o valor máximo de basal porque a configuração é inferior à sua basal máxima no perfil</string>

View file

@ -3,13 +3,13 @@
<string name="dynisf_adjust_sensitivity">Настроить чувствительность относительно ГК</string>
<string name="DynISFAdjust_title" formatted="false">Коэффициент регулировки динамического диапазона чувствительности ISF %</string>
<string name="DynISFAdjust_summary" formatted="false">Коэффициент корректировки динамического диапазона чувствительности ISF. Установите более 100% для агрессивных доз коррекции и менее 100% для менее агрессивной коррекции.</string>
<string name="high_temptarget_raises_sensitivity_title">Высокая врем. цель temptarget повышает чувствительность</string>
<string name="high_temptarget_raises_sensitivity_title">Высокая ВЦ повышает чувствительность</string>
<string name="high_temptarget_raises_sensitivity_summary"><![CDATA[Повысить чувствительность для temptargets > = 100]]></string>
<string name="low_temptarget_lowers_sensitivity_title">Низкая временная цель temptarget снижает чувствительность</string>
<string name="low_temptarget_lowers_sensitivity_title">Низкая ВЦ снижает чувствительность</string>
<string name="low_temptarget_lowers_sensitivity_summary"><![CDATA[Понизить чувствительность для temptargets > = 100]]></string>
<string name="openapssmb">Супер микро болюс OpenAPS</string>
<string name="openapssmb">OpenAPS СМБ</string>
<string name="openaps_smb_dynamic_isf">Динамический ISF</string>
<string name="smb_interval_summary">Как часто SMB будут подаваться в минутах</string>
<string name="smb_interval_summary">Как часто СМБ будут подаваться в минутах</string>
<string name="resistance_lowers_target_title">Сопротивляемость понижает цель</string>
<string name="resistance_lowers_target_summary">При обнаружении сопротивляемости целевой уровень гликемии понижается</string>
<string name="sensitivity_raises_target_title">Чувствительность поднимает цель</string>

View file

@ -6,6 +6,7 @@ import info.nightscout.database.entities.data.TargetBlock
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.PureProfile
import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.plugins.general.autotune.data.ATProfile
import info.nightscout.plugins.general.autotune.data.PreppedGlucose
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
@ -85,7 +86,7 @@ class AutotuneCoreTest : TestBaseWithProfile() {
* OpenAPS profile for Autotune only have one ISF value and one IC value
*/
@Suppress("SpellCheckingInspection")
private fun atProfileFromOapsJson(jsonObject: JSONObject, dateUtil: DateUtil, defaultUnits: String? = null): info.nightscout.plugins.general.autotune.data.ATProfile? {
private fun atProfileFromOapsJson(jsonObject: JSONObject, dateUtil: DateUtil, defaultUnits: String? = null): ATProfile? {
try {
min5mCarbImpact = JsonHelper.safeGetDoubleAllowNull(jsonObject, "min_5m_carbimpact") ?: return null
autotuneMin = JsonHelper.safeGetDoubleAllowNull(jsonObject, "autosens_min") ?: return null
@ -122,7 +123,7 @@ class AutotuneCoreTest : TestBaseWithProfile() {
timeZone = timezone,
dia = dia
)
return info.nightscout.plugins.general.autotune.data.ATProfile(ProfileSealed.Pure(pure), localInsulin, profileInjector).also { it.dateUtil = dateUtil }
return ATProfile(ProfileSealed.Pure(pure), localInsulin, profileInjector).also { it.dateUtil = dateUtil; it.profileUtil = profileUtil }
} catch (ignored: Exception) {
return null
}

View file

@ -21,13 +21,13 @@ import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.logging.UserEntryLogger
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.pump.PumpEnactResult
import info.nightscout.interfaces.queue.Callback
import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.interfaces.utils.JsonHelper.safeGetDouble
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.utils.DateUtil
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.kotlin.plusAssign
@ -42,6 +42,7 @@ class ActionStartTempTarget(injector: HasAndroidInjector) : Action(injector) {
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var uel: UserEntryLogger
@Inject lateinit var profileUtil: ProfileUtil
private val disposable = CompositeDisposable()
@ -53,7 +54,7 @@ class ActionStartTempTarget(injector: HasAndroidInjector) : Action(injector) {
}
override fun friendlyName(): Int = R.string.starttemptarget
override fun shortDescription(): String = rh.gs(R.string.starttemptarget) + ": " + tt().friendlyDescription(value.units, rh)
override fun shortDescription(): String = rh.gs(R.string.starttemptarget) + ": " + tt().friendlyDescription(value.units, rh, profileUtil)
@DrawableRes override fun icon(): Int = info.nightscout.core.main.R.drawable.ic_temptarget_high
override fun doAction(callback: Callback) {
@ -110,8 +111,8 @@ class ActionStartTempTarget(injector: HasAndroidInjector) : Action(injector) {
timestamp = dateUtil.now(),
duration = TimeUnit.MINUTES.toMillis(duration.getMinutes().toLong()),
reason = TemporaryTarget.Reason.AUTOMATION,
lowTarget = Profile.toMgdl(value.value, value.units),
highTarget = Profile.toMgdl(value.value, value.units)
lowTarget = profileUtil.convertToMgdl(value.value, value.units),
highTarget = profileUtil.convertToMgdl(value.value, value.units)
)
override fun isValid(): Boolean =

View file

@ -23,6 +23,7 @@ import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ProfileUtil
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
@ -35,6 +36,7 @@ abstract class Trigger(val injector: HasAndroidInjector) {
@Inject lateinit var rxBus: RxBus
@Inject lateinit var rh: ResourceHelper
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var profileUtil: ProfileUtil
@Inject lateinit var sp: SP
@Inject lateinit var locationDataContainer: LastLocationDataContainer
@Inject lateinit var repository: AppRepository

View file

@ -11,7 +11,6 @@ import info.nightscout.automation.elements.LayoutBuilder
import info.nightscout.automation.elements.StaticLabel
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.rx.logging.LTag
import org.json.JSONObject
@ -56,7 +55,7 @@ class TriggerBg(injector: HasAndroidInjector) : Trigger(injector) {
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
return false
}
if (comparator.value.check(glucoseStatus.glucose, Profile.toMgdl(bg.value, bg.units))) {
if (comparator.value.check(glucoseStatus.glucose, profileUtil.convertToMgdl(bg.value, bg.units))) {
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
return true
}

View file

@ -12,7 +12,6 @@ import info.nightscout.automation.elements.LayoutBuilder
import info.nightscout.automation.elements.StaticLabel
import info.nightscout.interfaces.Constants
import info.nightscout.interfaces.GlucoseUnit
import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.utils.JsonHelper
import info.nightscout.rx.logging.LTag
import org.json.JSONObject
@ -78,7 +77,7 @@ class TriggerDelta(injector: HasAndroidInjector) : Trigger(injector) {
DeltaType.LONG_AVERAGE -> glucoseStatus.longAvgDelta
else -> glucoseStatus.delta
}
if (comparator.value.check(calculatedDelta, Profile.toMgdl(delta.value, units))) {
if (comparator.value.check(calculatedDelta, profileUtil.convertToMgdl(delta.value, units))) {
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: delta is " + calculatedDelta + " " + friendlyDescription())
return true
}

Some files were not shown because too many files have changed in this diff Show more