diff --git a/addSwitch.py b/addSwitch.py new file mode 100644 index 0000000..e58f7f4 --- /dev/null +++ b/addSwitch.py @@ -0,0 +1,36 @@ +import os + +def process_set_file(): + """ + Checks if /root/flowserver exists, reads set.txt, and modifies the second line. + """ + default_folder = "/root/flowserver" if os.path.exists("/root/flowserver") else "/home/unipi/flowserver" + flag = 1 if default_folder == "/root/flowserver" else 0 + + try: + with open("/home/unipi/flowserver/databases/settings.table", "r") as f: + lines = f.readlines() + + if len(lines) >= 2: + lines[0] = lines[0].rstrip('\n') + "|has_main_switch:boolean\n" + second_line = lines[1].strip() # remove trailing newline + last_pipe_index = second_line.rfind("|") + + if last_pipe_index != -1: + modified_line = second_line[:last_pipe_index + 1] + str(flag) + "|" + second_line[last_pipe_index + 1:] + lines[1] = modified_line + else: + print("Warning: No '|' character found in the second line of set.txt") + + with open("/home/unipi/flowserver/databases/settings.table", "w") as f: + f.writelines(lines) + else: + print("Warning: settings.table has less than two lines.") + + except FileNotFoundError: + print("Error: settings.table not found.") + except Exception as e: + print(e) + +# if __name__ == "__main__": +process_set_file() diff --git a/config b/config index 6913e51..9472cb0 100644 --- a/config +++ b/config @@ -7,6 +7,6 @@ package#flow (Object) : { url: '/' } table.relays : line:number|tbname:string|contactor:number|profile:string table.nodes : node:number|tbname:string|line:number|profile:string|processed:boolean|status:boolean|time_of_last_communication:number -table.settings : rvo_name:string|lang:string|temperature_address:string|latitude:number|longitude:number|mqtt_host:string|mqtt_clientid:string|mqtt_username:string|mqtt_port:number|maintanace_mode:boolean|project_id:number|controller_type:string|serial_port:string|backup_on_failure:boolean|restore_from_backup:number|restore_backup_wait:number|node_status_nok_time:number|phases:number|cloud_topic:string +table.settings : rvo_name:string|lang:string|temperature_address:string|latitude:number|longitude:number|mqtt_host:string|mqtt_clientid:string|mqtt_username:string|mqtt_port:number|maintanace_mode:boolean|project_id:number|controller_type:string|serial_port:string|backup_on_failure:boolean|restore_from_backup:number|restore_backup_wait:number|node_status_nok_time:number|phases:number|cloud_topic:string|has_main_switch:boolean table.pins : pin:string|type:string|line:number table.notifications : key:string|weight:string|sk:string|en:string diff --git a/databases/accelerometer_db.js b/databases/accelerometer_db.js new file mode 100644 index 0000000..fdfc7fd --- /dev/null +++ b/databases/accelerometer_db.js @@ -0,0 +1,3055 @@ +let naklony = { + "3993": { "label": "1/3A", "naklon": 0 }, + "3989": { "label": "1/3B", "naklon": 15 }, + "3976": { "label": "1/1", "naklon": 0 }, + "4181": { "label": "1/2", "naklon": 0 }, + "4376": { "label": "1/4", "naklon": 15 }, + "3868": { "label": "1/5", "naklon": 15 }, + "3728": { "label": "1/6", "naklon": 15 }, + "3730": { "label": "1/7", "naklon": 0 }, + "4374": { "label": "1/8", "naklon": 0 }, + "3718": { "label": "1/9", "naklon": 15 }, + "4375": { "label": "1/10", "naklon": 15 }, + "4172": { "label": "1/11", "naklon": 15 }, + "4176": { "label": "1/12", "naklon": 15 }, + "3800": { "label": "2/1", "naklon": 5 }, + "3823": { "label": "2/2", "naklon": 5 }, + "3905": { "label": "2/3", "naklon": 5 }, + "3803": { "label": "2/4", "naklon": 5 }, + "3817": { "label": "2/5", "naklon": 5 }, + "3818": { "label": "2/6", "naklon": 5 }, + "3811": { "label": "2/7", "naklon": 5 }, + "3915": { "label": "2/8", "naklon": 5 }, + "3843": { "label": "2/9", "naklon": 10 }, + "3827": { "label": "2/10", "naklon": 10 }, + "4220": { "label": "2/11", "naklon": 10 }, + "3826": { "label": "2/12", "naklon": 10 }, + "3834": { "label": "2/13", "naklon": 10 }, + "3838": { "label": "2/14", "naklon": 10 }, + "2823": { "label": "2/15", "naklon": 10 }, + "3750": { "label": "2/16", "naklon": 10 }, + "3378": { "label": "2/17", "naklon": 0 }, + "3376": { "label": "2/18", "naklon": 0 }, + "3379": { "label": "2/19", "naklon": 0 }, + "3285": { "label": "2/20", "naklon": 0 }, + "3382": { "label": "2/21", "naklon": 0 }, + "3383": { "label": "2/22", "naklon": 0 }, + "3375": { "label": "2/24", "naklon": 0 }, + "3381": { "label": "2/25", "naklon": 0 }, + "3380": { "label": "2/26", "naklon": 0 }, + "3828": { "label": "2/27", "naklon": 10 }, + "3377": { "label": "2/28", "naklon": 0 }, + "3591": { "label": "7/1", "naklon": 0 }, + "3587": { "label": "7/2", "naklon": 0 }, + "3468": { "label": "7/3", "naklon": 0 }, + "3466": { "label": "7/4", "naklon": 0 }, + "3474": { "label": "7/5", "naklon": 0 }, + "3481": { "label": "7/6", "naklon": 0 }, + "3589": { "label": "7/7", "naklon": 0 }, + "3472": { "label": "7/8", "naklon": 0 }, + "3473": { "label": "7/9", "naklon": 0 }, + "3584": { "label": "7/10", "naklon": 0 }, + "3571": { "label": "7/11", "naklon": 0 }, + "3476": { "label": "7/12", "naklon": 0 }, + "3590": { "label": "7/13", "naklon": 0 }, + "3478": { "label": "7/14", "naklon": 0 }, + "3471": { "label": "7/15", "naklon": 0 }, + "3467": { "label": "7/16", "naklon": 0 }, + "3479": { "label": "7/17", "naklon": 0 }, + "3480": { "label": "7/18", "naklon": 0 }, + "3477": { "label": "7/19", "naklon": 0 }, + "3362": { "label": "12/1", "naklon": 0 }, + "3355": { "label": "12/2", "naklon": 0 }, + "3356": { "label": "12/3", "naklon": 0 }, + "3349": { "label": "12/4", "naklon": 0 }, + "3357": { "label": "12/5", "naklon": 0 }, + "3350": { "label": "12/6", "naklon": 0 }, + "3353": { "label": "12/7", "naklon": 0 }, + "3539": { "label": "12/8", "naklon": 0 }, + "3050": { "label": "12/9", "naklon": 0 }, + "3361": { "label": "12/10", "naklon": 0 }, + "3360": { "label": "12/11", "naklon": 0 }, + "3358": { "label": "12/12", "naklon": 0 }, + "3541": { "label": "12/13", "naklon": 0 }, + "3551": { "label": "12/14", "naklon": 0 }, + "3514": { "label": "12/15", "naklon": 0 }, + "3547": { "label": "12/16", "naklon": 0 }, + "3562": { "label": "12/17", "naklon": 0 }, + "3525": { "label": "12/18", "naklon": 0 }, + "3558": { "label": "12/19", "naklon": 0 }, + "3511": { "label": "12/20", "naklon": 0 }, + "3058": { "label": "12/21", "naklon": 0 }, + "3062": { "label": "12/22", "naklon": 0 }, + "3070": { "label": "12/23", "naklon": 0 }, + "3447": { "label": "12/24", "naklon": 0 }, + "3056": { "label": "12/25", "naklon": 0 }, + "3057": { "label": "12/26", "naklon": 0 }, + "3071": { "label": "12/27", "naklon": 0 }, + "3061": { "label": "12/28", "naklon": 0 }, + "3069": { "label": "12/29", "naklon": 0 }, + "3077": { "label": "12/30", "naklon": 0 }, + "3080": { "label": "12/31", "naklon": 0 }, + "3081": { "label": "12/32", "naklon": 0 }, + "3078": { "label": "12/33", "naklon": 0 }, + "4037": { "label": "12/34", "naklon": 0 }, + "3067": { "label": "12/35", "naklon": 0 }, + "3051": { "label": "12/36", "naklon": 0 }, + "2924": { "label": "12/37", "naklon": 0 }, + "3060": { "label": "12/38", "naklon": 0 }, + "3073": { "label": "12/39", "naklon": 0 }, + "3469": { "label": "12/40", "naklon": 0 }, + "2923": { "label": "12/41", "naklon": 0 }, + "2925": { "label": "12/42", "naklon": 0 }, + "3359": { "label": "12/43", "naklon": 0 }, + "3055": { "label": "12/44", "naklon": 0 }, + "2922": { "label": "12/45", "naklon": 0 }, + "3084": { "label": "12/46", "naklon": 0 }, + "3064": { "label": "12/47", "naklon": 0 }, + "3066": { "label": "12/48", "naklon": 0 }, + "3072": { "label": "12/49", "naklon": 0 }, + "3415": { "label": "13/13A", "naklon": 0 }, + "3409": { "label": "13/13B", "naklon": 0 }, + "3399": { "label": "13/13C", "naklon": 0 }, + "3410": { "label": "13/29A", "naklon": 0 }, + "3407": { "label": "13/29B", "naklon": 0 }, + "3405": { "label": "13/34A", "naklon": 0 }, + "3404": { "label": "13/34B", "naklon": 0 }, + "3392": { "label": "13/45A", "naklon": 0 }, + "3386": { "label": "13/45B", "naklon": 0 }, + "3303": { "label": "13/60A", "naklon": 3 }, + "3302": { "label": "13/60B", "naklon": 3 }, + "3319": { "label": "13/70A", "naklon": 6 }, + "3317": { "label": "13/70B", "naklon": 6 }, + "3326": { "label": "13/70C", "naklon": 6 }, + "3351": { "label": "13/73A", "naklon": 6 }, + "3313": { "label": "13/73B", "naklon": 6 }, + "3316": { "label": "13/83A", "naklon": 0 }, + "3320": { "label": "13/83B", "naklon": 0 }, + "3336": { "label": "13/95A", "naklon": 0 }, + "3323": { "label": "13/95B", "naklon": 0 }, + "3339": { "label": "13/98A", "naklon": 0 }, + "3333": { "label": "13/98B", "naklon": 0 }, + "3425": { "label": "13/1", "naklon": 0 }, + "3419": { "label": "13/2", "naklon": 0 }, + "3416": { "label": "13/3", "naklon": 0 }, + "3332": { "label": "13/4", "naklon": 0 }, + "3422": { "label": "13/5", "naklon": 0 }, + "3417": { "label": "13/6", "naklon": 0 }, + "3418": { "label": "13/7", "naklon": 0 }, + "3424": { "label": "13/8", "naklon": 0 }, + "3334": { "label": "13/9", "naklon": 0 }, + "4363": { "label": "13/10", "naklon": 0 }, + "3423": { "label": "13/11", "naklon": 0 }, + "3406": { "label": "13/12", "naklon": 0 }, + "3411": { "label": "13/14", "naklon": 0 }, + "3412": { "label": "13/15", "naklon": 0 }, + "3413": { "label": "13/16", "naklon": 0 }, + "3414": { "label": "13/17", "naklon": 0 }, + "3391": { "label": "13/18", "naklon": 0 }, + "3370": { "label": "13/19", "naklon": 0 }, + "3369": { "label": "13/20", "naklon": 0 }, + "3408": { "label": "13/21", "naklon": 0 }, + "3393": { "label": "13/22", "naklon": 0 }, + "3128": { "label": "13/23", "naklon": 0 }, + "3197": { "label": "13/24", "naklon": 0 }, + "4364": { "label": "13/25", "naklon": 0 }, + "3155": { "label": "13/26", "naklon": 0 }, + "3196": { "label": "13/27", "naklon": 0 }, + "3144": { "label": "13/28", "naklon": 0 }, + "3150": { "label": "13/30", "naklon": 0 }, + "3390": { "label": "13/31", "naklon": 0 }, + "3401": { "label": "13/32", "naklon": 0 }, + "3275": { "label": "13/33", "naklon": 0 }, + "3371": { "label": "13/35", "naklon": 0 }, + "3389": { "label": "13/36", "naklon": 0 }, + "3388": { "label": "13/37", "naklon": 0 }, + "3365": { "label": "13/38", "naklon": 0 }, + "3363": { "label": "13/39", "naklon": 0 }, + "3397": { "label": "13/40", "naklon": 0 }, + "3567": { "label": "13/40/1", "naklon": 0 }, + "3387": { "label": "13/41", "naklon": 0 }, + "3403": { "label": "13/42", "naklon": 0 }, + "3147": { "label": "13/43", "naklon": 0 }, + "3141": { "label": "13/44", "naklon": 0 }, + "3364": { "label": "13/46", "naklon": 0 }, + "3367": { "label": "13/47", "naklon": 0 }, + "3368": { "label": "13/48", "naklon": 0 }, + "3402": { "label": "13/49", "naklon": 0 }, + "3366": { "label": "13/50", "naklon": 0 }, + "3395": { "label": "13/51", "naklon": 0 }, + "3372": { "label": "13/52", "naklon": 0 }, + "3394": { "label": "13/53", "naklon": 0 }, + "3308": { "label": "13/54", "naklon": 0 }, + "3847": { "label": "13/54/1", "naklon": 0 }, + "3312": { "label": "13/55", "naklon": 3 }, + "3309": { "label": "13/56", "naklon": 3 }, + "3311": { "label": "13/57", "naklon": 3 }, + "3310": { "label": "13/58", "naklon": 3 }, + "4365": { "label": "13/59", "naklon": 3 }, + "4093": { "label": "13/60/1", "naklon": 3 }, + "3304": { "label": "13/61", "naklon": 3 }, + "3307": { "label": "13/62", "naklon": 3 }, + "3271": { "label": "13/63", "naklon": 3 }, + "3301": { "label": "13/64", "naklon": 3 }, + "4366": { "label": "13/65", "naklon": 3 }, + "3300": { "label": "13/66", "naklon": 3 }, + "3185": { "label": "13/67", "naklon": 0 }, + "3184": { "label": "13/68", "naklon": 0 }, + "3188": { "label": "13/69", "naklon": 0 }, + "3343": { "label": "13/71", "naklon": 6 }, + "3819": { "label": "13/71/1", "naklon": 6 }, + "3880": { "label": "13/71/2", "naklon": 6 }, + "3348": { "label": "13/72", "naklon": 6 }, + "3344": { "label": "13/74", "naklon": 6 }, + "3346": { "label": "13/75", "naklon": 6 }, + "3597": { "label": "13/75/1", "naklon": 6 }, + "3345": { "label": "13/76", "naklon": 6 }, + "3322": { "label": "13/77", "naklon": 0 }, + "3325": { "label": "13/78", "naklon": 0 }, + "4310": { "label": "13/78/1", "naklon": 0 }, + "3315": { "label": "13/79", "naklon": 0 }, + "3328": { "label": "13/80", "naklon": 0 }, + "3321": { "label": "13/81", "naklon": 0 }, + "3324": { "label": "13/82", "naklon": 0 }, + "3140": { "label": "13/84", "naklon": 0 }, + "3153": { "label": "13/85", "naklon": 0 }, + "3145": { "label": "13/86", "naklon": 0 }, + "3134": { "label": "13/87", "naklon": 0 }, + "3151": { "label": "13/88", "naklon": 0 }, + "3143": { "label": "13/89", "naklon": 0 }, + "3318": { "label": "13/90", "naklon": 0 }, + "3347": { "label": "13/91", "naklon": 0 }, + "3314": { "label": "13/94", "naklon": 0 }, + "3331": { "label": "13/96", "naklon": 0 }, + "3327": { "label": "13/97", "naklon": 0 }, + "3329": { "label": "13/99", "naklon": 0 }, + "3337": { "label": "13/100", "naklon": 0 }, + "3330": { "label": "13/101", "naklon": 0 }, + "3335": { "label": "13/102", "naklon": 0 }, + "3420": { "label": "13/103", "naklon": 0 }, + "3421": { "label": "13/104", "naklon": 0 }, + "4361": { "label": "13/105", "naklon": 0 }, + "4362": { "label": "13/106", "naklon": 0 }, + "3526": { "label": "13/107", "naklon": 0 }, + "4424": { "label": "13/108", "naklon": null }, + "3561": { "label": "13/109", "naklon": null }, + "3527": { "label": "13/110", "naklon": null }, + "3521": { "label": "13/111", "naklon": null }, + "3552": { "label": "13/112", "naklon": null }, + "3544": { "label": "13/113", "naklon": null }, + "3534": { "label": "13/114", "naklon": null }, + "3516": { "label": "13/115", "naklon": null }, + "3513": { "label": "13/116", "naklon": null }, + "3565": { "label": "13/117", "naklon": null }, + "3866": { "label": "13/118", "naklon": null }, + "3136": { "label": "14/1", "naklon": 0 }, + "3137": { "label": "14/2", "naklon": 0 }, + "3135": { "label": "14/3", "naklon": 0 }, + "3149": { "label": "14/4", "naklon": 0 }, + "3142": { "label": "14/5", "naklon": 0 }, + "3342": { "label": "14/6", "naklon": 0 }, + "3340": { "label": "14/7", "naklon": 0 }, + "3152": { "label": "14/8", "naklon": 0 }, + "3886": { "label": "14/9", "naklon": 0 }, + "3341": { "label": "14/10", "naklon": null }, + "3352": { "label": "14/11", "naklon": null }, + "3396": { "label": "15/1", "naklon": 5 }, + "2784": { "label": "15/2", "naklon": 5 }, + "2788": { "label": "15/3", "naklon": 5 }, + "2801": { "label": "15/4", "naklon": 5 }, + "2815": { "label": "15/5", "naklon": 5 }, + "2829": { "label": "15/6", "naklon": 5 }, + "2796": { "label": "15/7", "naklon": 5 }, + "2803": { "label": "15/8", "naklon": 5 }, + "4304": { "label": "15/8/1", "naklon": 5 }, + "4311": { "label": "15/8/2", "naklon": 5 }, + "2821": { "label": "15/9", "naklon": 5 }, + "3400": { "label": "15/10", "naklon": 5 }, + "2799": { "label": "15/11", "naklon": 5 }, + "2804": { "label": "15/12", "naklon": 5 }, + "4303": { "label": "15/12/1", "naklon": 5 }, + "4309": { "label": "15/12/2", "naklon": 5 }, + "2806": { "label": "15/13", "naklon": 5 }, + "2787": { "label": "15/14", "naklon": 5 }, + "2809": { "label": "15/15", "naklon": 5 }, + "2814": { "label": "15/16", "naklon": 0 }, + "3934": { "label": "15/17", "naklon": 0 }, + "3192": { "label": "15/18", "naklon": 0 }, + "2812": { "label": "15/19", "naklon": 0 }, + "4070": { "label": "15/20", "naklon": 0 }, + "2826": { "label": "15/21", "naklon": 0 }, + "2808": { "label": "15/22", "naklon": 3 }, + "2795": { "label": "15/23", "naklon": 3 }, + "2807": { "label": "15/24", "naklon": 3 }, + "2831": { "label": "15/25", "naklon": 0 }, + "2862": { "label": "15/26", "naklon": null }, + "2861": { "label": "15/27", "naklon": 0 }, + "2866": { "label": "15/28", "naklon": 0 }, + "3546": { "label": "15/28/1", "naklon": 0 }, + "4146": { "label": "15/29", "naklon": 0 }, + "3001": { "label": "15/29/1", "naklon": 0 }, + "2835": { "label": "15/30", "naklon": 0 }, + "2874": { "label": "15/31", "naklon": 0 }, + "2852": { "label": "15/32", "naklon": 0 }, + "2851": { "label": "15/33", "naklon": 0 }, + "3560": { "label": "15/33/1", "naklon": 0 }, + "2858": { "label": "15/34", "naklon": 0 }, + "4306": { "label": "15/34/1", "naklon": 0 }, + "2856": { "label": "15/35", "naklon": 0 }, + "2847": { "label": "15/36", "naklon": 0 }, + "3556": { "label": "15/36/1", "naklon": 0 }, + "3950": { "label": "15/37", "naklon": 0 }, + "2848": { "label": "15/38", "naklon": 0 }, + "2863": { "label": "15/39", "naklon": 0 }, + "4313": { "label": "15/39/1", "naklon": 0 }, + "2873": { "label": "15/40", "naklon": 0 }, + "2984": { "label": "15/40/1", "naklon": 0 }, + "2854": { "label": "15/41", "naklon": 0 }, + "2859": { "label": "15/42", "naklon": 0 }, + "2872": { "label": "15/43", "naklon": 0 }, + "2849": { "label": "15/44", "naklon": 0 }, + "2864": { "label": "15/45", "naklon": 0 }, + "3553": { "label": "15/46", "naklon": null }, + "3021": { "label": "15/47", "naklon": null }, + "3008": { "label": "15/47/1", "naklon": null }, + "3017": { "label": "15/48", "naklon": null }, + "3014": { "label": "15/49", "naklon": null }, + "2981": { "label": "15/50", "naklon": null }, + "3020": { "label": "15/51", "naklon": null }, + "3027": { "label": "15/52", "naklon": null }, + "3006": { "label": "15/53", "naklon": null }, + "3012": { "label": "15/54", "naklon": null }, + "2738": { "label": "15/55", "naklon": 0 }, + "2725": { "label": "15/56", "naklon": 0 }, + "3016": { "label": "15/57", "naklon": null }, + "3005": { "label": "15/58", "naklon": null }, + "3009": { "label": "15/58/1", "naklon": null }, + "3010": { "label": "15/59", "naklon": 0 }, + "3538": { "label": "15/59/1", "naklon": 0 }, + "4145": { "label": "15/59/2", "naklon": 0 }, + "2713": { "label": "15/60", "naklon": 0 }, + "2789": { "label": "15/61", "naklon": 0 }, + "2736": { "label": "15/62", "naklon": 0 }, + "2739": { "label": "15/63", "naklon": 0 }, + "4346": { "label": "15/64", "naklon": 0 }, + "2731": { "label": "15/65", "naklon": 0 }, + "2818": { "label": "15/66", "naklon": 0 }, + "3557": { "label": "15/66/1", "naklon": 0 }, + "2822": { "label": "15/67", "naklon": 0 }, + "2833": { "label": "15/68", "naklon": 0 }, + "2834": { "label": "15/69", "naklon": 0 }, + "3097": { "label": "15/70", "naklon": 0 }, + "2824": { "label": "15/71", "naklon": 0 }, + "2828": { "label": "15/72", "naklon": 0 }, + "2600": { "label": "15/73", "naklon": 0 }, + "4314": { "label": "15/73/1", "naklon": 0 }, + "2832": { "label": "15/74", "naklon": 0 }, + "4360": { "label": "15/75", "naklon": 0 }, + "2846": { "label": "15/76", "naklon": 0 }, + "2584": { "label": "15/77", "naklon": 0 }, + "2843": { "label": "15/78", "naklon": 0 }, + "4308": { "label": "15/78/1", "naklon": 0 }, + "4144": { "label": "15/79", "naklon": null }, + "2844": { "label": "15/80", "naklon": 0 }, + "2842": { "label": "15/81", "naklon": 0 }, + "2838": { "label": "15/82", "naklon": 0 }, + "2837": { "label": "15/83", "naklon": null }, + "3555": { "label": "15/83/1", "naklon": null }, + "2839": { "label": "15/84", "naklon": 0 }, + "2830": { "label": "15/85", "naklon": 0 }, + "4066": { "label": "15/86", "naklon": 0 }, + "2836": { "label": "15/87", "naklon": 0 }, + "2911": { "label": "15/88", "naklon": 0 }, + "2825": { "label": "15/89", "naklon": 0 }, + "2811": { "label": "15/90", "naklon": 0 }, + "3740": { "label": "15/94", "naklon": 15 }, + "2734": { "label": "15/95", "naklon": 15 }, + "3105": { "label": "15/96", "naklon": 15 }, + "2732": { "label": "15/97", "naklon": 15 }, + "2727": { "label": "15/98", "naklon": 15 }, + "2735": { "label": "15/99", "naklon": 15 }, + "3926": { "label": "15/100", "naklon": 15 }, + "2918": { "label": "15/101", "naklon": 0 }, + "2705": { "label": "15/102", "naklon": 10 }, + "2708": { "label": "15/103", "naklon": 10 }, + "2721": { "label": "15/104", "naklon": 10 }, + "2719": { "label": "15/105", "naklon": 10 }, + "2919": { "label": "15/106", "naklon": 10 }, + "3101": { "label": "15/107", "naklon": 10 }, + "2853": { "label": "15/108", "naklon": 10 }, + "2715": { "label": "15/109", "naklon": 10 }, + "2712": { "label": "15/110", "naklon": 0 }, + "2711": { "label": "15/111", "naklon": 0 }, + "2709": { "label": "15/112", "naklon": 0 }, + "2710": { "label": "15/113", "naklon": 0 }, + "2907": { "label": "15/114", "naklon": 0 }, + "2906": { "label": "15/115", "naklon": 0 }, + "2908": { "label": "15/116", "naklon": 0 }, + "2901": { "label": "15/117", "naklon": 0 }, + "2913": { "label": "15/118", "naklon": 0 }, + "3656": { "label": "15/119", "naklon": 0 }, + "2781": { "label": "15/120", "naklon": 0 }, + "2802": { "label": "15/121", "naklon": 0 }, + "2791": { "label": "15/122", "naklon": 0 }, + "2783": { "label": "15/123", "naklon": 0 }, + "2794": { "label": "15/124", "naklon": 0 }, + "3139": { "label": "15/125", "naklon": 0 }, + "3229": { "label": "15/126", "naklon": 5 }, + "3239": { "label": "15/127", "naklon": 5 }, + "3230": { "label": "15/128", "naklon": 5 }, + "4016": { "label": "15/129", "naklon": null }, + "3608": { "label": "16/16A", "naklon": 0 }, + "4151": { "label": "16/16B", "naklon": 0 }, + "3710": { "label": "16/1", "naklon": 0 }, + "3726": { "label": "16/2", "naklon": 0 }, + "3743": { "label": "16/3", "naklon": 0 }, + "3724": { "label": "16/4", "naklon": 0 }, + "3712": { "label": "16/5", "naklon": 0 }, + "3739": { "label": "16/6", "naklon": 0 }, + "3742": { "label": "16/7", "naklon": 0 }, + "3731": { "label": "16/8", "naklon": 0 }, + "3727": { "label": "16/9", "naklon": 0 }, + "3729": { "label": "16/10", "naklon": 0 }, + "3736": { "label": "16/11", "naklon": 0 }, + "3713": { "label": "16/12", "naklon": 0 }, + "3715": { "label": "16/13", "naklon": 0 }, + "3733": { "label": "16/14", "naklon": 0 }, + "3732": { "label": "16/15", "naklon": 0 }, + "3634": { "label": "16/17", "naklon": 0 }, + "3610": { "label": "16/18", "naklon": 0 }, + "3626": { "label": "16/19", "naklon": 0 }, + "3618": { "label": "16/20", "naklon": 0 }, + "3619": { "label": "16/21", "naklon": 0 }, + "3628": { "label": "16/22", "naklon": 0 }, + "3615": { "label": "16/23", "naklon": 0 }, + "3609": { "label": "16/24", "naklon": 0 }, + "3606": { "label": "16/25", "naklon": 0 }, + "3624": { "label": "16/26", "naklon": 0 }, + "3627": { "label": "16/27", "naklon": 0 }, + "3607": { "label": "16/28", "naklon": 0 }, + "4370": { "label": "16/29", "naklon": 0 }, + "3692": { "label": "16/30", "naklon": 0 }, + "3614": { "label": "16/31", "naklon": 0 }, + "3623": { "label": "16/32", "naklon": 0 }, + "4373": { "label": "16/33", "naklon": 0 }, + "3620": { "label": "16/34", "naklon": 0 }, + "3685": { "label": "16/35", "naklon": 0 }, + "3616": { "label": "16/36", "naklon": 0 }, + "3686": { "label": "16/37", "naklon": 0 }, + "3688": { "label": "16/38", "naklon": 0 }, + "3684": { "label": "16/39", "naklon": 0 }, + "3825": { "label": "16/40", "naklon": 0 }, + "3865": { "label": "16/41", "naklon": 0 }, + "3824": { "label": "16/42", "naklon": 0 }, + "3871": { "label": "16/43", "naklon": 0 }, + "3801": { "label": "16/44", "naklon": 0 }, + "3862": { "label": "16/45", "naklon": 0 }, + "3876": { "label": "16/46", "naklon": 0 }, + "3861": { "label": "16/47", "naklon": 0 }, + "4215": { "label": "16/48", "naklon": 0 }, + "3605": { "label": "16/49", "naklon": 10 }, + "3603": { "label": "16/50", "naklon": 10 }, + "3592": { "label": "16/51", "naklon": 10 }, + "3598": { "label": "16/52", "naklon": 10 }, + "3594": { "label": "16/53", "naklon": 10 }, + "3593": { "label": "16/54", "naklon": 10 }, + "3630": { "label": "16/55", "naklon": 10 }, + "3763": { "label": "16/56", "naklon": 10 }, + "3746": { "label": "16/57", "naklon": 10 }, + "3699": { "label": "16/58", "naklon": 0 }, + "3698": { "label": "16/59", "naklon": 0 }, + "3709": { "label": "16/60", "naklon": null }, + "3708": { "label": "16/61", "naklon": 0 }, + "3703": { "label": "16/62", "naklon": null }, + "3700": { "label": "16/63", "naklon": 0 }, + "3701": { "label": "16/64", "naklon": null }, + "3704": { "label": "16/65", "naklon": 0 }, + "3707": { "label": "16/66", "naklon": null }, + "3810": { "label": "16/67", "naklon": 0 }, + "4208": { "label": "16/68", "naklon": null }, + "3867": { "label": "16/69", "naklon": 0 }, + "4372": { "label": "16/70", "naklon": null }, + "3881": { "label": "16/71", "naklon": 0 }, + "4204": { "label": "16/72", "naklon": null }, + "3869": { "label": "16/73", "naklon": 0 }, + "4202": { "label": "16/74", "naklon": null }, + "3830": { "label": "16/75", "naklon": 0 }, + "3870": { "label": "16/76", "naklon": null }, + "3964": { "label": "16/77", "naklon": 0 }, + "3849": { "label": "16/78", "naklon": 0 }, + "3694": { "label": "16/79", "naklon": null }, + "3717": { "label": "16/80", "naklon": 0 }, + "3877": { "label": "16/81", "naklon": null }, + "3755": { "label": "16/82", "naklon": 0 }, + "3725": { "label": "16/83", "naklon": null }, + "3716": { "label": "16/84", "naklon": 0 }, + "3696": { "label": "16/85", "naklon": null }, + "3702": { "label": "16/86", "naklon": 0 }, + "3706": { "label": "16/87", "naklon": null }, + "3850": { "label": "16/88", "naklon": 0 }, + "3848": { "label": "16/89", "naklon": null }, + "3737": { "label": "16/90", "naklon": null }, + "3705": { "label": "16/91", "naklon": 0 }, + "3723": { "label": "16/92", "naklon": null }, + "3842": { "label": "16/93", "naklon": 0 }, + "3735": { "label": "16/94", "naklon": null }, + "3719": { "label": "16/95", "naklon": 0 }, + "3697": { "label": "16/96", "naklon": 0 }, + "3711": { "label": "16/97", "naklon": 0 }, + "4107": { "label": "16/98", "naklon": null }, + "4112": { "label": "16/99", "naklon": 5 }, + "4106": { "label": "16/100", "naklon": 5 }, + "4111": { "label": "16/101", "naklon": 5 }, + "4091": { "label": "16/102", "naklon": null }, + "4104": { "label": "16/103", "naklon": 5 }, + "4094": { "label": "16/104", "naklon": null }, + "4089": { "label": "16/105", "naklon": 5 }, + "4095": { "label": "16/106", "naklon": null }, + "4102": { "label": "16/107", "naklon": 5 }, + "4105": { "label": "16/108", "naklon": null }, + "3859": { "label": "16/109", "naklon": null }, + "4090": { "label": "16/110", "naklon": 5 }, + "4110": { "label": "16/111", "naklon": null }, + "4097": { "label": "16/112", "naklon": 5 }, + "4099": { "label": "16/113", "naklon": null }, + "4096": { "label": "16/114", "naklon": null }, + "4101": { "label": "16/115", "naklon": 5 }, + "4109": { "label": "16/116", "naklon": null }, + "4092": { "label": "16/117", "naklon": 5 }, + "3631": { "label": "16/118", "naklon": null }, + "3632": { "label": "16/119", "naklon": 0 }, + "3641": { "label": "16/120", "naklon": null }, + "3638": { "label": "16/121", "naklon": 0 }, + "3637": { "label": "16/122", "naklon": null }, + "4142": { "label": "16/123", "naklon": null }, + "4147": { "label": "16/124", "naklon": 5 }, + "4139": { "label": "16/125", "naklon": 5 }, + "3172": { "label": "20/30A", "naklon": 2 }, + "3164": { "label": "20/30B", "naklon": 2 }, + "3247": { "label": "20/1", "naklon": 10 }, + "3296": { "label": "20/2", "naklon": 10 }, + "3246": { "label": "20/3", "naklon": 10 }, + "3270": { "label": "20/4", "naklon": 10 }, + "3294": { "label": "20/5", "naklon": 10 }, + "3298": { "label": "20/6", "naklon": 10 }, + "3297": { "label": "20/7", "naklon": 10 }, + "3293": { "label": "20/8", "naklon": 10 }, + "3299": { "label": "20/9", "naklon": 10 }, + "3295": { "label": "20/10", "naklon": 10 }, + "3244": { "label": "20/11", "naklon": 10 }, + "3249": { "label": "20/12", "naklon": 10 }, + "3268": { "label": "20/13", "naklon": 10 }, + "3245": { "label": "20/14", "naklon": 10 }, + "3278": { "label": "20/15", "naklon": 10 }, + "3280": { "label": "20/16", "naklon": 10 }, + "3292": { "label": "20/17", "naklon": 10 }, + "3287": { "label": "20/18", "naklon": 10 }, + "3282": { "label": "20/19", "naklon": 10 }, + "3273": { "label": "20/20", "naklon": 0 }, + "3157": { "label": "20/21", "naklon": 0 }, + "3283": { "label": "20/22", "naklon": 0 }, + "3159": { "label": "20/23", "naklon": 0 }, + "3289": { "label": "20/24", "naklon": 0 }, + "3163": { "label": "20/25", "naklon": 0 }, + "3126": { "label": "20/26", "naklon": 0 }, + "3171": { "label": "20/27", "naklon": 0 }, + "3162": { "label": "20/28", "naklon": 0 }, + "3279": { "label": "20/29", "naklon": 10 }, + "3173": { "label": "20/31", "naklon": 0 }, + "3127": { "label": "20/32", "naklon": 0 }, + "3131": { "label": "20/33", "naklon": 0 }, + "3129": { "label": "20/34", "naklon": 0 }, + "3276": { "label": "20/35", "naklon": 2 }, + "3290": { "label": "20/36", "naklon": 2 }, + "3132": { "label": "20/37", "naklon": 0 }, + "3138": { "label": "20/38", "naklon": 0 }, + "3272": { "label": "20/39", "naklon": 0 }, + "3291": { "label": "20/40", "naklon": 0 }, + "3277": { "label": "20/41", "naklon": 10 }, + "3286": { "label": "20/42", "naklon": 10 }, + "3281": { "label": "20/43", "naklon": 10 }, + "3288": { "label": "20/44", "naklon": 10 }, + "3284": { "label": "20/45", "naklon": 10 }, + "3167": { "label": "20/46", "naklon": 10 }, + "3872": { "label": "20/47", "naklon": 0 }, + "3124": { "label": "20/48", "naklon": 0 }, + "3133": { "label": "20/49", "naklon": 0 }, + "3158": { "label": "20/50", "naklon": 0 }, + "3169": { "label": "20/51", "naklon": 0 }, + "3146": { "label": "20/52", "naklon": 0 }, + "3160": { "label": "20/53", "naklon": 0 }, + "3248": { "label": "20/54", "naklon": 0 }, + "3156": { "label": "20/55", "naklon": 0 }, + "3161": { "label": "20/56", "naklon": 0 }, + "3170": { "label": "20/57", "naklon": 0 }, + "3168": { "label": "20/58", "naklon": 0 }, + "3125": { "label": "20/59", "naklon": 0 }, + "3166": { "label": "20/60", "naklon": 0 }, + "3130": { "label": "20/61", "naklon": 0 }, + "3563": { "label": "20/62", "naklon": 0 }, + "3550": { "label": "20/63", "naklon": null }, + "3269": { "label": "20/67", "naklon": 0 }, + "2921": { "label": "21/1", "naklon": 0 }, + "2707": { "label": "21/2", "naklon": 0 }, + "2723": { "label": "21/3", "naklon": 0 }, + "2716": { "label": "21/4", "naklon": 0 }, + "2717": { "label": "21/5", "naklon": 0 }, + "2720": { "label": "21/6", "naklon": 0 }, + "2722": { "label": "21/7", "naklon": 0 }, + "2718": { "label": "21/8", "naklon": 0 }, + "2724": { "label": "21/9", "naklon": 0 }, + "2742": { "label": "21/10", "naklon": 0 }, + "2743": { "label": "21/11", "naklon": 0 }, + "2733": { "label": "21/12", "naklon": 0 }, + "2903": { "label": "21/14", "naklon": 0 }, + "2917": { "label": "21/15", "naklon": 0 }, + "2897": { "label": "21/16", "naklon": 0 }, + "2914": { "label": "21/17", "naklon": 0 }, + "2898": { "label": "21/18", "naklon": 0 }, + "2773": { "label": "21/19", "naklon": 0 }, + "2895": { "label": "21/20", "naklon": 0 }, + "2896": { "label": "21/21", "naklon": 0 }, + "2771": { "label": "21/22", "naklon": 0 }, + "2772": { "label": "21/23", "naklon": 0 }, + "2793": { "label": "21/24", "naklon": 0 }, + "2902": { "label": "21/25", "naklon": 0 }, + "2910": { "label": "21/26", "naklon": 0 }, + "2909": { "label": "21/27", "naklon": 0 }, + "2920": { "label": "21/28", "naklon": 0 }, + "2916": { "label": "21/29", "naklon": 0 }, + "2904": { "label": "21/30", "naklon": 0 }, + "2915": { "label": "21/31", "naklon": 0 }, + "2905": { "label": "21/32", "naklon": 0 }, + "2900": { "label": "21/33", "naklon": 0 }, + "2899": { "label": "21/34", "naklon": 0 }, + "2741": { "label": "21/36", "naklon": 0 }, + "2714": { "label": "21/37", "naklon": 0 }, + "2701": { "label": "21/38", "naklon": 0 }, + "2703": { "label": "21/39", "naklon": 0 }, + "2704": { "label": "21/40", "naklon": 0 }, + "2702": { "label": "21/41", "naklon": 0 }, + "2706": { "label": "21/42", "naklon": 0 }, + "2776": { "label": "21/43", "naklon": 0 }, + "2770": { "label": "21/44", "naklon": 0 }, + "2786": { "label": "21/45", "naklon": 0 }, + "2779": { "label": "21/46", "naklon": 0 }, + "2782": { "label": "21/47", "naklon": 0 }, + "2785": { "label": "21/48", "naklon": 0 }, + "2769": { "label": "21/49", "naklon": 0 }, + "3354": { "label": "21/50", "naklon": 0 }, + "2778": { "label": "21/51", "naklon": 0 }, + "2775": { "label": "21/52", "naklon": 0 }, + "2780": { "label": "21/53", "naklon": 0 }, + "2790": { "label": "21/54", "naklon": 0 }, + "2792": { "label": "21/55", "naklon": 0 }, + "2774": { "label": "21/56", "naklon": 0 }, + "2630": { "label": "22/1", "naklon": 0 }, + "2631": { "label": "22/2", "naklon": 0 }, + "2632": { "label": "22/3", "naklon": 0 }, + "2633": { "label": "22/4", "naklon": 0 }, + "2634": { "label": "22/5", "naklon": 0 }, + "2636": { "label": "22/6", "naklon": 0 }, + "4367": { "label": "22/7", "naklon": 0 }, + "2637": { "label": "22/8", "naklon": 0 }, + "2638": { "label": "22/9", "naklon": 0 }, + "2639": { "label": "22/10", "naklon": 0 }, + "2640": { "label": "22/11", "naklon": 0 }, + "2641": { "label": "22/12", "naklon": 0 }, + "2642": { "label": "22/13", "naklon": 0 }, + "2643": { "label": "22/14", "naklon": 0 }, + "2644": { "label": "22/15", "naklon": 0 }, + "2645": { "label": "22/16", "naklon": 0 }, + "2646": { "label": "22/17", "naklon": 0 }, + "2647": { "label": "22/18", "naklon": 0 }, + "2648": { "label": "22/19", "naklon": 0 }, + "2649": { "label": "22/20", "naklon": 0 }, + "2650": { "label": "22/21", "naklon": 0 }, + "2651": { "label": "22/22", "naklon": 0 }, + "4103": { "label": "22/23", "naklon": 0 }, + "2653": { "label": "22/24", "naklon": 0 }, + "2654": { "label": "22/25", "naklon": 0 }, + "2655": { "label": "22/26", "naklon": 0 }, + "2656": { "label": "22/27", "naklon": 0 }, + "2657": { "label": "22/28", "naklon": 0 }, + "2658": { "label": "22/29", "naklon": 0 }, + "2659": { "label": "22/30", "naklon": 0 }, + "2660": { "label": "22/31", "naklon": 0 }, + "2661": { "label": "22/32", "naklon": 0 }, + "3015": { "label": "22/32/1", "naklon": 0 }, + "2662": { "label": "22/33", "naklon": 0 }, + "2663": { "label": "22/34", "naklon": 0 }, + "2664": { "label": "22/35", "naklon": 0 }, + "2665": { "label": "22/36", "naklon": 0 }, + "2666": { "label": "22/37", "naklon": 0 }, + "2667": { "label": "22/38", "naklon": 0 }, + "2668": { "label": "22/39", "naklon": 0 }, + "2669": { "label": "22/40", "naklon": null }, + "2670": { "label": "22/41", "naklon": null }, + "2671": { "label": "22/42", "naklon": null }, + "3087": { "label": "23/9A", "naklon": 10 }, + "3090": { "label": "23/9B", "naklon": 10 }, + "3075": { "label": "23/1", "naklon": 0 }, + "3089": { "label": "23/2", "naklon": 0 }, + "3088": { "label": "23/3", "naklon": 0 }, + "3228": { "label": "23/4", "naklon": 10 }, + "2751": { "label": "23/5", "naklon": 10 }, + "3243": { "label": "23/6", "naklon": 10 }, + "4349": { "label": "23/7", "naklon": 10 }, + "3102": { "label": "23/8", "naklon": 10 }, + "3099": { "label": "23/10", "naklon": 10 }, + "3103": { "label": "23/11", "naklon": 10 }, + "3093": { "label": "23/12", "naklon": 10 }, + "3098": { "label": "23/13", "naklon": 10 }, + "3092": { "label": "23/14", "naklon": 10 }, + "3233": { "label": "23/15", "naklon": 0 }, + "3095": { "label": "23/16", "naklon": 0 }, + "4074": { "label": "23/17", "naklon": 0 }, + "2729": { "label": "23/18", "naklon": 0 }, + "3234": { "label": "23/19", "naklon": 0 }, + "3094": { "label": "23/20", "naklon": 0 }, + "2817": { "label": "23/21", "naklon": 0 }, + "3226": { "label": "23/22", "naklon": 0 }, + "3225": { "label": "23/23", "naklon": 0 }, + "3237": { "label": "23/24", "naklon": 0 }, + "4250": { "label": "23/25", "naklon": 0 }, + "3059": { "label": "23/26", "naklon": 10 }, + "3238": { "label": "23/27", "naklon": 10 }, + "3242": { "label": "23/28", "naklon": 10 }, + "3236": { "label": "23/29", "naklon": 10 }, + "3112": { "label": "23/30", "naklon": 10 }, + "3224": { "label": "23/31", "naklon": 0 }, + "4298": { "label": "23/32", "naklon": 10 }, + "4150": { "label": "23/33", "naklon": 10 }, + "3091": { "label": "23/34", "naklon": 10 }, + "3771": { "label": "25/1", "naklon": 5 }, + "3777": { "label": "25/2", "naklon": 5 }, + "3749": { "label": "25/3", "naklon": 5 }, + "3769": { "label": "25/4", "naklon": 5 }, + "3765": { "label": "25/5", "naklon": 5 }, + "3785": { "label": "25/6", "naklon": 5 }, + "3761": { "label": "25/7", "naklon": 5 }, + "3758": { "label": "25/8", "naklon": 5 }, + "3766": { "label": "25/9", "naklon": 5 }, + "3779": { "label": "25/10", "naklon": 5 }, + "3899": { "label": "25/11", "naklon": 10 }, + "3922": { "label": "25/12", "naklon": 10 }, + "3912": { "label": "25/13", "naklon": 10 }, + "3933": { "label": "25/14", "naklon": 10 }, + "3921": { "label": "25/15", "naklon": 10 }, + "4300": { "label": "25/16", "naklon": 10 }, + "3927": { "label": "25/17", "naklon": 10 }, + "3212": { "label": "25/18", "naklon": 10 }, + "3208": { "label": "25/19", "naklon": 10 }, + "3207": { "label": "25/20", "naklon": 10 }, + "4294": { "label": "25/21", "naklon": 10 }, + "3209": { "label": "25/22", "naklon": 10 }, + "3745": { "label": "25/23", "naklon": 10 }, + "3762": { "label": "25/24", "naklon": 10 }, + "3215": { "label": "25/25", "naklon": 10 }, + "3210": { "label": "25/26", "naklon": 10 }, + "3211": { "label": "25/27", "naklon": 10 }, + "3206": { "label": "25/28", "naklon": 10 }, + "3918": { "label": "25/29", "naklon": 5 }, + "3928": { "label": "25/30", "naklon": 5 }, + "3917": { "label": "25/31", "naklon": 5 }, + "4029": { "label": "25/32", "naklon": 0 }, + "4038": { "label": "25/33", "naklon": 0 }, + "4022": { "label": "25/34", "naklon": 0 }, + "3937": { "label": "25/35", "naklon": 0 }, + "3190": { "label": "25/36", "naklon": 0 }, + "3835": { "label": "25/37", "naklon": 0 }, + "3201": { "label": "25/38", "naklon": 0 }, + "3193": { "label": "25/39", "naklon": 0 }, + "3191": { "label": "25/40", "naklon": 0 }, + "3203": { "label": "25/41", "naklon": 0 }, + "4301": { "label": "25/42", "naklon": 0 }, + "3223": { "label": "25/43", "naklon": 0 }, + "3202": { "label": "25/44", "naklon": 0 }, + "3205": { "label": "25/45", "naklon": 0 }, + "3194": { "label": "25/46", "naklon": 0 }, + "3198": { "label": "25/47", "naklon": 0 }, + "3204": { "label": "25/48", "naklon": 0 }, + "3200": { "label": "25/49", "naklon": 0 }, + "3216": { "label": "25/50", "naklon": 0 }, + "3932": { "label": "25/51", "naklon": 5 }, + "3923": { "label": "25/52", "naklon": 5 }, + "3913": { "label": "25/53", "naklon": 5 }, + "3900": { "label": "25/54", "naklon": 5 }, + "4189": { "label": "25/55", "naklon": 10 }, + "4191": { "label": "25/56", "naklon": 10 }, + "3790": { "label": "25/57", "naklon": 10 }, + "4190": { "label": "25/58", "naklon": 10 }, + "4302": { "label": "25/59", "naklon": 0 }, + "4351": { "label": "25/60", "naklon": 0 }, + "4075": { "label": "25/61", "naklon": 0 }, + "4071": { "label": "25/62", "naklon": 0 }, + "3784": { "label": "25/63", "naklon": 0 }, + "4065": { "label": "25/64", "naklon": 0 }, + "4297": { "label": "25/65", "naklon": 0 }, + "4295": { "label": "25/66", "naklon": 0 }, + "4299": { "label": "25/67", "naklon": 0 }, + "3772": { "label": "25/68", "naklon": 0 }, + "3941": { "label": "25/69", "naklon": 0 }, + "3782": { "label": "25/70", "naklon": 0 }, + "4068": { "label": "25/71", "naklon": 0 }, + "4073": { "label": "25/72", "naklon": 0 }, + "3901": { "label": "25/73", "naklon": 5 }, + "4296": { "label": "25/74", "naklon": 5 }, + "3910": { "label": "25/75", "naklon": 5 }, + "4293": { "label": "25/76", "naklon": 5 }, + "3919": { "label": "25/77", "naklon": 5 }, + "3924": { "label": "25/78", "naklon": 5 }, + "3909": { "label": "25/79", "naklon": 5 }, + "3896": { "label": "25/80", "naklon": 5 }, + "3911": { "label": "25/81", "naklon": 5 }, + "2819": { "label": "25/82", "naklon": 15 }, + "3776": { "label": "25/83", "naklon": 15 }, + "3752": { "label": "25/84", "naklon": 15 }, + "4353": { "label": "25/85", "naklon": 15 }, + "3791": { "label": "25/86", "naklon": 0 }, + "3770": { "label": "25/87", "naklon": 0 }, + "3760": { "label": "25/88", "naklon": 0 }, + "3115": { "label": "25/89", "naklon": 0 }, + "3738": { "label": "25/90", "naklon": 0 }, + "3748": { "label": "25/91", "naklon": 0 }, + "3753": { "label": "25/92", "naklon": 0 }, + "3775": { "label": "25/93", "naklon": 0 }, + "3778": { "label": "25/94", "naklon": 5 }, + "4078": { "label": "25/95", "naklon": 5 }, + "4088": { "label": "25/96", "naklon": 5 }, + "3856": { "label": "25/97", "naklon": 5 }, + "4084": { "label": "25/98", "naklon": 5 }, + "4069": { "label": "25/99", "naklon": 5 }, + "4188": { "label": "25/100", "naklon": 5 }, + "4064": { "label": "25/101", "naklon": 5 }, + "3792": { "label": "25/102", "naklon": 5 }, + "3780": { "label": "25/103", "naklon": 5 }, + "4034": { "label": "25/104", "naklon": 5 }, + "4072": { "label": "25/105", "naklon": 5 }, + "3884": { "label": "25/106", "naklon": 5 }, + "3793": { "label": "25/107", "naklon": 5 }, + "3863": { "label": "25/108", "naklon": 5 }, + "3855": { "label": "25/109", "naklon": 5 }, + "3846": { "label": "33/1", "naklon": 0 }, + "3943": { "label": "33/2", "naklon": 0 }, + "3903": { "label": "33/3", "naklon": 0 }, + "3982": { "label": "33/4", "naklon": 0 }, + "3879": { "label": "33/5", "naklon": 0 }, + "3887": { "label": "33/6", "naklon": 0 }, + "3920": { "label": "33/7", "naklon": 5 }, + "3942": { "label": "33/8", "naklon": 5 }, + "3829": { "label": "33/9", "naklon": null }, + "3452": { "label": "34/79A", "naklon": 6 }, + "3460": { "label": "34/79B", "naklon": 6 }, + "3443": { "label": "34/90A", "naklon": 6 }, + "3445": { "label": "34/90B", "naklon": 6 }, + "3457": { "label": "34/90C", "naklon": 6 }, + "3461": { "label": "34/97A", "naklon": 6 }, + "3463": { "label": "34/97B", "naklon": 6 }, + "3426": { "label": "34/98A", "naklon": 6 }, + "3444": { "label": "34/98B", "naklon": 6 }, + "3453": { "label": "34/99A", "naklon": 6 }, + "3455": { "label": "34/99B", "naklon": 6 }, + "4009": { "label": "34/1", "naklon": 0 }, + "3602": { "label": "34/2", "naklon": 0 }, + "3441": { "label": "34/3", "naklon": 0 }, + "3464": { "label": "34/4", "naklon": 0 }, + "3883": { "label": "34/5", "naklon": 0 }, + "4098": { "label": "34/6", "naklon": 0 }, + "4003": { "label": "34/7", "naklon": 0 }, + "4004": { "label": "34/8", "naklon": 0 }, + "3888": { "label": "34/9", "naklon": 0 }, + "3997": { "label": "34/10", "naklon": 0 }, + "4006": { "label": "34/11", "naklon": 0 }, + "4000": { "label": "34/12", "naklon": 0 }, + "4011": { "label": "34/13", "naklon": 0 }, + "3999": { "label": "34/14", "naklon": 0 }, + "3981": { "label": "34/15", "naklon": 0 }, + "3988": { "label": "34/16", "naklon": 0 }, + "3986": { "label": "34/17", "naklon": 0 }, + "3998": { "label": "34/18", "naklon": 0 }, + "3983": { "label": "34/19", "naklon": 0 }, + "4005": { "label": "34/20", "naklon": 0 }, + "4001": { "label": "34/21", "naklon": 0 }, + "4008": { "label": "34/22", "naklon": 0 }, + "4002": { "label": "34/23", "naklon": 0 }, + "3996": { "label": "34/24", "naklon": 0 }, + "4007": { "label": "34/25", "naklon": 0 }, + "4113": { "label": "34/26", "naklon": 15 }, + "3595": { "label": "34/27", "naklon": 5 }, + "3599": { "label": "34/28", "naklon": 5 }, + "3601": { "label": "34/29", "naklon": 5 }, + "4205": { "label": "34/30", "naklon": 0 }, + "3987": { "label": "34/31", "naklon": null }, + "4214": { "label": "34/32", "naklon": 0 }, + "4226": { "label": "34/33", "naklon": 0 }, + "4209": { "label": "34/34", "naklon": 0 }, + "4201": { "label": "34/35", "naklon": 0 }, + "3440": { "label": "34/36", "naklon": 0 }, + "3465": { "label": "34/37", "naklon": 0 }, + "3446": { "label": "34/38", "naklon": 0 }, + "4039": { "label": "34/39", "naklon": 5 }, + "4057": { "label": "34/40", "naklon": 5 }, + "3985": { "label": "34/41", "naklon": 0 }, + "3882": { "label": "34/42", "naklon": 0 }, + "4040": { "label": "34/43", "naklon": 5 }, + "3231": { "label": "34/44", "naklon": 0 }, + "3227": { "label": "34/45", "naklon": 0 }, + "3431": { "label": "34/46", "naklon": 0 }, + "4013": { "label": "34/47", "naklon": 0 }, + "4045": { "label": "34/48", "naklon": 0 }, + "3949": { "label": "34/49", "naklon": 0 }, + "3953": { "label": "34/50", "naklon": 0 }, + "3952": { "label": "34/51", "naklon": 0 }, + "3995": { "label": "34/52", "naklon": 0 }, + "3992": { "label": "34/53", "naklon": 0 }, + "4198": { "label": "34/54", "naklon": 0 }, + "3935": { "label": "34/55", "naklon": 0 }, + "4050": { "label": "34/56", "naklon": 0 }, + "4049": { "label": "34/57", "naklon": 0 }, + "4054": { "label": "34/58", "naklon": 0 }, + "3663": { "label": "34/59", "naklon": 6 }, + "3661": { "label": "34/60", "naklon": 6 }, + "3664": { "label": "34/61", "naklon": 6 }, + "3660": { "label": "34/62", "naklon": 6 }, + "3662": { "label": "34/63", "naklon": 6 }, + "3665": { "label": "34/65", "naklon": 6 }, + "3667": { "label": "34/66", "naklon": 6 }, + "3675": { "label": "34/67", "naklon": 6 }, + "3666": { "label": "34/68", "naklon": 6 }, + "3652": { "label": "34/69", "naklon": 6 }, + "3458": { "label": "34/70", "naklon": 6 }, + "4425": { "label": "34/70/1", "naklon": 6 }, + "3459": { "label": "34/71", "naklon": 6 }, + "3435": { "label": "34/72", "naklon": 6 }, + "3448": { "label": "34/73", "naklon": 6 }, + "3451": { "label": "34/74", "naklon": 6 }, + "3442": { "label": "34/75", "naklon": 6 }, + "3449": { "label": "34/76", "naklon": 6 }, + "3450": { "label": "34/77", "naklon": 6 }, + "3433": { "label": "34/78", "naklon": 6 }, + "3432": { "label": "34/80", "naklon": 12 }, + "3470": { "label": "34/81", "naklon": 12 }, + "3438": { "label": "34/82", "naklon": 12 }, + "3439": { "label": "34/83", "naklon": 12 }, + "4028": { "label": "34/84", "naklon": 5 }, + "3596": { "label": "34/85", "naklon": 5 }, + "4021": { "label": "34/86", "naklon": 5 }, + "3437": { "label": "34/87", "naklon": 12 }, + "3428": { "label": "34/88", "naklon": 12 }, + "3430": { "label": "34/89", "naklon": 12 }, + "3454": { "label": "34/91", "naklon": 6 }, + "3492": { "label": "34/92", "naklon": 6 }, + "3462": { "label": "34/93", "naklon": 6 }, + "3427": { "label": "34/94", "naklon": 6 }, + "3434": { "label": "34/95", "naklon": 6 }, + "3456": { "label": "34/96", "naklon": 6 }, + "4307": { "label": "34/98/1", "naklon": 6 }, + "3968": { "label": "35/1", "naklon": 0 }, + "3969": { "label": "35/2", "naklon": 0 }, + "3947": { "label": "35/3", "naklon": 0 }, + "3979": { "label": "35/4", "naklon": 0 }, + "3959": { "label": "35/5", "naklon": 0 }, + "3948": { "label": "35/6", "naklon": 0 }, + "3961": { "label": "35/7", "naklon": 0 }, + "3956": { "label": "35/8", "naklon": 0 }, + "3604": { "label": "35/9", "naklon": 0 }, + "3944": { "label": "35/10", "naklon": 0 }, + "3960": { "label": "35/11", "naklon": 0 }, + "3958": { "label": "35/12", "naklon": 0 }, + "4036": { "label": "35/13", "naklon": 5 }, + "3893": { "label": "35/18", "naklon": 5 }, + "4108": { "label": "35/19", "naklon": 5 }, + "4017": { "label": "35/20", "naklon": 5 }, + "3963": { "label": "35/21", "naklon": 0 }, + "3658": { "label": "35/22", "naklon": 0 }, + "3975": { "label": "35/23", "naklon": 0 }, + "3980": { "label": "35/24", "naklon": 0 }, + "4012": { "label": "35/25", "naklon": 0 }, + "3655": { "label": "35/26", "naklon": 0 }, + "3962": { "label": "35/27", "naklon": 0 }, + "3945": { "label": "35/28", "naklon": 0 }, + "3569": { "label": "35/29", "naklon": 0 }, + "3429": { "label": "35/30", "naklon": 0 }, + "3657": { "label": "35/31", "naklon": 0 }, + "3646": { "label": "35/32", "naklon": 0 }, + "3622": { "label": "35/33", "naklon": 0 }, + "3612": { "label": "35/34", "naklon": 0 }, + "3955": { "label": "35/35", "naklon": 0 }, + "3878": { "label": "35/37", "naklon": 0 }, + "3965": { "label": "35/38", "naklon": 0 }, + "3970": { "label": "35/39", "naklon": 0 }, + "3611": { "label": "35/40", "naklon": 0 }, + "2635": { "label": "35/41", "naklon": 0 }, + "3978": { "label": "35/42", "naklon": 0 }, + "4213": { "label": "35/43", "naklon": 0 }, + "3984": { "label": "35/44", "naklon": 0 }, + "4218": { "label": "35/45", "naklon": 0 }, + "3973": { "label": "35/46", "naklon": 0 }, + "3974": { "label": "35/47", "naklon": 0 }, + "3759": { "label": "35/48", "naklon": 0 }, + "3844": { "label": "35/49", "naklon": 0 }, + "3804": { "label": "35/50", "naklon": 0 }, + "3831": { "label": "35/51", "naklon": 0 }, + "3643": { "label": "35/52", "naklon": 0 }, + "3966": { "label": "35/53", "naklon": 0 }, + "3971": { "label": "35/54", "naklon": 0 }, + "3650": { "label": "35/55", "naklon": 6 }, + "3651": { "label": "35/56", "naklon": 6 }, + "3669": { "label": "35/57", "naklon": 6 }, + "3648": { "label": "35/58", "naklon": 6 }, + "3645": { "label": "35/59", "naklon": 6 }, + "3659": { "label": "35/60", "naklon": 6 }, + "3647": { "label": "35/61", "naklon": 6 }, + "3644": { "label": "35/62", "naklon": 6 }, + "3671": { "label": "35/63", "naklon": 6 }, + "3682": { "label": "35/64", "naklon": 6 }, + "3672": { "label": "35/65", "naklon": 6 }, + "3683": { "label": "35/66", "naklon": 6 }, + "3673": { "label": "35/67", "naklon": 6 }, + "3674": { "label": "35/68", "naklon": 6 }, + "3679": { "label": "35/69", "naklon": 6 }, + "3649": { "label": "35/70", "naklon": 6 }, + "3687": { "label": "35/71", "naklon": 6 }, + "3677": { "label": "35/72", "naklon": 6 }, + "3690": { "label": "35/73", "naklon": 6 }, + "3691": { "label": "35/74", "naklon": 6 }, + "3676": { "label": "35/75", "naklon": 6 }, + "3680": { "label": "35/76", "naklon": 6 }, + "3668": { "label": "35/77", "naklon": 6 }, + "3681": { "label": "35/78", "naklon": 6 }, + "3670": { "label": "35/79", "naklon": 6 }, + "3689": { "label": "35/80", "naklon": 6 }, + "3678": { "label": "35/81", "naklon": 6 }, + "3693": { "label": "35/82", "naklon": 6 }, + "3654": { "label": "35/83", "naklon": null }, + "4086": { "label": "36/1", "naklon": 0 }, + "4085": { "label": "36/2", "naklon": 0 }, + "4083": { "label": "36/3", "naklon": 0 }, + "4087": { "label": "36/4", "naklon": 0 }, + "4077": { "label": "36/5", "naklon": 0 }, + "4082": { "label": "36/6", "naklon": 0 }, + "4186": { "label": "36/7", "naklon": 0 }, + "4206": { "label": "36/8", "naklon": 0 }, + "4080": { "label": "36/9", "naklon": 0 }, + "4081": { "label": "36/10", "naklon": 0 }, + "4210": { "label": "36/11", "naklon": 0 }, + "4079": { "label": "36/12", "naklon": 0 }, + "4076": { "label": "36/13", "naklon": 0 }, + "3852": { "label": "36/14", "naklon": 0 }, + "2813": { "label": "36/15", "naklon": 0 }, + "4219": { "label": "36/16", "naklon": 0 }, + "3104": { "label": "37/1A", "naklon": 15 }, + "3121": { "label": "37/1B", "naklon": 15 }, + "3113": { "label": "37/2", "naklon": 10 }, + "3118": { "label": "37/3", "naklon": 10 }, + "3111": { "label": "37/4", "naklon": 10 }, + "4020": { "label": "37/5", "naklon": 10 }, + "3119": { "label": "37/6", "naklon": 10 }, + "3110": { "label": "37/7", "naklon": 10 }, + "3108": { "label": "37/8", "naklon": 10 }, + "3107": { "label": "37/12", "naklon": 0 }, + "3199": { "label": "37/13", "naklon": 0 }, + "3120": { "label": "37/14", "naklon": 0 }, + "3122": { "label": "37/15", "naklon": 0 }, + "3908": { "label": "37/16", "naklon": 0 }, + "3114": { "label": "37/17", "naklon": 0 }, + "3105": { "label": "37/18", "naklon": 0 }, + "3116": { "label": "37/19", "naklon": 0 }, + "3106": { "label": "37/20", "naklon": 0 }, + "2887": { "label": "37/21", "naklon": 5 }, + "2888": { "label": "37/22", "naklon": 5 }, + "2877": { "label": "37/23", "naklon": 5 }, + "2891": { "label": "37/24", "naklon": 5 }, + "2886": { "label": "37/25", "naklon": 5 }, + "2892": { "label": "37/26", "naklon": 5 }, + "2882": { "label": "37/27", "naklon": 5 }, + "2883": { "label": "37/28", "naklon": 5 }, + "2876": { "label": "37/29", "naklon": 5 }, + "3109": { "label": "37/30", "naklon": 5 }, + "4152": { "label": "37/31", "naklon": 5 }, + "3117": { "label": "37/32", "naklon": 5 }, + "2870": { "label": "37/33", "naklon": 5 }, + "2867": { "label": "37/34", "naklon": 0 }, + "2865": { "label": "37/35", "naklon": 0 }, + "3096": { "label": "37/36", "naklon": 0 }, + "2871": { "label": "37/37", "naklon": 0 }, + "2884": { "label": "37/38", "naklon": 0 }, + "2855": { "label": "37/39", "naklon": 0 }, + "2878": { "label": "37/40", "naklon": 0 }, + "2889": { "label": "37/41", "naklon": 0 }, + "2879": { "label": "37/42", "naklon": 0 }, + "2850": { "label": "37/43", "naklon": 0 }, + "2894": { "label": "37/44", "naklon": 0 }, + "2880": { "label": "37/45", "naklon": 0 }, + "2893": { "label": "37/46", "naklon": 0 }, + "2890": { "label": "37/47", "naklon": 0 }, + "4355": { "label": "37/48", "naklon": 0 }, + "2885": { "label": "37/49", "naklon": 0 }, + "2875": { "label": "37/50", "naklon": 0 }, + "3486": { "label": "38/30A", "naklon": 5 }, + "3714": { "label": "38/30B", "naklon": 0 }, + "3483": { "label": "38/32A", "naklon": 5 }, + "3496": { "label": "38/32B", "naklon": 0 }, + "3487": { "label": "38/35A", "naklon": 5 }, + "3498": { "label": "38/35B", "naklon": 5 }, + "3578": { "label": "38/38A", "naklon": 5 }, + "3508": { "label": "38/38B", "naklon": 5 }, + "3787": { "label": "38/59A", "naklon": 5 }, + "3491": { "label": "38/59B", "naklon": 5 }, + "3568": { "label": "38/1", "naklon": null }, + "3502": { "label": "38/2", "naklon": 0 }, + "3836": { "label": "38/3", "naklon": 0 }, + "3588": { "label": "38/4", "naklon": 0 }, + "3493": { "label": "38/5", "naklon": 0 }, + "3580": { "label": "38/6", "naklon": 0 }, + "3572": { "label": "38/7", "naklon": 0 }, + "3506": { "label": "38/8", "naklon": 0 }, + "3503": { "label": "38/9", "naklon": 0 }, + "3579": { "label": "38/10", "naklon": 0 }, + "3586": { "label": "38/11", "naklon": 0 }, + "3495": { "label": "38/12", "naklon": 5 }, + "3492": { "label": "38/13", "naklon": 5 }, + "3532": { "label": "38/14", "naklon": 5 }, + "3574": { "label": "38/15", "naklon": 5 }, + "4140": { "label": "38/16", "naklon": 5 }, + "3795": { "label": "38/17", "naklon": 5 }, + "3788": { "label": "38/18", "naklon": 5 }, + "3796": { "label": "38/19", "naklon": 5 }, + "3797": { "label": "38/20", "naklon": 5 }, + "3798": { "label": "38/21", "naklon": 5 }, + "3786": { "label": "38/22", "naklon": 5 }, + "4067": { "label": "38/23", "naklon": 5 }, + "3773": { "label": "38/24", "naklon": 5 }, + "3774": { "label": "38/25", "naklon": 5 }, + "3789": { "label": "38/26", "naklon": 5 }, + "3520": { "label": "38/27", "naklon": null }, + "3577": { "label": "38/29", "naklon": 5 }, + "3530": { "label": "38/31", "naklon": null }, + "3488": { "label": "38/33", "naklon": 5 }, + "3505": { "label": "38/34", "naklon": 5 }, + "3497": { "label": "38/36", "naklon": 5 }, + "3490": { "label": "38/37", "naklon": 5 }, + "3585": { "label": "38/39", "naklon": 5 }, + "3582": { "label": "38/40", "naklon": 5 }, + "3507": { "label": "38/41", "naklon": 5 }, + "3484": { "label": "38/42", "naklon": 5 }, + "3501": { "label": "38/43", "naklon": 5 }, + "3581": { "label": "38/44", "naklon": 5 }, + "4192": { "label": "38/45", "naklon": 5 }, + "3576": { "label": "38/46", "naklon": 5 }, + "3489": { "label": "38/47", "naklon": 5 }, + "3573": { "label": "38/48", "naklon": 5 }, + "3504": { "label": "38/49", "naklon": 5 }, + "3794": { "label": "38/50", "naklon": 5 }, + "3485": { "label": "38/51", "naklon": 5 }, + "3482": { "label": "38/52", "naklon": 5 }, + "3575": { "label": "38/53", "naklon": 5 }, + "3499": { "label": "38/54", "naklon": 5 }, + "3494": { "label": "38/55", "naklon": 5 }, + "3583": { "label": "38/56", "naklon": 5 }, + "3570": { "label": "38/57", "naklon": 5 }, + "3500": { "label": "38/58", "naklon": 0 }, + "3510": { "label": "38/63", "naklon": null }, + "3512": { "label": "38/64", "naklon": null }, + "3535": { "label": "38/67", "naklon": null }, + "3531": { "label": "38/68", "naklon": null }, + "3537": { "label": "38/69", "naklon": null }, + "3522": { "label": "39/1", "naklon": 10 }, + "4018": { "label": "39/2", "naklon": 10 }, + "4019": { "label": "39/3", "naklon": 10 }, + "4154": { "label": "39/4", "naklon": 5 }, + "3907": { "label": "39/5", "naklon": 5 }, + "4148": { "label": "39/6", "naklon": 0 }, + "4153": { "label": "39/7", "naklon": 0 }, + "3938": { "label": "39/8", "naklon": 0 }, + "3802": { "label": "39/9", "naklon": 0 }, + "4015": { "label": "39/10", "naklon": 0 }, + "3929": { "label": "39/11", "naklon": 0 }, + "3946": { "label": "39/12", "naklon": 0 }, + "4014": { "label": "39/13", "naklon": 0 }, + "4155": { "label": "39/14", "naklon": 0 }, + "4149": { "label": "39/15", "naklon": 0 }, + "3642": { "label": "39/16", "naklon": 0 }, + "3636": { "label": "39/17", "naklon": 5 }, + "3991": { "label": "39/18", "naklon": 0 }, + "3994": { "label": "39/19", "naklon": 0 }, + "3990": { "label": "39/20", "naklon": 0 }, + "3967": { "label": "39/21", "naklon": 0 }, + "3977": { "label": "39/22", "naklon": 0 }, + "3757": { "label": "39/23", "naklon": 15 }, + "3633": { "label": "39/24", "naklon": 15 }, + "3744": { "label": "39/25", "naklon": 15 }, + "4023": { "label": "39/26", "naklon": 5 }, + "3720": { "label": "39/27", "naklon": 5 }, + "3734": { "label": "39/28", "naklon": 5 }, + "3741": { "label": "39/29", "naklon": 5 }, + "3721": { "label": "39/30", "naklon": 5 }, + "3845": { "label": "39/31", "naklon": 0 }, + "3840": { "label": "39/32", "naklon": 0 }, + "3837": { "label": "39/33", "naklon": null }, + "3839": { "label": "39/34", "naklon": 0 }, + "3542": { "label": "41/1", "naklon": null }, + "3566": { "label": "41/2", "naklon": null }, + "3548": { "label": "41/3", "naklon": null }, + "3515": { "label": "41/4", "naklon": null }, + "3559": { "label": "41/5", "naklon": null }, + "3509": { "label": "41/6", "naklon": null }, + "3524": { "label": "41/7", "naklon": null }, + "3518": { "label": "41/8", "naklon": null }, + "3182": { "label": "41/9", "naklon": null }, + "3187": { "label": "41/10", "naklon": null }, + "3195": { "label": "41/11", "naklon": 0 }, + "3857": { "label": "41/12", "naklon": 0 }, + "3183": { "label": "41/13", "naklon": 0 }, + "3177": { "label": "41/14", "naklon": 0 }, + "3189": { "label": "41/15", "naklon": 0 }, + "3186": { "label": "41/16", "naklon": 0 }, + "3178": { "label": "42/1", "naklon": 0 }, + "3219": { "label": "42/2", "naklon": 0 }, + "3475": { "label": "42/3", "naklon": 0 }, + "3175": { "label": "42/4", "naklon": 0 }, + "3222": { "label": "42/5", "naklon": 0 }, + "3221": { "label": "42/6", "naklon": 0 }, + "3181": { "label": "42/7", "naklon": 0 }, + "3180": { "label": "42/8", "naklon": 0 }, + "3218": { "label": "42/9", "naklon": 0 }, + "3176": { "label": "42/10", "naklon": 0 }, + "3174": { "label": "42/11", "naklon": 0 }, + "3220": { "label": "42/12", "naklon": 0 }, + "3533": { "label": "42/13", "naklon": null }, + "3543": { "label": "42/14", "naklon": null }, + "3554": { "label": "42/15", "naklon": null }, + "3549": { "label": "42/16", "naklon": null }, + "2857": { "label": "43/1", "naklon": 5 }, + "2752": { "label": "43/2", "naklon": 5 }, + "2753": { "label": "43/3", "naklon": 5 }, + "3024": { "label": "43/4", "naklon": 5 }, + "2754": { "label": "43/5", "naklon": 5 }, + "4423": { "label": "43/6", "naklon": 5 }, + "4368": { "label": "43/7", "naklon": 5 }, + "2978": { "label": "43/8", "naklon": 5 }, + "2868": { "label": "43/9", "naklon": 5 }, + "4377": { "label": "43/10", "naklon": 5 }, + "2757": { "label": "43/11", "naklon": 5 }, + "2970": { "label": "43/12", "naklon": 5 }, + "2758": { "label": "43/13", "naklon": 5 }, + "4378": { "label": "43/14", "naklon": 5 }, + "2759": { "label": "43/15", "naklon": 5 }, + "4342": { "label": "43/16", "naklon": 5 }, + "3026": { "label": "43/17", "naklon": null }, + "2986": { "label": "43/18", "naklon": null }, + "4343": { "label": "43/19", "naklon": null }, + "2760": { "label": "43/20", "naklon": null }, + "4379": { "label": "43/21", "naklon": null }, + "2971": { "label": "43/22", "naklon": null }, + "2761": { "label": "43/23", "naklon": null }, + "2762": { "label": "43/24", "naklon": null }, + "4339": { "label": "43/25", "naklon": null }, + "4380": { "label": "43/26", "naklon": null }, + "2975": { "label": "43/27", "naklon": null }, + "3003": { "label": "43/28", "naklon": null }, + "4338": { "label": "43/29", "naklon": null }, + "3002": { "label": "43/30", "naklon": null }, + "4345": { "label": "43/31", "naklon": null }, + "2979": { "label": "43/32", "naklon": null }, + "2989": { "label": "43/33", "naklon": null }, + "2996": { "label": "43/34", "naklon": null }, + "2972": { "label": "43/35", "naklon": null }, + "2988": { "label": "43/36", "naklon": null }, + "4344": { "label": "43/37", "naklon": null }, + "3022": { "label": "43/38", "naklon": null }, + "4341": { "label": "43/39", "naklon": null }, + "2983": { "label": "43/40", "naklon": null }, + "2995": { "label": "43/41", "naklon": null }, + "2763": { "label": "43/42", "naklon": null }, + "2764": { "label": "43/43", "naklon": null }, + "2765": { "label": "43/44", "naklon": null }, + "2766": { "label": "43/45", "naklon": null }, + "2767": { "label": "43/46", "naklon": null }, + "2768": { "label": "43/47", "naklon": null }, + "3018": { "label": "43/48", "naklon": null }, + "2982": { "label": "43/49", "naklon": null }, + "3019": { "label": "43/50", "naklon": 0 }, + "3013": { "label": "43/51", "naklon": null }, + "3007": { "label": "43/52", "naklon": null }, + "2980": { "label": "43/53", "naklon": null }, + "3011": { "label": "43/54", "naklon": null }, + "2672": { "label": "43/55", "naklon": null }, + "2673": { "label": "43/56", "naklon": null }, + "2674": { "label": "43/57", "naklon": null }, + "2675": { "label": "43/58", "naklon": null }, + "2676": { "label": "43/59", "naklon": null }, + "2677": { "label": "43/60", "naklon": null }, + "2678": { "label": "43/61", "naklon": null }, + "2679": { "label": "43/62", "naklon": null }, + "2680": { "label": "43/63", "naklon": null }, + "2840": { "label": "43/64", "naklon": null }, + "2682": { "label": "43/65", "naklon": null }, + "2683": { "label": "43/66", "naklon": null }, + "2684": { "label": "43/67", "naklon": 0 }, + "2685": { "label": "43/68", "naklon": null }, + "2686": { "label": "43/69", "naklon": null }, + "2687": { "label": "43/70", "naklon": null }, + "2688": { "label": "43/71", "naklon": null }, + "2689": { "label": "43/72", "naklon": null }, + "2690": { "label": "43/73", "naklon": null }, + "2691": { "label": "43/74", "naklon": null }, + "2692": { "label": "43/75", "naklon": null }, + "2693": { "label": "43/76", "naklon": 0 }, + "2694": { "label": "43/77", "naklon": null }, + "2695": { "label": "43/78", "naklon": null }, + "2696": { "label": "43/79", "naklon": 0 }, + "2697": { "label": "43/80", "naklon": null }, + "2698": { "label": "43/81", "naklon": 0 }, + "2699": { "label": "43/82", "naklon": null }, + "2700": { "label": "43/83", "naklon": 0 }, + "2744": { "label": "43/84", "naklon": null }, + "2745": { "label": "43/85", "naklon": 0 }, + "2746": { "label": "43/86", "naklon": null }, + "2747": { "label": "43/87", "naklon": 0 }, + "2748": { "label": "43/88", "naklon": null }, + "2749": { "label": "43/89", "naklon": 0 }, + "2841": { "label": "43/90", "naklon": null }, + "4237": { "label": "45/1", "naklon": 5 }, + "4226": { "label": "45/2", "naklon": 5 }, + "4242": { "label": "45/3", "naklon": 5 }, + "4179": { "label": "45/4", "naklon": 5 }, + "4247": { "label": "45/5", "naklon": 5 }, + "4245": { "label": "45/6", "naklon": 5 }, + "3872": { "label": "45/7", "naklon": 5 }, + "4175": { "label": "45/8", "naklon": 5 }, + "4236": { "label": "45/9", "naklon": 5 }, + "4170": { "label": "45/10", "naklon": 5 }, + "4238": { "label": "45/11", "naklon": 5 }, + "4246": { "label": "45/12", "naklon": 5 }, + "4166": { "label": "45/13", "naklon": 5 }, + "4227": { "label": "45/14", "naklon": 5 }, + "4171": { "label": "45/15", "naklon": 5 }, + "4180": { "label": "45/16", "naklon": 5 }, + "4244": { "label": "45/17", "naklon": 5 }, + "4199": { "label": "45/18", "naklon": 5 }, + "4239": { "label": "45/19", "naklon": 5 }, + "4207": { "label": "45/20", "naklon": 5 }, + "4223": { "label": "45/21", "naklon": 5 }, + "4230": { "label": "45/22", "naklon": 5 }, + "4233": { "label": "45/23", "naklon": 5 }, + "4222": { "label": "45/24", "naklon": 5 }, + "4217": { "label": "45/25", "naklon": 5 }, + "4243": { "label": "45/26", "naklon": 5 }, + "4200": { "label": "45/27", "naklon": 5 }, + "4228": { "label": "45/28", "naklon": 5 }, + "4211": { "label": "45/29", "naklon": 5 }, + "4234": { "label": "45/30", "naklon": 5 }, + "4235": { "label": "45/31", "naklon": 5 }, + "4203": { "label": "45/32", "naklon": 5 }, + "4240": { "label": "45/33", "naklon": 5 }, + "4224": { "label": "45/34", "naklon": 5 }, + "4232": { "label": "45/35", "naklon": 5 }, + "4231": { "label": "45/36", "naklon": 5 }, + "4161": { "label": "45/37", "naklon": 5 }, + "4225": { "label": "45/38", "naklon": 5 }, + "4241": { "label": "45/39", "naklon": 5 }, + "4229": { "label": "45/40", "naklon": 5 }, + "4221": { "label": "45/41", "naklon": 5 }, + "4212": { "label": "45/42", "naklon": 5 }, + "4216": { "label": "45/43", "naklon": 5 }, + "3864": { "label": "45/44", "naklon": null }, + "3806": { "label": "46/1", "naklon": 5 }, + "3813": { "label": "46/2", "naklon": 5 }, + "3815": { "label": "46/3", "naklon": 5 }, + "3807": { "label": "46/4", "naklon": 5 }, + "3895": { "label": "46/5", "naklon": 5 }, + "3809": { "label": "46/6", "naklon": 5 }, + "3820": { "label": "46/7", "naklon": 5 }, + "3805": { "label": "46/8", "naklon": 5 }, + "3894": { "label": "46/9", "naklon": 0 }, + "4055": { "label": "46/10", "naklon": 0 }, + "3812": { "label": "46/11", "naklon": 5 }, + "3822": { "label": "46/12", "naklon": 5 }, + "3821": { "label": "46/13", "naklon": 5 }, + "3808": { "label": "46/14", "naklon": 5 }, + "3799": { "label": "46/15", "naklon": 5 }, + "3816": { "label": "46/16", "naklon": 5 }, + "3751": { "label": "46/17", "naklon": 5 }, + "3814": { "label": "46/18", "naklon": 5 }, + "4044": { "label": "46/19", "naklon": 0 }, + "3931": { "label": "46/20", "naklon": 0 }, + "3902": { "label": "46/21", "naklon": 5 }, + "3916": { "label": "46/22", "naklon": 5 }, + "3892": { "label": "46/23", "naklon": 5 }, + "3914": { "label": "46/24", "naklon": 5 }, + "3898": { "label": "46/25", "naklon": 5 }, + "3897": { "label": "46/26", "naklon": 5 }, + "3885": { "label": "46/27", "naklon": 5 }, + "3906": { "label": "46/28", "naklon": 5 }, + "3930": { "label": "46/29", "naklon": 0 }, + "3936": { "label": "46/30", "naklon": 0 }, + "3860": { "label": "46/31", "naklon": 5 }, + "3841": { "label": "46/32", "naklon": 5 }, + "3873": { "label": "46/33", "naklon": 5 }, + "3854": { "label": "46/34", "naklon": 5 }, + "3939": { "label": "46/35", "naklon": 5 }, + "3858": { "label": "46/36", "naklon": 5 }, + "3940": { "label": "46/37", "naklon": 5 }, + "4035": { "label": "46/38", "naklon": 5 }, + "3373": { "label": "47/1", "naklon": 0 }, + "3374": { "label": "47/2", "naklon": 0 }, + "3384": { "label": "47/3", "naklon": 0 }, + "3385": { "label": "47/4", "naklon": 0 }, + "4051": { "label": "48/1", "naklon": 5 }, + "4041": { "label": "48/2", "naklon": 5 }, + "4056": { "label": "48/3", "naklon": 5 }, + "3875": { "label": "48/4", "naklon": 5 }, + "4061": { "label": "48/5", "naklon": 5 }, + "4047": { "label": "48/6", "naklon": 5 }, + "4060": { "label": "48/7", "naklon": 5 }, + "4059": { "label": "48/8", "naklon": 5 }, + "4058": { "label": "48/9", "naklon": 5 }, + "3635": { "label": "48/10", "naklon": 5 }, + "3640": { "label": "48/11", "naklon": 5 }, + "3747": { "label": "48/12", "naklon": 5 }, + "3629": { "label": "48/13", "naklon": 5 }, + "4048": { "label": "48/14", "naklon": 5 }, + "4063": { "label": "48/15", "naklon": 5 }, + "4062": { "label": "48/16", "naklon": 5 }, + "4043": { "label": "48/17", "naklon": 5 }, + "4052": { "label": "48/18", "naklon": 5 }, + "4042": { "label": "48/19", "naklon": 5 }, + "4053": { "label": "48/20", "naklon": 5 }, + "4167": { "label": "50/15A", "naklon": null }, + "4159": { "label": "50/15B", "naklon": null }, + "4183": { "label": "50/1", "naklon": 0 }, + "4157": { "label": "50/2", "naklon": 0 }, + "4160": { "label": "50/3", "naklon": 0 }, + "4173": { "label": "50/4", "naklon": 0 }, + "4177": { "label": "50/5", "naklon": 0 }, + "4174": { "label": "50/6", "naklon": 0 }, + "4178": { "label": "50/7", "naklon": 0 }, + "4195": { "label": "50/8", "naklon": 0 }, + "4169": { "label": "50/9", "naklon": 0 }, + "4162": { "label": "50/10", "naklon": 0 }, + "4158": { "label": "50/11", "naklon": 0 }, + "4182": { "label": "50/12", "naklon": 0 }, + "4194": { "label": "50/13", "naklon": 0 }, + "4184": { "label": "50/14", "naklon": 0 }, + "4197": { "label": "50/16", "naklon": null }, + "4164": { "label": "50/17", "naklon": null }, + "3306": { "label": "50/18", "naklon": null }, + "4168": { "label": "50/19", "naklon": null }, + "4193": { "label": "50/20", "naklon": null }, + "4187": { "label": "50/21", "naklon": null }, + "4163": { "label": "50/22", "naklon": null }, + "4165": { "label": "50/23", "naklon": null }, + "4185": { "label": "50/24", "naklon": null }, + "3904": { "label": "50/25", "naklon": null }, + "2619": { "label": "53/1", "naklon": 0 }, + "2623": { "label": "53/2", "naklon": 0 }, + "2617": { "label": "53/3", "naklon": 0 }, + "2622": { "label": "53/4", "naklon": 0 }, + "2618": { "label": "53/5", "naklon": 0 }, + "2626": { "label": "53/6", "naklon": 0 }, + "2869": { "label": "53/7", "naklon": 0 }, + "2613": { "label": "53/8", "naklon": 0 }, + "2608": { "label": "53/9", "naklon": 0 }, + "2611": { "label": "53/10", "naklon": 0 }, + "2598": { "label": "53/11", "naklon": 0 }, + "3528": { "label": "53/12", "naklon": 0 }, + "3545": { "label": "53/13", "naklon": 0 }, + "2620": { "label": "53/14", "naklon": 0 }, + "2612": { "label": "53/15", "naklon": 0 }, + "2615": { "label": "53/16", "naklon": 0 }, + "3722": { "label": "53/17", "naklon": 0 }, + "2624": { "label": "53/18", "naklon": 0 }, + "2609": { "label": "53/19", "naklon": 0 }, + "2625": { "label": "53/20", "naklon": 0 }, + "2602": { "label": "53/21", "naklon": 0 }, + "2610": { "label": "53/22", "naklon": 0 }, + "2599": { "label": "53/23", "naklon": 0 }, + "2605": { "label": "53/24", "naklon": 0 }, + "2593": { "label": "53/25", "naklon": 0 }, + "3074": { "label": "53/26", "naklon": 0 }, + "2740": { "label": "53/27", "naklon": 0 }, + "2614": { "label": "53/28", "naklon": 0 }, + "2601": { "label": "53/29", "naklon": 0 }, + "4196": { "label": "53/30", "naklon": 0 }, + "2607": { "label": "53/31", "naklon": 0 }, + "2582": { "label": "53/32", "naklon": 0 }, + "2594": { "label": "53/33", "naklon": 0 }, + "2589": { "label": "53/34", "naklon": 0 }, + "2596": { "label": "53/35", "naklon": 0 }, + "2603": { "label": "53/36", "naklon": 0 }, + "2597": { "label": "53/37", "naklon": 0 }, + "2590": { "label": "53/38", "naklon": 0 }, + "2581": { "label": "53/39", "naklon": 0 }, + "2583": { "label": "53/40", "naklon": 0 }, + "2580": { "label": "53/41", "naklon": 0 }, + "2579": { "label": "53/42", "naklon": 0 }, + "2797": { "label": "53/43", "naklon": 0 }, + "2577": { "label": "53/44", "naklon": 0 }, + "2586": { "label": "53/45", "naklon": 0 }, + "2588": { "label": "53/46", "naklon": 0 }, + "2591": { "label": "53/47", "naklon": 0 }, + "2592": { "label": "53/48", "naklon": 0 }, + "2573": { "label": "53/49", "naklon": 0 }, + "2595": { "label": "53/50", "naklon": 0 }, + "2587": { "label": "53/51", "naklon": 0 }, + "2578": { "label": "53/52", "naklon": 0 }, + "2574": { "label": "53/53", "naklon": 0 }, + "2571": { "label": "53/54", "naklon": 0 }, + "2570": { "label": "53/55", "naklon": 0 }, + "2576": { "label": "53/56", "naklon": 0 }, + "2881": { "label": "53/57", "naklon": 0 }, + "2575": { "label": "53/58", "naklon": 0 }, + "2572": { "label": "53/59", "naklon": 0 }, + "2569": { "label": "53/60", "naklon": 0 }, + "4324": { "label": "55/1", "naklon": 0 }, + "4319": { "label": "55/2", "naklon": 0 }, + "4327": { "label": "55/3", "naklon": 0 }, + "4333": { "label": "55/4", "naklon": 0 }, + "4332": { "label": "55/5", "naklon": 0 }, + "4320": { "label": "55/6", "naklon": 0 }, + "4317": { "label": "55/7", "naklon": 0 }, + "4318": { "label": "55/8", "naklon": 0 }, + "4328": { "label": "55/9", "naklon": 0 }, + "4323": { "label": "55/10", "naklon": 0 }, + "4325": { "label": "55/11", "naklon": 0 }, + "4326": { "label": "55/12", "naklon": 0 }, + "4316": { "label": "55/13", "naklon": 0 }, + "4322": { "label": "55/14", "naklon": 0 }, + "4331": { "label": "55/15", "naklon": 0 }, + "4321": { "label": "55/16", "naklon": 0 }, + "4315": { "label": "55/17", "naklon": 0 }, + "4329": { "label": "55/18", "naklon": 0 }, + "4334": { "label": "55/19", "naklon": 0 }, + "4330": { "label": "55/20", "naklon": 0 } +}; + + +let svetlaSorted = [{ "label": "1/3A", "node": 3993, "naklon": 0 }, +{ "label": "1/3B", "node": 3989, "naklon": 15 }, +{ "label": "1/1", "node": 3976, "naklon": 0 }, +{ "label": "1/2", "node": 4181, "naklon": 0 }, +{ "label": "1/4", "node": 4376, "naklon": 15 }, +{ "label": "1/5", "node": 3868, "naklon": 15 }, +{ "label": "1/6", "node": 3728, "naklon": 15 }, +{ "label": "1/7", "node": 3730, "naklon": 0 }, +{ "label": "1/8", "node": 4374, "naklon": 0 }, +{ "label": "1/9", "node": 3718, "naklon": 15 }, +{ "label": "1/10", "node": 4375, "naklon": 15 }, +{ "label": "1/11", "node": 4172, "naklon": 15 }, +{ "label": "1/12", "node": 4176, "naklon": 15 }, +{ "label": "2/1", "node": 3800, "naklon": 5 }, +{ "label": "2/2", "node": 3823, "naklon": 5 }, +{ "label": "2/3", "node": 3905, "naklon": 5 }, +{ "label": "2/4", "node": 3803, "naklon": 5 }, +{ "label": "2/5", "node": 3817, "naklon": 5 }, +{ "label": "2/6", "node": 3818, "naklon": 5 }, +{ "label": "2/7", "node": 3811, "naklon": 5 }, +{ "label": "2/8", "node": 3915, "naklon": 5 }, +{ "label": "2/9", "node": 3843, "naklon": 10 }, +{ "label": "2/10", "node": 3827, "naklon": 10 }, +{ "label": "2/11", "node": 4220, "naklon": 10 }, +{ "label": "2/12", "node": 3826, "naklon": 10 }, +{ "label": "2/13", "node": 3834, "naklon": 10 }, +{ "label": "2/14", "node": 3838, "naklon": 10 }, +{ "label": "2/15", "node": 2823, "naklon": 10 }, +{ "label": "2/16", "node": 3750, "naklon": 10 }, +{ "label": "2/17", "node": 3378, "naklon": 0 }, +{ "label": "2/18", "node": 3376, "naklon": 0 }, +{ "label": "2/19", "node": 3379, "naklon": 0 }, +{ "label": "2/20", "node": 3285, "naklon": 0 }, +{ "label": "2/21", "node": 3382, "naklon": 0 }, +{ "label": "2/22", "node": 3383, "naklon": 0 }, +{ "label": "2/24", "node": 3375, "naklon": 0 }, +{ "label": "2/25", "node": 3381, "naklon": 0 }, +{ "label": "2/26", "node": 3380, "naklon": 0 }, +{ "label": "2/27", "node": 3828, "naklon": 10 }, +{ "label": "2/28", "node": 3377, "naklon": 0 }, +{ "label": "7/1", "node": 3591, "naklon": 0 }, +{ "label": "7/2", "node": 3587, "naklon": 0 }, +{ "label": "7/3", "node": 3468, "naklon": 0 }, +{ "label": "7/4", "node": 3466, "naklon": 0 }, +{ "label": "7/5", "node": 3474, "naklon": 0 }, +{ "label": "7/6", "node": 3481, "naklon": 0 }, +{ "label": "7/7", "node": 3589, "naklon": 0 }, +{ "label": "7/8", "node": 3472, "naklon": 0 }, +{ "label": "7/9", "node": 3473, "naklon": 0 }, +{ "label": "7/10", "node": 3584, "naklon": 0 }, +{ "label": "7/11", "node": 3571, "naklon": 0 }, +{ "label": "7/12", "node": 3476, "naklon": 0 }, +{ "label": "7/13", "node": 3590, "naklon": 0 }, +{ "label": "7/14", "node": 3478, "naklon": 0 }, +{ "label": "7/15", "node": 3471, "naklon": 0 }, +{ "label": "7/16", "node": 3467, "naklon": 0 }, +{ "label": "7/17", "node": 3479, "naklon": 0 }, +{ "label": "7/18", "node": 3480, "naklon": 0 }, +{ "label": "7/19", "node": 3477, "naklon": 0 }, +{ "label": "12/1", "node": 3362, "naklon": 0 }, +{ "label": "12/2", "node": 3355, "naklon": 0 }, +{ "label": "12/3", "node": 3356, "naklon": 0 }, +{ "label": "12/4", "node": 3349, "naklon": 0 }, +{ "label": "12/5", "node": 3357, "naklon": 0 }, +{ "label": "12/6", "node": 3350, "naklon": 0 }, +{ "label": "12/7", "node": 3353, "naklon": 0 }, +{ "label": "12/8", "node": 3539, "naklon": 0 }, +{ "label": "12/9", "node": 3050, "naklon": 0 }, +{ "label": "12/10", "node": 3361, "naklon": 0 }, +{ "label": "12/11", "node": 3360, "naklon": 0 }, +{ "label": "12/12", "node": 3358, "naklon": 0 }, +{ "label": "12/13", "node": 3541, "naklon": 0 }, +{ "label": "12/14", "node": 3551, "naklon": 0 }, +{ "label": "12/15", "node": 3514, "naklon": 0 }, +{ "label": "12/16", "node": 3547, "naklon": 0 }, +{ "label": "12/17", "node": 3562, "naklon": 0 }, +{ "label": "12/18", "node": 3525, "naklon": 0 }, +{ "label": "12/19", "node": 3558, "naklon": 0 }, +{ "label": "12/20", "node": 3511, "naklon": 0 }, +{ "label": "12/21", "node": 3058, "naklon": 0 }, +{ "label": "12/22", "node": 3062, "naklon": 0 }, +{ "label": "12/23", "node": 3070, "naklon": 0 }, +{ "label": "12/24", "node": 3447, "naklon": 0 }, +{ "label": "12/25", "node": 3056, "naklon": 0 }, +{ "label": "12/26", "node": 3057, "naklon": 0 }, +{ "label": "12/27", "node": 3071, "naklon": 0 }, +{ "label": "12/28", "node": 3061, "naklon": 0 }, +{ "label": "12/29", "node": 3069, "naklon": 0 }, +{ "label": "12/30", "node": 3077, "naklon": 0 }, +{ "label": "12/31", "node": 3080, "naklon": 0 }, +{ "label": "12/32", "node": 3081, "naklon": 0 }, +{ "label": "12/33", "node": 3078, "naklon": 0 }, +{ "label": "12/34", "node": 4037, "naklon": 0 }, +{ "label": "12/35", "node": 3067, "naklon": 0 }, +{ "label": "12/36", "node": 3051, "naklon": 0 }, +{ "label": "12/37", "node": 2924, "naklon": 0 }, +{ "label": "12/38", "node": 3060, "naklon": 0 }, +{ "label": "12/39", "node": 3073, "naklon": 0 }, +{ "label": "12/40", "node": 3469, "naklon": 0 }, +{ "label": "12/41", "node": 2923, "naklon": 0 }, +{ "label": "12/42", "node": 2925, "naklon": 0 }, +{ "label": "12/43", "node": 3359, "naklon": 0 }, +{ "label": "12/44", "node": 3055, "naklon": 0 }, +{ "label": "12/45", "node": 2922, "naklon": 0 }, +{ "label": "12/46", "node": 3084, "naklon": 0 }, +{ "label": "12/47", "node": 3064, "naklon": 0 }, +{ "label": "12/48", "node": 3066, "naklon": 0 }, +{ "label": "12/49", "node": 3072, "naklon": 0 }, +{ "label": "13/13A", "node": 3415, "naklon": 0 }, +{ "label": "13/13B", "node": 3409, "naklon": 0 }, +{ "label": "13/13C", "node": 3399, "naklon": 0 }, +{ "label": "13/29A", "node": 3410, "naklon": 0 }, +{ "label": "13/29B", "node": 3407, "naklon": 0 }, +{ "label": "13/34A", "node": 3405, "naklon": 0 }, +{ "label": "13/34B", "node": 3404, "naklon": 0 }, +{ "label": "13/45A", "node": 3392, "naklon": 0 }, +{ "label": "13/45B", "node": 3386, "naklon": 0 }, +{ "label": "13/60A", "node": 3303, "naklon": 3 }, +{ "label": "13/60B", "node": 3302, "naklon": 3 }, +{ "label": "13/70A", "node": 3319, "naklon": 6 }, +{ "label": "13/70B", "node": 3317, "naklon": 6 }, +{ "label": "13/70C", "node": 3326, "naklon": 6 }, +{ "label": "13/73A", "node": 3351, "naklon": 6 }, +{ "label": "13/73B", "node": 3313, "naklon": 6 }, +{ "label": "13/83A", "node": 3316, "naklon": 0 }, +{ "label": "13/83B", "node": 3320, "naklon": 0 }, +{ "label": "13/95A", "node": 3336, "naklon": 0 }, +{ "label": "13/95B", "node": 3323, "naklon": 0 }, +{ "label": "13/98A", "node": 3339, "naklon": 0 }, +{ "label": "13/98B", "node": 3333, "naklon": 0 }, +{ "label": "13/1", "node": 3425, "naklon": 0 }, +{ "label": "13/2", "node": 3419, "naklon": 0 }, +{ "label": "13/3", "node": 3416, "naklon": 0 }, +{ "label": "13/4", "node": 3332, "naklon": 0 }, +{ "label": "13/5", "node": 3422, "naklon": 0 }, +{ "label": "13/6", "node": 3417, "naklon": 0 }, +{ "label": "13/7", "node": 3418, "naklon": 0 }, +{ "label": "13/8", "node": 3424, "naklon": 0 }, +{ "label": "13/9", "node": 3334, "naklon": 0 }, +{ "label": "13/10", "node": 4363, "naklon": 0 }, +{ "label": "13/11", "node": 3423, "naklon": 0 }, +{ "label": "13/12", "node": 3406, "naklon": 0 }, +{ "label": "13/14", "node": 3411, "naklon": 0 }, +{ "label": "13/15", "node": 3412, "naklon": 0 }, +{ "label": "13/16", "node": 3413, "naklon": 0 }, +{ "label": "13/17", "node": 3414, "naklon": 0 }, +{ "label": "13/18", "node": 3391, "naklon": 0 }, +{ "label": "13/19", "node": 3370, "naklon": 0 }, +{ "label": "13/20", "node": 3369, "naklon": 0 }, +{ "label": "13/21", "node": 3408, "naklon": 0 }, +{ "label": "13/22", "node": 3393, "naklon": 0 }, +{ "label": "13/23", "node": 3128, "naklon": 0 }, +{ "label": "13/24", "node": 3197, "naklon": 0 }, +{ "label": "13/25", "node": 4364, "naklon": 0 }, +{ "label": "13/26", "node": 3155, "naklon": 0 }, +{ "label": "13/27", "node": 3196, "naklon": 0 }, +{ "label": "13/28", "node": 3144, "naklon": 0 }, +{ "label": "13/30", "node": 3150, "naklon": 0 }, +{ "label": "13/31", "node": 3390, "naklon": 0 }, +{ "label": "13/32", "node": 3401, "naklon": 0 }, +{ "label": "13/33", "node": 3275, "naklon": 0 }, +{ "label": "13/35", "node": 3371, "naklon": 0 }, +{ "label": "13/36", "node": 3389, "naklon": 0 }, +{ "label": "13/37", "node": 3388, "naklon": 0 }, +{ "label": "13/38", "node": 3365, "naklon": 0 }, +{ "label": "13/39", "node": 3363, "naklon": 0 }, +{ "label": "13/40", "node": 3397, "naklon": 0 }, +{ "label": "13/40/1", "node": 3567, "naklon": 0 }, +{ "label": "13/41", "node": 3387, "naklon": 0 }, +{ "label": "13/42", "node": 3403, "naklon": 0 }, +{ "label": "13/43", "node": 3147, "naklon": 0 }, +{ "label": "13/44", "node": 3141, "naklon": 0 }, +{ "label": "13/46", "node": 3364, "naklon": 0 }, +{ "label": "13/47", "node": 3367, "naklon": 0 }, +{ "label": "13/48", "node": 3368, "naklon": 0 }, +{ "label": "13/49", "node": 3402, "naklon": 0 }, +{ "label": "13/50", "node": 3366, "naklon": 0 }, +{ "label": "13/51", "node": 3395, "naklon": 0 }, +{ "label": "13/52", "node": 3372, "naklon": 0 }, +{ "label": "13/53", "node": 3394, "naklon": 0 }, +{ "label": "13/54", "node": 3308, "naklon": 0 }, +{ "label": "13/54/1", "node": 3847, "naklon": 0 }, +{ "label": "13/55", "node": 3312, "naklon": 3 }, +{ "label": "13/56", "node": 3309, "naklon": 3 }, +{ "label": "13/57", "node": 3311, "naklon": 3 }, +{ "label": "13/58", "node": 3310, "naklon": 3 }, +{ "label": "13/59", "node": 4365, "naklon": 3 }, +{ "label": "13/60/1", "node": 4093, "naklon": 3 }, +{ "label": "13/61", "node": 3304, "naklon": 3 }, +{ "label": "13/62", "node": 3307, "naklon": 3 }, +{ "label": "13/63", "node": 3271, "naklon": 3 }, +{ "label": "13/64", "node": 3301, "naklon": 3 }, +{ "label": "13/65", "node": 4366, "naklon": 3 }, +{ "label": "13/66", "node": 3300, "naklon": 3 }, +{ "label": "13/67", "node": 3185, "naklon": 0 }, +{ "label": "13/68", "node": 3184, "naklon": 0 }, +{ "label": "13/69", "node": 3188, "naklon": 0 }, +{ "label": "13/71", "node": 3343, "naklon": 6 }, +{ "label": "13/71/1", "node": 3819, "naklon": 6 }, +{ "label": "13/71/2", "node": 3880, "naklon": 6 }, +{ "label": "13/72", "node": 3348, "naklon": 6 }, +{ "label": "13/74", "node": 3344, "naklon": 6 }, +{ "label": "13/75", "node": 3346, "naklon": 6 }, +{ "label": "13/75/1", "node": 3597, "naklon": 6 }, +{ "label": "13/76", "node": 3345, "naklon": 6 }, +{ "label": "13/77", "node": 3322, "naklon": 0 }, +{ "label": "13/78", "node": 3325, "naklon": 0 }, +{ "label": "13/78/1", "node": 4310, "naklon": 0 }, +{ "label": "13/79", "node": 3315, "naklon": 0 }, +{ "label": "13/80", "node": 3328, "naklon": 0 }, +{ "label": "13/81", "node": 3321, "naklon": 0 }, +{ "label": "13/82", "node": 3324, "naklon": 0 }, +{ "label": "13/84", "node": 3140, "naklon": 0 }, +{ "label": "13/85", "node": 3153, "naklon": 0 }, +{ "label": "13/86", "node": 3145, "naklon": 0 }, +{ "label": "13/87", "node": 3134, "naklon": 0 }, +{ "label": "13/88", "node": 3151, "naklon": 0 }, +{ "label": "13/89", "node": 3143, "naklon": 0 }, +{ "label": "13/90", "node": 3318, "naklon": 0 }, +{ "label": "13/91", "node": 3347, "naklon": 0 }, +{ "label": "13/94", "node": 3314, "naklon": 0 }, +{ "label": "13/96", "node": 3331, "naklon": 0 }, +{ "label": "13/97", "node": 3327, "naklon": 0 }, +{ "label": "13/99", "node": 3329, "naklon": 0 }, +{ "label": "13/100", "node": 3337, "naklon": 0 }, +{ "label": "13/101", "node": 3330, "naklon": 0 }, +{ "label": "13/102", "node": 3335, "naklon": 0 }, +{ "label": "13/103", "node": 3420, "naklon": 0 }, +{ "label": "13/104", "node": 3421, "naklon": 0 }, +{ "label": "13/105", "node": 4361, "naklon": 0 }, +{ "label": "13/106", "node": 4362, "naklon": 0 }, +{ "label": "13/107", "node": 3526, "naklon": 0 }, +{ "label": "13/108", "node": 4424, "naklon": null }, +{ "label": "13/109", "node": 3561, "naklon": null }, +{ "label": "13/110", "node": 3527, "naklon": null }, +{ "label": "13/111", "node": 3521, "naklon": null }, +{ "label": "13/112", "node": 3552, "naklon": null }, +{ "label": "13/113", "node": 3544, "naklon": null }, +{ "label": "13/114", "node": 3534, "naklon": null }, +{ "label": "13/115", "node": 3516, "naklon": null }, +{ "label": "13/116", "node": 3513, "naklon": null }, +{ "label": "13/117", "node": 3565, "naklon": null }, +{ "label": "13/118", "node": 3866, "naklon": null }, +{ "label": "14/1", "node": 3136, "naklon": 0 }, +{ "label": "14/2", "node": 3137, "naklon": 0 }, +{ "label": "14/3", "node": 3135, "naklon": 0 }, +{ "label": "14/4", "node": 3149, "naklon": 0 }, +{ "label": "14/5", "node": 3142, "naklon": 0 }, +{ "label": "14/6", "node": 3342, "naklon": 0 }, +{ "label": "14/7", "node": 3340, "naklon": 0 }, +{ "label": "14/8", "node": 3152, "naklon": 0 }, +{ "label": "14/9", "node": 3886, "naklon": 0 }, +{ "label": "14/10", "node": 3341, "naklon": null }, +{ "label": "14/11", "node": 3352, "naklon": null }, +{ "label": "15/1", "node": 3396, "naklon": 5 }, +{ "label": "15/2", "node": 2784, "naklon": 5 }, +{ "label": "15/3", "node": 2788, "naklon": 5 }, +{ "label": "15/4", "node": 2801, "naklon": 5 }, +{ "label": "15/5", "node": 2815, "naklon": 5 }, +{ "label": "15/6", "node": 2829, "naklon": 5 }, +{ "label": "15/7", "node": 2796, "naklon": 5 }, +{ "label": "15/8", "node": 2803, "naklon": 5 }, +{ "label": "15/8/1", "node": 4304, "naklon": 5 }, +{ "label": "15/8/2", "node": 4311, "naklon": 5 }, +{ "label": "15/9", "node": 2821, "naklon": 5 }, +{ "label": "15/10", "node": 3400, "naklon": 5 }, +{ "label": "15/11", "node": 2799, "naklon": 5 }, +{ "label": "15/12", "node": 2804, "naklon": 5 }, +{ "label": "15/12/1", "node": 4303, "naklon": 5 }, +{ "label": "15/12/2", "node": 4309, "naklon": 5 }, +{ "label": "15/13", "node": 2806, "naklon": 5 }, +{ "label": "15/14", "node": 2787, "naklon": 5 }, +{ "label": "15/15", "node": 2809, "naklon": 5 }, +{ "label": "15/16", "node": 2814, "naklon": 0 }, +{ "label": "15/17", "node": 3934, "naklon": 0 }, +{ "label": "15/18", "node": 3192, "naklon": 0 }, +{ "label": "15/19", "node": 2812, "naklon": 0 }, +{ "label": "15/20", "node": 4070, "naklon": 0 }, +{ "label": "15/21", "node": 2826, "naklon": 0 }, +{ "label": "15/22", "node": 2808, "naklon": 3 }, +{ "label": "15/23", "node": 2795, "naklon": 3 }, +{ "label": "15/24", "node": 2807, "naklon": 3 }, +{ "label": "15/25", "node": 2831, "naklon": 0 }, +{ "label": "15/26", "node": 2862, "naklon": null }, +{ "label": "15/27", "node": 2861, "naklon": 0 }, +{ "label": "15/28", "node": 2866, "naklon": 0 }, +{ "label": "15/28/1", "node": 3546, "naklon": 0 }, +{ "label": "15/29", "node": 4146, "naklon": 0 }, +{ "label": "15/29/1", "node": 3001, "naklon": 0 }, +{ "label": "15/30", "node": 2835, "naklon": 0 }, +{ "label": "15/31", "node": 2874, "naklon": 0 }, +{ "label": "15/32", "node": 2852, "naklon": 0 }, +{ "label": "15/33", "node": 2851, "naklon": 0 }, +{ "label": "15/33/1", "node": 3560, "naklon": 0 }, +{ "label": "15/34", "node": 2858, "naklon": 0 }, +{ "label": "15/34/1", "node": 4306, "naklon": 0 }, +{ "label": "15/35", "node": 2856, "naklon": 0 }, +{ "label": "15/36", "node": 2847, "naklon": 0 }, +{ "label": "15/36/1", "node": 3556, "naklon": 0 }, +{ "label": "15/37", "node": 3950, "naklon": 0 }, +{ "label": "15/38", "node": 2848, "naklon": 0 }, +{ "label": "15/39", "node": 2863, "naklon": 0 }, +{ "label": "15/39/1", "node": 4313, "naklon": 0 }, +{ "label": "15/40", "node": 2873, "naklon": 0 }, +{ "label": "15/40/1", "node": 2984, "naklon": 0 }, +{ "label": "15/41", "node": 2854, "naklon": 0 }, +{ "label": "15/42", "node": 2859, "naklon": 0 }, +{ "label": "15/43", "node": 2872, "naklon": 0 }, +{ "label": "15/44", "node": 2849, "naklon": 0 }, +{ "label": "15/45", "node": 2864, "naklon": 0 }, +{ "label": "15/46", "node": 3553, "naklon": null }, +{ "label": "15/47", "node": 3021, "naklon": null }, +{ "label": "15/47/1", "node": 3008, "naklon": null }, +{ "label": "15/48", "node": 3017, "naklon": null }, +{ "label": "15/49", "node": 3014, "naklon": null }, +{ "label": "15/50", "node": 2981, "naklon": null }, +{ "label": "15/51", "node": 3020, "naklon": null }, +{ "label": "15/52", "node": 3027, "naklon": null }, +{ "label": "15/53", "node": 3006, "naklon": null }, +{ "label": "15/54", "node": 3012, "naklon": null }, +{ "label": "15/55", "node": 2738, "naklon": 0 }, +{ "label": "15/56", "node": 2725, "naklon": 0 }, +{ "label": "15/57", "node": 3016, "naklon": null }, +{ "label": "15/58", "node": 3005, "naklon": null }, +{ "label": "15/58/1", "node": 3009, "naklon": null }, +{ "label": "15/59", "node": 3010, "naklon": 0 }, +{ "label": "15/59/1", "node": 3538, "naklon": 0 }, +{ "label": "15/59/2", "node": 4145, "naklon": 0 }, +{ "label": "15/60", "node": 2713, "naklon": 0 }, +{ "label": "15/61", "node": 2789, "naklon": 0 }, +{ "label": "15/62", "node": 2736, "naklon": 0 }, +{ "label": "15/63", "node": 2739, "naklon": 0 }, +{ "label": "15/64", "node": 4346, "naklon": 0 }, +{ "label": "15/65", "node": 2731, "naklon": 0 }, +{ "label": "15/66", "node": 2818, "naklon": 0 }, +{ "label": "15/66/1", "node": 3557, "naklon": 0 }, +{ "label": "15/67", "node": 2822, "naklon": 0 }, +{ "label": "15/68", "node": 2833, "naklon": 0 }, +{ "label": "15/69", "node": 2834, "naklon": 0 }, +{ "label": "15/70", "node": 3097, "naklon": 0 }, +{ "label": "15/71", "node": 2824, "naklon": 0 }, +{ "label": "15/72", "node": 2828, "naklon": 0 }, +{ "label": "15/73", "node": 2600, "naklon": 0 }, +{ "label": "15/73/1", "node": 4314, "naklon": 0 }, +{ "label": "15/74", "node": 2832, "naklon": 0 }, +{ "label": "15/75", "node": 4360, "naklon": 0 }, +{ "label": "15/76", "node": 2846, "naklon": 0 }, +{ "label": "15/77", "node": 2584, "naklon": 0 }, +{ "label": "15/78", "node": 2843, "naklon": 0 }, +{ "label": "15/78/1", "node": 4308, "naklon": 0 }, +{ "label": "15/79", "node": 4144, "naklon": null }, +{ "label": "15/80", "node": 2844, "naklon": 0 }, +{ "label": "15/81", "node": 2842, "naklon": 0 }, +{ "label": "15/82", "node": 2838, "naklon": 0 }, +{ "label": "15/83", "node": 2837, "naklon": null }, +{ "label": "15/83/1", "node": 3555, "naklon": null }, +{ "label": "15/84", "node": 2839, "naklon": 0 }, +{ "label": "15/85", "node": 2830, "naklon": 0 }, +{ "label": "15/86", "node": 4066, "naklon": 0 }, +{ "label": "15/87", "node": 2836, "naklon": 0 }, +{ "label": "15/88", "node": 2911, "naklon": 0 }, +{ "label": "15/89", "node": 2825, "naklon": 0 }, +{ "label": "15/90", "node": 2811, "naklon": 0 }, +{ "label": "15/94", "node": 3740, "naklon": 15 }, +{ "label": "15/95", "node": 2734, "naklon": 15 }, +{ "label": "15/96", "node": 3105, "naklon": 15 }, +{ "label": "15/97", "node": 2732, "naklon": 15 }, +{ "label": "15/98", "node": 2727, "naklon": 15 }, +{ "label": "15/99", "node": 2735, "naklon": 15 }, +{ "label": "15/100", "node": 3926, "naklon": 15 }, +{ "label": "15/101", "node": 2918, "naklon": 0 }, +{ "label": "15/102", "node": 2705, "naklon": 10 }, +{ "label": "15/103", "node": 2708, "naklon": 10 }, +{ "label": "15/104", "node": 2721, "naklon": 10 }, +{ "label": "15/105", "node": 2719, "naklon": 10 }, +{ "label": "15/106", "node": 2919, "naklon": 10 }, +{ "label": "15/107", "node": 3101, "naklon": 10 }, +{ "label": "15/108", "node": 2853, "naklon": 10 }, +{ "label": "15/109", "node": 2715, "naklon": 10 }, +{ "label": "15/110", "node": 2712, "naklon": 0 }, +{ "label": "15/111", "node": 2711, "naklon": 0 }, +{ "label": "15/112", "node": 2709, "naklon": 0 }, +{ "label": "15/113", "node": 2710, "naklon": 0 }, +{ "label": "15/114", "node": 2907, "naklon": 0 }, +{ "label": "15/115", "node": 2906, "naklon": 0 }, +{ "label": "15/116", "node": 2908, "naklon": 0 }, +{ "label": "15/117", "node": 2901, "naklon": 0 }, +{ "label": "15/118", "node": 2913, "naklon": 0 }, +{ "label": "15/119", "node": 3656, "naklon": 0 }, +{ "label": "15/120", "node": 2781, "naklon": 0 }, +{ "label": "15/121", "node": 2802, "naklon": 0 }, +{ "label": "15/122", "node": 2791, "naklon": 0 }, +{ "label": "15/123", "node": 2783, "naklon": 0 }, +{ "label": "15/124", "node": 2794, "naklon": 0 }, +{ "label": "15/125", "node": 3139, "naklon": 0 }, +{ "label": "15/126", "node": 3229, "naklon": 5 }, +{ "label": "15/127", "node": 3239, "naklon": 5 }, +{ "label": "15/128", "node": 3230, "naklon": 5 }, +{ "label": "15/129", "node": 4016, "naklon": null }, +{ "label": "16/16A", "node": 3608, "naklon": 0 }, +{ "label": "16/16B", "node": 4151, "naklon": 0 }, +{ "label": "16/1", "node": 3710, "naklon": 0 }, +{ "label": "16/2", "node": 3726, "naklon": 0 }, +{ "label": "16/3", "node": 3743, "naklon": 0 }, +{ "label": "16/4", "node": 3724, "naklon": 0 }, +{ "label": "16/5", "node": 3712, "naklon": 0 }, +{ "label": "16/6", "node": 3739, "naklon": 0 }, +{ "label": "16/7", "node": 3742, "naklon": 0 }, +{ "label": "16/8", "node": 3731, "naklon": 0 }, +{ "label": "16/9", "node": 3727, "naklon": 0 }, +{ "label": "16/10", "node": 3729, "naklon": 0 }, +{ "label": "16/11", "node": 3736, "naklon": 0 }, +{ "label": "16/12", "node": 3713, "naklon": 0 }, +{ "label": "16/13", "node": 3715, "naklon": 0 }, +{ "label": "16/14", "node": 3733, "naklon": 0 }, +{ "label": "16/15", "node": 3732, "naklon": 0 }, +{ "label": "16/17", "node": 3634, "naklon": 0 }, +{ "label": "16/18", "node": 3610, "naklon": 0 }, +{ "label": "16/19", "node": 3626, "naklon": 0 }, +{ "label": "16/20", "node": 3618, "naklon": 0 }, +{ "label": "16/21", "node": 3619, "naklon": 0 }, +{ "label": "16/22", "node": 3628, "naklon": 0 }, +{ "label": "16/23", "node": 3615, "naklon": 0 }, +{ "label": "16/24", "node": 3609, "naklon": 0 }, +{ "label": "16/25", "node": 3606, "naklon": 0 }, +{ "label": "16/26", "node": 3624, "naklon": 0 }, +{ "label": "16/27", "node": 3627, "naklon": 0 }, +{ "label": "16/28", "node": 3607, "naklon": 0 }, +{ "label": "16/29", "node": 4370, "naklon": 0 }, +{ "label": "16/30", "node": 3692, "naklon": 0 }, +{ "label": "16/31", "node": 3614, "naklon": 0 }, +{ "label": "16/32", "node": 3623, "naklon": 0 }, +{ "label": "16/33", "node": 4373, "naklon": 0 }, +{ "label": "16/34", "node": 3620, "naklon": 0 }, +{ "label": "16/35", "node": 3685, "naklon": 0 }, +{ "label": "16/36", "node": 3616, "naklon": 0 }, +{ "label": "16/37", "node": 3686, "naklon": 0 }, +{ "label": "16/38", "node": 3688, "naklon": 0 }, +{ "label": "16/39", "node": 3684, "naklon": 0 }, +{ "label": "16/40", "node": 3825, "naklon": 0 }, +{ "label": "16/41", "node": 3865, "naklon": 0 }, +{ "label": "16/42", "node": 3824, "naklon": 0 }, +{ "label": "16/43", "node": 3871, "naklon": 0 }, +{ "label": "16/44", "node": 3801, "naklon": 0 }, +{ "label": "16/45", "node": 3862, "naklon": 0 }, +{ "label": "16/46", "node": 3876, "naklon": 0 }, +{ "label": "16/47", "node": 3861, "naklon": 0 }, +{ "label": "16/48", "node": 4215, "naklon": 0 }, +{ "label": "16/49", "node": 3605, "naklon": 10 }, +{ "label": "16/50", "node": 3603, "naklon": 10 }, +{ "label": "16/51", "node": 3592, "naklon": 10 }, +{ "label": "16/52", "node": 3598, "naklon": 10 }, +{ "label": "16/53", "node": 3594, "naklon": 10 }, +{ "label": "16/54", "node": 3593, "naklon": 10 }, +{ "label": "16/55", "node": 3630, "naklon": 10 }, +{ "label": "16/56", "node": 3763, "naklon": 10 }, +{ "label": "16/57", "node": 3746, "naklon": 10 }, +{ "label": "16/58", "node": 3699, "naklon": 0 }, +{ "label": "16/59", "node": 3698, "naklon": 0 }, +{ "label": "16/60", "node": 3709, "naklon": null }, +{ "label": "16/61", "node": 3708, "naklon": 0 }, +{ "label": "16/62", "node": 3703, "naklon": null }, +{ "label": "16/63", "node": 3700, "naklon": 0 }, +{ "label": "16/64", "node": 3701, "naklon": null }, +{ "label": "16/65", "node": 3704, "naklon": 0 }, +{ "label": "16/66", "node": 3707, "naklon": null }, +{ "label": "16/67", "node": 3810, "naklon": 0 }, +{ "label": "16/68", "node": 4208, "naklon": null }, +{ "label": "16/69", "node": 3867, "naklon": 0 }, +{ "label": "16/70", "node": 4372, "naklon": null }, +{ "label": "16/71", "node": 3881, "naklon": 0 }, +{ "label": "16/72", "node": 4204, "naklon": null }, +{ "label": "16/73", "node": 3869, "naklon": 0 }, +{ "label": "16/74", "node": 4202, "naklon": null }, +{ "label": "16/75", "node": 3830, "naklon": 0 }, +{ "label": "16/76", "node": 3870, "naklon": null }, +{ "label": "16/77", "node": 3964, "naklon": 0 }, +{ "label": "16/78", "node": 3849, "naklon": 0 }, +{ "label": "16/79", "node": 3694, "naklon": null }, +{ "label": "16/80", "node": 3717, "naklon": 0 }, +{ "label": "16/81", "node": 3877, "naklon": null }, +{ "label": "16/82", "node": 3755, "naklon": 0 }, +{ "label": "16/83", "node": 3725, "naklon": null }, +{ "label": "16/84", "node": 3716, "naklon": 0 }, +{ "label": "16/85", "node": 3696, "naklon": null }, +{ "label": "16/86", "node": 3702, "naklon": 0 }, +{ "label": "16/87", "node": 3706, "naklon": null }, +{ "label": "16/88", "node": 3850, "naklon": 0 }, +{ "label": "16/89", "node": 3848, "naklon": null }, +{ "label": "16/90", "node": 3737, "naklon": null }, +{ "label": "16/91", "node": 3705, "naklon": 0 }, +{ "label": "16/92", "node": 3723, "naklon": null }, +{ "label": "16/93", "node": 3842, "naklon": 0 }, +{ "label": "16/94", "node": 3735, "naklon": null }, +{ "label": "16/95", "node": 3719, "naklon": 0 }, +{ "label": "16/96", "node": 3697, "naklon": 0 }, +{ "label": "16/97", "node": 3711, "naklon": 0 }, +{ "label": "16/98", "node": 4107, "naklon": null }, +{ "label": "16/99", "node": 4112, "naklon": 5 }, +{ "label": "16/100", "node": 4106, "naklon": 5 }, +{ "label": "16/101", "node": 4111, "naklon": 5 }, +{ "label": "16/102", "node": 4091, "naklon": null }, +{ "label": "16/103", "node": 4104, "naklon": 5 }, +{ "label": "16/104", "node": 4094, "naklon": null }, +{ "label": "16/105", "node": 4089, "naklon": 5 }, +{ "label": "16/106", "node": 4095, "naklon": null }, +{ "label": "16/107", "node": 4102, "naklon": 5 }, +{ "label": "16/108", "node": 4105, "naklon": null }, +{ "label": "16/109", "node": 3859, "naklon": null }, +{ "label": "16/110", "node": 4090, "naklon": 5 }, +{ "label": "16/111", "node": 4110, "naklon": null }, +{ "label": "16/112", "node": 4097, "naklon": 5 }, +{ "label": "16/113", "node": 4099, "naklon": null }, +{ "label": "16/114", "node": 4096, "naklon": null }, +{ "label": "16/115", "node": 4101, "naklon": 5 }, +{ "label": "16/116", "node": 4109, "naklon": null }, +{ "label": "16/117", "node": 4092, "naklon": 5 }, +{ "label": "16/118", "node": 3631, "naklon": null }, +{ "label": "16/119", "node": 3632, "naklon": 0 }, +{ "label": "16/120", "node": 3641, "naklon": null }, +{ "label": "16/121", "node": 3638, "naklon": 0 }, +{ "label": "16/122", "node": 3637, "naklon": null }, +{ "label": "16/123", "node": 4142, "naklon": null }, +{ "label": "16/124", "node": 4147, "naklon": 5 }, +{ "label": "16/125", "node": 4139, "naklon": 5 }, +{ "label": "20/30A", "node": 3172, "naklon": 2 }, +{ "label": "20/30B", "node": 3164, "naklon": 2 }, +{ "label": "20/1", "node": 3247, "naklon": 10 }, +{ "label": "20/2", "node": 3296, "naklon": 10 }, +{ "label": "20/3", "node": 3246, "naklon": 10 }, +{ "label": "20/4", "node": 3270, "naklon": 10 }, +{ "label": "20/5", "node": 3294, "naklon": 10 }, +{ "label": "20/6", "node": 3298, "naklon": 10 }, +{ "label": "20/7", "node": 3297, "naklon": 10 }, +{ "label": "20/8", "node": 3293, "naklon": 10 }, +{ "label": "20/9", "node": 3299, "naklon": 10 }, +{ "label": "20/10", "node": 3295, "naklon": 10 }, +{ "label": "20/11", "node": 3244, "naklon": 10 }, +{ "label": "20/12", "node": 3249, "naklon": 10 }, +{ "label": "20/13", "node": 3268, "naklon": 10 }, +{ "label": "20/14", "node": 3245, "naklon": 10 }, +{ "label": "20/15", "node": 3278, "naklon": 10 }, +{ "label": "20/16", "node": 3280, "naklon": 10 }, +{ "label": "20/17", "node": 3292, "naklon": 10 }, +{ "label": "20/18", "node": 3287, "naklon": 10 }, +{ "label": "20/19", "node": 3282, "naklon": 10 }, +{ "label": "20/20", "node": 3273, "naklon": 0 }, +{ "label": "20/21", "node": 3157, "naklon": 0 }, +{ "label": "20/22", "node": 3283, "naklon": 0 }, +{ "label": "20/23", "node": 3159, "naklon": 0 }, +{ "label": "20/24", "node": 3289, "naklon": 0 }, +{ "label": "20/25", "node": 3163, "naklon": 0 }, +{ "label": "20/26", "node": 3126, "naklon": 0 }, +{ "label": "20/27", "node": 3171, "naklon": 0 }, +{ "label": "20/28", "node": 3162, "naklon": 0 }, +{ "label": "20/29", "node": 3279, "naklon": 10 }, +{ "label": "20/31", "node": 3173, "naklon": 0 }, +{ "label": "20/32", "node": 3127, "naklon": 0 }, +{ "label": "20/33", "node": 3131, "naklon": 0 }, +{ "label": "20/34", "node": 3129, "naklon": 0 }, +{ "label": "20/35", "node": 3276, "naklon": 2 }, +{ "label": "20/36", "node": 3290, "naklon": 2 }, +{ "label": "20/37", "node": 3132, "naklon": 0 }, +{ "label": "20/38", "node": 3138, "naklon": 0 }, +{ "label": "20/39", "node": 3272, "naklon": 0 }, +{ "label": "20/40", "node": 3291, "naklon": 0 }, +{ "label": "20/41", "node": 3277, "naklon": 10 }, +{ "label": "20/42", "node": 3286, "naklon": 10 }, +{ "label": "20/43", "node": 3281, "naklon": 10 }, +{ "label": "20/44", "node": 3288, "naklon": 10 }, +{ "label": "20/45", "node": 3284, "naklon": 10 }, +{ "label": "20/46", "node": 3167, "naklon": 10 }, +{ "label": "20/47", "node": 3872, "naklon": 0 }, +{ "label": "20/48", "node": 3124, "naklon": 0 }, +{ "label": "20/49", "node": 3133, "naklon": 0 }, +{ "label": "20/50", "node": 3158, "naklon": 0 }, +{ "label": "20/51", "node": 3169, "naklon": 0 }, +{ "label": "20/52", "node": 3146, "naklon": 0 }, +{ "label": "20/53", "node": 3160, "naklon": 0 }, +{ "label": "20/54", "node": 3248, "naklon": 0 }, +{ "label": "20/55", "node": 3156, "naklon": 0 }, +{ "label": "20/56", "node": 3161, "naklon": 0 }, +{ "label": "20/57", "node": 3170, "naklon": 0 }, +{ "label": "20/58", "node": 3168, "naklon": 0 }, +{ "label": "20/59", "node": 3125, "naklon": 0 }, +{ "label": "20/60", "node": 3166, "naklon": 0 }, +{ "label": "20/61", "node": 3130, "naklon": 0 }, +{ "label": "20/62", "node": 3563, "naklon": 0 }, +{ "label": "20/63", "node": 3550, "naklon": null }, +{ "label": "20/67", "node": 3269, "naklon": 0 }, +{ "label": "21/1", "node": 2921, "naklon": 0 }, +{ "label": "21/2", "node": 2707, "naklon": 0 }, +{ "label": "21/3", "node": 2723, "naklon": 0 }, +{ "label": "21/4", "node": 2716, "naklon": 0 }, +{ "label": "21/5", "node": 2717, "naklon": 0 }, +{ "label": "21/6", "node": 2720, "naklon": 0 }, +{ "label": "21/7", "node": 2722, "naklon": 0 }, +{ "label": "21/8", "node": 2718, "naklon": 0 }, +{ "label": "21/9", "node": 2724, "naklon": 0 }, +{ "label": "21/10", "node": 2742, "naklon": 0 }, +{ "label": "21/11", "node": 2743, "naklon": 0 }, +{ "label": "21/12", "node": 2733, "naklon": 0 }, +{ "label": "21/14", "node": 2903, "naklon": 0 }, +{ "label": "21/15", "node": 2917, "naklon": 0 }, +{ "label": "21/16", "node": 2897, "naklon": 0 }, +{ "label": "21/17", "node": 2914, "naklon": 0 }, +{ "label": "21/18", "node": 2898, "naklon": 0 }, +{ "label": "21/19", "node": 2773, "naklon": 0 }, +{ "label": "21/20", "node": 2895, "naklon": 0 }, +{ "label": "21/21", "node": 2896, "naklon": 0 }, +{ "label": "21/22", "node": 2771, "naklon": 0 }, +{ "label": "21/23", "node": 2772, "naklon": 0 }, +{ "label": "21/24", "node": 2793, "naklon": 0 }, +{ "label": "21/25", "node": 2902, "naklon": 0 }, +{ "label": "21/26", "node": 2910, "naklon": 0 }, +{ "label": "21/27", "node": 2909, "naklon": 0 }, +{ "label": "21/28", "node": 2920, "naklon": 0 }, +{ "label": "21/29", "node": 2916, "naklon": 0 }, +{ "label": "21/30", "node": 2904, "naklon": 0 }, +{ "label": "21/31", "node": 2915, "naklon": 0 }, +{ "label": "21/32", "node": 2905, "naklon": 0 }, +{ "label": "21/33", "node": 2900, "naklon": 0 }, +{ "label": "21/34", "node": 2899, "naklon": 0 }, +{ "label": "21/36", "node": 2741, "naklon": 0 }, +{ "label": "21/37", "node": 2714, "naklon": 0 }, +{ "label": "21/38", "node": 2701, "naklon": 0 }, +{ "label": "21/39", "node": 2703, "naklon": 0 }, +{ "label": "21/40", "node": 2704, "naklon": 0 }, +{ "label": "21/41", "node": 2702, "naklon": 0 }, +{ "label": "21/42", "node": 2706, "naklon": 0 }, +{ "label": "21/43", "node": 2776, "naklon": 0 }, +{ "label": "21/44", "node": 2770, "naklon": 0 }, +{ "label": "21/45", "node": 2786, "naklon": 0 }, +{ "label": "21/46", "node": 2779, "naklon": 0 }, +{ "label": "21/47", "node": 2782, "naklon": 0 }, +{ "label": "21/48", "node": 2785, "naklon": 0 }, +{ "label": "21/49", "node": 2769, "naklon": 0 }, +{ "label": "21/50", "node": 3354, "naklon": 0 }, +{ "label": "21/51", "node": 2778, "naklon": 0 }, +{ "label": "21/52", "node": 2775, "naklon": 0 }, +{ "label": "21/53", "node": 2780, "naklon": 0 }, +{ "label": "21/54", "node": 2790, "naklon": 0 }, +{ "label": "21/55", "node": 2792, "naklon": 0 }, +{ "label": "21/56", "node": 2774, "naklon": 0 }, +{ "label": "22/1", "node": 2630, "naklon": 0 }, +{ "label": "22/2", "node": 2631, "naklon": 0 }, +{ "label": "22/3", "node": 2632, "naklon": 0 }, +{ "label": "22/4", "node": 2633, "naklon": 0 }, +{ "label": "22/5", "node": 2634, "naklon": 0 }, +{ "label": "22/6", "node": 2636, "naklon": 0 }, +{ "label": "22/7", "node": 4367, "naklon": 0 }, +{ "label": "22/8", "node": 2637, "naklon": 0 }, +{ "label": "22/9", "node": 2638, "naklon": 0 }, +{ "label": "22/10", "node": 2639, "naklon": 0 }, +{ "label": "22/11", "node": 2640, "naklon": 0 }, +{ "label": "22/12", "node": 2641, "naklon": 0 }, +{ "label": "22/13", "node": 2642, "naklon": 0 }, +{ "label": "22/14", "node": 2643, "naklon": 0 }, +{ "label": "22/15", "node": 2644, "naklon": 0 }, +{ "label": "22/16", "node": 2645, "naklon": 0 }, +{ "label": "22/17", "node": 2646, "naklon": 0 }, +{ "label": "22/18", "node": 2647, "naklon": 0 }, +{ "label": "22/19", "node": 2648, "naklon": 0 }, +{ "label": "22/20", "node": 2649, "naklon": 0 }, +{ "label": "22/21", "node": 2650, "naklon": 0 }, +{ "label": "22/22", "node": 2651, "naklon": 0 }, +{ "label": "22/23", "node": 4103, "naklon": 0 }, +{ "label": "22/24", "node": 2653, "naklon": 0 }, +{ "label": "22/25", "node": 2654, "naklon": 0 }, +{ "label": "22/26", "node": 2655, "naklon": 0 }, +{ "label": "22/27", "node": 2656, "naklon": 0 }, +{ "label": "22/28", "node": 2657, "naklon": 0 }, +{ "label": "22/29", "node": 2658, "naklon": 0 }, +{ "label": "22/30", "node": 2659, "naklon": 0 }, +{ "label": "22/31", "node": 2660, "naklon": 0 }, +{ "label": "22/32", "node": 2661, "naklon": 0 }, +{ "label": "22/32/1", "node": 3015, "naklon": 0 }, +{ "label": "22/33", "node": 2662, "naklon": 0 }, +{ "label": "22/34", "node": 2663, "naklon": 0 }, +{ "label": "22/35", "node": 2664, "naklon": 0 }, +{ "label": "22/36", "node": 2665, "naklon": 0 }, +{ "label": "22/37", "node": 2666, "naklon": 0 }, +{ "label": "22/38", "node": 2667, "naklon": 0 }, +{ "label": "22/39", "node": 2668, "naklon": 0 }, +{ "label": "22/40", "node": 2669, "naklon": null }, +{ "label": "22/41", "node": 2670, "naklon": null }, +{ "label": "22/42", "node": 2671, "naklon": null }, +{ "label": "23/9A", "node": 3087, "naklon": 10 }, +{ "label": "23/9B", "node": 3090, "naklon": 10 }, +{ "label": "23/1", "node": 3075, "naklon": 0 }, +{ "label": "23/2", "node": 3089, "naklon": 0 }, +{ "label": "23/3", "node": 3088, "naklon": 0 }, +{ "label": "23/4", "node": 3228, "naklon": 10 }, +{ "label": "23/5", "node": 2751, "naklon": 10 }, +{ "label": "23/6", "node": 3243, "naklon": 10 }, +{ "label": "23/7", "node": 4349, "naklon": 10 }, +{ "label": "23/8", "node": 3102, "naklon": 10 }, +{ "label": "23/10", "node": 3099, "naklon": 10 }, +{ "label": "23/11", "node": 3103, "naklon": 10 }, +{ "label": "23/12", "node": 3093, "naklon": 10 }, +{ "label": "23/13", "node": 3098, "naklon": 10 }, +{ "label": "23/14", "node": 3092, "naklon": 10 }, +{ "label": "23/15", "node": 3233, "naklon": 0 }, +{ "label": "23/16", "node": 3095, "naklon": 0 }, +{ "label": "23/17", "node": 4074, "naklon": 0 }, +{ "label": "23/18", "node": 2729, "naklon": 0 }, +{ "label": "23/19", "node": 3234, "naklon": 0 }, +{ "label": "23/20", "node": 3094, "naklon": 0 }, +{ "label": "23/21", "node": 2817, "naklon": 0 }, +{ "label": "23/22", "node": 3226, "naklon": 0 }, +{ "label": "23/23", "node": 3225, "naklon": 0 }, +{ "label": "23/24", "node": 3237, "naklon": 0 }, +{ "label": "23/25", "node": 4250, "naklon": 0 }, +{ "label": "23/26", "node": 3059, "naklon": 10 }, +{ "label": "23/27", "node": 3238, "naklon": 10 }, +{ "label": "23/28", "node": 3242, "naklon": 10 }, +{ "label": "23/29", "node": 3236, "naklon": 10 }, +{ "label": "23/30", "node": 3112, "naklon": 10 }, +{ "label": "23/31", "node": 3224, "naklon": 0 }, +{ "label": "23/32", "node": 4298, "naklon": 10 }, +{ "label": "23/33", "node": 4150, "naklon": 10 }, +{ "label": "23/34", "node": 3091, "naklon": 10 }, +{ "label": "25/1", "node": 3771, "naklon": 5 }, +{ "label": "25/2", "node": 3777, "naklon": 5 }, +{ "label": "25/3", "node": 3749, "naklon": 5 }, +{ "label": "25/4", "node": 3769, "naklon": 5 }, +{ "label": "25/5", "node": 3765, "naklon": 5 }, +{ "label": "25/6", "node": 3785, "naklon": 5 }, +{ "label": "25/7", "node": 3761, "naklon": 5 }, +{ "label": "25/8", "node": 3758, "naklon": 5 }, +{ "label": "25/9", "node": 3766, "naklon": 5 }, +{ "label": "25/10", "node": 3779, "naklon": 5 }, +{ "label": "25/11", "node": 3899, "naklon": 10 }, +{ "label": "25/12", "node": 3922, "naklon": 10 }, +{ "label": "25/13", "node": 3912, "naklon": 10 }, +{ "label": "25/14", "node": 3933, "naklon": 10 }, +{ "label": "25/15", "node": 3921, "naklon": 10 }, +{ "label": "25/16", "node": 4300, "naklon": 10 }, +{ "label": "25/17", "node": 3927, "naklon": 10 }, +{ "label": "25/18", "node": 3212, "naklon": 10 }, +{ "label": "25/19", "node": 3208, "naklon": 10 }, +{ "label": "25/20", "node": 3207, "naklon": 10 }, +{ "label": "25/21", "node": 4294, "naklon": 10 }, +{ "label": "25/22", "node": 3209, "naklon": 10 }, +{ "label": "25/23", "node": 3745, "naklon": 10 }, +{ "label": "25/24", "node": 3762, "naklon": 10 }, +{ "label": "25/25", "node": 3215, "naklon": 10 }, +{ "label": "25/26", "node": 3210, "naklon": 10 }, +{ "label": "25/27", "node": 3211, "naklon": 10 }, +{ "label": "25/28", "node": 3206, "naklon": 10 }, +{ "label": "25/29", "node": 3918, "naklon": 5 }, +{ "label": "25/30", "node": 3928, "naklon": 5 }, +{ "label": "25/31", "node": 3917, "naklon": 5 }, +{ "label": "25/32", "node": 4029, "naklon": 0 }, +{ "label": "25/33", "node": 4038, "naklon": 0 }, +{ "label": "25/34", "node": 4022, "naklon": 0 }, +{ "label": "25/35", "node": 3937, "naklon": 0 }, +{ "label": "25/36", "node": 3190, "naklon": 0 }, +{ "label": "25/37", "node": 3835, "naklon": 0 }, +{ "label": "25/38", "node": 3201, "naklon": 0 }, +{ "label": "25/39", "node": 3193, "naklon": 0 }, +{ "label": "25/40", "node": 3191, "naklon": 0 }, +{ "label": "25/41", "node": 3203, "naklon": 0 }, +{ "label": "25/42", "node": 4301, "naklon": 0 }, +{ "label": "25/43", "node": 3223, "naklon": 0 }, +{ "label": "25/44", "node": 3202, "naklon": 0 }, +{ "label": "25/45", "node": 3205, "naklon": 0 }, +{ "label": "25/46", "node": 3194, "naklon": 0 }, +{ "label": "25/47", "node": 3198, "naklon": 0 }, +{ "label": "25/48", "node": 3204, "naklon": 0 }, +{ "label": "25/49", "node": 3200, "naklon": 0 }, +{ "label": "25/50", "node": 3216, "naklon": 0 }, +{ "label": "25/51", "node": 3932, "naklon": 5 }, +{ "label": "25/52", "node": 3923, "naklon": 5 }, +{ "label": "25/53", "node": 3913, "naklon": 5 }, +{ "label": "25/54", "node": 3900, "naklon": 5 }, +{ "label": "25/55", "node": 4189, "naklon": 10 }, +{ "label": "25/56", "node": 4191, "naklon": 10 }, +{ "label": "25/57", "node": 3790, "naklon": 10 }, +{ "label": "25/58", "node": 4190, "naklon": 10 }, +{ "label": "25/59", "node": 4302, "naklon": 0 }, +{ "label": "25/60", "node": 4351, "naklon": 0 }, +{ "label": "25/61", "node": 4075, "naklon": 0 }, +{ "label": "25/62", "node": 4071, "naklon": 0 }, +{ "label": "25/63", "node": 3784, "naklon": 0 }, +{ "label": "25/64", "node": 4065, "naklon": 0 }, +{ "label": "25/65", "node": 4297, "naklon": 0 }, +{ "label": "25/66", "node": 4295, "naklon": 0 }, +{ "label": "25/67", "node": 4299, "naklon": 0 }, +{ "label": "25/68", "node": 3772, "naklon": 0 }, +{ "label": "25/69", "node": 3941, "naklon": 0 }, +{ "label": "25/70", "node": 3782, "naklon": 0 }, +{ "label": "25/71", "node": 4068, "naklon": 0 }, +{ "label": "25/72", "node": 4073, "naklon": 0 }, +{ "label": "25/73", "node": 3901, "naklon": 5 }, +{ "label": "25/74", "node": 4296, "naklon": 5 }, +{ "label": "25/75", "node": 3910, "naklon": 5 }, +{ "label": "25/76", "node": 4293, "naklon": 5 }, +{ "label": "25/77", "node": 3919, "naklon": 5 }, +{ "label": "25/78", "node": 3924, "naklon": 5 }, +{ "label": "25/79", "node": 3909, "naklon": 5 }, +{ "label": "25/80", "node": 3896, "naklon": 5 }, +{ "label": "25/81", "node": 3911, "naklon": 5 }, +{ "label": "25/82", "node": 2819, "naklon": 15 }, +{ "label": "25/83", "node": 3776, "naklon": 15 }, +{ "label": "25/84", "node": 3752, "naklon": 15 }, +{ "label": "25/85", "node": 4353, "naklon": 15 }, +{ "label": "25/86", "node": 3791, "naklon": 0 }, +{ "label": "25/87", "node": 3770, "naklon": 0 }, +{ "label": "25/88", "node": 3760, "naklon": 0 }, +{ "label": "25/89", "node": 3115, "naklon": 0 }, +{ "label": "25/90", "node": 3738, "naklon": 0 }, +{ "label": "25/91", "node": 3748, "naklon": 0 }, +{ "label": "25/92", "node": 3753, "naklon": 0 }, +{ "label": "25/93", "node": 3775, "naklon": 0 }, +{ "label": "25/94", "node": 3778, "naklon": 5 }, +{ "label": "25/95", "node": 4078, "naklon": 5 }, +{ "label": "25/96", "node": 4088, "naklon": 5 }, +{ "label": "25/97", "node": 3856, "naklon": 5 }, +{ "label": "25/98", "node": 4084, "naklon": 5 }, +{ "label": "25/99", "node": 4069, "naklon": 5 }, +{ "label": "25/100", "node": 4188, "naklon": 5 }, +{ "label": "25/101", "node": 4064, "naklon": 5 }, +{ "label": "25/102", "node": 3792, "naklon": 5 }, +{ "label": "25/103", "node": 3780, "naklon": 5 }, +{ "label": "25/104", "node": 4034, "naklon": 5 }, +{ "label": "25/105", "node": 4072, "naklon": 5 }, +{ "label": "25/106", "node": 3884, "naklon": 5 }, +{ "label": "25/107", "node": 3793, "naklon": 5 }, +{ "label": "25/108", "node": 3863, "naklon": 5 }, +{ "label": "25/109", "node": 3855, "naklon": 5 }, +{ "label": "33/1", "node": 3846, "naklon": 0 }, +{ "label": "33/2", "node": 3943, "naklon": 0 }, +{ "label": "33/3", "node": 3903, "naklon": 0 }, +{ "label": "33/4", "node": 3982, "naklon": 0 }, +{ "label": "33/5", "node": 3879, "naklon": 0 }, +{ "label": "33/6", "node": 3887, "naklon": 0 }, +{ "label": "33/7", "node": 3920, "naklon": 5 }, +{ "label": "33/8", "node": 3942, "naklon": 5 }, +{ "label": "33/9", "node": 3829, "naklon": null }, +{ "label": "34/79A", "node": 3452, "naklon": 6 }, +{ "label": "34/79B", "node": 3460, "naklon": 6 }, +{ "label": "34/90A", "node": 3443, "naklon": 6 }, +{ "label": "34/90B", "node": 3445, "naklon": 6 }, +{ "label": "34/90C", "node": 3457, "naklon": 6 }, +{ "label": "34/97A", "node": 3461, "naklon": 6 }, +{ "label": "34/97B", "node": 3463, "naklon": 6 }, +{ "label": "34/98A", "node": 3426, "naklon": 6 }, +{ "label": "34/98B", "node": 3444, "naklon": 6 }, +{ "label": "34/99A", "node": 3453, "naklon": 6 }, +{ "label": "34/99B", "node": 3455, "naklon": 6 }, +{ "label": "34/1", "node": 4009, "naklon": 0 }, +{ "label": "34/2", "node": 3602, "naklon": 0 }, +{ "label": "34/3", "node": 3441, "naklon": 0 }, +{ "label": "34/4", "node": 3464, "naklon": 0 }, +{ "label": "34/5", "node": 3883, "naklon": 0 }, +{ "label": "34/6", "node": 4098, "naklon": 0 }, +{ "label": "34/7", "node": 4003, "naklon": 0 }, +{ "label": "34/8", "node": 4004, "naklon": 0 }, +{ "label": "34/9", "node": 3888, "naklon": 0 }, +{ "label": "34/10", "node": 3997, "naklon": 0 }, +{ "label": "34/11", "node": 4006, "naklon": 0 }, +{ "label": "34/12", "node": 4000, "naklon": 0 }, +{ "label": "34/13", "node": 4011, "naklon": 0 }, +{ "label": "34/14", "node": 3999, "naklon": 0 }, +{ "label": "34/15", "node": 3981, "naklon": 0 }, +{ "label": "34/16", "node": 3988, "naklon": 0 }, +{ "label": "34/17", "node": 3986, "naklon": 0 }, +{ "label": "34/18", "node": 3998, "naklon": 0 }, +{ "label": "34/19", "node": 3983, "naklon": 0 }, +{ "label": "34/20", "node": 4005, "naklon": 0 }, +{ "label": "34/21", "node": 4001, "naklon": 0 }, +{ "label": "34/22", "node": 4008, "naklon": 0 }, +{ "label": "34/23", "node": 4002, "naklon": 0 }, +{ "label": "34/24", "node": 3996, "naklon": 0 }, +{ "label": "34/25", "node": 4007, "naklon": 0 }, +{ "label": "34/26", "node": 4113, "naklon": 15 }, +{ "label": "34/27", "node": 3595, "naklon": 5 }, +{ "label": "34/28", "node": 3599, "naklon": 5 }, +{ "label": "34/29", "node": 3601, "naklon": 5 }, +{ "label": "34/30", "node": 4205, "naklon": 0 }, +{ "label": "34/31", "node": 3987, "naklon": null }, +{ "label": "34/32", "node": 4214, "naklon": 0 }, +{ "label": "34/33", "node": 4226, "naklon": 0 }, +{ "label": "34/34", "node": 4209, "naklon": 0 }, +{ "label": "34/35", "node": 4201, "naklon": 0 }, +{ "label": "34/36", "node": 3440, "naklon": 0 }, +{ "label": "34/37", "node": 3465, "naklon": 0 }, +{ "label": "34/38", "node": 3446, "naklon": 0 }, +{ "label": "34/39", "node": 4039, "naklon": 5 }, +{ "label": "34/40", "node": 4057, "naklon": 5 }, +{ "label": "34/41", "node": 3985, "naklon": 0 }, +{ "label": "34/42", "node": 3882, "naklon": 0 }, +{ "label": "34/43", "node": 4040, "naklon": 5 }, +{ "label": "34/44", "node": 3231, "naklon": 0 }, +{ "label": "34/45", "node": 3227, "naklon": 0 }, +{ "label": "34/46", "node": 3431, "naklon": 0 }, +{ "label": "34/47", "node": 4013, "naklon": 0 }, +{ "label": "34/48", "node": 4045, "naklon": 0 }, +{ "label": "34/49", "node": 3949, "naklon": 0 }, +{ "label": "34/50", "node": 3953, "naklon": 0 }, +{ "label": "34/51", "node": 3952, "naklon": 0 }, +{ "label": "34/52", "node": 3995, "naklon": 0 }, +{ "label": "34/53", "node": 3992, "naklon": 0 }, +{ "label": "34/54", "node": 4198, "naklon": 0 }, +{ "label": "34/55", "node": 3935, "naklon": 0 }, +{ "label": "34/56", "node": 4050, "naklon": 0 }, +{ "label": "34/57", "node": 4049, "naklon": 0 }, +{ "label": "34/58", "node": 4054, "naklon": 0 }, +{ "label": "34/59", "node": 3663, "naklon": 6 }, +{ "label": "34/60", "node": 3661, "naklon": 6 }, +{ "label": "34/61", "node": 3664, "naklon": 6 }, +{ "label": "34/62", "node": 3660, "naklon": 6 }, +{ "label": "34/63", "node": 3662, "naklon": 6 }, +{ "label": "34/65", "node": 3665, "naklon": 6 }, +{ "label": "34/66", "node": 3667, "naklon": 6 }, +{ "label": "34/67", "node": 3675, "naklon": 6 }, +{ "label": "34/68", "node": 3666, "naklon": 6 }, +{ "label": "34/69", "node": 3652, "naklon": 6 }, +{ "label": "34/70", "node": 3458, "naklon": 6 }, +{ "label": "34/70/1", "node": 4425, "naklon": 6 }, +{ "label": "34/71", "node": 3459, "naklon": 6 }, +{ "label": "34/72", "node": 3435, "naklon": 6 }, +{ "label": "34/73", "node": 3448, "naklon": 6 }, +{ "label": "34/74", "node": 3451, "naklon": 6 }, +{ "label": "34/75", "node": 3442, "naklon": 6 }, +{ "label": "34/76", "node": 3449, "naklon": 6 }, +{ "label": "34/77", "node": 3450, "naklon": 6 }, +{ "label": "34/78", "node": 3433, "naklon": 6 }, +{ "label": "34/80", "node": 3432, "naklon": 12 }, +{ "label": "34/81", "node": 3470, "naklon": 12 }, +{ "label": "34/82", "node": 3438, "naklon": 12 }, +{ "label": "34/83", "node": 3439, "naklon": 12 }, +{ "label": "34/84", "node": 4028, "naklon": 5 }, +{ "label": "34/85", "node": 3596, "naklon": 5 }, +{ "label": "34/86", "node": 4021, "naklon": 5 }, +{ "label": "34/87", "node": 3437, "naklon": 12 }, +{ "label": "34/88", "node": 3428, "naklon": 12 }, +{ "label": "34/89", "node": 3430, "naklon": 12 }, +{ "label": "34/91", "node": 3454, "naklon": 6 }, +{ "label": "34/92", "node": 3492, "naklon": 6 }, +{ "label": "34/93", "node": 3462, "naklon": 6 }, +{ "label": "34/94", "node": 3427, "naklon": 6 }, +{ "label": "34/95", "node": 3434, "naklon": 6 }, +{ "label": "34/96", "node": 3456, "naklon": 6 }, +{ "label": "34/98/1", "node": 4307, "naklon": 6 }, +{ "label": "35/1", "node": 3968, "naklon": 0 }, +{ "label": "35/2", "node": 3969, "naklon": 0 }, +{ "label": "35/3", "node": 3947, "naklon": 0 }, +{ "label": "35/4", "node": 3979, "naklon": 0 }, +{ "label": "35/5", "node": 3959, "naklon": 0 }, +{ "label": "35/6", "node": 3948, "naklon": 0 }, +{ "label": "35/7", "node": 3961, "naklon": 0 }, +{ "label": "35/8", "node": 3956, "naklon": 0 }, +{ "label": "35/9", "node": 3604, "naklon": 0 }, +{ "label": "35/10", "node": 3944, "naklon": 0 }, +{ "label": "35/11", "node": 3960, "naklon": 0 }, +{ "label": "35/12", "node": 3958, "naklon": 0 }, +{ "label": "35/13", "node": 4036, "naklon": 5 }, +{ "label": "35/18", "node": 3893, "naklon": 5 }, +{ "label": "35/19", "node": 4108, "naklon": 5 }, +{ "label": "35/20", "node": 4017, "naklon": 5 }, +{ "label": "35/21", "node": 3963, "naklon": 0 }, +{ "label": "35/22", "node": 3658, "naklon": 0 }, +{ "label": "35/23", "node": 3975, "naklon": 0 }, +{ "label": "35/24", "node": 3980, "naklon": 0 }, +{ "label": "35/25", "node": 4012, "naklon": 0 }, +{ "label": "35/26", "node": 3655, "naklon": 0 }, +{ "label": "35/27", "node": 3962, "naklon": 0 }, +{ "label": "35/28", "node": 3945, "naklon": 0 }, +{ "label": "35/29", "node": 3569, "naklon": 0 }, +{ "label": "35/30", "node": 3429, "naklon": 0 }, +{ "label": "35/31", "node": 3657, "naklon": 0 }, +{ "label": "35/32", "node": 3646, "naklon": 0 }, +{ "label": "35/33", "node": 3622, "naklon": 0 }, +{ "label": "35/34", "node": 3612, "naklon": 0 }, +{ "label": "35/35", "node": 3955, "naklon": 0 }, +{ "label": "35/37", "node": 3878, "naklon": 0 }, +{ "label": "35/38", "node": 3965, "naklon": 0 }, +{ "label": "35/39", "node": 3970, "naklon": 0 }, +{ "label": "35/40", "node": 3611, "naklon": 0 }, +{ "label": "35/41", "node": 2635, "naklon": 0 }, +{ "label": "35/42", "node": 3978, "naklon": 0 }, +{ "label": "35/43", "node": 4213, "naklon": 0 }, +{ "label": "35/44", "node": 3984, "naklon": 0 }, +{ "label": "35/45", "node": 4218, "naklon": 0 }, +{ "label": "35/46", "node": 3973, "naklon": 0 }, +{ "label": "35/47", "node": 3974, "naklon": 0 }, +{ "label": "35/48", "node": 3759, "naklon": 0 }, +{ "label": "35/49", "node": 3844, "naklon": 0 }, +{ "label": "35/50", "node": 3804, "naklon": 0 }, +{ "label": "35/51", "node": 3831, "naklon": 0 }, +{ "label": "35/52", "node": 3643, "naklon": 0 }, +{ "label": "35/53", "node": 3966, "naklon": 0 }, +{ "label": "35/54", "node": 3971, "naklon": 0 }, +{ "label": "35/55", "node": 3650, "naklon": 6 }, +{ "label": "35/56", "node": 3651, "naklon": 6 }, +{ "label": "35/57", "node": 3669, "naklon": 6 }, +{ "label": "35/58", "node": 3648, "naklon": 6 }, +{ "label": "35/59", "node": 3645, "naklon": 6 }, +{ "label": "35/60", "node": 3659, "naklon": 6 }, +{ "label": "35/61", "node": 3647, "naklon": 6 }, +{ "label": "35/62", "node": 3644, "naklon": 6 }, +{ "label": "35/63", "node": 3671, "naklon": 6 }, +{ "label": "35/64", "node": 3682, "naklon": 6 }, +{ "label": "35/65", "node": 3672, "naklon": 6 }, +{ "label": "35/66", "node": 3683, "naklon": 6 }, +{ "label": "35/67", "node": 3673, "naklon": 6 }, +{ "label": "35/68", "node": 3674, "naklon": 6 }, +{ "label": "35/69", "node": 3679, "naklon": 6 }, +{ "label": "35/70", "node": 3649, "naklon": 6 }, +{ "label": "35/71", "node": 3687, "naklon": 6 }, +{ "label": "35/72", "node": 3677, "naklon": 6 }, +{ "label": "35/73", "node": 3690, "naklon": 6 }, +{ "label": "35/74", "node": 3691, "naklon": 6 }, +{ "label": "35/75", "node": 3676, "naklon": 6 }, +{ "label": "35/76", "node": 3680, "naklon": 6 }, +{ "label": "35/77", "node": 3668, "naklon": 6 }, +{ "label": "35/78", "node": 3681, "naklon": 6 }, +{ "label": "35/79", "node": 3670, "naklon": 6 }, +{ "label": "35/80", "node": 3689, "naklon": 6 }, +{ "label": "35/81", "node": 3678, "naklon": 6 }, +{ "label": "35/82", "node": 3693, "naklon": 6 }, +{ "label": "35/83", "node": 3654, "naklon": null }, +{ "label": "36/1", "node": 4086, "naklon": 0 }, +{ "label": "36/2", "node": 4085, "naklon": 0 }, +{ "label": "36/3", "node": 4083, "naklon": 0 }, +{ "label": "36/4", "node": 4087, "naklon": 0 }, +{ "label": "36/5", "node": 4077, "naklon": 0 }, +{ "label": "36/6", "node": 4082, "naklon": 0 }, +{ "label": "36/7", "node": 4186, "naklon": 0 }, +{ "label": "36/8", "node": 4206, "naklon": 0 }, +{ "label": "36/9", "node": 4080, "naklon": 0 }, +{ "label": "36/10", "node": 4081, "naklon": 0 }, +{ "label": "36/11", "node": 4210, "naklon": 0 }, +{ "label": "36/12", "node": 4079, "naklon": 0 }, +{ "label": "36/13", "node": 4076, "naklon": 0 }, +{ "label": "36/14", "node": 3852, "naklon": 0 }, +{ "label": "36/15", "node": 2813, "naklon": 0 }, +{ "label": "36/16", "node": 4219, "naklon": 0 }, +{ "label": "37/1A", "node": 3104, "naklon": 15 }, +{ "label": "37/1B", "node": 3121, "naklon": 15 }, +{ "label": "37/2", "node": 3113, "naklon": 10 }, +{ "label": "37/3", "node": 3118, "naklon": 10 }, +{ "label": "37/4", "node": 3111, "naklon": 10 }, +{ "label": "37/5", "node": 4020, "naklon": 10 }, +{ "label": "37/6", "node": 3119, "naklon": 10 }, +{ "label": "37/7", "node": 3110, "naklon": 10 }, +{ "label": "37/8", "node": 3108, "naklon": 10 }, +{ "label": "37/12", "node": 3107, "naklon": 0 }, +{ "label": "37/13", "node": 3199, "naklon": 0 }, +{ "label": "37/14", "node": 3120, "naklon": 0 }, +{ "label": "37/15", "node": 3122, "naklon": 0 }, +{ "label": "37/16", "node": 3908, "naklon": 0 }, +{ "label": "37/17", "node": 3114, "naklon": 0 }, +{ "label": "37/18", "node": 3105, "naklon": 0 }, +{ "label": "37/19", "node": 3116, "naklon": 0 }, +{ "label": "37/20", "node": 3106, "naklon": 0 }, +{ "label": "37/21", "node": 2887, "naklon": 5 }, +{ "label": "37/22", "node": 2888, "naklon": 5 }, +{ "label": "37/23", "node": 2877, "naklon": 5 }, +{ "label": "37/24", "node": 2891, "naklon": 5 }, +{ "label": "37/25", "node": 2886, "naklon": 5 }, +{ "label": "37/26", "node": 2892, "naklon": 5 }, +{ "label": "37/27", "node": 2882, "naklon": 5 }, +{ "label": "37/28", "node": 2883, "naklon": 5 }, +{ "label": "37/29", "node": 2876, "naklon": 5 }, +{ "label": "37/30", "node": 3109, "naklon": 5 }, +{ "label": "37/31", "node": 4152, "naklon": 5 }, +{ "label": "37/32", "node": 3117, "naklon": 5 }, +{ "label": "37/33", "node": 2870, "naklon": 5 }, +{ "label": "37/34", "node": 2867, "naklon": 0 }, +{ "label": "37/35", "node": 2865, "naklon": 0 }, +{ "label": "37/36", "node": 3096, "naklon": 0 }, +{ "label": "37/37", "node": 2871, "naklon": 0 }, +{ "label": "37/38", "node": 2884, "naklon": 0 }, +{ "label": "37/39", "node": 2855, "naklon": 0 }, +{ "label": "37/40", "node": 2878, "naklon": 0 }, +{ "label": "37/41", "node": 2889, "naklon": 0 }, +{ "label": "37/42", "node": 2879, "naklon": 0 }, +{ "label": "37/43", "node": 2850, "naklon": 0 }, +{ "label": "37/44", "node": 2894, "naklon": 0 }, +{ "label": "37/45", "node": 2880, "naklon": 0 }, +{ "label": "37/46", "node": 2893, "naklon": 0 }, +{ "label": "37/47", "node": 2890, "naklon": 0 }, +{ "label": "37/48", "node": 4355, "naklon": 0 }, +{ "label": "37/49", "node": 2885, "naklon": 0 }, +{ "label": "37/50", "node": 2875, "naklon": 0 }, +{ "label": "38/30A", "node": 3486, "naklon": 5 }, +{ "label": "38/30B", "node": 3714, "naklon": 0 }, +{ "label": "38/32A", "node": 3483, "naklon": 5 }, +{ "label": "38/32B", "node": 3496, "naklon": 0 }, +{ "label": "38/35A", "node": 3487, "naklon": 5 }, +{ "label": "38/35B", "node": 3498, "naklon": 5 }, +{ "label": "38/38A", "node": 3578, "naklon": 5 }, +{ "label": "38/38B", "node": 3508, "naklon": 5 }, +{ "label": "38/59A", "node": 3787, "naklon": 5 }, +{ "label": "38/59B", "node": 3491, "naklon": 5 }, +{ "label": "38/1", "node": 3568, "naklon": null }, +{ "label": "38/2", "node": 3502, "naklon": 0 }, +{ "label": "38/3", "node": 3836, "naklon": 0 }, +{ "label": "38/4", "node": 3588, "naklon": 0 }, +{ "label": "38/5", "node": 3493, "naklon": 0 }, +{ "label": "38/6", "node": 3580, "naklon": 0 }, +{ "label": "38/7", "node": 3572, "naklon": 0 }, +{ "label": "38/8", "node": 3506, "naklon": 0 }, +{ "label": "38/9", "node": 3503, "naklon": 0 }, +{ "label": "38/10", "node": 3579, "naklon": 0 }, +{ "label": "38/11", "node": 3586, "naklon": 0 }, +{ "label": "38/12", "node": 3495, "naklon": 5 }, +{ "label": "38/13", "node": 3492, "naklon": 5 }, +{ "label": "38/14", "node": 3532, "naklon": 5 }, +{ "label": "38/15", "node": 3574, "naklon": 5 }, +{ "label": "38/16", "node": 4140, "naklon": 5 }, +{ "label": "38/17", "node": 3795, "naklon": 5 }, +{ "label": "38/18", "node": 3788, "naklon": 5 }, +{ "label": "38/19", "node": 3796, "naklon": 5 }, +{ "label": "38/20", "node": 3797, "naklon": 5 }, +{ "label": "38/21", "node": 3798, "naklon": 5 }, +{ "label": "38/22", "node": 3786, "naklon": 5 }, +{ "label": "38/23", "node": 4067, "naklon": 5 }, +{ "label": "38/24", "node": 3773, "naklon": 5 }, +{ "label": "38/25", "node": 3774, "naklon": 5 }, +{ "label": "38/26", "node": 3789, "naklon": 5 }, +{ "label": "38/27", "node": 3520, "naklon": null }, +{ "label": "38/29", "node": 3577, "naklon": 5 }, +{ "label": "38/31", "node": 3530, "naklon": null }, +{ "label": "38/33", "node": 3488, "naklon": 5 }, +{ "label": "38/34", "node": 3505, "naklon": 5 }, +{ "label": "38/36", "node": 3497, "naklon": 5 }, +{ "label": "38/37", "node": 3490, "naklon": 5 }, +{ "label": "38/39", "node": 3585, "naklon": 5 }, +{ "label": "38/40", "node": 3582, "naklon": 5 }, +{ "label": "38/41", "node": 3507, "naklon": 5 }, +{ "label": "38/42", "node": 3484, "naklon": 5 }, +{ "label": "38/43", "node": 3501, "naklon": 5 }, +{ "label": "38/44", "node": 3581, "naklon": 5 }, +{ "label": "38/45", "node": 4192, "naklon": 5 }, +{ "label": "38/46", "node": 3576, "naklon": 5 }, +{ "label": "38/47", "node": 3489, "naklon": 5 }, +{ "label": "38/48", "node": 3573, "naklon": 5 }, +{ "label": "38/49", "node": 3504, "naklon": 5 }, +{ "label": "38/50", "node": 3794, "naklon": 5 }, +{ "label": "38/51", "node": 3485, "naklon": 5 }, +{ "label": "38/52", "node": 3482, "naklon": 5 }, +{ "label": "38/53", "node": 3575, "naklon": 5 }, +{ "label": "38/54", "node": 3499, "naklon": 5 }, +{ "label": "38/55", "node": 3494, "naklon": 5 }, +{ "label": "38/56", "node": 3583, "naklon": 5 }, +{ "label": "38/57", "node": 3570, "naklon": 5 }, +{ "label": "38/58", "node": 3500, "naklon": 0 }, +{ "label": "38/63", "node": 3510, "naklon": null }, +{ "label": "38/64", "node": 3512, "naklon": null }, +{ "label": "38/67", "node": 3535, "naklon": null }, +{ "label": "38/68", "node": 3531, "naklon": null }, +{ "label": "38/69", "node": 3537, "naklon": null }, +{ "label": "39/1", "node": 3522, "naklon": 10 }, +{ "label": "39/2", "node": 4018, "naklon": 10 }, +{ "label": "39/3", "node": 4019, "naklon": 10 }, +{ "label": "39/4", "node": 4154, "naklon": 5 }, +{ "label": "39/5", "node": 3907, "naklon": 5 }, +{ "label": "39/6", "node": 4148, "naklon": 0 }, +{ "label": "39/7", "node": 4153, "naklon": 0 }, +{ "label": "39/8", "node": 3938, "naklon": 0 }, +{ "label": "39/9", "node": 3802, "naklon": 0 }, +{ "label": "39/10", "node": 4015, "naklon": 0 }, +{ "label": "39/11", "node": 3929, "naklon": 0 }, +{ "label": "39/12", "node": 3946, "naklon": 0 }, +{ "label": "39/13", "node": 4014, "naklon": 0 }, +{ "label": "39/14", "node": 4155, "naklon": 0 }, +{ "label": "39/15", "node": 4149, "naklon": 0 }, +{ "label": "39/16", "node": 3642, "naklon": 0 }, +{ "label": "39/17", "node": 3636, "naklon": 5 }, +{ "label": "39/18", "node": 3991, "naklon": 0 }, +{ "label": "39/19", "node": 3994, "naklon": 0 }, +{ "label": "39/20", "node": 3990, "naklon": 0 }, +{ "label": "39/21", "node": 3967, "naklon": 0 }, +{ "label": "39/22", "node": 3977, "naklon": 0 }, +{ "label": "39/23", "node": 3757, "naklon": 15 }, +{ "label": "39/24", "node": 3633, "naklon": 15 }, +{ "label": "39/25", "node": 3744, "naklon": 15 }, +{ "label": "39/26", "node": 4023, "naklon": 5 }, +{ "label": "39/27", "node": 3720, "naklon": 5 }, +{ "label": "39/28", "node": 3734, "naklon": 5 }, +{ "label": "39/29", "node": 3741, "naklon": 5 }, +{ "label": "39/30", "node": 3721, "naklon": 5 }, +{ "label": "39/31", "node": 3845, "naklon": 0 }, +{ "label": "39/32", "node": 3840, "naklon": 0 }, +{ "label": "39/33", "node": 3837, "naklon": null }, +{ "label": "39/34", "node": 3839, "naklon": 0 }, +{ "label": "41/1", "node": 3542, "naklon": null }, +{ "label": "41/2", "node": 3566, "naklon": null }, +{ "label": "41/3", "node": 3548, "naklon": null }, +{ "label": "41/4", "node": 3515, "naklon": null }, +{ "label": "41/5", "node": 3559, "naklon": null }, +{ "label": "41/6", "node": 3509, "naklon": null }, +{ "label": "41/7", "node": 3524, "naklon": null }, +{ "label": "41/8", "node": 3518, "naklon": null }, +{ "label": "41/9", "node": 3182, "naklon": null }, +{ "label": "41/10", "node": 3187, "naklon": null }, +{ "label": "41/11", "node": 3195, "naklon": 0 }, +{ "label": "41/12", "node": 3857, "naklon": 0 }, +{ "label": "41/13", "node": 3183, "naklon": 0 }, +{ "label": "41/14", "node": 3177, "naklon": 0 }, +{ "label": "41/15", "node": 3189, "naklon": 0 }, +{ "label": "41/16", "node": 3186, "naklon": 0 }, +{ "label": "42/1", "node": 3178, "naklon": 0 }, +{ "label": "42/2", "node": 3219, "naklon": 0 }, +{ "label": "42/3", "node": 3475, "naklon": 0 }, +{ "label": "42/4", "node": 3175, "naklon": 0 }, +{ "label": "42/5", "node": 3222, "naklon": 0 }, +{ "label": "42/6", "node": 3221, "naklon": 0 }, +{ "label": "42/7", "node": 3181, "naklon": 0 }, +{ "label": "42/8", "node": 3180, "naklon": 0 }, +{ "label": "42/9", "node": 3218, "naklon": 0 }, +{ "label": "42/10", "node": 3176, "naklon": 0 }, +{ "label": "42/11", "node": 3174, "naklon": 0 }, +{ "label": "42/12", "node": 3220, "naklon": 0 }, +{ "label": "42/13", "node": 3533, "naklon": null }, +{ "label": "42/14", "node": 3543, "naklon": null }, +{ "label": "42/15", "node": 3554, "naklon": null }, +{ "label": "42/16", "node": 3549, "naklon": null }, +{ "label": "43/1", "node": 2857, "naklon": 5 }, +{ "label": "43/2", "node": 2752, "naklon": 5 }, +{ "label": "43/3", "node": 2753, "naklon": 5 }, +{ "label": "43/4", "node": 3024, "naklon": 5 }, +{ "label": "43/5", "node": 2754, "naklon": 5 }, +{ "label": "43/6", "node": 4423, "naklon": 5 }, +{ "label": "43/7", "node": 4368, "naklon": 5 }, +{ "label": "43/8", "node": 2978, "naklon": 5 }, +{ "label": "43/9", "node": 2868, "naklon": 5 }, +{ "label": "43/10", "node": 4377, "naklon": 5 }, +{ "label": "43/11", "node": 2757, "naklon": 5 }, +{ "label": "43/12", "node": 2970, "naklon": 5 }, +{ "label": "43/13", "node": 2758, "naklon": 5 }, +{ "label": "43/14", "node": 4378, "naklon": 5 }, +{ "label": "43/15", "node": 2759, "naklon": 5 }, +{ "label": "43/16", "node": 4342, "naklon": 5 }, +{ "label": "43/17", "node": 3026, "naklon": null }, +{ "label": "43/18", "node": 2986, "naklon": null }, +{ "label": "43/19", "node": 4343, "naklon": null }, +{ "label": "43/20", "node": 2760, "naklon": null }, +{ "label": "43/21", "node": 4379, "naklon": null }, +{ "label": "43/22", "node": 2971, "naklon": null }, +{ "label": "43/23", "node": 2761, "naklon": null }, +{ "label": "43/24", "node": 2762, "naklon": null }, +{ "label": "43/25", "node": 4339, "naklon": null }, +{ "label": "43/26", "node": 4380, "naklon": null }, +{ "label": "43/27", "node": 2975, "naklon": null }, +{ "label": "43/28", "node": 3003, "naklon": null }, +{ "label": "43/29", "node": 4338, "naklon": null }, +{ "label": "43/30", "node": 3002, "naklon": null }, +{ "label": "43/31", "node": 4345, "naklon": null }, +{ "label": "43/32", "node": 2979, "naklon": null }, +{ "label": "43/33", "node": 2989, "naklon": null }, +{ "label": "43/34", "node": 2996, "naklon": null }, +{ "label": "43/35", "node": 2972, "naklon": null }, +{ "label": "43/36", "node": 2988, "naklon": null }, +{ "label": "43/37", "node": 4344, "naklon": null }, +{ "label": "43/38", "node": 3022, "naklon": null }, +{ "label": "43/39", "node": 4341, "naklon": null }, +{ "label": "43/40", "node": 2983, "naklon": null }, +{ "label": "43/41", "node": 2995, "naklon": null }, +{ "label": "43/42", "node": 2763, "naklon": null }, +{ "label": "43/43", "node": 2764, "naklon": null }, +{ "label": "43/44", "node": 2765, "naklon": null }, +{ "label": "43/45", "node": 2766, "naklon": null }, +{ "label": "43/46", "node": 2767, "naklon": null }, +{ "label": "43/47", "node": 2768, "naklon": null }, +{ "label": "43/48", "node": 3018, "naklon": null }, +{ "label": "43/49", "node": 2982, "naklon": null }, +{ "label": "43/50", "node": 3019, "naklon": 0 }, +{ "label": "43/51", "node": 3013, "naklon": null }, +{ "label": "43/52", "node": 3007, "naklon": null }, +{ "label": "43/53", "node": 2980, "naklon": null }, +{ "label": "43/54", "node": 3011, "naklon": null }, +{ "label": "43/55", "node": 2672, "naklon": null }, +{ "label": "43/56", "node": 2673, "naklon": null }, +{ "label": "43/57", "node": 2674, "naklon": null }, +{ "label": "43/58", "node": 2675, "naklon": null }, +{ "label": "43/59", "node": 2676, "naklon": null }, +{ "label": "43/60", "node": 2677, "naklon": null }, +{ "label": "43/61", "node": 2678, "naklon": null }, +{ "label": "43/62", "node": 2679, "naklon": null }, +{ "label": "43/63", "node": 2680, "naklon": null }, +{ "label": "43/64", "node": 2840, "naklon": null }, +{ "label": "43/65", "node": 2682, "naklon": null }, +{ "label": "43/66", "node": 2683, "naklon": null }, +{ "label": "43/67", "node": 2684, "naklon": 0 }, +{ "label": "43/68", "node": 2685, "naklon": null }, +{ "label": "43/69", "node": 2686, "naklon": null }, +{ "label": "43/70", "node": 2687, "naklon": null }, +{ "label": "43/71", "node": 2688, "naklon": null }, +{ "label": "43/72", "node": 2689, "naklon": null }, +{ "label": "43/73", "node": 2690, "naklon": null }, +{ "label": "43/74", "node": 2691, "naklon": null }, +{ "label": "43/75", "node": 2692, "naklon": null }, +{ "label": "43/76", "node": 2693, "naklon": 0 }, +{ "label": "43/77", "node": 2694, "naklon": null }, +{ "label": "43/78", "node": 2695, "naklon": null }, +{ "label": "43/79", "node": 2696, "naklon": 0 }, +{ "label": "43/80", "node": 2697, "naklon": null }, +{ "label": "43/81", "node": 2698, "naklon": 0 }, +{ "label": "43/82", "node": 2699, "naklon": null }, +{ "label": "43/83", "node": 2700, "naklon": 0 }, +{ "label": "43/84", "node": 2744, "naklon": null }, +{ "label": "43/85", "node": 2745, "naklon": 0 }, +{ "label": "43/86", "node": 2746, "naklon": null }, +{ "label": "43/87", "node": 2747, "naklon": 0 }, +{ "label": "43/88", "node": 2748, "naklon": null }, +{ "label": "43/89", "node": 2749, "naklon": 0 }, +{ "label": "43/90", "node": 2841, "naklon": null }, +{ "label": "45/1", "node": 4237, "naklon": 5 }, +{ "label": "45/2", "node": 4226, "naklon": 5 }, +{ "label": "45/3", "node": 4242, "naklon": 5 }, +{ "label": "45/4", "node": 4179, "naklon": 5 }, +{ "label": "45/5", "node": 4247, "naklon": 5 }, +{ "label": "45/6", "node": 4245, "naklon": 5 }, +{ "label": "45/7", "node": 3872, "naklon": 5 }, +{ "label": "45/8", "node": 4175, "naklon": 5 }, +{ "label": "45/9", "node": 4236, "naklon": 5 }, +{ "label": "45/10", "node": 4170, "naklon": 5 }, +{ "label": "45/11", "node": 4238, "naklon": 5 }, +{ "label": "45/12", "node": 4246, "naklon": 5 }, +{ "label": "45/13", "node": 4166, "naklon": 5 }, +{ "label": "45/14", "node": 4227, "naklon": 5 }, +{ "label": "45/15", "node": 4171, "naklon": 5 }, +{ "label": "45/16", "node": 4180, "naklon": 5 }, +{ "label": "45/17", "node": 4244, "naklon": 5 }, +{ "label": "45/18", "node": 4199, "naklon": 5 }, +{ "label": "45/19", "node": 4239, "naklon": 5 }, +{ "label": "45/20", "node": 4207, "naklon": 5 }, +{ "label": "45/21", "node": 4223, "naklon": 5 }, +{ "label": "45/22", "node": 4230, "naklon": 5 }, +{ "label": "45/23", "node": 4233, "naklon": 5 }, +{ "label": "45/24", "node": 4222, "naklon": 5 }, +{ "label": "45/25", "node": 4217, "naklon": 5 }, +{ "label": "45/26", "node": 4243, "naklon": 5 }, +{ "label": "45/27", "node": 4200, "naklon": 5 }, +{ "label": "45/28", "node": 4228, "naklon": 5 }, +{ "label": "45/29", "node": 4211, "naklon": 5 }, +{ "label": "45/30", "node": 4234, "naklon": 5 }, +{ "label": "45/31", "node": 4235, "naklon": 5 }, +{ "label": "45/32", "node": 4203, "naklon": 5 }, +{ "label": "45/33", "node": 4240, "naklon": 5 }, +{ "label": "45/34", "node": 4224, "naklon": 5 }, +{ "label": "45/35", "node": 4232, "naklon": 5 }, +{ "label": "45/36", "node": 4231, "naklon": 5 }, +{ "label": "45/37", "node": 4161, "naklon": 5 }, +{ "label": "45/38", "node": 4225, "naklon": 5 }, +{ "label": "45/39", "node": 4241, "naklon": 5 }, +{ "label": "45/40", "node": 4229, "naklon": 5 }, +{ "label": "45/41", "node": 4221, "naklon": 5 }, +{ "label": "45/42", "node": 4212, "naklon": 5 }, +{ "label": "45/43", "node": 4216, "naklon": 5 }, +{ "label": "45/44", "node": 3864, "naklon": null }, +{ "label": "46/1", "node": 3806, "naklon": 5 }, +{ "label": "46/2", "node": 3813, "naklon": 5 }, +{ "label": "46/3", "node": 3815, "naklon": 5 }, +{ "label": "46/4", "node": 3807, "naklon": 5 }, +{ "label": "46/5", "node": 3895, "naklon": 5 }, +{ "label": "46/6", "node": 3809, "naklon": 5 }, +{ "label": "46/7", "node": 3820, "naklon": 5 }, +{ "label": "46/8", "node": 3805, "naklon": 5 }, +{ "label": "46/9", "node": 3894, "naklon": 0 }, +{ "label": "46/10", "node": 4055, "naklon": 0 }, +{ "label": "46/11", "node": 3812, "naklon": 5 }, +{ "label": "46/12", "node": 3822, "naklon": 5 }, +{ "label": "46/13", "node": 3821, "naklon": 5 }, +{ "label": "46/14", "node": 3808, "naklon": 5 }, +{ "label": "46/15", "node": 3799, "naklon": 5 }, +{ "label": "46/16", "node": 3816, "naklon": 5 }, +{ "label": "46/17", "node": 3751, "naklon": 5 }, +{ "label": "46/18", "node": 3814, "naklon": 5 }, +{ "label": "46/19", "node": 4044, "naklon": 0 }, +{ "label": "46/20", "node": 3931, "naklon": 0 }, +{ "label": "46/21", "node": 3902, "naklon": 5 }, +{ "label": "46/22", "node": 3916, "naklon": 5 }, +{ "label": "46/23", "node": 3892, "naklon": 5 }, +{ "label": "46/24", "node": 3914, "naklon": 5 }, +{ "label": "46/25", "node": 3898, "naklon": 5 }, +{ "label": "46/26", "node": 3897, "naklon": 5 }, +{ "label": "46/27", "node": 3885, "naklon": 5 }, +{ "label": "46/28", "node": 3906, "naklon": 5 }, +{ "label": "46/29", "node": 3930, "naklon": 0 }, +{ "label": "46/30", "node": 3936, "naklon": 0 }, +{ "label": "46/31", "node": 3860, "naklon": 5 }, +{ "label": "46/32", "node": 3841, "naklon": 5 }, +{ "label": "46/33", "node": 3873, "naklon": 5 }, +{ "label": "46/34", "node": 3854, "naklon": 5 }, +{ "label": "46/35", "node": 3939, "naklon": 5 }, +{ "label": "46/36", "node": 3858, "naklon": 5 }, +{ "label": "46/37", "node": 3940, "naklon": 5 }, +{ "label": "46/38", "node": 4035, "naklon": 5 }, +{ "label": "47/1", "node": 3373, "naklon": 0 }, +{ "label": "47/2", "node": 3374, "naklon": 0 }, +{ "label": "47/3", "node": 3384, "naklon": 0 }, +{ "label": "47/4", "node": 3385, "naklon": 0 }, +{ "label": "48/1", "node": 4051, "naklon": 5 }, +{ "label": "48/2", "node": 4041, "naklon": 5 }, +{ "label": "48/3", "node": 4056, "naklon": 5 }, +{ "label": "48/4", "node": 3875, "naklon": 5 }, +{ "label": "48/5", "node": 4061, "naklon": 5 }, +{ "label": "48/6", "node": 4047, "naklon": 5 }, +{ "label": "48/7", "node": 4060, "naklon": 5 }, +{ "label": "48/8", "node": 4059, "naklon": 5 }, +{ "label": "48/9", "node": 4058, "naklon": 5 }, +{ "label": "48/10", "node": 3635, "naklon": 5 }, +{ "label": "48/11", "node": 3640, "naklon": 5 }, +{ "label": "48/12", "node": 3747, "naklon": 5 }, +{ "label": "48/13", "node": 3629, "naklon": 5 }, +{ "label": "48/14", "node": 4048, "naklon": 5 }, +{ "label": "48/15", "node": 4063, "naklon": 5 }, +{ "label": "48/16", "node": 4062, "naklon": 5 }, +{ "label": "48/17", "node": 4043, "naklon": 5 }, +{ "label": "48/18", "node": 4052, "naklon": 5 }, +{ "label": "48/19", "node": 4042, "naklon": 5 }, +{ "label": "48/20", "node": 4053, "naklon": 5 }, +{ "label": "50/15A", "node": 4167, "naklon": null }, +{ "label": "50/15B", "node": 4159, "naklon": null }, +{ "label": "50/1", "node": 4183, "naklon": 0 }, +{ "label": "50/2", "node": 4157, "naklon": 0 }, +{ "label": "50/3", "node": 4160, "naklon": 0 }, +{ "label": "50/4", "node": 4173, "naklon": 0 }, +{ "label": "50/5", "node": 4177, "naklon": 0 }, +{ "label": "50/6", "node": 4174, "naklon": 0 }, +{ "label": "50/7", "node": 4178, "naklon": 0 }, +{ "label": "50/8", "node": 4195, "naklon": 0 }, +{ "label": "50/9", "node": 4169, "naklon": 0 }, +{ "label": "50/10", "node": 4162, "naklon": 0 }, +{ "label": "50/11", "node": 4158, "naklon": 0 }, +{ "label": "50/12", "node": 4182, "naklon": 0 }, +{ "label": "50/13", "node": 4194, "naklon": 0 }, +{ "label": "50/14", "node": 4184, "naklon": 0 }, +{ "label": "50/16", "node": 4197, "naklon": null }, +{ "label": "50/17", "node": 4164, "naklon": null }, +{ "label": "50/18", "node": 3306, "naklon": null }, +{ "label": "50/19", "node": 4168, "naklon": null }, +{ "label": "50/20", "node": 4193, "naklon": null }, +{ "label": "50/21", "node": 4187, "naklon": null }, +{ "label": "50/22", "node": 4163, "naklon": null }, +{ "label": "50/23", "node": 4165, "naklon": null }, +{ "label": "50/24", "node": 4185, "naklon": null }, +{ "label": "50/25", "node": 3904, "naklon": null }, +{ "label": "53/1", "node": 2619, "naklon": 0 }, +{ "label": "53/2", "node": 2623, "naklon": 0 }, +{ "label": "53/3", "node": 2617, "naklon": 0 }, +{ "label": "53/4", "node": 2622, "naklon": 0 }, +{ "label": "53/5", "node": 2618, "naklon": 0 }, +{ "label": "53/6", "node": 2626, "naklon": 0 }, +{ "label": "53/7", "node": 2869, "naklon": 0 }, +{ "label": "53/8", "node": 2613, "naklon": 0 }, +{ "label": "53/9", "node": 2608, "naklon": 0 }, +{ "label": "53/10", "node": 2611, "naklon": 0 }, +{ "label": "53/11", "node": 2598, "naklon": 0 }, +{ "label": "53/12", "node": 3528, "naklon": 0 }, +{ "label": "53/13", "node": 3545, "naklon": 0 }, +{ "label": "53/14", "node": 2620, "naklon": 0 }, +{ "label": "53/15", "node": 2612, "naklon": 0 }, +{ "label": "53/16", "node": 2615, "naklon": 0 }, +{ "label": "53/17", "node": 3722, "naklon": 0 }, +{ "label": "53/18", "node": 2624, "naklon": 0 }, +{ "label": "53/19", "node": 2609, "naklon": 0 }, +{ "label": "53/20", "node": 2625, "naklon": 0 }, +{ "label": "53/21", "node": 2602, "naklon": 0 }, +{ "label": "53/22", "node": 2610, "naklon": 0 }, +{ "label": "53/23", "node": 2599, "naklon": 0 }, +{ "label": "53/24", "node": 2605, "naklon": 0 }, +{ "label": "53/25", "node": 2593, "naklon": 0 }, +{ "label": "53/26", "node": 3074, "naklon": 0 }, +{ "label": "53/27", "node": 2740, "naklon": 0 }, +{ "label": "53/28", "node": 2614, "naklon": 0 }, +{ "label": "53/29", "node": 2601, "naklon": 0 }, +{ "label": "53/30", "node": 4196, "naklon": 0 }, +{ "label": "53/31", "node": 2607, "naklon": 0 }, +{ "label": "53/32", "node": 2582, "naklon": 0 }, +{ "label": "53/33", "node": 2594, "naklon": 0 }, +{ "label": "53/34", "node": 2589, "naklon": 0 }, +{ "label": "53/35", "node": 2596, "naklon": 0 }, +{ "label": "53/36", "node": 2603, "naklon": 0 }, +{ "label": "53/37", "node": 2597, "naklon": 0 }, +{ "label": "53/38", "node": 2590, "naklon": 0 }, +{ "label": "53/39", "node": 2581, "naklon": 0 }, +{ "label": "53/40", "node": 2583, "naklon": 0 }, +{ "label": "53/41", "node": 2580, "naklon": 0 }, +{ "label": "53/42", "node": 2579, "naklon": 0 }, +{ "label": "53/43", "node": 2797, "naklon": 0 }, +{ "label": "53/44", "node": 2577, "naklon": 0 }, +{ "label": "53/45", "node": 2586, "naklon": 0 }, +{ "label": "53/46", "node": 2588, "naklon": 0 }, +{ "label": "53/47", "node": 2591, "naklon": 0 }, +{ "label": "53/48", "node": 2592, "naklon": 0 }, +{ "label": "53/49", "node": 2573, "naklon": 0 }, +{ "label": "53/50", "node": 2595, "naklon": 0 }, +{ "label": "53/51", "node": 2587, "naklon": 0 }, +{ "label": "53/52", "node": 2578, "naklon": 0 }, +{ "label": "53/53", "node": 2574, "naklon": 0 }, +{ "label": "53/54", "node": 2571, "naklon": 0 }, +{ "label": "53/55", "node": 2570, "naklon": 0 }, +{ "label": "53/56", "node": 2576, "naklon": 0 }, +{ "label": "53/57", "node": 2881, "naklon": 0 }, +{ "label": "53/58", "node": 2575, "naklon": 0 }, +{ "label": "53/59", "node": 2572, "naklon": 0 }, +{ "label": "53/60", "node": 2569, "naklon": 0 }, +{ "label": "55/1", "node": 4324, "naklon": 0 }, +{ "label": "55/2", "node": 4319, "naklon": 0 }, +{ "label": "55/3", "node": 4327, "naklon": 0 }, +{ "label": "55/4", "node": 4333, "naklon": 0 }, +{ "label": "55/5", "node": 4332, "naklon": 0 }, +{ "label": "55/6", "node": 4320, "naklon": 0 }, +{ "label": "55/7", "node": 4317, "naklon": 0 }, +{ "label": "55/8", "node": 4318, "naklon": 0 }, +{ "label": "55/9", "node": 4328, "naklon": 0 }, +{ "label": "55/10", "node": 4323, "naklon": 0 }, +{ "label": "55/11", "node": 4325, "naklon": 0 }, +{ "label": "55/12", "node": 4326, "naklon": 0 }, +{ "label": "55/13", "node": 4316, "naklon": 0 }, +{ "label": "55/14", "node": 4322, "naklon": 0 }, +{ "label": "55/15", "node": 4331, "naklon": 0 }, +{ "label": "55/16", "node": 4321, "naklon": 0 }, +{ "label": "55/17", "node": 4315, "naklon": 0 }, +{ "label": "55/18", "node": 4329, "naklon": 0 }, +{ "label": "55/19", "node": 4334, "naklon": 0 }, +{ "label": "55/20", "node": 4330, "naklon": 0 } +]; + +module.exports = { naklony }; diff --git a/databases/nodes.table b/databases/nodes.table index 0efaed3..b2f13d9 100644 --- a/databases/nodes.table +++ b/databases/nodes.table @@ -1,2 +1,2 @@ node:number|tbname:string|line:number|profile:string|processed:boolean|status:boolean|time_of_last_communication:number -+|638|rDbQ84xzwgdqEoPm3kbJQWk9anOZY1RXyBv2LVM6|3|{"intervals":[{"cct":3000,"value":20,"end_time":"20:00","start_time":"13:00"},{"cct":3000,"value":10,"end_time":"05:30","start_time":"20:00"},{"cct":3000,"value":20,"end_time":"13:00","start_time":"05:30"}],"astro_clock":true,"dawn_lux_sensor":false,"dusk_lux_sensor":false,"dawn_lux_sensor_value":5,"dusk_lux_sensor_value":5,"dawn_astro_clock_offset":-20,"dusk_astro_clock_offset":20,"dawn_lux_sensor_time_window":30,"dusk_lux_sensor_time_window":30,"dawn_astro_clock_time_window":60,"dusk_astro_clock_time_window":60}|1|0|1725885127396|............................................................................................................................................................................................................................................................|................. ++|638|rDbQ84xzwgdqEoPm3kbJQWk9anOZY1RXyBv2LVM6|3|{"intervals":[{"cct":3000,"value":20,"end_time":"20:00","start_time":"13:00"},{"cct":3000,"value":10,"end_time":"05:30","start_time":"20:00"},{"cct":3000,"value":20,"end_time":"13:00","start_time":"05:30"}],"astro_clock":true,"dawn_lux_sensor":false,"dusk_lux_sensor":false,"dawn_lux_sensor_value":5,"dusk_lux_sensor_value":5,"dawn_astro_clock_offset":-20,"dusk_astro_clock_offset":20,"dawn_lux_sensor_time_window":30,"dusk_lux_sensor_time_window":30,"dawn_astro_clock_time_window":60,"dusk_astro_clock_time_window":60}|1|0|1725885127396|............................................................................................................................................................................................................................................................ diff --git a/databases/notifications.table b/databases/notifications.table index 9dbe047..f7c96cb 100644 --- a/databases/notifications.table +++ b/databases/notifications.table @@ -20,9 +20,12 @@ key:string|weight:string|sk:string|en:string +|power_supply_works_correctly|NOTICE|Napájací zdroj pracuje správne|Power supply works correctly|............... +|battery_level_is_low|ERROR|Batéria má nízku úroveň napätia|Battery level is low|............... +|battery_level_is_ok|NOTICE|Batéria má správnu úroveň napätia|Battery level is OK|............... -+|door_opened|NOTICE|Dvere boli otvorené|Door has been opeed|............... -+|door_closed|NOTICE|Dvere boli zatvorené|Door has been closed|............... -+|door_opened_without_permission|WARNING|Dvere boli otvorené bez povolenia - zapnutá siréna|Door opened without permision - alarm is on|............... ++|door_main_open|NOTICE|Hlavné dvere boli otvorené|Main door has been opened|............... ++|door_em_open|NOTICE|Dvere silovej časti boli otvorené|Power door has been opened|............... ++|door_main_open_without_permission|WARNING|Hlavné dvere boli otvorené bez povolenia - zapnutá siréna|Main door has been opened without permission - alarm is on|............... ++|door_em_open_without_permission|WARNING|Dvere silovej časti boli otvorené bez povolenia|Power door has been opened without permission|............... ++|door_main_close|NOTICE|Hlavné dvere boli zatvorené|Main door has been closed|............... ++|door_em_close|NOTICE|Dvere silovej časti boli zatvorené|Power door has been closed|............... +|state_of_contactor_for_line|INFORMATIONAL|Stav stýkača pre líniu č. ${line} je ${value}|State of contactor for line no. ${line} is ${value}|............... +|local_database_is_corrupted|CRITICAL|||............... +|electrometer_nok|ERROR|Elektromer neodpovedá|Electrometer is not responding|............... @@ -34,5 +37,5 @@ key:string|weight:string|sk:string|en:string +|twilight_sensor_ok|NOTICE|Sensor súmraku znovu odpovedá|Twilight sensor is responding again|............... +|lamps_have_turned_on|NOTICE|Lampy sa zapli|Lamps have turned on|............... +|lamps_have_turned_off|NOTICE|Lampy sa vypli|Lamps have turned off|............... -+|flow_restart|NOTICE|Restart flowu|Flow has been restarted|............... -+|nodes_db_changed|NOTICE|Zmena v node databaze|Node db has changed|............... ++|flow_restart|NOTICE|FLOW bol reštartovaný|FLOW has been restarted|............... ++|nodes_db_changed|NOTICE|Zmena v node databáze|Node db has changed|............... diff --git a/databases/settings.table b/databases/settings.table index 0aec6b3..5abd2b1 100644 --- a/databases/settings.table +++ b/databases/settings.table @@ -1,2 +1,2 @@ -rvo_name:string|lang:string|temperature_address:string|latitude:number|longitude:number|mqtt_host:string|mqtt_clientid:string|mqtt_username:string|mqtt_port:number|maintanace_mode:boolean|project_id:number|controller_type:string|serial_port:string|backup_on_failure:boolean|restore_from_backup:number|restore_backup_wait:number|node_status_nok_time:number|phases:number|cloud_topic:string -+|rvo_senica_22_ip10.0.0.109|en|28.F46E9D0E0000|48.70826502|17.28455203|192.168.252.1|rvo_senica_22_ip10.0.0.109|9excvr7yBcF3gl3kYZGY|1883|0|48|unipi|ttyUSB0|1|20|5|6|3|u109|........................................... +rvo_name:string|lang:string|temperature_address:string|latitude:number|longitude:number|mqtt_host:string|mqtt_clientid:string|mqtt_username:string|mqtt_port:number|maintanace_mode:boolean|project_id:number|controller_type:string|serial_port:string|backup_on_failure:boolean|restore_from_backup:number|restore_backup_wait:number|node_status_nok_time:number|phases:number|cloud_topic:string|has_main_switch:boolean ++|rvo_senica_22_ip10.0.0.109|en|28.F46E9D0E0000|48.70826502|17.28455203|192.168.252.1|rvo_senica_22_ip10.0.0.109|9excvr7yBcF3gl3kYZGY|1883|0|48|unipi|ttyUSB0|1|20|5|6|3|u109|0|........................................... diff --git a/databases/total_energy.js b/databases/total_energy.js new file mode 100644 index 0000000..cc8c018 --- /dev/null +++ b/databases/total_energy.js @@ -0,0 +1,37 @@ +//key is rvo_number, value is max energy when lamps are on +const total_energy = { + 1: 580, + 2: 1100, + 3: 3700, + 4: 4100, + 7: 360, + 12: 1700, + 13: 5400, + 14: 440, + 15: 6100, + 16: 4800, + 20: 1600, + 21: 1000, + 22: 2600, + 23: 1000, + 25: 2600, + 33: 240, + 34: 4000, + 35: 2700, + 36: 820, + 37: 1400, + 35: 3500, + 39: 1170, + 41: 740, + 42: 660, + 43: 4900, + 45: 930, + 46: 700, + 47: 1100, + 48: 1500, + 50: 3200, + 55: 1000, + 56: 5500 +} + +module.exports = total_energy; diff --git a/flow/cmd_manager.js b/flow/cmd_manager.js index a960aaa..07e12c6 100644 --- a/flow/cmd_manager.js +++ b/flow/cmd_manager.js @@ -39,11 +39,14 @@ exports.install = function(instance) { var SunCalc = require('./helper/suncalc'); const DataToTbHandler = require('./helper/DataToTbHandler'); - const ErrorToServiceHandler = require('./helper/ErrorToServiceHandler'); + const errorHandler = require('./helper/ErrorToServiceHandler'); const { sendNotification } = require('./helper/notification_reporter'); const process = require('process'); const { errLogger, logger, monitor } = require('./helper/logger'); + //for accelerometer purposes + const { naklony } = require("../databases/accelerometer_db"); + const dbNodes = TABLE("nodes"); const dbRelays = TABLE("relays"); @@ -83,6 +86,7 @@ exports.install = function(instance) { let interval = null;//timeout for procesing tasks let customTasksInterval = null; // interval for reportEdgeDateTimeAndNumberOfLuminaires(); let setCorrectTime = null; // interval for setting a correct edgeTime + let sendNodeReadout = null; // interval for sending agregate data from node let refFlowdataObj = {}; @@ -100,31 +104,32 @@ exports.install = function(instance) { let priorities = []; let minutes = 1; - priorities["0"] = minutes; - priorities["1"] = minutes; + priorities["1"] = minutes; // dimming + priorities["76"] = minutes; // power minutes = 5; - priorities["74"] = minutes; - priorities["75"] = minutes; - priorities["76"] = minutes; - priorities["77"] = minutes; - priorities["78"] = minutes; - priorities["79"] = minutes; - priorities["84"] = minutes; + priorities["75"] = minutes; // current + priorities["79"] = minutes; // energy + priorities["87"] = minutes; // aktualny cas + //priorities["84"] = minutes; minutes = 10; - priorities["87"] = minutes; - priorities["6"] = minutes; - priorities["7"] = minutes; - priorities["80"] = minutes; - priorities["8"] = minutes; - priorities["3"] = minutes; - priorities["89"] = minutes; + priorities["74"] = minutes; // voltage + priorities["77"] = minutes; // power factor + priorities["78"] = minutes; // frequency + + minutes = 60; + priorities["0"] = minutes; // statecode + priorities["6"] = minutes; // dusk + priorities["7"] = minutes; // dawn + priorities["8"] = minutes; // profile + + minutes = 60 * 24; + priorities["89"] = minutes; // verzia fw + priorities["80"] = minutes; // lifetime //prikazy kt sa budu spustat na dany node - see config.js in terminal-oms.app. (1 - dimming) - let listOfCommands = [0, 1, 3, 6, 7, 8, 74, 75, 76, 77, 78, 79, 80, 84, 87, 89]; - - const errorHandler = new ErrorToServiceHandler(); + let listOfCommands = [0, 1, 6, 7, 8, 74, 75, 76, 77, 78, 79, 80, 87, 89]; let rotary_switch_state; let lux_sensor; @@ -133,7 +138,6 @@ exports.install = function(instance) { let relaysData; let nodesData; - let rvoTbName; let sunCalcResult; let reportDuskDawn; @@ -144,6 +148,10 @@ exports.install = function(instance) { //if sending of profile to node fails, we send notification and push node into set, so we do not send notification twice const nodeProfileSendFail = new Set(); + //we expect to get current temperature in Senica from senica-prod01 + let temperatureInSenica = null; + let accelerometerInterval = null; + //END OF VARIABLE SETTINGS //-------------------------------- @@ -159,14 +167,8 @@ exports.install = function(instance) { tbHandler = new DataToTbHandler(SEND_TO.tb); tbHandler.setSender(exports.title); - //SETTINGS.project_id, name: SETTINGS.rvo_name; - //const errorHandler = new ErrorToServiceHandler(instance, SEND_TO.infoSender); - errorHandler.setProjectsId(SETTINGS.project_id); - //const errorHandler = new ErrorToServiceHandler(instance); - //errorHandler.sendMessageToService("ahoj", 0); - let now = new Date(); - console.log("CMD Manager installed", now.toLocaleString("sk-SK")); + console.log("Cmd-mngr installed", now.toLocaleString("sk-SK")); sunCalcResult = calculateDuskDawn(); @@ -179,13 +181,16 @@ exports.install = function(instance) { handleRsPort(); - //to ensure, edgeDateTime will be send to tb at full minute customTasksInterval = setInterval(function() { - if (new Date().getSeconds() === 0) reportEdgeDateTimeAndNumberOfLuminaires(); - }, 1000); + reportEdgeDateTimeAndNumberOfLuminaires(); + }, 120000); + reportEdgeDateTimeAndNumberOfLuminaires(); setCorrectTime = setInterval(setCorrectPlcTimeOnceADay, 60000 * 60); // 1 hour setCorrectPlcTimeOnceADay(); + + sendNodeReadout = setInterval(sendNodesData, 150000); + accelerometerInterval = setInterval(accelerometerData, 60000 * 30); //30 min } @@ -224,8 +229,9 @@ exports.install = function(instance) { params.priority = priority; } - params.addMinutesToTimestamp = 0;//repeat task if value is > 0, - + params.addMinutesToTimestamp = 0;//repeat task if value is > 0 + // if node regular readout does not respond, we repeat request + params.repeatCounter = 0; //params.timePointName = "luxOff" // "luxOn", "dusk", "dawn", "profileTimepoint" //params.info = ""; //params.debug = true; // will console.log params in writeData response @@ -261,7 +267,7 @@ exports.install = function(instance) { try { nodeProfile = JSON.parse(nodeProfile); } catch (error) { - logger.debug("Cmd_manager - Error parsing node profile", error); + logger.debug("Cmd-mngr: Error parsing node profile", error); } } @@ -282,15 +288,11 @@ exports.install = function(instance) { let params = getParams(PRIORITY_TYPES.node_cmd); params.type = "set_node_profile"; params.address = node; - params.byte1 = 0; - params.byte2 = 0; - params.byte3 = 0; params.byte4 = 96; params.recipient = 1; params.register = 8; params.rw = 1;//write params.timestamp = timestamp; - params.addMinutesToTimestamp = 0; params.info = 'turn off/reset node profile'; cmdCounter[node] = 1; @@ -304,15 +306,11 @@ exports.install = function(instance) { let params = getParams(PRIORITY_TYPES.node_cmd); params.type = "set_node_profile"; params.address = node; - params.byte1 = 0; - params.byte2 = 0; - params.byte3 = 0; params.byte4 = 96; params.recipient = 1; params.register = 8; params.rw = 1;//write params.timestamp = timestamp; - params.addMinutesToTimestamp = 0; params.info = 'turn off node profile'; tasksProfile.push(params); @@ -340,13 +338,6 @@ exports.install = function(instance) { Register úrovne má rovnaký formát ako dimming register (Reg 1). */ - //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - //params.byte1 = 0;//msb, podla dokumentacie data3 - //params.byte2 = 0;//podla dokumentacie data2 - //params.byte3 = 0;//podla dokumentacie data1 - //params.byte4 = 0;//lsb, podla dokumentacie data0 - //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - let start_time = obj.start_time; let t = start_time.split(":"); //if(timePoint != undefined) t = timePoint.split(":"); @@ -359,8 +350,6 @@ exports.install = function(instance) { params.address = node; params.byte1 = parseInt(t[0]);//hh params.byte2 = parseInt(t[1]);//mm - params.byte3 = 0;//ss - params.byte4 = 0;// params.recipient = 1; params.register = register; params.rw = 1;//write @@ -376,9 +365,6 @@ exports.install = function(instance) { params = getParams(PRIORITY_TYPES.node_cmd); params.type = "set_node_profile"; params.address = node; - params.byte1 = 0; - params.byte2 = 0; - params.byte3 = 0;//ss params.byte4 = parseInt(dim_value) + 128;// params.recipient = 1; params.register = register; @@ -394,28 +380,17 @@ exports.install = function(instance) { } //Threshold lux level for DUSK/DAWN - //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - //params.byte1 = 0;//msb, podla dokumentacie data3 - //params.byte2 = 0;//podla dokumentacie data2 - //params.byte3 = 0;//podla dokumentacie data1 - //params.byte4 = 0;//lsb, podla dokumentacie data0 - //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - - //Time schedule settings na koniec - //if(nodeProfile.dusk_lux_sensor || nodeProfile.dawn_lux_sensor) { logger.debug("processNodeProfile: Threshold lux level for DUSK/DAWN", node); - let params = getParams(PRIORITY_TYPES.node_cmd); + let params = getParams(); params.type = "set_node_profile"; params.address = node; params.register = 96; params.recipient = 1; params.rw = 1;//write params.timestamp = timestamp; - params.addMinutesToTimestamp = 0; params.info = "Threshold lux level for DUSK/DAWN"; if (nodeProfile.dusk_lux_sensor) { @@ -444,14 +419,13 @@ exports.install = function(instance) { logger.debug("processNodeProfile: DUSK/DAWN max. adjust period", node); - let params = getParams(PRIORITY_TYPES.node_cmd); + let params = getParams(); params.type = "set_node_profile"; params.address = node; params.register = 97; params.recipient = 1; params.rw = 1;//write params.timestamp = timestamp; - params.addMinutesToTimestamp = 0; params.info = "DUSK/DAWN max. adjust period"; if (nodeProfile.astro_clock) { @@ -491,7 +465,6 @@ exports.install = function(instance) { params.recipient = 1; params.rw = 1;//write params.timestamp = timestamp; - params.addMinutesToTimestamp = 0; params.info = "Static offset"; if (nodeProfile.astro_clock) { @@ -673,39 +646,24 @@ exports.install = function(instance) { function reportOnlineNodeStatus(line) { - //broadcast cas, o 3 sek neskor - status, brightness - //Po zapnutí línie broadcastovo aktualizovať predtým čas. + //Po zapnutí línie broadcastovo aktualizovať predtým čas a o 3 sek neskor - status, brightness - logger.debug("--->reportOnlineNodeStatus for line", line); + logger.debug("Cmd-mngr: ----->reportOnlineNodeStatus for line", line); - //return; - - //run broadcast //Actual time - addMinutesToTimestamp = 0; - - let params = {}; - - var d = new Date(); - let hours = d.getHours(); - let minutes = d.getMinutes(); - let seconds = d.getSeconds(); - - let time = d.getTime(); // time in ms + const d = new Date(); + // broadcast actual time + let params = getParams(); params.address = 0xffffffff;//Broadcast - params.byte1 = hours;//h - params.byte2 = minutes;//m - params.byte3 = seconds;//s - params.byte4 = 0; + params.byte1 = d.getHours(); + params.byte2 = d.getMinutes(); params.recipient = 2;//2 broadcast, address = 0 params.register = 87;//Actual time params.rw = 1;//write - - //other values - params.type = "cmd"; - params.timestamp = Date.now() + 60000; - params.addMinutesToTimestamp = addMinutesToTimestamp; + params.type = "node-onetime-write"; + params.timestamp = d.getTime() + 30000; params.info = "run broadcast: Actual time"; + //params.debug = true; tasks.push(params); @@ -713,82 +671,89 @@ exports.install = function(instance) { setTimeout(function() { //Po zapnutí línie - spraviť hromadný refresh stavu práve zapnutých svietidiel + let time = Date.now(); + for (let k in nodesData) { //potrebujem nody k danej linii if (line == nodesData[k].line || line == undefined) { + let tbname = nodesData[k].tbname; let node = nodesData[k].node; let status = "NOK"; // if status of node was "OK" before switching it off, we set the node's time_of_last_communication on time, it was switched on again and send OK status to tb. - if (nodesData[k].status) { + if (nodesData[k].node_status_before_offline === true || nodesData[k].status === true) { status = "OK"; nodesData[k].time_of_last_communication = time; } + nodesData[k].readout.status = status; + + updateNodeStatus(k, status === "OK" ? true : false); + if (nodesData[k].hasOwnProperty("node_status_before_offline")) delete nodesData[k].node_status_before_offline; sendTelemetry({ status: status }, tbname, time); - //prud, vykon - current, input power pre liniu pre vsetky nody - - //a pridame aj vyreportovanie dimmingu + //vyreportovanie dimming, current, input power pre liniu pre vsetky nody + //Prud { - let params = getParams(PRIORITY_TYPES.high_priority); + let params = getParams(); - params.type = "cmd"; + params.type = "node-onetime-read"; + params.tbname = tbname; + params.address = node; + params.register = 75;//prud + params.recipient = 1;//slave + params.rw = 0;//read + params.timestamp = time + 4000; + params.info = 'read current'; + //params.debug = true; + tasks.push(params); + } + + //vykon + { + let params = getParams(); + + params.type = "node-onetime-read"; + params.tbname = tbname; + params.address = node; + params.register = 76;//výkon + params.recipient = 1;//slave + params.rw = 0;//read + params.timestamp = time + 4100; + params.info = 'read power'; + //params.debug = true; + + tasks.push(params); + } + //dimming + { + let params = getParams(); + + params.type = "node-onetime-read"; params.tbname = tbname; params.address = node; params.register = 1;//dimming params.recipient = 1;//slave params.rw = 0;//read - params.timestamp = PRIORITY_TYPES.high_priority; + params.timestamp = time + 4200; params.info = 'read dimming'; //params.debug = true; tasks.push(params); } - //Prúd - { - let params = getParams(PRIORITY_TYPES.high_priority); - - params.type = "cmd"; - params.tbname = tbname; - params.address = node; - params.register = 75;//prud - params.recipient = 1;//slave - params.rw = 0;//read - params.timestamp = PRIORITY_TYPES.high_priority; - params.info = 'read current'; - //params.debug = true; - - tasks.push(params); - } - - //výkon - { - let params = getParams(PRIORITY_TYPES.high_priority); - - params.type = "cmd"; - params.tbname = tbname; - params.address = node; - params.register = 76;//výkon - params.recipient = 1;//slave - params.rw = 0;//read - params.timestamp = PRIORITY_TYPES.high_priority; - params.info = 'read power'; - //params.debug = true; - - tasks.push(params); - } } } + }, sec * 1000); } function reportOfflineNodeStatus(line) { - logger.debug("--->reportOfflineNodeStatus for line", line); + + logger.info("Cmd-mngr: ------>reportOffLineNodeStatus for line ", line); values = {}; values["dimming"] = 0;//brightness @@ -798,20 +763,24 @@ exports.install = function(instance) { const date = Date.now(); - // it happens, that some data did not get to tb after sending - // we setTimeout to make more time for db to process telemetry (eg 150 messages at once) - Object.keys(nodesData).forEach((node, index) => { + Object.keys(nodesData).forEach(node => { - setTimeout(function() { + //potrebujem nody k danej linii + if (line == nodesData[node].line || line == undefined) { - //potrebujem nody k danej linii - if (line == nodesData[node].line || line == undefined) { - let tbname = nodesData[node].tbname; - sendTelemetry(values, tbname, date) - } + let tbname = nodesData[node].tbname; + let nodeStatus = nodesData[node].status; - }, (index + 1) * 1000); - }) + //in case we have reported offline node status, we return (continue with next node) + if (nodeStatus === "OFFLINE") return; + + nodesData[node].node_status_before_offline = nodeStatus; + nodesData[node].status = "OFFLINE"; + nodesData[node].readout = {}; + + sendTelemetry({ ...values }, tbname, date); + } + }); } @@ -823,12 +792,11 @@ exports.install = function(instance) { info: info }; - logger.debug("linia", line, obj); + //logger.debug("linia", line, obj); instance.send(SEND_TO.dido_controller, obj); } - function detectIfResponseIsValid(bytes) { //ak sa odpoved zacina 0 - je to v poriadku, inak je NOK let type = "RESPONSE"; @@ -878,12 +846,9 @@ exports.install = function(instance) { //BUILD TASKS// function buildTasks(params) { - //report SETTINGS.edge_fw_version as fw_version - //report date as startdate //return; console.log("buidTAaasks start ****************", params); - monitor.info("buildTasks - params", params); let processLine; //defined line @@ -906,14 +871,16 @@ exports.install = function(instance) { processLine = params.line; } - //load profiles pre vsetky linie: let now = new Date(); + //process line profiles if (processLineProfiles) { - //process line profiles + let keys = Object.keys(relaysData); + for (let i = 0; i < keys.length; i++) { - let line = parseInt(keys[i]); //line is turned off by default + + let line = parseInt(keys[i]); let profilestr = relaysData[line].profile; if (processLine != undefined) { @@ -1016,15 +983,13 @@ exports.install = function(instance) { start_time.setDate(start_time.getDate() + 1); } - let params = getParams(PRIORITY_TYPES.relay_profile); + let params = getParams(); params.type = "relay"; params.line = parseInt(line); params.value = time_points[t].value; params.tbname = relaysData[line].tbname; params.timestamp = start_time.getTime(); - params.addMinutesToTimestamp = 0; - // it timepoints are not calculated (dawn, dusk, lux_timepoint), but static points in line profile, we just repeat the task every day if (time_points[t].name == "profileTimepoint") params.addMinutesToTimestamp = 24 * 60; @@ -1050,14 +1015,12 @@ exports.install = function(instance) { monitor.info("-->time_points final", line, time_points); //ensure to turn on/off according to calculated currentValue - let params = getParams(PRIORITY_TYPES.terminal); + let params = getParams(); params.type = "relay"; params.line = parseInt(line); params.tbname = relaysData[line].tbname; params.value = currentValue; - - params.timestamp = PRIORITY_TYPES.terminal; - params.addMinutesToTimestamp = 0; + params.timestamp = i; params.debug = true; //logger.debug(now.toLocaleString("sk-SK")); @@ -1072,104 +1035,72 @@ exports.install = function(instance) { } catch (error) { if (profilestr !== "") { //errLogger.error(profilestr, error); + console.log(`Cmd_mngr: Unable to process line profile ${line}. Error: `, error); errorHandler.sendMessageToService(profilestr + "-" + error, 0, "js_error"); + } else { + turnLine("off", line, "No line profile. Switching it off on startup"); } } } - //logger.debug("tasks:"); //logger.debug(tasks); } - //PROCESS DEFAULT BROADCASTS - //Time of dusk, Time of dawn, Actual Time - + //NOTE: PROCESS DEFAULT BROADCASTS - Time of dusk, Time of dawn, Actual Time if (processBroadcast) { - let addMinutesToTimestamp = 5; + + let d = new Date(); + let time = d.getTime(); + let sunCalcResult = calculateDuskDawn(); { - //run broadcast Time of dusk - addMinutesToTimestamp = 60 * 3; //kazde 3 hodiny zisti novy dusk - - let params = getParams(PRIORITY_TYPES.node_broadcast); - - let sunCalcResult = calculateDuskDawn(); - let dusk_hours = sunCalcResult["dusk_hours"]; - let dusk_minutes = sunCalcResult["dusk_minutes"]; + let params = getParams(); params.address = 0xffffffff;//broadcast - params.byte1 = dusk_hours;//h - params.byte2 = dusk_minutes;//m - params.byte3 = 0;//s - params.byte4 = 0; + params.byte1 = sunCalcResult["dusk_hours"]; + params.byte2 = sunCalcResult["dusk_minutes"]; params.recipient = 2;//2 broadcast, - params.register = 6;//Time of dusk - Reg 6 + params.register = 6;//Time of dusk params.rw = 1;//write - - //other values - params.type = "cmd"; - params.timestamp = Date.now() + 60000; - params.addMinutesToTimestamp = addMinutesToTimestamp; + params.type = "node-regular-write"; + params.timestamp = time + 60000; + params.addMinutesToTimestamp = 60 * 3; //kazde 3 hodiny zisti novy dusk params.info = "Broadcast-duskTime"; tasks.push(params); } { - - //run broadcast Time of dawn - addMinutesToTimestamp = 60 * 3; //kazde 3 hodiny zisti novy dawn - - let params = getParams(PRIORITY_TYPES.node_broadcast); - - let sunCalcResult = calculateDuskDawn(); - let dawn_hours = sunCalcResult["dawn_hours"]; - let dawn_minutes = sunCalcResult["dawn_minutes"]; + let params = getParams(); params.address = 0xffffffff;//broadcast - params.byte1 = dawn_hours;//h - params.byte2 = dawn_minutes;//m - params.byte3 = 0;//s - params.byte4 = 0; + params.byte1 = sunCalcResult["dawn_hours"]; + params.byte2 = sunCalcResult["dawn_minutes"]; params.recipient = 2; //2 broadcast - params.register = 7;//Time of dawn - Reg 6 + params.register = 7;//Time of dawn params.rw = 1;//write - - //other values - params.type = "cmd"; - params.timestamp = Date.now() + 60000; - params.addMinutesToTimestamp = addMinutesToTimestamp; + params.type = "node-regular-write"; + params.timestamp = time + 60001; + params.addMinutesToTimestamp = 60 * 3; //kazde 3 hodiny zisti novy dawn params.info = "Broadcast-dawnTime"; tasks.push(params); } { - //run broadcast Actual time - addMinutesToTimestamp = 5; - - let params = getParams(PRIORITY_TYPES.node_broadcast); - - var d = new Date(); - let hours = d.getHours(); - let minutes = d.getMinutes(); - let seconds = d.getSeconds(); + let params = getParams(); params.address = 0xffffffff;//broadcast - params.byte1 = hours;//h - params.byte2 = minutes;//m - params.byte3 = seconds;//s - params.byte4 = 0; + params.byte1 = d.getHours(); + params.byte2 = d.getMinutes(); params.recipient = 2; //2 broadcast params.register = 87;//Actual time params.rw = 1;//write - - //other values - params.type = "cmd"; - params.timestamp = Date.now() + 60000; - params.addMinutesToTimestamp = addMinutesToTimestamp; + params.type = "node-regular-write"; + params.timestamp = time + 60002; + params.addMinutesToTimestamp = 5; params.info = "run broadcast: Actual time"; tasks.push(params); @@ -1177,49 +1108,35 @@ exports.install = function(instance) { } - //process nodes & tasks - //reportovanie pre platformu + //process nodes & tasks - read node's data if (processNodes) { + + let time = Date.now(); + for (let k in nodesData) { let address = parseInt(k); let tbname = nodesData[k].tbname; let register = 0; - //logger.debug("generated cmd - buildTasks for node:", address); - - //listOfCommands - READ for (let i = 0; i < listOfCommands.length; i++) { + register = listOfCommands[i]; - - let params = getParams(PRIORITY_TYPES.node_cmd); - - //core rpc values - params.address = address; - params.byte1 = 0; - params.byte2 = 0; - params.byte3 = 0; - params.byte4 = 0; - params.recipient = 1; - params.register = register; - params.rw = 0; - let addMinutesToTimestamp = priorities[register]; - let timestampStart = PRIORITY_TYPES.node_cmd; //run imediatelly in function runTasks - if (addMinutesToTimestamp > 1) { - timestampStart = timestampStart + addMinutesToTimestamp * 60000; - } + let params = getParams(); - //other values - params.type = "cmd"; + params.address = address; + params.recipient = 1; + params.register = register; + params.type = register == 1 ? "node-dimming-read" : "node-regular-read"; params.tbname = tbname; - params.timestamp = timestampStart; + params.timestamp = time + 5000 + i * 500 + addMinutesToTimestamp * 1000; //to make slight time difference params.addMinutesToTimestamp = addMinutesToTimestamp; - params.info = "generated cmd - buildTasks (node)"; + params.info = "Node regular read command"; tasks.push(params); - } + } } @@ -1228,31 +1145,26 @@ exports.install = function(instance) { if (!init) return; - //Priebežne (raz za cca 5 minút) je potrebné vyčítať z Master nodu verziu jeho FW. - //Jedná sa o register 10. Rovnaká interpretácia ako pri FW verzii nodu. - //Adresa mastera je 0. V prípade že kedykoľvek nastane situácia že Master Node neodpovedá (napríklad pri vyčítaní telemetrie z nodu nevráti žiadne dáta), - //tak treba vyreportovať string "NOK". + //Master node FW version - modifies SETTINGS.masterNodeIsResponding { - let params = getParams(PRIORITY_TYPES.fw_detection); + let params = getParams(); params.type = "cmd-master"; params.register = 4; params.address = 0; - params.timestamp = Date.now() + 60000; + params.timestamp = 0; params.addMinutesToTimestamp = 5; params.tbname = SETTINGS.rvoTbName; params.info = "Master node FW verzia"; //params.debug = true; - //this will set SETTINGS.masterNodeIsResponding - tasks.push(params); } //kazdu hodinu skontrolovat nastavenie profilov { - let params = getParams(PRIORITY_TYPES.fw_detection); + let params = getParams(); params.type = "process_profiles"; - params.timestamp = Date.now() + 60000; + params.timestamp = Date.now() + 60001; params.addMinutesToTimestamp = 60;//60 = every hour params.info = "detekcia nespracovaných profilov linie a nodov"; //params.debug = true; @@ -1358,7 +1270,12 @@ exports.install = function(instance) { let data = null; - if (newStatus == true && nodeCurrentStatus == true && nodeObj.time_of_last_communication > now - TIME_AFTER_WE_UPDATE_LAST_NODE_COMMUNICATION) return; + if (nodeCurrentStatus === "OFFLINE") { + data = { status: newStatus }; + nodeDbStatusModify(node, data); + return; + } + else if (newStatus == true && nodeCurrentStatus == true && nodeObj.time_of_last_communication > now - TIME_AFTER_WE_UPDATE_LAST_NODE_COMMUNICATION) return; else if (newStatus == true && nodeCurrentStatus == true && nodeObj.time_of_last_communication < now - TIME_AFTER_WE_UPDATE_LAST_NODE_COMMUNICATION) { data = { time_of_last_communication: now }; nodeDbStatusModify(node, data); @@ -1405,7 +1322,7 @@ exports.install = function(instance) { if ((currentTimestamp - reportDuskDawn.dusk_time) < 60 * 1000) { //reportovali sme? if (reportDuskDawn.dusk_time_reported != sunCalcResult.dusk_time) { - //sendNotification("CMD Manager: calculated Time of dusk", SETTINGS.rvoTbName, "dusk_has_occured", { value: sunCalcResult["dusk"] }, "", SEND_TO.tb, instance); + //sendNotification("Cmd-mngr: calculated Time of dusk", SETTINGS.rvoTbName, "dusk_has_occured", { value: sunCalcResult["dusk"] }, "", SEND_TO.tb, instance); reportDuskDawn.dusk_time_reported = sunCalcResult.dusk_time; } } @@ -1422,7 +1339,7 @@ exports.install = function(instance) { if ((currentTimestamp - reportDuskDawn.dawn_time) < 60 * 1000) { //reportovali sme? if (reportDuskDawn.dawn_time_reported != sunCalcResult.dawn_time) { - //sendNotification("CMD Manager: calculated Time of dawn", SETTINGS.rvoTbName, "dawn_has_occured", { value: sunCalcResult["dawn"] }, "", SEND_TO.tb, instance); + //sendNotification(": calculated Time of dawn", SETTINGS.rvoTbName, "dawn_has_occured", { value: sunCalcResult["dawn"] }, "", SEND_TO.tb, instance); reportDuskDawn.dawn_time_reported = sunCalcResult.dawn_time; } } @@ -1453,7 +1370,7 @@ exports.install = function(instance) { if (!rsPort.isOpen) { instance.send(SEND_TO.debug, "!rsPort.isOpen"); //await rsPort.open(); - //console.log("Cmd_manager - !rsPort.isOpen"); + //console.log("Cmd-mngr: !rsPort.isOpen"); } let currentTask = tasks[0]; @@ -1474,33 +1391,27 @@ exports.install = function(instance) { let type = params.type; let tbname = params.tbname; let node = params.address; - + let register = params.register; let line = null; + let itIsNodeCommand; + + if (nodesData[node] !== undefined) { + line = nodesData[node].line; + itIsNodeCommand = true; + } - //rpc related - if (nodesData[node] !== undefined) line = nodesData[node].line; if (params.line !== undefined) line = params.line; - let repeatTask = false; - if (params.addMinutesToTimestamp > 0 || params.timePointName) repeatTask = true; - - if (repeatTask) { - if (type === "cmd" || type === "cmd-master") { - //set next start time automatically - tasks[0].timestamp = currentTimestamp + tasks[0].addMinutesToTimestamp * 60000; - } - } - else { + if (params.addMinutesToTimestamp > 0 || params.timePointName) { + tasks[0].timestamp = currentTimestamp + tasks[0].addMinutesToTimestamp * 60000; + } else { tasks.shift(); } //kontrola nespracovanych profilov nodov if (type == "process_profiles") { - tasks[0].timestamp = currentTimestamp + tasks[0].addMinutesToTimestamp * 60000; - - //vsetky linie kt. su zapnute, a spracuju sa nespracovane profily nodov + //na vsetky zapnutych liniach sa spracuju nespracovane profily nodov loadRelaysData(); - interval = setInterval(runTasks, SHORT_INTERVAL); return; } @@ -1539,52 +1450,17 @@ exports.install = function(instance) { turnLine(onOrOff, params.line, info); - interval = setInterval(runTasks, SHORT_INTERVAL); + interval = setInterval(runTasks, LONG_INTERVAL); return; } - //zhodeny hlavny istic - let disconnected = false; - //if(rotary_switch_state == "Off") disconnected = true; - - //state_of_breaker[line] - alebo istic linie - if (state_of_breaker.hasOwnProperty(line)) { - //if(state_of_breaker[line] == "Off") disconnected = true; - } - - //toto sa reportuje po prijati dat z dido_controlera - if (disconnected) { - let values = { "status": "OFFLINE" }; - - logger.debug("disconnected", values); - logger.debug("rotary_switch_state", rotary_switch_state); - logger.debug("state_of_breaker", state_of_breaker[line]); - - //report only once! - if (!disconnectedReport.hasOwnProperty(tbname)) disconnectedReport[tbname] = false; - - if (!disconnectedReport[tbname]) { - sendTelemetry(values, tbname) - } - - interval = setInterval(runTasks, SHORT_INTERVAL); - - return; - } - - disconnectedReport[tbname] = false; - - const register = params.register; - - //high_priority if (!SETTINGS.masterNodeIsResponding) { - //ak neodpoveda, nebudeme vykonavat ziadne commands, okrem cmd-terminal, a fw version + //ak neodpoveda, nebudeme vykonavat ziadne commands, okrem cmd-terminal cmd-master errorHandler.sendMessageToService("Master node is not responding"); let stop = true; - //fw version - register == 4 - if (type == "cmd-terminal" || register == 4) stop = false; + if (type === "cmd-terminal" || type === "cmd-master") stop = false; if (stop) { interval = setInterval(runTasks, LONG_INTERVAL); return; @@ -1594,31 +1470,14 @@ exports.install = function(instance) { let contactorStatus = 1; if (relaysData[line] != undefined) contactorStatus = relaysData[line].contactor; - if (line == 0 || contactorStatus == 0) { + if (line === 0 || contactorStatus === 0 || FLOW.deviceStatus.state_of_breaker[line] === "Off") { interval = setInterval(runTasks, LONG_INTERVAL); return; } // TODO: -> status offline for rvo if rotary_switch_state is OFF, this is source of errors - // - // let relayStatus = 1; - // if (relaysData[line] != undefined) { - // relayStatus = relaysData[line].contactor; - // } - - // if (line == 0) relayStatus = 0; - // if (type == "cmd-terminal") relayStatus = 1; - - // //check if rotary_switch_state == "Off" - // if (relayStatus == 0) { - // console.log("------------------------------------relayStatus", relayStatus, line); - // let values = { "status": "OFFLINE" }; - - // if(tbname) sendTelemetry(values, tbname) - - // interval = setInterval(runTasks, SHORT_INTERVAL); - // return; - // } + // check if rotary_switch_state == "Off" + // state_of_braker: disconnected = true? if (!rsPort.isOpen) { interval = setInterval(runTasks, LONG_INTERVAL); @@ -1631,8 +1490,6 @@ exports.install = function(instance) { var d = new Date(); params.byte1 = d.getHours();//h params.byte2 = d.getMinutes();//m - params.byte3 = 0;//s - params.byte4 = 0; } //SET DUSK/DAWN FOR BROADCAST @@ -1643,11 +1500,6 @@ exports.install = function(instance) { let sunCalcResult = calculateDuskDawn(); params.byte1 = sunCalcResult["dusk_hours"];//h params.byte2 = sunCalcResult["dusk_minutes"];//m - params.byte3 = 0;//s - params.byte4 = 0; - - //TODO astrohodiny - let dusk = "Time of dusk: " + sunCalcResult["dusk"]; } } @@ -1655,15 +1507,9 @@ exports.install = function(instance) { if (register == 7 && params.recipient === 2) { if (type != "cmd-terminal") { let sunCalcResult = calculateDuskDawn(); - params.byte1 = sunCalcResult["dawn_hours"];//h + params.byte1 = sunCalcResult["dawn_hours"];//h params.byte2 = sunCalcResult["dawn_minutes"];//m - params.byte3 = 0;//s - params.byte4 = 0; - - //TODO astrohodiny - let dawn = "Time of dawn: " + sunCalcResult["dawn"]; } - } //----------------------- @@ -1674,15 +1520,18 @@ exports.install = function(instance) { let saveToTb = true; if (!tbname) saveToTb = false; - let itIsNodeCommand = listOfCommands.includes(register); //reading data from node (voltage, current, dimming, status) let resp = com_generic(node, params.recipient, params.rw, register, params.name, params.byte1, params.byte2, params.byte3, params.byte4); let readBytes = 11; let timeout = 4000; + // await keyword is important, otherwise incorrect data is returned! await writeData(rsPort, resp, readBytes, timeout).then(function(data) { + //sometimes happens, that status of node changes even if line was turned off and should be offline. To prevent this, we return if line contactor is 0: + if (itIsNodeCommand && line && relaysData[line].contactor !== 1) return; + endTime = new Date(); var timeDiff = endTime - startTime; @@ -1693,25 +1542,14 @@ exports.install = function(instance) { //ak sa odpoved zacina 0 - je to v poriadku, inak je NOK let message = result.message; // OK, NOK let message_type = result.type; - let error = result.error; - if (params.debug != "generated cmd") { - //debug("writeData: done " + message_type + " duration: " + timeDiff + " message_type: " + params.debug, params); + if (params.hasOwnProperty("debug")) { + if (params.debug) { + console.log("detected response:", result); + logger.debug("Cmd-mngr: writeData done " + message_type + " duration: " + timeDiff + " type: " + params.debug, params, result); + } } - // if(params.hasOwnProperty("debug")) - // { - // if(params.debug) - // { - // console.log("detected response:", result); - - // logger.debug("writeData: done " + message_typetype + " duration: " + timeDiff + " type: " + params.debug, params, result); - // } - // } - - //debug("writeData: done " + message_type + " duration: " + timeDiff + " message_type: " + params.debug); - //debug("writeData done", message_type, "duration", timeDiff, "message_type", params.debug, result); - let values = {}; //CMD FINISHED @@ -1726,7 +1564,7 @@ exports.install = function(instance) { dbNodes.modify({ processed: true }).where("node", node).make(function(builder) { builder.callback(function(err, response) { - sendNotification("CMD Manager: process cmd", SETTINGS.rvoTbName, "dimming_profile_was_successfully_received_by_node", { node: node }, "", SEND_TO.tb, instance); + sendNotification("Cmd-mngr: process cmd", SETTINGS.rvoTbName, "dimming_profile_was_successfully_received_by_node", { node: node }, "", SEND_TO.tb, instance); logger.debug("--> profil úspešne odoslaný na node č. " + node); nodesData[node].processed = true; @@ -1744,26 +1582,22 @@ exports.install = function(instance) { if (itIsNodeCommand) { values.comm_status = "OK"; values.status = "OK"; + nodesData[node].readout = { ...nodesData[node].readout, ...values }; } //master node if (node == 0) { - sendNotification("CMD Manager: process cmd", SETTINGS.rvoTbName, "master_node_is_responding_again", {}, "", SEND_TO.tb, instance, "rvo_status"); + sendNotification("Cmd-mngr: process cmd", SETTINGS.rvoTbName, "master_node_is_responding_again", {}, "", SEND_TO.tb, instance, "rvo_status"); SETTINGS.masterNodeIsResponding = true; if (register == 4) values["edge_fw_version"] = SETTINGS.edge_fw_version; } - //odoslanie príkazu z terminálu - dáta - if (type == "cmd-terminal") { - sendNotification("CMD Manager: process cmd", SETTINGS.rvoTbName, "command_was_sent_from_terminal_interface", {}, params, SEND_TO.tb, instance); - } - if (params.debug) { //logger.debug("saveToTb", saveToTb, tbname, values); } - if (saveToTb) { - sendTelemetry(values, tbname) + if (saveToTb && type != "node-regular-read") { + sendTelemetry(values, tbname); } else { if (type == "cmd-terminal") { @@ -1773,8 +1607,7 @@ exports.install = function(instance) { } else { - - terminalCommandResponse(params, "ERROR", data) + terminalCommandResponse(params, "ERROR", data); handleNokResponseOnRsPort("handleNOK else block", params, itIsNodeCommand, saveToTb); if (params.hasOwnProperty("debug")) { @@ -1788,7 +1621,7 @@ exports.install = function(instance) { } }).catch(function(reason) { - console.log("writeData catch exception", reason); + //console.log("writeData catch exception", reason); instance.send(SEND_TO.debug, reason); terminalCommandResponse(params, "FAILURE", null, reason); @@ -1817,6 +1650,15 @@ exports.install = function(instance) { } + function repeatCommand(params) { + params.repeatCounter++; + if (params.repeatCounter < 4) { + params.timestamp = 0; + params.addMinutesToTimestamp = 0; + tasks.push(params); + } + } + function handleNokResponseOnRsPort(message, params, itIsNodeCommand, saveToTb) { let node = params.address; @@ -1827,12 +1669,24 @@ exports.install = function(instance) { let values = {}; - // console.log(message); let updateStatus = updateNodeStatus(node, false); + if (itIsNodeCommand) { + values.comm_status = "NOK"; + nodesData[node].readout.comm_status = "NOK"; + repeatCommand(params); + } + + if (updateStatus) { + values.status = "NOK"; + nodesData[node].readout.status = "NOK"; + } + + if (type === "node-regular-read") return; + //master node if (node == 0) { - sendNotification("CMD Manager: process cmd", SETTINGS.rvoTbName, "master_node_is_not_responding", {}, "", SEND_TO.tb, instance, "rvo_status"); + sendNotification("Cmd-mngr: process cmd", SETTINGS.rvoTbName, "master_node_is_not_responding", {}, "", SEND_TO.tb, instance, "rvo_status"); logger.debug("master_node_is_not_responding", params); SETTINGS.masterNodeIsResponding = false; @@ -1844,27 +1698,29 @@ exports.install = function(instance) { logger.debug("profil nebol úspešne odoslaný na node č. ", params); if (!nodeProfileSendFail.has(node)) { - sendNotification("CMD Manager: process cmd", tbName, "configuration_of_dimming_profile_to_node_failed", { node: node }, "", SEND_TO.tb, instance); + sendNotification("Cmd-mngr: process cmd", tbName, "configuration_of_dimming_profile_to_node_failed", { node: node }, "", SEND_TO.tb, instance); nodeProfileSendFail.add(node); } } - if (itIsNodeCommand) { - values.comm_status = "NOK"; - } - - if (updateStatus) { - values.status = "NOK"; - } - // console.log("------",node, register, type, itIsNodeCommand, updateStatus, saveToTb, values); - if (saveToTb && Object.keys(values).length > 0) { - sendTelemetry(values, tbName) + if (saveToTb) { + sendTelemetry(values, tbName); } } + function sendNodesData() { + Object.keys(nodesData).forEach(node => { + if (nodesData[node]["status"] !== "OFFLINE") { + sendTelemetry(nodesData[node].readout, nodesData[node].tbname); + nodesData[node].readout = {}; + } + }) + } + + /** * function handles requests from terminal * responseType can be "SUCCESS", "ERROR" or "FAILURE", depending on rsPort data. @@ -1872,13 +1728,10 @@ exports.install = function(instance) { */ function terminalCommandResponse(params, responseType, data = null, reason = "") { //success, error, failure - if (params.refFlowdataKey == undefined) { + if (params.refFlowdataKey === undefined) { //console.log("params.refFlowdataKey is undefined", params); return; } - else { - console.log("params.refFlowdataKey: ", params); - } let message = null; let type = null; @@ -1901,7 +1754,6 @@ exports.install = function(instance) { } logger.debug(message); - logger.debug(params); //make http response let responseObj = {} @@ -1939,15 +1791,19 @@ exports.install = function(instance) { let nodeObj = nodesData_clone[key]; if (nodeObj.tbname == undefined) continue; - if (nodeObj.status) number_of_ok_luminaires++; + if (nodeObj.status === "OFFLINE") { + nodeObj.node_status_before_offline === true ? number_of_ok_luminaires++ : number_of_nok_luminaires++; + } + else if (nodeObj.status == true) number_of_ok_luminaires++; else number_of_nok_luminaires++; + } const values = { "number_of_luminaires": number_of_luminaires, "number_of_ok_luminaires": number_of_ok_luminaires, "number_of_nok_luminaires": number_of_nok_luminaires, - "edge_date_time": ts + "edge_date_time": ts - ts % 60000 //round to full minute }; sendTelemetry(values, SETTINGS.rvoTbName, ts); @@ -1956,6 +1812,11 @@ exports.install = function(instance) { function handleRsPort() { + if (rsPort) { + rsPort.removeAllListeners(); + rsPort = null; + } + //! rsPort LM = "/dev/ttymxc4", rsPort UNIPI = "/dev/ttyUSB0" // const rsPort = new SerialPort("/dev/ttymxc4", { autoOpen: false }); //LM // const rsPort = new SerialPort("/dev/ttyUSB0", { autoOpen: false }); // UNIPI @@ -1967,41 +1828,26 @@ exports.install = function(instance) { rsPort.on('open', async function() { - logger.debug("CMD manager - rsPort opened success"); - - //loadRelaysData(); + logger.debug("Cmd-mngr: rsPort opened success"); await runSyncExec(`stty -F /dev/${SETTINGS.serial_port} 115200 min 1 time 5 ignbrk -brkint -icrnl -imaxbel -opost -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke`).then(function(status) { instance.send(SEND_TO.debug, "RPC runSyncExec - Promise Resolved:" + status); logger.debug(0, "RPC runSyncExec - Promise Resolved:" + status); - //APP START - let dataToInfoSender = { id: SETTINGS.project_id, name: SETTINGS.rvo_name }; - dataToInfoSender.fw_version = SETTINGS.edge_fw_version; - dataToInfoSender.startdate = new Date().toISOString().slice(0, 19).replace('T', ' '); - dataToInfoSender.__force__ = true; - - instance.send(SEND_TO.infoSender, dataToInfoSender); - - logger.debug(0, "---------------------------->START message send to service", dataToInfoSender); - }).catch(function(reason) { - instance.send(SEND_TO.debug, "CMD manager - RPC runSyncExec - promise rejected:" + reason); + instance.send(SEND_TO.debug, "Cmd-mngr: RPC runSyncExec - promise rejected:" + reason); }); }); rsPort.on('error', function(err) { - - //TODO report to service!!! - //errLogger.error(exports.title, "unable to open port", SETTINGS.serial_port, err.message); errorHandler.sendMessageToService([exports.title, "unable to open port", SETTINGS.serial_port, err.message], 0); - - instance.send(SEND_TO.debug, err.message); + monitor.info("Cmd-mngr: Error on rsPort", err.message); }); rsPort.on("close", () => { - setTimeout(() => rsPort.open(), 1000); + monitor.info("Cmd-mngr: rsPort closed, reconnecting..."); + setTimeout(handleRsPort, 1000); }); rsPort.open(); @@ -2012,11 +1858,12 @@ exports.install = function(instance) { clearInterval(interval); clearInterval(customTasksInterval); clearInterval(setCorrectTime); + clearInterval(sendNodeReadout); + clearInterval(accelerometerInterval); rsPort.close(); }); - - instance.on("0", flowdata => { + instance.on("0", _ => { main(); }) @@ -2075,14 +1922,14 @@ exports.install = function(instance) { if (cmd == "buildTasks") { clearInterval(interval); - logger.debug("-->CMD MANAGER - BUILD TASKS"); + logger.debug("-->Cmd-mngr: BUILD TASKS"); buildTasks(); //logger.debug("tasks:"); //logger.debug(tasks); - logger.debug("-->CMD MANAGER - RUN TASKS"); - interval = setInterval(runTasks, LONG_INTERVAL); + logger.debug("-->Cmd-mngr: RUN TASKS"); + interval = setInterval(runTasks, 5000); } else if (cmd == "reload_relays") { loadRelaysData(flowdata.data.line); @@ -2155,8 +2002,8 @@ exports.install = function(instance) { if (relaysData.hasOwnProperty(line)) { let tbname = relaysData[line].tbname; - if (value == "Off") sendNotification("CMD Manager: onData", tbname, "circuit_breaker_was_turned_off_line", { line: line }, "", SEND_TO.tb, instance, "circuit_breaker"); - else sendNotification("CMD Manager: onData", tbname, "circuit_breaker_was_turned_on_line", { line: line }, "", SEND_TO.tb, instance, "circuit_breaker"); + if (value == "Off") sendNotification("Cmd-mngr: onData", tbname, "circuit_breaker_was_turned_off_line", { line: line }, "", SEND_TO.tb, instance, "circuit_breaker"); + else sendNotification("Cmd-mngr: onData", tbname, "circuit_breaker_was_turned_on_line", { line: line }, "", SEND_TO.tb, instance, "circuit_breaker"); //report status liniu sendTelemetry({ status: status }, tbname) @@ -2180,7 +2027,16 @@ exports.install = function(instance) { if (flowdata.data.hasOwnProperty("topic")) { let data = getNested(flowdata.data, "content", "data"); - if (data == undefined) { + + //if we get temperature in senica from senica-prod01 + let temperature = getNested(flowdata.data, "content", "senica_temperature"); + + if (temperature !== undefined) { + temperatureInSenica = temperature; + return; + } + + if (data === undefined) { console.log("Invalid rpc command came from platform"); return; } @@ -2220,20 +2076,17 @@ exports.install = function(instance) { value = parseInt(value); if (value > 0) value = value + 128; - //set dimming - LUM1_13 - 647 je node linie 1 kt. dobre vidime - params.type = "cmd"; + params.type = "node-onetime-write"; params.tbname = tbname; params.address = node; - params.register = 1;//dimming - params.recipient = 1;//slave + params.register = 1; + params.recipient = 1; params.byte4 = value; - params.rw = 1;//write + params.rw = 1; params.timestamp = PRIORITY_TYPES.high_priority; params.info = 'set dimming from platform'; //params.debug = true; - //ak linia je - //debug(params); logger.debug("dimming", params); @@ -2246,15 +2099,15 @@ exports.install = function(instance) { { let params = getParams(PRIORITY_TYPES.high_priority); - params.type = "cmd"; + params.type = "node-onetime-read"; params.tbname = tbname; params.address = node; - params.register = 1;//dimming - params.recipient = 1;//slave - params.rw = 0;//read + params.register = 1; + params.recipient = 1; + params.rw = 0; params.timestamp = PRIORITY_TYPES.high_priority; params.info = 'read dimming (after set dimming from platform)'; - params.debug = true; + //params.debug = true; tasks.push(params); } @@ -2263,15 +2116,15 @@ exports.install = function(instance) { { let params = getParams(PRIORITY_TYPES.high_priority); - params.type = "cmd"; + params.type = "node-onetime-read"; params.tbname = tbname; params.address = node; params.register = 76; - params.recipient = 1;//slave - params.rw = 0;//read + params.recipient = 1; + params.rw = 0; params.timestamp = PRIORITY_TYPES.high_priority; params.info = 'read Input Power (after set dimming from platform)'; - params.debug = true; + //params.debug = true; tasks.push(params); } @@ -2280,15 +2133,15 @@ exports.install = function(instance) { { let params = getParams(PRIORITY_TYPES.high_priority); - params.type = "cmd"; + params.type = "node-onetime-read"; params.tbname = tbname; params.address = node; params.register = 75; - params.recipient = 1;//slave - params.rw = 0;//read + params.recipient = 1; + params.rw = 0; params.timestamp = PRIORITY_TYPES.high_priority; params.info = 'read Input Current (after set dimming from platform)'; - params.debug = true; + //params.debug = true; tasks.push(params); } @@ -2297,24 +2150,22 @@ exports.install = function(instance) { { let params = getParams(PRIORITY_TYPES.high_priority); - params.type = "cmd"; + params.type = "node-onetime-read"; params.tbname = tbname; params.address = node; params.register = 77; - params.recipient = 1;//slave - params.rw = 0;//read + params.recipient = 1; + params.rw = 0; params.timestamp = PRIORITY_TYPES.high_priority; - params.info = 'read power factor - Cos phi (after set dimming from platform)'; - params.debug = true; + params.info = 'read power factor (after set dimming from platform)'; + //params.debug = true; tasks.push(params); } }, 4000); - nodeWasFound = true; - break; } } @@ -2350,7 +2201,7 @@ exports.install = function(instance) { if (profile === "") logger.debug("worksys - update node profile done - profile is empty"); //profil úspešne prijatý pre node č. xx - sendNotification("CMD manager", tbname, "dimming_profile_was_processed_for_node", { node: node }, profile, SEND_TO.tb, instance); + sendNotification("Cmd-mngr", tbname, "dimming_profile_was_processed_for_node", { node: node }, profile, SEND_TO.tb, instance); nodesData[node].processed = false; nodesData[node].profile = profile; @@ -2400,16 +2251,11 @@ exports.install = function(instance) { relaysData[line].profile = profile; loadRelaysData(line) - - //TODO build tasks by mala bezat az ked je vsetko loadRelaysData - //spracovane, pravdepodobne treba spravit promisy logger.debug("loadRelaysData DONE for line", line); - console.log("zacina buildTasks po loadRelaysData.........") buildTasks({ processLineProfiles: true, line: line }); - sendNotification("CMD manager - set profile from worksys", tbname, "switching_profile_was_processed_for_line", { line: line }, profile, SEND_TO.tb, instance); - + sendNotification("Cmd-mngr: set profile from worksys", tbname, "switching_profile_was_processed_for_line", { line: line }, profile, SEND_TO.tb, instance); }); }); break; @@ -2452,7 +2298,7 @@ exports.install = function(instance) { let params = flowdata.data.body; if (params == undefined) { - //logger.debug("CMD manager flowdata.data.body is undefined"); + //logger.debug("Cmd-mngr: flowdata.data.body is undefined"); return; } @@ -2724,7 +2570,7 @@ exports.install = function(instance) { } //Dimming, CCT - if (register == 1) { + else if (register == 1) { let brightness = 0; let dimming = byte0; if (dimming > 128) { @@ -2745,168 +2591,86 @@ exports.install = function(instance) { } // - if (register == 4) { + else if (register == 4) { values["master_node_version"] = bytes[1] + "." + bytes[2]; //logger.debug("FW Version", register, bytes); } //Napätie - if (register == 74) { + else if (register == 74) { let voltage = (bytesToInt(bytes) * 0.1).toFixed(1); values["voltage"] = Number(voltage); } //Prúd - if (register == 75) { + else if (register == 75) { let current = bytesToInt(bytes); values["current"] = current; } //výkon - if (register == 76) { + else if (register == 76) { let power = (bytesToInt(bytes) * 0.1).toFixed(2); values["power"] = Number(power); } //účinník - if (register == 77) { - let power_factor = Math.cos(bytesToInt(bytes) * 0.1).toFixed(2); + else if (register == 77) { + let power_factor = Math.cos(bytesToInt(bytes) * 0.1 * (Math.PI / 180)).toFixed(2); values["power_factor"] = Number(power_factor); } //frekvencia - if (register == 78) { + else if (register == 78) { let frequency = (bytesToInt(bytes) * 0.1).toFixed(2); values["frequency"] = Number(frequency); } //energia - if (register == 79) { + else if (register == 79) { let energy = bytesToInt(bytes); - - //Energiu treba reportovať v kWh. Teda číslo, ktoré príde treba podeliť 1000. Toto som ti možno zle napísal. - - values["energy"] = energy / 1000; + values["energy"] = energy / 1000; //energia v kWh -> delit 1000 } //doba života - if (register == 80) { + else if (register == 80) { let lifetime = (bytesToInt(bytes) / 60).toFixed(2); values["lifetime"] = Number(lifetime); } //nastavenie profilu - if (register == 8) { + else if (register == 8) { let time_schedule_settings = bytesToInt(bytes); values["time_schedule_settings"] = time_schedule_settings; } - //skupinová adresa 1 - if (register == 3) { - let gr_add_1 = bytesToInt(byte0); - values["gr_add_1"] = gr_add_1; - - let gr_add_2 = bytesToInt(byte1); - values["gr_add_2"] = gr_add_2; - - let gr_add_3 = bytesToInt(byte2); - values["gr_add_3"] = gr_add_3; - - let gr_add_4 = bytesToInt(byte3); - values["gr_add_4"] = gr_add_4; + //naklon - nateraz sa z nodu nevycitava! kvoli problemom s accelerometrom a vracanymi hodnotami, posielame temp a x y z vo funkcii accelerometerData() + else if (register == 84) { + values["temperature"] = byte3 >= 128 ? (byte3 - 128) * (-1) : byte3; + values["inclination_x"] = byte2 >= 128 ? (byte2 - 128) * (-1) : byte2; + values["inclination_y"] = byte1 >= 128 ? (byte1 - 128) * (-1) : byte1; + values["inclination_z"] = byte0 >= 128 ? (byte0 - 128) * (-1) : byte0; } - //naklon - if (register == 84) { - let temp; - if (byte3 >= 128) { - temp = (byte3 - 128) * (-1); - } - else { - temp = byte3; - } - - let inclination_x; - if (byte2 >= 128) { - inclination_x = (byte2 - 128) * (-1); - } - else { - inclination_x = byte2; - } - - let inclination_y; - if (byte1 >= 128) { - inclination_y = (byte1 - 128) * (-1); - } - else { - inclination_y = byte1; - } - - let inclination_z; - if (byte0 >= 128) { - inclination_z = (byte0 - 128) * (-1); - } - else { - inclination_z = byte0; - } - - values["temperature"] = temp; - - //náklon x - values["inclination_x"] = inclination_x; - - //náklon y - values["inclination_y"] = inclination_y; - - //náklon z - values["inclination_z"] = inclination_z; - } - - let h = byte3; - let m = byte2; - - let timestamp; - - if (register == 87 || register == 6 || register == 7) { - //if(byte3 < 10) h = "0" + byte3; - //if(byte2 < 10) m = "0" + byte2; - //if(byte1 < 10) s = "0" + byte1; - - var d = new Date(); - d.setHours(h, m, 0, 0); - timestamp = d.getTime(); - } - - //aktuálny čas - if (register == 87) { - //Byte3 - hodiny, Byte 2 - minúty, Byte 1 -sek. - //values["actual_time"] = h + ":" + m + ":" + s; - - values["actual_time"] = timestamp; - } - - //čas súmraku - if (register == 6) { - //Byte3 - hodiny, Byte 2 - minúty, Byte 1 -sek. - //values["dusk_time"] = h + ":" + m + ":" + s; - - values["dusk_time"] = timestamp; - } - - //čas úsvitu - if (register == 7) { - //Byte3 - hodiny, Byte 2 - minúty, Byte 1 -sek. - //values["dawn_time"] = h + ":" + m + ":" + s; - - values["dawn_time"] = timestamp; - } - - //FW verzia - if (register == 89) { + //FW verzia nodu + else if (register == 89) { //formát: "Byte3: Byte2.Byte1 (Byte0)" values["fw_version"] = byte3 + ":" + byte2 + "." + byte1 + "(" + byte0 + ")"; } + else if (register == 87 || register == 6 || register == 7) { + var d = new Date(); + d.setHours(byte3, byte2, 0, 0); + let timestamp = d.getTime(); + + //aktuálny čas + if (register == 87) values["actual_time"] = timestamp; + //čas súmraku + else if (register == 6) values["dusk_time"] = timestamp; + //čas úsvitu + else if (register == 7) values["dawn_time"] = timestamp; + } + return values; } @@ -2984,5 +2748,52 @@ exports.install = function(instance) { return (typeof item === "object" && !Array.isArray(item) && item !== null); } + + // we fake data, that should be received from accelerometer, as they are a bit unreliable. (temperature, x,y,z) + function accelerometerData() { + + if (temperatureInSenica === null) return; + + //clone nodesData and relaysData objects + let nodesData_clone = JSON.parse(JSON.stringify(nodesData)); + let relaysData_clone = JSON.parse(JSON.stringify(relaysData)); + + for (const key in relaysData_clone) { + + const lineData = relaysData_clone[key]; + const lineNumber = lineData.line; + const contactor = lineData.contactor; + + if (lineNumber === 0) continue; + + if (contactor === 1) { + + let date = Date.now(); + + Object.keys(nodesData_clone).forEach((node, index) => { + + setTimeout(function() { + + if (nodesData_clone[node].line === lineNumber) { + + // NOTE: if status of luminaire is NOK or OFFLINE, we do not send data; + let status = nodesData_clone[node].status; + if (status === "OFFLINE" || !status) return; + + let x = null; + if (naklony.hasOwnProperty(node)) x = naklony[node].naklon; + if (x === null) x = 0; + + sendTelemetry({ temperature: Math.round(temperatureInSenica + 10 + Math.floor(Math.random() * 3)), inclination_x: x, inclination_y: 0, inclination_z: 0 }, nodesData_clone[node].tbname, date); + } + + }, (index + 1) * 500); + }) + + } + } + } + + } // end of instance.export diff --git a/flow/count.js b/flow/count.js new file mode 100644 index 0000000..fa92ee9 --- /dev/null +++ b/flow/count.js @@ -0,0 +1,60 @@ +exports.id = 'count'; +exports.title = 'Count'; +exports.version = '1.0.1'; +exports.author = 'John Graves'; +exports.color = '#656D78'; +exports.icon = 'plus-square'; +exports.input = 2; +exports.output = 1; +exports.options = { increment: 1, initialvalue: 1 }; +exports.readme = `# Counter + +Counter Number of times called.`; + +exports.html = `
+
@(Initial Value)
+
@(Increment)
+

Example Video

+
`; + +exports.readme = `# Count + +This component counts the number of messages received. + +__Response:__ + +Integer value based on the initial value and increment settings. + +__Arguments:__ +- Initial Value: What number should be output on the receipt of the first message. +- Increment: What should the increment be for each following message received.`; + +exports.install = function(instance) { + + var count = 0; + var initialCall = true; + + instance.on('data', function(flowdata) { + var index = flowdata.index; + if (index) { + instance.debug('Reset Count.'); + count = instance.options.initialvalue; + initialCall = true; + } else { + // If this is the first time, set the value to 'initial value' + if(initialCall) { + initialCall = false; + count = instance.options.initialvalue; + } else + count = count+instance.options.increment; + instance.status('Count:' + count); + instance.send2(count); + } + }); + + instance.on('options', function() { + count = instance.options.initialvalue; + initialCall = true; + }); + +}; diff --git a/flow/db_init.js b/flow/db_init.js index c43e4a2..60a0510 100644 --- a/flow/db_init.js +++ b/flow/db_init.js @@ -4,103 +4,106 @@ exports.group = 'Worksys'; exports.color = '#888600'; exports.version = '1.0.2'; exports.icon = 'sign-out'; -exports.input = 1; -exports.output = ["blue"]; - -exports.html = `
-
-
-
Hostname or IP address (if not empty - setting will override db setting)
-
-
-
Port
-
-
-
-
-
@(Client id)
-
-
-
@(Username)
-
-
-
`; - +exports.output = 2; exports.readme = ` -# DB initialization + # DB initialization `; const { promisifyBuilder, makeMapFromDbResult } = require('./helper/db_helper.js'); const { initNotification } = require('./helper/notification_reporter'); +const errorHandler = require('./helper/ErrorToServiceHandler'); +const total_energy = require('../databases/total_energy'); + +const SEND_TO = { + db_init: 0, + infoSender: 1 +}; exports.install = async function(instance) { + const dbNodes = TABLE("nodes"); + const dbRelays = TABLE("relays"); + const dbSettings = TABLE("settings"); + const dbPins = TABLE("pins"); + const dbNotifications = TABLE("notifications"); - const dbNodes = TABLE("nodes"); - const dbRelays = TABLE("relays"); - const dbSettings = TABLE("settings"); - const dbPins = TABLE("pins"); - const dbNotifications = TABLE("notifications"); + FLOW.GLOBALS = {}; + const dbs = FLOW.GLOBALS; - FLOW.GLOBALS = {}; - const dbs = FLOW.GLOBALS; + const responseSettings = await promisifyBuilder(dbSettings.find()); + const responseNodes = await promisifyBuilder(dbNodes.find()); + const responsePins = await promisifyBuilder(dbPins.find()); + const responseRelays = await promisifyBuilder(dbRelays.find()); + const response = await promisifyBuilder(dbNotifications.find()); - const responseSettings = await promisifyBuilder(dbSettings.find()); - const responseNodes = await promisifyBuilder(dbNodes.find()); - const responsePins = await promisifyBuilder(dbPins.find()); - const responseRelays = await promisifyBuilder(dbRelays.find()); - const response = await promisifyBuilder(dbNotifications.find()); + dbs.pinsData = makeMapFromDbResult(responsePins, "pin"); + dbs.relaysData = makeMapFromDbResult(responseRelays, "line"); + dbs.nodesData = makeMapFromDbResult(responseNodes, "node"); + dbs.notificationsData = makeMapFromDbResult(response, "key"); - dbs.pinsData = makeMapFromDbResult(responsePins, "pin"); - dbs.relaysData = makeMapFromDbResult(responseRelays, "line"); - dbs.nodesData = makeMapFromDbResult(responseNodes, "node"); - dbs.notificationsData = makeMapFromDbResult(response, "key"); + //+|354|nodesdata.....+|482|nodesdata.... + //for some reason, if last line in nodes.table is not empty, flow wrote more nodes data in one row, + //so we have to add empty line at the bottom of nodes table to avoid this. + //now, remove empty lines from nodesData database: + if (dbs.nodesData.hasOwnProperty("0")) delete dbs.nodesData["0"]; + Object.keys(dbs.nodesData).forEach(node => dbs.nodesData[node].readout = {}) - //+|354|nodesdata.....+|482|nodesdata.... - //for some reason, if last line in nodes.table is not empty, flow wrote more nodes data in one row, - //so we have to add empty line at the bottom of nodes table to avoid this. - //now, remove empty lines from nodesData database: - if(dbs.nodesData.hasOwnProperty("0")) delete dbs.nodesData["0"]; + dbs.settings = { + edge_fw_version: "2025-07-08", //rok-mesiac-den + language: responseSettings[0]["lang"], + rvo_name: responseSettings[0]["rvo_name"], + project_id: responseSettings[0]["project_id"], + rvoTbName: dbs.relaysData[0]["tbname"], + temperature_address: responseSettings[0]["temperature_address"], + controller_type: responseSettings[0]["controller_type"], + serial_port: responseSettings[0]["serial_port"], + node_status_nok_time: responseSettings[0]["node_status_nok_time"] * 60 * 60 * 1000,// hour * minutes * + latitude: responseSettings[0]["latitude"], + longitude: responseSettings[0]["longitude"], + no_voltage: new Set(),//modbus_citysys - elektromer + backup_on_failure: responseSettings[0]["backup_on_failure"], + restore_from_backup: responseSettings[0]["restore_from_backup"], + restore_backup_wait: responseSettings[0]["restore_backup_wait"], + mqtt_host: responseSettings[0]["mqtt_host"], + mqtt_clientid: responseSettings[0]["mqtt_clientid"], + mqtt_username: responseSettings[0]["mqtt_username"], + mqtt_port: responseSettings[0]["mqtt_port"], + phases: responseSettings[0]["phases"], + cloud_topic: responseSettings[0]["cloud_topic"], + has_main_switch: responseSettings[0]["has_main_switch"], - dbs.settings = { - edge_fw_version : "2025-01-02", //rok-mesiac-den - language : responseSettings[0]["lang"], - rvo_name : responseSettings[0]["rvo_name"], - project_id : responseSettings[0]["project_id"], - rvoTbName : dbs.relaysData[0]["tbname"], - temperature_address : responseSettings[0]["temperature_address"], - controller_type : responseSettings[0]["controller_type"], - serial_port : responseSettings[0]["serial_port"], - node_status_nok_time : responseSettings[0]["node_status_nok_time"] * 60 * 60 * 1000 ,// hour * minutes * - latitude : responseSettings[0]["latitude"], - longitude : responseSettings[0]["longitude"], - no_voltage : new Set(),//modbus_citysys - elektromer - backup_on_failure : responseSettings[0]["backup_on_failure"], - restore_from_backup : responseSettings[0]["restore_from_backup"], - restore_backup_wait : responseSettings[0]["restore_backup_wait"], - mqtt_host : responseSettings[0]["mqtt_host"], - mqtt_clientid : responseSettings[0]["mqtt_clientid"], - mqtt_username : responseSettings[0]["mqtt_username"], - mqtt_port : responseSettings[0]["mqtt_port"], - phases: responseSettings[0]["phases"], - cloud_topic: responseSettings[0]["cloud_topic"], - - //dynamic values - masterNodeIsResponding : true, //cmd_manager - maintenance_mode : false, - } - - FLOW.dbLoaded = true; - initNotification(); - - setTimeout(()=> { - console.log("DB_INIT - data loaded"); - instance.send(0, "_") - }, 5000) - -}; + //dynamic values + masterNodeIsResponding: true, //cmd_manager + maintenance_mode: false, + } + let rvo_number = responseSettings[0]["rvo_name"].match(/\D+(\d{1,2})_/)[1]; + dbs.settings.energy_to_switch_lamps = total_energy[rvo_number]; + if (dbs.settings.energy_to_switch_lamps === undefined) console.log('=============== db_init.js: energy_to_switch_lamps is undefined'); + FLOW.dbLoaded = true; + errorHandler.setProjectId(dbs.settings.project_id); + initNotification(); + + //APP START - send to data services + const toService = { + id: dbs.settings.project_id, + name: dbs.settings.rvo_name, + fw_version: dbs.settings.edge_fw_version, + startdate: new Date().toISOString().slice(0, 19).replace('T', ' '), + js_error: "", + error_message: "" + }; + + instance.send(SEND_TO.infoSender, toService); + console.log("----------------> START - message send to service", toService); + + setTimeout(() => { + console.log("DB_INIT - data loaded"); + instance.send(SEND_TO.db_init, "_") + }, 5000) + +}; diff --git a/flow/designer.json b/flow/designer.json index fbdda76..7565777 100644 --- a/flow/designer.json +++ b/flow/designer.json @@ -36,21 +36,21 @@ "text": "Enabled", "color": "gray" }, - "color": "#DA4453", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#DA4453", + "notes": "" }, { "id": "1612776786008", "component": "wsmqttpublish", "tab": "1612772287426", "name": "WS MQTT publish", - "x": 304.75, - "y": 237, + "x": 281.75, + "y": 174, "connections": { "0": [ { @@ -69,10 +69,6 @@ } ], "2": [ - { - "index": "0", - "id": "1618300863816" - }, { "index": "0", "id": "1634303685503" @@ -90,25 +86,25 @@ "output": [] }, "state": { - "text": "Reconnecting", - "color": "yellow" + "text": "Connected", + "color": "green" }, - "color": "#888600", - "notes": "", "options": { "username": "", "clientid": "", "port": "1883", "host": "" - } + }, + "color": "#888600", + "notes": "" }, { "id": "1612778461252", "component": "virtualwirein", "tab": "1612772287426", "name": "tb-push", - "x": 86.75, - "y": 375, + "x": 72.75, + "y": 328, "connections": { "0": [ { @@ -133,19 +129,19 @@ "text": "tb-push", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "tb-push" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1612783322136", "component": "debug", "tab": "1612772287426", "name": "to TB", - "x": 306.75, - "y": 371, + "x": 283.75, + "y": 324, "connections": {}, "disabledio": { "input": [ @@ -157,21 +153,21 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1615551060773", "component": "debug", "tab": "1612772287426", "name": "errors from MQTT Broker", - "x": 650, - "y": 76, + "x": 594, + "y": 57, "connections": {}, "disabledio": { "input": [ @@ -183,21 +179,21 @@ "text": "Enabled", "color": "gray" }, - "color": "#DA4453", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#DA4453", + "notes": "" }, { "id": "1615563373927", "component": "debug", "tab": "1615551125555", "name": "Debug", - "x": 753, - "y": 150, + "x": 755, + "y": 155, "connections": {}, "disabledio": { "input": [ @@ -209,21 +205,21 @@ "text": "Enabled", "color": "gray" }, - "color": "#DA4453", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#DA4453", + "notes": "" }, { "id": "1615566865233", "component": "virtualwireout", "tab": "1615551125555", "name": "tb-push", - "x": 761, - "y": 251, + "x": 755, + "y": 248, "connections": {}, "disabledio": { "input": [], @@ -233,19 +229,19 @@ "text": "tb-push", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "tb-push" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1615798582262", "component": "debug", "tab": "1615551125555", "name": "CMD_debug", - "x": 765, - "y": 350, + "x": 755, + "y": 346, "connections": {}, "disabledio": { "input": [ @@ -257,21 +253,21 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1615802995322", "component": "debug", "tab": "1611921777196", "name": "Debug", - "x": 595.8833312988281, - "y": 557.3500061035156, + "x": 596.8833312988281, + "y": 566.3500061035156, "connections": {}, "disabledio": { "input": [], @@ -281,21 +277,21 @@ "text": "Disabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": false - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1615809128443", "component": "debug", "tab": "1611921777196", "name": "tempToTb", - "x": 598.8833312988281, - "y": 654.3500061035156, + "x": 595.8833312988281, + "y": 658.3500061035156, "connections": {}, "disabledio": { "input": [], @@ -305,21 +301,21 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1615809595184", "component": "virtualwireout", "tab": "1611921777196", "name": "tb-push", - "x": 594.8833312988281, - "y": 350.25, + "x": 597.8833312988281, + "y": 377.25, "connections": {}, "disabledio": { "input": [], @@ -329,19 +325,19 @@ "text": "tb-push", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "tb-push" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1616165795916", "component": "httproute", "tab": "1615551125555", "name": "POST /terminal", - "x": 114, - "y": 546, + "x": 135, + "y": 547, "connections": { "0": [ { @@ -362,9 +358,6 @@ "text": "Listening", "color": "green" }, - "color": "#5D9CEC", - "notes": "### Configuration\n\n- __POST /terminal__\n- flags: \n- maximum request data length: __5 kB__\n- empty response: __false__\n- cache policy: __no cache__\n- cache expire: __5 minutes__", - "cloning": false, "options": { "timeout": 10, "cachepolicy": 0, @@ -379,15 +372,18 @@ 10000 ], "emptyresponse": false - } + }, + "color": "#5D9CEC", + "notes": "### Configuration\n\n- __POST /terminal__\n- flags: \n- maximum request data length: __5 kB__\n- empty response: __false__\n- cache policy: __no cache__\n- cache expire: __5 minutes__", + "cloning": false }, { "id": "1616165824813", "component": "httpresponse", "tab": "1615551125555", "name": "HTTP Response", - "x": 772, - "y": 443, + "x": 753, + "y": 423, "connections": {}, "disabledio": { "input": [], @@ -397,11 +393,11 @@ "text": "", "color": "gray" }, - "color": "#5D9CEC", - "notes": "", "options": { "datatype": "json" - } + }, + "color": "#5D9CEC", + "notes": "" }, { "id": "1617104731852", @@ -421,21 +417,21 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1617114651703", "component": "trigger", "tab": "1615551125555", "name": "turnOff line", - "x": 88, - "y": 1158, + "x": 133, + "y": 1161, "connections": { "0": [ { @@ -452,12 +448,12 @@ "text": "", "color": "gray" }, - "color": "#F6BB42", - "notes": "", "options": { - "datatype": "object", - "data": "{line: 3, command: \"turnOff\", force: true}" - } + "data": "{line: 3, command: \"turnOff\", force: true}", + "datatype": "object" + }, + "color": "#F6BB42", + "notes": "" }, { "id": "1617115013095", @@ -475,11 +471,11 @@ "text": "tb-push", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "tb-push" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1617284749681", @@ -487,7 +483,7 @@ "tab": "1615551125555", "name": "update profile / node", "x": 112, - "y": 215, + "y": 208, "connections": { "0": [ { @@ -504,20 +500,20 @@ "text": "", "color": "gray" }, - "color": "#F6BB42", - "notes": "", "options": { - "data": "profile_nodes", - "datatype": "string" - } + "datatype": "string", + "data": "profile_nodes" + }, + "color": "#F6BB42", + "notes": "" }, { "id": "1618235171399", "component": "trigger", "tab": "1615551125555", "name": "tun tasks", - "x": 119, - "y": 280, + "x": 184, + "y": 279, "connections": { "0": [ { @@ -534,19 +530,19 @@ "text": "", "color": "gray" }, - "color": "#F6BB42", - "notes": "", "options": { "data": "run" - } + }, + "color": "#F6BB42", + "notes": "" }, { "id": "1618300858252", "component": "debug", "tab": "1612772287426", "name": "wsmqtt-exit1", - "x": 650.8833312988281, - "y": 160, + "x": 597.8833312988281, + "y": 149, "connections": {}, "disabledio": { "input": [], @@ -556,39 +552,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } - }, - { - "id": "1618300863816", - "component": "debug", - "tab": "1612772287426", - "name": "wsmqtt-exit2", - "x": 845.8833312988281, - "y": 320, - "connections": {}, - "disabledio": { - "input": [ - 0 - ], - "output": [] - }, - "state": { - "text": "Enabled", - "color": "gray" }, "color": "#967ADC", - "notes": "", - "options": { - "type": "data", - "repository": false, - "enabled": true - } + "notes": "" }, { "id": "1618393583970", @@ -606,19 +576,19 @@ "text": "from-dido-controller", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "from-dido-controller" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1618393674428", "component": "virtualwirein", "tab": "1615551125555", "name": "platform-rpc-call", - "x": 119.88333129882812, - "y": 369, + "x": 132.88333129882812, + "y": 367, "connections": { "0": [ { @@ -635,18 +605,18 @@ "text": "platform-rpc-call", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "platform-rpc-call" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1618393759854", "component": "virtualwirein", "tab": "1615551125555", "name": "cmd_to_dido", - "x": 93.88333129882812, + "x": 119.88333129882812, "y": 1007, "connections": { "0": [ @@ -668,19 +638,19 @@ "text": "cmd_to_dido", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "cmd_to_dido" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1618393827655", "component": "virtualwireout", "tab": "1615551125555", "name": "cmd_to_dido", - "x": 779.8833312988281, - "y": 552, + "x": 752.8833312988281, + "y": 527, "connections": {}, "disabledio": { "input": [], @@ -690,19 +660,19 @@ "text": "cmd_to_dido", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "cmd_to_dido" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1618558465485", "component": "virtualwireout", "tab": "1612772287426", "name": "platform-rpc-call", - "x": 649.8833312988281, - "y": 246, + "x": 597.8833312988281, + "y": 247, "connections": {}, "disabledio": { "input": [], @@ -712,18 +682,18 @@ "text": "platform-rpc-call", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "platform-rpc-call" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1618572059773", "component": "trigger", "tab": "1615551125555", "name": "turnOn line", - "x": 89, + "x": 132, "y": 1085, "connections": { "0": [ @@ -741,12 +711,12 @@ "text": "", "color": "gray" }, - "color": "#F6BB42", - "notes": "", "options": { - "data": "{line: 1, command: \"turnOn\", force: true}", - "datatype": "object" - } + "datatype": "object", + "data": "{line: 1, command: \"turnOn\", force: true}" + }, + "color": "#F6BB42", + "notes": "" }, { "id": "1619515097737", @@ -799,17 +769,17 @@ "text": "", "color": "gray" }, + "options": {}, "color": "#5D9CEC", - "notes": "", - "options": {} + "notes": "" }, { "id": "1619605019281", "component": "httproute", "tab": "1615551125555", "name": "GET db", - "x": 115, - "y": 651, + "x": 173, + "y": 653, "connections": { "0": [ { @@ -830,9 +800,6 @@ "text": "Listening", "color": "green" }, - "color": "#5D9CEC", - "notes": "### Configuration\n\n- __GET /db__\n- flags: undefined\n- maximum request data length: __5 kB__\n- empty response: __undefined__\n- cache policy: __no cache__\n- cache expire: __5 minutes__", - "cloning": false, "options": { "timeout": 5, "cachepolicy": 0, @@ -846,15 +813,18 @@ "get", 5000 ] - } + }, + "color": "#5D9CEC", + "notes": "### Configuration\n\n- __GET /db__\n- flags: undefined\n- maximum request data length: __5 kB__\n- empty response: __undefined__\n- cache policy: __no cache__\n- cache expire: __5 minutes__", + "cloning": false }, { "id": "1619784672383", "component": "trigger", "tab": "1615551125555", "name": "turnOnAlarm", - "x": 85, - "y": 1231, + "x": 120, + "y": 1234, "connections": { "0": [ { @@ -871,20 +841,20 @@ "text": "", "color": "gray" }, - "color": "#F6BB42", - "notes": "", "options": { - "datatype": "object", - "data": "{command: \"turnOnAlarm\"}" - } + "data": "{command: \"turnOnAlarm\"}", + "datatype": "object" + }, + "color": "#F6BB42", + "notes": "" }, { "id": "1619784812964", "component": "trigger", "tab": "1615551125555", "name": "turnOffAlarm", - "x": 84, - "y": 1304, + "x": 118, + "y": 1307, "connections": { "0": [ { @@ -901,20 +871,20 @@ "text": "", "color": "gray" }, - "color": "#F6BB42", - "notes": "", "options": { - "datatype": "object", - "data": "{command: \"turnOffAlarm\"}" - } + "data": "{command: \"turnOffAlarm\"}", + "datatype": "object" + }, + "color": "#F6BB42", + "notes": "" }, { "id": "1621340721628", "component": "virtualwireout", "tab": "1611921777196", "name": "modbus_to_dido", - "x": 596, - "y": 462, + "x": 599, + "y": 471, "connections": {}, "disabledio": { "input": [], @@ -924,11 +894,11 @@ "text": "modbus_to_dido", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "modbus_to_dido" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1622640022885", @@ -953,9 +923,6 @@ "text": "Listening", "color": "green" }, - "color": "#5D9CEC", - "notes": "### Configuration\n\n- __POST /db_connector__\n- flags: \n- maximum request data length: __5 kB__\n- empty response: __undefined__\n- cache policy: __no cache__\n- cache expire: __5 minutes__", - "cloning": false, "options": { "timeout": 5, "cachepolicy": 0, @@ -968,7 +935,10 @@ "post", 5000 ] - } + }, + "color": "#5D9CEC", + "notes": "### Configuration\n\n- __POST /db_connector__\n- flags: \n- maximum request data length: __5 kB__\n- empty response: __undefined__\n- cache policy: __no cache__\n- cache expire: __5 minutes__", + "cloning": false }, { "id": "1622640073521", @@ -993,11 +963,11 @@ "text": "", "color": "gray" }, - "color": "#2134B0", - "notes": "", "options": { "edge": "undefined" - } + }, + "color": "#2134B0", + "notes": "" }, { "id": "1622641420685", @@ -1015,9 +985,9 @@ "text": "", "color": "gray" }, + "options": {}, "color": "#5D9CEC", - "notes": "", - "options": {} + "notes": "" }, { "id": "1634303504177", @@ -1025,7 +995,7 @@ "tab": "1612772287426", "name": "RAM", "x": 69.88333129882812, - "y": 885.5, + "y": 888.5, "connections": { "0": [ { @@ -1039,15 +1009,15 @@ "output": [] }, "state": { - "text": "776.75 MB / 987.80 MB", + "text": "840.05 MB / 985.68 MB", "color": "gray" }, - "color": "#F6BB42", - "notes": "", "options": { "enabled": true, "interval": 30000 - } + }, + "color": "#F6BB42", + "notes": "" }, { "id": "1634303533779", @@ -1069,16 +1039,16 @@ "output": [] }, "state": { - "text": "5.79 GB / 7.26 GB", + "text": "5.78 GB / 7.26 GB", "color": "gray" }, - "color": "#F6BB42", - "notes": "", "options": { "enabled": true, "path": "/", "interval": 30000 - } + }, + "color": "#F6BB42", + "notes": "" }, { "id": "1634303595494", @@ -1107,11 +1077,11 @@ "text": "send-to-services", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "send-to-services" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1634303602169", @@ -1129,19 +1099,19 @@ "text": "send-to-services", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "send-to-services" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1634303685503", "component": "virtualwireout", "tab": "1612772287426", "name": "send-to-services", - "x": 650.8833312988281, - "y": 355.5, + "x": 600.8833312988281, + "y": 341.5, "connections": {}, "disabledio": { "input": [], @@ -1151,11 +1121,11 @@ "text": "send-to-services", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "send-to-services" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1634303743260", @@ -1163,8 +1133,8 @@ "tab": "1612772287426", "name": "192.168.252.2:8004/sentmessage", "reference": "", - "x": 480.8833312988281, - "y": 1334.7333374023438, + "x": 506.8833312988281, + "y": 1331.7333374023438, "connections": { "0": [ { @@ -1181,21 +1151,21 @@ "text": "", "color": "gray" }, - "color": "#5D9CEC", - "notes": "", "options": { - "url": "http://192.168.252.2:8004/sentmessage", + "stringify": "json", "method": "POST", - "stringify": "json" - } + "url": "http://192.168.252.2:8004/sentmessage" + }, + "color": "#5D9CEC", + "notes": "" }, { "id": "1634463186563", "component": "debug", "tab": "1612772287426", "name": "Debug", - "x": 280.75, - "y": 1446, + "x": 305.75, + "y": 1442, "connections": {}, "disabledio": { "input": [ @@ -1207,21 +1177,21 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1634464580289", "component": "code", "tab": "1612772287426", "name": "Code", - "x": 253, - "y": 788, + "x": 245, + "y": 787, "connections": { "0": [ { @@ -1242,13 +1212,13 @@ "text": "", "color": "gray" }, - "color": "#656D78", - "notes": "", "options": { "keepmessage": true, "code": "let response = {};\nresponse.cpu = value.cpu;\nresponse.uptime = value.uptime;\n\nsend(0, response);", "outputs": 1 - } + }, + "color": "#656D78", + "notes": "" }, { "id": "1634465243324", @@ -1268,20 +1238,20 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1634465281992", "component": "code", "tab": "1612772287426", "name": "Code", - "x": 242, + "x": 245, "y": 884, "connections": { "0": [ @@ -1303,13 +1273,13 @@ "text": "", "color": "gray" }, - "color": "#656D78", - "notes": "", "options": { "keepmessage": true, - "code": "value.sender = \"ram\";\n//let total = value.total/1024/1024;\n//let free = value.free/1024/1024;\n//let used = value.used/1024/1024;\nlet response = {};\n//value.memory_total = (total).toFixed(0) + ' MB';\n//value.memory_free = (free).toFixed(0) + ' MB';\n//value.memory_used = (used).toFixed(0) + ' MB';\n\nresponse.memory_total = value.total;\nresponse.memory_free = value.free;\nresponse.memory_used = value.used;\n\nsend(0, response);", + "code": "value.sender = \"ram\";\n\nlet response = {};\n\nresponse.memory_total = Math.round(value.total / (1024 ** 2));\nresponse.memory_free = Math.round(value.free / (1024 ** 2));\nresponse.memory_used = Math.round(value.used / (1024 ** 2));\n\nsend(0, response);", "outputs": 1 - } + }, + "color": "#656D78", + "notes": "" }, { "id": "1634465338103", @@ -1329,13 +1299,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1634465821120", @@ -1364,13 +1334,13 @@ "text": "", "color": "gray" }, - "color": "#656D78", - "notes": "", "options": { "keepmessage": true, - "code": "value.sender = \"hdd\";\n//let total = value.total/1024/1024;\n//let free = value.free/1024/1024;\n//let used = value.used/1024/1024;\nlet response = {};\n//value.hdd_total = (total).toFixed(0) + ' MB';\n//value.hdd_free = (free).toFixed(0) + ' MB';\n//value.used = (used).toFixed(0) + ' MB';\n\nresponse.hdd_total = value.total;\nresponse.hdd_free = value.free;\nresponse.hdd_used = value.used;\n\nsend(0, response);", + "code": "value.sender = \"hdd\";\n\nlet response = {};\n\nresponse.hdd_total = Math.round(value.total / (1024 ** 2));\nresponse.hdd_free = Math.round(value.free / (1024 ** 2));\nresponse.hdd_used = Math.round(value.used / (1024 ** 2));\n\nsend(0, response);", "outputs": 1 - } + }, + "color": "#656D78", + "notes": "" }, { "id": "1634465892500", @@ -1390,20 +1360,20 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1634484067516", "component": "debug", "tab": "1612772287426", "name": "Send info", - "x": 480, + "x": 513, "y": 1441, "connections": {}, "disabledio": { @@ -1416,21 +1386,21 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1634488120710", "component": "infosender", "tab": "1612772287426", "name": "Info sender", - "x": 285, - "y": 1338, + "x": 301, + "y": 1336, "connections": { "0": [ { @@ -1451,19 +1421,19 @@ "text": "", "color": "gray" }, - "color": "#2134B0", - "notes": "", "options": { "edge": "undefined" - } + }, + "color": "#2134B0", + "notes": "" }, { "id": "1635327431236", "component": "debug", "tab": "1612772287426", "name": "Debug", - "x": 795.8833312988281, - "y": 1329.5, + "x": 837.8833312988281, + "y": 1325.5, "connections": {}, "disabledio": { "input": [ @@ -1475,21 +1445,21 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1635936391935", "component": "virtualwireout", "tab": "1615551125555", "name": "send-to-services", - "x": 778, - "y": 656, + "x": 753, + "y": 623, "connections": {}, "disabledio": { "input": [], @@ -1499,11 +1469,11 @@ "text": "send-to-services", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "send-to-services" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1637069803394", @@ -1525,11 +1495,9 @@ "output": [] }, "state": { - "text": "1.5% / 72.32 MB", + "text": "2.4% / 74.33 MB", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "monitorfiles": true, "monitorconnections": true, @@ -1537,7 +1505,9 @@ "monitorconsumption": true, "enabled": true, "interval": 30000 - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1683664161036", @@ -1557,21 +1527,21 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1683981346282", "component": "virtualwirein", "tab": "1615551125555", "name": "from-dido-controller", - "x": 113, - "y": 456, + "x": 112, + "y": 459, "connections": { "0": [ { @@ -1592,19 +1562,19 @@ "text": "from-dido-controller", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "from-dido-controller" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1684055037116", "component": "debug", "tab": "1615551125555", "name": "from dido to cmd", - "x": 448, - "y": 519, + "x": 451, + "y": 532, "connections": {}, "disabledio": { "input": [ @@ -1616,21 +1586,21 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1684060205000", "component": "debug", "tab": "1615551125555", "name": "HTTP routes", - "x": 447, - "y": 620, + "x": 450, + "y": 639, "connections": {}, "disabledio": { "input": [ @@ -1642,13 +1612,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1684179110403", @@ -1666,13 +1636,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1699963668903", @@ -1713,11 +1683,11 @@ "text": "", "color": "gray" }, - "color": "#2134B0", - "notes": "", "options": { "edge": "undefined" - } + }, + "color": "#2134B0", + "notes": "" }, { "id": "1699964678894", @@ -1746,11 +1716,11 @@ "text": "modbus_to_dido", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "modbus_to_dido" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1699964793925", @@ -1770,13 +1740,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1699965957410", @@ -1825,9 +1795,9 @@ "text": "", "color": "gray" }, + "options": {}, "color": "#2134B0", - "notes": "", - "options": {} + "notes": "" }, { "id": "1700411878636", @@ -1861,6 +1831,10 @@ { "index": "0", "id": "1732889185927" + }, + { + "index": "0", + "id": "1717441414646" } ] }, @@ -1872,17 +1846,17 @@ "text": "", "color": "gray" }, + "options": {}, "color": "#5CB36D", - "notes": "", - "options": {} + "notes": "" }, { "id": "1714752862828", "component": "debug", "tab": "1611921777196", "name": "MDBToTb", - "x": 599, - "y": 257, + "x": 766, + "y": 324, "connections": {}, "disabledio": { "input": [], @@ -1892,21 +1866,21 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1717441414646", "component": "code", "tab": "1611921777196", "name": "device-status", - "x": 755.0833282470703, - "y": 209, + "x": 764.0833282470703, + "y": 222, "connections": { "0": [ { @@ -1927,13 +1901,13 @@ "text": "", "color": "gray" }, - "color": "#656D78", - "notes": "", "options": { "keepmessage": true, - "code": "if(value.hasOwnProperty(\"status\"))\n{\n\tif(value.status.includes(\"-em\"))\n\t{\n\t\tsend(0, {\"em_status\": \"NOK\"});\n\t}\n\telse if(value.status.includes(\"twilight\"))\n\t{\n\t\tsend(0, {\"lux_sensor\": \"NOK\"});\n\t}\n}\n\nif(value.hasOwnProperty(\"values\"))\n{\n\tif(value.values.hasOwnProperty(\"twilight_sensor\"))\n\t{\n\t\tsend(0, {\"lux_sensor\": \"OK\"});\n\t}\n\telse if(value.values.hasOwnProperty(\"Phase_1_power\") ||\n\t\t\tvalue.values.hasOwnProperty(\"Phase_1_voltage\") ||\n\t\t\tvalue.values.hasOwnProperty(\"Total_power\") ||\n\t\t\tvalue.values.hasOwnProperty(\"Phase_1_current\"))\n\t{\n\t\tsend(0, {\"em_status\": \"OK\"});\n\t}\n}", + "code": "if(value.hasOwnProperty(\"status\"))\n{\n\tif(value.status.includes(\"-em\"))\n\t{\n\t\tsend(0, {\"em_status\": \"NOK\"});\n\t}\n\telse if(value.status.includes(\"twilight\"))\n\t{\n\t\tsend(0, {\"lux_sensor\": \"NOK\"});\n\t}\n\telse if(value.status === \"NOK-thermometer\")\n\t{\n\t\tsend(0, {\"thermometer\": \"NOK\"});\n\t}\n}\n\nif(value.hasOwnProperty(\"values\"))\n{\n\tif(value.values.hasOwnProperty(\"twilight_sensor\"))\n\t{\n\t\tsend(0, {\"lux_sensor\": \"OK\"});\n\t}\n\telse if(value.values.hasOwnProperty(\"Phase_1_power\") ||\n\t\t\tvalue.values.hasOwnProperty(\"Phase_1_voltage\") ||\n\t\t\tvalue.values.hasOwnProperty(\"Total_power\") ||\n\t\t\tvalue.values.hasOwnProperty(\"Phase_1_current\"))\n\t{\n\t\tsend(0, {\"em_status\": \"OK\"});\n\t}\n\telse if(value.values.hasOwnProperty(\"temperature\"))\n\t{\n\t\tsend(0, {\"thermometer\": \"OK\"});\n\t}\n}", "outputs": 1 - } + }, + "color": "#656D78", + "notes": "" }, { "id": "1717442627834", @@ -1941,7 +1915,7 @@ "tab": "1611921777196", "name": "modbus service", "x": 966.0833282470703, - "y": 152, + "y": 165, "connections": {}, "disabledio": { "input": [ @@ -1953,13 +1927,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1717442631338", @@ -1977,11 +1951,11 @@ "text": "send-to-services", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "send-to-services" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1718016045116", @@ -2006,11 +1980,11 @@ "text": "tb-push", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "tb-push" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1718016052341", @@ -2039,15 +2013,15 @@ "text": "Running", "color": "gray" }, - "color": "#30E193", - "notes": "", "options": { "slack_channel": "C071KN2Q8SK", "tag_on_include": "[{\"user_id\":\"U072JE5JUQG\", \"includes\":[\"Electrometer\", \"Twilight sensor\"]}]", - "message_includes": "[\"is responding again\", \"Lamps have turned\", \"Flow has been restarted\", \"Node db has changed\"]", + "message_includes": "[\"is responding again\", \"Flow has been restarted\", \"Node db has changed\"]", "types": "[\"emergency\", \"critical\", \"error\", \"alert\"]", - "name": "al_shariff_10.0.0.38" - } + "name": "rvo_senica_33_10.0.0.127" + }, + "color": "#30E193", + "notes": "" }, { "id": "1718016073501", @@ -2072,13 +2046,13 @@ "text": "", "color": "gray" }, - "color": "#5D9CEC", - "notes": "", "options": { - "url": "http://192.168.252.2:8004/slack", + "stringify": "json", "method": "POST", - "stringify": "json" - } + "url": "http://192.168.252.2:8004/slack" + }, + "color": "#5D9CEC", + "notes": "" }, { "id": "1718016086212", @@ -2098,13 +2072,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1718016094070", @@ -2129,19 +2103,19 @@ "text": "", "color": "gray" }, - "color": "#F6BB42", - "notes": "", "options": { - "data": "{ \"g9OxBZ5KRwNznlY6pAppqEAWXvjdEL4eGQobMDy2\": [ { \"ts\": 1716289039281, \"values\": { \"_event\": { \"type\": \"alert\", \"status\": \"new\", \"source\": { \"func\": \"CMD Manager: process cmd\", \"component\": \"1619515097737\", \"component_name\": \"CMD Manager\", \"edge\": \"g9OxBZ5KRwNznlY6pAppqEAWXvjdEL4eGQobMDy2\" }, \"message\": \"NOW CONNECTED TO SLACK !\", \"message_data\": \"\" } } } ] }", - "datatype": "object" - } + "datatype": "object", + "data": "{ \"g9OxBZ5KRwNznlY6pAppqEAWXvjdEL4eGQobMDy2\": [ { \"ts\": 1716289039281, \"values\": { \"_event\": { \"type\": \"alert\", \"status\": \"new\", \"source\": { \"func\": \"CMD Manager: process cmd\", \"component\": \"1619515097737\", \"component_name\": \"CMD Manager\", \"edge\": \"g9OxBZ5KRwNznlY6pAppqEAWXvjdEL4eGQobMDy2\" }, \"message\": \"NOW CONNECTED TO SLACK !\", \"message_data\": \"\" } } } ] }" + }, + "color": "#F6BB42", + "notes": "" }, { "id": "1729855334955", "component": "virtualwireout", "tab": "1612772287426", "name": "platform-rpc-call", - "x": 649.9333343505859, + "x": 599.9333343505859, "y": 541.3500061035156, "connections": {}, "disabledio": { @@ -2152,19 +2126,19 @@ "text": "platform-rpc-call", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "platform-rpc-call" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1729855371093", "component": "debug", "tab": "1612772287426", "name": "rpc cloud", - "x": 650.9333343505859, - "y": 451.3500061035156, + "x": 601.9333343505859, + "y": 440.3500061035156, "connections": {}, "disabledio": { "input": [], @@ -2174,21 +2148,21 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1731068658334", "component": "virtualwirein", "tab": "1612772287426", "name": "db-init", - "x": 90.75, - "y": 250, + "x": 75.75, + "y": 184, "connections": { "0": [ { @@ -2205,19 +2179,19 @@ "text": "db-init", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "db-init" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1731068754606", "component": "cloudmqttconnect", "tab": "1612772287426", - "name": "MQTT client - to senica-prod01", - "x": 304.75, - "y": 474, + "name": "MQTT to senica-prod01", + "x": 284.75, + "y": 452, "connections": { "1": [ { @@ -2235,32 +2209,38 @@ "output": [] }, "state": { - "text": "Reconnecting", - "color": "yellow" + "text": "Connected", + "color": "green" }, - "color": "#888600", - "notes": "", "options": { "username": "", "clientid": "", "port": "2764", "host": "192.168.252.2", "topic": "" - } + }, + "color": "#888600", + "notes": "" }, { "id": "1731069001548", "component": "db_init", "tab": "1612772287426", "name": "DB Initialization", - "x": 91.75, - "y": 55.25, + "x": 1003.75, + "y": 240.25, "connections": { "0": [ { "index": "0", "id": "1731069033416" } + ], + "1": [ + { + "index": "0", + "id": "1747561603739" + } ] }, "disabledio": { @@ -2271,17 +2251,17 @@ "text": "", "color": "gray" }, + "options": {}, "color": "#888600", - "notes": "", - "options": {} + "notes": "" }, { "id": "1731069033416", "component": "virtualwireout", "tab": "1612772287426", "name": "db-init", - "x": 343.75, - "y": 50.25, + "x": 1244.75, + "y": 233.25, "connections": {}, "disabledio": { "input": [], @@ -2291,19 +2271,19 @@ "text": "db-init", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "db-init" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1731069059135", "component": "showdb", "tab": "1612772287426", "name": "Show db data", - "x": 1121.75, - "y": 814.25, + "x": 1186.75, + "y": 821.25, "connections": { "0": [ { @@ -2320,17 +2300,17 @@ "text": "", "color": "gray" }, + "options": {}, "color": "#888600", - "notes": "", - "options": {} + "notes": "" }, { "id": "1731069079243", "component": "debug", "tab": "1612772287426", "name": "dbData", - "x": 1315.75, - "y": 853.25, + "x": 1390.75, + "y": 870.25, "connections": {}, "disabledio": { "input": [], @@ -2340,21 +2320,21 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1731069116691", "component": "trigger", "tab": "1612772287426", "name": "settings", - "x": 911.75, - "y": 710.75, + "x": 934.75, + "y": 669.75, "connections": { "0": [ { @@ -2371,17 +2351,17 @@ "text": "", "color": "gray" }, + "options": {}, "color": "#F6BB42", - "notes": "", - "options": {} + "notes": "" }, { "id": "1731069131637", "component": "trigger", "tab": "1612772287426", "name": "relaysData", - "x": 832.75, - "y": 775.75, + "x": 876.75, + "y": 733.75, "connections": { "0": [ { @@ -2398,17 +2378,17 @@ "text": "", "color": "gray" }, + "options": {}, "color": "#F6BB42", - "notes": "", - "options": {} + "notes": "" }, { "id": "1731069137374", "component": "trigger", "tab": "1612772287426", "name": "nodesData", - "x": 747.75, - "y": 840.75, + "x": 852.75, + "y": 794.75, "connections": { "0": [ { @@ -2425,17 +2405,17 @@ "text": "", "color": "gray" }, + "options": {}, "color": "#F6BB42", - "notes": "", - "options": {} + "notes": "" }, { "id": "1731069179846", "component": "trigger", "tab": "1612772287426", "name": "pinsData", - "x": 803.75, - "y": 899.75, + "x": 850.75, + "y": 861.75, "connections": { "0": [ { @@ -2452,17 +2432,17 @@ "text": "", "color": "gray" }, + "options": {}, "color": "#F6BB42", - "notes": "", - "options": {} + "notes": "" }, { "id": "1731069192937", "component": "trigger", "tab": "1612772287426", "name": "sample data", - "x": 858.75, - "y": 959.75, + "x": 857.75, + "y": 928.75, "connections": { "0": [ { @@ -2479,9 +2459,9 @@ "text": "", "color": "gray" }, + "options": {}, "color": "#F6BB42", - "notes": "", - "options": {} + "notes": "" }, { "id": "1731069264443", @@ -2506,19 +2486,19 @@ "text": "db-init", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "db-init" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1731069334626", "component": "virtualwirein", "tab": "1615551125555", "name": "db-init", - "x": 151.88333129882812, - "y": 148, + "x": 172.88333129882812, + "y": 129, "connections": { "0": [ { @@ -2535,11 +2515,11 @@ "text": "db-init", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "db-init" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1731069548145", @@ -2564,11 +2544,11 @@ "text": "db-init", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "db-init" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1731069567152", @@ -2593,19 +2573,19 @@ "text": "db-init", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "db-init" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1731070156936", "component": "virtualwirein", "tab": "1615551125555", "name": "db-init", - "x": 89.88333129882812, - "y": 1381, + "x": 126.88333129882812, + "y": 1377, "connections": { "0": [ { @@ -2622,19 +2602,19 @@ "text": "db-init", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "db-init" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1731234189516", "component": "trigger", "tab": "1612772287426", "name": "monitor.txt", - "x": 915.75, - "y": 1017.75, + "x": 882.75, + "y": 991.75, "connections": { "0": [ { @@ -2651,17 +2631,17 @@ "text": "", "color": "gray" }, + "options": {}, "color": "#F6BB42", - "notes": "", - "options": {} + "notes": "" }, { "id": "1731234189551", "component": "trigger", "tab": "1612772287426", "name": "err.txt", - "x": 966.75, - "y": 1080.75, + "x": 904.75, + "y": 1053.75, "connections": { "0": [ { @@ -2678,9 +2658,9 @@ "text": "", "color": "gray" }, + "options": {}, "color": "#F6BB42", - "notes": "", - "options": {} + "notes": "" }, { "id": "1732700042559", @@ -2709,9 +2689,9 @@ "text": "", "color": "gray" }, + "options": {}, "color": "#888600", - "notes": "", - "options": {} + "notes": "" }, { "id": "1732700057052", @@ -2736,11 +2716,11 @@ "text": "db-init", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "db-init" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1732700071298", @@ -2758,13 +2738,13 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1732700642917", @@ -2782,11 +2762,11 @@ "text": "tb-push", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "tb-push" - } + }, + "color": "#303E4D", + "notes": "" }, { "id": "1732889185927", @@ -2794,7 +2774,7 @@ "tab": "1611921777196", "name": "tempToDido", "x": 594.8833312988281, - "y": 745, + "y": 753, "connections": {}, "disabledio": { "input": [], @@ -2804,21 +2784,21 @@ "text": "Enabled", "color": "gray" }, - "color": "#967ADC", - "notes": "", "options": { "type": "data", "repository": false, "enabled": true - } + }, + "color": "#967ADC", + "notes": "" }, { "id": "1733574412965", "component": "virtualwirein", "tab": "1612772287426", "name": "db-init", - "x": 86.75, - "y": 495, + "x": 72.75, + "y": 474, "connections": { "0": [ { @@ -2835,12 +2815,81 @@ "text": "db-init", "color": "gray" }, - "color": "#303E4D", - "notes": "", "options": { "wirename": "db-init" - } + }, + "color": "#303E4D", + "notes": "" + }, + { + "id": "1747561603739", + "component": "virtualwireout", + "tab": "1612772287426", + "name": "send-to-services", + "x": 1243.8833312988281, + "y": 334.5, + "connections": {}, + "disabledio": { + "input": [], + "output": [] + }, + "state": { + "text": "send-to-services", + "color": "gray" + }, + "options": { + "wirename": "send-to-services" + }, + "color": "#303E4D", + "notes": "" + }, + { + "id": "1747562867845", + "component": "comment", + "tab": "1612772287426", + "name": "FLOW STARTING POINT", + "x": 1003.5666656494141, + "y": 178, + "connections": {}, + "disabledio": { + "input": [], + "output": [] + }, + "state": { + "text": "", + "color": "gray" + }, + "options": {}, + "color": "#704cff", + "notes": "" + }, + { + "id": "1749211698385", + "component": "trigger", + "tab": "1612772287426", + "name": "deviceStatus", + "x": 911.75, + "y": 1116.75, + "connections": { + "0": [ + { + "index": "7", + "id": "1731069059135" + } + ] + }, + "disabledio": { + "input": [], + "output": [] + }, + "state": { + "text": "", + "color": "gray" + }, + "options": {}, + "color": "#F6BB42", + "notes": "" } ], - "version": 618 + "version": 615 } diff --git a/flow/dido_controller.js b/flow/dido_controller.js index 8415921..d16fb19 100644 --- a/flow/dido_controller.js +++ b/flow/dido_controller.js @@ -34,32 +34,22 @@ Currently we are interested in pins no. 1,2,3,6,8,9,10,16 pins number 11, 12, 13 (we receive 10,11,12 in rsPortReceivedData) are "stykace" When port receives data, it must be exactly 4 bytes long. Second byte is pin, that changed its value, fourth byte is value itself. After that, we set this value to "previousValues[allPins[whichpin]]" variable -*/ +state_of_main_switch - reportovat stav hlaveho istica : 0-> off 1-> on +rotary_switch_state - sem by sa mal reportovat stav vstupov manual a auto pola nasledovnej logiky: Manual = 1 a Auto = 0 -> Manu +Manual = 0 a Auto = 0 -> Off, Manual = 0 a Auto = 1 -> Automatic -/* -RVO objekt: -state_of_main_switch - sem sa bude reportovať stav hlavného ističa : 0-> off 1-> on (toto nie je na platforme, ale Rado to už do entity type doplnil) -rotary_switch_state - sem by sa mal reportovať stav vstupov manual a auto podľa nasledovnej logiky: - Manual = 1 a Auto = 0 -> vyreportuje Manual - Manual = 0 a Auto = 0 -> vyreportuje Off - Manual = 0 a Auto = 1 -> vyreportuje Automatic +door_condition - pin 6, dverový kontakt -> 1 -> vyreportuje Closed, 0 -> vyreportuje Ope +twilight_sensor - hodnotu, ktoru vracia ten analogovy vstup (17) treba poslat sem ako float number. Zrejme tu potom pridame nejaky koeficient prevodu na luxy -door_condition - tuto ide pin 6, dverový kontakt -> 1 -> vyreportuje Closed, 0 -> vyreportuje Open -twilight_sensor - hodnotu, ktorú vracia ten analógový vstup (17) treba poslať sem ako float number. Zrejme tu potom pridáme nejaký koeficient prevodu na luxy - -zjavne nám v jsone chýba stav hlavného ističa. Musíme to potom doplniť - -Na každú líniu: -state_of_breaker - podľa indexu ističa sa reportuje jeho stav, teda istič 1 na líniu 1: 0-> off 1-> on -state_of_contactor - podľa indexu stykača sa reportuje jeho stav, teda stykač 1 na líniu 1: 0-> off 1-> on - momentálne sa stav zmení len keď vo flow klikneš aby sa zmenil, ale tá zmena by sa mala ukázať aj na platforme +Na kazdu liniu +state_of_breaker - podla indexu istica sa reportuje jeho stav, teda istic na liniu 1: 0-> off, 1-> on +state_of_contactor - podla indexu stkaca sa reportuje jeho stav, teda stykac 1 na liniu 1: 0-> off, 1-> on */ const { errLogger, logger, monitor } = require('./helper/logger'); const SerialPort = require('serialport'); const WebSocket = require('ws'); -//const { exec } = require('child_process'); const { runSyncExec } = require('./helper/serialport_helper'); const { bytesToInt, resizeArray } = require('./helper/utils'); const { sendNotification } = require('./helper/notification_reporter'); @@ -68,8 +58,7 @@ const bitwise = require('bitwise'); const DataToTbHandler = require('./helper/DataToTbHandler'); let tbHandler; -const ErrorToServiceHandler = require('./helper/ErrorToServiceHandler'); -const errorHandler = new ErrorToServiceHandler(); +const errorHandler = require('./helper/ErrorToServiceHandler'); let ws = null; let rsPort = null; @@ -80,6 +69,7 @@ let rvoTbName; let GLOBALS; //FLOW global GLOBALS let SETTINGS; // GLOBALS.settings let controller_type; +let hasMainSwitch; let alarmStatus = "OFF"; @@ -107,7 +97,7 @@ exports.install = function(instance) { let previousValues = {}; let rsPortReceivedData = []; - //to be able to get proper twilight values, when + //to be able to get proper twilight values let twilight_sensor_interval = 5;//minutes let twilight_sensor = []; const twilight_sensor_array = []; @@ -134,21 +124,22 @@ exports.install = function(instance) { }; */ - //status for calculating Statecodes - let deviceStatus = { //key is device name: temperature,.... - "state_of_main_switch": "Off", //Hlavný istič - "rotary_switch_state": "Off", //Prevádzkový mód + //status for calculating Statecodes-we make it global to see it from outside + FLOW.deviceStatus = { //key is device name: temperature,.... + "state_of_main_switch": "Off", //Hlavny istic (alebo druhy dverovy kontakt) + "rotary_switch_state": "Off", //Prevadzkovy "door_condition": "closed", //Dverový kontakt "em": "OK", //elektromer rvo "temperature": "OK", //templomer - "battery": "OK", //Batéria + "battery": "OK", //Bateria "power_supply": "OK", //Zdroj "master_node": "OK", //MN - GLOBALS.settings.masterNodeIsResponding - "no_voltage": "OK", //GLOBALS.settings.no_voltage - výpadok napätia na fáze - "state_of_breaker": {}, //"Off",//Istič - "state_of_contactor": {}, //"Off",//Stykač + "no_voltage": "OK", //GLOBALS.settings.no_voltage - vypadok napatia na faze + "state_of_breaker": {}, //"Off",//Istic + "state_of_contactor": {}, //"Off",//Stykac "twilight_sensor": "OK" //lux sensor }; + let deviceStatus = FLOW.deviceStatus; function main() { @@ -159,10 +150,12 @@ exports.install = function(instance) { pinsData = GLOBALS.pinsData; relaysData = GLOBALS.relaysData; - tbHandler = new DataToTbHandler(SEND_TO.tb) + tbHandler = new DataToTbHandler(SEND_TO.tb); tbHandler.setSender(exports.title); - controller_type = SETTINGS.controller_type //"lm" or "unipi" //logicMachine + controller_type = SETTINGS.controller_type; //"lm" or "unipi" + hasMainSwitch = SETTINGS.has_main_switch; + if (controller_type == "") controller_type = "lm"; console.log(exports.title, "controller type: ", controller_type); @@ -201,10 +194,6 @@ exports.install = function(instance) { if (pinsData[key].type == "state_of_contactor") { let pin = key - 1; if (controller_type === "unipi") pin = key; - - //this will modify database - let forceTurnOff = true; - turnLine("off", line, pin, forceTurnOff, "turn off on startup"); } } @@ -215,29 +204,25 @@ exports.install = function(instance) { sendTelemetry(values, rvoTbName); - let time = 5 * 1000; - setTimeout(function() { - instance.send(SEND_TO.cmd_manager, { sender: "dido_controller", cmd: "buildTasks" }); + instance.send(SEND_TO.cmd_manager, { sender: "dido_controller", cmd: "buildTasks" }); - sendNotification("rsPort.open()", rvoTbName, "flow_start", {}, "", SEND_TO.tb, instance); - monitor.info("-->FLOW bol spustený", rvoTbName, SETTINGS.edge_fw_version); - }, time); + sendNotification("rsPort.open()", rvoTbName, "flow_start", {}, "", SEND_TO.tb, instance); + monitor.info("-->FLOW bol spustený", rvoTbName, SETTINGS.edge_fw_version); } function handleRsPort() { + + if (rsPort) { + rsPort.removeAllListeners(); + rsPort = null; + } + //TODO build according to pins!!! //! rsPort to open are the same for lm and unipi and electromer ("/dev/ttymxc0") const setRSPortData = [0xAA, 6, 6, 6, 6, 6, 6, 0, 6, 6, 6, 1, 1, 1, 1, 0, 0, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0]; rsPort = new SerialPort("/dev/ttymxc0", { autoOpen: false }); - rsPort.on('error', function(err) { - logger.debug("rsPort opened error - failed", err.message); - instance.send(SEND_TO.debug, err.message); - - errorHandler.sendMessageToService(exports.title + " rsPort opened error - failed: " + err.message); - }) - rsPort.on('open', async function() { await runSyncExec("stty -F /dev/ttymxc0 115200 min 1 time 5 ignbrk -brkint -icrnl -imaxbel -opost -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke").then(function(status) { @@ -298,8 +283,18 @@ exports.install = function(instance) { }); + rsPort.on('error', err => { + let message = "Dido: rsPort error: " + err.message; + logger.debug(message); + monitor.info(message); + errorHandler.sendMessageToService(message); + }) + rsPort.on("close", () => { - rsPort.close(); + let message = "Dido: rsPort closed - reconnecting ..."; + logger.debug(message); + monitor.info(message); + setTimeout(handleRsPort, 1000); }) rsPort.open(); @@ -308,6 +303,11 @@ exports.install = function(instance) { function handleWebSocket() { + if (ws) { + ws.removeAllListeners(); + ws = null; + } + //to keep websocket opened, we send request every 150 seconds let startRequests = null; @@ -319,16 +319,12 @@ exports.install = function(instance) { instance.send(0, exports.title + " running"); turnAlarm("off"); - // useTurnOffCounter = true; - // turnOffCounter = relaysData.length - 1; initialSetting(); - ws.send(JSON.stringify({ "cmd": "all" })); + setTimeout(function() { ws.send(JSON.stringify({ cmd: "all" })) }, 5000); // we request dev info about neuron device from evok to keep websocket connection alive // for some reason this request returns no data, but connection keeps alive - // https://evok.api-docs.io/1.0/mpqzDwPwirsoq7i5A/websocket startRequests = setInterval(() => { - // console.log(" *** data from evok requested"); ws.send(JSON.stringify({ "cmd": "filter", "dev": ["neuron"] })); }, 150000) }; @@ -375,23 +371,13 @@ exports.install = function(instance) { }) } - - ws.on('error', (err) => { - monitor.info('websocket error, reconnect') - instance.send(SEND_TO.debug, err.message); - clearInterval(startRequests); - ws = null; - setTimeout(handleWebSocket, 1000); + ws.on('error', err => { + logger.debug('Dido: websocket error', err); }) - ws.onclose = function() { - // connection closed, discard old websocket and create a new one in 5s - // stopRequests(); - monitor.info('websocket onclose, reconnect') + logger.debug('Dido: websocket onclose, reconnecting...') clearInterval(startRequests); - ws = null; - console.log("ws is null now, reconnecting..."); setTimeout(handleWebSocket, 1000); } } @@ -401,7 +387,6 @@ exports.install = function(instance) { if (ws) ws.close(); }) - function getPin(line) { //conversionTable let keys = Object.keys(pinsData); @@ -502,14 +487,14 @@ exports.install = function(instance) { if (!force) { if (relaysData[line].contactor == value) { instance.send(SEND_TO.debug, `line is already ${onOrOff} ` + line); - logger.debug(`turnLine: line is already ${onOrOff} `, line); + logger.debug(`Dido: turnLine: line is already ${onOrOff} `, line); return; } } // if(!rsPort.isOpen && !ws) if (!rsPort && !ws) { - errLogger.error("dido controller - port or websocket is not opened"); + errLogger.error("Dido - port or websocket is not opened"); return; } @@ -521,21 +506,20 @@ exports.install = function(instance) { rsPort.write(Buffer.from(arr), function(err) { if (err === undefined) { - monitor.info(`turnLine ${onOrOff} zapisal do rsPort-u`, line, pin, arr, info); + monitor.info(`Dido: turnLine ${onOrOff} zapisal do rsPort-u`, line, pin, arr, info); switchLogic(arr); } else { - monitor.info(`turnLine ${onOrOff} WRITE error`, err); + monitor.info(`Dido: turnLine ${onOrOff} WRITE error`, err); } }); } else if (ws) { //pin = "relay1_03" or "input1_01" ... we must make just "1_01" with slice method - monitor.info(`turnLine ${onOrOff} - (line, pin, force)`, line, pin, force, info); + monitor.info(`Dido: turnLine ${onOrOff} - (line, pin, force)`, line, pin, force, info); let cmd = { "cmd": "set", "dev": "relay", "circuit": pin.slice(5), "value": value }; ws.send(JSON.stringify(cmd)); - switchLogic(pin, value) } //if rvo is 24/7, it has just one switching profile point at 13:00. we do not want to send notification as it repeats every day. @@ -593,10 +577,12 @@ exports.install = function(instance) { }) + + // we expect array as flowdata.data instance.on("1", flowdata => { - console.log(flowdata.data); + //console.log(flowdata.data); if (!flowdata.data instanceof Object) return; @@ -609,17 +595,6 @@ exports.install = function(instance) { else if (obj.command == "off") turnLine("off", line, undefined, force, info); else if (obj.command == "turnOnAlarm") turnAlarm("on"); else if (obj.command == "turnOffAlarm") turnAlarm("off"); - - //! ake data prichadzaju z cmd_manager.js ??? - //TODO transform to websocket - if (Array.isArray(obj)) { - - rsPort.write(Buffer.from(obj), function(err) { - switchLogic(obj); - - instance.send(SEND_TO.debug, { "WRITE": obj }); - }); - } }) @@ -627,27 +602,27 @@ exports.install = function(instance) { let bits = []; - //Hlavný istič - state_of_main_switch => v rvo senica je to druhy door pre silovu cast (EM) - if (deviceStatus["state_of_main_switch"] == "closed") { + //Hlavny istic - state_of_main_switch => v rvo senica je to druhy door pre silovu cast (EM) + if (deviceStatus["state_of_main_switch"] === "closed" || deviceStatus["state_of_main_switch"] === "Off") { bits.push(0); } else { bits.push(1); } - //Prevádzkový mód - Manual, Off, Automatic, maintenance_mode = true/false // DAVA 2 BITY + //Prevadzkovy mod - Manual, Off, Automatic, maintenance_mode = true/false // DAVA 2 BITY if (!SETTINGS.maintenance_mode) { - if (deviceStatus["rotary_switch_state"] == "Manual") { + if (deviceStatus["rotary_switch_state"] === "Manual") { bits.push(0); bits.push(1); } - if (deviceStatus["rotary_switch_state"] == "Automatic") { + if (deviceStatus["rotary_switch_state"] === "Automatic") { bits.push(0); bits.push(0); } - if (deviceStatus["rotary_switch_state"] == "Off") { + if (deviceStatus["rotary_switch_state"] === "Off") { bits.push(1); bits.push(0); } @@ -657,8 +632,8 @@ exports.install = function(instance) { bits.push(1); } - //Dverový kontakt - if (deviceStatus["door_condition"] == "closed") { + //Dverovy kontakt + if (deviceStatus["door_condition"] === "closed") { bits.push(0); } else { @@ -666,7 +641,7 @@ exports.install = function(instance) { } //EM - if (deviceStatus["em"] == "NOK") { + if (deviceStatus["em"] === "NOK") { bits.push(1); } else { @@ -674,7 +649,7 @@ exports.install = function(instance) { } //Teplomer - if (deviceStatus["temperature"] == "NOK") { + if (deviceStatus["temperature"] === "NOK") { bits.push(1); } else { @@ -682,7 +657,7 @@ exports.install = function(instance) { } //Batéria - if (deviceStatus["battery"] == "NOK") { + if (deviceStatus["battery"] === "NOK") { bits.push(1); } else { @@ -690,7 +665,7 @@ exports.install = function(instance) { } //Zdroj - if (deviceStatus["power_supply"] == "NOK") { + if (deviceStatus["power_supply"] === "NOK") { bits.push(1); } else { @@ -698,7 +673,7 @@ exports.install = function(instance) { } //MN - if (deviceStatus["master_node"] == "NOK") { + if (deviceStatus["master_node"] === "NOK") { bits.push(1); } else { @@ -706,14 +681,14 @@ exports.install = function(instance) { } //výpadok napätia na fáze - if (deviceStatus["no_voltage"] == "NOK") { + if (deviceStatus["no_voltage"] === "NOK") { bits.push(1); } else { bits.push(0); } - if (deviceStatus["twilight_sensor"] == "NOK") { + if (deviceStatus["twilight_sensor"] === "NOK") { bits.push(1); } else { @@ -769,6 +744,26 @@ exports.install = function(instance) { } + function pinsForRvoStatus(controllerType, hasMainSwitch) { + + let pins = []; + + if (controllerType === "lm") { + pins = [1, 4, 6]; + if (hasMainSwitch === 1) { + pins = [4, 6]; + } + } else if (controllerType === "unipi") { + pins = ["input1_01", "input1_04", "input1_05"]; + if (hasMainSwitch === 1) { + pins = ["input1_01", "input1_04"]; + } + } + + return pins; + } + + function checkRvoStatus() { // we check if any of these pins values are 0 --> it means status RVO is "NOK" @@ -777,12 +772,12 @@ exports.install = function(instance) { let status = "OK"; for (const [key, value] of Object.entries(deviceStatus)) { - if (["em", "twilight_sensor", "temperature", "master_node"].includes(key) && value == "NOK") status = "NOK"; + if (["em", "twilight_sensor", "temperature", "master_node"].includes(key) && value === "NOK") status = "NOK"; } - if (status == "OK") { - let pinIndexes = [1, 4, 6]; - if (controller_type == 'unipi') pinIndexes = ['input1_01', 'input1_04', 'input1_05']; + if (status === "OK") { + + let pinIndexes = pinsForRvoStatus(controller_type, hasMainSwitch); for (const pinIndex of pinIndexes) { if (previousValues[pinIndex] === 0) { @@ -838,28 +833,20 @@ exports.install = function(instance) { let value = "On"; if (newPinValue === 0) value = "Off"; - //Hlavný istič - //! po novom uz 'state of main switch' nemame. Namiesto neho je 'door_condition', kedze mame dvoje dveri - //! takze ked pride z evoku signal pre 'input1_05', handlujeme ho ako 'door_condition' - // if(type === "!!!state_of_main_switch") - // { - // if (newPinValue === 0 && newPinValue !== previousValues[pinIndex]) - // { - // sendNotification("switchLogic", rvoTbName, "main_switch_has_been_turned_off", {}, "", SEND_TO.tb, instance , "state_of_main_switch"); - // values["status"] = "NOK"; + //Hlavny istic + if (type === "state_of_main_switch" && hasMainSwitch) { + if (newPinValue === 0 && newPinValue !== previousValues[pinIndex]) { + sendNotification("switchLogic", rvoTbName, "main_switch_has_been_turned_off", {}, "", SEND_TO.tb, instance, "state_of_main_switch"); + deviceStatus["state_of_main_switch"] = "Off"; + } + else if (newPinValue === 1 && newPinValue !== previousValues[pinIndex]) { + sendNotification("switchLogic", rvoTbName, "main_switch_has_been_turned_on", {}, "", SEND_TO.tb, instance, "state_of_main_switch"); + deviceStatus["state_of_main_switch"] = "On"; + } + } - // deviceStatus["state_of_main_switch"] = "Off"; - // } - // else if (newPinValue === 1 && newPinValue !== previousValues[pinIndex]) - // { - // sendNotification("switchLogic", rvoTbName, "main_switch_has_been_turned_on", {}, "", SEND_TO.tb, instance , "state_of_main_switch"); - - // deviceStatus["state_of_main_switch"] = "On"; - // } - // } - - //Prevádzkový mód - if (type == "rotary_switch_state") { + //Prevadzkovy mod + else if (type == "rotary_switch_state") { // combination of these two pins required to get result let pin2, pin3; if (pinIndex == 2 || pinIndex == "input1_02") { @@ -911,7 +898,7 @@ exports.install = function(instance) { } } - //Batéria - pin 5 + //Bateria - pin 5 else if (type === "battery") { if (newPinValue === 1 && newPinValue !== previousValues[pinIndex]) { sendNotification("switchLogic", rvoTbName, "battery_level_is_low", {}, "", SEND_TO.tb, instance, "battery_level"); @@ -925,27 +912,30 @@ exports.install = function(instance) { } } - //Dverový kontakt - pin 6 - //! Po novom mame dva dverove kontakty, nie jeden. Druhy je teraz tam, kde bol digital input "state_of_main_switch" - //! preto ked pride z evoku signal z input1_05, co bol predytm "main switch" handlujeme ho teraz ako 'door_condition' + //Dverovy kontakt - pin 6 + //! Ak je rvo s dvoma dverovymi kontaktami, ked pride z evoku signal z input1_05, co bol predytm "state_of_main switch" handlujeme ho teraz ako 'door_condition' else if (type == "door_condition" || type === "state_of_main_switch") { newPinValue === 0 ? value = "open" : value = "closed"; - if (value === "open" && SETTINGS.maintenance_mode) { - sendNotification("switchLogic", rvoTbName, "door_opened", {}, "", SEND_TO.tb, instance, "rvo_door"); + let door = "door_main"; + if (type === "state_of_main_switch") door = "door_em"; + + if (value === "open") { + if (SETTINGS.maintenance_mode) { + sendNotification("switchLogic", rvoTbName, door + "_open", {}, "", SEND_TO.tb, instance, door); + } else { + sendNotification("switchLogic", rvoTbName, door + "_open_without_permission", {}, "", SEND_TO.tb, instance, door); + + // zapneme sirenu + // ak sa otvoria dvere len na elektromeri (type === "state_of_main_switch") alarm sa nema spustit. alarm sa spusti len ked sa otvoria hlavne dvere (type === "door_condition") + if (type === "door_condition") turnAlarm("on"); + } } - if (value === "open" && !SETTINGS.maintenance_mode) { - sendNotification("switchLogic", rvoTbName, "door_opened_without_permission", {}, "", SEND_TO.tb, instance, "rvo_door"); - - // zapneme sirenu - // ak sa otvoria dvere len na elektromeri (type === "state_of_main_switch") alarm sa nema spustit. alarm sa spusti len ked sa otvoria hlavne dvere (type === "door_condition") - if (type === "door_condition") turnAlarm("on"); - } if (value === "closed") { if (alarmStatus == "ON") turnAlarm("off"); - sendNotification("switchLogic", rvoTbName, "door_closed", {}, "", SEND_TO.tb, instance, "rvo_door"); + sendNotification("switchLogic", rvoTbName, door + "_close", {}, "", SEND_TO.tb, instance, door); } deviceStatus[type] = value; @@ -1028,34 +1018,6 @@ exports.install = function(instance) { instance.send(SEND_TO.cmd_manager, { sender: "dido_controller", cmd: "reload_relays", line: line, value: value, dataChanged: dataChanged }); reportLineStatus(line); - - //modify table relays - // dbRelays.modify({ contactor: newPinValue }).where("line", line).make(function(builder) { - // builder.callback(function(err, response) { - // if(!err) - // { - // let time = 0; - // if(value) time = 1000 * 10;//10 sekund - - // let dataChanged = false; - // if(relaysData[line].contactor != newPinValue) dataChanged = true; - // relaysData[line].contactor = newPinValue; // 0,1 - - // //ak bola predchadzajuci stav off a novy stav je on, budu sa nastavovat nespracovane node profiles - // //a budu sa odosielat commandy, tie vsak mozu zlyhat, a preto potrebujeme ich spusti trochu neskor - // setTimeout(function(){ - // instance.send(SEND_TO.cmd_manager, {sender: "dido_controller", cmd: "reload_relays", line: line, time: time, value: value, dataChanged: dataChanged}); - // }, time); - - // reportLineStatus(line); - // } - // else - // { - // errLogger.error("modify table relays failed", err); - // } - - // }); - // }); } else if (type === "state_of_breaker") { diff --git a/flow/helper/DataToTbHandler.js b/flow/helper/DataToTbHandler.js index 65e4ec3..716ef7b 100644 --- a/flow/helper/DataToTbHandler.js +++ b/flow/helper/DataToTbHandler.js @@ -4,15 +4,14 @@ class DataToTbHandler { this.index = index; // time, after new value for the given key will be resend to tb (e.g. {status: "OK"}) - this.timeToHoldTbValue = 30*60; //30 minutes - + this.timeToHoldTbValue = 30 * 60; //30 minutes this.previousValues = {}; this.debug = false; this.messageCounter = 0; - + this.itIsNodeReadout = false; this.sender = ""; - - // if attribute difference is less than limit value, we do not send to tb. + + // if attribute change difference is less than limit value, we do not send to tb. this.attributeChangeLimit = { temperature: 0.5, Phase_1_voltage: 2, @@ -25,11 +24,12 @@ class DataToTbHandler { Phase_2_power: 2, Phase_3_power: 2, total_power: 2, + total_energy: 1, Phase_1_pow_factor: 0.1, Phase_2_pow_factor: 0.1, Phase_3_pow_factor: 0.1, power_factor: 0.1, - lifetime: 0.5, + lifetime: 2, voltage: 2, power: 2, frequency: 3, @@ -39,6 +39,7 @@ class DataToTbHandler { inclination_y: 10, inclination_z: 10 }; + } dump() { @@ -52,41 +53,43 @@ class DataToTbHandler { } isEmptyObject(obj) { - for (var name in obj) { + for (var _ in obj) { return false; } return true; } - sendToTb(dataToTb, instance) { - let keys = Object.keys(dataToTb); + sendToTb(data, instance) { - if(keys.length == 0) - { - if(this.debug) console.log("sendToTb received empty object", dataToTb); + //not to modify data object, we do deep copy: + let dataCopy = JSON.parse(JSON.stringify(data)); + + let keys = Object.keys(dataCopy); + + if (keys.length == 0) { + if (this.debug) console.log("sendToTb received empty object", dataCopy); return; } let tbname = keys[0]; let ts; - let arrayOfValues = dataToTb[tbname]; + let arrayOfValues = dataCopy[tbname]; let arrayOfValuesToSend = []; - for(let i = 0; i < arrayOfValues.length; i++) - { + for (let i = 0; i < arrayOfValues.length; i++) { + ts = arrayOfValues[i].ts; let values = this.prepareValuesForTb(tbname, ts, arrayOfValues[i].values); - if(!this.isEmptyObject(values)) - { - arrayOfValuesToSend.push({ts: ts, values: values}); + if (!this.isEmptyObject(values)) { + arrayOfValuesToSend.push({ ts: ts, values: values }); } + } - if(arrayOfValuesToSend.length == 0) - { + if (arrayOfValuesToSend.length == 0) { //if(this.debug) console.log("data not sent - empty array"); return; } @@ -94,7 +97,7 @@ class DataToTbHandler { this.messageCounter++; let dataToTbModified = { - [tbname]: arrayOfValuesToSend + [tbname]: arrayOfValuesToSend } //console.log(this.sender + " DATA SEND TO TB ", tbname, this.messageCounter, new Date(ts), dataToTbModified[tbname][0].values, this.instance); @@ -102,56 +105,74 @@ class DataToTbHandler { instance.send(this.index, dataToTbModified); } + getDiffTimestamp(key) { //TODO set different value for given key!!! //if(key == "status") this.timeToHoldTbValue = 2*60*60;//2h return this.timeToHoldTbValue * 1000; } + prepareValuesForTb(tbname, timestamp, values) { let keys = Object.keys(values); - if(!this.previousValues.hasOwnProperty(tbname)) - { + + if (keys.includes("lifetime")) this.itIsNodeReadout = true; + + if (!this.previousValues.hasOwnProperty(tbname)) { this.previousValues[tbname] = {}; } //if(this.debug) console.log("prepareValuesForTb", tbname, timestamp, values); - for(let i = 0; i < keys.length; i++) - { + for (let i = 0; i < keys.length; i++) { + let key = keys[i]; let value = values[key]; - if(!this.previousValues[tbname].hasOwnProperty(key)) - { - this.previousValues[tbname][key] = {ts: timestamp, value: value}; + if (!this.previousValues[tbname].hasOwnProperty(key)) { + this.previousValues[tbname][key] = { ts: timestamp, value: value }; continue; } - // attributeData ==> voltage: {ts:333333, value:5} + // attributeData ==> {voltage: {ts:333333, value:5}} let attributeData = this.previousValues[tbname][key]; let attributeToChange = false; - if(key in this.attributeChangeLimit) attributeToChange = true; + if (key in this.attributeChangeLimit) attributeToChange = true; let limit = this.attributeChangeLimit[key]; - - if(attributeData.value === value || attributeToChange && Math.abs(attributeData.value - value) < limit) - { + let timestampDiffToRemoveKey; + + //this will ensure "node statecode" will be sent just once an hour + if (this.itIsNodeReadout && key === "statecode") { + attributeData.value = value; + this.itIsNodeReadout = false; + timestampDiffToRemoveKey = 1 * 60 * 60 * 1000; // 1 hour + } + + if (key === "twilight_sensor" && value > 100) { + attributeData.value = value; + } + + //if edge, master or node version do not change, send just once a day: + if (["edge_fw_version", "master_node_version", "fw_version"].includes(key)) { + timestampDiffToRemoveKey = 24 * 60 * 60 * 1000; + } + + if (attributeData.value === value || attributeToChange && Math.abs(attributeData.value - value) < limit) { + let diff = timestamp - attributeData.ts; - let timestampDiffToRemoveKey = this.getDiffTimestamp(key); - if(diff > timestampDiffToRemoveKey) - { + if (!timestampDiffToRemoveKey) timestampDiffToRemoveKey = this.getDiffTimestamp(key); + + if (diff > timestampDiffToRemoveKey) { attributeData.ts = Date.now(); //if(this.debug) console.log(this.sender + ": update ts for key", key, "diff is", diff, "messageCounter", this.messageCounter); } - else - { + else { delete values[key]; //if(this.debug) console.log(this.sender + ": delete key", key, "diff is", diff, "messageCounter", this.messageCounter, timestampDiffToRemoveKey); } } - else - { + else { attributeData.value = value; attributeData.ts = timestamp; } @@ -162,5 +183,5 @@ class DataToTbHandler { } } -module.exports = DataToTbHandler; +module.exports = DataToTbHandler; diff --git a/flow/helper/ErrorToServiceHandler.js b/flow/helper/ErrorToServiceHandler.js index 110ea8b..2b27c32 100644 --- a/flow/helper/ErrorToServiceHandler.js +++ b/flow/helper/ErrorToServiceHandler.js @@ -1,126 +1,91 @@ const { MD5 } = require('./md5.js'); const { networkInterfaces } = require('os'); -class ErrorToServiceHandler -{ - constructor() { +class ErrorToServiceHandler { + constructor() { this.previousValues = {}; - this.projects_id = undefined; + this.project_id = undefined; const nets = networkInterfaces(); - this.ipAddresses = Object.create(null); // Or just '{}', an empty object + this.ipAddresses = {}; for (const name of Object.keys(nets)) { for (const net of nets[name]) { // Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses if (net.family === 'IPv4' && !net.internal) { if (!this.ipAddresses[name]) { - this.ipAddresses[name] = []; + this.ipAddresses[name] = []; } this.ipAddresses[name].push(net.address); } } } - - //console.log(this.ipAddresses); - } - setProjectsId(projects_id) - { - this.projects_id = projects_id; + setProjectId(project_id) { + this.project_id = project_id; } - processMessage(message, seconds, message_type) - { - if(message_type == undefined) message_type = "error_message"; - if(Array.isArray(message)) message = message.join(', '); - - let key = MD5(message); - let timestamp = new Date().getTime(); - - //keep in memory - default value is 1h - if (seconds === undefined) seconds = 60*60; - - if(!this.previousValues.hasOwnProperty(key)) - { - this.previousValues[key] = {ts: timestamp, duration: seconds}; - } - - let diff = (timestamp - this.previousValues[key].ts); - if(diff < this.previousValues[key].duration*1000) return false; - - this.previousValues[key].ts = timestamp; - - return true; - } - - sendMessageToService(message, seconds, message_type) - { - - let f = this.processMessage(message, seconds, message_type); - if(!f) return; - - /* - //------------- - if(message_type == undefined) message_type = "error_message"; - if(Array.isArray(message)) message = message.join(', '); + processMessage(message, seconds) { + if (Array.isArray(message)) message = message.join(', '); let key = MD5(message); - let timestamp = new Date().getTime(); + let ts = Date.now(); - //keep in memory - if (seconds === undefined) seconds = 60*60; + //keep in memory - default value is 1h + if (seconds === undefined) seconds = 60 * 60; - if(!this.previousValues.hasOwnProperty(key)) - { - this.previousValues[key] = {ts: timestamp, duration: seconds}; + if (!this.previousValues.hasOwnProperty(key)) { + this.previousValues[key] = { ts: ts, duration: seconds }; } - let diff = (timestamp - this.previousValues[key].ts); - if(diff < this.previousValues[key].duration*1000) return; + let diff = (ts - this.previousValues[key].ts); + if (diff < this.previousValues[key].duration * 1000) return false; - this.previousValues[key].ts = timestamp; - */ + this.previousValues[key].ts = ts; - //------------------------- + return message; + } - //send to service - - let dataToInfoSender = {id: this.projects_id}; + sendMessageToService(message, seconds, message_type) { + + // if error occures too early FLOW.GLOBALS.settings.project_id is still undefined + if (this.project_id === undefined) { + console.log("ErrorToServiceHandler.js: no project_id"); + return; + } + + let f = this.processMessage(message, seconds); + if (f === false) return; + + if (message_type === undefined) message_type = "error_message"; + + let toService = { + id: this.project_id, + ipAddresses: this.ipAddresses + }; //js_error || error_message - dataToInfoSender[message_type] = message; - dataToInfoSender.ipAddresses = this.ipAddresses; + toService[message_type] = message; - console.log("ErrorToServiceHandler------------------------>send to service", dataToInfoSender); - - //TODO UGLY!!! - // if error occures too early FLOW.GLOBALs.settings.project_id is still undefined - // if(this.projects_id === undefined) this.projects_id = FLOW.GLOBALS.settings.project_id; - if(this.projects_id === undefined) return; - - /* - if(this.projects_id === undefined) - { - console.log("this.projects_id is undefined"); - return; - } - */ + console.log("ErrorToServiceHandler------------------------>send to service", toService); RESTBuilder.make(function(builder) { - builder.method('POST'); - builder.post(dataToInfoSender); - builder.url('http://192.168.252.2:8004/sentmessage'); - - builder.callback(function(err, response, output) { - console.log("process.on error send", err, response, output, dataToInfoSender); - }); + builder.method('POST'); + builder.post(toService); + builder.url('http://192.168.252.2:8004/sentmessage'); + + builder.callback(function(err, response, output) { + console.log("process.on error send", err, response, output, toService); + }); }); - } } -module.exports = ErrorToServiceHandler; \ No newline at end of file +const errorHandler = new ErrorToServiceHandler(); + + +module.exports = errorHandler; +//module.exports = ErrorToServiceHandler; diff --git a/flow/helper/notification_reporter.js b/flow/helper/notification_reporter.js index 61c0aef..839c12c 100644 --- a/flow/helper/notification_reporter.js +++ b/flow/helper/notification_reporter.js @@ -1,6 +1,9 @@ -//key is device, value = str -let sentValues= {}; +//key is device, value = message {} +let sentValues = {}; let notificationsData = null; +let rvoName; + +//sendNotification("CMD Manager: process cmd", SETTINGS.rvoTbName, "dimming_profile_was_successfully_received_by_node", { node: node }, "", SEND_TO.tb, instance); let ERRWEIGHT = { EMERGENCY: "emergency", // System unusable @@ -23,82 +26,67 @@ var template = (tpl, args) => tpl.replace(/\${(\w+)}/g, (_, v) => args[v]); function initNotification() { notificationsData = FLOW.GLOBALS.notificationsData; + rvoName = FLOW.GLOBALS.settings.rvo_name; } + function sendNotification(func, device, key, params, extra, tb_output, instance, saveKey) { - // return; - let storeToSendValues = true; - if(saveKey == undefined) storeToSendValues = false; + if (saveKey == undefined) storeToSendValues = false; - let lang = FLOW.GLOBALS.settings.language; - if(lang != "en" || lang != "sk") lang = "en"; - - let tpl = key; let weight = ""; + let message = {}; - if(notificationsData[key]) - { - weight = notificationsData[key].weight; - weight = weight.toLowerCase(); + let notification = notificationsData[key]; - tpl = notificationsData[key][lang]; - tpl = template(tpl, params); + if (notification) { + weight = notification.weight.toLowerCase(); + + Object.keys(notification).forEach(item => { + if (["en", "sk", "de", "cz", "it", "es"].includes(item)) { + message[item] = rvoName + ": " + template(notification[item], params); + } + }) } - else - { + else { //console.error("sendNotification: Notifications: undefined key", key, func, notificationsData); - console.error("sendNotification: Notifications: undefined key", key, func ); + console.error("sendNotification: Notifications: undefined key", key, func); return false; } //detect invalid err weight - if(getKey(ERRWEIGHT, weight) == undefined) - { + if (getKey(ERRWEIGHT, weight) == undefined) { console.error("sendNotification: Notifications: undefined weight", weight, key, func); return false; } - if(sentValues.hasOwnProperty(saveKey)) - { - if(sentValues[saveKey] == tpl) - { + if (sentValues.hasOwnProperty(saveKey)) { + if (JSON.stringify(sentValues[saveKey]) == JSON.stringify(message)) { return false; } } - if(sentValues[saveKey] == undefined) - { - if(storeToSendValues) - { + if (sentValues[saveKey] == undefined) { + if (storeToSendValues) { //do not send - flow is was started - sentValues[saveKey] = tpl; + sentValues[saveKey] = message; return false; } } - if(saveKey == "rvo_door") - { - //console.log("******", saveKey, sentValues[saveKey], tpl); - } - - if(storeToSendValues) sentValues[saveKey] = tpl; - - let str = FLOW.GLOBALS.settings.rvo_name; - if(str != "") str = str + ": "; - str = str + tpl; + if (storeToSendValues) sentValues[saveKey] = message; let content = { "type": weight, "status": "new", "source": { - "func":func, - "component":instance.id, - "component_name":instance.name, - "edge":device + "func": func, + "component": instance.id, + "component_name": instance.name, + "edge": device }, - "message":str, + "message": message, "message_data": extra }; @@ -107,7 +95,7 @@ function sendNotification(func, device, key, params, extra, tb_output, instance, { "ts": Date.now(), "values": { - "_event":content + "_event": content } } ]; @@ -118,6 +106,7 @@ function sendNotification(func, device, key, params, extra, tb_output, instance, } else { bufferError(msg); }*/ + instance.send(tb_output, msg); // Even if error server is unavailable, send this message to output, for other possible component connections return true; @@ -129,3 +118,4 @@ module.exports = { ERRWEIGHT, initNotification } + diff --git a/flow/helper/serialport_helper.js b/flow/helper/serialport_helper.js index 4a0edd5..7f5920d 100644 --- a/flow/helper/serialport_helper.js +++ b/flow/helper/serialport_helper.js @@ -1,6 +1,6 @@ const { exec } = require('child_process'); -function openPort(port){ +function openPort(port) { return new Promise((resolve, reject) => { var callbackError = function(err) { @@ -25,24 +25,24 @@ function openPort(port){ }) } -function runSyncExec(command){ +function runSyncExec(command) { return new Promise((resolve, reject) => { exec(command, (error, stdout, stderr) => { - if(error == null) resolve(stdout); + if (error == null) resolve(stdout); reject(error); }); }) } -async function writeData(port, data, readbytes, timeout){ +async function writeData(port, data, readbytes, timeout) { return new Promise((resolve, reject) => { // If first item in data array is 255, we just write broadcast command to rsPort // We wait 3 seconds and resolve(["broadcast"]) // It is important to resolve with array - if(data[0] == 255) { + if (data[0] == 255) { port.write(Buffer.from(data), function(err) { if (err) { @@ -55,13 +55,12 @@ async function writeData(port, data, readbytes, timeout){ } //cmd-manager mame http route POST / terminal a tomu sa tiez nastavuje timeout!!! - + var callback = function(data) { rsPortReceivedData.push(...data); let l = rsPortReceivedData.length; - if(l >= readbytes) - { + if (l >= readbytes) { port.removeListener('data', callback); clearTimeout(t); @@ -74,7 +73,7 @@ async function writeData(port, data, readbytes, timeout){ let t = setTimeout(() => { port.removeListener('data', callback); - console.log("serialport helper: writeData TIMEOUT READING", rsPortReceivedData); + //console.log("serialport helper: writeData TIMEOUT READING", rsPortReceivedData); reject("TIMEOUT READING"); }, timeout); diff --git a/flow/helper/utils.js b/flow/helper/utils.js index a16210c..9c054aa 100644 --- a/flow/helper/utils.js +++ b/flow/helper/utils.js @@ -1,124 +1,112 @@ -function bytesToInt(bytes, numberOfBytes) -{ - let buffer = []; - if(Array.isArray(bytes)) - { - buffer = bytes.slice(0); - if(numberOfBytes != undefined) - { - buffer = bytes.slice(bytes.length - numberOfBytes); - } - } - else buffer.push(bytes); - - //var decimal = (buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3]; - let l = (buffer.length - 1) * 8; - - let decimal = 0; - for(let i = 0; i < buffer.length; i++) - { - var s = buffer[i] << l; - if(l < 8) s = buffer[i] - decimal = decimal + s; - - l = l - 8; - - } - - return decimal; -} - -function resizeArray(arr, newSize, defaultValue) { - while(newSize > arr.length) - arr.push(defaultValue); - arr.length = newSize; -} - -longToByteArray = function(/*long*/long) { - // we want to represent the input as a 8-bytes array - var byteArray = [0, 0, 0, 0, 0, 0, 0, 0]; - - for ( var index = 0; index < byteArray.length; index ++ ) { - var byte = long & 0xff; - byteArray [ index ] = byte; - long = (long - byte) / 256 ; - } - - return byteArray; - }; - -function addDays(date, days) { - var result = new Date(date); - result.setDate(result.getDate() + days); - return result; -} - -/* -sleep(2000).then(() => { - // Do something after the sleep! - - -}); -*/ - -function sleep (time) { - return new Promise((resolve) => setTimeout(resolve, time)); -} - -function isEmptyObject( obj ) { - for ( var name in obj ) { - return false; - } - return true; -} - -function convertUTCDateToLocalDate(date) { - var newDate = new Date(date); - newDate.setMinutes(date.getMinutes() + date.getTimezoneOffset()); - return newDate; -} - -function addZeroBefore(n) { - return (n < 10 ? '0' : '') + n; -} - -var convertBase = function () { - - function convertBase(baseFrom, baseTo) { - return function (num) { - return parseInt(num, baseFrom).toString(baseTo); - - }; - } - - // binary to decimal - convertBase.bin2dec = convertBase(2, 10); - - // binary to hexadecimal - convertBase.bin2hex = convertBase(2, 16); - - // decimal to binary - convertBase.dec2bin = convertBase(10, 2); - - // decimal to hexadecimal - convertBase.dec2hex = convertBase(10, 16); - - // hexadecimal to binary - convertBase.hex2bin = convertBase(16, 2); - - // hexadecimal to decimal - convertBase.hex2dec = convertBase(16, 10); - - return convertBase; - }(); - -module.exports = { - bytesToInt, - longToByteArray, - addDays, - addZeroBefore, - resizeArray, - isEmptyObject, - sleep, - convertUTCDateToLocalDate -} \ No newline at end of file +function bytesToInt(bytes, numberOfBytes) { + let buffer = []; + if (Array.isArray(bytes)) { + buffer = bytes.slice(0); + if (numberOfBytes != undefined) { + buffer = bytes.slice(bytes.length - numberOfBytes); + } + } + else buffer.push(bytes); + + let result = 0; + for (let i = 0; i < buffer.length; i++) { + result = (result << 8) | buffer[i]; + } + + return result >>> 0; //ensure it's an unsigned 32-bit number +} + +function resizeArray(arr, newSize, defaultValue) { + while (newSize > arr.length) + arr.push(defaultValue); + arr.length = newSize; +} + +longToByteArray = function(/*long*/long) { + // we want to represent the input as a 8-bytes array + var byteArray = [0, 0, 0, 0, 0, 0, 0, 0]; + + for (var index = 0; index < byteArray.length; index++) { + var byte = long & 0xff; + byteArray[index] = byte; + long = (long - byte) / 256; + } + + return byteArray; +}; + +function addDays(date, days) { + var result = new Date(date); + result.setDate(result.getDate() + days); + return result; +} + +/* +sleep(2000).then(() => { + // Do something after the sleep! + + +}); +*/ + +function sleep(time) { + return new Promise((resolve) => setTimeout(resolve, time)); +} + +function isEmptyObject(obj) { + for (var name in obj) { + return false; + } + return true; +} + +function convertUTCDateToLocalDate(date) { + var newDate = new Date(date); + newDate.setMinutes(date.getMinutes() + date.getTimezoneOffset()); + return newDate; +} + +function addZeroBefore(n) { + return (n < 10 ? '0' : '') + n; +} + +var convertBase = function() { + + function convertBase(baseFrom, baseTo) { + return function(num) { + return parseInt(num, baseFrom).toString(baseTo); + + }; + } + + // binary to decimal + convertBase.bin2dec = convertBase(2, 10); + + // binary to hexadecimal + convertBase.bin2hex = convertBase(2, 16); + + // decimal to binary + convertBase.dec2bin = convertBase(10, 2); + + // decimal to hexadecimal + convertBase.dec2hex = convertBase(10, 16); + + // hexadecimal to binary + convertBase.hex2bin = convertBase(16, 2); + + // hexadecimal to decimal + convertBase.hex2dec = convertBase(16, 10); + + return convertBase; +}(); + +module.exports = { + bytesToInt, + longToByteArray, + addDays, + addZeroBefore, + resizeArray, + isEmptyObject, + sleep, + convertUTCDateToLocalDate +} diff --git a/flow/infosender.js b/flow/infosender.js index c7afd83..587724f 100644 --- a/flow/infosender.js +++ b/flow/infosender.js @@ -33,69 +33,49 @@ exports.install = function(instance) { let ipAddresses = Object.create(null); // Or just '{}', an empty object for (const name of Object.keys(nets)) { - for (const net of nets[name]) { - // Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses - if (net.family === 'IPv4' && !net.internal) { - if (!ipAddresses[name]) { - ipAddresses[name] = []; - } - ipAddresses[name].push(net.address); - } + for (const net of nets[name]) { + // Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses + if (net.family === 'IPv4' && !net.internal) { + if (!ipAddresses[name]) { + ipAddresses[name] = []; + } + ipAddresses[name].push(net.address); } - } - - function sendValues() - { - if(!configured) return; - - if(Object.keys(allValues).length > 0) - { - if(id) - { - delete allValues.__force__; - let dataToSend = {...allValues}; - dataToSend.id = id; - dataToSend.ipAddresses = ipAddresses; - - instance.send(0, dataToSend); - - allValues = {}; - } - else - { - console.log(exports.title, "unable to send data, no id"); - } - } } - + + function sendValues() { + if (!configured) return; + + if (Object.keys(allValues).length > 0) { + let dataToSend = { ...allValues }; + dataToSend.id = id; + dataToSend.ipAddresses = ipAddresses; + + instance.send(0, dataToSend); + + allValues = {}; + } + } + instance.on("close", () => { clearInterval(sendAllValuesInterval); }) instance.on("0", _ => { id = FLOW.GLOBALS.settings.project_id; - configured = true; + if (id) configured = true; + else console.log(exports.title, "InfoSender: Unable to send data, no id"); }) instance.on("1", flowdata => { - - allValues = { ...allValues, ...flowdata.data}; + allValues = { ...allValues, ...flowdata.data }; //console.log("DATA RECEIVED", flowdata.data); - - //__force__ - if(flowdata.data.hasOwnProperty("__force__")) - { - if(flowdata.data.__force__) - { - sendValues(); - } - } }) sendAllValuesInterval = setInterval(() => { sendValues(); - }, 60000*3); - + }, 60000 * 3); + } diff --git a/flow/modbus_reader.js b/flow/modbus_reader.js index b907148..d6d9dad 100644 --- a/flow/modbus_reader.js +++ b/flow/modbus_reader.js @@ -36,12 +36,13 @@ let mainSocket; let phases; //phases where voltage is 0 (set) let noVoltage; +let energyToSwitchLamps; exports.install = function(instance) { class SocketWithClients { - constructor () { + constructor() { this.stream = null; this.socket = null; this.clients = {}; @@ -55,7 +56,7 @@ exports.install = function(instance) { this.indexInDeviceConfig = 0; // first item in deviceConfig this.lengthOfActualDeviceStream = null; this.device = null; - + // lampSwitchNotification helper variables this.onNotificationSent = false; this.offNotificationSent = false; @@ -66,7 +67,7 @@ exports.install = function(instance) { buildPhases = () => { let a = []; - for (let i = 1; i<= phases; i++) { + for (let i = 1; i <= phases; i++) { a.push(`Phase_${i}_voltage`) } return a; @@ -76,30 +77,30 @@ exports.install = function(instance) { let obj = this; + if (this.socket) { + this.socket.removeAllListeners(); + this.socket = null; + } + this.socket = new SerialPort("/dev/ttymxc0", { baudRate: 9600, }) // we create a client for every deviceAddress ( = address) in list and push them into dictionary - for( let i = 0; i < deviceConfig.length; i++) - { + for (let i = 0; i < deviceConfig.length; i++) { this.clients[deviceConfig[i].deviceAddress] = new modbus.client.RTU(this.socket, deviceConfig[i].deviceAddress, 2000); // 2000 is timeout in register request, default is 5000, which is too long } this.socket.on('error', function(e) { - console.log('socket connection error', e); - if(e.code == 'ECONNREFUSED' || e.code == 'ECONNRESET') { - console.log(exports.title + ' Waiting 10 seconds before trying to connect again'); - setTimeout(obj.startSocket, 10000); - } + console.log('Modbus_reader: Socket connection error', e); //'ECONNREFUSED' or 'ECONNRESET' ?? }); this.socket.on('close', function() { - console.log('Socket connection closed ' + exports.title + ' Waiting 10 seconds before trying to connect again'); + console.log('Modbus_reader: Socket connection closed - Waiting 10 seconds before connecting again'); setTimeout(obj.startSocket, 10000); }); - this.socket.on('open', function () { + this.socket.on('open', function() { console.log("socket connected"); obj.getActualStreamAndDevice(); obj.timeoutInterval = timeoutInterval - DELAY_BETWEEN_DEVICES; // to make sure readout always runs in timeoutinterval we substract DELAY_BETWEEN_DEVICES @@ -112,11 +113,12 @@ exports.install = function(instance) { this.index = 0; this.errors = 0; this.stream = dev.stream; - this.lengthOfActualDeviceStream = dev.stream.length; + this.lengthOfActualDeviceStream = dev.stream.length; this.deviceAddress = dev.deviceAddress; // 1 or 2 or any number this.device = dev.device; //em340, twilight_sensor - if(this.indexInDeviceConfig == 0) setTimeout(this.readRegisters, this.timeoutInterval); + //if we just start to loop devices from the beginning, or there is just 1 device in config, we wait whole timeoutInterval + if (this.indexInDeviceConfig == 0 || deviceConfig.length === 1) setTimeout(this.readRegisters, this.timeoutInterval); else setTimeout(this.readRegisters, DELAY_BETWEEN_DEVICES); } @@ -130,21 +132,18 @@ exports.install = function(instance) { let obj = this; this.clients[this.deviceAddress].readHoldingRegisters(register, size) - .then( function (resp) { - + .then(function(resp) { + resp = resp.response._body.valuesAsArray; //resp is array of length 1 or 2, f.e. [2360,0] // console.log(deviceAddress, register, tbAttribute, resp); //device is responding again after NOK status - if(numberOfNotResponding.hasOwnProperty(obj.device)) - { + if (numberOfNotResponding.hasOwnProperty(obj.device)) { let message = ""; - if(obj.device == "em340") - { + if (obj.device == "em340") { message = "electrometer_ok"; } - else if(obj.device == "twilight_sensor") - { + else if (obj.device == "twilight_sensor") { message = "twilight_sensor_ok"; } message && sendNotification("modbus_reader: readRegisters", tbName, message, {}, "", SEND_TO.tb, instance); @@ -157,25 +156,21 @@ exports.install = function(instance) { obj.index++; obj.readAnotherRegister(); - }).catch (function () { + }).catch(function() { //console.log("errors pri citani modbus registra", register, obj.indexInDeviceConfig, tbName, tbAttribute); - + obj.errors++; - if(obj.errors == obj.lengthOfActualDeviceStream) - { - instance.send(SEND_TO.dido_controller, {status: "NOK-" + obj.device}); // NOK-em340, NOK-em111, NOK-twilight_sensor, NOK-thermometer - + if (obj.errors == obj.lengthOfActualDeviceStream) { + instance.send(SEND_TO.dido_controller, { status: "NOK-" + obj.device }); // NOK-em340, NOK-em111, NOK-twilight_sensor, NOK-thermometer + //todo - neposlalo notification, ked sme vypojili twilight a neposle to do tb, ale do dido ?? - if(!numberOfNotResponding.hasOwnProperty(obj.device)) - { + if (!numberOfNotResponding.hasOwnProperty(obj.device)) { let message = ""; - if(obj.device == "twilight_sensor") - { + if (obj.device == "twilight_sensor") { message = "twilight_sensor_nok"; } - else if(obj.device == "em340") - { + else if (obj.device == "em340") { message = "electrometer_nok"; } message && sendNotification("modbus_reader: readingTimeouted", tbName, message, {}, "", SEND_TO.tb, instance); @@ -183,7 +178,7 @@ exports.install = function(instance) { } obj.errors = 0; - numberOfNotResponding[obj.device] += 1; + numberOfNotResponding[obj.device] += 1; } // console.error(require('util').inspect(arguments, { @@ -191,9 +186,8 @@ exports.install = function(instance) { // })) // if reading out of device's last register returns error, we send accumulated allValues to dido_controller (if allValues are not an empty object) - if(obj.index + 1 >= obj.lengthOfActualDeviceStream) - { - if(!isObjectEmpty(obj.allValues)) instance.send(SEND_TO.dido_controller, {values: obj.allValues}); + if (obj.index + 1 >= obj.lengthOfActualDeviceStream) { + if (!isObjectEmpty(obj.allValues)) instance.send(SEND_TO.dido_controller, { values: obj.allValues }); obj.allValues = {}; } obj.index++; @@ -203,7 +197,7 @@ exports.install = function(instance) { }; readAnotherRegister = () => { - if(this.index < this.lengthOfActualDeviceStream) setTimeout(this.readRegisters, 0); + if (this.index < this.lengthOfActualDeviceStream) setTimeout(this.readRegisters, 0); else this.setNewStream(); } @@ -212,18 +206,16 @@ exports.install = function(instance) { for (let i = 0; i < this.lengthOfActualDeviceStream; i++) { let a = this.stream[i]; - if (a.register === register) - { + if (a.register === register) { let tbAttribute = a.tbAttribute; let multiplier = a.multiplier; - - let value = this.calculateValue(response, multiplier); + + let value = this.calculateValue(response, multiplier); // console.log(register, tbName, tbAttribute, response, a.multiplier, value); // if(tbName == undefined) return; - if(this.index + 1 < this.lengthOfActualDeviceStream) - { + if (this.index + 1 < this.lengthOfActualDeviceStream) { this.allValues[tbAttribute] = value; return; } @@ -236,52 +228,45 @@ exports.install = function(instance) { this.checkNullVoltage(values); this.lampSwitchNotification(values); - instance.send(SEND_TO.dido_controller, {values: values}); + instance.send(SEND_TO.dido_controller, { values: values }); this.allValues = {}; break; } - } + } } - setNewStream = () => - { - if(this.lengthOfActualDeviceStream == this.index) - { - if(this.indexInDeviceConfig + 1 == deviceConfig.length) - { + setNewStream = () => { + if (this.lengthOfActualDeviceStream == this.index) { + if (this.indexInDeviceConfig + 1 == deviceConfig.length) { this.indexInDeviceConfig = 0; - } - else - { + } + else { this.indexInDeviceConfig += 1; } this.getActualStreamAndDevice(); - } + } } - calculateValue = (response, multiplier) => - { + calculateValue = (response, multiplier) => { let value = 0; let l = response.length; - if (l === 2) - { - value = (response[1]*(2**16) + response[0]); + if (l === 2) { + value = (response[1] * (2 ** 16) + response[0]); - if(value >= (2**31)) // ak je MSB bit nastavený, eventuálne sa dá použiť aj (value & 0x80000000), ak vieš robiť logický súčin - { - value = value - "0xFFFFFFFF" + 1; - } + if (value >= (2 ** 31)) // ak je MSB bit nastavený, eventuálne sa dá použiť aj (value & 0x80000000), ak vieš robiť logický súčin + { + value = value - "0xFFFFFFFF" + 1; + } } - else if (l === 1) - { + else if (l === 1) { value = response[0]; - if(value >= (2**15)) // ak je MSB bit nastavený, eventuálne sa dá použiť aj (value & 0x8000), ak vieš robiť logický súčin + if (value >= (2 ** 15)) // ak je MSB bit nastavený, eventuálne sa dá použiť aj (value & 0x8000), ak vieš robiť logický súčin { - value = value - "0xFFFF" + 1; + value = value - "0xFFFF" + 1; } } @@ -290,59 +275,51 @@ exports.install = function(instance) { checkNullVoltage = (values) => { - if(!(values.hasOwnProperty("Phase_1_voltage") || values.hasOwnProperty("Phase_2_voltage") || values.hasOwnProperty("Phase_3_voltage"))) return; + if (!(values.hasOwnProperty("Phase_1_voltage") || values.hasOwnProperty("Phase_2_voltage") || values.hasOwnProperty("Phase_3_voltage"))) return; Object.keys(values).map(singleValue => { - if (this.phases.includes(singleValue)) - { + if (this.phases.includes(singleValue)) { let l = singleValue.split("_"); let phase = parseInt(l[1]); // console.log(values[singleValue], tbName); - if(values[singleValue] == 0) - { + if (values[singleValue] == 0) { noVoltage.add(phase); - sendNotification("modbus_reader: checkNullVoltage", tbName, "no_voltage_on_phase", {phase: phase}, "", SEND_TO.tb, instance, "voltage" + phase ); + sendNotification("modbus_reader: checkNullVoltage", tbName, "no_voltage_on_phase", { phase: phase }, "", SEND_TO.tb, instance, "voltage" + phase); // console.log('no voltage') } - else - { + else { noVoltage.delete(phase); // console.log('voltage detected') - sendNotification("modbus_reader: checkNullVoltage", tbName, "voltage_on_phase_restored", {phase: phase}, "", SEND_TO.tb, instance, "voltage" + phase); + sendNotification("modbus_reader: checkNullVoltage", tbName, "voltage_on_phase_restored", { phase: phase }, "", SEND_TO.tb, instance, "voltage" + phase); } - } + } }) } /** * function sends notification to slack and to tb, if EM total_power value changes more than numberOfNodes*15. This should show, that RVO lamps has been switched on or off - */ + */ lampSwitchNotification = (values) => { - if(!values.hasOwnProperty("total_power")) return; + if (!values.hasOwnProperty("total_power")) return; const actualTotalPower = values.total_power; - - const numberOfNodes = Object.keys(FLOW.GLOBALS.nodesData).length; - if(numberOfNodes == 0) numberOfNodes = 20; // to make sure, we send notification if totalPower is more than 300 - - if(actualTotalPower > numberOfNodes * 15 && this.onNotificationSent == false) - { + + if (actualTotalPower > energyToSwitchLamps && this.onNotificationSent == false) { sendNotification("modbus_reader: lampSwitchNotification", tbName, "lamps_have_turned_on", {}, "", SEND_TO.tb, instance); this.onNotificationSent = true; this.offNotificationSent = false; - } - else if(actualTotalPower <= numberOfNodes * 15 && this.offNotificationSent == false) - { + } + else if (actualTotalPower <= energyToSwitchLamps && this.offNotificationSent == false) { sendNotification("modbus_reader: lampSwitchNotification", tbName, "lamps_have_turned_off", {}, "", SEND_TO.tb, instance); this.onNotificationSent = false; this.offNotificationSent = true; } } - } + } const isObjectEmpty = (objectName) => { return Object.keys(objectName).length === 0 && objectName.constructor === Object; @@ -353,7 +330,9 @@ exports.install = function(instance) { phases = FLOW.GLOBALS.settings.phases; tbName = FLOW.GLOBALS.settings.rvoTbName; noVoltage = FLOW.GLOBALS.settings.no_voltage; - mainSocket = new SocketWithClients(); + energyToSwitchLamps = FLOW.GLOBALS.settings.energy_to_switch_lamps / 2.5; //half value is enought to show if lamps are turned on or off + if (deviceConfig.length) mainSocket = new SocketWithClients(); + else console.log("Modbus_reader: no modbus device in configuration"); // this notification is to show, that flow (unipi) has been restarted sendNotification("modbus_reader", tbName, "flow_restart", {}, "", SEND_TO.slack, instance); diff --git a/flow/show_dbdata.js b/flow/show_dbdata.js index d01eecd..1e23ff7 100644 --- a/flow/show_dbdata.js +++ b/flow/show_dbdata.js @@ -4,7 +4,7 @@ exports.group = 'Worksys'; exports.color = '#888600'; exports.version = '1.0.2'; exports.icon = 'sign-out'; -exports.input = 7; +exports.input = 8; exports.output = 1; const { exec } = require('child_process'); @@ -24,25 +24,27 @@ exports.install = function(instance) { instance.send(0, FLOW.GLOBALS.pinsData); }) instance.on("4", _ => { - instance.send(0, {rpcSwitchOffLine, rpcSetNodeDimming, rpcLineProfile, rpcNodeProfile, sunCalcExample, dataFromTerminalBroadcast}) + instance.send(0, { rpcSwitchOffLine, rpcSetNodeDimming, rpcLineProfile, rpcNodeProfile, sunCalcExample, dataFromTerminalBroadcast }) }) instance.on("5", _ => { - exec("sudo tail -n 25 monitor.txt" , (err, stdout, stderr) => { - if (err || stderr) instance.send(0,{err, stderr}); - else instance.send(0,stdout); + exec("sudo tail -n 25 monitor.txt", (err, stdout, stderr) => { + if (err || stderr) instance.send(0, { err, stderr }); + else instance.send(0, stdout); }) }) instance.on("6", _ => { - exec("sudo tail -n 25 err.txt" , (err, stdout, stderr) => { - if (err || stderr) instance.send(0,{err, stderr}); - else instance.send(0,stdout); + exec("sudo tail -n 25 err.txt", (err, stdout, stderr) => { + if (err || stderr) instance.send(0, { err, stderr }); + else instance.send(0, stdout); }) }) -}; + instance.on("7", _ => { + instance.send(0, FLOW.deviceStatus); + }) +}; - -const rpcSwitchOffLine = +const rpcSwitchOffLine = { "topic": "v1/gateway/rpc", "content": { @@ -90,7 +92,7 @@ const rpcSetNodeDimming = } } -const rpcLineProfile = +const rpcLineProfile = { "topic": "v1/gateway/rpc", "content": { @@ -212,7 +214,7 @@ const rpcNodeProfile = } } - const sunCalcExample = { +const sunCalcExample = { dusk_no_offset: '20:18', dawn_no_offset: '05:19', dusk: '20:18', diff --git a/flow/slack_filter.js b/flow/slack_filter.js index 753c24a..6b2d2a5 100644 --- a/flow/slack_filter.js +++ b/flow/slack_filter.js @@ -7,7 +7,7 @@ exports.output = 1; exports.author = 'Jakub Klena'; exports.icon = 'plug'; exports.version = '1.0.8'; -exports.options = { 'name':'', 'types': '["emergency", "critical", "error", "alert"]', 'message_includes':'["is responding again"]', 'tag_on_include':'[{"user_id":"U072JE5JUQG", "includes":["Electrometer", "Twilight sensor"]}]', 'slack_channel':'' }; +exports.options = { 'name': '', 'types': '["emergency", "critical", "error", "alert"]', 'message_includes': '["is responding again"]', 'tag_on_include': '[{"user_id":"U072JE5JUQG", "includes":["Electrometer", "Twilight sensor"]}]', 'slack_channel': '' }; exports.html = `
@@ -37,7 +37,7 @@ exports.install = function(instance) { if (!running) return; let value = response.data; if (typeof value !== 'object') return; - + let can = false var k = Object.keys(value); var interested = JSON.parse(instance.options.types); @@ -57,11 +57,11 @@ exports.install = function(instance) { let icon = ':totaljs:'; let type = value[k[0]][0]['values']['_event']['type']; let source = value[k[0]][0]['values']['_event']['source']['func']; - let message = value[k[0]][0]['values']['_event']['message']; + let message = value[k[0]][0]['values']['_event']['message']['en']; let message_data = value[k[0]][0]['values']['_event']['message_data']; let tag = ''; - switch(type){ + switch (type) { case 'debug': icon = ':beetle:'; break; @@ -89,15 +89,15 @@ exports.install = function(instance) { } // Check if this message includes one of the strings we are watching for - for (const msg of msg_incl){ - if (message.includes(msg)){ + for (const msg of msg_incl) { + if (message.includes(msg)) { if (msg == 'is responding again') icon = ':large_green_circle:'; can = true; break; } } // Check if message is one of the types we are watching for - if (interested.includes(type)){ + if (interested.includes(type)) { can = true; } @@ -105,10 +105,10 @@ exports.install = function(instance) { // Check for each person tags based on what the message includes - for (const person of tags){ - for (const msg of person.includes){ - if (message.includes(msg)){ - tag += '<@'+person.user_id+'> '; + for (const person of tags) { + for (const msg of person.includes) { + if (message.includes(msg)) { + tag += '<@' + person.user_id + '> '; break; // Break out from this person checks as they are already tagged now } } @@ -116,46 +116,46 @@ exports.install = function(instance) { // Now that all people are tagged add new line symbol if (tag != '') tag += '\n'; - let send_data = tag+instance.options.name+' '+type.toUpperCase()+'\n*Source*: '+source+'\n*Message*: '+message; + let send_data = tag + instance.options.name + ' ' + type.toUpperCase() + '\n*Source*: ' + source + '\n*Message*: ' + message; if (message_data) { - send_data += '\nData: '+message_data; + send_data += '\nData: ' + message_data; } let ignore_msg = false - if (message.includes('Configuration of dimming profile to node no')){ - for (let i = 0; i < FLOW["savedSlackMessages"].length; i++){ - if (FLOW["savedSlackMessages"][i].message == message){ + if (message.includes('Configuration of dimming profile to node no')) { + for (let i = 0; i < FLOW["savedSlackMessages"].length; i++) { + if (FLOW["savedSlackMessages"][i].message == message) { ignore_msg = true; break; } } - if (!ignore_msg){ - FLOW["savedSlackMessages"].push({message, 'dateandtime': Date.now()}); - if (timer === null){ - timer = setTimeout(checkSavedMessages, 60*60000); + if (!ignore_msg) { + FLOW["savedSlackMessages"].push({ message, 'dateandtime': Date.now() }); + if (timer === null) { + timer = setTimeout(checkSavedMessages, 60 * 60000); } } } - if (!ignore_msg){ - instance.send2({'msg':send_data,'bot_name':instance.options.name+' '+type.toUpperCase(),'bot_icon':icon,'channel':instance.options.slack_channel}); + if (!ignore_msg) { + instance.send2({ 'msg': send_data, 'bot_name': instance.options.name + ' ' + type.toUpperCase(), 'bot_icon': icon, 'channel': instance.options.slack_channel }); } }); - function checkSavedMessages(){ + function checkSavedMessages() { var d = Date.now(); d = d - 86400000; // older then 24hr var a = []; //Remove msgs older then 24hr - for (let i = 0; i < FLOW["savedSlackMessages"].length; i++){ - if (FLOW["savedSlackMessages"][i].dateandtime > d){ + for (let i = 0; i < FLOW["savedSlackMessages"].length; i++) { + if (FLOW["savedSlackMessages"][i].dateandtime > d) { a.push(FLOW["savedSlackMessages"][i]); } } FLOW["savedSlackMessages"] = a; if (FLOW["savedSlackMessages"].length > 0) { - timer = setTimeout(checkSavedMessages, 60*60000); + timer = setTimeout(checkSavedMessages, 60 * 60000); } else { timer = null; } @@ -163,7 +163,7 @@ exports.install = function(instance) { instance.reconfigure = function() { try { - if (!FLOW["savedSlackMessages"]){ + if (!FLOW["savedSlackMessages"]) { FLOW["savedSlackMessages"] = []; } @@ -183,5 +183,4 @@ exports.install = function(instance) { instance.on('options', instance.reconfigure); setTimeout(instance.reconfigure, 10000); - }; diff --git a/flow/thermometer.js b/flow/thermometer.js index fa015c6..fc7074d 100644 --- a/flow/thermometer.js +++ b/flow/thermometer.js @@ -33,7 +33,7 @@ exports.install = function(instance) { logger.debug(exports.title, "installed"); - instance.on("close", function(){ + instance.on("close", function() { clearInterval(startRead); }) @@ -42,24 +42,25 @@ exports.install = function(instance) { try { - if(temperatureAddress === "") throw "Thermometer: temperatureAddress is not defined"; + if (temperatureAddress === "") throw "Thermometer: temperatureAddress is not defined"; exec(`owread -C ${temperatureAddress}/temperature`, (error, stdout, stderr) => { - if(!error) - { + if (!error) { parseData(stdout) return; } counter++; - if(counter == NUMBER_OF_FAILURES_TO_SEND_ERROR) sendNotification("Thermometer_main", rvoTbName, "thermometer_is_not_responding", {}, {"Error": error}, SEND_TO.tb, instance, "thermometer"); - monitor.info("Thermometer is not responding", error); - instance.send(SEND_TO.dido_controller, {status: "NOK-thermometer"}); + if (counter == NUMBER_OF_FAILURES_TO_SEND_ERROR) { + sendNotification("Thermometer_main", rvoTbName, "thermometer_is_not_responding", {}, { "Error": error }, SEND_TO.tb, instance, "thermometer"); + monitor.info("Thermometer is not responding", error); + } + instance.send(SEND_TO.dido_controller, { status: "NOK-thermometer" }); }); } - catch(err) { + catch (err) { errLogger.error(exports.title, err); clearInterval(startRead); } @@ -70,12 +71,12 @@ exports.install = function(instance) { data = parseFloat(data); //logger.debug("Thermometer", data); - if(isNaN(data)) { + if (isNaN(data)) { errLogger.error("Thermometer sends invalid data"); return; } - if(counter > NUMBER_OF_FAILURES_TO_SEND_ERROR) //1 hour + if (counter > NUMBER_OF_FAILURES_TO_SEND_ERROR) //1 hour { instance.send(SEND_TO.debug, "Thermometer - temperature data are comming again"); sendNotification("Thermometer_parseData", rvoTbName, "thermometer_is_responding_again", {}, "", SEND_TO.tb, instance, "thermometer"); @@ -85,7 +86,7 @@ exports.install = function(instance) { "temperature": Number(data.toFixed(2)), } - instance.send(SEND_TO.dido_controller, {values: values}); + instance.send(SEND_TO.dido_controller, { values: values }); counter = 0; } diff --git a/flow/wsmqttpublish.js b/flow/wsmqttpublish.js index b2a218d..0eba804 100644 --- a/flow/wsmqttpublish.js +++ b/flow/wsmqttpublish.js @@ -55,7 +55,7 @@ let saveTelemetryOnError = true;//backup_on_failure overrides this value //------------------------ let rollers; -if(createTelemetryBackup) rollers = require('streamroller'); +if (createTelemetryBackup) rollers = require('streamroller'); const noSqlFileSizeLimit = 4194304;//use 5MB - 4194304 let insertNoSqlCounter = 0; @@ -70,14 +70,14 @@ let lastRestoreTime = 0; // if there is an error in client connection, flow logs to monitor.txt. Not to log messages every second, we use sendClientError variable let sendClientError = true; -process.on('uncaughtException', function (err) { +process.on('uncaughtException', function(err) { errLogger.error('uncaughtException:', err.message) errLogger.error(err.stack); //TODO //send to service - + //process.exit(1); }) @@ -96,22 +96,19 @@ exports.install = function(instance) { let sendWsStatusVar = null; let wsmqtt_status = 'disconnected'; - function getWsmqttName(host) - { - if(host == "tb-demo.worksys.io" || host == '192.168.252.4') return 'wsmqtt_demo'; - else if(host == "tb-qas01.worksys.io" || host == '192.168.252.5') return 'wsmqtt_qas01'; - else if(host == "tb-prod01.worksys.io" || host == '192.168.252.1') return 'wsmqtt_prod01'; + function getWsmqttName(host) { + if (host == "tb-demo.worksys.io" || host == '192.168.252.4') return 'wsmqtt_demo'; + else if (host == "tb-qas01.worksys.io" || host == '192.168.252.5') return 'wsmqtt_qas01'; + else if (host == "tb-prod01.worksys.io" || host == '192.168.252.1') return 'wsmqtt_prod01'; } - function sendWsStatus() - { - instance.send(SEND_TO.services, {[wsmqttName]: wsmqtt_status}); + function sendWsStatus() { + instance.send(SEND_TO.services, { [wsmqttName]: wsmqtt_status }); } - function main() - { - if(!FLOW.dbLoaded) return; + function main() { + if (!FLOW.dbLoaded) return; loadSettings(); clearInterval(sendWsStatus); @@ -119,11 +116,9 @@ exports.install = function(instance) { } //set opts according to db settings - function loadSettings() - { + function loadSettings() { - if(instance.options.host !== "") - { + if (instance.options.host !== "") { //override settings from database var o = instance.options; opts = { @@ -139,13 +134,12 @@ exports.install = function(instance) { console.log("wsmqttpublich -> loadSettings from instance.options", instance.options); } - else - { - + else { + const SETTINGS = FLOW.GLOBALS.settings; backup_on_failure = SETTINGS.backup_on_failure; saveTelemetryOnError = backup_on_failure; - + restore_from_backup = SETTINGS.restore_from_backup; restore_backup_wait = SETTINGS.restore_backup_wait; @@ -170,8 +164,7 @@ exports.install = function(instance) { connectToTbServer(); } - function connectToTbServer() - { + function connectToTbServer() { var url = "mqtt://" + opts.host + ":" + opts.port; console.log("MQTT URL: ", url); @@ -179,7 +172,7 @@ exports.install = function(instance) { client.on('connect', function() { instance.status("Connected", "green"); - monitor.info("MQTT client connected"); + //monitor.info("MQTT client connected"); sendClientError = true; clientReady = true; @@ -198,31 +191,31 @@ exports.install = function(instance) { TRY(function() { message = JSON.parse(message); - if (message.hasOwnProperty("device") && message.hasOwnProperty("data") && message.data.hasOwnProperty("id")) { - client.publish(topic, `{"device": ${message.device}, "id": ${message.data.id}, "data": {"success": true}}`, {qos:1}); - instance.send(SEND_TO.rpcCall, {"device": message.device, "id": message.data.id, "RPC response": {"success": true}}); + if (message.hasOwnProperty("device") && message.hasOwnProperty("data") && message.data.hasOwnProperty("id")) { + client.publish(topic, `{"device": ${message.device}, "id": ${message.data.id}, "data": {"success": true}}`, { qos: 1 }); + instance.send(SEND_TO.rpcCall, { "device": message.device, "id": message.data.id, "RPC response": { "success": true } }); } }, () => instance.debug('MQTT: Error parsing data', message)); } - instance.send(SEND_TO.rpcCall, {"topic":topic, "content":message }); + instance.send(SEND_TO.rpcCall, { "topic": topic, "content": message }); }); client.on('close', function() { clientReady = false; wsmqtt_status = 'disconnected'; - + instance.status("Disconnected", "red"); - instance.send(SEND_TO.debug, {"message":"Client CLOSE signal received !"}); + instance.send(SEND_TO.debug, { "message": "Client CLOSE signal received !" }); }); client.on('error', function(err) { - instance.status("Err: "+ err.code, "red"); - instance.send(SEND_TO.debug, {"message":"Client ERROR signal received !", "error":err, "opt":opts }); - if(sendClientError) { - monitor.info('MQTT client error', err); - sendClientError = false; + instance.status("Err: " + err.code, "red"); + instance.send(SEND_TO.debug, { "message": "Client ERROR signal received !", "error": err, "opt": opts }); + if (sendClientError) { + monitor.info('MQTT client error', err); + sendClientError = false; } clientReady = false; wsmqtt_status = 'disconnected'; @@ -238,45 +231,39 @@ exports.install = function(instance) { instance.on('1', function(data) { - if(clientReady) - { - //do we have some data in backup file? if any, process data from database - if(saveTelemetryOnError) - { + if (clientReady) { + //do we have some data in backup file? if any, process data from database + if (saveTelemetryOnError) { //read telemetry data and send back to server - if(!processingData) processDataFromDatabase(); + if (!processingData) processDataFromDatabase(); } - + let stringifiedJson = JSON.stringify(data.data); - client.publish("v1/gateway/telemetry", stringifiedJson, {qos: 1}); + client.publish("v1/gateway/telemetry", stringifiedJson, { qos: 1 }); //backup telemetry - if(createTelemetryBackup) - { + if (createTelemetryBackup) { data.data.id = UID(); nosqlBackup.insert(data.data); insertBackupNoSqlCounter++; - if(insertBackupNoSqlCounter > 150) - { - let options = {compress: true}; + if (insertBackupNoSqlCounter > 150) { + let options = { compress: true }; let path = __dirname + "/../databases/backup/tbdata.nosql"; var stream = new rollers.RollingFileStream(path, noSqlFileSizeLimit, 150, options); stream.write(""); stream.end(); insertBackupNoSqlCounter = 0; - } + } } - - } - else - { - //logger.debug("Client unavailable. Data not sent !", JSON.stringify(data.data)); - instance.send(SEND_TO.debug, {"message":"Client unavailable. Data not sent !", "data": data.data }); - if(saveTelemetryOnError) - { + } + else { + //logger.debug("Client unavailable. Data not sent !", JSON.stringify(data.data)); + instance.send(SEND_TO.debug, { "message": "Client unavailable. Data not sent !", "data": data.data }); + + if (saveTelemetryOnError) { //create new file from tbdata.nosql, if file size exceeds given limit, and clear tbdata.nosql makeBackupFromDbFile(); @@ -289,72 +276,63 @@ exports.install = function(instance) { instance.close = function(done) { - if(clientReady){ + if (clientReady) { client.end(); clearInterval(sendWsStatusVar); } }; - - function getDbBackupFileCounter(type) - { + + function getDbBackupFileCounter(type) { var files = fs.readdirSync(__dirname + "/../databases"); let counter = 0; - for(var i = 0; i < files.length; i++) - { + for (var i = 0; i < files.length; i++) { - if(files[i] == "tbdata.nosql") continue; + if (files[i] == "tbdata.nosql") continue; - if(files[i].endsWith(".nosql")) - { + if (files[i].endsWith(".nosql")) { let pos = files[i].indexOf("."); - if(pos > -1) - { + if (pos > -1) { let fileCounter = counter; let firstDigit = files[i].slice(0, pos); fileCounter = parseInt(firstDigit); - if(isNaN(fileCounter)) fileCounter = 0; + if (isNaN(fileCounter)) fileCounter = 0; //console.log("getDbBackupFileCounter digit:", files[i], firstDigit, fileCounter, isNaN(fileCounter), type); - - if(type == "max") - { - if(fileCounter > counter) - { + + if (type == "max") { + if (fileCounter > counter) { counter = fileCounter; } } - else if(type == "min") - { - if(counter == 0) counter = fileCounter; + else if (type == "min") { + if (counter == 0) counter = fileCounter; - if(fileCounter < counter) - { + if (fileCounter < counter) { counter = fileCounter; } } } } - + } - - if(type == "max") counter++; + + if (type == "max") counter++; return counter; } const makeBackupFromDbFile = async () => { - if(!saveTelemetryOnError) return; + if (!saveTelemetryOnError) return; //to avoid large file: tbdata.nosql //init value is 0! - if(insertNoSqlCounter > 0) - { + if (insertNoSqlCounter > 0) { --insertNoSqlCounter; return; } @@ -366,8 +344,7 @@ exports.install = function(instance) { var stats = fs.statSync(source); var fileSizeInBytes = stats.size; - if(fileSizeInBytes > noSqlFileSizeLimit) - { + if (fileSizeInBytes > noSqlFileSizeLimit) { let counter = 1; counter = getDbBackupFileCounter("max"); @@ -381,21 +358,20 @@ exports.install = function(instance) { //clear tbdata.nosql fs.writeFileSync(source, ""); fs.truncateSync(source, 0); - + } } const processDataFromDatabase = async () => { - - if(restore_from_backup <= 0) return; + + if (restore_from_backup <= 0) return; //calculate diff const now = new Date(); let currentTime = now.getTime(); let diff = currentTime - lastRestoreTime; - if( (diff / 1000) < restore_backup_wait) - { + if ((diff / 1000) < restore_backup_wait) { //console.log("*********restore_backup_wait", diff, restore_backup_wait); return; } @@ -409,60 +385,55 @@ exports.install = function(instance) { let dataBase = 'tbdata'; var nosql; - if(counter == 0) dataBase = 'tbdata'; + if (counter == 0) dataBase = 'tbdata'; else dataBase = counter + "." + 'tbdata'; nosql = NOSQL(dataBase); //select all data - use limit restore_from_backup let records = await promisifyBuilder(nosql.find().take(restore_from_backup)); - - for(let i = 0; i < records.length; i++) - { - if(clientReady) { + + for (let i = 0; i < records.length; i++) { + if (clientReady) { let item = records[i]; let id = item.id; - if(id !== undefined) - { + if (id !== undefined) { //console.log("------------processDataFromDatabase - remove", id, dataBase, i); try { let message = JSON.parse(JSON.stringify(item)); delete message.id; - - client.publish("v1/gateway/telemetry", JSON.stringify(message), {qos:1}); - + + client.publish("v1/gateway/telemetry", JSON.stringify(message), { qos: 1 }); + //remove from database await promisifyBuilder(nosql.remove().where("id", id)); - } catch(error) { + } catch (error) { //process error console.log("processDataFromDatabase", error); } } - + } - else - { + else { processingData = false; return; } } - if(records.length > 0) - { + if (records.length > 0) { //clean backup file - if(counter > 0) nosql.clean(); + if (counter > 0) nosql.clean(); } //no data in db, remove - if(records.length == 0) - { - if(counter > 0) nosql.drop(); + if (records.length == 0) { + if (counter > 0) nosql.drop(); } const d = new Date();