+1
Under review

Iridium Schedule edit/ Server-Client project

niky94547 5 years ago in Other updated by Truc Nguyen Van 4 years ago 22

Hi,

   We implement iridium server-client platform to one of our

projects. Already try your sample code for schedules within the

project (see attachment). All operate as expected we could manage

schedule time/date and enable/disable, but the states do not saved

after server reboot. We try to save EventData tag within DB but

without success. Could you please advice/provide some hints

guidelines so we could solve it.


Thanks a lot for kind support,

Schedule_edit.zip

Under review

Hello.

You need to specify saving in the database in the feedback settings, in your case this is a string:


Then the values in the database will be saved:

Hello Vladimir,

Thanks for your reply. I had tested as described. Following error appear on log when saving schedule or on server start:

Tag EventData_from_server string is to big to Web socket. Limit is about 900 bytes for name_len and value_len.

 I had check db string records are made, but on restart same behavior not load edited values.


Thanks again,

Br,

Hello.

This error only indicates that the web server in the web browser cannot display more than 900 bytes for feedback. This restriction is intended to ensure that large values in feedbacks do not cause the browser to crash. The size of the feedback in iRidium server is limited only by the available memory. If the database recorded the entire line, then everything works correctly. GetFeedback() method can get the entire string.

Hello,

  Thanks so it's not the case. I made more tests with your sample (only enabling/disabling schedules). Here is db records. Records on UI update changes are ok, but after restart string with defaults values are written. Most probably something within js code?

Br,

Hello.

Please specify what kind of restart it? Server restart? Or a client? What is the default value?

Hello,

  Only server restart cause issue. When restart/release client there is no issue, correct values were loaded exactly as it was set in the string. But when server restart correct values are not loaded (last values set in the string), but "defaults" which i think comes from initial creation of schedule within studio.

Br,  

In the server project, set the parameter "Load On Start = False".

I set "Load On Start = False" , for "EventData_from_server" tag.  No result, same behavior.


Studio.png


Br,

Hello.

In the project everything is correct, it does not handle the restart of the server. Therefore, at the start, the value from the Schedule will always be taken.

In your case, for the tag "EventData_from_server" you need to enable saving to the database and "Load On Start". Then in the listener with EVENT_START to take value of a feedback "EventData_from_server" and to execute EventChanger.

+1

Hi Vladimir,

  Thanks for your support. As i understood sample project is not intended to save schedule values when server restart, even if tag "EventData_from_server" is saved in db and load on start. So js modification should be made. Could you assist with modification of js as I'm beginner and no into scripting. It's not an urgent matter, but would like to implement functionality withing final visualization and project fulfillment.

Thanks a lot,

Br,

here with some modifications

server

function clone(obj) {
    if (null == obj || "object" != typeof obj) return obj;
    var copy = obj.constructor();
    for (var attr in obj) {//if (obj.hasOwnProperty(attr))
         copy[attr] = obj[attr];
    }
    return copy;
}

if (!Array.isArray) {
  Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
  };
}

var schedule;
// creating a string with schedule data
var EventChanger = function() {
var EventBuff = [];

//function EventP() { }

//MonkeyPathcing
var EventProt = {
    //constructor: EventP,
    Name: undefined,     // event name
    Start: undefined,   // event start date-time
    End: undefined,  // event finish date-time
    Enabled: undefined,
    Type: undefined,
    //Parent: undefined,
    Day: undefined,
    End: undefined,
    WeekDays: undefined,
    RepeatEnd: undefined,
    MonthRepeatType: undefined,
    MonthDays: undefined,
    DayNumber: undefined,
    WeekDay: undefined,
    StartSunType: undefined,
    //TODO: Sun Offset
}
    //EventP.prototype=EventProt;
    
 /* 
var Event = function(inp) {
    this.Name;     // event name
    this.Start;   // event start date-time
    this.End;  // event finish date-time
    this.Enabled;
    this.Type;
    this.Day;
    this.End;
    this.WeekDays;
    this.RepeatEnd;
    this.MonthRepeatType;
    this.MonthDays;
    this.DayNumber;
    this.WeekDay;
    this.StartSunType;
    //TODO: Sun Offset
    for (var inpn in inp) {
    this[inpn] = inp[inpn];
        //if (inp.hasOwnProperty(inpn) && inp[inpn]!==undefined){ 
            //IR.Log("add prop " + inpn.toString() + " = " + inp[inpn]);        
            //this[inpn.toString()] = inp[inpn];
            //}
    }
} 
*/

// writing schedule data in virtual tag
  this.Write = function(in_events) {
  
 
    EventBuff = [];
    for(i in in_events) {
    //.propertyIsEnumerable("Name"));
      in_events[i].__proto__= EventProt;       
      var d2 = clone(in_events[i]);
      EventBuff.push(d2);
    }
    var string = JSON.Stringify(EventBuff);                     
    IR.SetVariable("Server.Tags.EventData_from_server", string);   
  }   
// reading schedule data in virtual tag 
  this.Read = function(in_schedule, in_NewData) { 
    for (u=0;u<in_newdata.length;++u) {="" in_newdata_u="in_NewData[u];" ir.log("update="" "="" +="" in_newdata_u.name);="" eventedit="in_schedule.GetEvent(in_NewData_u.Name);" eventedit.start="Math.floor(new" date(in_newdata_u.start));="" eventedit.end="Math.floor(new" date(in_newdata_u.end));="" eventedit.enabled="(in_NewData_u.Enabled" =="1);" eventedit.done();="" event="" update="" }="" var="" eventsobj="new" eventchanger();="" getting="" schedule="" data="" at="" server="" start="" ir.addlistener(ir.event_start,0,function()="" svddata="IR.GetVariable("Server.Tags.EventData_from_server");" 1");="" if="" (svddata)="" ir.log("saveved="" svddata);="" eventsobj.read(schedule,="" json.parse(svddata));="" else="" events="schedule.GetEvents();" eventsobj.write(events);="" });="" new="" from="" panel="" ir.setgloballistener(ir.event_global_tag_change,="" function(in_sname,="" in_svalue)="" newdata="JSON.Parse(in_sValue);" ?="" [newdata]:newdata;="" newdata);="" systembase.execute("commit");="" subscribing="" for="" tag="" changes="" ir.subscribetagchange("server.channels.eventdata_to_server");="" <="" pre=""></in_newdata.length;++u)>

client

var Server = IR.GetDevice("iRidium Server");
var ListBox = IR.GetItem("Page 1").GetItem("ListBox");
var EventNameField = IR.GetItem("Page 1").GetItem("EventName");
var Lamp = IR.GetItem("Page 1").GetItem("Lamp");
var Switch = IR.GetItem("Page 1").GetItem("Switch");
var EventStartField = IR.GetItem("Page 1").GetItem("EventStart");
var EventFinishField = IR.GetItem("Page 1").GetItem("EventFinish");
var EventStartField1 = IR.GetItem("Page 1").GetItem("EventStart 1");
var EventFinishField1 = IR.GetItem("Page 1").GetItem("EventFinish 1");
var UpdateButton = IR.GetItem("Page 1").GetItem("UpdateBtn");

var EventsObj;


var selectedItem = 0;

var events = [];

var EventProt = {}

/* var Event = function(inp) {
    this.Name;     // event name
    this.Start;   // event start date-time
    this.End;  // event finish date-time
    this.Enabled;
    this.Type;
    this.Day;
    this.End;
    this.WeekDays;
    this.RepeatEnd;
    this.MonthRepeatType;
    this.MonthDays;
    this.DayNumber;
    this.WeekDay;
    //TODO: Sun Offset
    for (var inpn in inp) {
        if (inp.hasOwnProperty(inpn)) 
            this[inpn] = inp[inpn];
    }
}
    
*/


var EventChanger = function(in_list) {

  var list = in_list;    //  link to GUI list with items and data
  var that = this;  
// read event data from virtual tag in JSON format and fill the list with items
  this.Read = function(in_ChannelName, in_Value) {         
    if (in_ChannelName == "EventData_from_server") {   
      //IR.Log("Now we parse " + in_Value);
      events = JSON.Parse(in_Value);
      for (i in events) {
        list.CreateItem(parseInt(i), 1, {Text: events[i].Name});
      }
      fill(selectedItem);
    }
  }
// write new date-times of event in virtual tag 
  this.Write = function(NEvent) {
    Server.Set("EventData_to_server", JSON.Stringify(NEvent));
  }
}

IR.AddListener(IR.EVENT_START,0,function() {
  EventsObj = new EventChanger(ListBox);
}); 

IR.AddListener(IR.EVENT_ITEM_SELECT, ListBox, function(item, subitem) {
  selectedItem = item;
  fill(selectedItem);
});
      
IR.AddListener(IR.EVENT_TAG_CHANGE, Server, function(name, value) {
  EventsObj.Read(name, value);
});
 
 
fill = function (in_item) {
  startTime = new Date(events[in_item].Start * 1000);
  finishTime = new Date(events[in_item].End * 1000);
  EventNameField.Text = events[in_item].Name;
  Lamp.Value = events[in_item].Enabled;
  Switch.Value = events[in_item].Enabled;
  EventStartField.Text = startTime;
  EventFinishField.Text = finishTime;
  EventStartField1.Text = startTime;
  EventFinishField1.Text = finishTime;
}

IR.AddListener(IR.EVENT_ITEM_PRESS, UpdateButton, function() {

  startTime = new Date(EventStartField1.Text);
  finishTime = new Date(EventFinishField1.Text);
  
  //var NEvent = new Event({Name:EventNameField.Text, Start: Math.floor(startTime.getTime()/1000), End: Math.floor(finishTime.getTime()/1000), Enabled: Switch.Value});
  var NEvent = {Name:EventNameField.Text, Start: Math.floor(startTime.getTime()/1000), End: Math.floor(finishTime.getTime()/1000), Enabled: Switch.Value};
  EventsObj.Write(NEvent); 
});

linked:

https://support.iridiummobile.net/communities/5/topics/12357-log-of-channels-and-feedbacks-in-ui#comment-74761

https://support.iridiummobile.net/communities/5/topics/12955-sohranenie-znachenij-tegov-na-servere-iridium

server (correct formatting)

function clone(obj) {
    if (null == obj || "object" != typeof obj) return obj;
    var copy = obj.constructor();
    for (var attr in obj) {//if (obj.hasOwnProperty(attr))
         copy[attr] = obj[attr];
    }
    return copy;
}


//IR.Log("ENUM " + createNewProperty);


var schedule = IR.GetScheduler("Schedule 1");
// creating a string with schedule data
var EventChanger = function() {
var EventBuff = [];

//function EventP() { }

//MonkeyPathcing
var EventProt = {
    //constructor: EventP,
    Name: undefined,     // event name
    Start: undefined,   // event start date-time
    End: undefined,  // event finish date-time
    Enabled: undefined,
    Type: undefined,
    //Parent: undefined,
    Day: undefined,
    End: undefined,
    WeekDays: undefined,
    RepeatEnd: undefined,
    MonthRepeatType: undefined,
    MonthDays: undefined,
    DayNumber: undefined,
    WeekDay: undefined,
    StartSunType: undefined,
    //TODO: Sun Offset
}
    //EventP.prototype=EventProt;
    
 /* 
var Event = function(inp) {
    this.Name;     // event name
    this.Start;   // event start date-time
    this.End;  // event finish date-time
    this.Enabled;
    this.Type;
    this.Day;
    this.End;
    this.WeekDays;
    this.RepeatEnd;
    this.MonthRepeatType;
    this.MonthDays;
    this.DayNumber;
    this.WeekDay;
    this.StartSunType;
    //TODO: Sun Offset
    for (var inpn in inp) {
    this[inpn] = inp[inpn];
        //if (inp.hasOwnProperty(inpn) && inp[inpn]!==undefined){ 
            //IR.Log("add prop " + inpn.toString() + " = " + inp[inpn]);        
            //this[inpn.toString()] = inp[inpn];
            //}
    }
} 
*/

// writing schedule data in virtual tag
  this.Write = function(in_events) {
  
 
    EventBuff = [];
    for(i in in_events) {
    //.propertyIsEnumerable("Name"));
    //IR.Log ("PROTEIN " + in_events[i].__proto__);
    
    
        in_events[i].__proto__= EventProt;
        //for(j in  in_events[i]) {
        //    IR.Log("Enumerable " + j + " == " + in_events[i][j]);
        //}
        
        var d2 = clone(in_events[i]);

        //var NEvent = new Event(in_events[i]);
      EventBuff.push(d2);
    }
    var string = JSON.Stringify(EventBuff);                     
    IR.SetVariable("Server.Tags.EventData_from_server", string);   
  }   
// reading schedule data in virtual tag 
  this.Read = function(in_schedule, in_NewData) { 
    EventEdit = in_schedule.GetEvent(in_NewData.Name);
    EventEdit.Start = Math.floor(new Date(in_NewData.Start));
    EventEdit.End = Math.floor(new Date(in_NewData.End));
    EventEdit.Enabled = (in_NewData.Enabled == 1);
    EventEdit.Done();  // event update
  }  
}

var EventsObj = new EventChanger();
// getting schedule data at server start
IR.AddListener(IR.EVENT_START,0,function() {
  var svdData = IR.GetVariable("Server.Tags.EventData_from_server");
  var schedule = IR.GetScheduler("Schedule 1");

  if (svdData)
  {
     IR.Log("SAVEVED DAta " + svdData);
     EventsObj.Read(schedule, JSON.Parse(svdData));
  }
  else {
    events = schedule.GetEvents();
    EventsObj.Write(events); 
  }  
});

// getting new data from panel
IR.SetGlobalListener(IR.EVENT_GLOBAL_TAG_CHANGE, function(in_sName, in_sValue) {

  var newData = JSON.Parse(in_sValue);
  EventsObj.Read(schedule, newData);
  events = schedule.GetEvents();
  EventsObj.Write(events); 
});
 
// subscribing for tag changes
IR.SubscribeTagChange("Server.Channels.EventData_to_server");

Hello!

I try test JS of you, but IR.Log is notice :

EventEdit = in_schedule.GetEvent(in_NewData.Name);

[29-10-2019 22:39:49.855] WARNING SCRIPT Script exception: RangeError: C:\Users\Admin\Documents\iRidium pro documents\Server\Documents\Schedule_edit\scripts\serverCript.js:95: error

+1

Hi,

 Thanks a lot for the support on our issue. I also test revised code. Following error appear on server log, when I try to update new values from client UI:

[29-10-2019 19:59:39.211] WARNING SCRIPT Script exception: TypeError: C:\Users\USER\Documents\iRidium pro documents\Server\Documents\Project_1396248390\scripts\Newscript.js:95: Tried to use undefined as an object

Br,

Sorry, it's old code

Server.js

moderator: please, edit message above

Hi!

the states do not saved

after server reboot. I try to save EventData tag within DB but

without success. 

Can you upload project for me?

You must reboot server after 1min or press ESC key twice

https://translate.google.com/translate?sl=ru&tl=en&u=https%3A%2F%2Fsupport.iridiummobile.net%2Fcommunities%2F5%2Ftopics%2F12955-sohranenie-znachenij-tegov-na-servere-iridium%23comment-138979

Good afternoon.
Thanks for the information provided.
Indeed, when choosing Store in DB = UTF-8, the interval is 1 minute (more precisely, no more than 1 minute). However, the choice of strategy (by changing the value or by the interval) is absent in the studio settings (both old and new). After your appeal, we decided to add the possibility of choosing a conservation strategy to the database, but the implementation deadlines have not yet been determined. We will inform you when ready.

https://support.iridiummobile.net/s/attachments/15553/18/11018/a7f9f2d84eec2f1982ffeba051241053.bmp

Hi!

I use iridium studio 2019 version then it's success.

Thank you!

Hi!

With Window server then it's OK

but if i use raspberry then it's not OK. 

I reboot raspberry server after 2-3 minutes , it still not ok

Which version are you using on the server?

hi!

i using 1.3.10.18280 version