github.com/simpleiot/simpleiot@v0.18.3/frontend/src/Api/Point.elm (about) 1 module Api.Point exposing 2 ( Point 3 , blankMajicValue 4 , clearText 5 , decode 6 , encodeList 7 , filterDeleted 8 , filterSpecialPoints 9 , filterTombstone 10 , get 11 , getAll 12 , getBestDesc 13 , getBool 14 , getLatest 15 , getText 16 , getTextArray 17 , getValue 18 , input 19 , keyHighRate 20 , keyParent 21 , keyPointKey 22 , keyPointType 23 , light 24 , newText 25 , renderPoint 26 , renderPoint2 27 , sort 28 , switch 29 , typeAction 30 , typeActive 31 , typeAddress 32 , typeAuthToken 33 , typeAutoDownload 34 , typeAutoReboot 35 , typeBatchPeriod 36 , typeBaud 37 , typeBinary 38 , typeBitRate 39 , typeBucket 40 , typeChannel 41 , typeClientServer 42 , typeConditionType 43 , typeConnected 44 , typeControlled 45 , typeData 46 , typeDataFormat 47 , typeDate 48 , typeDebug 49 , typeDescription 50 , typeDestination 51 , typeDevice 52 , typeDeviceID 53 , typeDirectory 54 , typeDisabled 55 , typeDiscardDownload 56 , typeDownload 57 , typeDownloadOS 58 , typeEmail 59 , typeEnd 60 , typeError 61 , typeErrorCount 62 , typeErrorCountCRC 63 , typeErrorCountCRCReset 64 , typeErrorCountEOF 65 , typeErrorCountEOFReset 66 , typeErrorCountHR 67 , typeErrorCountReset 68 , typeErrorCountResetHR 69 , typeFallbackServer 70 , typeFilePath 71 , typeFirstName 72 , typeFrequency 73 , typeFrom 74 , typeHRDest 75 , typeHash 76 , typeHrRx 77 , typeHrRxReset 78 , typeID 79 , typeIP 80 , typeIndex 81 , typeInitialValue 82 , typeLastName 83 , typeLightSet 84 , typeLog 85 , typeMaxIncrement 86 , typeMaxMessageLength 87 , typeMaxValue 88 , typeMinActive 89 , typeMinIncrement 90 , typeMinValue 91 , typeModbusIOType 92 , typeMsgsInDb 93 , typeMsgsRecvdDb 94 , typeMsgsRecvdDbReset 95 , typeMsgsRecvdOther 96 , typeMsgsRecvdOtherReset 97 , typeName 98 , typeNodeID 99 , typeOSDownloaded 100 , typeOSUpdate 101 , typeOffline 102 , typeOffset 103 , typeOperator 104 , typeOrg 105 , typePass 106 , typePeriod 107 , typePhone 108 , typePointKey 109 , typePointType 110 , typePollPeriod 111 , typePort 112 , typePrefix 113 , typeProgress 114 , typeProtocol 115 , typeRate 116 , typeRateHR 117 , typeReadOnly 118 , typeReboot 119 , typeRefresh 120 , typeRoundTo 121 , typeRx 122 , typeRxReset 123 , typeSID 124 , typeSampleRate 125 , typeScale 126 , typeServer 127 , typeService 128 , typeSignalType 129 , typeSignalsInDb 130 , typeSize 131 , typeStart 132 , typeSwitchSet 133 , typeSyncCount 134 , typeSyncCountReset 135 , typeSyncParent 136 , typeSysState 137 , typeTag 138 , typeTagPointType 139 , typeTombstone 140 , typeTx 141 , typeTxReset 142 , typeType 143 , typeURI 144 , typeUnits 145 , typeValue 146 , typeValueSet 147 , typeValueText 148 , typeValueType 149 , typeVariableType 150 , typeVersionApp 151 , typeVersionHW 152 , typeVersionOS 153 , typeWeekday 154 -- , keyNodeID 155 156 , updatePoints 157 , valueApp 158 , valueClient 159 , valueContains 160 , valueEqual 161 , valueFLOAT32 162 , valueGreaterThan 163 , valueINT16 164 , valueINT32 165 , valueLessThan 166 , valueModbusCoil 167 , valueModbusDiscreteInput 168 , valueModbusHoldingRegister 169 , valueModbusInputRegister 170 , valueNotEqual 171 , valueNotify 172 , valueNumber 173 , valueOnOff 174 , valuePlayAudio 175 , valuePointValue 176 , valueProcess 177 , valueRTU 178 , valueRandomWalk 179 , valueSchedule 180 , valueServer 181 , valueSetValue 182 , valueSine 183 , valueSquare 184 , valueSystem 185 , valueTCP 186 , valueText 187 , valueTriangle 188 , valueTwilio 189 , valueUINT16 190 , valueUINT32 191 ) 192 193 import Iso8601 194 import Json.Decode as Decode 195 import Json.Decode.Extra 196 import Json.Decode.Pipeline exposing (optional) 197 import Json.Encode 198 import List.Extra 199 import Round 200 import Time 201 202 203 typeChannel : String 204 typeChannel = 205 "channel" 206 207 208 typeDevice : String 209 typeDevice = 210 "device" 211 212 213 typeDescription : String 214 typeDescription = 215 "description" 216 217 218 typeFilePath : String 219 typeFilePath = 220 "filePath" 221 222 223 typeDownload : String 224 typeDownload = 225 "download" 226 227 228 typeProgress : String 229 typeProgress = 230 "progress" 231 232 233 typeScale : String 234 typeScale = 235 "scale" 236 237 238 typeOffset : String 239 typeOffset = 240 "offset" 241 242 243 typeUnits : String 244 typeUnits = 245 "units" 246 247 248 typeValue : String 249 typeValue = 250 "value" 251 252 253 typeValueSet : String 254 typeValueSet = 255 "valueSet" 256 257 258 typeLightSet : String 259 typeLightSet = 260 "lightSet" 261 262 263 typeSwitchSet : String 264 typeSwitchSet = 265 "switchSet" 266 267 268 typeValueText : String 269 typeValueText = 270 "valueText" 271 272 273 typeReadOnly : String 274 typeReadOnly = 275 "readOnly" 276 277 278 typeSysState : String 279 typeSysState = 280 "sysState" 281 282 283 typeVersionOS : String 284 typeVersionOS = 285 "versionOS" 286 287 288 typeVersionApp : String 289 typeVersionApp = 290 "versionApp" 291 292 293 typeVersionHW : String 294 typeVersionHW = 295 "versionHW" 296 297 298 typeFirstName : String 299 typeFirstName = 300 "firstName" 301 302 303 typeLastName : String 304 typeLastName = 305 "lastName" 306 307 308 typeEmail : String 309 typeEmail = 310 "email" 311 312 313 typePhone : String 314 typePhone = 315 "phone" 316 317 318 typePass : String 319 typePass = 320 "pass" 321 322 323 typePort : String 324 typePort = 325 "port" 326 327 328 typeRx : String 329 typeRx = 330 "rx" 331 332 333 typeHrRx : String 334 typeHrRx = 335 "hrRx" 336 337 338 typeTx : String 339 typeTx = 340 "tx" 341 342 343 typeRxReset : String 344 typeRxReset = 345 "rxReset" 346 347 348 typeTxReset : String 349 typeTxReset = 350 "txReset" 351 352 353 typeHrRxReset : String 354 typeHrRxReset = 355 "hrRxReset" 356 357 358 typeBaud : String 359 typeBaud = 360 "baud" 361 362 363 typeHRDest : String 364 typeHRDest = 365 "hrDest" 366 367 368 typeMaxMessageLength : String 369 typeMaxMessageLength = 370 "maxMessageLength" 371 372 373 typeID : String 374 typeID = 375 "id" 376 377 378 typeLog : String 379 typeLog = 380 "log" 381 382 383 typeAddress : String 384 typeAddress = 385 "address" 386 387 388 typeError : String 389 typeError = 390 "error" 391 392 393 typeErrorCount : String 394 typeErrorCount = 395 "errorCount" 396 397 398 typeErrorCountEOF : String 399 typeErrorCountEOF = 400 "errorCountEOF" 401 402 403 typeErrorCountCRC : String 404 typeErrorCountCRC = 405 "errorCountCRC" 406 407 408 typeErrorCountReset : String 409 typeErrorCountReset = 410 "errorCountReset" 411 412 413 typeErrorCountEOFReset : String 414 typeErrorCountEOFReset = 415 "errorCountEOFReset" 416 417 418 typeErrorCountCRCReset : String 419 typeErrorCountCRCReset = 420 "errorCountCRCReset" 421 422 423 typeSyncCount : String 424 typeSyncCount = 425 "syncCount" 426 427 428 typeSyncCountReset : String 429 typeSyncCountReset = 430 "syncCountReset" 431 432 433 typeErrorCountHR : String 434 typeErrorCountHR = 435 "errorCountHR" 436 437 438 typeErrorCountResetHR : String 439 typeErrorCountResetHR = 440 "errorCountResetHR" 441 442 443 typeMsgsInDb : String 444 typeMsgsInDb = 445 "msgsInDb" 446 447 448 typeSignalsInDb : String 449 typeSignalsInDb = 450 "signalsInDb" 451 452 453 typeMsgsRecvdDb : String 454 typeMsgsRecvdDb = 455 "msgsRecvdDb" 456 457 458 typeMsgsRecvdOther : String 459 typeMsgsRecvdOther = 460 "msgsRecvdOther" 461 462 463 typeMsgsRecvdDbReset : String 464 typeMsgsRecvdDbReset = 465 "msgsRecvdDbReset" 466 467 468 typeMsgsRecvdOtherReset : String 469 typeMsgsRecvdOtherReset = 470 "msgsRecvdOtherReset" 471 472 473 typeProtocol : String 474 typeProtocol = 475 "protocol" 476 477 478 valueRTU : String 479 valueRTU = 480 "RTU" 481 482 483 valueTCP : String 484 valueTCP = 485 "TCP" 486 487 488 typeModbusIOType : String 489 typeModbusIOType = 490 "modbusIoType" 491 492 493 valueModbusDiscreteInput : String 494 valueModbusDiscreteInput = 495 "modbusDiscreteInput" 496 497 498 valueModbusCoil : String 499 valueModbusCoil = 500 "modbusCoil" 501 502 503 valueModbusInputRegister : String 504 valueModbusInputRegister = 505 "modbusInputRegister" 506 507 508 valueModbusHoldingRegister : String 509 valueModbusHoldingRegister = 510 "modbusHoldingRegister" 511 512 513 typeDataFormat : String 514 typeDataFormat = 515 "dataFormat" 516 517 518 typeDebug : String 519 typeDebug = 520 "debug" 521 522 523 typePollPeriod : String 524 typePollPeriod = 525 "pollPeriod" 526 527 528 valueUINT16 : String 529 valueUINT16 = 530 "uint16" 531 532 533 valueINT16 : String 534 valueINT16 = 535 "int16" 536 537 538 valueUINT32 : String 539 valueUINT32 = 540 "uint32" 541 542 543 valueINT32 : String 544 valueINT32 = 545 "int32" 546 547 548 valueFLOAT32 : String 549 valueFLOAT32 = 550 "float32" 551 552 553 typeClientServer : String 554 typeClientServer = 555 "clientServer" 556 557 558 valueClient : String 559 valueClient = 560 "client" 561 562 563 valueServer : String 564 valueServer = 565 "server" 566 567 568 typeURI : String 569 typeURI = 570 "uri" 571 572 573 typePrefix : String 574 typePrefix = 575 "prefix" 576 577 578 typeConditionType : String 579 typeConditionType = 580 "conditionType" 581 582 583 valuePointValue : String 584 valuePointValue = 585 "pointValue" 586 587 588 valueSchedule : String 589 valueSchedule = 590 "schedule" 591 592 593 typeValueType : String 594 typeValueType = 595 "valueType" 596 597 598 typeStart : String 599 typeStart = 600 "start" 601 602 603 typeEnd : String 604 typeEnd = 605 "end" 606 607 608 typeWeekday : String 609 typeWeekday = 610 "weekday" 611 612 613 typeDate : String 614 typeDate = 615 "date" 616 617 618 typePointType : String 619 typePointType = 620 "pointType" 621 622 623 typePointKey : String 624 typePointKey = 625 "pointKey" 626 627 628 typeOperator : String 629 typeOperator = 630 "operator" 631 632 633 valueGreaterThan : String 634 valueGreaterThan = 635 ">" 636 637 638 valueLessThan : String 639 valueLessThan = 640 "<" 641 642 643 valueEqual : String 644 valueEqual = 645 "=" 646 647 648 valueNotEqual : String 649 valueNotEqual = 650 "!=" 651 652 653 valueContains : String 654 valueContains = 655 "contains" 656 657 658 typeMinActive : String 659 typeMinActive = 660 "minActive" 661 662 663 typeAction : String 664 typeAction = 665 "action" 666 667 668 valueNotify : String 669 valueNotify = 670 "notify" 671 672 673 valueSetValue : String 674 valueSetValue = 675 "setValue" 676 677 678 valuePlayAudio : String 679 valuePlayAudio = 680 "playAudio" 681 682 683 typeService : String 684 typeService = 685 "service" 686 687 688 valueTwilio : String 689 valueTwilio = 690 "twilio" 691 692 693 typeSID : String 694 typeSID = 695 "sid" 696 697 698 typeAuthToken : String 699 typeAuthToken = 700 "authToken" 701 702 703 typeFrom : String 704 typeFrom = 705 "from" 706 707 708 typeVariableType : String 709 typeVariableType = 710 "variableType" 711 712 713 typeNodeID : String 714 typeNodeID = 715 "nodeID" 716 717 718 typeTombstone : String 719 typeTombstone = 720 "tombstone" 721 722 723 valueOnOff : String 724 valueOnOff = 725 "onOff" 726 727 728 valueNumber : String 729 valueNumber = 730 "number" 731 732 733 valueText : String 734 valueText = 735 "text" 736 737 738 typeActive : String 739 typeActive = 740 "active" 741 742 743 typeBucket : String 744 typeBucket = 745 "bucket" 746 747 748 typeOrg : String 749 typeOrg = 750 "org" 751 752 753 typeDisabled : String 754 typeDisabled = 755 "disabled" 756 757 758 typeConnected : String 759 typeConnected = 760 "connected" 761 762 763 typeControlled : String 764 typeControlled = 765 "controlled" 766 767 768 typeOffline : String 769 typeOffline = 770 "offline" 771 772 773 typeSignalType : String 774 typeSignalType = 775 "signalType" 776 777 778 typeBatchPeriod : String 779 typeBatchPeriod = 780 "batchPeriod" 781 782 783 typeIndex : String 784 typeIndex = 785 "index" 786 787 788 typeFrequency : String 789 typeFrequency = 790 "frequency" 791 792 793 typeMinValue : String 794 typeMinValue = 795 "minValue" 796 797 798 typeMaxValue : String 799 typeMaxValue = 800 "maxValue" 801 802 803 typeInitialValue : String 804 typeInitialValue = 805 "initialValue" 806 807 808 typeMinIncrement : String 809 typeMinIncrement = 810 "minIncrement" 811 812 813 typeMaxIncrement : String 814 typeMaxIncrement = 815 "maxIncrement" 816 817 818 typeRoundTo : String 819 typeRoundTo = 820 "roundTo" 821 822 823 typeSampleRate : String 824 typeSampleRate = 825 "sampleRate" 826 827 828 typePeriod : String 829 typePeriod = 830 "period" 831 832 833 typeName : String 834 typeName = 835 "name" 836 837 838 typeData : String 839 typeData = 840 "data" 841 842 843 typeSize : String 844 typeSize = 845 "size" 846 847 848 typeHash : String 849 typeHash = 850 "hash" 851 852 853 typeBitRate : String 854 typeBitRate = 855 "bitRate" 856 857 858 typeRate : String 859 typeRate = 860 "rate" 861 862 863 typeRateHR : String 864 typeRateHR = 865 "rateHR" 866 867 868 valueSine : String 869 valueSine = 870 "sine" 871 872 873 valueSquare : String 874 valueSquare = 875 "square" 876 877 878 valueTriangle : String 879 valueTriangle = 880 "triangle" 881 882 883 valueRandomWalk : String 884 valueRandomWalk = 885 "random walk" 886 887 888 typeType : String 889 typeType = 890 "type" 891 892 893 typeIP : String 894 typeIP = 895 "ip" 896 897 898 typeDeviceID : String 899 typeDeviceID = 900 "deviceID" 901 902 903 valueApp : String 904 valueApp = 905 "app" 906 907 908 valueProcess : String 909 valueProcess = 910 "process" 911 912 913 valueSystem : String 914 valueSystem = 915 "system" 916 917 918 switch : String 919 switch = 920 "switch" 921 922 923 input : String 924 input = 925 "input" 926 927 928 light : String 929 light = 930 "light" 931 932 933 typeServer : String 934 typeServer = 935 "server" 936 937 938 typeFallbackServer : String 939 typeFallbackServer = 940 "fallbackServer" 941 942 943 typeSyncParent : String 944 typeSyncParent = 945 "syncParent" 946 947 948 typeDestination : String 949 typeDestination = 950 "destination" 951 952 953 typeTagPointType : String 954 typeTagPointType = 955 "tagPointType" 956 957 958 typeTag : String 959 typeTag = 960 "tag" 961 962 963 964 --keyNodeID : String 965 --keyNodeID = 966 -- "nodeID" 967 968 969 keyParent : String 970 keyParent = 971 "parent" 972 973 974 keyHighRate : String 975 keyHighRate = 976 "highRate" 977 978 979 keyPointType : String 980 keyPointType = 981 "pointType" 982 983 984 keyPointKey : String 985 keyPointKey = 986 "pointKey" 987 988 989 typeDownloadOS : String 990 typeDownloadOS = 991 "downloadOS" 992 993 994 typeReboot : String 995 typeReboot = 996 "reboot" 997 998 999 typeAutoReboot : String 1000 typeAutoReboot = 1001 "autoReboot" 1002 1003 1004 typeAutoDownload : String 1005 typeAutoDownload = 1006 "autoDownload" 1007 1008 1009 typeOSDownloaded : String 1010 typeOSDownloaded = 1011 "osDownloaded" 1012 1013 1014 typeDiscardDownload : String 1015 typeDiscardDownload = 1016 "discardDownload" 1017 1018 1019 typeOSUpdate : String 1020 typeOSUpdate = 1021 "osUpdate" 1022 1023 1024 typeDirectory : String 1025 typeDirectory = 1026 "directory" 1027 1028 1029 typeRefresh : String 1030 typeRefresh = 1031 "refresh" 1032 1033 1034 typeBinary : String 1035 typeBinary = 1036 "binary" 1037 1038 1039 1040 -- Point should match data/Point.go 1041 1042 1043 type alias Point = 1044 { typ : String 1045 , key : String 1046 , time : Time.Posix 1047 , value : Float 1048 , text : String 1049 , tombstone : Int 1050 } 1051 1052 1053 newText : String -> String -> String -> Point 1054 newText typ key text = 1055 { typ = typ 1056 , key = key 1057 , time = Time.millisToPosix 0 1058 , value = 0 1059 , text = text 1060 , tombstone = 0 1061 } 1062 1063 1064 specialPoints : List String 1065 specialPoints = 1066 [ typeDescription 1067 , typeVersionHW 1068 , typeVersionOS 1069 , typeVersionApp 1070 , typeBaud 1071 , typeHRDest 1072 , typeMaxMessageLength 1073 , typeDebug 1074 , typeDisabled 1075 , typeConnected 1076 , typeControlled 1077 , typeOffline 1078 , typeError 1079 , typeErrorCount 1080 , typeErrorCountReset 1081 , typeSyncCount 1082 , typeSyncCountReset 1083 , typeErrorCountHR 1084 , typeErrorCountResetHR 1085 , typeLog 1086 , typePort 1087 , typeRx 1088 , typeHrRx 1089 , typeHrRxReset 1090 , typeRxReset 1091 , typeTx 1092 , typeTxReset 1093 , typeRate 1094 , typeRateHR 1095 , typeType 1096 , typeIP 1097 , typePeriod 1098 , typeName 1099 , typeAuthToken 1100 , typeValue 1101 , typeValueSet 1102 , typeLightSet 1103 , typeSwitchSet 1104 , typeDeviceID 1105 , switch 1106 , input 1107 , light 1108 , typeDirectory 1109 , typeRefresh 1110 , typeBinary 1111 ] 1112 1113 1114 filterSpecialPoints : List Point -> List Point 1115 filterSpecialPoints points = 1116 List.filter (\p -> not <| List.member p.typ specialPoints) points 1117 1118 1119 filterTombstone : List Point -> List Point 1120 filterTombstone points = 1121 List.filter (\p -> p.tombstone == 0) points 1122 1123 1124 encode : Point -> Json.Encode.Value 1125 encode p = 1126 Json.Encode.object 1127 [ ( "type", Json.Encode.string <| p.typ ) 1128 , ( "key", Json.Encode.string <| p.key ) 1129 , ( "time", Iso8601.encode <| p.time ) 1130 , ( "value", Json.Encode.float <| p.value ) 1131 , ( "text", Json.Encode.string <| p.text ) 1132 , ( "tombstone", Json.Encode.int <| p.tombstone ) 1133 ] 1134 1135 1136 encodeList : List Point -> Json.Encode.Value 1137 encodeList p = 1138 Json.Encode.list encode p 1139 1140 1141 decode : Decode.Decoder Point 1142 decode = 1143 Decode.succeed Point 1144 |> optional "type" Decode.string "" 1145 |> optional "key" Decode.string "" 1146 |> optional "time" Json.Decode.Extra.datetime (Time.millisToPosix 0) 1147 |> optional "value" Decode.float 0 1148 |> optional "text" Decode.string "" 1149 |> optional "tombstone" Decode.int 0 1150 1151 1152 renderPoint : Point -> String 1153 renderPoint s = 1154 let 1155 key = 1156 if s.key == "" then 1157 "" 1158 1159 else 1160 s.key ++ ":" 1161 1162 value = 1163 if s.text /= "" then 1164 s.text 1165 1166 else 1167 Round.round 2 s.value ++ ":" 1168 1169 typ = 1170 s.typ ++ ":" 1171 in 1172 typ ++ key ++ " " ++ value 1173 1174 1175 renderPoint2 : Point -> { desc : String, value : String } 1176 renderPoint2 s = 1177 let 1178 key = 1179 if s.key == "" then 1180 "" 1181 1182 else 1183 s.key ++ ":" 1184 1185 value = 1186 if s.text /= "" then 1187 s.text 1188 1189 else 1190 Round.round 2 s.value 1191 in 1192 { desc = s.typ ++ ":" ++ key, value = value } 1193 1194 1195 updatePoint : List Point -> Point -> List Point 1196 updatePoint points point = 1197 case 1198 List.Extra.findIndex 1199 (\p -> 1200 point.typ == p.typ && point.key == p.key 1201 ) 1202 points 1203 of 1204 Just index -> 1205 List.Extra.setAt index point points 1206 1207 Nothing -> 1208 point :: points 1209 1210 1211 updatePoints : List Point -> List Point -> List Point 1212 updatePoints points newPoints = 1213 List.foldr 1214 (\newPoint updatedPoints -> updatePoint updatedPoints newPoint) 1215 points 1216 newPoints 1217 1218 1219 get : List Point -> String -> String -> Maybe Point 1220 get points typ key = 1221 let 1222 keyS = 1223 if key == "" then 1224 "0" 1225 1226 else 1227 key 1228 in 1229 List.Extra.find 1230 (\p -> 1231 typ == p.typ && keyS == p.key 1232 ) 1233 points 1234 1235 1236 getAll : List Point -> String -> List Point 1237 getAll points typ = 1238 List.filter (\p -> typ == p.typ) points 1239 1240 1241 filterDeleted : List Point -> List Point 1242 filterDeleted points = 1243 List.filter (\p -> p.tombstone == 0) points 1244 1245 1246 getText : List Point -> String -> String -> String 1247 getText points typ key = 1248 case 1249 get points typ key 1250 of 1251 Just found -> 1252 found.text 1253 1254 Nothing -> 1255 "" 1256 1257 1258 getTextArray : List Point -> String -> List String 1259 getTextArray points typ = 1260 List.map .text <| 1261 List.sortWith 1262 (\a b -> 1263 let 1264 aInt = 1265 Maybe.withDefault 0 (String.toInt a.key) 1266 1267 bInt = 1268 Maybe.withDefault 0 (String.toInt b.key) 1269 in 1270 compare aInt bInt 1271 ) 1272 <| 1273 List.foldl 1274 (\p acc -> 1275 if p.typ == typ && p.tombstone == 0 then 1276 p :: acc 1277 1278 else 1279 acc 1280 ) 1281 [] 1282 points 1283 1284 1285 getBestDesc : List Point -> String 1286 getBestDesc points = 1287 let 1288 firstName = 1289 getText points typeFirstName "" 1290 in 1291 if firstName /= "" then 1292 firstName ++ " " ++ getText points typeLastName "" 1293 1294 else 1295 let 1296 desc = 1297 getText points typeDescription "" 1298 in 1299 if desc /= "" then 1300 desc 1301 1302 else 1303 "no description" 1304 1305 1306 getValue : List Point -> String -> String -> Float 1307 getValue points typ key = 1308 case 1309 get points typ key 1310 of 1311 Just found -> 1312 found.value 1313 1314 Nothing -> 1315 0 1316 1317 1318 getBool : List Point -> String -> String -> Bool 1319 getBool points typ key = 1320 getValue points typ key == 1 1321 1322 1323 getLatest : List Point -> Maybe Point 1324 getLatest points = 1325 List.foldl 1326 (\p result -> 1327 case result of 1328 Just point -> 1329 if Time.posixToMillis p.time > Time.posixToMillis point.time then 1330 Just p 1331 1332 else 1333 Just point 1334 1335 Nothing -> 1336 Just p 1337 ) 1338 Nothing 1339 points 1340 1341 1342 1343 -- clearText is used to sanitize points that have number values before saving. 1344 -- the text value is used by the form when editting things like decimal points 1345 1346 1347 blankMajicValue : String 1348 blankMajicValue = 1349 "123BLANK123" 1350 1351 1352 clearText : List Point -> List Point 1353 clearText points = 1354 List.map 1355 (\p -> 1356 if p.value /= 0 || p.text == blankMajicValue then 1357 { p | text = "" } 1358 1359 else 1360 p 1361 ) 1362 points 1363 1364 1365 sort : Point -> Point -> Order 1366 sort a b = 1367 if a.typ /= b.typ then 1368 compare a.typ b.typ 1369 1370 else 1371 let 1372 keysAreInt = 1373 String.toInt a.key /= Nothing && String.toInt b.key /= Nothing 1374 1375 aKeyInt = 1376 Maybe.withDefault 0 (String.toInt a.key) 1377 1378 bKeyInt = 1379 Maybe.withDefault 0 (String.toInt b.key) 1380 in 1381 if keysAreInt && aKeyInt /= bKeyInt then 1382 compare aKeyInt bKeyInt 1383 1384 else if a.key /= b.key then 1385 compare a.key b.key 1386 1387 else 1388 compare a.value b.value