nebulous / infinitude

Open control of Carrier/Bryant thermostats
MIT License
225 stars 50 forks source link

All API Calls Fail on Fresh Install - Operation "eq": no method found #57

Closed MizterB closed 5 years ago

MizterB commented 6 years ago

After performing a successfully fresh install on a Ubuntu 18.04 system, using the Raspbian install instructions, the proxy functionality is working fine, but any calls to the /api path are failing with 500 errors. I have tried numerous examples of API calls found in the wiki and issues section, and none of them are successful.

After enabling development mode, I was able to pull some more details about the error, which are shown below. This was returned after calling http://:3000/api/config/

Operation "eq": no method found,
    left argument in overloaded package XML::Simple::Minded,
    right argument has no overloaded magic at /usr/share/perl5/XML/Simple.pm line 198.
193 
194  if(not defined $target) {
195     return $self->parse_file(undef, @_);
196  }
197 
198  elsif($target eq '-') {
199   local($/) = undef;
200   $target = <STDIN>;
201    return $self->parse_string(\$target, @_);
202 }
203 

/usr/share/perl5/XML/Simple.pm:194
/home/<username>/source/infinitude/lib/XML/Simple/Minded.pm:37
(eval 361):54
./infinitude:214
/usr/share/perl5/Mojolicious.pm:146
/usr/share/perl5/Mojolicious/Plugins.pm:15
/usr/share/perl5/Mojolicious/Plugins.pm:18
/usr/share/perl5/Mojolicious/Routes.pm:87
/usr/share/perl5/Mojolicious/Routes.pm:94
/usr/share/perl5/Mojolicious/Routes.pm:35
/usr/share/perl5/Mojolicious/Routes.pm:44
/usr/share/perl5/Mojolicious.pm:137
/usr/share/perl5/Mojolicious.pm:147
/usr/share/perl5/Mojolicious/Plugins.pm:15
/usr/share/perl5/Mojolicious.pm:209
/usr/share/perl5/Mojolicious.pm:209
/usr/share/perl5/Mojolicious/Plugins.pm:15
/usr/share/perl5/Mojolicious/Plugins.pm:18
/usr/share/perl5/Mojolicious.pm:153
/usr/share/perl5/Mojo/Server.pm:68
/usr/share/perl5/Mojo/EventEmitter.pm:15
/usr/share/perl5/Mojo/Server/Daemon.pm:103
/usr/share/perl5/Mojo/EventEmitter.pm:15
/usr/share/perl5/Mojo/Transaction/HTTP.pm:60
/usr/share/perl5/Mojo/Server/Daemon.pm:219
/usr/share/perl5/Mojo/Server/Daemon.pm:200
/usr/share/perl5/Mojo/EventEmitter.pm:15
/usr/share/perl5/Mojo/IOLoop/Stream.pm:99
/usr/share/perl5/Mojo/IOLoop/Stream.pm:48
/usr/share/perl5/Mojo/Reactor/Poll.pm:143
/usr/share/perl5/Mojo/Reactor/Poll.pm:143
/usr/share/perl5/Mojo/Reactor/EV.pm:46
/usr/share/perl5/Mojo/Reactor/EV.pm:25
/usr/share/perl5/Mojo/Reactor/EV.pm:25
/usr/share/perl5/Mojo/IOLoop.pm:136
/usr/share/perl5/Mojo/Server/Daemon.pm:39
/usr/share/perl5/Mojolicious/Command/daemon.pm:23
/usr/share/perl5/Mojolicious/Commands.pm:54
/usr/share/perl5/Mojolicious.pm:200
./infinitude:456
MizterB commented 6 years ago

Some additional observations...

I ran the same install process against Ubuntu 16.04 as well...interestingly, the call to /api/config/ worked the first time it was called. However, all subsequent calls returned the same error as above. I tried clearing the state directory and restarting Infinitude to recreate the behavior. It did not help - I still received an error on every API call after the restart.

sbrown4 commented 5 years ago

There seems to be some confusion as to whether systems.xml contains xml or an XML::Simple::Minded object. The latter gets passed to XML::Simple::Minded->new and the error occurs. I conformed the code to store the X::S::M object and the problem goes away.

I'm not sure which is preferred or I'd send a PR.

--- a/infinitude
+++ b/infinitude
@@ -136,7 +136,7 @@ sub qtr_hr {
 #      but we want to ensure automation devices eg VeraLite will work first
 any '/api/:zone_id/hold' => sub {
        my $c = shift;
-       my $xml = XML::Simple::Minded->new($store->get('systems.xml'));
+       my $xml = XML::Simple::Minded->new($store->get('systems.xml').'');

        my $idx = ($c->stash('zone_id')||1) - 1;
        my $zone = $xml->system->config->zones->zone->[$idx];
@@ -186,7 +186,7 @@ get '/api/status/' => \&api_stat;

 any '/api/:zone_id/activity/:activity_id' => sub {
        my $c = shift;
-       my $xml = XML::Simple::Minded->new($store->get('systems.xml'));
+       my $xml = XML::Simple::Minded->new($store->get('systems.xml').'');

        my $idx = ($c->stash('zone_id')||1) - 1;
        my $zone = $xml->system->config->zones->zone->[$idx];
@@ -211,7 +211,7 @@ any '/api/:zone_id/activity/:activity_id' => sub {
 # access simple system config variables by path
 any '/api/*path' => sub {
        my $c = shift;
-       my $xml = XML::Simple::Minded->new($store->get('systems.xml'));
+       my $xml = XML::Simple::Minded->new($store->get('systems.xml').'');
        my $search = $xml->system();
        foreach my $node (split('/',$c->stash('path'))) {
                $search = $search->$node;
@@ -273,7 +273,7 @@ post '/systems/:id' => sub {
        my $c = shift;
        if ($c->stash('id') eq 'infinitude') { # Data is being saved from web client
                my $xml = XML::Simple::Minded->new($c->req->json);
-               $store->set('systems.xml'  => $xml.'');
+               $store->set('systems.xml'  => $xml);
                $store->set('systems.json' => $xml->_as_json);
                $store->set(changes => 'true');
        } else { # Data from thermostat.
@@ -294,7 +294,7 @@ get '/systems/:id/config' => sub {
          $store->set(changes => time+60); # Force a followup stat->infinitude push/pull cycle after 1m
sbrown4 commented 5 years ago

This was resolved by PR 60.