Scan ODB for alarms.
692 {
695 }
696
697#ifdef LOCAL_ROUTINES
698 {
702
704
706
709
710
712 size = sizeof(flag);
714 if (!flag)
716
717
719 size = sizeof(flag);
721 if (!flag)
723
724
730 fprintf(stderr,
"al_check: Something is wrong with our semaphore, ss_semaphore_wait_for() returned %d, aborting.\n",
status);
731
732
733 fprintf(stderr, "al_check: Cannot abort - this will lock you out of odb. From this point, MIDAS will not work correctly. Please read the discussion at https://midas.triumf.ca/elog/Midas/945\n");
735 }
736
737
739 if (!hkeyroot) {
740
742 demo_odb.
connect(
"/Alarms/Alarms/Demo ODB");
743
745 if (!hkeyroot) {
748 }
749
751 demo_periodic.
connect(
"/Alarms/Alarms/Demo periodic");
752
754 if (!hkeyroot) {
757 }
758
759
761 {"Write system message", true},
762 {"Write Elog message", false},
763 {"System message interval", 60},
764 {"System message last", (uint32_t)0},
765 {"Execute command", ""},
766 {"Execute interval", 0},
767 {"Execute last", (uint32_t)0},
768 {"Stop run", false},
769 {"Display BGColor", "red"},
770 {"Display FGColor", "black"},
771 {"Alarm sound", true}
772 };
773 auto warning = alarm;
774 alarm.
connect(
"/Alarms/Classes/Alarm");
775 warning["Display BGColor"] = "yellow";
776 warning.connect("/Alarms/Classes/Warning");
777 }
778
779 for (
int i = 0;;
i++) {
782 break;
783
785
786 std::string alarm_path =
"/Alarms/Alarms/" + std::string(
key.
name);
789
790 int alarm_type = alarm["Type"];
791 if (alarm_type < 1 || alarm_type >
AT_LAST) {
793 continue;
794 }
795
796 bool active = alarm["Active"];
797 int check_interval = alarm["Check interval"];
798 DWORD checked_last = alarm[
"Checked last"];
799
800
801 if (active && alarm_type ==
AT_PERIODIC && check_interval > 0 && (
INT)
ss_time() - (
INT) checked_last > check_interval) {
802
803 if (checked_last == 0) {
805 alarm["Checked last"] = checked_last;
806 } else {
807 std::string alarm_message = alarm["Alarm Message"];
808 std::string alarm_class = alarm["Alarm Class"];
810 }
811 }
812
813
814 if (active && alarm_type ==
AT_EVALUATED && check_interval > 0 && (
INT)
ss_time() - (
INT) checked_last > check_interval) {
815
816 std::string condition = alarm["Condition"];
819 alarm[
"Checked last"] = (uint32_t)
ss_time();
820 DWORD trigger_count = alarm[
"Trigger count"];
821 DWORD trigger_count_required = alarm[
"Trigger count required"];
822 alarm["Trigger count"] = ++trigger_count;
823 if (trigger_count >= trigger_count_required) {
824 alarm["Trigger count"] = (uint32_t)0;
825
826 std::string
str = alarm[
"Alarm Message"];
827 size_t value_pos =
str.find(
"%s");
828 if (value_pos != std::string::npos)
830 if (trigger_count_required > 0)
831 str +=
" (for more than " + std::to_string(trigger_count_required) +
"*" +
832 std::to_string(check_interval) + " seconds)";
833 std::string alarm_class = alarm["Alarm Class"];
835 }
836 } else {
837 alarm[
"Checked last"] = (uint32_t)
ss_time();
838 alarm["Trigger count"] = (uint32_t)0;
839 }
840 }
841 }
842
843
845 if (hkeyroot) {
846 for (
int i = 0;;
i++) {
849 break;
850
852
853
855 continue;
856
858
860
861
864
865
866
868
869
870
871
872
873
874
876 DWORD first_failed = program_info[
"First failed"];
877 if (first_failed == 0) {
878 first_failed = (
DWORD) now;
879 program_info["First failed"] = first_failed;
880 }
881
882
883
884
885
886 DWORD check_interval = program_info[
"Check interval"];
887 if (now - first_failed >= check_interval / 1000) {
888
889 std::string alarm_class = program_info["Alarm class"];
890 if (!alarm_class.empty()) {
893 }
894
895
897 std::string start_command = program_info["Start command"];
900 program_info["First failed"] = (uint32_t)0;
902 }
903 }
904 } else {
905 DWORD first_failed = program_info[
"First failed"];
906 if (first_failed != 0)
907 program_info["First failed"] = (uint32_t)0;
908 }
909 }
910 }
911
913 }
914#endif
915
917}
void connect_and_fix_structure(std::string path)
void connect(const std::string &path, const std::string &name, bool write_defaults, bool delete_keys_not_in_defaults=false)
static midas::odb al_make_alarm_odb(bool periodic=false)
BOOL al_evaluate_condition(const char *alarm_name, const char *condition, std::string *pvalue)
INT al_trigger_alarm(const char *alarm_name, const char *alarm_message, const char *default_class, const char *cond_str, INT type)
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
INT cm_get_experiment_semaphore(INT *semaphore_alarm, INT *semaphore_elog, INT *semaphore_history, INT *semaphore_msg)
INT cm_exist(const char *name, BOOL bClientName)
#define DB_NO_MORE_SUBKEYS
INT ss_semaphore_release(HNDLE semaphore_handle)
INT ss_semaphore_wait_for(HNDLE semaphore_handle, DWORD timeout_millisec)
INT ss_system(const char *command)
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
BOOL equal_ustring(const char *str1, const char *str2)
INT db_get_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, void *data, INT *buf_size, DWORD type, BOOL create)
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
INT db_find_key(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
INT db_enum_key(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
std::string rpc_get_name()
INT rpc_call(DWORD routine_id,...)
std::string msprintf(const char *format,...)