├── LithopiaNodeRed.json ├── LithopiaWorkshop.cto ├── LithopiaWorkshop.js ├── NodeREDMarch2019.json ├── README.md ├── UML-Diagram.xml ├── identity.acl ├── lithopiaFeb22.json ├── logic.js ├── mate └── readme.md ├── org.lithopia.basic.cto └── permissions.acl /LithopiaNodeRed.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id":"2c510c19.115f44", 4 | "type":"tab", 5 | "label":"Lithopia-basic", 6 | "disabled":false, 7 | "info":"# First column\n**Basic info on Lithopia, Lithopians, their properties, marriages and partnerships**\n 1. **Retro LCD display:** courtesy of Peter Scargill https://tech.scargill.net/lcd-display-for-node-red/\n 2. **Openweather widget**: courtesy of FRED http://developers.sensetecnic.com/article/a-node-red-flow-to-monitor-the-weather/ to which I added text-to-speech node for weather announcement.\n 3. **Openweather icon**: generating and showing html objects IMG based on \nhttps://flows.nodered.org/flow/2f1aaf0635f9bf23207152682323240a \nTrick is to createthe payload with the tags in a function-node and then in the template-node just represent it with `
`\n4. **Texfields on Lithopians, property, marriages**: all use http-node with get command to query the REST-API composer contract on http://anonette.net:3000/explorer and with switch-node and JSONATA get the requesteddata out of the complex JSON, basic JSONARA https://docs.jsonata.org/string-functions.html\nhttps://console.bluemix.net/docs/services/IoT/GA_information_management/mapping_expression_language.html#mapping_expression \nTo test also http://try.jsonata.org/. Useful resource to learn how to work with SWITCH - courtesy [Steve Cope from min 10.](https://www.youtube.com/watch?v=PbEoHxFOdmE&fbclid=IwAR2rvMT7lKdwk8LwGtcBF7V29AhJ-GAr07tJrVVXCyeA-ZFwSb6hy_akhzo)\n" 8 | }, 9 | { 10 | "id":"b36b79fb.681da8", 11 | "type":"tab", 12 | "label":"Transactions", 13 | "disabled":false, 14 | "info":"# Second column\n**Info on the Sentinel2A satellite position, view on Earth from ISS, forms to blockchain transactions on how to become Lithopian, register a property or parnership**\n 1. **Tracking satellites on a map:** important to get the TLE data for the satellite nodes from [https://www.celestrak.com/NORAD/elements/supplemental/](https://www.celestrak.com/NORAD/elements/supplemental/)\nthen use instructions from [node-red-satellites node](https://flows.nodered.org/node/node-red-contrib-satellites) and [world-map-node](https://flows.nodered.org/node/node-red-contrib-web-worldmap).\n2. **ISS real time video of Earth**: just video embedded in node-red templat.\n 3. **Hyperleder Composer REST API post commands**: allowing participants to register on the blockchain their names, property and type of partnerships." 15 | }, 16 | { 17 | "id":"b0c47343.b841f", 18 | "type":"tab", 19 | "label":"Markets", 20 | "disabled":false, 21 | "info":"" 22 | }, 23 | { 24 | "id":"16cbe86b.7d5128", 25 | "type":"tab", 26 | "label":"Example of ui_list", 27 | "disabled":true, 28 | "info":"" 29 | }, 30 | { 31 | "id":"34da0e1.ff218f2", 32 | "type":"tab", 33 | "label":"Dashboard Form", 34 | "disabled":true, 35 | "info":"" 36 | }, 37 | { 38 | "id":"79da451d.1847cc", 39 | "type":"tab", 40 | "label":"Flow 1", 41 | "disabled":true, 42 | "info":"" 43 | }, 44 | { 45 | "id":"1237b296.98e65d", 46 | "type":"twitter-credentials", 47 | "z":"", 48 | "screen_name":"Lithopia1" 49 | }, 50 | { 51 | "id":"8949c15e.fa253", 52 | "type":"ui_base", 53 | "z":"", 54 | "theme":{ 55 | "name":"theme-light", 56 | "lightTheme":{ 57 | "default":"#0094CE", 58 | "baseColor":"#040000", 59 | "baseFont":"-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif", 60 | "edited":true, 61 | "reset":false 62 | }, 63 | "darkTheme":{ 64 | "default":"#097479", 65 | "baseColor":"#c0c0c0", 66 | "baseFont":"Lucida Sans Unicode,Lucida Grande,sans-serif", 67 | "edited":true, 68 | "reset":false 69 | }, 70 | "customTheme":{ 71 | "name":"Untitled Theme 1", 72 | "default":"#4B7930", 73 | "baseColor":"#4B7930", 74 | "baseFont":"-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif", 75 | "reset":false 76 | }, 77 | "themeState":{ 78 | "base-color":{ 79 | "default":"#0094CE", 80 | "value":"#040000", 81 | "edited":true 82 | }, 83 | "page-titlebar-backgroundColor":{ 84 | "value":"#040000", 85 | "edited":false 86 | }, 87 | "page-backgroundColor":{ 88 | "value":"#fafafa", 89 | "edited":false 90 | }, 91 | "page-sidebar-backgroundColor":{ 92 | "value":"#000000", 93 | "edited":false 94 | }, 95 | "group-textColor":{ 96 | "value":"#500000", 97 | "edited":false 98 | }, 99 | "group-borderColor":{ 100 | "value":"#ffffff", 101 | "edited":false 102 | }, 103 | "group-backgroundColor":{ 104 | "value":"#ffffff", 105 | "edited":false 106 | }, 107 | "widget-textColor":{ 108 | "value":"#111111", 109 | "edited":false 110 | }, 111 | "widget-backgroundColor":{ 112 | "value":"#040000", 113 | "edited":false 114 | }, 115 | "widget-borderColor":{ 116 | "value":"#ffffff", 117 | "edited":false 118 | }, 119 | "base-font":{ 120 | "value":"-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif" 121 | } 122 | }, 123 | "angularTheme":{ 124 | "primary":"indigo", 125 | "accents":"blue", 126 | "warn":"red", 127 | "background":"grey" 128 | } 129 | }, 130 | "site":{ 131 | "name":"It's a new day under the starry satellites above and the moral law within the distributed ledgers...", 132 | "hideToolbar":"false", 133 | "allowSwipe":"false", 134 | "lockMenu":"true", 135 | "allowTempTheme":"true", 136 | "dateFormat":"DD/MM/YYYY", 137 | "sizes":{ 138 | "sx":48, 139 | "sy":48, 140 | "gx":6, 141 | "gy":6, 142 | "cx":6, 143 | "cy":6, 144 | "px":4, 145 | "py":4 146 | } 147 | } 148 | }, 149 | { 150 | "id":"5d0ccd43.158994", 151 | "type":"ui_group", 152 | "z":"", 153 | "name":"LITHIUM SENTIMENTS", 154 | "tab":"", 155 | "order":2, 156 | "disp":true, 157 | "width":"6", 158 | "collapse":false 159 | }, 160 | { 161 | "id":"7dcc8114.426918", 162 | "type":"ui_group", 163 | "z":"", 164 | "name":"INTERACT WITH HYPERLEDGER", 165 | "tab":"", 166 | "order":1, 167 | "disp":false, 168 | "width":"8", 169 | "collapse":false 170 | }, 171 | { 172 | "id":"55f8ba0a.7fcd54", 173 | "type":"ui_group", 174 | "z":"", 175 | "name":"basic", 176 | "tab":"53d478d.6778088", 177 | "order":1, 178 | "disp":false, 179 | "width":"6", 180 | "collapse":false 181 | }, 182 | { 183 | "id":"53d478d.6778088", 184 | "type":"ui_tab", 185 | "z":"", 186 | "name":"Tab 1", 187 | "icon":"handshake-o", 188 | "order":1 189 | }, 190 | { 191 | "id":"60e96444.be8e4c", 192 | "type":"ui_group", 193 | "z":"", 194 | "name":"transactions", 195 | "tab":"53d478d.6778088", 196 | "order":2, 197 | "disp":false, 198 | "width":"6", 199 | "collapse":false 200 | }, 201 | { 202 | "id":"c4b4d589.76ec78", 203 | "type":"ui_group", 204 | "z":"", 205 | "name":"market", 206 | "tab":"53d478d.6778088", 207 | "order":3, 208 | "disp":false, 209 | "width":"6", 210 | "collapse":false 211 | }, 212 | { 213 | "id":"92766969.968688", 214 | "type":"ui_group", 215 | "z":"", 216 | "name":"Group 2", 217 | "tab":"41ec81fb.6afe6", 218 | "order":2, 219 | "disp":true, 220 | "width":"6" 221 | }, 222 | { 223 | "id":"9f110b7e.d5e048", 224 | "type":"ui_group", 225 | "z":"", 226 | "name":"Default Group", 227 | "tab":"", 228 | "disp":true, 229 | "width":"9" 230 | }, 231 | { 232 | "id":"437124cf.dde0cc", 233 | "type":"ui_group", 234 | "z":"", 235 | "name":"Default", 236 | "tab":"", 237 | "disp":true, 238 | "width":"6" 239 | }, 240 | { 241 | "id":"f7b63450.88cf08", 242 | "type":"ui_group", 243 | "z":"", 244 | "name":"T1", 245 | "tab":"", 246 | "disp":true, 247 | "width":"6", 248 | "collapse":false 249 | }, 250 | { 251 | "id":"3000e6a0.476bda", 252 | "type":"ui_group", 253 | "z":"", 254 | "name":"Default", 255 | "tab":"", 256 | "disp":true, 257 | "width":"12", 258 | "collapse":false 259 | }, 260 | { 261 | "id":"76ccb74f.5c14b8", 262 | "type":"ui_group", 263 | "z":"", 264 | "name":"Add an Asset", 265 | "tab":"", 266 | "order":1, 267 | "disp":true, 268 | "width":"6" 269 | }, 270 | { 271 | "id":"70399ba8.caa894", 272 | "type":"ui_group", 273 | "z":"", 274 | "name":"Select an Asset to Delete", 275 | "tab":"", 276 | "order":2, 277 | "disp":true, 278 | "width":"8" 279 | }, 280 | { 281 | "id":"a2297d4a.167c1", 282 | "type":"ui_group", 283 | "z":"", 284 | "name":"Inventory List", 285 | "tab":"", 286 | "order":3, 287 | "disp":true, 288 | "width":"12" 289 | }, 290 | { 291 | "id":"6f9764e9.3c0bac", 292 | "type":"ui_group", 293 | "z":"", 294 | "name":"testy", 295 | "tab":"", 296 | "disp":true, 297 | "width":"6" 298 | }, 299 | { 300 | "id":"f83a757c.eb42c8", 301 | "type":"ui_group", 302 | "z":"", 303 | "name":"testy", 304 | "tab":"", 305 | "disp":true, 306 | "width":"6" 307 | }, 308 | { 309 | "id":"d4817f7f.ac4d9", 310 | "type":"ui_group", 311 | "z":"", 312 | "name":"Examples", 313 | "tab":"a24f46f4.79e948", 314 | "order":1, 315 | "disp":true, 316 | "width":"12" 317 | }, 318 | { 319 | "id":"3b7286fb.6656ea", 320 | "type":"http request", 321 | "z":"2c510c19.115f44", 322 | "name":"getlithopians", 323 | "method":"GET", 324 | "ret":"obj", 325 | "url":"http://anonette.net:3000/api/Lithopian", 326 | "tls":"", 327 | "x":110, 328 | "y":740, 329 | "wires":[ 330 | [ 331 | "b5a434c3.6ce398" 332 | ] 333 | ] 334 | }, 335 | { 336 | "id":"b5a434c3.6ce398", 337 | "type":"change", 338 | "z":"2c510c19.115f44", 339 | "name":"Present Lithopians:", 340 | "rules":[ 341 | { 342 | "t":"set", 343 | "p":"payload", 344 | "pt":"msg", 345 | "to":"payload.name", 346 | "tot":"jsonata" 347 | } 348 | ], 349 | "action":"", 350 | "property":"", 351 | "from":"", 352 | "to":"", 353 | "reg":false, 354 | "x":110, 355 | "y":780, 356 | "wires":[ 357 | [ 358 | "74452208.0355ac" 359 | ] 360 | ] 361 | }, 362 | { 363 | "id":"c34450ab.ae98", 364 | "type":"ui_text", 365 | "z":"2c510c19.115f44", 366 | "group":"55f8ba0a.7fcd54", 367 | "order":6, 368 | "width":"0", 369 | "height":"0", 370 | "name":"who?", 371 | "label":"", 372 | "format":"{{msg.payload | uppercase}}", 373 | "layout":"col-center", 374 | "x":90, 375 | "y":860, 376 | "wires":[ 377 | 378 | ] 379 | }, 380 | { 381 | "id":"7901605c.cfbb8", 382 | "type":"function", 383 | "z":"2c510c19.115f44", 384 | "name":"clouds", 385 | "func":"if (msg.payload.weather === \"Clear\") {\nmsg.payload = \"clear skies ahead! Ideal day for transactions with \" + msg.payload.clouds + \" clouds and \" + msg.payload.humidity + \"% humidity in Lithopia.\"; \n} else {\nmsg.payload = \"Expect \" + msg.payload.detail + \" today in Lithopia. The sky is covered with \" + msg.payload.clouds + \"% clouds and the temperature will drop to \" + msg.payload.temp_minc + \" C. If you have to transact on the hyperledger, call a public drone!\";\n}\nreturn msg;", 386 | "outputs":1, 387 | "noerr":0, 388 | "x":350, 389 | "y":160, 390 | "wires":[ 391 | [ 392 | "1129d49d.a89a7b", 393 | "d668ae3.3fc715" 394 | ] 395 | ] 396 | }, 397 | { 398 | "id":"1129d49d.a89a7b", 399 | "type":"ui_text", 400 | "z":"2c510c19.115f44", 401 | "group":"55f8ba0a.7fcd54", 402 | "order":2, 403 | "width":"6", 404 | "height":"3", 405 | "name":"Weather announcement ", 406 | "label":"", 407 | "format":"{{msg.payload}}", 408 | "layout":"col-center", 409 | "x":650, 410 | "y":200, 411 | "wires":[ 412 | 413 | ] 414 | }, 415 | { 416 | "id":"74452208.0355ac", 417 | "type":"csv", 418 | "z":"2c510c19.115f44", 419 | "name":"", 420 | "sep":" ", 421 | "hdrin":"", 422 | "hdrout":"", 423 | "multi":"one", 424 | "ret":"\\r\\n", 425 | "temp":"", 426 | "skip":"0", 427 | "x":90, 428 | "y":820, 429 | "wires":[ 430 | [ 431 | "c34450ab.ae98" 432 | ] 433 | ] 434 | }, 435 | { 436 | "id":"2346cf24.0e789", 437 | "type":"ui_audio", 438 | "z":"2c510c19.115f44", 439 | "name":"Voice announcement", 440 | "group":"55f8ba0a.7fcd54", 441 | "voice":"en-US", 442 | "always":true, 443 | "x":760, 444 | "y":160, 445 | "wires":[ 446 | 447 | ] 448 | }, 449 | { 450 | "id":"d668ae3.3fc715", 451 | "type":"trigger", 452 | "z":"2c510c19.115f44", 453 | "op1":"", 454 | "op2":"", 455 | "op1type":"pay", 456 | "op2type":"pay", 457 | "duration":"5", 458 | "extend":false, 459 | "units":"min", 460 | "reset":"", 461 | "bytopic":"all", 462 | "name":"", 463 | "x":550, 464 | "y":160, 465 | "wires":[ 466 | [ 467 | "2346cf24.0e789" 468 | ] 469 | ] 470 | }, 471 | { 472 | "id":"11624031.6732b", 473 | "type":"http request", 474 | "z":"2c510c19.115f44", 475 | "name":"getmarriages", 476 | "method":"GET", 477 | "ret":"obj", 478 | "url":"http://anonette.net:3000/api/LithopiaMarriage", 479 | "tls":"", 480 | "x":710, 481 | "y":740, 482 | "wires":[ 483 | [ 484 | "7c4c121b.03d8ac" 485 | ] 486 | ] 487 | }, 488 | { 489 | "id":"ecfe912e.40844", 490 | "type":"csv", 491 | "z":"2c510c19.115f44", 492 | "name":"", 493 | "sep":",", 494 | "hdrin":true, 495 | "hdrout":false, 496 | "multi":"one", 497 | "ret":"\\r\\n", 498 | "temp":"", 499 | "skip":"0", 500 | "x":690, 501 | "y":820, 502 | "wires":[ 503 | [ 504 | "cf48b917.5acc88" 505 | ] 506 | ] 507 | }, 508 | { 509 | "id":"f3866e8a.24c78", 510 | "type":"ui_button", 511 | "z":"2c510c19.115f44", 512 | "name":"", 513 | "group":"55f8ba0a.7fcd54", 514 | "order":5, 515 | "width":"0", 516 | "height":"0", 517 | "passthru":false, 518 | "label":"Lithopians", 519 | "color":"white", 520 | "bgcolor":"black", 521 | "icon":"fa-address-book", 522 | "payload":"true", 523 | "payloadType":"bool", 524 | "topic":"", 525 | "x":110, 526 | "y":700, 527 | "wires":[ 528 | [ 529 | "3b7286fb.6656ea" 530 | ] 531 | ] 532 | }, 533 | { 534 | "id":"9a283b54.30e8e8", 535 | "type":"ui_button", 536 | "z":"2c510c19.115f44", 537 | "name":"", 538 | "group":"55f8ba0a.7fcd54", 539 | "order":7, 540 | "width":"0", 541 | "height":"0", 542 | "passthru":false, 543 | "label":"Lithopia properties", 544 | "color":"white", 545 | "bgcolor":"black", 546 | "icon":"home", 547 | "payload":"true", 548 | "payloadType":"bool", 549 | "topic":"", 550 | "x":370, 551 | "y":700, 552 | "wires":[ 553 | [ 554 | "52bbad98.ceb4e4" 555 | ] 556 | ] 557 | }, 558 | { 559 | "id":"52bbad98.ceb4e4", 560 | "type":"http request", 561 | "z":"2c510c19.115f44", 562 | "name":"getproperty", 563 | "method":"GET", 564 | "ret":"obj", 565 | "url":"http://anonette.net:3000/api/LithopiaPlace", 566 | "tls":"", 567 | "x":370, 568 | "y":740, 569 | "wires":[ 570 | [ 571 | "e3e65257.075b3" 572 | ] 573 | ] 574 | }, 575 | { 576 | "id":"e3e65257.075b3", 577 | "type":"change", 578 | "z":"2c510c19.115f44", 579 | "name":"Lithopians Property:", 580 | "rules":[ 581 | { 582 | "t":"set", 583 | "p":"payload", 584 | "pt":"msg", 585 | "to":"payload.(name & ' owned by ' & owner)", 586 | "tot":"jsonata" 587 | } 588 | ], 589 | "action":"", 590 | "property":"", 591 | "from":"", 592 | "to":"", 593 | "reg":false, 594 | "x":380, 595 | "y":780, 596 | "wires":[ 597 | [ 598 | "628b23a8.4a7ecc" 599 | ] 600 | ] 601 | }, 602 | { 603 | "id":"628b23a8.4a7ecc", 604 | "type":"csv", 605 | "z":"2c510c19.115f44", 606 | "name":"", 607 | "sep":"\\t", 608 | "hdrin":true, 609 | "hdrout":"", 610 | "multi":"one", 611 | "ret":"\\r\\n", 612 | "temp":"", 613 | "skip":"0", 614 | "x":350, 615 | "y":820, 616 | "wires":[ 617 | [ 618 | "e4a1e6cb.b50d38" 619 | ] 620 | ] 621 | }, 622 | { 623 | "id":"e4a1e6cb.b50d38", 624 | "type":"ui_text", 625 | "z":"2c510c19.115f44", 626 | "group":"55f8ba0a.7fcd54", 627 | "order":8, 628 | "width":"0", 629 | "height":"0", 630 | "name":"What?", 631 | "label":"", 632 | "format":"{{msg.payload | uppercase}}", 633 | "layout":"col-center", 634 | "x":330, 635 | "y":860, 636 | "wires":[ 637 | 638 | ] 639 | }, 640 | { 641 | "id":"4796adf7.427f34", 642 | "type":"inject", 643 | "z":"16cbe86b.7d5128", 644 | "name":"Fruits", 645 | "topic":"", 646 | "payload":"[{\"title\":\"Apple\",\"description\":\"This is description of Apple.\",\"icon\":\"https://upload.wikimedia.org/wikipedia/commons/thumb/1/15/Red_Apple.jpg/500px-Red_Apple.jpg\"},{\"title\":\"Banana\",\"description\":\"This is description of Banana(no picture).\",\"icon\":null},{\"title\":\"Orange\",\"description\":\"This is description of Orange.\",\"icon\":\"https://upload.wikimedia.org/wikipedia/commons/thumb/4/43/Ambersweet_oranges.jpg/440px-Ambersweet_oranges.jpg\"},{\"title\":\"Watermelon\",\"description\":\"This is description of Watermelon.\",\"icon\":\"https://upload.wikimedia.org/wikipedia/commons/thumb/4/4c/Vampire_watermelon.jpg/440px-Vampire_watermelon.jpg\"}]", 647 | "payloadType":"json", 648 | "repeat":"", 649 | "crontab":"", 650 | "once":false, 651 | "onceDelay":0.1, 652 | "x":110, 653 | "y":100, 654 | "wires":[ 655 | [ 656 | 657 | ] 658 | ] 659 | }, 660 | { 661 | "id":"3aacfb71.ae54c4", 662 | "type":"debug", 663 | "z":"16cbe86b.7d5128", 664 | "name":"", 665 | "active":true, 666 | "tosidebar":true, 667 | "console":false, 668 | "tostatus":false, 669 | "complete":"false", 670 | "x":250, 671 | "y":100, 672 | "wires":[ 673 | 674 | ] 675 | }, 676 | { 677 | "id":"757b7811.0ca488", 678 | "type":"inject", 679 | "z":"16cbe86b.7d5128", 680 | "name":"WiFi", 681 | "topic":"", 682 | "payload":"[{\"title\":\"No WiFi Signal\",\"description\":\"Lost network connection\",\"icon_name\":\"signal_wifi_0_bar\"},{\"title\":\"Weak WiFi Signal\",\"description\":\"May lose network connection\",\"icon_name\":\"signal_wifi_2_bar\"},{\"title\":\"Strong WiFi Signal\",\"description\":\"Connected to network\",\"icon_name\":\"signal_wifi_4_bar\"}]", 683 | "payloadType":"json", 684 | "repeat":"", 685 | "crontab":"", 686 | "once":false, 687 | "onceDelay":0.1, 688 | "x":110, 689 | "y":180, 690 | "wires":[ 691 | [ 692 | 693 | ] 694 | ] 695 | }, 696 | { 697 | "id":"2aeb7ecb.4ec932", 698 | "type":"ui_list", 699 | "z":"16cbe86b.7d5128", 700 | "group":"3000e6a0.476bda", 701 | "name":"", 702 | "order":3, 703 | "width":"4", 704 | "height":"7", 705 | "lineType":"one", 706 | "actionType":"check", 707 | "allowHTML":false, 708 | "x":230, 709 | "y":220, 710 | "wires":[ 711 | [ 712 | "6a8542b3.0cd90c" 713 | ] 714 | ] 715 | }, 716 | { 717 | "id":"19558a8e.71f195", 718 | "type":"inject", 719 | "z":"16cbe86b.7d5128", 720 | "name":"Day of Week", 721 | "topic":"", 722 | "payload":"[{\"title\":\"Sunday\",\"isChecked\":true},{\"title\":\"Monday\"},{\"title\":\"Tuesday\"},{\"title\":\"Wednesday\"},{\"title\":\"Thursday\"},{\"title\":\"Friday\"},{\"title\":\"Saturday\",\"isChecked\":true}]", 723 | "payloadType":"json", 724 | "repeat":"", 725 | "crontab":"", 726 | "once":false, 727 | "onceDelay":0.1, 728 | "x":130, 729 | "y":260, 730 | "wires":[ 731 | [ 732 | "2aeb7ecb.4ec932" 733 | ] 734 | ] 735 | }, 736 | { 737 | "id":"6a8542b3.0cd90c", 738 | "type":"debug", 739 | "z":"16cbe86b.7d5128", 740 | "name":"", 741 | "active":true, 742 | "tosidebar":true, 743 | "console":false, 744 | "tostatus":false, 745 | "complete":"false", 746 | "x":130, 747 | "y":300, 748 | "wires":[ 749 | 750 | ] 751 | }, 752 | { 753 | "id":"d8a7b9e8.c36ee8", 754 | "type":"debug", 755 | "z":"16cbe86b.7d5128", 756 | "name":"", 757 | "active":true, 758 | "tosidebar":true, 759 | "console":false, 760 | "tostatus":false, 761 | "complete":"false", 762 | "x":230, 763 | "y":160, 764 | "wires":[ 765 | 766 | ] 767 | }, 768 | { 769 | "id":"9a6d8439.dda668", 770 | "type":"inject", 771 | "z":"34da0e1.ff218f2", 772 | "name":"Reset Database load", 773 | "topic":"", 774 | "payload":"true", 775 | "payloadType":"bool", 776 | "repeat":"", 777 | "crontab":"", 778 | "once":true, 779 | "x":180, 780 | "y":80, 781 | "wires":[ 782 | [ 783 | "599043ce.b0c69c" 784 | ] 785 | ] 786 | }, 787 | { 788 | "id":"599043ce.b0c69c", 789 | "type":"change", 790 | "z":"34da0e1.ff218f2", 791 | "name":"", 792 | "rules":[ 793 | { 794 | "t":"set", 795 | "p":"db-loaded", 796 | "pt":"flow", 797 | "to":"false", 798 | "tot":"bool" 799 | } 800 | ], 801 | "action":"", 802 | "property":"", 803 | "from":"", 804 | "to":"", 805 | "reg":false, 806 | "x":410, 807 | "y":100, 808 | "wires":[ 809 | [ 810 | "ae006376.3ec33" 811 | ] 812 | ] 813 | }, 814 | { 815 | "id":"4d664b1d.ea73b4", 816 | "type":"inject", 817 | "z":"34da0e1.ff218f2", 818 | "name":"", 819 | "topic":"", 820 | "payload":"true", 821 | "payloadType":"bool", 822 | "repeat":"", 823 | "crontab":"", 824 | "once":true, 825 | "x":130, 826 | "y":160, 827 | "wires":[ 828 | [ 829 | "ae006376.3ec33" 830 | ] 831 | ] 832 | }, 833 | { 834 | "id":"ae006376.3ec33", 835 | "type":"switch", 836 | "z":"34da0e1.ff218f2", 837 | "name":"Load Asset Database", 838 | "property":"db-loaded", 839 | "propertyType":"flow", 840 | "rules":[ 841 | { 842 | "t":"false" 843 | }, 844 | { 845 | "t":"true" 846 | } 847 | ], 848 | "checkall":"true", 849 | "outputs":2, 850 | "x":340, 851 | "y":160, 852 | "wires":[ 853 | [ 854 | 855 | ], 856 | [ 857 | 858 | ] 859 | ], 860 | "outputLabels":[ 861 | "IoTP Target DB not loaded", 862 | "IoTP Target DB loaded" 863 | ] 864 | }, 865 | { 866 | "id":"ce144049.dd51c", 867 | "type":"debug", 868 | "z":"34da0e1.ff218f2", 869 | "name":"", 870 | "active":true, 871 | "console":"false", 872 | "complete":"false", 873 | "x":1070, 874 | "y":160, 875 | "wires":[ 876 | 877 | ] 878 | }, 879 | { 880 | "id":"8d5f300f.88417", 881 | "type":"ui_form", 882 | "z":"34da0e1.ff218f2", 883 | "name":"", 884 | "label":"Add a new Asset", 885 | "group":"76ccb74f.5c14b8", 886 | "order":0, 887 | "width":0, 888 | "height":0, 889 | "options":[ 890 | { 891 | "label":"Asset Name", 892 | "value":"AssetName", 893 | "type":"text", 894 | "required":true 895 | }, 896 | { 897 | "label":"Asset Type", 898 | "value":"AssetType", 899 | "type":"text", 900 | "required":true 901 | }, 902 | { 903 | "label":"Asset ID", 904 | "value":"AssetID", 905 | "type":"text", 906 | "required":true 907 | }, 908 | { 909 | "label":"Location", 910 | "value":"Location", 911 | "type":"text", 912 | "required":true 913 | } 914 | ], 915 | "formValue":{ 916 | "AssetName":"", 917 | "AssetType":"", 918 | "AssetID":"", 919 | "Location":"" 920 | }, 921 | "payload":"", 922 | "topic":"", 923 | "x":120, 924 | "y":260, 925 | "wires":[ 926 | [ 927 | "2856484.99e51b8", 928 | "1ef11136.659fef" 929 | ] 930 | ] 931 | }, 932 | { 933 | "id":"2856484.99e51b8", 934 | "type":"debug", 935 | "z":"34da0e1.ff218f2", 936 | "name":"", 937 | "active":true, 938 | "console":"false", 939 | "complete":"false", 940 | "x":350, 941 | "y":300, 942 | "wires":[ 943 | 944 | ] 945 | }, 946 | { 947 | "id":"dafb82aa.68281", 948 | "type":"ui_dropdown", 949 | "z":"34da0e1.ff218f2", 950 | "name":"", 951 | "label":"Select an Asset to Delete", 952 | "place":"Existing Asset", 953 | "group":"70399ba8.caa894", 954 | "order":0, 955 | "width":0, 956 | "height":0, 957 | "passthru":true, 958 | "options":[ 959 | { 960 | "label":"AssetName", 961 | "value":"Asset Name", 962 | "type":"str" 963 | } 964 | ], 965 | "payload":"", 966 | "topic":"", 967 | "x":500, 968 | "y":560, 969 | "wires":[ 970 | [ 971 | "969aa18a.8ecda" 972 | ] 973 | ] 974 | }, 975 | { 976 | "id":"a20016f5.5b3988", 977 | "type":"function", 978 | "z":"34da0e1.ff218f2", 979 | "name":"Load Dropdown list", 980 | "func":"var AssetList = global.get(\"Assets\");\nif (typeof AssetList == 'undefined') {\n return null;\n}\nvar DropDownList = [];\n\n// Just load the list of Asset in the dropdown, not the Asset details\nfor (i=0; i < AssetList.length; i++) {\n DropDownList.push(AssetList[i].AssetName);\n}\nmsg.options = DropDownList;\nreturn msg;", 981 | "outputs":1, 982 | "noerr":0, 983 | "x":230, 984 | "y":560, 985 | "wires":[ 986 | [ 987 | "dafb82aa.68281", 988 | "e0dfe530.67ba88" 989 | ] 990 | ] 991 | }, 992 | { 993 | "id":"e0dfe530.67ba88", 994 | "type":"debug", 995 | "z":"34da0e1.ff218f2", 996 | "name":"", 997 | "active":true, 998 | "console":"false", 999 | "complete":"options", 1000 | "x":460, 1001 | "y":520, 1002 | "wires":[ 1003 | 1004 | ] 1005 | }, 1006 | { 1007 | "id":"1ef11136.659fef", 1008 | "type":"function", 1009 | "z":"34da0e1.ff218f2", 1010 | "name":"Add to Asset Array", 1011 | "func":"var AssetList = global.get(\"Assets\") || [];\n\n// Add the new Asset / Asset Details as an json object to the array of Assets\nAssetList.push(msg.payload);\n\nglobal.set(\"Assets\",AssetList);\nreturn msg;", 1012 | "outputs":1, 1013 | "noerr":0, 1014 | "x":370, 1015 | "y":260, 1016 | "wires":[ 1017 | [ 1018 | "ac8c2b68.530f38" 1019 | ] 1020 | ] 1021 | }, 1022 | { 1023 | "id":"77fee4fd.0ac78c", 1024 | "type":"function", 1025 | "z":"34da0e1.ff218f2", 1026 | "name":"Remove Asset from Array", 1027 | "func":"// If the Delete Asset button has been pressed\nif( msg.payload === true ) {\n var AssetList = global.get(\"Assets\");\n if (typeof Assets == 'undefined') {\n return null;\n }\n var SelectedAsset = flow.get(\"SelectedAsset\");\n var Asset2Delete = {};\n // Dropdown will return just the \"AssetName\" in the flow.SelectedOrg variable\n // Iterate through the list, looking for the entry to remove\n for (i=0; i < AssetList.length; i++) {\n if( AssetList[i].AssetName === SelectedAsset ) {\n Asset2Delete = AssetList[i];\n // Remove the Asset json object to the AssetList array\n AssetList.splice(i,1);\n }\n }\n // Update the global array\n global.set(\"Assets\",AssetList);\n \n\n // To delete documents from the database, provide values for \n // _id and _rev and select the remove option in the Cloudant node. \n // You can pass these values in the msg object itself or as an object in the msg.payload.\n // Asset2Delete will contain :\n // {\"_id\":\"6c8e321192522d363c7d439993529cac\",\n // \"_rev\":\"1-1fbb9d32a306748e63e11f023cf3c4db\",\n // \"AssetName\":\"JWJWJW\",\n // \"key\":\"value\"}\n \n msg.payload = Asset2Delete;\n return msg;\n} else { \n return null;\n}", 1028 | "outputs":1, 1029 | "noerr":0, 1030 | "x":820, 1031 | "y":400, 1032 | "wires":[ 1033 | [ 1034 | "2476d89c.05d668", 1035 | "ac8c2b68.530f38" 1036 | ] 1037 | ] 1038 | }, 1039 | { 1040 | "id":"2476d89c.05d668", 1041 | "type":"debug", 1042 | "z":"34da0e1.ff218f2", 1043 | "name":"", 1044 | "active":true, 1045 | "console":"false", 1046 | "complete":"false", 1047 | "x":1070, 1048 | "y":440, 1049 | "wires":[ 1050 | 1051 | ] 1052 | }, 1053 | { 1054 | "id":"969aa18a.8ecda", 1055 | "type":"change", 1056 | "z":"34da0e1.ff218f2", 1057 | "name":"", 1058 | "rules":[ 1059 | { 1060 | "t":"set", 1061 | "p":"SelectedAsset", 1062 | "pt":"flow", 1063 | "to":"payload", 1064 | "tot":"msg" 1065 | } 1066 | ], 1067 | "action":"", 1068 | "property":"", 1069 | "from":"", 1070 | "to":"", 1071 | "reg":false, 1072 | "x":760, 1073 | "y":560, 1074 | "wires":[ 1075 | [ 1076 | "9ef0f658.9abb38" 1077 | ] 1078 | ] 1079 | }, 1080 | { 1081 | "id":"9ef0f658.9abb38", 1082 | "type":"ui_button", 1083 | "z":"34da0e1.ff218f2", 1084 | "name":"", 1085 | "group":"70399ba8.caa894", 1086 | "order":0, 1087 | "width":"8", 1088 | "height":"1", 1089 | "passthru":false, 1090 | "label":"Delete this Asset", 1091 | "color":"", 1092 | "bgcolor":"", 1093 | "icon":"", 1094 | "payload":"true", 1095 | "payloadType":"bool", 1096 | "topic":"", 1097 | "x":990, 1098 | "y":560, 1099 | "wires":[ 1100 | [ 1101 | "77fee4fd.0ac78c" 1102 | ] 1103 | ] 1104 | }, 1105 | { 1106 | "id":"81831f14.51168", 1107 | "type":"link in", 1108 | "z":"34da0e1.ff218f2", 1109 | "name":"", 1110 | "links":[ 1111 | "ac8c2b68.530f38" 1112 | ], 1113 | "x":95, 1114 | "y":560, 1115 | "wires":[ 1116 | [ 1117 | "a20016f5.5b3988" 1118 | ] 1119 | ] 1120 | }, 1121 | { 1122 | "id":"ac8c2b68.530f38", 1123 | "type":"link out", 1124 | "z":"34da0e1.ff218f2", 1125 | "name":"", 1126 | "links":[ 1127 | "81831f14.51168" 1128 | ], 1129 | "x":1005, 1130 | "y":260, 1131 | "wires":[ 1132 | 1133 | ] 1134 | }, 1135 | { 1136 | "id":"57bd90f6.0da6c", 1137 | "type":"debug", 1138 | "z":"34da0e1.ff218f2", 1139 | "name":"", 1140 | "active":false, 1141 | "console":"false", 1142 | "complete":"true", 1143 | "x":810, 1144 | "y":120, 1145 | "wires":[ 1146 | 1147 | ] 1148 | }, 1149 | { 1150 | "id":"c540cc7d.1cd3f", 1151 | "type":"inject", 1152 | "z":"34da0e1.ff218f2", 1153 | "name":"", 1154 | "topic":"", 1155 | "payload":"", 1156 | "payloadType":"date", 1157 | "repeat":"10", 1158 | "crontab":"", 1159 | "once":false, 1160 | "x":150, 1161 | "y":660, 1162 | "wires":[ 1163 | [ 1164 | "5aee8590.cc321c" 1165 | ] 1166 | ] 1167 | }, 1168 | { 1169 | "id":"5aee8590.cc321c", 1170 | "type":"function", 1171 | "z":"34da0e1.ff218f2", 1172 | "name":"Build an Inventory Table", 1173 | "func":"var AssetList = global.get(\"Assets\");\nif (typeof AssetList == 'undefined') {\n return null;\n}\n\nmsg.template=\"\";\n\nmsg.template=msg.template+\"Assets | Type | ID | Location |
---|---|---|---|
\" + AssetList[i].AssetName + \" | \" + AssetList[i].AssetType + \" | \" + AssetList[i].AssetID + \" | \" +AssetList[i].Location + \" |
Prepare your offers & wait!
\nRead the manual!
\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":150,"y":100,"wires":[[]]},{"id":"e6916fcf.63c67","type":"function","z":"b36b79fb.681da8","name":"getting satellite data","func":"var sat = msg.payload;\n\nmsg.payload = {\n name: sat.name,\n icon: \"satellite\",\n iconColor: \"blue\",\n lat: sat.position.lat, \n lon: sat.position.lon, \n}\nreturn msg;","outputs":1,"noerr":0,"x":140,"y":220,"wires":[["2997de66.39b212"]]},{"id":"2997de66.39b212","type":"worldmap","z":"b36b79fb.681da8","name":"","lat":"","lon":"","zoom":"2","layer":"OSM grey","cluster":"","maxage":"","usermenu":"hide","panit":"true","path":"","x":110,"y":260,"wires":[]},{"id":"dab56a2b.8cc2a8","type":"binance-get-all-prices","z":"b0c47343.b841f","name":"crypto","x":270,"y":460,"wires":[["5ac5dd98.58dad4","ee9a3381.b4656","ad1dd7e.1201128"]]},{"id":"e5f7022d.c5a88","type":"inject","z":"b0c47343.b841f","name":"","topic":"","payload":"","payloadType":"date","repeat":"300","crontab":"","once":true,"onceDelay":0.1,"x":130,"y":460,"wires":[["dab56a2b.8cc2a8"]]},{"id":"e592c3b5.bbd59","type":"ui_chart","z":"b0c47343.b841f","name":"prices","group":"c4b4d589.76ec78","order":6,"width":0,"height":0,"label":"Cryptocurrencies today (ETH, LTC etc.) to BTC","chartType":"line","legend":"true","xformat":"D/M","interpolate":"linear","nodata":"","dot":false,"ymin":"0","ymax":"0.05","removeOlder":"24","removeOlderPoints":"","removeOlderUnit":"86400","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"x":610,"y":460,"wires":[[],[]]},{"id":"5ac5dd98.58dad4","type":"change","z":"b0c47343.b841f","name":"ETHBTC","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.ETHBTC","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"ETHBTC","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":440,"y":440,"wires":[["e592c3b5.bbd59"]]},{"id":"ee9a3381.b4656","type":"change","z":"b0c47343.b841f","name":"LTCBTC","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.LTCBTC","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"LTCBTC","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":440,"y":480,"wires":[["e592c3b5.bbd59"]]},{"id":"ad1dd7e.1201128","type":"change","z":"b0c47343.b841f","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.BTCUSDT","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"BTCUSDT","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":520,"wires":[["7f2e4737.4c8988"]]},{"id":"7f2e4737.4c8988","type":"ui_chart","z":"b0c47343.b841f","name":"","group":"c4b4d589.76ec78","order":5,"width":0,"height":0,"label":"BTC to USD chart","chartType":"line","legend":"true","xformat":"Y-M-D","interpolate":"linear","nodata":"","dot":true,"ymin":"3000","ymax":"10000","removeOlder":"100","removeOlderPoints":"","removeOlderUnit":"604800","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"x":650,"y":520,"wires":[[],[]]},{"id":"63de302c.df42d","type":"http request","z":"b36b79fb.681da8","name":"addnewlithopian","method":"POST","ret":"obj","url":"http://anonette.net:3000/api/Lithopian","tls":"","x":380,"y":380,"wires":[[]]},{"id":"5e216a86.440684","type":"ui_form","z":"b36b79fb.681da8","name":"","label":"Become a Lithopian:","group":"60e96444.be8e4c","order":3,"width":"0","height":"0","options":[{"label":"What is your name?","value":"name","type":"text","required":true}],"formValue":{"name":""},"payload":"","submit":"submit","cancel":"cancel","topic":"","x":130,"y":380,"wires":[["63de302c.df42d"]]},{"id":"30187a1c.9e6436","type":"ui_form","z":"b36b79fb.681da8","name":"","label":"Offer a partnership or marriage:","group":"60e96444.be8e4c","order":4,"width":"0","height":"0","options":[{"label":"You need an original name:","value":"name","type":"text","required":true},{"label":"For how long?","value":"period","type":"text","required":true}],"formValue":{"name":"","period":""},"payload":"","submit":"submit","cancel":"cancel","topic":"","x":170,"y":420,"wires":[["53b26d6.fec7894"]]},{"id":"53b26d6.fec7894","type":"http request","z":"b36b79fb.681da8","name":"addnewpartnership","method":"POST","ret":"obj","url":"http://anonette.net:3000/api/LithopiaMarriage","tls":"","x":410,"y":420,"wires":[[]]},{"id":"535f8acd.a63994","type":"ui_form","z":"b36b79fb.681da8","name":"","label":"Register a property:","group":"60e96444.be8e4c","order":5,"width":"0","height":"0","options":[{"label":"Location /name","value":"name","type":"text","required":true},{"label":"Owner","value":"owner","type":"text","required":true}],"formValue":{"name":"","owner":""},"payload":"","submit":"submit","cancel":"cancel","topic":"","x":130,"y":460,"wires":[["d32f4b7.9fb41b8"]]},{"id":"d32f4b7.9fb41b8","type":"http request","z":"b36b79fb.681da8","name":"addnewplace","method":"POST","ret":"obj","url":"http://anonette.net:3000/api/LithopiaPlace","tls":"","x":370,"y":460,"wires":[["a03b5bd5.4e8518"]]},{"id":"c97e232e.5d66a","type":"ui_template","z":"2c510c19.115f44","group":"695e648e.ad075c","name":"Time and Temp","order":1,"width":"0","height":"0","format":"\n\n\n \n{{row}} | \n
{{row}} | \n
{{row}} | \n
Become a Lithopian
Buying & selling property
Marry & partner
\n\tSatellite Lithoscopes
\n\t\tconcept: Denisa Kera and Petr Šourek
\nscript: Petr Šourek
\ndesigner: Eva Holá
\ndirector of photography: Jan Hrdý, Michal Krásl
\neditor: Miloslav Holman
\ninstallation and 3D print: Virtuoso by Swetja
\nblockchain and Node RED: Denisa Kera and Yair Reshef
\nsatellite image processing: Mateusz Kraiński
\nmusic: Swetja, Ivan Zelenka
\nsound: Libor Ščerba, Swetja
\nactors: Dan Dittrich, Eva Čechová, Dan Šváb, Barbara Humel, Justin Svoboda, Radim Klásek, Vojtěch Bárta, Zdeněk Žatečka, Olga Vincencová, Alice Šourková, Ivana Runštuková, Marie Johnson\n
\ntechnician: Roman Trochta
\nproducer: Petra Brodská
\ndirector: Petr Šourek
\nLithopia was supported by Czech Ministry of Culture & Marie Curie Horizon2020 fellowship
\n\t","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":353.0173645019531,"y":606.0104370117188,"wires":[[]]},{"id":"da1a5324.00899","type":"comment","z":"b36b79fb.681da8","name":"credits","info":"","x":410,"y":560,"wires":[]},{"id":"1129d49d.a89a7b","type":"ui_text","z":"2c510c19.115f44","group":"695e648e.ad075c","order":2,"width":"8","height":"3","name":"Weather announcement ","label":"","format":"{{msg.payload || titlecase}}","layout":"col-center","x":630,"y":120,"wires":[]},{"id":"a4eb5ec7.e3934","type":"inject","z":"f61baa36.7abee8","name":"","topic":"","payload":"","payloadType":"date","repeat":"2","crontab":"","once":true,"onceDelay":0.1,"x":170,"y":80,"wires":[[]]},{"id":"e79c7114.dfd09","type":"inject","z":"f61baa36.7abee8","name":"","topic":"","payload":"","payloadType":"date","repeat":"3","crontab":"","once":true,"onceDelay":0.1,"x":430,"y":40,"wires":[[]]},{"id":"f843b5ad.9eb4f8","type":"inject","z":"f61baa36.7abee8","name":"","topic":"","payload":"","payloadType":"date","repeat":"5","crontab":"","once":true,"onceDelay":0.1,"x":750,"y":40,"wires":[[]]},{"id":"46b919df.aa79d8","type":"change","z":"f61baa36.7abee8","name":"Present Lithopians:","rules":[{"t":"set","p":"payload","pt":"msg","to":"$.payload.name","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":190,"y":300,"wires":[["436d65aa.03f59c"]]},{"id":"eb21bbb1.bd0118","type":"function","z":"f61baa36.7abee8","name":"sort","func":"arr = msg.payload;\narr.sort(function(a, b){\n //compare two values\n if(a.name.toLowerCase() < b.name.toLowerCase()) return -1;\n if(a.name.toLowerCase() > b.name.toLowerCase()) return 1;\n return 0;\n})\nreturn msg;","outputs":1,"noerr":0,"x":170,"y":260,"wires":[["46b919df.aa79d8"]]},{"id":"fe3c51ca.64012","type":"function","z":"f61baa36.7abee8","name":"sort","func":"arr = msg.payload;\narr.sort(function(a, b){\n //compare two values\n if(a.name.toLowerCase() < b.name.toLowerCase()) return -1;\n if(a.name.toLowerCase() > b.name.toLowerCase()) return 1;\n return 0;\n})\nreturn msg;","outputs":1,"noerr":0,"x":450,"y":220,"wires":[["2a09394d.67b526"]]},{"id":"29cb1e45.059162","type":"function","z":"f61baa36.7abee8","name":"sort","func":"arr = msg.payload;\narr.sort(function(a, b){\n //compare two values\n if(a.name.toLowerCase() < b.name.toLowerCase()) return -1;\n if(a.name.toLowerCase() > b.name.toLowerCase()) return 1;\n return 0;\n})\nreturn msg;","outputs":1,"noerr":0,"x":730,"y":220,"wires":[["b4cf3631.0bfa98"]]},{"id":"a03b5bd5.4e8518","type":"debug","z":"b36b79fb.681da8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":550,"y":500,"wires":[]}] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LITHOPIA/LITHOPY project 2 |  3 | 4 | 1. [ Description. ](#desc) 5 | 2. [ Prototypes. ](#usage) 6 | 3. [ Dashboard. ](#dash) 7 | 4. [ Satellite scanner. ](#scanner) 8 | 5. [ Blockchain contracts. ](#hype) 9 | 5. [ Workshop. ](#workshop) 10 | 7. [ Credits. ](#credit) 11 | 12 | 13 | 14 | ## Description 15 | The design fiction village Lithopia explores the **extreme scenarios of future data and blockchain governance, but also resistance** by using Hyperledger Composer and Fabric to deploy smart contracts triggered by satellite and drone data. The villagers in this fictional place use satellite and drone data to govern their affairs in an extremely transparent, but also aesthetic manner. They live their lives in front of the all-seeing technical “eyes” of God and Providence, such as Sentinel 2A and B Copernicus satellites, and public drones used as notaries. **Special long gestures, large LiCoins, but also acts of covering spaces in land-art, Christo manner at strictly defined times trigger the transactions on the Hyperledger blockchain** managed over the Node RED dashboard. 16 | 17 |  18 | 19 | Lithopia has a **sister city on the Micronesian island of Yap** that uses similar large stone coins to preserve their oral memory of ownership, marriages, and important events. Lithopians deploy their **large 3D printed LiCoins visible to satellites and drones** in various rituals and transactions that trigger the Hyperledger smart contracts. LiCoins are similar in size to the famous Rai stones, but they also **contain lithium in the plastic filaments** used to 3D print them. The LiCoins are moved around to indicate important transactions and contracts on the blockchain. **In their plastic, they mix and hide the illegally obtained lithium from the old mines** to reclaim the ownership of their natural resources. **Hyperledger blockchain for Lithopians is a form of oral culture timestamping all transactions and emphasizing genealogy over exchanges and stewardship over ownership.** 20 | 21 |  22 | 23 | This aesthetic and at times ironic, blockchain and satellite "lithopia" is **inspired by stories from the mining region of Cinovec** about facades of family houses covered in lithium powder. In the 1980s, the former miners had regarded lithium’s glittering powder as a junk material freely available for the exterior decoration of houses. During the 2017 Czech Republic elections, a Lithium craze unleashed, and the winning party scored extra 10 percentage for promising a lithium paradise for all without ever mining even a single grain of lithium ore. The semi-legal facades of the miners family houses suddenly became an unlikely form of fortune, an unintended form of resistance in the speculative lithium wars between the political fractions and corrupt business interests. We intepret this as a start of the **Czech lithium punk genre** and a model of management of resources and emergent technologies. 24 | 25 | To respond to the **populist promises and ongoing speculations in Lithium, but also similar political projects, such as the calls for national blockchain cryptocurrency**, the Lithopy team continues in the work of these villagers and their lithium punk genre. We support early and extreme forms of adoption of emergent technologies that reproduce the “facade” effect or a hack and bring unintended forms of resistance as alternative to the speculative and extractive powers to be. 26 | 27 | **In Lithopy, all sorts of promises and three sorts of mining come together: mineral extraction, big data mining and blockchain mining** to explore the Czech lithium punk fantasy. The ideal citizen of Lithopia follows in the steps of the good soldier Švejk and follows ad absurdum all emergent technological protocols to embrace all data structures and alghoritms. The multiscreen movie that accompanies the blockchcain, LiCoins and Node RED prototypes advertises a Sunny Day in Lithopy: _”A Sunny Day in Lithopy 28 | 29 | 30 | _It is a sunny day in Lithopy, a quackerish-hackerish community given to transparency, justice & accountability. 31 | 32 | _In Lithopy, sunny days are made for transactions. No clouds prevent satellites from keeping an eye on you. Satellites track your every move. A decentralized, distributed and public digital ledger of blockchain records every transaction. 33 | 34 | _On sunny days, contracts are made. Assets change hands. People make payments and friends, marry and divorce. 35 | 36 | _Lithopians use coins big enough to catch the eye of a satellite. They shake hands for minutes. When you travel to Lithopy on a sunny day, you never pull your hand back before a Lithopian unless you are less serious about business. 37 | 38 | _In Lithopy, hugs are big and kisses are many to make sure satellites recognize and the blockchain records their affection, love & friendship. 39 | 40 | _There is no excess, no frivolity in their actions. Their all-or-nothing gestures, their fits of laughter, their floods of tears are in fact all well measured. 41 | 42 | _You may notice the furtive looks they cast toward the sky. Whatever Lithopians do on sunny days, 43 | they do before the face of satellites. 44 | 45 | _In Lithopy, all social contact is a smart contract.“` 46 | 47 | 48 | ## Prototypes 49 | The project comprises from **several prototypes of smart contracts, documentation of their testing, and a design fiction movie and installation:** 50 | 51 | - Multi-screen installation and movie 52 | - BNA (business network definition) and several JS transactions (smart contracts) deployed on the Hyperledger Fabric as an art/design fiction 53 | [CTO model](https://github.com/anonette/lithopia/blob/master/org.lithopia.basic.cto) 54 | [JS logic](https://github.com/anonette/lithopia/blob/master/logic.js) 55 | - Lithopia satellite scanner (developed by Mateusz Kraiński) 56 | [API](http://anonette.net:8000/summary/) 57 | - Node RED dashboard enabling interaction with the smart contracts and other services in Lithopia 58 | [Node RED JSON](https://github.com/anonette/lithopia/blob/master/NodeREDMarch2019.json) 59 | - Proposal for a Lithopia streaming packets service (pay per packet) on the blockchain, where IP packets of fragmented 188-byte streaming packets (Packetized Elementary Stream - PES) are monetized (just as all other data in the future). Lithopians measure their time in packets of data to create a “blockchain-ed” paradise. Packets on a ledger fulfill the **old dream of a divine providence supervising and managing every occurrence and every creature. Blockchain technologies perform what Christianity and Judaism imagined as a continual creation, sometimes described as ( השגחה פרטית Hashgochoh Protis), what Descartes in his “Meditation III” describes as a God that conserves the world by continuously creating it, and what Leibnizian imagines as a pre-established harmony. To stream and timestamp packets on the ledger is to design an all-seeing, all present and perpetually creating God. The timestamps and blocks of all the transactions and activities in the life of the Lithopians is a form of divine providence, but also a magical ritual of protection via God’s eyes. 60 | 61 | 62 | ## Lithopia Dashboard in Node-RED 63 | [Link](http://anonette.net:1780/ui/#/0) 64 |  65 | This is a design fiction dashboard for Lithopians used to follow satellites (and drones) in order to transact over Hyperledger Composer/Fabric based smart contracts, to follow the LiCoin cryptocurrency and its relations to the Lithium sentiments and markets. 66 | In the [lithopiaFeb22.json](https://github.com/anonette/lithopia/blob/master/lithopiaFeb22.json) file there are **three columns**: 67 | 68 | ### DATE, TIME & WEATHER 69 | **Basic info on Lithopia** 70 | 1. **Retro LCD display:** courtesy of Peter Scargill ([link](https://tech.scargill.net/lcd-display-for-node-red/)) 71 | 2. **Openweather widget**: courtesy of FRED ([link](http://developers.sensetecnic.com/article/a-node-red-flow-to-monitor-the-weather/)). 72 | - to which I added text-to-speech node for weather announcement (disabled for the installation, present in JSON). 73 | 3. **Openweather icon**: generating and showing html objects IMG based on this [flow](https://flows.nodered.org/flow/2f1aaf0635f9bf23207152682323240a). 74 | - Trick is to create the payload with the tags in a function-node and then in the template-node just represent it with `` 75 | 3. **Lithopia**: how to trigger various blockchain transactions and future plans. 76 | 77 | ### WHO'S WHO 78 | **Basic info on Lithopians, their properties, marriages and partnerships** 79 | 1. **Texfields on Lithopians, property, marriages Hyperlegder GET commands**: see http://anonette.net:3000/explorer 80 | - we use http-node with get command to query the REST-API composer contract with switch-node and [JSONATA](https://docs.jsonata.org/). 81 | - to get the requested data out of complex JSON, see [string functions](https://docs.jsonata.org/string-functions.html) and handeling of [expressions](https://console.bluemix.net/docs/services/IoT/GA_information_management/mapping_expression_language.html#mapping_expression ). 82 | - To test also try the [online parser](http://try.jsonata.org/). 83 | - another [Useful resource](https://youtu.be/PbEoHxFOdmE?t=600) to learn how to work with SWITCH - courtesy Steve Cope 84 | 85 | ### BLOCKCHAIN TRANSACTIONS 86 | **Info on the Sentinel2A satellite position, view on Earth from ISS, forms to blockchain transactions on how to become Lithopian, register a property or parnership** 87 | 1. **Tracking satellites on a map:** important to get the TLE data for the satellite nodes from [https://www.celestrak.com/NORAD/elements/supplemental/](https://www.celestrak.com/NORAD/elements/supplemental/) 88 | then use instructions from [node-red-satellites node](https://flows.nodered.org/node/node-red-contrib-satellites) and [world-map-node](https://flows.nodered.org/node/node-red-contrib-web-worldmap). 89 | 90 | 2. **ISS real time video of Earth**: just video embedded in node-red templat (disabled for the installation, but present in the JSON). 91 | 92 | 3. **Hyperleder Composer REST API POST commands**: allowing participants to register on the blockchain their names, property and type of partnerships. The challenging part here was to figure out how to extract values from the JSON object created by the hyperldger REST API in Basic info part, here is the example of such object: `[{"$class":"org.lithopia.basic.LithopiaPlace","name":"Balcony","flagColors":[],"requestSources":[],"datasetIds":[],"owner":"Yair"},{"$class":"org.lithopia.basic.LithopiaPlace","name":"Balcony2","flagColors":[],"requestSources":[],"datasetIds":[],"owner":"Yair"}]` 93 | 94 | We need just this part `payload.(name & ' owned by ' & owner)` to get `["Balcony owned by Yair","Balcony2 owned by Yair"]`that appears in the text-node (after csv-node). 95 | 96 | 4.**Credits, Lithopia team**: 97 | First inhabitants ;-) 98 | 99 | ### MARKETS & SENTIMENTS 100 | **Sentiment analysis of Twitter feeds on Lithium and cryptocurrency exchange for Lithopians** 101 | 102 | 1. **Twitter sentiment analysis:** Combines examples from [Jelastic](https://jelastic.com/blog/node-red-cloud-hosting-for-tweeter-feed-analysis/) and [IBM](https://www.ibm.com/blogs/bluemix/2015/11/analyze-tweets-in-30-minutes/). Excellent source is also [Luc Bors blog](http://lucbors.blogspot.com/2018/09/how-to-use-node-red-to-interact-with.html). For the node-red-gauge UI telling when to buy or sell LiCoins based on the sentimens, courtesy of [Tim Minter](https://flows.nodered.org/flow/3fa024a69e24d94b4985934ce931aa7d) 103 | 104 | 2. **Cryptocurrency charts**: Followed Node RED [ programming guide](http://noderedguide.com/cryptocurrencies-and-node-red/) on Binance node, needs improvement. 105 | 106 | 107 | ## Lithopia scanner 108 | Application for the Lithopia project, which extracts latest Sentinel-2 image for a given area and analyses it for a presence of a visual marker. If such marker is detected, the application is triggerring a blockchain contract. [More](https://github.com/mt-krainski/lithopia_scanner) 109 | 110 | 111 | ## Hyperledger Composer BNA and transactions (JS) deployed on Fabric 112 | ### BNA and JS files 113 | Lithopia "business network" comprises from lithopians and their assets (properties, partnerships, LiCoins) transacted based on data from drones and satellites that are triggered by gestures Christo style coverings of places and large objects (LiCoin Yap). 114 | Possible transactions: change ownership of property, become part of a parnership or marriage (that can involve more parties) for a defined period of time (inspired by [SmartVows project](https://smartvows.com/) ). 115 | **CTO file defining the network:** 116 | ``` 117 | /* 118 | /** 119 | * Sample business network definition. 120 | */ 121 | namespace org.lithopia.basic 122 | /** 123 | * Location in Lithopia visible to satellites owned by a Lithopian 124 | */ 125 | asset LithopiaPlace identified by name { 126 | o String name 127 | o Flagcolor[] flagColors optional 128 | o Flagcolor[] requestSources optional 129 | o Flagcolor[] datasetIds optional 130 | o String owner 131 | } 132 | /** 133 | * An abstract transaction that is related to a LithopiaPlace 134 | */ 135 | abstract transaction LithopiaPlaceTransaction { 136 | --> LithopiaPlace place 137 | } 138 | /** 139 | * A satellite reading for a GPS location identifying a color 140 | */ 141 | transaction Flagcolor extends LithopiaPlaceTransaction { 142 | o String flagColor 143 | o String requestSource 144 | o String datasetId 145 | } 146 | /** 147 | * Changing the owner of the place based on the color identified by a satellite 148 | */ 149 | transaction LithopiaPlaceSold extends LithopiaPlaceTransaction { 150 | -->Lithopian newOwner 151 | } 152 | /** 153 | * Announcing a change of ownership of a place 154 | */ 155 | event LithopiaPlaceTransactions { 156 | --> LithopiaPlace place 157 | o String newOwner 158 | } 159 | /** 160 | * Marriage contract in Lithopia 161 | */ 162 | asset LithopiaMarriage identified by name { 163 | o String name 164 | o String period 165 | o Partners[] partners optional 166 | } 167 | 168 | /** 169 | * Partnering, friendship and marriages in Lithopia 170 | */ 171 | abstract transaction LithopiaPartnering { 172 | -->LithopiaMarriage contract 173 | } 174 | 175 | /** 176 | * Lithopians entering some contract in pairs or groups 177 | */ 178 | transaction Partners extends LithopiaPartnering { 179 | o String[] newPartner 180 | } 181 | /** 182 | * Announcing a marriage between individuals in Lithopia 183 | */ 184 | event NewPartnershipinLithopia { 185 | -->LithopiaMarriage contract 186 | o Partners[] partners 187 | } 188 | /** 189 | * Marrying someone or few people in Lithopia 190 | */ 191 | transaction Marriage extends LithopiaPartnering { 192 | -->Lithopian partnerMarriage 193 | } 194 | /** 195 | * Lithopian living in Lithopia 196 | */ 197 | participant Lithopian identified by name { 198 | o String name 199 | o String status optional 200 | } 201 | ``` 202 | **JS logic file** 203 | ``` 204 | /* global getParticipantRegistry getAssetRegistry getFactory */ 205 | /** 206 | * A satellite color reading has been received 207 | * @param {org.lithopia.basic.Flagcolor} flagcolor - the Flagcolor transaction 208 | * @transaction 209 | */ 210 | async function flagColor(flagcolor) { // eslint-disable-line no-unused-vars 211 | const place = flagcolor.place; 212 | //console.log('Checking the flag color ' + flagcolor.flagColor + ' to place ' + flagcolor.$name); 213 | if (place.flagColors) { 214 | place.flagColors.unshift(flagcolor); 215 | place.requestSources.unshift(flagcolor); 216 | place.datasetIds.unshift(flagcolor); 217 | } else { 218 | place.flagColors = [flagcolor]; 219 | place.requestSources = [flagcolor]; 220 | place.datasetIds = [flagcolor]; 221 | } 222 | // add the satelliteReading to the Lithopian Place 223 | const placeRegistry = await getAssetRegistry('org.lithopia.basic.LithopiaPlace'); 224 | await placeRegistry.update(place); 225 | } 226 | /** 227 | * LithopiaPlaceSold transaction triggered by satellite data changing the owner of a property 228 | * @param {org.lithopia.basic.LithopiaPlaceSold} lithopiaPlaceSold - the LithopianPlaceSold transaction 229 | * @transaction 230 | */ 231 | async function selling(lithopiaPlaceSold) { // eslint-disable-line no-unused-vars 232 | const place = lithopiaPlaceSold.place; 233 | const flag = place.flagColors[0].flagColor; 234 | // if thecolor didn't change, the owner remains 235 | if (flag === 'red'){ 236 | place.owner = lithopiaPlaceSold.newOwner.name; 237 | } 238 | else{ 239 | place.owner = lithopiaPlaceSold.place.owner; 240 | } 241 | // update the newOwner 242 | const assetRegistry = await getAssetRegistry('org.lithopia.basic.LithopiaPlace'); 243 | await assetRegistry.update(place); 244 | // emit who is the old or new owner 245 | let placeEvent = getFactory().newEvent('org.lithopia.basic', 'LithopiaPlaceTransactions'); 246 | placeEvent.place = lithopiaPlaceSold.place; 247 | placeEvent.newOwner = place.owner; 248 | emit(placeEvent); 249 | } 250 | /** 251 | * Lithopians entering partnership contract 252 | * @param {org.lithopia.basic.Partners} partnering - the Partners transaction 253 | * @transaction 254 | */ 255 | async function partnering(partnering) { // eslint-disable-line no-unused-vars 256 | const contract = partnering.contract; 257 | if (contract.partners) { 258 | contract.partners.push(partnering); 259 | } 260 | else{ 261 | contract.partners = [partnering]; 262 | } 263 | // add the partners to the contract 264 | const placeRegistry = await getAssetRegistry('org.lithopia.basic.LithopiaMarriage'); 265 | await placeRegistry.update(contract); 266 | // emit the new partnership in Lithopia 267 | let partnerEvent = getFactory().newEvent('org.lithopia.basic', 'NewPartnershipinLithopia'); 268 | partnerEvent.contract = partnering.contract; 269 | partnerEvent.partners = partnering.contract.partners; 270 | emit(partnerEvent); 271 | } 272 | /** 273 | * LithopiaMarriage transaction changng the status of some partners 274 | * @param {org.lithopia.basic.Marriage} marrying - the LithopianPlaceSold transaction 275 | * @transaction 276 | */ 277 | async function married(marrying) { // eslint-disable-line no-unused-vars 278 | const partner = marrying.partnerMarriage; 279 | const partners = marrying.contract.partners; 280 | //console.log(Object.values(partners)); 281 | //console.log(partners[0].newPartner); 282 | //console.log(partner.name); 283 | //console.log(partner); 284 | let i; 285 | for (i=0; i < partners.length; i++){ 286 | if (partners[i].newPartner.includes(partner.name)){ 287 | partner.status = "Married"; 288 | } 289 | else 290 | { 291 | partner.status = "Single"; 292 | } 293 | } 294 | // change the status of the partnership based on enum 295 | const participantRegistry = await getParticipantRegistry('org.lithopia.basic.Lithopian'); 296 | await participantRegistry.update(partner); 297 | } 298 | ``` 299 | 300 | ### Deployment of Fabirc 301 | #### After Restart 302 | ```bash 303 | cd ~/fabric-dev-servers 304 | 305 | #kill node-red 306 | pm2 stop node-red 307 | pm2 stop ~/runRest.sh 308 | 309 | ./startFabric.sh 310 | 311 | composer network install --card PeerAdmin@hlfv1 --archiveFile ~/fabric-dev-servers/lithopia/lithopia@0.0.1.bna 312 | 313 | composer network start --networkName lithopia --networkVersion 0.0.1 --networkAdmin admin --networkAdminEnrollSecret adminpw --card PeerAdmin@hlfv1 --file networkadmin.card 314 | 315 | #check you have the peerAdminCards 316 | composer card list 317 | 318 | #to run in terminal 319 | composer-rest-server -c admin@lithopia -n never -u true -w true 320 | #or to run in background 321 | pm2 start ~/runRest.sh 322 | 323 | #restart node-red 324 | pm2 start node-red 325 | ``` 326 | 327 | #### HTTPS 328 | check 329 | ``` 330 | /etc/letsencrypt/renewal-hooks/deploy/renewal_success 331 | ``` 332 | 333 | ###errr 334 | if 335 | ``` 336 | dk@anonette:~/fabric-dev-servers$ composer network list -c admin@lithopia 337 | ✖ List business network from card admin@lithopia 338 | Error trying to ping. Error: 2 UNKNOWN: identity expired 339 | Error: Error trying to ping. Error: 2 UNKNOWN: identity expired 340 | Command failed 341 | ``` 342 | do 343 | ``` 344 | composer card delete 345 | composer card import --file networkadmin.card 346 | composer network ping --card admin@lithopia 347 | #then continue to test with 348 | composer-rest-server -c admin@lithopia -n never -u true -w true 349 | #and deploy with 350 | pm2 start runRest 351 | ``` 352 | #### CLEAN 353 | (following official uninstall [guide](https://hyperledger.github.io/composer/latest/installing/uninstall-dev-env.html) ) 354 | 355 | ``` 356 | npm uninstall -g composer-cli composer-rest-server generator-hyperledger-composer 357 | rm -rf ~/.composer 358 | ``` 359 | stop and teardown the docker setup 360 | ``` 361 | export FABRIC_VERSION=hlfv12 362 | ~/fabric-dev-servers/stopFabric.sh 363 | ~/fabric-dev-servers/teardownFabric.sh 364 | ``` 365 | clear tools and script folder 366 | `rm -rf ~/fabric-dev-servers` 367 | 368 | #### START 369 | from the [docs](https://hyperledger.github.io/composer/latest/tutorials/developer-tutorial.html) 370 | 371 | 0. make sure we use the right node version 372 | ``` 373 | nvm install v8 374 | nvm use v8 375 | ``` 376 | 1. install node packages, CLI tools, rest server and generators 377 | ``` 378 | npm install -g composer-cli@0.20 composer-rest-server@0.20 generator-hyperledger-composer@0.20 yo 379 | ``` 380 | 381 | 2. Hyperledger Fabric runtime to deploy 382 | ``` 383 | #Create a directory and let's name it fabric-tools 384 | mkdir ~/fabric-tools && cd ~/fabric-tools 385 | ``` 386 | 387 | 3. inside fabric-tools: 388 | ``` 389 | curl -O https://raw.githubusercontent.com/hyperledger/composer-tools/master/packages/fabric-dev-servers/fabric-dev-servers.zip 390 | unzip fabric-dev-servers.zip 391 | ``` 392 | 393 | 4. run a local Hyperledger Fabric runtime. 394 | ``` 395 | ./downloadFabric.sh 396 | ./startFabric.sh 397 | ./createPeerAdminCard.sh 398 | ``` 399 | 400 | 5. then create a businesse network over YO 401 | `yo hyperledger-composer:businessnetwork` 402 | 403 | 6. yo hyperledger-composer:businessnetwork 404 | `composer archive create -t dir -n .` 405 | 406 | 7. install the composer runtime with: 407 | `composer network install --card PeerAdmin@hlfv1 --archiveFile lithopia@0.0.1.bna` 408 | 409 | 8. deploy the business network: 410 | `composer network start --networkName lithopia --networkVersion 0.0.1 --networkAdmin admin --networkAdminEnrollSecret adminpw --card PeerAdmin@hlfv1 --file networkadmin.card` 411 | 412 | 9. import the network administrator card into the network: 413 | `composer card import --file networkadmin.card ` 414 | 415 | 10. composer-rest-server 416 | `composer-rest-server -c admin@lithopia -n never -u true -w true` 417 | 418 | #### RESET 419 | ``` 420 | composer network reset -c admin@example-network 421 | #change the files in the model & lib of lithopia 422 | #change the version of package.json 423 | composer archive create -t dir -n . 424 | composer network upgrade -c PeerAdmin@hlfv1 -n lithopia -V 0.0.1 425 | composer network install -c PeerAdmin@hlfv1 -n lithopia -V 0.0.1 426 | ``` 427 | #### PREREQ 428 | from the [docs](https://hyperledger.github.io/composer/latest/installing/installing-prereqs.html) 429 | ``` 430 | curl -O https://hyperledger.github.io/composer/latest/prereqs-ubuntu.sh 431 | chmod u+x prereqs-ubuntu.sh 432 | ./prereqs-ubuntu.sh 433 | ``` 434 | 435 | this bit us before, cuoldnt start the rest server because of gPRC node module issues 436 | #### rebuild grpc 437 | `cd ~/.nvm//versions/node/v8.14.1/lib/node_modules/composer-rest-server` 438 | `npm rebuild` 439 | 440 | #### redeploy 441 | `./tearDownFabric` 442 | 443 | 1. remove preconfigurations previous cards and identities 444 | `rm -fr ~/.composer` 445 | 446 | 2. re-create the admin card 447 | `./createPeerAdminCard.sh` 448 | 449 | 3. if using the same bna, no need to yo it again 450 | ``` 451 | composer network install --card PeerAdmin@hlfv1 --archiveFile ~/fabric-dev-servers/lithopia/lithopia@0.0.1.bna 452 | ``` 453 | 454 | 4. re-start network 455 | `composer network start --networkName lithopia --networkVersion 0.0.1 --networkAdmin admin --networkAdminEnrollSecret adminpw --card PeerAdmin@hlfv1 --file networkadmin.card` 456 | 457 | 5. start rest 458 | `composer-rest-server -c admin@lithopia -n never -u true -w true` 459 | 460 | #### LINKS 461 | 462 | * [How to build a blockchain network using Hyperledger Fabric and Composer](https://medium.freecodecamp.org/how-to-build-a-blockchain-network-using-hyperledger-fabric-and-composer-e06644ff801d) - A tutorial for new blockchain developers 463 | * [REST-server wiki](https://github.com/hyperledger/composer/wiki/REST-Server) 464 | * [upgrading-bna](https://hyperledger.github.io/composer/v0.19/business-network/upgrading-bna) 465 | * [development-tools](https://hyperledger.github.io/composer/latest/installing/development-tools.html) 466 | * [update-dev-en](https://hyperledger.github.io/composer/latest/installing/update-dev-env.html) 467 | 468 | 469 | ## Workshop 470 | 471 | While the first decade of distributed ledger technologies (DLTs) was mainly about transactions between individuals (Bitcoin and numerous crypto-alt-currency projects), we are entering a phase which expands transactions into contracts and involves new actors. The new generation of DLTs emphasize these interactions with corporate and institutional actors through self-executing “smart contracts” (Ethereum, Ripple and Corda platforms and protocols) along “machine-to-machine” transactions involving IoTs using ledger technologies (IOTA) and soon probably AI. The increasing complexity of transactions and interactions over DLTs is leading to attempts to consolidate platforms (Enterprise Ethereum Alliance, Linux Hyperledger Fabric 1.0) and enable interoperability. The original, libertarian and crypto-anarchist emphasis on privacy and anonymity of the individuals and their transactions (as stated in the original white paper) is transforming into a pragmatic search for convergences of DLTs with existing social, but also technological infrastructures (IoTs, institutions, banks, supply chains). 472 | 473 | How to engage with the promises and threats of blockchain future infrastructure, algo and data governance? 474 | 475 | How to respond to the technological, ethical, social and legal opportunities and limits of the so-called smart contracts that automatize all decision making processes? 476 | 477 | What are the consequences of timestamping all our data to ensure the authenticity of media in an age of rampant simulations and fakes 478 | 479 | How to combine existing institutions with this new infrastructure? 480 | 481 | On which level to regulate these convergences? 482 | 483 | * [How to run a workshop on stakeholder involvement in blockchain futures](https://docs.google.com/document/d/182Ecyipv7Aytc2i7a2DK1kxtNB3J_RsW3PkQfA7ez5c/edit#) - Summary of tools and activities for the workshop with methodological overview 484 | * [Forms for the participants](https://docs.google.com/document/d/11mbW3AjeUv3XzmOXi-A6rmHq17ruip5Te2ZQ9WQ6rac/edit) - Modular forms used by participants/stakeholders in the workshop 485 | [Form](https://docs.google.com/document/d/1zRIaxUZkdVLvwp5iwqMSl2d-QH_WZ-F6Hyhsd39CPA4/edit) - New form for a shorter workshop without stakeholder roles (recommended) 486 | * [Stakeholders cards used by the participants for the simulation game](https://docs.google.com/document/d/1vCqB2JdEchHp9ddEYwUvh3Z0dQdpHCF1YJC7t91zZLU/edit#) -To give one to each group or to an individual (depending on the size of the workshop) 487 | * [Basic vocabulary of terms](https://docs.google.com/document/d/1yHcElO57kkqf6I6ATkSFkLfS7QQfCNO96BfpfFkp-iY/edit#) - To give one copy to each participant 488 | * [Issue cards, summary of policy and technology issues](https://docs.google.com/document/d/1zrDojr8z9UzD0jYacMxvlZ4N_dijGdf8AlL3TwQ7MaE/edit#) - To give the whole set to all participants so they pick and choose one issue (you can also assign the issues randomly) 489 | * Examples of adverserial (evil)code to play with in the workshop: 490 | 491 | [CTO model](https://github.com/anonette/lithopia/blob/master/LithopiaWorkshop.cto) 492 | [JS logic](https://github.com/anonette/lithopia/blob/master/LithopiaWorkshop.js) 493 | 494 | 495 | 496 | ## Credits 497 | **Lithopy:**Prepare your offers & wait!
\nRead the manual!
\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":150,"y":100,"wires":[[]]},{"id":"e6916fcf.63c67","type":"function","z":"b36b79fb.681da8","name":"getting satellite data","func":"var sat = msg.payload;\n\nmsg.payload = {\n name: sat.name,\n icon: \"satellite\",\n iconColor: \"blue\",\n lat: sat.position.lat, \n lon: sat.position.lon, \n}\nreturn msg;","outputs":1,"noerr":0,"x":140,"y":220,"wires":[["2997de66.39b212"]]},{"id":"2997de66.39b212","type":"worldmap","z":"b36b79fb.681da8","name":"","lat":"","lon":"","zoom":"2","layer":"OSM grey","cluster":"","maxage":"","usermenu":"hide","panit":"true","path":"","x":110,"y":260,"wires":[]},{"id":"dab56a2b.8cc2a8","type":"binance-get-all-prices","z":"b0c47343.b841f","name":"crypto","x":270,"y":460,"wires":[["5ac5dd98.58dad4","ee9a3381.b4656","ad1dd7e.1201128"]]},{"id":"e5f7022d.c5a88","type":"inject","z":"b0c47343.b841f","name":"","topic":"","payload":"","payloadType":"date","repeat":"300","crontab":"","once":true,"onceDelay":0.1,"x":130,"y":460,"wires":[["dab56a2b.8cc2a8"]]},{"id":"e592c3b5.bbd59","type":"ui_chart","z":"b0c47343.b841f","name":"prices","group":"c4b4d589.76ec78","order":6,"width":0,"height":0,"label":"Cryptocurrencies today (ETH, LTC etc.) to BTC","chartType":"line","legend":"true","xformat":"D/M","interpolate":"linear","nodata":"","dot":false,"ymin":"0","ymax":"0.05","removeOlder":"24","removeOlderPoints":"","removeOlderUnit":"86400","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"x":610,"y":460,"wires":[[],[]]},{"id":"5ac5dd98.58dad4","type":"change","z":"b0c47343.b841f","name":"ETHBTC","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.ETHBTC","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"ETHBTC","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":440,"y":440,"wires":[["e592c3b5.bbd59"]]},{"id":"ee9a3381.b4656","type":"change","z":"b0c47343.b841f","name":"LTCBTC","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.LTCBTC","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"LTCBTC","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":440,"y":480,"wires":[["e592c3b5.bbd59"]]},{"id":"ad1dd7e.1201128","type":"change","z":"b0c47343.b841f","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.BTCUSDT","tot":"msg"},{"t":"set","p":"topic","pt":"msg","to":"BTCUSDT","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":520,"wires":[["7f2e4737.4c8988"]]},{"id":"7f2e4737.4c8988","type":"ui_chart","z":"b0c47343.b841f","name":"","group":"c4b4d589.76ec78","order":5,"width":0,"height":0,"label":"BTC to USD chart","chartType":"line","legend":"true","xformat":"Y-M-D","interpolate":"linear","nodata":"","dot":true,"ymin":"3000","ymax":"4000","removeOlder":"100","removeOlderPoints":"","removeOlderUnit":"604800","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"x":650,"y":520,"wires":[[],[]]},{"id":"63de302c.df42d","type":"http request","z":"b36b79fb.681da8","name":"addnewlithopian","method":"POST","ret":"obj","url":"http://anonette.net:3000/api/Lithopian","tls":"","x":380,"y":380,"wires":[[]]},{"id":"5e216a86.440684","type":"ui_form","z":"b36b79fb.681da8","name":"","label":"Become a Lithopian:","group":"60e96444.be8e4c","order":3,"width":"0","height":"0","options":[{"label":"What is your name?","value":"name","type":"text","required":true}],"formValue":{"name":""},"payload":"","submit":"submit","cancel":"cancel","topic":"","x":130,"y":380,"wires":[["63de302c.df42d"]]},{"id":"30187a1c.9e6436","type":"ui_form","z":"b36b79fb.681da8","name":"","label":"Offer a partnership or marriage:","group":"60e96444.be8e4c","order":4,"width":"0","height":"0","options":[{"label":"What type?","value":"name","type":"text","required":true},{"label":"For how long?","value":"period","type":"text","required":true}],"formValue":{"name":"","period":""},"payload":"","submit":"submit","cancel":"cancel","topic":"","x":170,"y":420,"wires":[["53b26d6.fec7894"]]},{"id":"53b26d6.fec7894","type":"http request","z":"b36b79fb.681da8","name":"addnewpartnership","method":"POST","ret":"obj","url":"http://anonette.net:3000/api/LithopiaMarriage","tls":"","x":410,"y":420,"wires":[[]]},{"id":"535f8acd.a63994","type":"ui_form","z":"b36b79fb.681da8","name":"","label":"Register a property:","group":"60e96444.be8e4c","order":5,"width":"0","height":"0","options":[{"label":"Location /name","value":"name","type":"text","required":true},{"label":"Owner","value":"owner","type":"text","required":true}],"formValue":{"name":"","owner":""},"payload":"","submit":"submit","cancel":"cancel","topic":"","x":130,"y":460,"wires":[["d32f4b7.9fb41b8"]]},{"id":"d32f4b7.9fb41b8","type":"http request","z":"b36b79fb.681da8","name":"addnewplace","method":"POST","ret":"obj","url":"http://anonette.net:3000/api/LithopiaPlace","tls":"","x":370,"y":460,"wires":[[]]},{"id":"c97e232e.5d66a","type":"ui_template","z":"2c510c19.115f44","group":"695e648e.ad075c","name":"Time and Temp","order":1,"width":"0","height":"0","format":"\n\n\n \n{{row}} | \n
{{row}} | \n
{{row}} | \n
Become a Lithopian
Buying & selling property
Marry & partner
\n\tSatellite Lithoscopes
\n\t\tconcept: Denisa Kera and Petr Šourek
\ndirector: Petr Šourek
\ndesigner: Eva Holá
\nphotography: Jan Hrdý
\ninstallation and 3D print: Virtuoso by Swetja
\nblockchain and Node RED: Denisa Kera and Yair Reshef
\nsatellite image processing: Mateusz Kraiński
\nactors: Milan Holman, Michal Krásl, Ivan Zelenka, Libor Ščerba, Dan Dittrich, Eva Čechová, Dan Šváb, Barbara Humel, Justin Svoboda, Radim Klásek, Vojtěch Bárta, Roman Trochta, Zdeněk Žatečka, Olga Vincencová, Alice Šourková, Ivana Runštuková, Marie Johnson, Petra Brodská.\n
\n\t","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":353.0173645019531,"y":606.0104370117188,"wires":[[]]},{"id":"da1a5324.00899","type":"comment","z":"b36b79fb.681da8","name":"credits","info":"","x":410,"y":560,"wires":[]}] -------------------------------------------------------------------------------- /logic.js: -------------------------------------------------------------------------------- 1 | /* global getParticipantRegistry getAssetRegistry getFactory */ 2 | /** 3 | * A satellite color reading has been received 4 | * @param {org.lithopia.basic.Flagcolor} flagcolor - the Flagcolor transaction 5 | * @transaction 6 | */ 7 | async function flagColor(flagcolor) { // eslint-disable-line no-unused-vars 8 | const place = flagcolor.place; 9 | //console.log('Checking the flag color ' + flagcolor.flagColor + ' to place ' + flagcolor.$name); 10 | if (place.flagColors) { 11 | place.flagColors.unshift(flagcolor); 12 | place.requestSources.unshift(flagcolor); 13 | place.datasetIds.unshift(flagcolor); 14 | } else { 15 | place.flagColors = [flagcolor]; 16 | place.requestSources = [flagcolor]; 17 | place.datasetIds = [flagcolor]; 18 | } 19 | 20 | // add the satelliteReading to the Lithopian Place 21 | const placeRegistry = await getAssetRegistry('org.lithopia.basic.LithopiaPlace'); 22 | await placeRegistry.update(place); 23 | } 24 | /** 25 | * LithopiaPlaceSold transaction triggered by satellite data changing the owner of a property 26 | * @param {org.lithopia.basic.LithopiaPlaceSold} lithopiaPlaceSold - the LithopianPlaceSold transaction 27 | * @transaction 28 | */ 29 | async function selling(lithopiaPlaceSold) { // eslint-disable-line no-unused-vars 30 | const place = lithopiaPlaceSold.place; 31 | const flag = place.flagColors[0].flagColor; 32 | // if thecolor didn't change, the owner remains 33 | if (flag === 'red'){ 34 | place.owner = lithopiaPlaceSold.newOwner.name; 35 | } 36 | else{ 37 | place.owner = lithopiaPlaceSold.place.owner; 38 | } 39 | // update the newOwner 40 | const assetRegistry = await getAssetRegistry('org.lithopia.basic.LithopiaPlace'); 41 | await assetRegistry.update(place); 42 | // emit who is the old or new owner 43 | let placeEvent = getFactory().newEvent('org.lithopia.basic', 'LithopiaPlaceTransactions'); 44 | placeEvent.place = lithopiaPlaceSold.place; 45 | placeEvent.newOwner = place.owner; 46 | emit(placeEvent); 47 | } 48 | /** 49 | * Lithopians entering partnership contract 50 | * @param {org.lithopia.basic.Partners} partnering - the Partners transaction 51 | * @transaction 52 | */ 53 | async function partnering(partnering) { // eslint-disable-line no-unused-vars 54 | const contract = partnering.contract; 55 | if (contract.partners) { 56 | contract.partners.push(partnering); 57 | } 58 | else{ 59 | contract.partners = [partnering]; 60 | } 61 | // add the partners to the contract 62 | const placeRegistry = await getAssetRegistry('org.lithopia.basic.LithopiaMarriage'); 63 | await placeRegistry.update(contract); 64 | // emit the new partnership in Lithopia 65 | let partnerEvent = getFactory().newEvent('org.lithopia.basic', 'NewPartnershipinLithopia'); 66 | partnerEvent.contract = partnering.contract; 67 | partnerEvent.partners = partnering.contract.partners; 68 | emit(partnerEvent); 69 | } 70 | /** 71 | * LithopiaMarriage transaction changng the status of some partners 72 | * @param {org.lithopia.basic.Marriage} marrying - the LithopianPlaceSold transaction 73 | * @transaction 74 | */ 75 | async function married(marrying) { // eslint-disable-line no-unused-vars 76 | const partner = marrying.partnerMarriage; 77 | const partners = marrying.contract.partners; 78 | //console.log(Object.values(partners)); 79 | //console.log(partners[0].newPartner); 80 | //console.log(partner.name); 81 | //console.log(partner); 82 | let i; 83 | for (i=0; i < partners.length; i++){ 84 | if (partners[i].newPartner.includes(partner.name)){ 85 | partner.status = "Married"; 86 | } 87 | else 88 | { 89 | partner.status = "Single"; 90 | } 91 | } 92 | // change the status of the partnership based on enum 93 | const participantRegistry = await getParticipantRegistry('org.lithopia.basic.Lithopian'); 94 | await participantRegistry.update(partner); 95 | } 96 | -------------------------------------------------------------------------------- /mate/readme.md: -------------------------------------------------------------------------------- 1 | 2 | http://anonette.net:8000/summary/ 3 | 4 | 5 | 6 | ### How To Restart ? 7 | 8 | you can just restart the server, the nginx is runing as service on startup 9 | 10 | ### whats running on django 11 | ``` 12 | /home/mate⟫ ps -aux | grep guni 13 | mate 17803 0.0 0.7 88272 14484 ? Ss Dec23 1:42 /home/mate/Envs/lithopia/bin/python3.7 /home/mate/Envs/lithopia/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock lithopia_server.wsgi:application 14 | ``` 15 | 16 | ``` 17 | /home/mate⟫ locate lithopia_server 18 | /etc/nginx/sites-available/lithopia_server 19 | /etc/nginx/sites-enabled/lithopia_server 20 | /home/mate/lithopia/lithopia_server 21 | ``` 22 | ``` 23 | $cat /etc/nginx/sites-available/lithopia_server 24 | server { 25 | listen 8000; 26 | server_name anonette; 27 | location = /favicon.ico { access_log off; log_not_found off; } 28 | location /static/ { 29 | root /home/mate/lithopia/lithopia_server/lithopia_server; 30 | } 31 | location / { 32 | include proxy_params; 33 | proxy_pass http://unix:/run/gunicorn.sock; 34 | } 35 | } 36 | ``` 37 | 38 | 39 | -------------------------------------------------------------------------------- /org.lithopia.basic.cto: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample business network definition. 3 | */ 4 | namespace org.lithopia.basic 5 | /** 6 | * Location in Lithopia visible to satellites owned by a Lithopian 7 | */ 8 | asset LithopiaPlace identified by name { 9 | o String name 10 | o Flagcolor[] flagColors optional 11 | o Flagcolor[] requestSources optional 12 | o Flagcolor[] datasetIds optional 13 | o String owner 14 | } 15 | /** 16 | * An abstract transaction that is related to a LithopiaPlace 17 | */ 18 | abstract transaction LithopiaPlaceTransaction { 19 | --> LithopiaPlace place 20 | } 21 | /** 22 | * A satellite reading for a GPS location identifying a color 23 | */ 24 | transaction Flagcolor extends LithopiaPlaceTransaction { 25 | o String flagColor 26 | o String requestSource 27 | o String datasetId 28 | } 29 | /** 30 | * Changing the owner of the place based on the color identified by a satellite 31 | */ 32 | transaction LithopiaPlaceSold extends LithopiaPlaceTransaction { 33 | -->Lithopian newOwner 34 | } 35 | /** 36 | * Announcing a change of ownership of a place 37 | */ 38 | event LithopiaPlaceTransactions { 39 | --> LithopiaPlace place 40 | o String newOwner 41 | } 42 | /** 43 | * Marriage contract in Lithopia 44 | */ 45 | asset LithopiaMarriage identified by name { 46 | o String name 47 | o String period 48 | o Partners[] partners optional 49 | } 50 | 51 | /** 52 | * Partnering, friendship and marriages in Lithopia 53 | */ 54 | abstract transaction LithopiaPartnering { 55 | -->LithopiaMarriage contract 56 | } 57 | 58 | /** 59 | * Lithopians entering some contract in pairs or groups 60 | */ 61 | transaction Partners extends LithopiaPartnering { 62 | o String[] newPartner 63 | } 64 | /** 65 | * Announcing a marriage between individuals in Lithopia 66 | */ 67 | event NewPartnershipinLithopia { 68 | -->LithopiaMarriage contract 69 | o Partners[] partners 70 | } 71 | /** 72 | * Marrying someone or few people in Lithopia 73 | */ 74 | transaction Marriage extends LithopiaPartnering { 75 | -->Lithopian partnerMarriage 76 | } 77 | /** 78 | * Lithopian living in Lithopia 79 | */ 80 | participant Lithopian identified by name { 81 | o String name 82 | o String status optional 83 | } 84 | 85 | -------------------------------------------------------------------------------- /permissions.acl: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | rule NetworkAdminUser { 16 | description: "Grant business network administrators full access to user resources" 17 | participant: "org.hyperledger.composer.system.NetworkAdmin" 18 | operation: ALL 19 | resource: "**" 20 | action: ALLOW 21 | } 22 | 23 | rule NetworkAdminSystem { 24 | description: "Grant business network administrators full access to system resources" 25 | participant: "org.hyperledger.composer.system.NetworkAdmin" 26 | operation: ALL 27 | resource: "org.hyperledger.composer.system.**" 28 | action: ALLOW 29 | } --------------------------------------------------------------------------------