uint64_t JSONTimeOffset(uint64_t dt) { // calculate number of milliseconds between midnight 1-jan-1970 to midnight 1-jan-1980 (1972 and 1976 were leap years) static const uint64_t offset = ADateTime::DaysSince1970 * (uint64_t)24 * (uint64_t)3600 * (uint64_t)1000; // convert to local time return offset + ADateTime(dt).UTCToLocal().operator uint64_t(); }
bool RunAndLogCommand(const AString& cmd) { const ADVBConfig& config = ADVBConfig::Get(); AString cmd1 = cmd; if (config.IsOutputDisabled()) cmd1.printf(" >>\"%s\" 2>&1", config.GetLogFile(ADateTime().GetDays()).str()); else cmd1.printf(" 2>&1 | tee -a \"%s\"", config.GetLogFile(ADateTime().GetDays()).str()); if (config.LogRemoteCommands()) { config.logit("Running '%s'", cmd1.str()); } bool success = (system(cmd1) == 0); if (!success) config.logit("Command '%s' failed", cmd.str()); return success; }
ADateTime ATimeControl::GetTime() { int h,m,s; h = AIntVal(m_pEditHour->GetText()); m = AIntVal(m_pEditMinute->GetText()); s = AIntVal(m_pEditSecond->GetText()); if( h < 0 ) h = 0; if( h > 23 ) h = 23; if( m < 0 ) m = 0; if( m > 59 ) m = 59; if( s < 0 ) s = 0; if( s > 59 ) s = 59; return ADateTime(1900,1,1,h,m,s); }
void ADVBPatterns::GetFieldValue(const FIELD& field, VALUE& value, AString& val) { switch (field.type) { case FieldType_string: value.str = val.Steal(); break; case FieldType_date: case FieldType_span: case FieldType_age: value.u64 = (uint64_t)ADateTime(val, ADateTime::Time_Absolute); break; case FieldType_uint32_t: case FieldType_external_uint32_t: value.u32 = (uint32_t)val; break; case FieldType_sint32_t: case FieldType_external_sint32_t: value.s32 = (sint32_t)val; break; case FieldType_uint16_t: value.u16 = (uint16_t)val; break; case FieldType_sint16_t: value.s16 = (sint16_t)val; break; case FieldType_uint8_t: value.u8 = (uint8_t)(uint16_t)val; break; case FieldType_sint8_t: value.s8 = (sint8_t)(sint16_t)val; break; case FieldType_flag...FieldType_lastflag: value.u8 = ((uint32_t)val != 0); break; } }
MotionDetector::MotionDetector(ASocketServer& _server, const ASettingsHandler& _settings, ASettingsHandler& _stats, AStdFile& _log, uint_t _index) : ImageHandler(), stream(&_server), settings(_settings), stats(_stats), log(_log), index(_index), images(4), imgindex(0), verbose(0) { Configure(); stream.SetImageHandler(this); diffavg = (double)stats.Get(AString("avg%").Arg(index), "0.0"); diffsd = (double)stats.Get(AString("sd%").Arg(index), "0.0"); log.printf("%s[%u]: New detector\n", ADateTime().DateFormat("%Y-%M-%D %h:%m:%s.%S").str(), index); }
void MotionDetector::Configure() { AString nstr = AString("%").Arg(index); log.printf("%s[%u]: Reading new settings...\n", ADateTime().DateFormat("%Y-%M-%D %h:%m:%s.%S").str(), index); stream.Close(); stream.SetUsernameAndPassword(GetSetting("username", "admin"), GetSetting("password", "arsebark")); AString camera = GetSetting("camera", ""); log.printf("%s[%u]: Connecting to %s...\n", ADateTime().DateFormat("%Y-%M-%D %h:%m:%s.%S").str(), index, camera.str()); if (!stream.OpenHost(camera)) { log.printf("%s[%u]: Failed to connect to %s...\n", ADateTime().DateFormat("%Y-%M-%D %h:%m:%s.%S").str(), index, camera.str()); } imagedir = GetSetting("imagedir", "/media/cctv"); imagefmt = GetSetting("filename", "%Y-%M-%D/%h/Image-{camera}-%Y-%M-%D-%h-%m-%s-%S"); detimgdir = GetSetting("detimagedir"); detimgfmt = GetSetting("detfilename", "%Y-%M-%D/%h/detection/Image-{camera}-%Y-%M-%D-%h-%m-%s-%S"); detcmd = GetSetting("detcommand", ""); nodetcmd = GetSetting("nodetcommand", ""); coeff = (double)GetSetting("coeff", "1.0e-3"); avgfactor = (double)GetSetting("avgfactor", "1.0"); sdfactor = (double)GetSetting("sdfactor", "2.0"); redscale = (double)GetSetting("rscale", "1.0"); grnscale = (double)GetSetting("gscale", "1.0"); bluscale = (double)GetSetting("bscale", "1.0"); threshold = (double)GetSetting("threshold", "3000.0"); verbose = (uint_t)GetSetting("verbose", "0"); matmul = 1.f; matwid = mathgt = 0; AString _matrix = GetSetting("matrix", ""); if (_matrix.Valid()) { uint_t row, nrows = _matrix.CountLines(";"); uint_t col, ncols = 1; int p; if ((p = _matrix.Pos("*")) >= 0) { AString mul = _matrix.Mid(p + 1); _matrix = _matrix.Left(p); if ((p = mul.Pos("/")) >= 0) { matmul = (float)mul.Left(p) / (float)mul.Mid(p + 1); } else matmul = (float)mul; } else if ((p = _matrix.Pos("/")) >= 0) { AString mul = _matrix.Mid(p + 1); _matrix = _matrix.Left(p); matmul = 1.f / (float)mul; } for (row = 0; row < nrows; row++) { uint_t n = _matrix.Line(row, ";").CountLines(","); ncols = MAX(ncols, n); } nrows |= 1; ncols |= 1; matrix.resize(nrows * ncols); for (row = 0; row < nrows; row++) { AString line = _matrix.Line(row,";"); for (col = 0; col < ncols; col++) matrix[col + row * ncols] = (float)line.Line(col, ","); } matwid = ncols; mathgt = nrows; #if 0 printf("Matrix is %u x %u:\n", matwid, mathgt); for (row = 0; row < nrows; row++) { for (col = 0; col < ncols; col++) printf("%8.3f", matrix[col + row * ncols]); printf("\n"); } printf("Multiplier %0.6f\n", matmul); #endif } else matrix.resize(0); }
MotionDetector::~MotionDetector() { log.printf("%s[%u]: Shutting down\n", ADateTime().DateFormat("%Y-%M-%D %h:%m:%s.%S").str(), index); }
AString ADVBPatterns::ParsePattern(const AString& _line, PATTERN& pattern, const AString& user) { const ADVBConfig& config = ADVBConfig::Get(); ADataList& list = pattern.list; AString& errors = pattern.errors; AString line = config.ReplaceTerms(user, _line); TERM *term; uint_t i; pattern.exclude = false; pattern.enabled = true; pattern.scorebased = false; pattern.pri = 0; pattern.user = user; pattern.pattern = line; if (pattern.user.Valid()) { pattern.pri = (int)config.GetUserConfigItem(pattern.user, "pri"); } list.DeleteList(); list.SetDestructor(&__DeleteTerm); i = 0; while (IsWhiteSpace(line[i])) i++; if (line[i] == '#') { pattern.enabled = false; i++; } else if (line[i] == ';') { return errors; } while (IsWhiteSpace(line[i])) i++; if (line[i]) { while (line[i] && errors.Empty()) { if (!IsSymbolStart(line[i])) { errors.printf("Character '%c' (at %u) is not a legal field start character (term %u)", line[i], i, list.Count() + 1); break; } uint_t fieldstart = i++; while (IsSymbolChar(line[i])) i++; AString field = line.Mid(fieldstart, i - fieldstart).ToLower(); while (IsWhiteSpace(line[i])) i++; if (field == "exclude") { pattern.exclude = true; continue; } const FIELD *fieldptr = (const FIELD *)ADVBProg::fieldhash.Read(field); if (!fieldptr) { uint_t nfields; const FIELD *fields = ADVBProg::GetFields(nfields); errors.printf("'%s' (at %u) is not a valid search field (term %u), valid search fields are: ", field.str(), fieldstart, list.Count() + 1); for (i = 0; i < nfields; i++) { const FIELD& field = fields[i]; if (i) errors.printf(", "); errors.printf("'%s'", field.name); } break; } uint_t opstart = i; const char *str = line.str() + i; bool isassign = fieldptr->assignable; uint_t j; uint_t opindex = 0, opcode = Operator_EQ; for (j = 0; j < NUMBEROF(operators); j++) { if (((isassign == operators[j].assign) || (isassign && !operators[j].assign)) && (operators[j].fieldtypes & (1U << fieldptr->type)) && (strncmp(str, operators[j].str, operators[j].len) == 0)) { i += operators[j].len; opindex = j; opcode = operators[j].opcode; break; } } while (IsWhiteSpace(line[i])) i++; AString value; bool implicitvalue = false; if (j == NUMBEROF(operators)) { if (!line[i] || IsSymbolStart(line[i])) { if (fieldptr->assignable) { switch (fieldptr->type) { case FieldType_string: break; case FieldType_date: value = "now"; break; default: value = "1"; break; } opcode = Operator_Assign; } else opcode = Operator_NE; for (j = 0; j < NUMBEROF(operators); j++) { if ((opcode == operators[j].opcode) && ((isassign == operators[j].assign) || (isassign && !operators[j].assign)) && (operators[j].fieldtypes & (1U << fieldptr->type))) { opindex = j; break; } } implicitvalue = true; } else { errors.printf("Symbols at %u do not represent a legal operator (term %u), legal operators for the field '%s' are: ", opstart, list.Count() + 1, field.str()); bool flag = false; for (j = 0; j < NUMBEROF(operators); j++) { if (((isassign == operators[j].assign) || (isassign && !operators[j].assign)) && (operators[j].fieldtypes & (1U << fieldptr->type))) { if (flag) errors.printf(", "); errors.printf("'%s'", operators[j].str); flag = true; } } break; } } if (!implicitvalue) { char quote = 0; if (IsQuoteChar(line[i])) quote = line[i++]; uint_t valuestart = i; while (line[i] && ((!quote && !IsWhiteSpace(line[i])) || (quote && (line[i] != quote)))) { if (line[i] == '\\') i++; i++; } value = line.Mid(valuestart, i - valuestart).DeEscapify(); if (quote && (line[i] == quote)) i++; while (IsWhiteSpace(line[i])) i++; } bool orflag = false; if ((line.Mid(i, 2).ToLower() == "or") && IsWhiteSpace(line[i + 2])) { orflag = true; i += 2; while (IsWhiteSpace(line[i])) i++; } else if ((line[i] == '|') && IsWhiteSpace(line[i + 1])) { orflag = true; i += 1; while (IsWhiteSpace(line[i])) i++; } if ((term = new TERM) != NULL) { term->data.start = fieldstart; term->data.length = i - fieldstart; term->data.field = fieldptr - ADVBProg::fields; term->data.opcode = opcode; term->data.opindex = opindex; term->data.value = value; term->data.orflag = (orflag && !RANGE(opcode, Operator_First_Assignable, Operator_Last_Assignable)); term->field = fieldptr; term->datetype = DateType_none; switch (term->field->type) { case FieldType_string: #if DVBDATVERSION > 1 if (fieldptr->offset == ADVBProg::GetTagsDataOffset()) { value = "|" + value + "|"; } #endif if ((opcode & ~Operator_Inverted) == Operator_Regex) { AString regexerrors; AString rvalue; rvalue = ParseRegex(value, regexerrors); if (regexerrors.Valid()) { errors.printf("Regex error in value '%s' (term %u): %s", value.str(), list.Count() + 1, regexerrors.str()); } value = rvalue; } term->value.str = value.Steal(); break; case FieldType_date: { ADateTime dt; uint_t specified; dt.StrToDate(value, ADateTime::Time_Relative_Local, &specified); //debug("Value '%s', specified %u\n", value.str(), specified); if (!specified) { errors.printf("Failed to parse date '%s' (term %u)", value.str(), list.Count() + 1); break; } else if (((specified == ADateTime::Specified_Day) && (stricmp(term->field->name, "on") == 0)) || (stricmp(term->field->name, "day") == 0)) { //debug("Date from '%s' is '%s' (week day only)\n", value.str(), dt.DateToStr().str()); term->value.u64 = dt.GetWeekDay(); term->datetype = DateType_weekday; } else if (specified & ADateTime::Specified_Day) { specified |= ADateTime::Specified_Date; } if (term->datetype == DateType_none) { specified &= ADateTime::Specified_Date | ADateTime::Specified_Time; if (specified == (ADateTime::Specified_Date | ADateTime::Specified_Time)) { //debug("Date from '%s' is '%s' (full date and time)\n", value.str(), dt.DateToStr().str()); term->value.u64 = (uint64_t)dt; term->datetype = DateType_fulldate; } else if (specified == ADateTime::Specified_Date) { //debug("Date from '%s' is '%s' (date only)\n", value.str(), dt.DateToStr().str()); term->value.u64 = dt.GetDays(); term->datetype = DateType_date; } else if (specified == ADateTime::Specified_Time) { //debug("Date from '%s' is '%s' (time only)\n", value.str(), dt.DateToStr().str()); term->value.u64 = dt.GetMS(); term->datetype = DateType_time; } else { errors.printf("Unknown date specifier '%s' (term %u)", value.str(), list.Count() + 1); } } break; } case FieldType_span: case FieldType_age: { ADateTime dt; //ADateTime::EnableDebugStrToDate(true); term->value.u64 = (uint64_t)ADateTime(value, ADateTime::Time_Absolute); //ADateTime::EnableDebugStrToDate(false); break; } case FieldType_uint32_t: case FieldType_external_uint32_t: term->value.u32 = (uint32_t)value; break; case FieldType_sint32_t: case FieldType_external_sint32_t: term->value.s32 = (sint32_t)value; break; case FieldType_uint16_t: term->value.u16 = (uint16_t)value; break; case FieldType_sint16_t: term->value.s16 = (sint16_t)value; break; case FieldType_uint8_t: term->value.u8 = (uint8_t)(uint16_t)value; break; case FieldType_sint8_t: term->value.s8 = (sint8_t)(sint16_t)value; break; case FieldType_flag...FieldType_lastflag: term->value.u8 = ((uint32_t)value != 0); //debug("Setting test of flag to %u\n", (uint_t)term->value.u8); break; case FieldType_prog: { ADVBProg *prog; if ((prog = new ADVBProg) != NULL) { if (prog->Base64Decode(value)) { term->value.prog = prog; } else { errors.printf("Failed to decode base64 programme ('%s') for %s at %u (term %u)", value.str(), field.str(), fieldstart, list.Count() + 1); delete prog; } } else { errors.printf("Failed to allocate memory for base64 programme ('%s') for %s at %u (term %u)", value.str(), field.str(), fieldstart, list.Count() + 1); } break; } default: errors.printf("Unknown field '%s' type (%u) (term %u)", field.str(), (uint_t)term->field->type, list.Count() + 1); break; } //debug("term: field {name '%s', type %u, assignable %u, offset %u} type %u dateflags %u value '%s'\n", term->field->name, (uint_t)term->field->type, (uint_t)term->field->assignable, term->field->offset, (uint_t)term->data.opcode, (uint_t)term->dateflags, term->value.str); if (errors.Empty()) { pattern.scorebased |= (term->field->offset == ADVBProg::GetScoreDataOffset()); list.Add((uptr_t)term); } else { __DeleteTerm((uptr_t)term, NULL); break; } } } }