Comme annoncé, ce forum est passé en lecture seule au 1er janvier 2020. Désormais nous vous invitons à vous rendre sur notre nouvelle page communauté :
Image

A très bientôt !

[Plugin Tiers][Sujet Principal] Volets

Pour échanger sur les plugins classés en catégorie "Automatisation"
Avatar de l’utilisateur
mika-nt28
Actif
Messages : 7995
Inscription : 05 août 2014, 08:58
Localisation : Dreux - France

Re: [Plugin Tiers][Sujet Principal] Volets

Message par mika-nt28 » 01 juin 2017, 10:22

Oui c'est corrigé et ce sera repliquer sur le market cette nuit.
Si ca vous bloque de trop je peux forcer une mise a jours du market
Pour faciliter la compréhension de votre problème, n’oubliez pas de poster
- Des Screenshots de votre configuration
- Le Log au moment du problème constaté

Encouragez-moi https://www.paypal.me/mikant28

Avatar de l’utilisateur
jiminy
Actif
Messages : 756
Inscription : 26 févr. 2016, 18:27
Localisation : Montpellier

Re: [Plugin Tiers][Sujet Principal] Volets

Message par jiminy » 01 juin 2017, 11:20

Hello,
Tout d'abord un grand merci pour ce plugin. Je l'ai découvert récemment mais je le trouve super.
Pour le moment en fait je teste mes conditions et mes réglages en faisant juste envoyer des mails je ne commande pas réellement mes volets mais çà marche déjà nettement mieux que mes scénarios bordéliques.
Donc pour moi pas nécessaire de forcer une mise à jour, mais je ne peux pas parler pour les autres.

Avatar de l’utilisateur
jiminy
Actif
Messages : 756
Inscription : 26 févr. 2016, 18:27
Localisation : Montpellier

Re: [Plugin Tiers][Sujet Principal] Volets

Message par jiminy » 02 juin 2017, 09:27

Hello,
Pour certaines ouvertures j'ai une condition #time# >= 0700 pour éviter que je ne sois réveillé trop tôt lors du lever du soleil.
Comme je me fait expédier un mail à chaque commande d'ouverture je remarque qu'en fait il y en a deux, une à 7h00 et l'autre à 7h05.
Ce n'est pas du tout gênant car si la fenêtre est ouverte la seconde commande ne fait rien d'autre que de m'envoyer un mail, mais j'ai pensé préférable de le signaler.
Michael, je peux ouvrir une issue sur Github si tu pense que ça en vaut la peine.

Avatar de l’utilisateur
jiminy
Actif
Messages : 756
Inscription : 26 févr. 2016, 18:27
Localisation : Montpellier

Re: [Plugin Tiers][Sujet Principal] Volets

Message par jiminy » 02 juin 2017, 09:30

J'y pense, j'ai fait la mise à jour ce matin après l'ouverture des volets donc c'est peut être déjà corrigé ? Mieux vaut attendre demain pour voir si c'est toujours pareil.

Avatar de l’utilisateur
mika-nt28
Actif
Messages : 7995
Inscription : 05 août 2014, 08:58
Localisation : Dreux - France

Re: [Plugin Tiers][Sujet Principal] Volets

Message par mika-nt28 » 02 juin 2017, 09:49

C'est etrange effectivement
Est ce que ce ne serai pas les 2 type de gestion qui s'entermel
car chez moi j'ai remarqué qu'au levé du soleil mes volet se sont ouvert et 1 minute apres refermer car le soleil etait dans la fenetre
Pour faciliter la compréhension de votre problème, n’oubliez pas de poster
- Des Screenshots de votre configuration
- Le Log au moment du problème constaté

Encouragez-moi https://www.paypal.me/mikant28

Avatar de l’utilisateur
jiminy
Actif
Messages : 756
Inscription : 26 févr. 2016, 18:27
Localisation : Montpellier

Re: [Plugin Tiers][Sujet Principal] Volets

Message par jiminy » 02 juin 2017, 10:44

Non car ce sont les volets au nord qui font çà et en plus j'ai bien 2 messages d'ouverture successifs. Je regarderai les logs demain matin.

willjee
Timide
Messages : 47
Inscription : 22 avr. 2017, 17:45

Re: [Plugin Tiers][Sujet Principal] Volets

Message par willjee » 03 juin 2017, 09:24

Micka,
Dans la dernière mise à jour, on n'a plus le détail des conditions dans le mode débug, on sait juste si les conditions sont remplies ou pas.
le détail est intéressant pour connaitre la condition manquante.
Bon WE

Avatar de l’utilisateur
mika-nt28
Actif
Messages : 7995
Inscription : 05 août 2014, 08:58
Localisation : Dreux - France

Re: [Plugin Tiers][Sujet Principal] Volets

Message par mika-nt28 » 03 juin 2017, 12:01

Je regarde ça
Pour faciliter la compréhension de votre problème, n’oubliez pas de poster
- Des Screenshots de votre configuration
- Le Log au moment du problème constaté

Encouragez-moi https://www.paypal.me/mikant28

Gaillb1
Timide
Messages : 113
Inscription : 20 nov. 2016, 23:06
Localisation : sud ouest parisien

Re: [Plugin Tiers][Sujet Principal] Volets

Message par Gaillb1 » 04 juin 2017, 06:43

Bonjour à tous

Depuis la derniere mise à jour, disparition des actions et impossible à les créer
Cela ressemble à un soucis deja eu il y a quelques semaines
Je suis le seul dans ce cas ?

bolino
Timide
Messages : 48
Inscription : 06 nov. 2015, 16:41
Localisation : pontchateau

Re: [Plugin Tiers][Sujet Principal] Volets

Message par bolino » 06 juin 2017, 15:02

Gaillb1 a écrit :
04 juin 2017, 06:43
Bonjour à tous

Depuis la derniere mise à jour, disparition des actions et impossible à les créer
Cela ressemble à un soucis deja eu il y a quelques semaines
Je suis le seul dans ce cas ?
Non j'ai le même soucis que toi ...et toujours ma tache planifiée VoletSoir à 21h21 dans le cron, qui ne suit pas l'heure du coucher du soleil ...

j'ai desinstallé le plugin pour le reinstaller, mais est-ce qu'il y a des traces de configurations autre part que dans /var/www/jeedom/plugins/Volets , car le 21h21 il doit bien le récupérer qqpart..

je reinstalle le plugin pour vérifier si le bug des actions est toujours présent

Avatar de l’utilisateur
mika-nt28
Actif
Messages : 7995
Inscription : 05 août 2014, 08:58
Localisation : Dreux - France

Re: [Plugin Tiers][Sujet Principal] Volets

Message par mika-nt28 » 07 juin 2017, 08:07

Effectivement j'ai bien trouvé un bug sur le retours de la sélection de commande.
Par contre je ne trouve rien sur la disparition d'action, chez moi je les ai bien tous

@bolino, la suppression d'un plugin ne changera rien s'il y a un bug.
La tache de coucher et de levée des volets est une tache cron que tu retrouve dans le moteur de tache de jeedom
Si cette tache n'evolue pas c'est que le plugin heliotrope ne la met pas a jours.
Pour faciliter la compréhension de votre problème, n’oubliez pas de poster
- Des Screenshots de votre configuration
- Le Log au moment du problème constaté

Encouragez-moi https://www.paypal.me/mikant28

AlienQueen
Timide
Messages : 142
Inscription : 26 avr. 2016, 15:28

Re: [Plugin Tiers][Sujet Principal] Volets

Message par AlienQueen » 13 juin 2017, 12:07

Merci pour ce plugin Mika ! Et bon courage pour le développement !

superbricolo
Actif
Messages : 543
Inscription : 01 janv. 2016, 12:45
Contact :

Re: [Plugin Tiers][Sujet Principal] Volets

Message par superbricolo » 16 juin 2017, 01:11

Bonjour,
J'ai fait évoluer le code du plugin pour répondre à mes besoins. Je m'explique:
En effet je souhaitais, pouvoir ré-ouvrir le volets si certaines conditions n'était pas réunies. Par exemple, aujourd'hui, je ferme mes velux si la température extérieure dépasse 23 °C et la température intérieure dépasse 23 °C et l'altitude du soleil > 5. Je veux donc que si une des 2 températures est <= à 23°C ou que le soleil est trop bas, les velux s'ouvrent.
Pour cela j'ai mis en place un nouveau critère, qui permet de tester une condition à l'inverse et donc si celle-ci est vrai de ré-ouvrir le volet pendant que le soleil est dans la fenêtre.
De même cela fonctionnera l’hiver pour refermer le volet si la condition inverse est vrai.
Toutes les autres conditions marquées "condition normale' continuent à être testées normalement et vérifiées lors du contrôle pour la ré-ouverture avec le soleil dans la fenêtre.
Le test inversé n'est pas réalisé dans le cas jour/nuit, et toutes les conditions sont testées de manière normale s'il s'agit du test de fermeture quand le soleil arrive dans la fenêtre.

Voici un exemple de configuration pour mes velux
condition plugin volet.JPG
condition plugin volet.JPG (356.37 Kio) Consulté 2256 fois
Et voici le code modifié:
Volets/desktop/js/Volets.js

Code : Tout sélectionner

var map;
var DroitLatLng=new Object();
var CentreLatLng=new Object();
var GaucheLatLng=new Object();
$("#table_cmd").sortable({axis: "y", cursor: "move", items: ".cmd", placeholder: "ui-state-highlight", tolerance: "intersect", forcePlaceholderSize: true});
$("#table_condition").sortable({axis: "y", cursor: "move", items: ".ConditionGroup", placeholder: "ui-state-highlight", tolerance: "intersect", forcePlaceholderSize: true});
$("#table_ouverture").sortable({axis: "y", cursor: "move", items: ".ActionGroup", placeholder: "ui-state-highlight", tolerance: "intersect", forcePlaceholderSize: true});
$("#table_fermeture").sortable({axis: "y", cursor: "move", items: ".ActionGroup", placeholder: "ui-state-highlight", tolerance: "intersect", forcePlaceholderSize: true});
$('body').on('change','.eqLogicAttr[data-l1key=configuration][data-l2key=isRandom]',function(){
	if($(this).is(':checked'))
		$('.Presence').show();
	else
		$('.Presence').hide();
});
$('body').on('change','.eqLogicAttr[data-l1key=configuration][data-l2key=heliotrope]',function(){
	$('#MyMap').html('');
	$.ajax({
		type: 'POST',            
		async: false,
		url: 'plugins/Volets/core/ajax/Volets.ajax.php',
		data:{
			action: 'getInformation',
			heliotrope:$(this).val(),
		},
		dataType: 'json',
		global: false,
		error: function(request, status, error) {},
		success: function(data) {
			if (!data.result)
				$('#div_alert').showAlert({message: 'Aucun message reçu', level: 'error'});
			if (typeof(data.result.geoloc) !== 'undefined') {
				var center=data.result.geoloc.configuration.coordinate.split(",");
				CentreLatLng.lat=parseFloat(center[0]);
				CentreLatLng.lng=parseFloat(center[1]);
				map = new ol.Map({
					view: new ol.View({
						center: ol.proj.fromLonLat([CentreLatLng.lng,CentreLatLng.lat]),
						zoom: 10
					}),
					layers: [
						new ol.layer.Tile({
							source: new ol.source.OSM()
						})
					],
					target: 'MyMap'
				});
			}
		}
	});
});

function saveEqLogic(_eqLogic) {
	_eqLogic.configuration.condition=new Object();
	_eqLogic.configuration.action=new Object();
	var ConditionArray= new Array();
	var OpenArray= new Array();
	var CloseArray= new Array();
	$('#conditiontab .ConditionGroup').each(function( index ) {
		ConditionArray.push($(this).getValues('.expressionAttr')[0])
	});
	$('#ouverturetab .ActionGroup').each(function( index ) {
		OpenArray.push($(this).getValues('.expressionAttr')[0])
	});
	$('#fermeturetab .ActionGroup').each(function( index ) {
		CloseArray.push($(this).getValues('.expressionAttr')[0])
	});
	_eqLogic.configuration.condition=ConditionArray;
	_eqLogic.configuration.action.open=OpenArray;
	_eqLogic.configuration.action.close=CloseArray;
   	return _eqLogic;
}
function printEqLogic(_eqLogic) {
	$('.ConditionGroup').remove();
	$('.ActionGroup').remove();
	$('.eqLogicAttr[data-l1key=configuration][data-l2key=Droite]').val(JSON.stringify(_eqLogic.configuration.Droite));
	$('.eqLogicAttr[data-l1key=configuration][data-l2key=Centre]').val(JSON.stringify(_eqLogic.configuration.Centre));
	$('.eqLogicAttr[data-l1key=configuration][data-l2key=Gauche]').val(JSON.stringify(_eqLogic.configuration.Gauche));
	if (typeof(_eqLogic.configuration.heliotrope) !== 'undefined' && _eqLogic.configuration.heliotrope!='') 
		TraceMapZone(_eqLogic);
	if (typeof(_eqLogic.configuration.condition) !== 'undefined') {
		for(var index in _eqLogic.configuration.condition) { 
			if( (typeof _eqLogic.configuration.condition[index] === "object") && (_eqLogic.configuration.condition[index] !== null) )
				addCondition(_eqLogic.configuration.condition[index],$('#conditiontab').find('table tbody'));
		}
	}
	if (typeof(_eqLogic.configuration.action) !== 'undefined') {
		if (typeof(_eqLogic.configuration.action.open) !== 'undefined') {
			for(var index in _eqLogic.configuration.action.open) { 
				if( (typeof _eqLogic.configuration.action.open[index] === "object") && (_eqLogic.configuration.action.open[index] !== null) )
					addAction(_eqLogic.configuration.action.open[index],$('#ouverturetab').find('table tbody'));
			}
		}
		if (typeof(_eqLogic.configuration.action.close) !== 'undefined') {
			for(var index in _eqLogic.configuration.action.close) { 
				if( (typeof _eqLogic.configuration.action.close[index] === "object") && (_eqLogic.configuration.action.close[index] !== null) )
					addAction(_eqLogic.configuration.action.close[index],$('#fermeturetab').find('table tbody'));
			}
		}
	}	
}
function TraceMapZone(_zone){
	DroitLatLng.lat=CentreLatLng.lat;
	DroitLatLng.lng=CentreLatLng.lng- (1 / 3600);
	GaucheLatLng.lat=CentreLatLng.lat;
	GaucheLatLng.lng=CentreLatLng.lng+ (1 / 3600);
	if (typeof(_zone.configuration.Droite) !== 'undefined' && _zone.configuration.Droite != "") {
		if (typeof(_zone.configuration.Droite.lat) !== 'undefined' && _zone.configuration.Droite.lat != "" ) 
			DroitLatLng.lat=parseFloat(_zone.configuration.Droite.lat);
		if (typeof(_zone.configuration.Droite.lng) !== 'undefined' && _zone.configuration.Droite.lng != "" ) 
			DroitLatLng.lng=parseFloat(_zone.configuration.Droite.lng);
	}
	if (typeof(_zone.configuration.Gauche) !== 'undefined' && _zone.configuration.Gauche != "") {
		if (typeof(_zone.configuration.Gauche.lat) !== 'undefined' && _zone.configuration.Gauche.lat != "" ) 
			GaucheLatLng.lat=parseFloat(_zone.configuration.Gauche.lat);
		if (typeof(_zone.configuration.Gauche.lng) !== 'undefined' && _zone.configuration.Gauche.lng != "" ) 
			GaucheLatLng.lng=parseFloat(_zone.configuration.Gauche.lng);
	}
	if (typeof(_zone.configuration.Centre) !== 'undefined' && _zone.configuration.Centre != "") {
		if (typeof(_zone.configuration.Centre.lat) !== 'undefined' && _zone.configuration.Centre.lat != "" ) 
			CentreLatLng.lat=parseFloat(_zone.configuration.Centre.lat);
		if (typeof(_zone.configuration.Centre.lng) !== 'undefined' && _zone.configuration.Centre.lng != "" )
			CentreLatLng.lng=parseFloat(_zone.configuration.Centre.lng);
	}
	var features = [];
	var PolylineDroite = new ol.geom.Polygon([[[CentreLatLng.lng,CentreLatLng.lat], [DroitLatLng.lng,DroitLatLng.lat]]]);
	PolylineDroite.transform('EPSG:4326', 'EPSG:3857');
	features.push(new ol.Feature(PolylineDroite));
	var PolylineGauche = new ol.geom.Polygon([[[CentreLatLng.lng,CentreLatLng.lat], [GaucheLatLng.lng,GaucheLatLng.lat]]]);
	PolylineGauche.transform('EPSG:4326', 'EPSG:3857');
	features.push(new ol.Feature(PolylineGauche));
	var Droit = new ol.Feature({
		geometry: new ol.geom.Point(ol.proj.transform([DroitLatLng.lng,DroitLatLng.lat], 'EPSG:4326', 'EPSG:3857'))
	});
	Droit.setStyle([  
		new ol.style.Style({      
			image: new ol.style.Circle({
     				radius: 5,
        			stroke: new ol.style.Stroke({
          				color: '#000'
				}),
				fill: new ol.style.Fill({
					color: 'rgba(255,255,255,0.4)'
				}),
      			}),
			text: new ol.style.Text({
				text: _zone.name + " - Droite vue extérieur",
				offsetY: -25,
				fill: new ol.style.Fill({
					color: '#fff'
				})
			})
		})
	]);
	map.addInteraction(new ol.interaction.Modify({
		features: new ol.Collection([Droit]),
		style: null
	}));
	Droit.on('change',function(){
		var coord = this.getGeometry().getCoordinates();
		coord = ol.proj.transform(coord, 'EPSG:3857', 'EPSG:4326');
		DroitLatLng.lat= coord[1];
		DroitLatLng.lng= coord[0];
		$('.eqLogicAttr[data-l1key=configuration][data-l2key=Droite]').val(JSON.stringify(DroitLatLng));
		PolylineDroite.setCoordinates([[[CentreLatLng.lng,CentreLatLng.lat], [DroitLatLng.lng,DroitLatLng.lat]]]);
		PolylineDroite.transform('EPSG:4326', 'EPSG:3857');
	},Droit);
	features.push(Droit);
	var Centre = new ol.Feature({
		geometry: new ol.geom.Point(ol.proj.transform([CentreLatLng.lng,CentreLatLng.lat], 'EPSG:4326', 'EPSG:3857'))
	});
	map.addInteraction(new ol.interaction.Modify({
		features: new ol.Collection([Centre]),
		style: null
	}));
	Centre.on('change',function(){
		var coord = this.getGeometry().getCoordinates();
		coord = ol.proj.transform(coord, 'EPSG:3857', 'EPSG:4326');
		CentreLatLng.lat= coord[1];
		CentreLatLng.lng= coord[0];
		$('.eqLogicAttr[data-l1key=configuration][data-l2key=Centre]').val(JSON.stringify(CentreLatLng));
		PolylineDroite.setCoordinates([[[CentreLatLng.lng,CentreLatLng.lat], [DroitLatLng.lng,DroitLatLng.lat]]]);
		PolylineDroite.transform('EPSG:4326', 'EPSG:3857');
		PolylineGauche.setCoordinates([[[CentreLatLng.lng,CentreLatLng.lat], [GaucheLatLng.lng,GaucheLatLng.lat]]]);
		PolylineGauche.transform('EPSG:4326', 'EPSG:3857');
	},Centre);
	features.push(Centre);
	var Gauche = new ol.Feature({
		geometry: new ol.geom.Point(ol.proj.transform([GaucheLatLng.lng,GaucheLatLng.lat], 'EPSG:4326', 'EPSG:3857')),
		style: new ol.style.Style({text:new ol.style.Text({text: _zone.name + " - Gauche vue extérieur"})})
	});
	Gauche.setStyle([
		new ol.style.Style({  
			image: new ol.style.Circle({
     				radius: 5,
        			stroke: new ol.style.Stroke({
          				color: '#000'
				}),
				fill: new ol.style.Fill({
					color: 'rgba(255,255,255,0.4)'
				}),
      			}),
			text: new ol.style.Text({
				text: _zone.name + " - Gauche vue extérieur",
				offsetY: -25,
				fill: new ol.style.Fill({
					color: '#fff'
				})
			})
		})
	]);
	map.addInteraction(new ol.interaction.Modify({
		features: new ol.Collection([Gauche]),
		style: null
	}));
	Gauche.on('change',function(){
		var coord = this.getGeometry().getCoordinates();
		coord = ol.proj.transform(coord, 'EPSG:3857', 'EPSG:4326');
		GaucheLatLng.lat= coord[1];
		GaucheLatLng.lng= coord[0];
		$('.eqLogicAttr[data-l1key=configuration][data-l2key=Gauche]').val(JSON.stringify(GaucheLatLng));
		PolylineGauche.setCoordinates([[[CentreLatLng.lng,CentreLatLng.lat], [GaucheLatLng.lng,GaucheLatLng.lat]]]);
		PolylineGauche.transform('EPSG:4326', 'EPSG:3857');
	},Gauche);
	features.push(Gauche);
	var vectorLayer = new ol.layer.Vector({
		source: new ol.source.Vector({
			features: features 
		})
	});
	map.addLayer(vectorLayer);
	map.getView().fit(vectorLayer.getSource().getExtent(), map.getSize());
}
function addCondition(_condition,_el) {
	var tr = $('<tr class="ConditionGroup">')
		.append($('<td>')
			.append($('<input type="checkbox" class="expressionAttr" data-l1key="enable"/>')))
		.append($('<td>')
			.append($('<div class="input-group">')
				.append($('<span class="input-group-btn">')
					.append($('<a class="btn btn-default conditionAttr btn-sm" data-action="remove">')
						.append($('<i class="fa fa-minus-circle">'))))
				.append($('<input class="expressionAttr form-control input-sm cmdCondition" data-l1key="expression"/>'))
				.append($('<span class="input-group-btn">')
					.append($('<a class="btn btn-warning btn-sm listCmdCondition">')
						.append($('<i class="fa fa-list-alt">'))))))
		.append($('<td>')
			.append($('<select class="expressionAttr form-control input-sm cmdCondition" data-l1key="TypeGestion" />')
			       .append($('<option value="all">')
					.text('{{Position du soleil et Jour / Nuit}}'))
			       .append($('<option value="Helioptrope">')
					.text('{{Position du soleil}}'))
			       .append($('<option value="DayNight">')
					.text('{{Jour / Nuit}}'))
			       .append($('<option value="Day">')
					.text('{{Jour}}'))
			       .append($('<option value="Night">')
					.text('{{Nuit}}')))
			.append($('<select class="expressionAttr form-control input-sm cmdCondition" data-l1key="saison" />')
			       .append($('<option value="all">')
					.text('{{Toutes les saisons}}'))
			       .append($('<option value="été">')
					.text('{{Eté}}'))
			       .append($('<option value="hiver">')
					.text('{{Hivers}}')))
			.append($('<select class="expressionAttr form-control input-sm cmdCondition" data-l1key="evaluation" />')
			       .append($('<option value="all">')
					.text('{{Ouverture et Fermeture}}'))
			       .append($('<option value="close">')
					.text('{{Fermeture}}'))
			       .append($('<option value="open">')
					.text('{{Ouverture}}')))
			.append($('<select class="expressionAttr form-control input-sm cmdCondition" data-l1key="controle" />')
			       .append($('<option value="No">')
					.text('{{Condition normale}}'))
			       .append($('<option value="Yes">')
					.text('{{Condition vérifiée à l\'inverse si soleil dans fenêtre. Permet d\'ouvrir le volet l\'été et le fermer l\'hiver}}'))))	
		.append($('<td>'));

        _el.append(tr);
        _el.find('tr:last').setValues(_condition, '.expressionAttr');
  
}
function addAction(_action,  _el) {
	var tr = $('<tr class="ActionGroup">')
		.append($('<td>')
			.append($('<input type="checkbox" class="expressionAttr" data-l1key="enable"/>')))		
		.append($('<td>')
			.append($('<div class="input-group">')
				.append($('<span class="input-group-btn">')
					.append($('<a class="btn btn-default ActionAttr btn-sm" data-action="remove">')
						.append($('<i class="fa fa-minus-circle">'))))
				.append($('<input class="expressionAttr form-control input-sm cmdAction" data-l1key="cmd"/>'))
				.append($('<span class="input-group-btn">')
					.append($('<a class="btn btn-success btn-sm listAction" title="Sélectionner un mot-clé">')
						.append($('<i class="fa fa-tasks">')))
					.append($('<a class="btn btn-success btn-sm listCmdAction">')
						.append($('<i class="fa fa-list-alt">'))))))
		.append($('<td>')
		       .append($(jeedom.cmd.displayActionOption(init(_action.cmd, ''), _action.options))));
        _el.append(tr);
        _el.find('tr:last').setValues(_action, '.expressionAttr');
  
}
$('#tab_zones a').click(function(e) {
    e.preventDefault();
    $(this).tab('show');
});
$('body').on('focusout','.expressionAttr[data-l1key=cmd]', function (event) {
    var expression = $(this).closest('.ActionGroup').getValues('.expressionAttr');
    var el = $(this);
    jeedom.cmd.displayActionOption($(this).value(), init(expression[0].options), function (html) {
        el.closest('.ActionGroup').find('.actionOptions').html(html);
    })
});
$('body').on('click','.conditionAttr[data-action=add]',function(){
	addCondition({},$(this).closest('.tab-pane').find('table'));
});
$('body').on('click','.conditionAttr[data-action=remove]',function(){
	$(this).closest('tr').remove();
});
$('body').on('click','.listCmdCondition',function(){
	var el = $(this).closest('tr').find('.expressionAttr[data-l1key=expression]');	
	jeedom.cmd.getSelectModal({cmd: {type: 'info'}}, function (result) {
		var message = 'Aucun choix possible';
		if(result.cmd.subType == 'numeric'){
			message = '<div class="row">  ' +
			'<div class="col-md-12"> ' +
			'<form class="form-horizontal" onsubmit="return false;"> ' +
			'<div class="form-group"> ' +
			'<label class="col-xs-5 control-label" >'+result.human+' {{est}}</label>' +
			'             <div class="col-xs-3">' +
			'                <select class="conditionAttr form-control" data-l1key="operator">' +
			'                    <option value="==">{{égal}}</option>' +
			'                  <option value=">">{{supérieur}}</option>' +
			'                  <option value="<">{{inférieur}}</option>' +
			'                 <option value="!=">{{différent}}</option>' +
			'            </select>' +
			'       </div>' +
			'      <div class="col-xs-4">' +
			'         <input type="number" class="conditionAttr form-control" data-l1key="operande" />' +
			'    </div>' +
			'</div>' +
			'<div class="form-group"> ' +
			'<label class="col-xs-5 control-label" >{{Ensuite}}</label>' +
			'             <div class="col-xs-3">' +
			'                <select class="conditionAttr form-control" data-l1key="next">' +
			'                    <option value="">rien</option>' +
			'                  <option value="OU">{{ou}}</option>' +
			'            </select>' +
			'       </div>' +
			'</div>' +
			'</div> </div>' +
			'</form> </div>  </div>';
		}
		if(result.cmd.subType == 'string'){
			message = '<div class="row">  ' +
			'<div class="col-md-12"> ' +
			'<form class="form-horizontal" onsubmit="return false;"> ' +
			'<div class="form-group"> ' +
			'<label class="col-xs-5 control-label" >'+result.human+' {{est}}</label>' +
			'             <div class="col-xs-3">' +
			'                <select class="conditionAttr form-control" data-l1key="operator">' +
			'                    <option value="==">{{égale}}</option>' +
			'                  <option value="matches">{{contient}}</option>' +
			'                 <option value="!=">{{différent}}</option>' +
			'            </select>' +
			'       </div>' +
			'      <div class="col-xs-4">' +
			'         <input class="conditionAttr form-control" data-l1key="operande" />' +
			'    </div>' +
			'</div>' +
			'<div class="form-group"> ' +
			'<label class="col-xs-5 control-label" >{{Ensuite}}</label>' +
			'             <div class="col-xs-3">' +
			'                <select class="conditionAttr form-control" data-l1key="next">' +
			'                    <option value="">{{rien}}</option>' +
			'                  <option value="OU">{{ou}}</option>' +
			'            </select>' +
			'       </div>' +
			'</div>' +
			'</div> </div>' +
			'</form> </div>  </div>';
		}
		if(result.cmd.subType == 'binary'){
			message = '<div class="row">  ' +
			'<div class="col-md-12"> ' +
			'<form class="form-horizontal" onsubmit="return false;"> ' +
			'<div class="form-group"> ' +
			'<label class="col-xs-5 control-label" >'+result.human+' {{est}}</label>' +
			'            <div class="col-xs-7">' +
			'                 <input class="conditionAttr" data-l1key="operator" value="==" style="display : none;" />' +
			'                  <select class="conditionAttr form-control" data-l1key="operande">' +
			'                       <option value="1">{{Ouvert}}</option>' +
			'                       <option value="0">{{Fermé}}</option>' +
			'                       <option value="1">{{Allumé}}</option>' +
			'                       <option value="0">{{Éteint}}</option>' +
			'                       <option value="1">{{Déclenché}}</option>' +
			'                       <option value="0">{{Au repos}}</option>' +
			'                       </select>' +
			'                    </div>' +
			'                 </div>' +
			'<div class="form-group"> ' +
			'<label class="col-xs-5 control-label" >{{Ensuite}}</label>' +
			'             <div class="col-xs-3">' +
			'                <select class="conditionAttr form-control" data-l1key="next">' +
			'                  <option value="">{{rien}}</option>' +
			'                  <option value="OU">{{ou}}</option>' +
			'            </select>' +
			'       </div>' +
			'</div>' +
			'</div> </div>' +
			'</form> </div>  </div>';
		}

		bootbox.dialog({
			title: "{{Ajout d'une nouvelle condition}}",
			message: message,
			buttons: {
				"Ne rien mettre": {
					className: "btn-default",
					callback: function () {
						el.atCaret('insert', result.human);
					}
				},
				success: {
					label: "Valider",
					className: "btn-primary",
					callback: function () {
    						var condition = result.human;
						condition += ' ' + $('.conditionAttr[data-l1key=operator]').value();
						if(result.cmd.subType == 'string'){
							if($('.conditionAttr[data-l1key=operator]').value() == 'matches'){
								condition += ' "/' + $('.conditionAttr[data-l1key=operande]').value()+'/"';
							}else{
								condition += ' "' + $('.conditionAttr[data-l1key=operande]').value()+'"';
							}
						}else{
							condition += ' ' + $('.conditionAttr[data-l1key=operande]').value();
						}
						condition += ' ' + $('.conditionAttr[data-l1key=next]').value()+' ';
						el.atCaret('insert', condition);
						if($('.conditionAttr[data-l1key=next]').value() != ''){
							el.click();
						}
					}
				},
			}
		});
	});
});
$('body').on('click','.ActionAttr[data-action=add]',function(){
	addAction({},$(this).closest('.tab-pane').find('table'));
});
$('body').on('click','.ActionAttr[data-action=remove]', function () {
	$(this).closest('.ActionGroup').remove();
});
$("body").on('click', ".listAction", function() {
	var el = $(this).closest('td').find('.expressionAttr[data-l1key=cmd]');
	jeedom.getSelectActionModal({}, function (result) {
		el.value(result.human);
		jeedom.cmd.displayActionOption(el.value(), '', function (html) {
			el.closest('.form-group').find('.actionOptions').html(html);
		});
	});
}); 
$("body").on('click', ".listCmdAction", function() {
	var el = $(this).closest('td').find('.expressionAttr[data-l1key=cmd]');
	jeedom.cmd.getSelectModal({cmd: {type: 'action'}}, function (result) {
		el.value(result.human);
		jeedom.cmd.displayActionOption(el.value(), '', function (html) {
			el.closest('.form-group').find('.actionOptions').html(html);
		});
	});
});
function addCmdToTable(_cmd) {
	var tr =$('<tr class="cmd" data-cmd_id="' + init(_cmd.id) + '">');
	tr.append($('<td>')
		.append($('<input type="hidden" class="cmdAttr form-control input-sm" data-l1key="id">'))
		.append($('<input class="cmdAttr form-control input-sm" data-l1key="name" value="' + init(_cmd.name) + '" placeholder="{{Name}}" title="Name">')));
	var parmetre=$('<td>');	
	parmetre.append($('<span class="type" type="' + init(_cmd.type) + '">')
			.append(jeedom.cmd.availableType()));
	parmetre.append($('<span class="subType" subType="'+init(_cmd.subType)+'">'));
	if (is_numeric(_cmd.id)) {
		parmetre.append($('<a class="btn btn-default btn-xs cmdAction" data-action="test">')
			.append($('<i class="fa fa-rss">')
				.text('{{Tester}}')));
	}
	parmetre.append($('<a class="btn btn-default btn-xs cmdAction tooltips" data-action="configure">')
		.append($('<i class="fa fa-cogs">')));
	parmetre.append($('<div>')
		.append($('<span>')
			.append($('<label class="checkbox-inline">')
				.append($('<input type="checkbox" class="cmdAttr checkbox-inline" data-size="mini" data-label-text="{{Historiser}}" data-l1key="isHistorized" checked/>'))
				.append('{{Historiser}}')
				.append($('<sup>')
					.append($('<i class="fa fa-question-circle tooltips" style="font-size : 1em;color:grey;">')
					.attr('title','Souhaitez vous Historiser les changements de valeur'))))));
	parmetre.append($('<div>')
		.append($('<span>')
			.append($('<label class="checkbox-inline">')
				.append($('<input type="checkbox" class="cmdAttr checkbox-inline" data-size="mini" data-label-text="{{Afficher}}" data-l1key="isVisible" checked/>'))
				.append('{{Afficher}}')
				.append($('<sup>')
					.append($('<i class="fa fa-question-circle tooltips" style="font-size : 1em;color:grey;">')
					.attr('title','Souhaitez vous afficher cette commande sur le dashboard'))))));
	tr.append(parmetre);
	$('#table_cmd tbody').append(tr);
	$('#table_cmd tbody tr:last').setValues(_cmd, '.cmdAttr');
	jeedom.cmd.changeType($('#table_cmd tbody tr:last'), init(_cmd.subType));
}
et Volets/core/class/Volets.class.php

Code : Tout sélectionner

<?php
require_once dirname(__FILE__) . '/../../../../core/php/core.inc.php';
class Volets extends eqLogic {
	public static function deamon_info() {
		$return = array();
		$return['log'] = 'Volets';
		$return['launchable'] = 'ok';
		$return['state'] = 'nok';
		foreach(eqLogic::byType('Volets') as $Volet){
			if($Volet->getIsEnable()){
				$listener = listener::byClassAndFunction('Volets', 'pull', array('Volets_id' => $Volet->getId()));
			if (!is_object($listener))
					return $return;
				if ($Volet->getConfiguration('DayNight')){
					$cron = cron::byClassAndFunction('Volets', 'ActionJour', array('Volets_id' => $Volet->getId()));
					if (!is_object($cron)) 	
						return $return;
					$cron = cron::byClassAndFunction('Volets', 'ActionNuit', array('Volets_id' => $Volet->getId()));
					if (!is_object($cron)) 	
						return $return;
				}
			}
		}
		$return['state'] = 'ok';
		return $return;
	}
	public static function deamon_start($_debug = false) {
		log::remove('Volets');
		self::deamon_stop();
		$deamon_info = self::deamon_info();
		if ($deamon_info['launchable'] != 'ok') 
			return;
		if ($deamon_info['state'] == 'ok') 
			return;
		foreach(eqLogic::byType('Volets') as $Volet)
			$Volet->StartDemon();
	}
	public static function deamon_stop() {	
		foreach(eqLogic::byType('Volets') as $Volet){
			$listener = listener::byClassAndFunction('Volets', 'pull', array('Volets_id' => $Volet->getId()));
			if (is_object($listener))
				$listener->remove();
			$cron = cron::byClassAndFunction('Volets', 'ActionJour', array('Volets_id' => $Volet->getId()));
			if (is_object($cron)) 	
				$cron->remove();
			$cron = cron::byClassAndFunction('Volets', 'ActionNuit', array('Volets_id' => $Volet->getId()));
			if (is_object($cron)) 	
				$cron->remove();
		}
	}
	public static function pull($_option) {
		log::add('Volets', 'debug', 'Objet mis à jour => ' . json_encode($_option));
		$Volet = Volets::byId($_option['Volets_id']);
		if (is_object($Volet) && $Volet->getIsEnable()) {
			$Event = cmd::byId($_option['event_id']);
			if(is_object($Event)){
				switch($Event->getlogicalId()){
					case 'azimuth360':
						log::add('Volets', 'info',$Volet->getHumanName().' : Gestion des volets par l\'azimuth');
						$Volet->ActionAzimute($_option['value']);
					break;
					case 'sunrise':
						log::add('Volets', 'info',$Volet->getHumanName().' : Replanification de l\'ouverture au lever du soleil');	
						$timstamp=$Volet->CalculHeureEvent($_option['value'],'DelaisDay');
						$Schedule=date("i",$timstamp) . ' ' . date("H",$timstamp) . ' * * * *';
						$cron = $Volet->CreateCron($Schedule, 'ActionJour');
					break;
					case 'sunset':	
						log::add('Volets', 'info',$Volet->getHumanName().' : Replanification de la fermeture au coucher du soleil');	
						$timstamp=$Volet->CalculHeureEvent($_option['value'],'DelaisNight');
						$Schedule=date("i",$timstamp) . ' ' . date("H",$timstamp) . ' * * * *';
						$cron = $Volet->CreateCron($Schedule, 'ActionNuit');
					break;
				}
			}
		}
	}
	public static function ActionJour($_option) {    
		log::add('Volets', 'debug', 'Objet mis à jour => ' . json_encode($_option));
		$Volet = Volets::byId($_option['Volets_id']);
		if (is_object($Volet) && $Volet->getIsEnable()) {
			log::add('Volets', 'info', $Volet->getHumanName().' : Exécution de la gestion du lever du soleil');
			$Saison=$Volet->getSaison();
			$result=$Volet->EvaluateCondition('open',$Saison,'Day','No');
			if($result){
				$Action=$Volet->getConfiguration('action');
				$Volet->ExecuteAction($Action['open']);
				cache::set('Volets::Position::'.$Volet->getId(), 'open', 0);
			}else{
				log::add('Volets', 'info',$Volet->getHumanName().' : Replanification de l\'évaluation des conditions d\'ouverture au lever du soleil');
				$timstamp=$Volet->CalculHeureEvent(date('Hi'),'DelaisEval');
				$Schedule=date("i",$timstamp) . ' ' . date("H",$timstamp) . ' * * * *';
				$cron = $Volet->CreateCron($Schedule, 'ActionJour', array('Volets_id' => intval($Volet->getId())));
			}
		}
	}
	public static function ActionNuit($_option) {
		log::add('Volets', 'debug', 'Objet mis à jour => ' . json_encode($_option));
		$Volet = Volets::byId($_option['Volets_id']);
		if (is_object($Volet) && $Volet->getIsEnable()) {
			log::add('Volets', 'info',$Volet->getHumanName().' : Exécution de la gestion du coucher du soleil ');
			$Saison=$Volet->getSaison();
			$result=$Volet->EvaluateCondition('close',$Saison,'Night','No');
			if($result){
				$Action=$Volet->getConfiguration('action');
				$Volet->ExecuteAction($Action['close']);
				cache::set('Volets::Position::'.$Volet->getId(), 'close', 0);
			}else{
				log::add('Volets', 'info', $Volet->getHumanName().' : Replanification de l\'évaluation des conditions de fermeture au coucher du soleil');
				$timstamp=$Volet->CalculHeureEvent(date('Hi'),'DelaisEval');
				$Schedule=date("i",$timstamp) . ' ' . date("H",$timstamp) . ' * * * *';
				$cron = $Volet->CreateCron($Schedule, 'ActionNuit', array('Volets_id' => intval($Volet->getId())));
			}
		}
	}
  	public function ActionAzimute($Azimuth) {
		if($this->getCmd(null,'isArmed')->execCmd()){
			if($this->checkJour()){
				$Saison=$this->getSaison();
				$Evenement=$this->SelectAction($Azimuth,$Saison);
				if($Evenement != false){
					$conditon=$this->EvaluateCondition($Evenement,$Saison,'Helioptrope','No');
					/*if(!$conditon && $Evenement =='open')
                     				$Evenement =='close';
					if(!$conditon && $Evenement =='close')
                      				$Evenement =='open';*/
					$position = cache::byKey('Volets::Position::'.$this->getId());
					if(!$conditon) {
						log::add('Volets','info',$this->getHumanName().' : Je teste les conditions inversées');
						$conditon=$this->EvaluateCondition($Evenement,$Saison,'Helioptrope','Yes');
						if($conditon) {
							$Action=$this->getConfiguration('action');
							if($position->getValue('') == $Evenement and $Evenement == 'close' and $Saison == 'été'){
								log::add('Volets','info',$this->getHumanName().' : Position actuelle est '.$Evenement.' conditions inversées validées, j ouvre les volets');
								$this->ExecuteAction($Action['open']);
								cache::set('Volets::Position::'.$this->getId(), 'open', 0);						
							}
							if($position->getValue('') == $Evenement and $Evenement == 'open' and $Saison == 'hivers'){
								log::add('Volets','info',$this->getHumanName().' : Position actuelle est '.$Evenement.' conditions inversées validées, je ferme les volets');
								$this->ExecuteAction($Action['close']);
								cache::set('Volets::Position::'.$this->getId(), 'close', 0);						
							}
						}
						return;
					}
					$Action=$this->getConfiguration('action');
                    $position = cache::byKey('Volets::Position::'.$this->getId());
					if($position->getValue('') != $Evenement){
						log::add('Volets','info',$this->getHumanName().' : Position actuelle est '.$Evenement);
						$this->ExecuteAction($Action[$Evenement]);
			      			cache::set('Volets::Position::'.$this->getId(), $Evenement, 0);
					}
					else {
						log::add('Volets','info',$this->getHumanName().' : Position actuelle est '.$Evenement.' les volets sont déjà dans la bonne position, je ne fait rien');
					}
				}
				return;
			}
			log::add('Volets','debug',$this->getHumanName().' : Il fait nuit, la gestion par azimuth est désactivée');
		}
		else
			log::add('Volets','debug',$this->getHumanName().' : Gestion par azimuth désactivée');
	}
   	public function checkJour() {
		$heliotrope=eqlogic::byId($this->getConfiguration('heliotrope'));
		if(is_object($heliotrope)){	
			$sunrise=$heliotrope->getCmd(null,'sunrise');
			if(is_object($sunrise)){
				$value=$sunrise->execCmd();
				$Jours= new DateTime('@' .$this->CalculHeureEvent($value,'DelaisDay'));
			}
			else{	
				log::add('Volets','debug',$this->getHumanName().' : L\'objet "sunrise" n\'a pas été trouvé');
				return false;
			}
			$sunset=$heliotrope->getCmd(null,'sunset');
			if(is_object($sunset)){
				$value=$sunset->execCmd();
				$Nuit= new DateTime('@' .$this->CalculHeureEvent($value,'DelaisNight'));
			}else{	
				log::add('Volets','debug',$this->getHumanName().' : L\'objet "sunset" n\'a pas été trouvé');
				return false;
			}
			$Now=new DateTime();
			if($Now>$Jours && $Now<$Nuit)
				return true;
		}else
			log::add('Volets','debug',$this->getHumanName().' : Aucune commande Héliotrope configurée');
		return false;
	}		
	public function CheckAngle($Azimuth) {
		$Droite=$this->getConfiguration('Droite');
		$Gauche=$this->getConfiguration('Gauche');
		$Centre=$this->getConfiguration('Centre');
		if(is_array($Droite)&&is_array($Centre)&&is_array($Gauche)){
			$AngleCntDrt=$this->getAngle(
				$Centre['lat'],
				$Centre['lng'],
				$Droite['lat'],
				$Droite['lng']);
			$AngleCntGau=$this->getAngle(
				$Centre['lat'],
				$Centre['lng'],
				$Gauche['lat'],
				$Gauche['lng']);
			log::add('Volets','info',$this->getHumanName().' : La fenêtre d\'ensoleillement est comprise entre : '.$AngleCntDrt.'° et '.$AngleCntGau.'°');
			if ($AngleCntDrt < $AngleCntGau){
				if($AngleCntDrt <= $Azimuth && $Azimuth <= $AngleCntGau)
					return true;
			}else{
				if($AngleCntDrt <= $Azimuth && $Azimuth <= 360)
					return true;
				if(0 <= $Azimut && $Azimuth <= $AngleCntGau)
					return true;
			}
		}else
			log::add('Volets','debug',$this->getHumanName().' : Les coordonnées GPS de l\'angle d\'exposition au soleil de votre fenêtre sont mal configurées');
		return false;			
	}	
	public function getSaison() {
		$isInWindows=$this->getCmd(null,'isInWindows');
		if(!is_object($isInWindows))
			return false;
		if($isInWindows->execCmd()){
			log::add('Volets','info',$this->getHumanName().' : Le plugin est configuré en mode hiver');
			return 'hiver';
		}else{
			log::add('Volets','info',$this->getHumanName().' : Le plugin est configuré en mode été');
			return 'été';
		}
		return false;
	}	
	public function SelectAction($Azimuth,$saison) {
		$Action=false;
		$StateCmd=$this->getCmd(null,'state');
		if(!is_object($StateCmd))
			return false;
		if($this->CheckAngle($Azimuth)){
			$StateCmd->event(true);
			log::add('Volets','info',$this->getHumanName().' : Le soleil est dans la fenêtre');
			if($saison =='hiver')
				$Action='open';
			else
				$Action='close';
		}else{
			$StateCmd->event(false);
			log::add('Volets','info',$this->getHumanName().' : Le soleil n\'est pas dans la fenêtre');
			if($saison == 'été')
				$Action='open';
			else
				$Action='close';
		}
		$StateCmd->setCollectDate(date('Y-m-d H:i:s'));
		$StateCmd->save();
		return $Action;
	}
	public function ExecuteAction($Action) {	
		foreach($Action as $cmd){
			if (isset($cmd['enable']) && $cmd['enable'] == 0)
				continue;
			try {
				$options = array();
				if (isset($cmd['options'])) 
					$options = $cmd['options'];
				scenarioExpression::createAndExec('action', $cmd['cmd'], $options);
			} catch (Exception $e) {
				log::add('Volets', 'error',$this->getHumanName().' : '. __('Erreur lors de l\'exécution de ', __FILE__) . $action['cmd'] . __('. Détails : ', __FILE__) . $e->getMessage());
			}
			$Commande=cmd::byId(str_replace('#','',$cmd['cmd']));
			if(is_object($Commande)){
				if($this->getConfiguration('isRandom'))
				   sleep(rand(0,$this->getConfiguration('DelaisPresence')));
				log::add('Volets','debug',$this->getHumanName().' : Exécution de '.$Commande->getHumanName());
				$Commande->event($cmd['options']);
			}
		}
	}
	public function CalculHeureEvent($HeureStart, $delais) {
		if(strlen($HeureStart)==3)
			$Heure=substr($HeureStart,0,1);
		else
			$Heure=substr($HeureStart,0,2);
		$Minute=floatval(substr($HeureStart,-2));
		if($this->getConfiguration($delais)!='')
			$Minute+=floatval($this->getConfiguration($delais));
		while($Minute>=60){
			$Minute-=60;
			$Heure+=1;
		}
		return mktime($Heure,$Minute);
	}
	public function CreateCron($Schedule, $logicalId) {
		$cron =cron::byClassAndFunction('Volets', $logicalId, array('Volets_id' => $this->getId()));
			if (!is_object($cron)) {
				$cron = new cron();
				$cron->setClass('Volets');
				$cron->setFunction($logicalId);
				$cron->setOption(array('Volets_id' => $this->getId()));
				$cron->setEnable(1);
				$cron->setDeamon(0);
				$cron->setSchedule($Schedule);
				$cron->save();
			}else{
				$cron->setSchedule($Schedule);
				$cron->save();
			}
		return $cron;
	}
	public function EvaluateCondition($Evenement,$Saison,$TypeGestion,$Controle){
		foreach($this->getConfiguration('condition') as $condition){
			if($condition['evaluation']!=$Evenement && $condition['evaluation']!='all')
				continue;
			if($condition['saison']!=$Saison && $condition['saison']!='all')
				continue;
			if(stripos($condition['TypeGestion'],$TypeGestion) === false && $condition['TypeGestion']!='all')	
				continue;		
			if (isset($condition['enable']) && $condition['enable'] == 0)
				continue;
			$_scenario = null;
			$expression = scenarioExpression::setTags($condition['expression'], $_scenario, true);
			$message = __('Evaluation de la condition : [', __FILE__) . trim($expression) . '] = ';
			$result = evaluate($expression);
			if (is_bool($result)) {
				if ($result) {
					$message .= __('Vrai', __FILE__);
				} else {
					$message .= __('Faux', __FILE__);
				}
			} else {
				$message .= $result;
			}
			if($Controle == 'Yes' and $condition['controle'] == 'Yes' and !$result) {
				$result = true;
				$message .= __(' inversé', __FILE__);
			} 
			log::add('Volets','info',$this->getHumanName().' : '.$message);
			if(!$result){
				log::add('Volets','info',$this->getHumanName().' : Les conditions ne sont pas remplies');
				return false;
			}
		}
		log::add('Volets','info',$this->getHumanName().' :  Les conditions sont remplies');
		return true;
	}
	public function getAngle($latitudeOrigine,$longitudeOrigne, $latitudeDest,$longitudeDest) { 
		$rlongitudeOrigne = deg2rad($longitudeOrigne); 
		$rlatitudeOrigine = deg2rad($latitudeOrigine); 
		$rlongitudeDest = deg2rad($longitudeDest); 
		$rlatitudeDest = deg2rad($latitudeDest); 
		$longDelta = $rlongitudeDest - $rlongitudeOrigne; 
		$y = sin($longDelta) * cos($rlatitudeDest); 
		$x = (cos($rlatitudeOrigine)*sin($rlatitudeDest)) - (sin($rlatitudeOrigine)*cos($rlatitudeDest)*cos($longDelta)); 
		$angle = rad2deg(atan2($y, $x)); 
		if ($angle < 0) { 

			$angle += 360; 
		}
		return floatval($angle % 360);
	}
	public function StartDemon() {
		if($this->getIsEnable()){
			$heliotrope=eqlogic::byId($this->getConfiguration('heliotrope'));
			if(is_object($heliotrope)){
				$sunrise=$heliotrope->getCmd(null,'sunrise');
				if(!is_object($sunrise))
					return false;
				$sunset=$heliotrope->getCmd(null,'sunset');
				if(!is_object($sunset))
					return false;
				$listener = listener::byClassAndFunction('Volets', 'pull', array('Volets_id' => $this->getId()));
				if (!is_object($listener))
				    $listener = new listener();
				$listener->setClass('Volets');
				$listener->setFunction('pull');
				$listener->setOption(array('Volets_id' => $this->getId()));
				$listener->emptyEvent();
				if ($this->getConfiguration('Helioptrope'))
					$listener->addEvent($heliotrope->getCmd(null,'azimuth360')->getId());
				if ($this->getConfiguration('DayNight')){
					$listener->addEvent($sunrise->getId());
					$listener->addEvent($sunset->getId());
					$value=$sunrise->execCmd();
					$timstamp=$this->CalculHeureEvent($value,'DelaisDay');
					$Schedule=date("i",$timstamp) . ' ' . date("H",$timstamp) . ' * * * *';
					$cron = $this->CreateCron($Schedule, 'ActionJour', array('Volets_id' => intval($this->getId())));
					$value=$sunset->execCmd();
					$timstamp=$this->CalculHeureEvent($value,'DelaisNight');
					$Schedule=date("i",$timstamp) . ' ' . date("H",$timstamp) . ' * * * *';
					$cron = $this->CreateCron($Schedule, 'ActionNuit', array('Volets_id' => intval($this->getId())));
				}
				$listener->save();	
			}
		}
	}
	public static function AddCommande($eqLogic,$Name,$_logicalId,$Type="info", $SubType='binary',$visible,$Template='') {
		$Commande = $eqLogic->getCmd(null,$_logicalId);
		if (!is_object($Commande))
		{
			$Commande = new VoletsCmd();
			$Commande->setId(null);
			$Commande->setName($Name);
			$Commande->setIsVisible($visible);
			$Commande->setLogicalId($_logicalId);
			$Commande->setEqLogic_id($eqLogic->getId());
			$Commande->setType($Type);
			$Commande->setSubType($SubType);
		}
   		$Commande->setTemplate('dashboard',$Template );
		$Commande->setTemplate('mobile', $Template);
		$Commande->save();
		return $Commande;
	}
	public function postSave() {
		$state=self::AddCommande($this,"Position du soleil","state","info", 'binary',true,'sunInWindows');
		$state->event(false);
		$state->setCollectDate(date('Y-m-d H:i:s'));
		$state->save();
		$isInWindows=self::AddCommande($this,"Etat mode","isInWindows","info","binary",false,'isInWindows');
		$inWindows=self::AddCommande($this,"Mode","inWindows","action","other",true,'inWindows');
		$inWindows->setValue($isInWindows->getId());
		$inWindows->save();
		$isArmed=self::AddCommande($this,"Etat activation","isArmed","info","binary",false,'lock');
		$isArmed->event(true);
		$isArmed->setCollectDate(date('Y-m-d H:i:s'));
		$isArmed->save();
		$Armed=self::AddCommande($this,"Activer","armed","action","other",true,'lock');
		$Armed->setValue($isArmed->getId());
		$Armed->setConfiguration('state', '1');
		$Armed->setConfiguration('armed', '1');
		$Armed->save();
		$Released=self::AddCommande($this,"Désactiver","released","action","other",true,'lock');
		$Released->setValue($isArmed->getId());
		$Released->save();
		$Released->setConfiguration('state', '0');
		$Released->setConfiguration('armed', '1');
		self::deamon_stop();
	}	
	public function postRemove() {
		$listener = listener::byClassAndFunction('Volets', 'pull', array('Volets_id' => $this->getId()));
		if (is_object($listener))
			$listener->remove();
		$cron = cron::byClassAndFunction('Volets', 'ActionJour', array('Volets_id' => $this->getId()));
		if (is_object($cron)) 	
			$cron->remove();
		$cron = cron::byClassAndFunction('Volets', 'ActionNuit', array('Volets_id' => $this->getId()));
		if (is_object($cron)) 	
			$cron->remove();
	}
}
class VoletsCmd extends cmd {
    	public function execute($_options = null) {
		$Listener=cmd::byId(str_replace('#','',$this->getValue()));
		if (is_object($Listener)) {	
			switch($this->getLogicalId()){
				case 'armed':
					$Listener->event(true);
				break;
				case 'released':
					$Listener->event(false);
				break;
				case 'inWindows':
						if($Listener->execCmd())
							$Listener->event(false);
						else
							$Listener->event(true);
				break;
			}
			$Listener->setCollectDate(date('Y-m-d H:i:s'));
			$Listener->save();
		}
	}
}
?>
Jeedom mini PC Core I5 4300U ESXI
Zwave: Z-Stick Gen5, 31 noeuds, XIAOMI: 13 périph RFLINK,RFPLAYER,ZIBASEDOM: OWL, sondes Oregon,Livolo,X2D STARBOX F03, ECO-DEVICE, Bluetooth, ORVIBO, Karotz, RM PRO
Ecran tactile sur Pi 3, Google Home
Site météo: flash.galaxy.free.fr

mutmut
Actif
Messages : 609
Inscription : 10 nov. 2014, 17:09
Localisation : Stutzheim

Re: [Plugin Tiers][Sujet Principal] Volets

Message par mutmut » 16 juin 2017, 10:23

salut @superbricolo,
j'avais la même idée en tête et j'allais passer par d'autres groupes de volets.
Peux-tu mettre tout ça sur le github ?
ça permettra à mika-nt28 de l'intégrer plus facilement et surtout de ne pas passer à côté.
Merci à toi !
Odroid C2 / Jeedom stable
Zwave.me UZB1 / RFXtrx433E / HEM2 / Orvibo / Connexoon / Netatmo
Synology DS1512+ / FBX6


Un grand MERCI à l'équipe Jeedom !

superbricolo
Actif
Messages : 543
Inscription : 01 janv. 2016, 12:45
Contact :

Re: [Plugin Tiers][Sujet Principal] Volets

Message par superbricolo » 16 juin 2017, 17:03

Voilà, j'ai mis sur github. Mais c'est la première fois que je fais ça. J'espère que j'ai tout fait comme il faut.
Jeedom mini PC Core I5 4300U ESXI
Zwave: Z-Stick Gen5, 31 noeuds, XIAOMI: 13 périph RFLINK,RFPLAYER,ZIBASEDOM: OWL, sondes Oregon,Livolo,X2D STARBOX F03, ECO-DEVICE, Bluetooth, ORVIBO, Karotz, RM PRO
Ecran tactile sur Pi 3, Google Home
Site météo: flash.galaxy.free.fr

Avatar de l’utilisateur
mika-nt28
Actif
Messages : 7995
Inscription : 05 août 2014, 08:58
Localisation : Dreux - France

Re: [Plugin Tiers][Sujet Principal] Volets

Message par mika-nt28 » 17 juin 2017, 06:36

Je vais regarder ca de pret
Pour faciliter la compréhension de votre problème, n’oubliez pas de poster
- Des Screenshots de votre configuration
- Le Log au moment du problème constaté

Encouragez-moi https://www.paypal.me/mikant28

Avatar de l’utilisateur
jiminy
Actif
Messages : 756
Inscription : 26 févr. 2016, 18:27
Localisation : Montpellier

Re: [Plugin Tiers][Sujet Principal] Volets

Message par jiminy » 17 juin 2017, 18:35

Hello Michael,
J'ai fait pas mal de programmation mais je découvre le développement Jeedom, donc peut-être que je me trompe, mais pour ta fonction Volets_update, comme avec les changements que tu as fait pour augmenter les possibilités pour les actions plus le changement proposé par superbricolo (très bonne idée qui augmente encore les possibilités, vraiment la version pour Jeedom 3.0, va être super), cela implique de mettre à jour les données pour ceux qui ont déjà des actions configurées, tu devrais envisager une procédure d'upgrade qui prenne en compte la version installée. Il y a un bon exemple de çà dans le plugin DaikinOnlineCtrl. En plus cela simplifierai les évolutions ultérieures, comme le plugin est encore jeune on peut penser qu'il y en aura.
Malheureusement je ne crois pas qu'il y ait un dépot Github pour DaikinOnlineCtrl, mais comme le plugin est gratuit, en l'installant sur un Jeedom de test, tu pourra jeter un œil au code et voir ce que je veux dire.

Avatar de l’utilisateur
mika-nt28
Actif
Messages : 7995
Inscription : 05 août 2014, 08:58
Localisation : Dreux - France

Re: [Plugin Tiers][Sujet Principal] Volets

Message par mika-nt28 » 19 juin 2017, 08:24

La procédure existe mais je l'ai desactivé ce weekend car elle avait un bug lors d'une 2eme mise a jours.
Elle effaçais toute les actions.
Je doit la reprendre avant la sortie effectivement.
Pour faciliter la compréhension de votre problème, n’oubliez pas de poster
- Des Screenshots de votre configuration
- Le Log au moment du problème constaté

Encouragez-moi https://www.paypal.me/mikant28

bolino
Timide
Messages : 48
Inscription : 06 nov. 2015, 16:41
Localisation : pontchateau

Re: [Plugin Tiers][Sujet Principal] Volets

Message par bolino » 23 juin 2017, 14:53

Bonjour,

j'ai trouvé d'ou venait mon soucis de l'heure dans le cron fixée à 21h21... dans l'heliotrope, mes coordonnées GPS etaient réglées avec ce format : xx.xxxxx:xx.xxxxxx ( : entre les valeurs ) , ça fonctionnait comme ça pour les plugins utilisant la geolocalisation, mais le plugin volets semble vouloir le format xx.xxxxx,xx.xxxxxx ( valeurs séparées par une virgule )

par contre ma maison d'il y a 4 ans n'apparait pas sur la map .. dans google map elle apparaissait en vue satelitte mais pas en vue map, du coup le positionnement des fenetres se fait un peu à l'aveugle ;) : ce serait cool de voir la valeur de l'angle en live sur la map en bougeant les pointeurs de fenetres, ça permettrait de regler finement le positionnement selon la position du soleil. en faisant apparaire un cercle avec les valeurs de l'angle par exemple..je ne sais pas si c'est faisable..

Avatar de l’utilisateur
mika-nt28
Actif
Messages : 7995
Inscription : 05 août 2014, 08:58
Localisation : Dreux - France

Re: [Plugin Tiers][Sujet Principal] Volets

Message par mika-nt28 » 24 juin 2017, 07:52

Oui j'ai le meme soucis.
Pour le positionnements des angle je me suis baser sur la vegetation.
Je regarde également pour ajouter les carte cadastral, mais ça sera le meme problème elle ne sont pas a jours sur geoportail
Pour faciliter la compréhension de votre problème, n’oubliez pas de poster
- Des Screenshots de votre configuration
- Le Log au moment du problème constaté

Encouragez-moi https://www.paypal.me/mikant28

Répondre

Revenir vers « [Catégorie] Automatisation »

Qui est en ligne ?

Utilisateurs parcourant ce forum : Aucun utilisateur inscrit et 5 invités