Limpiar filtro
Artículo
Nancy Martínez · 30 mayo, 2022
Estoy seguro de que os habéis encontrado esta situación:
Hay un bug en un sistema que no puedes reproducir por ti mismo localmente
Necesitas ejecutar unas pocas líneas en la instancia afectada
Tienes acceso completo al Portal de Gestión
Pero no hay terminal, ni consola, ni acceso con Studio, Atelier o VSCode
¿Cómo ejecutar tus pocas líneas para probar???
Entra en Portal de Gestión / Explorador / SQL= Ejecutar consulta
Ahora crea un Stored Procedure con cualquier código que necesites
No hay límite de complejidad. Yo simplemente hago uno sencillo con un resultado predecible.
CREATE PROCEDURE RUN.ISOS()
LANGUAGE OBJECTSCRIPT
{
For i=1:1:20 write i," > "
Write "<br>THANKS !"
}
Haz clic en EJECUTAR y observa un nuevo Procedimiento
Después, examina este Procedimiento reciente y ejecútalo
Otra ejecución lo activa
y este es el resultado
y como especialista bien educado, limpia tu entorno cuando acabes
DROP PROCEDURE RUN.ISOS
¡Espero que os resulte útil en algún momento!
Documentación
Este artículo ha sido etiquetado como "Mejores prácticas" ("Best practices").
Los artículos con la etiqueta "Mejores prácticas" incluyen recomendaciones sobre cómo desarrollar, probar, implementar y administrar mejor las soluciones de InterSystems.
Anuncio
Esther Sanchez · 24 jun, 2022
Como sabéis, hay una etiqueta llamada "Mejores Prácticas", que se utiliza para destacar artículos de la Comunidad de Desarrolladores que incluyen recomendaciones sobre cómo desarrollar, probar, implementar y administrar mejor las soluciones de InterSystems. Cada 1-2 semanas los expertos de la companía eligen un nuevo artículo.
Hasta ahora, solo tienen dicha etiqueta artículos originales en inglés o artículos en español traducidos al inglés. La buena noticia es que ya podéis proponer artículos en español para que sean evaluados, aunque no estén traducidos al inglés.
¿Cómo podéis proponer un artículo?
Tenéis que acceder a este reto en Global Masters y poner el enlace al artículo que queréis que sea evaluado para incluir la etiqueta "Mejores Prácticas". También tenéis que incluir un breve comentario que explique por qué habéis elegido ese artículo.
Notas:
Puede ser un artículo propio o de otra persona
Aseguraos de que el artículo no tenga ya la etiqueta "Mejores Prácticas"
Podéis proponer hasta 5 artículos en este reto
Y además... ¡obtendréis 25 puntos en Global Masters solo por completar el reto! 🎉
¡Animaos! Seguro que hay más de un artículo en español que merece llevar la etiqueta "Mejores Prácticas".
Anuncio
Esther Sanchez · 18 nov, 2022
¡Hola desarrolladores!
Fue un auténtico placer encontrarnos en persona en el 1er Encuentro de la Comunidad de Desarrolladores. ¡Y fue un honor ver la sala llena! Lo pasamos muy bien y aprendimos muchas cosas. ¡Y os echamos de menos a todos los que no pudisteis venir!
Muchísimas gracias a todos los que estuvisteis y especialmente a nuestros amigos de Roche Diagnostics y Arisnova por las presentaciones tan interesantes que hicieron.
Gracias también a @Anastasia.Dyubaylo y @Evgeny.Shvarov por acompañarnos.
¡Y enhorabuena a Mario del Pozo, por su premio en el Kahoot! 👏
¡Estamos deseando volver a veros!
Algunas fotos del evento ⬇️
Yo creo que en el Kahoot hubo hasta codazos!! La verdad es que estuvo genial poder compartir experiencias y sobre todo vernos después de casi 3 años... y las exposiciones super interesantes... personalmente me quedé con ganas de más... y los que exponían ya ni hablamos (David Cano y Carlos Fernández de Roche y Florencio López y Mario del Pozo por Arisnova)... yo creo que si no los paran aún seguían. Estuvo genial. A ver si repetimos. Gran encuentro, la verdad es que va muy bien ver ejemplos de como la gente utiliza la tecnología Intersystems y sobretodo de sectores diferentes, casi tendremos que hacer un summit paralelo solo para desarrolladores, lanzo la idea ;-)
Anuncio
David Reche · 27 mar, 2023
InterSystems anuncia la Versión de Mantenimiento (Maintenance Release, MR) 2018.1.8 de Caché, Ensemble y HSAP. Es una versión de mantenimiento con muchas actualizaciones en una gran variedad de áreas.
Caché y Ensemble
Los kits completos de instalación de producto se pueden descargar de la página de distribución de software del Centro de Soporte Internacional (WRC):
Caché
Ensemble
Para más información sobre las correcciones en esta versión, consultad las Notas de Cambios de la Versión. La documentación de Caché y Ensemble incluye dichas Notas, así como el documento de Plataformas Soportadas, la Referencia de Clase y una completo conjunto de guías, referencias, tutoriales y artículos.
El número de compilación de esta versión es 2018.1.8.766.0.
HSAP
Esta versión de HealthShare Health Connect (HSAP) se basa en tecnología core versión 2018.1.5.659.0 con el siguiente módulo HealthShare:
Core: 15.032.9077
Los kits completos de instalación de producto se pueden descargar de la página de distribución de software del Centro de Soporte Internacional (clic aquí).
El número de versión de los kits de HealthShare Health Connect para esta versión es 2018.1.8HS.9077.0.
--> Nota: usa el campo "Maint/Core Ver" en la parte superior de la tabla e introduce "2018.1.8" para ver todos los kits disponibles.
Pregunta
Yone Moreno · 9 mayo, 2023
Buenos días,
Antes que nada agradecer el tiempo de ustedes al leer, reflexionar y sobre todo responder y aclarar las dudas.
Tenemos una cuestión:
¿Cuál es la forma recomendada de convertir un Objeto de Ensemble a JSON?,
en concreto, para ser más preciso:
¿cuál es la manera idónea de transformar un Mensaje Response con cualquier tipo de Property: %String, %List of String, otros objetos de Ensemble (EsquemasDatos); a un GlobalCharacterStream que represente al JSON? a retornar a Sistema Origen, desde el Servicio.
Porque en el equipo, a lo que estamos acostumbrados en los Servicios REST es a emplear el:
set claseAux = ##class(%ZEN.Auxiliary.jsonProvider).%New()
[...]
set tSC = claseAux.%WriteJSONStreamFromObject(.pOutput,.objetoSalida,,,,"aeloqtuw")
Set pOutput=##class(%GlobalBinaryStream).%New()
set claseAux = ##class(%ZEN.Auxiliary.jsonProvider).%New()
//Sacamos el body
set body = pInput.Read()
//Lo convertimos a Mensaje
set tSC= claseAux.%ConvertJSONToObject(.body,"Mensajes.Request.miFormacion.LoginRequest",.objetoEntrada,1)
//Enviamos al Proceso
set tSC = ..SendRequestSync("miFormacionv01r00",objetoEntrada,.objetoSalida)
//Convertimos el OBJETO devuelto por el Proceso en JSON
#dim objetoSalida As Mensajes.Response.miFormacion.LoginResponse
set tSC = claseAux.%WriteJSONStreamFromObject(.pOutput,.objetoSalida,,,,"aeloqtuw")
//Enviamos el JSON con cabeceras
Do:$$$ISOK(tSC) pOutput.SetAttribute("Content-Type","application/json")
do pOutput.SetAttribute("Access-Control-Allow-Origin","*")
do pOutput.SetAttribute("Access-Control-Allow-Credentials","true")
do pOutput.SetAttribute("Access-Control-Allow-Methods","GET")
do pOutput.SetAttribute("Access-Control-Allow-Headers","request,Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers")
Quit tSC
Sin embargo ¿cuál es la manera recomendada por ustedes desde InterSystems para realizar esta conversión?
De nuevo; gracias por el tiempo de ustedes al leer, reflexionar y sobre todo responder y aclarar las dudas.
Un saludo. Hola Yone! Justamente han preguntado algo parecido en la comunidad en inglés, te copio el hilo:
https://community.intersystems.com/post/creating-json-objects-objectscript-objects Gracias Luis Ángel Pérez.
En el hilo, se explican 3 formas de convertir Objeto a JSON, ahora bien; ¿cuál de las 3 es la recomendada por Intersystems, la preferible y/o estándar y por qué?
Eduard Lebedyuk expone 2 alternativas:
1º Utilizar la clase "result set" para contener los resultados:
Para utilizar esta opción, se debe crear una clase que extienda de %RegisteredObject y %JSON.Adaptor que tenga propiedades para contar los resultados (count) y una lista de los mismos (results). Por ejemplo:
Class Test.JSONRS Extends (%RegisteredObject, %JSON.Adaptor)
{
Property count As %Integer;
Property results As list Of Book;
}
Luego, se puede convertir un objeto normal a un objeto dinámico y asignarlo a la propiedad results de la clase Test.JSONRS utilizando la función %ObjectToAET:
set dynObj = ##class(%ZEN.Auxiliary.altJSONProvider).%ObjectToAET(obj)
set resultSet = ##class(Test.JSONRS).%New()
set resultSet.count = <cantidad de resultados>
set resultSet.results = dynObj
set jsonString = resultSet.%ToJSON()
2º Utilizar un enfoque más simple:
En esta opción, se genera el JSON directamente utilizando la función %JSONExport para cada objeto y concatenando los resultados. Por ejemplo:
set jsonString = {"results": <cantidad de resultados>, "items": [
##class(%JSON.Adaptor).%JSONExport(obj1)_", "_##class(%JSON.Adaptor).%JSONExport(obj2)_", "_...]}
Este enfoque es más simple pero puede ser menos eficiente en términos de uso de memoria y tiempo de ejecución. Sin embargo, puede ser más adecuado para casos en los que se trabaja con un pequeño número de objetos.
Por otro lado, Muni Ganesh explica esta 3ª vía:
Emplear la función "%ToJSON()" para convertir el objeto "MainObj" a formato JSON y se imprime el resultado.
set array=[]
set obj = {}
set obj.title="For Whom the Bell Tolls"
set obj.author="Hemmingway"
do array.%Push(obj)
set obj = {}
set obj.title="The Invisible Man"
set obj.author="Ellison"
do array.%Push(obj)
set obj = {}
set obj.title="Tender is the Night"
set obj.author="Fitzgerald"
do array.%Push(obj)
set arraylen=0
set iter = array.%GetIterator()
while iter.%GetNext() {
set arraylen=$I(arraylen)
}
set MainObj={}
set MainObj.results=arraylen
set MainObj.items=array
w MainObj.%ToJSON()
----------------------------------------------------------------------------------------------------------------
Output:
{"results":3,"items":[{"title":"For Whom the Bell Tolls","author":"Hemmingway"},{"title":"The Invisible Man","author":"Ellison"},{"title":"Tender is the Night","author":"Fitzgerald"}]}
--------------------------------------------------------------------------------------------------------------------
Desarrollando una integración en el ámbito de la interoperabilidad sanitaria, en un Servicio REST ¿cuál es la forma aconsejada por ustedes en Intersystems para convertir Objeto a JSON?
¿Cuál de las 3 es la recomendada por Intersystems, la preferible y/o estándar y por qué?
Gracias, muchas gracias por leer y responder, un saludo. Personalmente siempre he usado la de %JSONExport para transformar el JSON de una llamada REST por su sencillez de uso, pero es más una opinión personal.
Anuncio
David Reche · 2 mar, 2020
Desde marzo de 2020, Microsoft planea lanzar una serie de actualizaciones de seguridad que harán que los servidores Active Directory (AD) de Windows rechacen vínculos de canales no cifrados. Para más detalles de los cambios en Active Directory, pueden consultar el aviso de seguridad de Microsoft: ADV190023.
Las instancias de todos los productos de InterSystems que utilizan LDAP con los servidores Windows AD para el acceso de usuarios, pueden verse afectadas si no están configuradas correctamente para usar TLS/SSL. No solo las instancias ejecutándose en los servidores de Windows pueden verse afectadas. El riesgo potencial existe tanto para instancias que realizan la autenticación LDAP directamente como a través del mecanismo de Autenticación Delegada.
En base a las pruebas de InterSystems usando servidores AD actualizados con las políticas de seguridad estándar, se recomienda configurar todas las conexiones LDAP AD para utilizar TLS/SSL antes de aplicar los pertinentes parches de Microsoft a los servidores AD. Consulten la nota al final de este aviso para obtener ayuda en la configuración.
Además, antes de actualizar cualquier servidor AD, se debe instalar el parche CVE-2017-8563de Microsoft en todos los servidores Windows que conectan con estos servidores AD. Si no, los servidores AD rechazarán las conexiones desde los servidores de Windows, incluso si usan TLS/SSL.
Para cualquier pregunta relacionada con este aviso, contacten por favor con el Centro de Soporte Internacional.
Nota sobre configuración:
Si estas usando configuraciones LDAP, selecciona el checkbox de Use TLS/SSL encryption for LDAP sessions, tal y como se describe en el capitulo “Using LDAP” de la Security Administration Guide.
Si usas la clase %SYS.LDAP, invoca el método StartTLSs(), tal y como se describe en la documentación Class Reference Documentation. Los métodos Init() y SetOption() son también relevantes.
Tanto las Configuraciones LDAP como la clase %SYS.LDAP deben disponer de todos los certificados necesarios para validar el servidor de AD utilizado en la negociación TLS, incluyendo el Certificado raiz de la Autoridad de Certificación y cualquier certificado intermedio. Contacta con tu administrador de Windows Active Directory para obtener una copia the los certificados requeridos. Instala los mismos según:
Para clientes Windows, en el almacén de certificados local del computador Windows local
Para clientes no-Windows, en un fichero accesible por la instancia en formato PEM. Si exportas el certificado desde Windows utilizando el Certificate Export Wizard, el formato correcto es el denominado "Base-64 encoded X.509".
para más información acerca de localización de certificados, mira el capitulo “Using LDAP” de la Security Administration Guide
Artículo
Ricardo Paiva · 9 jul, 2021
Hola todos,
Quiero compartir un sencillo y rápido método que puede usarse para habilitar ssl con un certificado auto-firmado en una instancia de desarrollo local de IRIS/HealthShare. Esto permite probar funciones específicas de https, como OAuth.
1. Instalar OpenSSL
Windows: https://slproweb.com/download/Win64OpenSSL_Light-1_1_1g.exe
Debian Linux: $ sudo apt-get -y install openssl
RHEL: $ sudo yum install openssl
2. Crear un par de certificados auto-firmados. En tu terminal (powershell, bash, zsh, etc.)
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout apache-selfsigned.key -out apache-selfsigned.crt
Nota: este comando anterior creará un certificado que durará un año.
3. Editar el servidor web privado para utilizar el nuevo par de certificados auto-firmados
En el directorio de instalación de tu instancia, edita tu configuración de pws <install-dir>/httpd/conf/httpd-local.conf. Añade la siguiente sección antes de las directivas "Incluir ...".
# Port to listen for secure traffic On. The default is 443
LoadModule ssl_module "modules/mod_ssl.so"
Listen 10443
# Listen Virtual Host Block to define the keys we should use for that port
# If you define a different port in the Listen directive, change that here as well
<VirtualHost *:10443>
# We need a servername, it has not effect but is required by apache
ServerName mysecureinstance
# Turn on SSL for this Virtual Host
SSLEngine on
#key files, replace these paths with the path you generated the keys from in step 2.
SSLCertificateFile "/path/to/apache-selfsigned.crt"
SSLCertificateKeyFile "/path/to/apache-selfsigned.key"
</VirtualHost>
Este es un ejemplo de mi archivo de configuración:
En ejecución:
Nota: InterSystems no soporta este tipo de configuración HTTPS y, si necesitas un producto de producción, debes seguir las instrucciones para instalar apache2/IIS/nginx de manera completa. Este artículo está etiquetado como "Mejores prácticas" ("Best practices")
(Los artículos con la etiqueta "Mejores prácticas" incluyen recomendaciones sobre cómo desarrollar, probar, implementar y administrar mejor las soluciones de InterSystems).
Artículo
Jose-Tomas Salvador · 1 mayo, 2020
Era el momento del InterSystems hackathon y nuestro equipo, Artem Viznyuk y Eduard Lebedyuk tenian una placa Arduino (one) y varios componentes (de sobra). Así que su curso de acción estaba marcado - como todos los aprendices de Arduino, decidieron construir una estación meteorológica. Voy a aprovechar este artículo para seguir sus pasos y hacer lo mismo que ellos hicieron en 2016, pero con la persistencia de datos en IRIS y la visualización en Business Intelligence (antiguo DeepSee)! (Digamos que además de hacer la traducción del artículo original, aprovecho y nos actualizamos todos ;-) )
Trabajar con dispositivos
InterSystems IRIS puede trabajar directamente con muchos tipos de dispositivos físicos y lógicos:
Terminal
TCP
Al Spooler
Impresoras
Cinta magnética
Puertos COM
y muchos otros
Puesto que Arduino utilizar el puerto COM para las comunicaciones, tenemos todo lo que necesitamos.Generalmente, trabajar con dispositivos puede dividirse en 5 pasos:
Comando OPEN para registrar el dispositivo con el proceso actual y acceder
Comando USE para hacer que sea el primario
Hacer algún trabajo. READ para recibir datos de un dispositivo, y WRITE para enviar datos
USE de nuevo para conmutar el dispositivo primario
Comando CLOSE para liberar el dispositivo
Bien, esa es la teoría, ¿cómo es en la práctica?
Un parpadeo desde InterSystems IRIS
Primeramente, construimos un dispositivo con Arduino que lee un número del puerto COM y enciende un led durante unos milisegundos.
Circuito:
C code (for Arduino)
/* Led.ino
* Receive data on a COM port
* Connect your led to ledPin
*/
// Pin, to connect your led
#define ledpin 8
// Received data buffer
String inString = "";
// Execute once at the beginning
void setup() {
Serial.begin(9600);
pinMode(ledpin, OUTPUT);
digitalWrite(ledpin, LOW);
}
// Execute indefinetly
void loop() {
// Get data from com
while (Serial.available() > 0) {
int inChar = Serial.read();
if (isDigit(inChar)) {
// one character at a time
// and append it to data buffer
inString += (char)inChar;
}
// Encounter new line
if (inChar == '\n') {
// Power on the led
digitalWrite(ledpin, HIGH);
// be aware: toInt() converts a string that starts with a number to number...
int time = inString.toInt();
delay(time);
digitalWrite(ledpin, LOW);
// Flush the buffer
inString = "";
}
}
}
Y por último un método en InterSystems IRIS que envía el string 1000\n (acabado en nueva línea) al puerto COM:
/// Send 1000\n to a com port
ClassMethod SendSerial()
{
// Pon el puerto que te haya asignado el sistema a tu Arduino
set port = "COM3"
open port:(:::" 0801n0":/BAUD=9600) // Open device
set old = $IO // Record current primary device
use port // Switch to com port
write $Char(10) // Send some test data
hang 1
write 1000 _ $Char(10) // Send 1000\n
use old // Back to old terminal
close port // Free the device
}
«0801n0» es una cadena con parámetros para acceder al puerto COM, tal y como se describe en la documentación (busca portstate cuando estés en la página). Y /BAUD=9600 es, por supuesto, la velocidad de conexión.
Si ejecutamos este método en un terminal:
do ##class(Arduino.Habr).SendSerial()
No devolverá nada, pero un led parpadeará por un segundo.
Recepción de datos
Ahora vamos a conectar un keypad a InterSystems IRIS y recibir datos de entrada. Esto podría utilizarse para autenticar a un usuario con autenticación delegada, implementando también la rutina ZAUTHENTICATE.mac.
Circuito:
C code
/* Keypadtest.ino *
* Uses Keypad library,
* Connect Keypad to Arduino pins
* as specified in rowPins[] and colPins[].
*
*/
// Repository:
// https://github.com/Chris--A/Keypad
#include <Keypad.h>
const byte ROWS = 4; // Four rows
const byte COLS = 4; // Three columns
// Map symbols to keys
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
// Connect keypad pins 1-8 (up-down) to Arduino pins 11-4: 1->11, 2->10, ... , 8->4
// Connect keypad ROW0, ROW1, ROW2 и ROW3 to this Arduino pins
byte rowPins[ROWS] = { 7, 6, 5, 4 };
// Connect keypad COL0, COL1 and COL2 to this Arduino pins
byte colPins[COLS] = { 8, 9, 10, 11 };
// Keypad initialization
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup() {
Serial.begin(9600);
}
void loop() {
char key = kpd.getKey(); // Receive key pressed
if(key)
{
switch (key)
{
case '#':
Serial.println();
default:
Serial.print(key);
}
}
}
Y aquí tenemos un método en InterSystems IRIS utilizado para recoger los datos desde un puerto COM, una línea cada vez:
/// Receive one line till we encounter line terminator from COM1
ClassMethod ReceiveOneLine() As %String
{
set port = "COM3"
set str=""
try {
open port:(:::" 0801n0":/BAUD=9600)
set old = $io
use port
read str // Read till we encounter line terminator
use old
close port
} catch ex {
close port
}
return str
}
Lo ejecutamos en un terminal:
write ##class(Arduino.Habr).ReceiveOneLine()
Y se quedará esperando recibiendo datos de entrada hasta que se presione # (que sería enviado como un terminador de línea), tras lo cual los datos introducidos se mostrarán en el terminal.
Esto era la I/O básica Arduino-IRIS, y ahora ya estamos preparados para construir nuestra propia estación meteorológica.
Estación Meteorológica
¡Finalmente estamos llegando a la estación meteorológica! Utilizamos un fotoresistor y un sensor de Humedad y Temperatura DHT11 para obtener los datos.
Circuito:
C code
/* Meteo.ino *
* Register humidity, temperature and light level
* And send them to a COM port
* Output sample: H=1.0;T=1.0;LL=1;
*/
// Photoresistor pin (analog)
int lightPin = 0;
// DHT-11 pin (digital)
int DHpin = 8;
// Array to store DHT-11 temporary data
byte dat[5];
void setup() {
Serial.begin(9600);
pinMode(DHpin,OUTPUT);
}
void loop() {
delay(1000); // measure everything once per second
int lightLevel = analogRead(lightPin); //Get brightness level
temp_hum(); // Get temperature and humidity into dat variable
// And output the result
Serial.print("H=");
Serial.print(dat[0], DEC);
Serial.print('.');
Serial.print(dat[1],DEC);
Serial.print(";T=");
Serial.print(dat[2], DEC);
Serial.print('.');
Serial.print(dat[3],DEC);
Serial.print(";LL=");
Serial.print(lightLevel);
Serial.println(";");
}
// Get DHT-11 data into dat
void temp_hum() {
digitalWrite(DHpin,LOW);
delay(30);
digitalWrite(DHpin,HIGH);
delayMicroseconds(40);
pinMode(DHpin,INPUT);
while(digitalRead(DHpin) == HIGH);
delayMicroseconds(80);
if(digitalRead(DHpin) == LOW);
delayMicroseconds(80);
for(int i=0;i<4;i++)
{
dat[i] = read_data();
}
pinMode(DHpin,OUTPUT);
digitalWrite(DHpin,HIGH);
}
// Get a chunk of data from DHT-11
byte read_data() {
byte data;
for(int i=0; i<8; i++)
{
if(digitalRead(DHpin) == LOW)
{
while(digitalRead(DHpin) == LOW);
delayMicroseconds(30);
if(digitalRead(DHpin) == HIGH)
{
data |= (1<<(7-i));
}
while(digitalRead(DHpin) == HIGH);
}
}
return data;
}
Una vez que hemos cargado este código en Arduino, va a comenzar a enviar datos desde el puerto COM con el siguiente formato:
H=34.0;T=24.0;LL=605;
Donde:
H — humedad (de 0 al 100 por ciento)
T — temperatura (grados Celsius)
LL — Luminosidad (de 0 a 1023)
Vamos a almacenar estos datos en InterSystems IRIS. Para eso, escribimos una nueva clase Arduino.Info:
Class Arduino.Info Extends %Persistent
{
/// Puerto COM asociado - cambialo según tu sistema
Parameter SerialPort As %String = "com3";
Property DateTime As %DateTime;
Property Temperature As %Double;
Property Humidity As %Double(MAXVAL = 100, MINVAL = 0);
Property Brightness As %Double(MAXVAL = 100, MINVAL = 0);
Property Volume As %Double(MAXVAL = 100, MINVAL = 0);
ClassMethod AddNew(Temperature = 0, Humidity = 0, Brightness = 0, Volume = 0)
{
set obj = ..%New()
set obj.DateTime=$ZDT($H,3,1)
set obj.Temperature=Temperature
set obj.Humidity=Humidity
set obj.Brightness=Brightness/1023*100
set obj.Volume=Volume
write $SYSTEM.Status.DisplayError(obj.%Save())
}
Despues, escribimos un método que recibirá los datos desde Arduino y los transformará en objetos de tipo Arduino.Info:
/// Receive a RAW data in this format: H=34.0;T=24.0;LL=605;\n
/// Convert into Arduino.Info objects
ClassMethod ReceiveSerial(port = {..#SerialPort})
{
try {
open port:(:::" 0801n0":/BAUD=9600)
set old = $IO
use port
for {
read x //read one line
if (x '= "") {
set Humidity = $Piece($Piece(x,";",1),"=",2)
set Temperature = $Piece($Piece(x,";",2),"=",2)
set Brightness = $Piece($Piece(x,";",3),"=",2)
do ..AddNew(Temperature,Humidity,Brightness) // Add data
}
}
} catch anyError {
close port
}
}
Y finalmente conectamos Arduino y ejecutamos el método ReceiveSerial:
write ##class(Arduino.Info).ReceiveSerial()
Este método recibirá y almacenrá datos desde Arduino ininterrumpidamente.
Visualización de Datos
Tras construir nuestro dispositivo lo podemos poner fuera por ejemplo, para recoger datos durante una noche:
Al llegar la mañana tendremos miles de registros (en este caso más de 36.000), que podemos visualizar con las herramientas de Business Analytics utilizando por ejemplo herramientas disponibles en Open Exchange como el API REST de servidor MDX2JSON y el generador de cuadros de mando DeepSeeWeb , y aquí tenéis una muestra de los resultados:
Niveles de Luminosidad. En esta serie de datos la salida del Sol es claramente visible alrededor de las 5:50:
Gráficos de temperatura y humedad:La correlación negativa entre la humedad y la temperatura es claramente visible.
Conclusión
Con InterSystems IRIS puedes comunicar directamente con una gran cantidad de dispositivos diferentes. Puedes desarrollar muy rápidamente tanto tus soluciones para procesamiento de datos como de visualización - a nuestro equipo le llevó sobre 4 horas construir nuestra propia estación meteorológica, conectarla a IRIS y visualizar los resultados y la mayor parte del tiempo se empleó en el diseño del circuito y en escribir y ajustar el código C.
Links
» Documentation» GitHub - Repositorio del proyecto Original de Eduard Lebedyuk
Pregunta
Yone Moreno · 10 mar, 2022
Hola ¿cómo están?
Estamos indagando cómo recuperar datos mediante una Operación: EnsLib.DICOM.Operation.TCP
Hemos configurado en: Ensemble > Configuración de DICOM > Configuración de DICOM
Las configuraciones de contexto como:
ESBPRE > VNAPRE
VNAPRE > ESBPRE
Siendo para ambas los Contextos de Presentación, los por defecto:
Lo cual hemos generado mediante el código encontrado en el ejemplo del "Namespace: ENSDEMO", el cual hemos incluido en el OnStart() de la Producción:
/// Override this in your Production class to do setup before the Production starts
ClassMethod OnStart(pTimeStarted As %String) As %Status
{
#; Make sure that the associations exist
If '##class(EnsLib.DICOM.Util.AssociationContext).AETExists("ESBPRE","VNAPRE")
{
Do ##class(EnsLib.DICOM.Util.AssociationContext).CreateAssociation("ESBPRE","VNAPRE",$ListBuild($$$IMPLICITVRLETRANSFERSYNTAX))
}
If '##class(EnsLib.DICOM.Util.AssociationContext).AETExists("VNAPRE","ESBPRE")
{
Do ##class(EnsLib.DICOM.Util.AssociationContext).CreateAssociation("VNAPRE","ESBPRE",$ListBuild($$$IMPLICITVRLETRANSFERSYNTAX))
}
If '##class(EnsLib.DICOM.Util.AssociationContext).AETExists("JD-SCU","ENS-SCP")
{
Do ##class(EnsLib.DICOM.Util.AssociationContext).CreateAssociation("JD-SCU","ENS-SCP",$ListBuild($$$IMPLICITVRLETRANSFERSYNTAX))
}
If '##class(EnsLib.DICOM.Util.AssociationContext).AETExists("ENS-SCU","JD-SCP")
{
Do ##class(EnsLib.DICOM.Util.AssociationContext).CreateAssociation("ENS-SCU","JD-SCP",$ListBuild($$$IMPLICITVRLETRANSFERSYNTAX))
}
Quit $$$OK
}
El reto, desafío al cual necesitamos acudir a ustedes para que nos apoyen, guíen, orienten, indiquen, informen, aconsejen, de cómo proceder es el siguiente:
Probamos la Operación de forma directa desde la Producción Web > Acciones > Prueba > ( Rellenamos los datos )
Al acceder a la traza nos encontramos el siguiente hándicap, reto, desafío, al cual necesitamos su auxilio, apoyo, indicaciones para depurarlo, solventarlo y corregirlo:
ERROR <EnsDICOM>NoActiveAssociation: No hay asociación activa para Calling-AET 'ESBPRE y Called-AET 'VNAPRE'
Siendo la visual:
¿Cómo podríamos reparar🔧, depurar 🐞⌨️, entender y solventar este desafío o reto?
Gracias por su lectura y respuestas
🔎 Hemos leido:
https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=EDICOM_intro#EDICOM_intro_samples
https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=EDICOM_storage_production
https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=EDICOM_associations#EDICOM_associations_import
https://github.com/intersystems-ib/iris-dicom-sample
https://github.com/dcm4che/dcm4che
Cualquier enlace a la documentación 📄, explicación detallada, paso a paso, o instrucciones para juntos indagar, investigar, atender este misterio, son bienvenidos 🙏.
Necesitamos su apoyo, aporte, axilio y respuestas, puesto que es algo bastante distinto a lo habitual y necesitamos mucha orientación, apoyo, y guía 🧭 con esta construcción. 🏗
Gracias 🙇♂️💭
Hola Yone,
Me parece que estás intentado hacer una prueba de envío DICOM por TCP desde Producción > Acciones > Prueba.
Ese tipo de pruebas pueden servirte para casos más sencillos pero no para enviar un mensaje DICOM, que es un poco más complejo.
Si tienes el namespace ENSDEMO, encontrarás ejemplos de producciones que usan ficheros DICOM. Te pueden servir de punto de partida.
Si estás interesado en envío DICOM a través de TCP, necesitarás contar con un simulador. Te paso un ejemplo que utiliza interoperabilidad de IRIS y un simulador (dcm4che). Puedes seguirlo paso a paso: https://github.com/intersystems-ib/iris-dicom-sample
Échale un vistazo, si no consigues avanzar o tienes dudas podemos buscar un hueco la próxima semana y lo comentamos.
Hola Alberto,
Gracias por responder y explicar
Una duda:
¿el uso de las herramientas que comentas es posible para la version HS2017?
¿cual es la versión mínima IRIS para ello?
Lo preguntamos por dos motivos:
Primero: estamos desarollando en:
"" Cache for UNIX (Red Hat Enterprise Linux for x86-64) 2017.2.1 (Build 801_3_18358U) Tue Jul 24 2018 16:36:10 EDT""
Segundo: se presenta el reto o desafío de emplear el simulador para probar DICOM dcm4che
Gracias por responder Hola Yone,
Sí, puedes utilizar HS2017 para implementar integraciones con DICOM.
El ejemplo que te pasé está implementado en IRIS, pero puedes hacer lo mismo en HS2017.
En cuanto al simulador, puedes utilizar el que quieres. Yo he utilizado dcm4che en el ejemplo porque puedes utilizarlo desde línea de comandos en Linux. En el propio ejemplo está incluido cómo hacer algunas llamadas simples para enviar mensajes a través de DICOM TCP. Hola Alberto,
gracias por responder, porque es un apoyo, alivio, auxilio y aporte tus indicaciones, instrucciones y ejemplos
Siguiendo tus indicaciones ubicadas en el ejemplo: https://github.com/intersystems-ib/iris-dicom-sampleHemos realizado 2 pruebas:
Primera prueba: tratamos de guardar DICOM
Siguiendo el ejemplo 1: https://github.com/intersystems-ib/iris-dicom-sample#receiving-dicom-with-embedded-pdf
Circuito:
Siendo la respuesta del sistema destino:
ERROR <EnsDICOM>PeerRejectedAssociation: La contraparte ha rechazado la asociación. Fuente: '' Motivo: ''
Además, realizamos una segunda prueba
Segunda prueba: Consultar y Recuperar, Query / Retrieve: https://github.com/intersystems-ib/iris-dicom-sample#query--retrieve-scenario
Siendo la respuesta por parte del sistema destino:
ERROR <Ens>ErrBPTerminated: Finalizando BP DICOM Query Process # debido a un error: ERROR <EnsDICOM>PeerRejectedAssociation: La contraparte ha rechazado la asociación. Fuente: '%1' Motivo: '%2'> ERROR <EnsDICOM>PeerRejectedAssociation: La contraparte ha rechazado la asociación. Fuente: '%1' Motivo: '%2'
¿ de qué manera, Alberto, nos recomiendan ustedes depurar, buscar, investigar, indagar el porqué de estas 2 excepciones ?
¿ mediante qué mecanismo, o cuál sería tu proceso mental y toma de acciones para organizar, ordenar, entender y sobre todo seguir y dar con la causa de estas excepciones ?
¿ cuál sería la vía correcta para entender, atender, depurar, corregir, y comprender mejor este tipo de integraciones, Alberto ?
Muchas gracias por leer y responder, porque es un gran espaldarazo, auxilio y aporte el hecho de que nos hagas seguimiento y nos vayas indicando, ordenando, explicando, cómo continuar, o en qué ejemplos basarnos
Un saludo
Hola Yone,
En tu caso, parece que el host al que intentas conectar (supongo que es un simulador), está rechazando la conexión.
Quizá porque el documento DICOM que intentas enviar tiene un TransferSyntax que no está configurado. Lo mejor sería que intentaras obtener información / logs en el host que lo está rechazando. Por ejemplo si usas el simulador dcm4che te mostrará información que te puede ayudar a investigar qué ha sucedido.
Yo te recomendaría:
1-Intenta ejecutar el ejemplo que te pasé, utilizando contenedores, y comprueba que todo te funciona bien y comprendes cómo funciona la integración con DICOM.
2-Intenta replicar el comportamiento que te interese en tu propia producción con tu propio simulador. Ten presente la información que te devuelva el simulador. Te ayudará a comprender el proceso de negociación de la conexión y la transferencia.
Pregunta
Javier Sanchis · 13 feb, 2020
Hola a todos,
He estado leyendo algún post en la comunidad pero no he conseguido llegar a una conclusión. Os expongo mi cuestión.
Tengo un código caché, y siguiendo esta guía https://cedocs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=TUNT pero no llego a entender como poder ejecutar esto desde jenkins por ejemplo, sin tener que utilizar la consola, y con ello automatizar el proceso. Es decir, si fuera posible hacerlo, que pasos debería seguir.
muchas gracias Hola Javier! Ya he visto que te han contestado en el developer community
Por lo que preguntas parece que lo que necesitas es ejecutar los tests automáticos, convertir el resultado a JUnit e interpretarlo en Jenkins.
Como te ha dicho Timothy, échale un ojo a JUnitOutput. Te servirá para exportar los resultados de un %UnitTest a formato JUnit.
https://github.com/intersystems-community/zpm/blob/master/src/cls/_ZPM/PackageManager/Developer/UnitTest/JUnitOutput.cls
Por si te sirve de "inspiración", te paso un ejemplo (anticuado - habría que adaptarlo), pero que en esencia al final hacía algo parecido a lo que buscas:
https://github.com/albertoft/widgets-direct/blob/master/WidgetsDirect/Jenkinsfile ¡Qué bien, muy bien! A mí también me ayudó. Hola Alberto!
Muchas gracias por tu respuesta, le echo un ojo ahora mismo.
Anuncio
Esther Sanchez · 4 feb, 2021
¡Hola desarrolladores!
Os queríamos dar las gracias por formar parte de la Comunidad de InterSystems en español. ¡Ya hay más de 300 usuarios registrados en ella!
Día a día, trabajamos para hacerla aún mejor y más útil para todos. Pero nos gustaría saber cómo lo estamos haciendo, y para eso necesitamos conocer vuestra opinión.
Por ello, hemos preparado una breve encuesta para saber qué pensáis de la Comunidad en español, si os resulta útil y qué podríamos mejorar.
👉🏼 Encuesta sobre la Comunidad de Desarrolladores en español 👈🏼
Nota: Os llevará menos de 5 minutos responderla.
También podéis dejar vuestra opinión en los comentarios de esta publicación.
¡Muchas gracias a todos! ¡Hola a todos!
¿Ya habéis respondido a la encuesta sobre la Comunidad de Desarrolladores en español?
Si es así, ¡muchas gracias!
Si no, ¡aún estáis a tiempo de ayudarnos a hacerla aún mejor!! Os llevará menos de 5 minutos...
➡️ Encuesta sobre la Comunidad de Desarrolladores en español Este jueves 4 termina el plazo para recibir vuestras respuestas a la Encuesta sobre la Comunidad!
Si aún no habéis respondido, aquí tenéis el enlace, os llevará menos de 5 minutos completarla:
➡️ Encuesta sobre la Comunidad de Desarrolladores en español
¡Os leemos a todos y nos encanta saber vuestra opinión! ¡Muchas gracias!
Pregunta
Evgeny Shvarov · 15 abr, 2021
¡Hola amigos!
A menudo, durante la depuración, quieres conocer los valores de todos los parámetros.
Utilizar VSCode Debugger no es una opción.
¿Qué se podría usar para saber qué parámetros vinieron al método?
¿Existe una macro "mágica" que almacene todas las variables con sus nombres en un global?
¿Alguna idea? ¡Gracias!
@Julius.Kavay ha dado una muy buena alternativa.
En lugar de insertar debug_macros, prueba la utilidad TRACE de Intersystems.
write $$DIR^TRACE("c:\Temp\") ; to set an output directory
write $$ON^TRACE(jobnr) ; the pid of the process you want to trace
; zn "appNamespace"
; do ^yourProgram
; zn "%SYS"
write $$OFF^TRACE(jobnr) ; to stopp the trace
do ^TRACE ; to display the trace result
TRACE muestras las llamadas a métodos/funciones con argumentos.
Para hacer uso de ella, debéis de estar en el namespace %SYS... o podéis mapearla al namespace %ALL y así la podréis utilizar desde cualquier sitio. No aparece actualmente en la documentación oficial, pero podéis encontrar información de uso ejecutando do ^TRACE y en la propia rutina ^TRACE.int (podéis ver el código fuente completo desde el portal, el Studio, VS Code,...)
Anuncio
Esther Sanchez · 12 mayo, 2021
¡Hola desarrolladores!
Os invitamos a un nuevo webinar en español: "Aprende ObjectScript desde cero", el martes 25 de mayo, a las 4:00 PM (CEST).
Para todos aquellos que no tienen ni idea de ObjectScript y quieren empezar a utilizarlo, o para aquellos que llevan tiempo desarrollando con el lenguaje de programación de InterSystems sin saber cómo lo hacen, vamos a explicar los conceptos básicos de ObjectScript, descubrir algunas trampas y mostrar algunos trucos muy útiles.
Además, haremos una ginkana en directo para demostrar lo aprendido. Los tres primeros clasificados ganarán un polo de la Comunidad de Desarrolladores... ¡y algunas cosas más!¡Os esperamos!
➡️ David Reche, el ponente del webinar, os invita personalmente a asistir! >>➡️ Podéis registraros aquí >>
El próximo martes es el webinar de ObjectScript.
Además de aprender, pasaremos un rato muy divertido jugando a un juego de preguntas y respuestas online sobre lo explicado en el webinar. Competiremos unos contra otros y el podio final mostrará a los ganadores!
¡Apúntate antes de que se te olvide! :D Empieza la cuenta atrás... ¡mañana ya es el webinar!
Durante 30 minutos, explicaremos los conceptos básicos de ObjectScript, descubriremos algunas trampas y mostraremos algunos trucos muy útiles.
Y, al terminar el webinar, haremos una ginkana en directo para que demostréis lo aprendido! 😃
¡Os esperamos!
Artículo
Muhammad Waseem · 29 sep, 2021
https://www.appeon.com/products/powerbuilder
Appeon PowerBuilder es una herramienta de desarrollo empresarial que permite crear componentes y aplicaciones empresariales basadas en datos.Es un producto de una suite de Appeon que ofrece las herramientas para desarrollar aplicaciones cliente/servidor, web, móviles y distribuidas.
En este artículo, mostraré los pasos para conectarse a Caché con Appeon PowerBuilder usando ODBC.
Paso 1 : Asegúrate de que la opción "ODBC Driver" está seleccionada al instalar IRIS:
Paso 2: Configura la fuente de datos ODBC IRIS mediante el Administrador de fuentes de datos ODBC:
Paso 3: Configura la fuente de datos ODBC de InterSystems:
Paso 4: Prueba la conexión (asegúrate de que la instancia de IRIS se está ejecutando):
Paso 5: Desde PowerBuilder, abre "Database profiles", seleccione "ODB ODBC" de la lista y haz clic en el botón "New...":
Paso 6: Selecciona la fuente de datos "IRISHealth User" que creamos usando el administrador de ODBC:
Paso 7: Prueba la conexión en la pestaña "Preview" haciendo clic en el botón "Test connection":
¡Enhorabuena! ¡Nos hemos conectado con Caché!Ahora podemos ver Tablas y Datos utilizando el pintor de bases de datos de PowerBuilder.
¡Espero que os resulte útil!
¡Gracias!
Anuncio
Esther Sanchez · 3 mar, 2022
¡Hola desarrolladores!
Muchísimas gracias a todos los que habéis participado, de una forma u otra, en el 1er concurso de artículos técnicos en español! Hemos recibido
🌟 8 ARTÍCULOS INCREÍBLES 🌟
Y... ¡llegó el momento de anunciar los mejores!
Estos son los ganadores y sus artículos:
⭐️ Premios de los expertos – los ganadores han sido elegidos por expertos de InterSystems:
🥇 Primer puesto: Enviando mensajes a Kafka, escrito por @Daniel.Aguilar
🥈 Segundo puesto: Cómo convertirse en un señor del tiempo - El Nacimiento, escrito por @Francisco.Lopez1549
🥉 Tercer puesto: Implementación de patrones de proyecto utilizando el lenguaje Caché ObjectScript, escrito por @Marcio.Pereira
⭐️ Premio de la Comunidad – el ganador es elegido por los miembros de la Comunidad y es el artículo con mayor número de "likes":
🏆 Cómo convertirse en un señor del tiempo - El Nacimiento, escrito por @Francisco.Lopez1549
¡Enhorabuena a todos los ganadores!
¡Y un fuerte aplauso al resto de participantes!
@Robert.Cemper1003
@Laura.BlázquezGarcía
@Nancy.Martinez
@Yone.Moreno
¡GRACIAS por vuestro esfuerzo y por contribuir en la Comunidad!!!
Los premios están en producción. Contactaremos con los ganadores para enviárselos lo antes posible. Enhorabuena a los premiados. Muy buenos artículos han salido. Hay que repetirlo porque hay mucha calidad en la comunidad ¡Enhorabuena por tus dos premios!! 🎊🎊 ¡Felicitaciones a todos! ¡Gracias por tu contribución! Muchas felicidades a los ganadores y a todos los participantes