go to post Julian Matthews · Apr 17, 2020 Hi Vic. This is what I expected to work as well, but for some reason the messages don't route if I try this method. For example this works: HL7.{PIDgrpgrp(1).ORCgrp(1).OBR:UniversalServiceIdentifier.identifier} contains "ABC" But this doesn't: HL7.{PIDgrpgrp(1).ORCgrp().OBR:UniversalServiceIdentifier.identifier} contains "ABC" Even though I'd expect the "HL7.{PIDgrpgrp(1).ORCgrp().OBR:UniversalServiceIdentifier.identifier}" to return something along the lines of "<ABC><XYZ><LMN>" and therefore would be picked up by the contains function.
go to post Julian Matthews · Feb 5, 2020 Hi Joao. Here is the working version of the code I referred to - I'm sure someone here can probably look at it and refactor it into 4 lines, but it does the job Class DEV.Monitoring.FolderMonitor Extends %SYS.Task.Definition { Parameter TaskName = "Folder Queue Monitor"; Property MonitoredFolder As %String; Property AgeToAlert As %Integer(VALUELIST = ",5,10,15,20,25,30,35,40,45,50,55,60") [ InitialExpression = "30" ]; Property SMTPServer As %String; Property SMTPPort As %String [ InitialExpression = "25" ]; Property SMTPUsername As %String; Property SMTPPassword As %String; Property Recipient As %String(MAXLEN = 256); Method OnTask() As %Status { Set tsc = ..CheckFileAgeInFolder(..MonitoredFolder,..AgeToAlert,"*.*") Quit tsc } Method CheckFileAgeInFolder(Directory As %String, AgeToAlert As %Integer, Extention As %String) As %Status { set tSC = $$$OK // Calculate the file age that we want to trigger the alert // $h is Horolog. HOROLOG contains a character string that consists of two integer values // separated by a comma. These two integers represent the current local date and time in // Caché storage format. These integers are counters, not user-readable dates and times. // The format is ddddd,sssss //First, take the HOROLOG into a variable so that it isn't different everytime we need to use the HOROLOG. Set pHorolog = $H //Now break down each part of the Horolog into the days and seconds set currentdate = $PIECE(pHorolog,",",1) set currenttime = $PIECE(pHorolog,",",2) // We multiply the AgeToAlert by 60 to convert the AgeToAlert to Seconds so we can use it easily with the HOROLOG. set pAgeToAlertSeconds = AgeToAlert*60 // At this point, we want to subtract the age to alert from the curent time in seconds. HOWEVER, we can't go negative without going back a day. // So, to get around this, I have attempted to bodge the checks. If the age to alert in seconds is greater that the // current time, we then go back to before midnight... I dunno, I'm just making this up and hoping it works. If pAgeToAlertSeconds>currenttime { Set currentdate = currentdate-1 Set timediff = pAgeToAlertSeconds-currenttime set adjustedtime = 86400-timediff } Else{ set adjustedtime = currenttime - pAgeToAlertSeconds } // We create the value "triggered" with the value of 0 now, so that we can check to see if we need to alert. set triggered = 0 // We then build a new Horolog by concatinating the currentdate and adjustedtime values // within the $zdt function. The $zdt function then converts the Horolog to a date/time // which can be used for comparing against the datemodified value of the files being checked. set BeforeThisDate = $zdt(currentdate_","_adjustedtime,3) // Gather the list of files in the specified directory set rs=##class(%ResultSet).%New("%File:FileSet") do rs.Execute(Directory,Extention,"DateModified") // Step through the files in DateModified order and compare their date modified // with the BeforeThisDate Value to see if any files are old enough to active the trigger while rs.Next() { set DateModified=rs.Get("DateModified") if BeforeThisDate]DateModified { // trigger the trigger set triggered = 1 } // Stop when we get to files with last modified dates on or after our fileage adjusted date to // avoid checking files that don't need to be checked at this time. if DateModified]BeforeThisDate set tSC = $$$OK } // Evaluate if trigger has been triggered if triggered = 1 { //Create and send an email Set newSMTP=##class(%Net.SMTP).%New() Set newSMTP.smtpserver=..SMTPServer Set newSMTP.port=..SMTPPort Set newAuthenticator=##class(%Net.Authenticator).%New() Set newAuthenticator.UserName=..SMTPUsername Set newAuthenticator.Password=..SMTPPassword Set newSMTP.authenticator=newAuthenticator Set newEmailMessage=##class(%Net.MailMessage).%New() Set EmailCount = $LENGTH(..Recipient,",") For i=1:1:EmailCount { Do newEmailMessage.To.Insert($PIECE(..Recipient,",",i)) } Set newEmailMessage.From="DoNotReply@imadethisemailupandlackcreativity.co.uk" Set newEmailMessage.Subject="Queue Building in folder:"_..MonitoredFolder #Dim MessageText Set MessageText = "<html><head><style>th#la {padding-left: 10px; padding-right:20px; padding-bottom:15px; text-align: left;}td#la {padding-left: 10px; padding-right:20px; padding-bottom:5px; text-align: left;}</style></head><body><table border=""0"" cellpadding=""0"" cellspacing=""0"" height=""100%"" width=""100%"" id=""bodyTable""><tr><td align=""center"" valign=""top""><table border=""0"" cellpadding=""20"" cellspacing=""0"" width=""1000"" id=""emailContainer""><tr><td align=""center"" valign=""top""><table border=""0"" cellpadding=""10"" cellspacing=""0"" width=""100%"" id=""emailHeader""><tr><td bgcolor=""#0072CE"" align=""center"" valign=""top"">" // This is the Header of the email. Set MessageText = MessageText _ "<h1 style=""color: #ffffff; ; font-size: 28px;"" >Queue Building in folder "_..MonitoredFolder_"</h1>" // This is the HTML for the start of the body which is built up within a table for structure Set MessageText = MessageText _ "</td></tr></table></td></tr><tr><td align=""center"" valign=""top""><table border=""0"" cellpadding=""20"" cellspacing=""0"" width=""100%"" id=""emailBody""><tr><td align=""left"" valign=""top"">" // This is the Body of the email. These lines can be repeated // as many times as needed to act as the lines of text in the email. Set MessageText = MessageText _ "<p style=""color: #153643; ; font-size: 18px;"">Files are queueing in the folder "_..MonitoredFolder_".</p>" // This line closes off the table secion created above Set MessageText = MessageText _ "</td></tr></table></td></tr><tr><td align=""center"" valign=""top""><table border=""0"" cellpadding=""10"" cellspacing=""0"" width=""100%"" id=""emailFooter""><tr><td bgcolor=""#0072CE"" align=""center"" valign=""top"">" // This is the Footer of the email Set MessageText = MessageText _ "<p style=""color: #ffffff; ; font-size: 12px;"">This email was generated automatically by xyz corp.</p>" // This is the end of the HTML. Set MessageText = MessageText _ "</td></tr></table></td></tr></table></td></tr></table></body></html>" Set newEmailMessage.IsHTML = 1 Do newEmailMessage.TextData.Write(MessageText) ///Send the Email Set tSC=newSMTP.Send(newEmailMessage) Quit tSC } else{ Quit tSC } } }
go to post Julian Matthews · Feb 4, 2020 Hi Joao. I have a task that runs every x mins to check a folder for files older than y mins, and it then sends an alert to Ens.Alert to then trigger an alert to our team. The logic is, if the file has been sat in the folder for more than the defined period, it is effectively "queued". However, as I went to dig it out, I have realised I made a mistake with subtracting the seconds from the Horolog near midnight... I'll try clean it up, and then see if it safe to submit here :)
go to post Julian Matthews · Dec 30, 2019 All the documentation I have read advises against recompiling like that: "You could also use the $SYSTEM.OBJ.CompileAllNamespaces() method to recompile all namespaces, but you should not do this when upgrading a HealthShare installation. You should not recompile a namespace used for HealthShare." Were any errors returned when you ran this? It might be worth checking with WRC to see if there's anything they can advise on?
go to post Julian Matthews · Dec 30, 2019 Have you tried rebooting the machine running healthshare? Did you complete any post upgrade tasks like recompiling custom classes?
go to post Julian Matthews · Nov 21, 2019 Hi Steve. The main reason is that I'm trying to reduce the footprint within our Ensemble/interoperability production. However, I'm not too proud to rule it out if I am stuck for other options.
go to post Julian Matthews · Sep 6, 2019 Doesn't answer your question, but I use Winmerge with some tweaks to the settings to make the highlighting a little nicer:http://forums.winmerge.org/viewtopic.php?f=4&t=1040If I need to compare 1000s of messages from two sets of transforms, I then point their outbound to a single fileout (or since I upgraded to 2019.1, using the export) and then compare the two files.
go to post Julian Matthews · Aug 29, 2019 That is actually quite impressive - thanks @Evgeny Shvarov (and @Nikita.Savchenko for the tool itself)
go to post Julian Matthews · Aug 29, 2019 Just to add to this - in a real world situation, you would be accessing the terminal from the cube menu as described by Robert. I think this is something created by Intersystems to facilitate the online learning.
go to post Julian Matthews · Aug 29, 2019 Hi Marta.I just took a look at the course to see what was what, and on the lab site generated, there is a link for the terminal on the home page:This then prompts you to log in with the credentials provided when you first created the lab session, and you end up with an oversized terminal window the size of your browser
go to post Julian Matthews · Aug 29, 2019 Hi Vandrei.Have a look at the learning site: https://learning.intersystems.comHere you will find learning paths for what you want such as Building Your First Application with Caché and Learn Caché for Developers.There is also classroom training that can be arranged with Intersystems, but it might be good to give yourself exposure with the above before considering such courses.
go to post Julian Matthews · Aug 28, 2019 It might be unrelated, but I recently had a similar issue when installing healthconnect on a windows 10 machine with Kaspersky Endpoint Security.Kaspersky was being triggered by some temp files created by the installer, and placing them in quarantine. This was then leaving the installer showing it had completed, but with the progress bar still showing. I never did leave it for as long as you did to then get the error you didn't save.The weird thing was that Kaspersky only reported a virus with the installer on specific versions of Windows 10.I ended up submitting the installer to Kaspersky so that they could white list it. Long story short, check the reports section within Kaspersky and see if it interfered with your install.
go to post Julian Matthews · Aug 21, 2019 I did consider going the oldschool route, but your guidance above worked perfectly for me
go to post Julian Matthews · Aug 21, 2019 This looks really good!Any idea how I'd be able to use this in a non-docker environment?
go to post Julian Matthews · Aug 19, 2019 Hi David.I raised this with WRC following my recent upgrade to IRIS, and the reason given was that the auto-refresh interferes with a new feature that logs out inactive users.What you need to do (in a Terminal session) is set a global as follows:>set ^%SYS("Portal","EnableAutoRefresh")=1
go to post Julian Matthews · Aug 8, 2019 I have a task that deletes txt files older than x number of days: Class PROD.Schedule.PurgeTxtFiles Extends %SYS.Task.Definition { Parameter TaskName = "Purge TXT Files"; Property Directory As %String; Property Daystokeep As %Integer(VALUELIST = ",5,10,15,20,25,30,35,40,45,50,55,60") [ InitialExpression = "30" ]; Method OnTask() As %Status { Set tsc = ..PurgeSentFolder(..Directory,..Daystokeep,"txt") Quit tsc } Method PurgeSentFolder(Directory As %String, DaysToKeep As %Integer, Extention As %String) As %Status { // Calculate the oldest date to keep files on or after set BeforeThisDate = $zdt($h-DaysToKeep_",0",3) // Gather the list of files in the specified directory set rs=##class(%ResultSet).%New("%File:FileSet") Set ext = "*."_Extention do rs.Execute(Directory,ext,"DateModified") // Step through the files in DateModified order while rs.Next() { set DateModified=rs.Get("DateModified") if BeforeThisDate]DateModified { // Delete the file set Name=rs.Get("Name") do ##class(%File).Delete(Name) } // Stop when we get to files with last modified dates on or after our delete date if DateModified]BeforeThisDate set tSC = 1 } quit tSC } } Hopefully you can make this work for your needs
go to post Julian Matthews · Aug 5, 2019 Thanks Jeff, that's a better articulation of what I originally tried to say.
go to post Julian Matthews · Aug 1, 2019 Personally, I would use a DTL which removes the EVN, and then I would call the DTL class from objectscript:Set tSC=$CLASSMETHOD("DEV.Transformations.DUMMY.A01toA01","Transform",request,.messageWithoutEVN)So, "Transform" in quotes is the action, request is your original Enslib.HL7.Message coming in, and .messageWithoutEVN is the output from your DTL.Does that help?
go to post Julian Matthews · Jul 31, 2019 The method RemoveSegmentAt returns a status, not the message with the segment removed.So your HL7 message with the EVN removed is still "newreq" and it is this that you want to pass on.